Pipeline
The sync pipeline that transforms config into content.
Overview
The sync() function in packages/cli/src/lib/sync/index.ts runs a four-phase pipeline: setup, resolve, write, and generate. This expands the three-phase model from the Engine Overview into the individual steps that run within each phase.
Steps
Returns: { pagesWritten, pagesSkipped, pagesRemoved, elapsed } (elapsed in milliseconds)
Page Transformation
Each page passes through copyPage() (sync/copy.ts):
- Mtime skip check -- If source mtime and frontmatter hash match the previous manifest, return the cached entry (see Incremental Sync)
- Read source file (or evaluate virtual content)
- Rewrite relative markdown links using source-to-output path map
- Copy referenced images to
content/public/images/, rewrite paths to/images/<name>-<hash>.<ext>(8-char MD5 of the image path) - Merge frontmatter (config defaults + source frontmatter, source wins)
- SHA-256 content hash -- skip write if unchanged from previous manifest
- Write final markdown/MDX to
.ciderpress/content/
Entry Resolution
The entry resolver (sync/resolve/index.ts) recursively walks the config tree and resolves each entry:
Text Derivation
Text derivation is configurable via the title field's from property:
Multi-Sidebar
ciderpress generates a multi-sidebar structure for Rspress. Root entries share the / namespace. Standalone scopes (workspace items, sections with standalone: true, root-level OpenAPI sidebars) get their own namespace (e.g., /apps/api/). Each scope has an independent sidebar tree.
The two relevant entry fields are:
Runtime contract: scopes.json
The list of standalone scope paths is collected at sync time (packages/cli/src/lib/sync/index.ts:378-380 filters on e.standalone || e.root) and written to .ciderpress/content/.generated/scopes.json. The UI loads it at runtime (packages/ui/src/config.ts:89-98) so the custom Sidebar component can isolate each standalone scope into its own pane.