Files
docmost-sync/AGENTS.md
vvzvlad c6edd73324 refactor(pull): extract tested vault-layout module; harden pull; close review findings
Address the Increment-1 code review (3 warnings + suggestions).

- layout: new pure src/layout.ts (buildVaultLayout) — page-tree -> vault paths,
  sibling + full-path collision disambiguation (sanitized ~slugId suffix), parent
  cycle guard; pull.ts is now a thin I/O loop
- layout: resolve orphan/root collisions at the NAME stage so an orphan ancestor
  can't desync its children's folder segments (fixes review Major); covered by test
- pull: per-page try/catch (one bad page no longer aborts the mirror), bounded
  concurrency (6), progress logging, process.exitCode=1 on partial mirror
- security: filename disambiguation suffix now passes through sanitizeTitle
- docs: AGENTS.md -> Increment 1 status/structure/run targets; pull.ts meta-block
  comment; collectRecentSince JSDoc (lexicographic UTC-ISO precondition)
- tests: layout (9), markdown-document round-trip (no comments block, SPEC §3),
  firstDivergence; export firstDivergence. 49 tests green.
2026-06-16 21:09:40 +03:00

77 lines
3.7 KiB
Markdown

# AGENTS.md
Onboarding notes for agents working on **docmost-sync** (Node / TypeScript, ESM).
## What this is
A daemon that bidirectionally syncs Docmost articles with a local Markdown git
vault (git is the state store). It reuses the sibling project **docmost-mcp** as
a library (DocmostClient, ProseMirror ↔ Markdown converter, collab-write).
**Status: Increment 1.** `src/index.ts` is still a thin config-validating entry,
but the engine now has a working READ-ONLY `pull` (Docmost -> FS mirror) and a
Phase-0 round-trip idempotency harness. Bidirectional sync, conflict handling,
and git are NOT implemented yet (see the SPEC phases). See `SPEC.md` for the full
design and the phased plan before adding engine logic.
## Project structure
The project is now an **npm-workspaces monorepo**. `packages/docmost-client` is
the extracted `DocmostClient` + `lib/` — a verbatim 1:1 copy of `docmost-mcp/src/`
with the sync-specific methods appended under a clear banner (changes are
backported into `docmost-mcp` manually). The **ROOT remains the engine app**
(`src/`, `test/`, `build/`, `data/`) and depends on `docmost-client`. `npm run
build` builds the lib first, then compiles the app to `build/`.
- `src/` — application code.
- `src/settings.ts` — the single config entry point (zod schema keyed by the
real ENV var names; `parseSettings` is pure, `loadSettings` reads `.env`).
- `src/config-errors.ts``loadSettingsOrExit` turns a config error into a
clear startup message that names the missing/invalid variable, then exits.
- `src/index.ts` — thin entry point.
- `src/sanitize.ts` — filesystem-safe filename sanitization (SPEC §12).
- `src/layout.ts` — pure page-tree -> vault path mapping.
- `src/roundtrip.ts` — Phase-0 idempotency harness (SPEC §11).
- `src/pull.ts` — read-only Docmost -> FS mirror (SPEC §6).
- `test/` — vitest tests (`*.test.ts`).
- `data/` — all mutable runtime state (the git vault lives here). Gitignored;
mounted as a docker volume in production. Never put code/static assets here.
- `build/` — compiled output (`tsc`). Gitignored.
Relative imports inside `src/` use the `.js` extension (NodeNext), e.g.
`import { loadSettings } from './settings.js'`.
## Setup
- `make install` — install dependencies (`npm ci`).
- `make env` — create `.env` from `.env.example` (or `cp .env.example .env`),
then fill in the values.
## Running
- `make test` — run the test suite (vitest).
- `make run` — build and run the app.
- `make dev` — run in watch mode (tsx).
- `make roundtrip` — run the offline round-trip idempotency harness.
- `make pull` — mirror the configured space into the vault (read-only).
`make` (or `make help`) lists all targets.
## Conventions
- All mutable state lives ONLY under `data/`. Static assets are code, never in `data/`.
- All config and credentials come ONLY from ENV / `.env`, read through
`src/settings.ts`. Credentials and the addresses of our own services that the
user provides go ONLY into `.env` (never into code, never as inline env vars on
the command line) and are read through settings.
- No default/example credentials in code. Addresses of our own services (Docmost)
have NO default either. A missing required variable must FAIL AT STARTUP with a
clear message that names the variable — no raw stack trace.
- Defaults are allowed only for non-secret tunables (log level, intervals, vault
path under `data/`).
- All code comments are written in ENGLISH.
- Repeated actions go through the `Makefile`.
- Tests are required for new code. In CI the `build` job needs `test` (tests gate
the docker build).
- No `EXPOSE` in the Dockerfile — this is a daemon with no inbound HTTP port.