Wire the push cycle (SPEC §6) into a runnable command; SAFE BY DEFAULT.
- runPush + main(): dry-run by default (plan only, ZERO Docmost writes, no ref
advance); --apply is the ONLY path that builds a client and mutates Docmost
- orchestration mirrors pull.ts: assertGitAvailable -> ensureRepo ->
merge-in-progress guard (§9/§12) -> checkout main -> commit local working tree
(Docmost-Sync-Source: local, §7.3) -> base = refs/docmost/last-pushed else
docmost -> diffNameStatus(base, main) -> computePushActions -> (apply) ->
write-back created pageIds + advance refs; divergent-docmost escalates (exit 1)
- npm run push (dry-run) / npm run push -- --apply (writes; needs creds)
- fix (review Blocker): pass the WHOLE VaultGit to applyPushActions (bare method
refs lost `this` -> --apply crashed on real git); regression test exercises the
--apply path against a REAL VaultGit temp repo + fake client (proven to catch it)
- symmetric divergent-docmost escalation in both ff branches; dry-run logs the
local commit explicitly; SPEC §6 notes the dry-run/local-commit behavior
- 737 -> 747 green (x2 stable); build clean; corpus STABLE
Deferred (daemon increment): FS-watcher/debounce (§7.1), git-remote push (§7.2),
continuous poll loop, pull-side §10 record consumption, fractional-index position.
Set up the project structure per the new-project guide, adapted from the
Python skeleton to the Node/TS stack fixed in SPEC.md (reuses docmost-mcp).
Scaffold only — the sync engine is not implemented yet.
- src/settings.ts: single config layer on zod, schema keyed by real ENV
names; credentials and own-service address have no default (fail fast).
- src/config-errors.ts: loadSettingsOrExit — clear startup message naming
the missing/invalid env var instead of a raw stack trace; exit(1).
- src/index.ts: thin entry point that validates config and logs (stub).
- test/: vitest unit tests for settings parsing and config errors (10 tests).
- Makefile (install/env/build/test/run/dev/clean), strict tsconfig, vitest.
- Dockerfile (single-stage, no EXPOSE, prunes dev deps), docker-compose
(daemon, volume on /app/data, watchtower), ghcr CI with build needs test.
- .env.example, .gitignore/.dockerignore, AGENTS.md, README.md.
- Pinned deps (dotenv, zod) + committed package-lock.json.