Files

129 lines
5.2 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<%*
/* Add Intel Entry (NPC) — clear, step-labeled prompts */
const file = app.workspace.getActiveFile();
if (!file) { new Notice("Open an NPC note first."); return; }
const today = tp.date.now("YYYY-MM-DD");
/* ——— Step 1: TYPE ——— */
new Notice("Step 1/7 — Type (what kind of intel?)");
const typeDisp = [
"interaction — direct conversation/action with this NPC",
"report — secondhand info relayed by someone else",
"rumor — unverified hearsay",
"asset — resource/contact identified or secured",
"op — operation/mission detail"
];
const typeVals = ["interaction","report","rumor","asset","op"];
const TYPE = await tp.system.suggester(typeDisp, typeVals);
if (!TYPE) { new Notice("Cancelled."); return; }
/* ——— Step 2: SUMMARY ——— */
new Notice("Step 2/7 — Summary (what happened?)");
const summary = await tp.system.prompt(
"Summary (12 sentences). You can include [[links]] to NPCs/factions/places.\nExample: Says that [[House Asase]] is rebuilding the Drenches walls."
) ?? "";
/* ——— Step 3: SESSION link (optional) ——— */
new Notice("Step 3/7 — Session link (optional)");
const allFiles = app.vault.getMarkdownFiles();
function hasSessionTag(f) {
const fm = app.metadataCache.getFileCache(f)?.frontmatter ?? {};
const tags = fm.Tags ?? fm.tags ?? [];
const arr = Array.isArray(tags) ? tags : [tags];
const lower = arr.map(x => String(x||"").toLowerCase());
return lower.includes("session") || lower.includes("pf2e");
}
const sessions = allFiles.filter(hasSessionTag).sort((a,b)=>{
const fa = app.metadataCache.getFileCache(a)?.frontmatter ?? {};
const fb = app.metadataCache.getFileCache(b)?.frontmatter ?? {};
const da = String(fa.Date||"");
const db = String(fb.Date||"");
return db.localeCompare(da) || b.basename.localeCompare(a.basename);
});
const sessionChoicesDisp = ["(skip — no session link)"].concat(
sessions.map(f=>{
const d = app.metadataCache.getFileCache(f)?.frontmatter?.Date ?? "";
return d ? `Link to session: [[${f.basename}]] — ${d}` : `Link to session: [[${f.basename}]]`;
})
);
const sessionChoicesVal = ["__skip__"].concat(sessions.map(f=>`[[${f.basename}]]`));
let sesPick = await tp.system.suggester(sessionChoicesDisp, sessionChoicesVal);
if (!sesPick) sesPick = "__skip__";
const sessionField = (sesPick === "__skip__") ? undefined : sesPick;
/* ——— Step 4: SOURCE (who/what told us?) ——— */
new Notice("Step 4/7 — Source (who/what told us?)");
const srcChoicesDisp = ["(skip)","(manual entry — type your own)"].concat(
allFiles.map(f=>`[[${f.basename}]]`).sort((a,b)=>a.localeCompare(b, undefined, {sensitivity:"base"}))
);
const srcChoicesVal = ["__skip__","__manual__"].concat(
allFiles.map(f=>`[[${f.basename}]]`).sort((a,b)=>a.localeCompare(b, undefined, {sensitivity:"base"}))
);
let srcPick = await tp.system.suggester(srcChoicesDisp, srcChoicesVal);
if (!srcPick) srcPick = "__skip__";
let sourceField = "";
if (srcPick === "__manual__") {
sourceField = (await tp.system.prompt("Type any source (free text or [[Link]])")) ?? "";
} else if (srcPick !== "__skip__") {
sourceField = srcPick;
}
/* ——— Step 5: RELIABILITY (AE) ——— */
new Notice("Step 5/7 — Reliability (AE)");
const relDisp = [
"A — confirmed (firsthand/corroborated)",
"B — likely (trustworthy witness/evidence)",
"C — uncertain (unverified details)",
"D — doubtful (conflicts / low trust)",
"E — unknown (no basis to judge)"
];
const relVals = ["A","B","C","D","E"];
const reliability = await tp.system.suggester(relDisp, relVals) ?? "C";
/* ——— Step 6: CREDIBILITY (15) ——— */
new Notice("Step 6/7 — Credibility (15)");
const credDisp = ["5 — strong","4 — good","3 — fair","2 — weak","1 — very weak"];
const credVals = ["5","4","3","2","1"];
const credibility = Number(await tp.system.suggester(credDisp, credVals) ?? "3");
/* ——— Step 7: TAGS (multi-select, optional) ——— */
new Notice("Step 7/7 — Tags (optional)");
const tagMap = app.metadataCache.getTags?.() ?? {};
let allTags = Array.from(new Set(Object.keys(tagMap).map(t => t.replace(/^#/, ""))))
.sort((a,b)=>a.localeCompare(b, undefined, {sensitivity:"base"}));
const chosen = new Set();
while (true) {
const remaining = allTags.filter(t => !chosen.has(t));
const disp = ["(done)","(new tag…)"].concat(remaining.map(t=>`#${t}`));
const vals = ["__done__","__new__"].concat(remaining);
const pick = await tp.system.suggester(disp, vals);
if (!pick || pick === "__done__") break;
if (pick === "__new__") {
const nt = (await tp.system.prompt("New tag (without #)"))?.trim();
if (nt) { chosen.add(nt); if (!allTags.includes(nt)) allTags.push(nt); }
} else {
chosen.add(pick);
}
}
const tags = Array.from(chosen);
/* ——— Write to frontmatter ——— */
await app.fileManager.processFrontMatter(file, (fm) => {
if (!Array.isArray(fm.Intel)) fm.Intel = [];
fm.Intel.unshift({
date: today,
type: TYPE,
summary,
session: sessionField, // shows up in NPC/Session tables
source: sourceField || undefined, // e.g., [[Ronan Elidari]] or free text
reliability,
credibility,
tags
});
});
new Notice("NPC Intel entry added.");
%>