Files
gitmost/packages/git-sync/src/index.ts
claude_code f1a8f40b9f fix(git-sync): address PR #119 review (#1571)
Resolve the code-review findings from comment #1571 on PR #119.

Engine (packages/git-sync):
- Idempotent CREATE on retry: before createPage, look the page up in the
  live Docmost tree by (parentPageId, title) and ADOPT it instead of
  duplicating when a prior cycle created it but failed to persist the
  pageId back to disk. Only trust a COMPLETE tree for the lookup; fall
  back to createPage otherwise. Covered by new tests incl. a complete=false
  regression-lock.
- Route applyPullActions diagnostics through an injected logger instead of
  bare console (thread log from the cycle).
- Add a timeout to the git execFile chokepoint (runRaw) so a hung git
  subprocess cannot wedge a sync cycle.
- Translate remaining Russian code comments to English.
- Remove dead standalone-CLI code (parseArgs/PushParsedArgs,
  parseSettings/envSchema, loadSettingsOrExit + config-errors.ts) and the
  matching index exports/specs; keep the Settings type.
- Fix the dangling docs link in package.json.
- Add a schema-surface snapshot guard so any drift in the vendored
  document schema is a loud, must-review CI failure (+ provenance header).

Server (apps/server):
- Add a configurable watchdog timeout to the spawned git http-backend so a
  stalled push cannot hold the per-space lock forever
  (GIT_SYNC_BACKEND_TIMEOUT_MS).
- Close the in-process TOCTOU window in SpaceLockService.withSpaceLock by
  reserving the slot synchronously before acquire.
- Add tests: removePage git-sync provenance (both branches), ensureServable
  force-push-protection git configs, and the phase-B+ datasource methods.

Docs / build:
- AGENTS.md: list git-sync as the fifth workspace package and note the
  three schema mirrors; fix the dangling git-sync-plan.md backlog link.
- pnpm-lock.yaml: add the missing @docmost/git-sync workspace link so
  pnpm install --frozen-lockfile (CI default) succeeds.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-27 05:30:29 +03:00

120 lines
3.0 KiB
TypeScript

/**
* Public surface of `@docmost/git-sync`.
*
* Exposes the pure converter (markdown <-> ProseMirror, file envelope,
* canonicalization) and the sync engine (reconcile planner, vault layout,
* pull/push, the git wrapper, and the settings parser) that the gitmost server
* drives in-process.
*/
// Pure converter (markdown <-> ProseMirror, file envelope, canonicalization).
export {
serializeDocmostMarkdown,
serializeDocmostMarkdownBody,
parseDocmostMarkdown,
convertProseMirrorToMarkdown,
markdownToProseMirror,
canonicalizeContent,
docsCanonicallyEqual,
} from "./lib/index.js";
export type { DocmostMdMeta } from "./lib/index.js";
// Pure engine (no IO): reconcile planner, vault layout, sanitize, stabilize,
// loop-guard body hash.
export {
planReconciliation,
decideAbsenceDeletions,
MASS_DELETE_MIN_EXISTING,
MASS_DELETE_FRACTION,
} from "./engine/reconcile.js";
export type {
LiveEntry,
ExistingEntry,
WriteEntry,
MovedEntry,
ReconciliationPlan,
DeletionDecision,
} from "./engine/reconcile.js";
export { buildVaultLayout } from "./engine/layout.js";
export type { PageNode, VaultEntry } from "./engine/layout.js";
export { sanitizeTitle, disambiguate } from "./engine/sanitize.js";
export { stabilizePageFile } from "./engine/stabilize.js";
export type { PageMeta } from "./engine/stabilize.js";
export { bodyHash } from "./engine/loop-guard.js";
// IO engine: the client seam, the VaultGit git wrapper, the
// pull (Docmost->FS) + push (FS->Docmost) planners/appliers, and the (pure)
// settings parser. The engine consumes the native `GitSyncClient` seam (the
// server implements it) rather than any REST client.
export type { GitSyncClient, GitSyncPageNodeLite } from "./engine/client.types.js";
export {
VaultGit,
vaultGitEnv,
buildCommitMessage,
BOT_AUTHOR_NAME,
BOT_AUTHOR_EMAIL,
DEFAULT_BRANCH,
} from "./engine/git.js";
export type { DiffEntry, MergeResult, CommitOptions } from "./engine/git.js";
export {
readExisting,
computePullActions,
applyPullActions,
} from "./engine/pull.js";
export type {
ReadExistingDeps,
PullActionsInput,
PullActions,
ApplyPullActionsDeps,
ApplyResult,
} from "./engine/pull.js";
export {
classifyRenameMoves,
computePushActions,
applyPushActions,
runPush,
parentFolderFile,
LAST_PUSHED_REF,
DOCMOST_BRANCH,
LOCAL_AUTHOR_NAME,
LOCAL_AUTHOR_EMAIL,
LOCAL_SOURCE_TRAILER,
} from "./engine/push.js";
export type {
CreateAction,
UpdateAction,
DeleteAction,
RenameMoveAction,
RenameMoveActionClassified,
ClassifyRenameMovesDeps,
PushActions,
PushActionsInput,
MetaSide,
ApplyPushDeps,
WrittenBackPage,
PushedPageRecord,
PushFailure,
PushNoop,
ApplyPushResult,
PushDeps,
PushRunResult,
} from "./engine/push.js";
export type { Settings } from "./engine/settings.js";
export { runCycle } from "./engine/cycle.js";
export type {
RunCycleDeps,
RunCycleResult,
CycleFs,
} from "./engine/cycle.js";
export { parsePageFile, serializePageFile } from "./lib/page-file.js";