Development — build, test, run
Canonical Octonode repository documentation.
Development — build, test, run
Build & test (Node ≥ 24, Yarn 4)
yarn install # workspace links + deps
yarn build # tsc -b across all packages (project references; only changed pkgs recompile)
yarn rebuild # tsc -b --clean && tsc -b (when references get stale)
yarn test # vitest run
yarn test:watch # vitest (watch mode)- The engine is TypeScript on Node ≥ 24. This repo runs Node 24, which cannot execute
.tsdirectly — for the runtime/CLI always run from built JS (packages/*/dist), not source. - Run the CLI from the build:
node packages/cli/dist/index.js <command>. - Tests run on Vitest.
vitest.config.tsaliases each@octonode/*package to itssrc/index.tsand transpiles on the fly, so unit tests need noyarn buildand import source directly. Addtests/*.test.tsthatimportfrom@octonode/*. Tests that spawn a process (such as MCP and CLI subprocess tests) still launch builtdistbinaries — keep thosedistpaths, andyarn buildbefore running them.
Running the app (server + Studio)
Two processes. The server owns the engine; Studio is a Vite client that proxies to it.
yarn build # build packages first
# 1. API + SSE server on :4000 (point it at a demo project)
node packages/cli/dist/index.js serve --config examples/workflows-demo/.octonode.yaml
# 2. Studio dev server on :5173 (proxies /api and /ws → localhost:4000)
yarn workspace @octonode/studio devOpen http://localhost:5173. If apps/studio/dist exists, octonode serve will also serve the
built UI from its own origin on :4000 (single-origin production mode). API reference: Swagger
UI at http://localhost:4000/api/docs.
The repository-owned Playbook can run locally through the OpenNext Cloudflare adapter or deploy
to the Worker configured in apps/playbook/wrangler.jsonc:
yarn workspace @octonode/playbook preview
yarn workspace @octonode/playbook deployThe private coding-assistant process is separate and is never called by Studio directly:
export OPENAI_API_KEY="..."
export OCTONODE_CHAT_MODEL="..."
export OCTONODE_CHAT_SERVICE_TOKEN="..."
export OCTONODE_API_URL="http://127.0.0.1:4000"
yarn workspace @octonode/chat-service startIt binds to 127.0.0.1:4101 by default. /v1/runs accepts only the server-to-service bearer plus
a separate project-scoped caller token, rejects browser origins, and streams normalized NDJSON.
Readiness performs an Octonode MCP tool/resource handshake without calling OpenAI.
Configure the Cloudflare backend with OCTONODE_CHAT_SERVICE_URL and the same
OCTONODE_CHAT_SERVICE_TOKEN; neither value is exposed to Studio.
Node process execution is a trusted local-profile capability. A production server accepts
authenticated API traffic but rejects node invocation, workflow runs, and native materialization
with 503 rather than launching a host child process. Deploy runnable production workflows only
through a sandbox-backed worker.
Before opening a PR
yarn buildis clean.yarn testpasses — add tests for new behavior.node packages/cli/dist/index.js scan --check --config <touched example>passes (CI drift gate).- If you touched the IPC contract or config shape, update
docs/andoctonode.schema.json. - If you changed a server route's request/response shape, regenerate the client
(
yarn workspace @octonode/studio openapi) and commitapps/studio/openapi.json+apps/studio/src/api/gen/. See api-codegen.md. - If you added or changed a Studio component, it has a
*.stories.tsxandyarn workspace @octonode/studio build-storybookis clean.
Deployment validation, canary promotion, release evidence, and rollback follow the release contract.
Quick smoke test
CLI="node packages/cli/dist/index.js"
CFG="--config examples/workflows-demo/.octonode.yaml"
$CLI scan $CFG
$CLI run etl $CFG # TypeScript workflow ⇒ {"load":{"loaded":2}}
$CLI run fan-out-fan-in --input '{"n":5}' $CFG # parallel branches ⇒ {"combine":{"sum":25}}