Building from source
The repository is an npm workspaces monorepo. There are no TypeScript project references and no
bundler: each package compiles with tsc and publishes dist/.
npm install # installs every workspacenpm run build # builds all of themnpm test # vitest across all of themBuild order matters and is already pinned in the root script: core-edge → protocol → otel →
connector-sdk → demo → connectors → the rest. The workspaces build is not topological, so
without that pre-build the runner’s dist/ can’t resolve the @rootpilot/* packages.
The two TypeScript profiles
Section titled “The two TypeScript profiles”Not every package compiles under the same flags, and that is deliberate.
| Profile | Packages | Flags |
|---|---|---|
tsconfig.base.json |
protocol, otel, connector-sdk, runner |
Full strict: noUncheckedIndexedAccess, exactOptionalPropertyTypes, verbatimModuleSyntax, isolatedModules. |
tsconfig.migrated.json |
connectors, core-edge |
The same, but with noUncheckedIndexedAccess and exactOptionalPropertyTypes off. |
The second profile exists because those packages came from a monolith written with only
strict: true. Turning both flags on would generate thousands of risky ! assertions over
already-tested code, for close to zero gain. Ratcheting up to full strict is future hardening, not
forgotten debt.
Conventions the build assumes
Section titled “Conventions the build assumes”- ESM + NodeNext.
"type": "module", and every relative import carries the.jsextension. - Honest dependencies. Each package declares only what it imports;
zodis a peer dependency only where it is actually used. - Tests.
vitesteverywhere. In migrated packages, tests are colocated undersrc/**/__tests__/*.test.tsto minimize churn, a conscious divergence from thetests/convention used by native packages.
The runner image
Section titled “The runner image”docker build -f apps/runner/Dockerfile -t rootpilot-runner .The build context is the repository root, not apps/runner: the runner depends on sibling
workspaces.
The image has three stages, and the third is the one that matters to you:
- build:
npm ci && npm run build. - prune:
npm ci --omit=dev, which preserves workspace symlinks and drops the build toolchain. - runtime: copies only
dist/, thepackage.jsonfiles, and production dependencies.
Publishing
Section titled “Publishing”The @rootpilot/* packages are semver-versioned with backward compatibility, which is critical for a
cattle fleet, where runners of different versions coexist. publishConfig.access is public.