5.2 KiB
<%* /* 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 (1–2 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 (A–E) ——— */ new Notice("Step 5/7 — Reliability (A–E)"); 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 (1–5) ——— */ new Notice("Step 6/7 — Credibility (1–5)"); 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."); %>