Development setup
The SDK is a single npm package (Node ≥ 22, ESM only). Clone the repo and install:
git clone https://github.com/archmax-ai/harness.gitcd harnessnpm installcp .env.example .env # fill in an OpenAI-compatible endpoint + keyEveryday commands
Section titled “Everyday commands”npm run dev # run the CLI from source via tsx (src/cli.ts)npm run build # clean + tsc + copy assets; emits dist/npm start # run the compiled CLI (node dist/cli.js)npm run typecheck # tsc --noEmit over everything INCLUDING testsnpm test # vitest run — colocated *.test.ts unit testsnpm run test:watch # vitest watchnpm run docs:build # build the docs sitenpx openspec validate --specs # validate the specs under openspec/specsRun the bundled example from source:
npm run dev -- run order-lookup "Which orders are delayed for Acme?" --root examples/customer-supportnpm run dev -- test order-lookup --root examples/customer-supportnpm run dev -- validate order-lookup --root examples/customer-supportUnit tests
Section titled “Unit tests”Unit tests are colocated with the code they cover: src/**/foo.ts +
src/**/foo.test.ts. src/behaviour/ drives the public barrel end to end with
a scripted fake model:
npx vitest run src/machine/allow.test.ts # one filenpx vitest run -t "resolves transition" # by test-name substringA workflow’s cases are a separate thing:
declarative YAML documents, interpreted host-side by archmax test.
Repository layout
Section titled “Repository layout”src/is the runtime (library). It holdsassembly/(createAgent),machine/(the schema and the compiled machine),validate/,workflow/(governance middleware, parks, control tools),kernel/,sandbox/,lifecycle/,rubrics/,sessions/,testing/(the case engine),cli/,core/,public/(thesandbox,testingandclisubpaths),behaviour/,env.ts,index.ts.core/platform-prompt.mdis the platform prompt, the graph-state execution model merged into every governed agent’s system prompt.npm run buildgeneratescore/platform-prompt.generated.tsfrom it, so it ships inside the code; edit the Markdown and runnpm run generate:prompt(a unit test fails while the two differ). A passage between<!-- top-level-only -->and<!-- /top-level-only -->lines is left out of a sub-workflow child’s prompt; the marker lines reach no model.skills/archmax-harness/is the authoring skill, shipped asdist/authoring-skill/archmax-harness.npx skills add archmax-ai/harnessdiscovers it as the repo’s only public skill: the contributor skills under.claude/skills/carrymetadata.internal: trueso the skills CLI hides them. Keep that flag whenopenspec updateregenerates them.examples/customer-support/is the reference workspace.docs/is this documentation site (Astro + Starlight), self-contained with its ownpackage.json. Build it withnpm run docs:buildfrom the repo root.openspec/holds change proposals and specs; see the OpenSpec workflow.
Documentation ships with features
Section titled “Documentation ships with features”User-facing behavior covers the CLI, configuration, the authoring model, the
skills or workflow schema, and the public API. Any change affecting it must
update the relevant pages under docs/ in the same change. This convention is
encoded in openspec/config.yaml and surfaced when authoring proposals and task
lists.
Releasing
Section titled “Releasing”Releases are cut by merging a labelled PR into main. The label picks the bump:
release for a patch, release:minor or release:major. On merge,
.github/workflows/release.yml re-runs the checks, tags vX.Y.Z, creates the
GitHub Release with generated notes, and publishes that version to npm with
provenance. The first release is v0.1.0.
The tag is the version. package.json on main is never bumped; the publish
job stamps the tag’s version into it before npm publish. A manual dispatch
(Actions → Release) takes a bump and defaults to a dry run that logs the next
version and changes nothing.
npm authenticates the workflow through
trusted publishing: the package’s
trusted publisher on npmjs.com names archmax-ai/harness and release.yml, and
the job’s GitHub OIDC token is exchanged for a short-lived publish credential.
There is no npm token to store or rotate. Publishing is switched on by the
NPM_PUBLISH repository variable (true); until then the workflow tags and
releases but only runs npm pack.