<%* /* 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."); %>