Overview
This document explains the typical developer flow for:
- Building the full workspace (
pnpm -r build) - Running tests (workspace-wide and package-specific) and how Vitest is configured for the CLI package
- Building/linking the Rust native core used by
@sintesi/core - Running the CLI locally during development
Follow the short step-by-step procedures below to get a working development environment quickly.
Quick start — clone and install
Run these commands from your terminal:
git clone https://github.com/doctypedev/doctype.git
cd doctype
pnpm installpnpm install will set up workspace symlinks and install dependencies for all packages.
Build the monorepo
The canonical root build command is:
pnpm -r buildThis runs every package's build script in the workspace recursively. The root package.json includes a helper script that, on success, prints the path to the built CLI entry file:
# Example output when build completes
✅ Build Completed. Run: /full/path/to/repo/packages/cli/dist/cli/src/index.jsIf you prefer to build a single package instead of the whole workspace, change into that package and run its build script (for example):
cd packages/cli
pnpm run buildBuilding and linking the Rust core
The monorepo uses a Rust core (located in crates/core) exposed to Node via N-API. The TypeScript wrapper in packages/core expects the native bindings to be available (the workspace links native platform packages under crates/core/npm/*).
Local development workflow (two-step):
- Build the Rust library:
cd crates/core
cargo build --release- Rebuild workspace packages and TypeScript wrappers so the CLI and
@sintesi/corecan consume the native artifacts:
# Back to repository root
cd ../..
pnpm -r buildImportant notes:
packages/clidepends on@sintesi/coreusing a workspace link (workspace:*), so rebuilding the workspace picks up the locally builtpackages/corewrapper.- The workspace lockfile contains optional links for native packages (e.g.,
@sintesi/core-darwin-arm64) — CI normally handles publishing platform-specific packages.
Running the CLI locally
After a successful workspace build you can run the compiled CLI entry directly with Node:
# from repo root, after pnpm -r build
node packages/cli/dist/cli/src/index.jsAlternatively, if you want to run the TypeScript source during development, you can use tsx or ts-node if configured; for reliable results run the build and then node on the built file.
Tests — workspace and package level
Run all tests across the workspace:
pnpm -r testRun tests for the CLI package only (recommended while working on CLI code):
cd packages/cli
pnpm testImportant: the repository uses two related but different Vitest configurations. The workspace/root Vitest configuration maps @sintesi/core to the TypeScript source (packages/core/index.ts) so workspace-level tests run against the TS source. The CLI package's Vitest config (packages/cli/vitest.config.ts) maps @sintesi/core to the built wrapper (../core/dist/index.js) so CLI tests run against the compiled TypeScript wrapper. Keep this separation in mind when running or authoring tests.
The file packages/cli/vitest.config.ts contains key test-time settings that matter for development:
environment: 'node'— tests run in a Node environment.include: ['__tests__/**/*.{test,spec}.ts']— default pattern for test files.pool: 'forks'— Vitest usesforks(processes) instead ofthreadsto supportprocess.chdir()and other process-level behaviors in tests.resolve.aliasmaps@sintesi/coreto../core/dist/index.jsso tests in the CLI package import the builtpackages/corewrapper instead of relying on runtime resolution of native packages.
Example: run Vitest directly (from packages/cli):
pnpm exec vitest
# or for a single test file
pnpm exec vitest __tests__/check.test.tsTest authoring tips (how tests in the repo behave)
The tests use these common techniques (see packages/cli/__tests__/check.test.ts):
- Mocking Node built-ins like
fsandchild_processwithvi.mock(...)— declare each module mock once per test file to avoid duplicated mocks. - The
vitestconfig usespool: 'forks'to avoid issues when tests callprocess.chdir()or rely on process isolation. - Aliasing
@sintesi/coretocore/dist/index.jsin the CLI package ensures those package-specific tests run against the compiled TypeScript wrapper; workspace/root tests use the TS source instead.
CLI flags (common options referenced in tests & changelog)
The table below documents flags that appear in tests and changelogs. Use these flags when running sintesi CLI commands (for example sintesi check).
| Flag | Type | Description | Default |
|---|---|---|---|
--base <branch> | string | Base branch used for git diff / incremental checks | (not fixed in tests; commonly main) |
--smart | boolean | Enable the smart drift check (incremental AI-driven check) | true by default (the CLI will run smart checks if available) |
--verbose | boolean | Enable verbose logging for debugging | false |
--force | boolean | Force generation / bypass incremental checks and state validation | false |
--prune | boolean | For fix commands: remove dead documentation entries | false |
Use
--no-<flag>counterpart when you need to explicitly disable boolean flags (Yargs-style implicit negation).
Common workflows
Rebuild everything and run the CLI
pnpm -r build
node packages/cli/dist/cli/src/index.jsIterate on CLI code and run unit tests for a single file
# edit sources in packages/cli/src
cd packages/cli
pnpm run build
pnpm exec vitest __tests__/check.test.tsAdd changes to Rust core and test them in the CLI
# 1) Build Rust core
cd crates/core
cargo build --release
# 2) Build TS wrappers and CLI
cd ../..
pnpm -r build
# 3) Run CLI or tests
node packages/cli/dist/cli/src/index.js
# or
cd packages/cli
pnpm testTroubleshooting
- If tests fail because native bindings cannot be found, ensure
packages/core/dist/index.jsexists and the Rust native binary is present incrates/core/npm/{platform}when required. - If
pnpmerrors due to version mismatch, use thepnpmversion recorded inpackageManagerat the repo root:pnpm@8.15.5. - For CI reproduction, prefer the workspace-wide commands
pnpm -r buildandpnpm -r testto guarantee the same order and resolution as local runs.
Development flow diagram
Further reading
- Rust core README:
crates/core/README.md— contains notes about building the native package and platform packaging. - Package linking: look at
pnpm-lock.yamlandpackages/core/index.tsto understand how native exports are re-exported through the TypeScript wrapper.