Raise coverage from 2.6% to 68% statements by adding 19 test files (~480 tests) covering every module in test-strategy-report.md. No production code changed — tests reach private logic via (client as any), mock HTTP with axios-mock-adapter on the real axios instance (interceptors intact), and mock the Hocuspocus provider with vi.mock + real yjs + fake timers. Coverage: auth-utils/filters/page-lock/json-edit 100%, diff 99%, node-ops 96%, transforms 95%, collaboration 86%, layout 91%, client.ts 41% (transport). - node-ops/transforms/json-edit/page-lock/filters: pure tree/text ops, immutability + clone guarantees, throw-vs-noop contracts - markdown-converter + markdown-document envelope + fast-check round-trip property test - diff, docmost-schema (sanitizeCssColor/clampCalloutType security guards) - collaboration: pure (buildCollabWsUrl/buildYDoc) + write-path (mutatePageContent read-transform-write, false-success suppression) - client.ts: isSafeUrl/validateDoc* XSS guards, vm-sandbox, REST pagination, 401 re-auth interceptor, login dedup, uploadImage/createPage multipart guards - collectRecentSince edge cases; loadSettingsOrExit invalid-value branch - env-gated E2E skeleton (DOCMOST_E2E) Two genuine markdown round-trip non-idempotency bugs are documented as it.fails (code-mark excludes other marks; block-image injects a blank line). Latent: isSafeUrl allows file:// on link context. Adds dev-deps: fast-check, @vitest/coverage-v8, axios-mock-adapter; adds the "coverage" npm script.
docmost-sync
Bidirectional sync between Docmost articles and a local Markdown git vault — the
git repository is the state store. For the full design and the phased
implementation plan, see SPEC.md (the authoritative spec).
Status: Increment 1 — monorepo scaffold + read-only
pull+ Phase-0 round-trip harness. Continuous two-way sync is not implemented yet; see the phased plan inSPEC.md.
It reuses the sibling project docmost-mcp as a library: the DocmostClient
REST client and the lossless ProseMirror ↔ Markdown converter are extracted into
this monorepo (so changes can be backported file-by-file).
Layout
This is an npm-workspaces monorepo:
packages/docmost-client(docmost-client) — the Docmost REST client and itslib/(converter, markdown-document, collaboration, …). Its source layout mirrorsdocmost-mcp/src/1:1 so diffs can be backported by copying files. Sync-specific REST methods are added under clearly markeddocmost-sync additionsbanners.- the repo ROOT — the sync engine app (
src/,test/,build/,data/). It depends ondocmost-clientand holds the config (src/settings.ts), filename sanitization (src/sanitize.ts), the Phase-0 round-trip idempotency harness (src/roundtrip.ts), and the read-onlypull(src/pull.ts).
Install & build
Requires Node >= 20.
npm install # links the workspace packages
npm run build # builds docmost-client, then compiles the app into build/
docmost-client must build before the app (the app consumes its built output);
the root build script builds the lib first, then runs tsc.
Configuration
Copy .env.example to .env and fill in real values. The
config is read through src/settings.ts.
| Variable | Required | Meaning |
|---|---|---|
DOCMOST_API_URL |
yes | Base URL of our Docmost instance. |
DOCMOST_EMAIL |
yes | Docmost service-user login email. |
DOCMOST_PASSWORD |
yes | Docmost service-user login password. |
DOCMOST_SPACE_ID |
yes | Which Docmost space to mirror. |
VAULT_PATH |
no | Local vault directory (default data/vault). |
GIT_REMOTE |
no | Optional git remote the vault pushes to. |
POLL_INTERVAL_MS |
no | Poll interval in ms (default 15000). |
DEBOUNCE_MS |
no | Debounce window in ms (default 2000). |
LOG_LEVEL |
no | debug | info | warn | error (default info). |
Real secrets go in .env, which is git-ignored — never commit them. The
git remote grants access to the whole vault, so protect it no less than Docmost
itself (SPEC §12).
Running
Round-trip idempotency harness (Phase 0, SPEC §11)
Verifies that export → import → export is byte-stable. Runs offline against a
fixture (the default for CI) — no Docmost credentials needed:
npm run build
node build/roundtrip.js --fixture test/fixtures/sample-doc.json
Or against a live page (needs .env):
node build/roundtrip.js --page <pageId>
Exit code is 0 when the markdown is byte-stable, 1 on a markdown divergence (CI-able). A document-level divergence after stripping block ids is a known SPEC §11 finding and does not fail the run.
Pull (Docmost → filesystem mirror, SPEC §6)
Read-only mirror: walks the configured space's page tree and writes one .md
per page under <VAULT_PATH>/<…ancestors>/<Title>.md. Requires a .env with
real Docmost credentials — it makes live REST calls and does not touch Docmost
state (read-only this increment):
npm run pull