2.5 KiB
2.5 KiB
type: module
path: "src/push.ts"
status: active
language: typescript
purpose: "Push one refined note into LIVE Foundry via the relay (Foundry keeps running)."
maintainer: Kaysser Kayyali
last_updated: 2026-06-22
linked_issues: []
depends_on: relay-client, name-uuid-resolver, foundry-block, foundry/assets.ts, toFoundry.ts
used_by: server, autosync, cli
tags: [module]
created: 2026-06-22
updated: 2026-06-22
push
src/push.ts — pushNote(deps) and the pure buildPushPayload(md, noteName, liveEntry, resolver, imageOverride?).
pushNote flow (see push-flow)
- Read the note; pre-process body
![[image]]embeds (upload co-located files to Foundry's uploads dir, rewrite to, drop non-local). Frontmatter untouched. readNoteFoundryMeta→foundry.cc_uuid(throws if absent — "run seed first") + portrait.- Resolve the name↔uuid map: preloaded
resolver, else<out>/name-uuid.json, else build via relay/search. relay.getEntry(id)— fetch the LIVE entry (preserves ownership/folder/pages/existing image).- Portrait upload if the note has one (and
foundryDataDir/worldset). buildPushPayload→obsidianToFoundryJsonLive(full entry withname+flags.campaign-codexoverridden, links resolved) → minimal diff{ name, "flags.campaign-codex": cc }(dot-path merge preserves sibling flags; never echoes_id/pages/ownership).dryRun→ return diff. Apply → back up the live entry to<out>/bak/<name>.<stamp>.json(reversible), thenrelay.updateEntry(id, diff).
Critical: no internal idempotency
pushNote ALWAYS PUTs (unless dryRun). It does NOT compare the note body to anything. The
caller is responsible for gating: the dashboard's push-all and autosync call baselineNote
afterward to set foundry.contentHash = contentHash(body) so a re-run skips unchanged notes.
Without that, repeated pushes re-send the same diff.
Depends on
- relay-client, name-uuid-resolver, foundry-block (
splitFrontmatter,readFoundryBlock),src/foundry/assets.ts(portrait + body-image upload),src/toFoundry.ts(obsidianToFoundryJsonLive).
Notes / gotchas
- Image upload needs
FOUNDRY_DATA_DIR+FOUNDRY_WORLD; without them, images are skipped and existing ones kept. See foundry-uploads-convention (in the user's memory, not this wiki). skipImageUploadis used for fast batch dry-run previews that shouldn't touch the Foundry data dir.