- Node
22.21.0(pinned in.node-version) or Node 24 LTS. The engine range is>=22.21.0 <23 || >=24.0.0 <25; CI stays pinned to Node 22 for reproducibility. - pnpm
9.0.0via corepack (packageManagerfield). Run commands ascorepack pnpm <command>so the pinned version is used.
corepack pnpm install # install dependencies
corepack pnpm check:source-artifacts # fail if generated files sit under src/
corepack pnpm typecheck # tsc -b across the workspace
corepack pnpm test # clean-compile + run all tests
corepack pnpm test:coverage # same, with Node coverage thresholds
corepack pnpm test:desktop # desktop routing and workflow contracts
corepack pnpm test:desktop-browser # real headless Chrome/Edge route smoke after build
corepack pnpm test:live-provider # opt-in check against a configured provider
corepack pnpm build # TypeScript build + desktop web build
corepack pnpm check:bundle-size # enforce startup and lazy-chunk size budgets
corepack pnpm build:desktop # packaged native desktop executable
corepack pnpm test owns test compilation: it cleans TypeScript output,
force-rebuilds, then runs scripts/run-tests.mjs. The runner discovers
src/**/*.test.ts(x) as the source of truth and fails when zero tests are
found, when an expected compiled test is missing, or when stale compiled
tests have no source counterpart. Do not bypass it with ad-hoc node --test
invocations for CI-relevant validation.
srcdirectories contain authored TypeScript/TSX and reviewed assets only.- Compiler output (
.js,.d.ts,.mapand variants) is emitted only to ignoreddistdirectories and is never committed or hand-edited. - A
.jsimport specifier inside TypeScript source does not imply a committed.jsfile; it resolves at build time. - Never invoke
tscwith positional file arguments such astsc packages/core/src/index.ts— that bypasses project output settings and writes JavaScript next to the source. Usecorepack pnpm typecheck,corepack pnpm build, orcorepack pnpm --filter <pkg> build. - Run
corepack pnpm check:source-artifactsbefore committing. CI runs it before and after builds. - A genuinely handwritten declaration file requires an exact-path allowlist
entry in
scripts/lib/artifact-scan.mjswith a rationale and owner; never allowlist an extension or directory wholesale.
A checkout shared between Windows and WSL must install dependencies in the
same OS that runs Vite/Rollup/esbuild — optional native packages are
platform-specific. If the repo lives on the Windows filesystem, run installs,
typecheck, tests, and builds from Windows. Plain node:test suites work in
either OS, but do not mix node_modules between them.
- Backend tests use
node:test+node:assert/strict, live next to the code assrc/**/*.test.ts, and run compiled fromdist. - The desktop workspace is
noEmit. Pure routing and workflow contracts run throughtest:desktop; the built app shell runs through a real Chromium browser withtest:desktop-browser. - Filesystem tests must create their own temp roots under
os.tmpdir()and clean up after themselves.