Skip to content

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/.

Terminal window
npm install # installs every workspace
npm run build # builds all of them
npm test # vitest across all of them

Build order matters and is already pinned in the root script: core-edgeprotocolotelconnector-sdkdemoconnectors → the rest. The workspaces build is not topological, so without that pre-build the runner’s dist/ can’t resolve the @rootpilot/* packages.

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.

  • ESM + NodeNext. "type": "module", and every relative import carries the .js extension.
  • Honest dependencies. Each package declares only what it imports; zod is a peer dependency only where it is actually used.
  • Tests. vitest everywhere. In migrated packages, tests are colocated under src/**/__tests__/*.test.ts to minimize churn, a conscious divergence from the tests/ convention used by native packages.
Terminal window
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:

  1. build: npm ci && npm run build.
  2. prune: npm ci --omit=dev, which preserves workspace symlinks and drops the build toolchain.
  3. runtime: copies only dist/, the package.json files, and production dependencies.

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.