129 lines
5.2 KiB
Markdown
129 lines
5.2 KiB
Markdown
<%*
|
||
/* 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.");
|
||
%>
|