<%* /* Add Intel entry to CURRENT Faction note, with vault-aware suggestions & link completion. */ const file = app.workspace.getActiveFile(); if (!file) { new Notice("Open a Faction note first."); return; } const today = tp.date.now("YYYY-MM-DD"); // ---------- TYPE ---------- new Notice("Step 1/6 — Pick Intel TYPE"); const TYPE_OPTIONS = ["interaction","report","rumor","asset","op"]; const type = await tp.system.suggester(TYPE_OPTIONS.map(x => `Type: ${x}`), TYPE_OPTIONS); if (!type) { new Notice("Cancelled."); return; } // ---------- SOURCE (suggest existing notes as [[Note]]) ---------- new Notice("Step 2/6 — Choose SOURCE"); const allFiles = app.vault.getMarkdownFiles(); const names = allFiles.map(f => f.basename).sort((a,b)=>a.localeCompare(b, undefined, {sensitivity:"base"})); const wikiChoices = ["(manual entry)…", ...names.map(n => `[[${n}]]`)]; let sourcePick = await tp.system.suggester(wikiChoices, wikiChoices); if (!sourcePick) { new Notice("Cancelled."); return; } let source = sourcePick === "(manual entry)…" ? (await tp.system.prompt("Source (free text or [[Link]])")) ?? "" : sourcePick; // ---------- SUMMARY (free text, then auto-complete [[links]]) ---------- new Notice("Step 3/6 — Write SUMMARY (you can include [[links]])"); let summary = await tp.system.prompt("Summary (what happened)?\nTip: You can include [[Note]] names; we’ll auto-complete them next.") ?? ""; // Helper: resolve [[links]] in the summary to existing notes (prompt if ambiguous) async function resolveWikiLinks(text) { // Find [[...]] occurrences const re = /\[\[([^[\]|#]+)(?:#[^\]|]+)?(?:\|[^\]]+)?\]\]/g; let m, out = text, offset = 0; while ((m = re.exec(text)) !== null) { const raw = m[0], term = m[1].trim(); const exact = names.find(n => n.toLowerCase() === term.toLowerCase()); let replacement = raw; if (exact) { replacement = `[[${exact}]]`; } else { // Offer matching notes to replace this token const matches = names.filter(n => n.toLowerCase().includes(term.toLowerCase())).slice(0,50); const disp = [`Keep as typed: [[${term}]]`, ...matches.map(n => `→ [[${n}]]`)]; const vals = [null, ...matches]; const pick = await tp.system.suggester(disp, vals); if (pick) replacement = `[[${pick}]]`; } // Splice into output string at the correct position (accounting for prior replacements) const start = m.index + offset; out = out.slice(0, start) + replacement + out.slice(start + raw.length); offset += replacement.length - raw.length; } return out; } summary = await resolveWikiLinks(summary); // Optional: append more links via suggester loop while (true) { const addMore = await tp.system.suggester( ["(done)","Append a wikilink…"], ["__done__","__add__"] ); if (!addMore || addMore === "__done__") break; const pick = await tp.system.suggester(names.map(n => `[[${n}]]`), names.map(n => `[[${n}]]`)); if (pick) summary = (summary ? summary + " " : "") + pick; } // ---------- RELIABILITY / CREDIBILITY ---------- new Notice("Step 4/6 — Reliability (A–E)"); const relDisplay = ["A — confirmed","B — likely","C — uncertain","D — doubtful","E — unknown"]; const relValues = ["A","B","C","D","E"]; const reliability = (await tp.system.suggester(relDisplay, relValues)) ?? "C"; new Notice("Step 5/6 — Credibility (1–5)"); const credDisplay = ["5 — strong","4 — good","3 — fair","2 — weak","1 — very weak"]; const credValues = ["5","4","3","2","1"]; const credibility = (await tp.system.suggester(credDisplay, credValues)) ?? "3"; // ---------- TAGS (multi-select from existing vault tags) ---------- new Notice("Step 6/6 — Add TAGS (optional)"); const tagMap = app.metadataCache.getTags?.() ?? {}; let allTags = Array.from(new Set(Object.keys(tagMap).map(t => t.replace(/^#/, "")))).sort(); const chosen = new Set(); while (true) { const remaining = allTags.filter(t => !chosen.has(t)); const display = ["(done)", "(new tag)…", ...remaining.map(t => `#${t}`)]; const values = ["__done__", "__new__", ...remaining]; const pick = await tp.system.suggester(display, values); if (!pick || pick === "__done__") break; if (pick === "__new__") { const newTag = (await tp.system.prompt("New tag (without #)"))?.trim(); if (newTag) { chosen.add(newTag); if (!allTags.includes(newTag)) allTags.push(newTag); } } else { chosen.add(pick); } } const tags = Array.from(chosen); // ---------- Update frontmatter safely ---------- await app.fileManager.processFrontMatter(file, (fm) => { if (!Array.isArray(fm.Intel)) fm.Intel = []; fm.Intel.unshift({ date: today, type, summary, source, reliability, credibility: Number(credibility), tags }); }); new Notice("Intel entry added."); %>