906733b5c8
Blocking (review id 2514): - [security] Forbid symlinks in vaults. ensureServable now sets core.symlinks=false in each vault's local git config (a pushed symlink is checked out as a plain file, never a real link), and the engine cycle wraps every read/write/mkdir in an lstat/realpath guard (new path-guard.ts) that refuses a path that is — or traverses — a symlink, or whose realpath escapes the vault root. Prevents a writer from publishing /etc/passwd or the server .env, or writing outside the vault. Adds unit tests (path-guard.test.ts) + a read-guard integration test (cycle.test.ts) + real lstat/realpath in the roundtrip integration test. - [simplification] Delete dead lib/diff.ts + test/diff.test.ts and drop the now-unused @fellow/prosemirror-recreate-transform dependency. - [documentation] Add a CHANGELOG [Unreleased] → Added entry for git-sync. Warnings: - [test-coverage] Cover the CREATE-branch conflict-markers guard (a new .md with markers and no gitmost_id is recorded as a create failure, never created). Suggestions: - [stability] Bound each `git config` in ensureServable with a timeout. - [authz] Trigger endpoint resolves spaceId workspace-scoped and 404s a foreign space before any vault directory is created. - [stability] Attribute git-initiated moves to the service account (lastUpdatedById), via an optional actor param on PageService.movePage. - [documentation] Document the per-space autoMergeConflicts toggle in AGENTS.md. - [test-coverage] Cover the unterminated `:::` callout fence fallback. - [simplification] Move test-only roundtrip-helpers.ts out of src/ into test/. Architecture: - Move the Yjs/ProseMirror merge primitives (yjs-body-merge, three-way-merge, lcs + specs) into collaboration/merge/, breaking the collaboration → integrations/git-sync dependency cycle this PR introduced. - Port the schema-surface drift gate to packages/mcp (the mcp schema mirror had none); pins 52 entries. Deferred (with rationale in the review thread): the incremental-pull perf warning (correctness-neutral; needs a high-water-mark design + its own tests on the data-loss-critical path) and the redis-sync rolling-deploy mixed-version edge (the deficient behavior is in already-released old-instance code; the new code is correct on both sides; impact is a transient rollout-window artifact). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
127 lines
3.2 KiB
TypeScript
127 lines
3.2 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 {
|
|
assertVaultPathSafe,
|
|
isWithinRoot,
|
|
VaultPathUnsafeError,
|
|
} from "./engine/path-guard.js";
|
|
export type { PathGuardIo, VaultPathUnsafeReason } from "./engine/path-guard.js";
|
|
|
|
export { parsePageFile, serializePageFile } from "./lib/page-file.js";
|