3 Commits

Author SHA1 Message Date
37dceb9ac5 feat: refine workflow, take first steps towards thiking about other peoples preferences 2026-06-22 16:27:51 +00:00
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
ce8040c41b feat: file uploads (portrait + body images) + live-relay batch scripts
Portrait upload was broken: it wrote to Data/worlds/<world>/uploads (per-world,
missing the Data/ segment) and did not URL-encode. Fixed to the verified
convention -- copy to the GLOBAL Data/uploads/<world>/ dir (unencoded on disk),
flag stored URL-encoded as uploads/<world>/<encodeURIComponent(file)>. Extracted
a reusable uploadImageAsset helper.

Body ![[image]] embeds were dropped by mdToHtml. Added push-layer pre-processing
(processBodyImages in push.ts): upload co-located files, rewrite the embed to
![](servedPath), drop non-local refs gracefully. mdToHtml renders ![alt](src)
-> <img>. parseBody now returns a preface (preamble content besides the tagline)
so a loose image between the tagline and the first ## section is no longer
dropped before conversion.

scripts/ helpers for the live-relay path (no offline CC export needed):
- seed-by-name: link refined notes to Foundry by name -> uuid, inject foundry block
- import-missing: create Foundry entries with no vault note as new pushable notes
- gen-cc-dir: generate a cc dir from a journal snapshot so the dashboard ui can run
- resync: push every body-changed note and baseline its foundry.contentHash so
  re-runs only catch new edits (idempotent, re-runnable)

Verified end-to-end against the dev Foundry world: portraits + body images
served by Foundry, bidirectional round-trip faithful, push is no-clobber
(diff keys only name + flags.campaign-codex).

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-20 21:01:15 +00:00