Files
obsidian-foundry-sync/scripts/gen-cc-dir.ts
Kaysser Kayyali 533f4fdc6b feat(dashboard): uuid auto-match, push-all, auto-cc, link picker, rec filters
Bring every scripts/-only capability into the dashboard UI so nothing
requires a manual shell command, plus dev-mode overlay + UX fixes.

- indexAll: fall back to foundry.cc_uuid when basename doesn't match
  (basename wins; cc claimed once). Resolves refined-only orphans whose
  filename differs from the Foundry entry (e.g. "Angro Harn" vs
  "Angro Harn - Journal") with no new UI.
- Push all changed: POST /api/push-all + header button. Dry-run lists
  vault-newer notes; apply pushes each (live entry backed up to <out>/bak),
  baselines foundry.contentHash, concurrency 4. Replaces scripts/resync.ts.
  pushNote gains skipImageUpload for fast dry-run previews.
- Auto-build cc dir at launch: --cc is now optional; cmdUi synthesizes cc
  stubs from the journal via new src/ccdir.ts (generateCcDir). Replaces
  running scripts/gen-cc-dir.ts by hand.
- Refined-only table + Link-to-Foundry picker: surface the previously
  hidden refined-only rows; GET /api/entries + POST /api/link inject the
  foundry block for a chosen entry and re-index. For notes with no link.
- Dev-mode mirror overlay: index/detail/push read mirror-first so dev
  writes preview as apply would. Overlay is mtime-aware (mirror wins only
  if >= real mtime) so Obsidian edits to the real vault still surface as
  changed instead of being masked by a stale baselined mirror copy.
- Re-scan button + auto-refresh on tab focus so edits show without reload.
- Recommendation panel: "See N" buttons filter the table to a bucket, with
  an active-filter chip and filtered counts in the section headers.
- Row badge wording: short status nouns (cc-only / vault newer / ...) so
  the tag doesn't read like a button.
- Dashboard binds 0.0.0.0 by default (tailnet-reachable); --host to restrict.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-20 22:05:57 +00:00

38 lines
1.5 KiB
TypeScript

#!/usr/bin/env tsx
/**
* Generate a Campaign Codex cc export dir from a journal LevelDB snapshot, when no
* real CC export exists on disk. Writes one cc.md per CC entry, named by entry name
* (so the dashboard's indexAll matches refined notes by basename) with frontmatter
* cc_id + cc_type — the minimum indexAll needs to link a note to its Foundry entry
* (db.byId(cc_id)) and for seed to build the foundry: block. cc bodies are stubs; a
* real CC export would have full bodies + cc_sync_hash, but those aren't needed for
* the seed/push flow.
*
* npx tsx scripts/gen-cc-dir.ts --journal <snapshot> --cc <out-cc-dir>
*/
import { JournalDb } from "../src/db.js";
import { generateCcDir } from "../src/ccdir.js";
function parseArgs(argv: string[]) {
const o: { journal: string; cc: string } = { journal: "", cc: "" };
for (let i = 2; i < argv.length; i++) {
if (argv[i] === "--journal") o.journal = argv[++i];
else if (argv[i] === "--cc") o.cc = argv[++i];
else throw new Error(`unknown flag: ${argv[i]}`);
}
if (!o.journal || !o.cc) throw new Error("--journal <snapshot> and --cc <out-dir> are required");
return o;
}
async function main() {
const { journal, cc } = parseArgs(process.argv);
const db = await JournalDb.open(journal);
try {
const n = await generateCcDir(db, cc);
console.log(`wrote ${n} cc stubs -> ${cc}`);
} finally {
await db.close();
}
}
main().catch((e) => { console.error(`error: ${(e as Error).message}`); process.exit(1); });