Sandbox
@enmanuelmag/agent-harness-kit

Multi-agent workflow harness for Claude Code and Codex

This kit scaffolds a structured workflow for AI agents in your repository. It creates task backlogs, role-based agent files, a health check, and a local log so each action is recorded and repeatable. It works through the `ahk` CLI and a local MCP server, and it can generate provider-specific setup for Claude Code, Codex, OpenCode, and other MCP tools. The database stays local by default, with a dashboard for viewing tasks, actions, and file activity.

181 stars9 forksTypeScriptUpdated 10d ago
Who it's for

Builders who want their agent work to stay coordinated, auditable, and tied to a task backlog.

What it delivers

You can run multi-agent work with shared context, role boundaries, and a visible audit trail instead of ad hoc chat sessions.

What it does

Structured five-agent workflow

Defines Lead, Explorer, Consultant, Builder, and Reviewer roles with separate responsibilities.

Atomic task claiming

Lets agents claim tasks in SQLite so two agents do not pick up the same work at once.

Persistent action log

Records actions, files touched, tools used, blockers, and results in the harness database.

Health gate before work starts

Runs `health.sh` and requires a green exit before agents can begin or close tasks.

Provider-agnostic MCP setup

Generates launch config for Claude Code, Codex CLI, OpenCode, Grok Build, and other MCP-compatible tools.

Local dashboard

Provides a web UI for tasks, agent actions, file operations, and live timelines.

Docs search and spec flow

Adds docs search and spec-oriented commands for turning conversations into markdown specs.

How to get it

  1. 1Run
    # Install in your project as a dev dependency (recommended)
    npm install --save-dev @cardor/agent-harness-kit
  2. 2Then run the interactive setup inside your project
    npx ahk init

README

@cardor/agent-harness-kit

A provider-agnostic scaffolding kit for running structured multi-agent workflows in your codebase.

npm version npm downloads license Known Vulnerabilities

Instead of letting AI agents roam freely through your project with no memory, no coordination, and no audit trail, agent-harness-kit gives them a shared structure: a task backlog, a defined workflow, a persistent log of every action taken, and a health gate that must be green before any work begins.

You stay in control. The agents stay on track.

Visit the website to view a full explanation, examples, and other tools!

Buy Me a Coffee at ko-fi.com

npx ahk init

Table of Contents


Why this exists

If you don't know what is Agent Harness, you can check this blog post: Introducing Agent Harness.

Most AI coding tools give you a single agent with a chat window. That works for small tasks. It breaks down when:

  • You want multiple specialized agents working in sequence (plan → explore → build → review)
  • You need to track what changed, what was tried, and what was blocked — across sessions
  • You switch between AI providers (Claude Code today, OpenCode tomorrow) and don't want to re-setup everything
  • You want a health check that agents must pass before touching code

agent-harness-kit solves all of this with a thin layer of scaffolding and a local MCP server that any MCP-compatible AI tool can connect to.


How it works

ahk init
  └── creates config, agent definitions, task backlog, health check

AI tool opens your project
  └── reads .claude/mcp.json, opencode.json, .codex/config.toml, or .grok/config.toml
  └── spawns: ahk serve (stdio MCP server)
      via your package manager (npx/pnpm exec/yarn run/bunx) when the
      package is a local dependency, or the bare binary when it isn't

Agent starts working
  └── tasks.get()         → picks a task from the backlog
  └── tasks.claim(id)     → atomically claims it (no double-work)
  └── actions.start()     → registers its action
  └── actions.write()     → logs sections: result, files, blockers…
  └── actions.complete()  → closes the action

Lead → Explorer → Consultant → Builder → Reviewer
  └── each role has its own agent definition with clear responsibilities
  └── the harness DB records the full history

Everything is stored locally in a SQLite database (.harness/harness.db). No cloud, no external services, no API keys required beyond what your AI tool already uses.


Features

  • Provider-agnostic — works with Claude Code, OpenCode, Codex CLI, Grok Build, or any MCP-compatible AI tool. Switch providers without losing your task history or reconfiguring your workflow.

Note: "Grok Build" here refers to xAI's official Grok Build CLI (provider: 'grok-cli') — it is unrelated to the unofficial, community-maintained grok-cli/grok-dev npm packages.

  • Structured 5-agent workflow — Lead, Explorer, Consultant, Builder, and Reviewer each have defined responsibilities and can only act within their role.
  • Atomic task claiming — agents use tasks.claim() which uses a SQLite transaction to prevent two agents from picking up the same task at the same time.
  • Full audit trail — every action, file touched, tool used, and section written is stored in SQLite and queryable.
  • Health gate — agents must run health.sh and get a green exit before starting or closing any task. You define what "healthy" means.
  • Docs search — agents can call docs.search(query) to find relevant content in your project's docs folder before writing code.
  • Specification discoveryahk-use-cases turns an agreed product conversation into an iterative, non-technical Markdown spec in docs/specs/; ahk-use-case-tech creates a linked technical spec only after the source use case is approved.
  • Multi-database support — SQLite by default (uses better-sqlite3 on Node ≥ 22 or bun:sqlite on Bun). Switch to PostgreSQL or MySQL with a single config line — same schema, same MCP tools, same workflow.
  • Global installationahk init can scaffold the harness into your home directory (~/.claude or ~/.config/opencode) to share it across all projects.
  • Input validation — CLI prompts validate all inputs (name length, path format, task title, etc.) and retry with the error message instead of silently accepting bad values.

Requirements

  • Node.js ≥ 22.5 or Bun (any recent version)
  • npm ≥ 9

Installation

# Install in your project as a dev dependency (recommended)
npm install --save-dev @cardor/agent-harness-kit

Then run the interactive setup inside your project:

npx ahk init

The config file format depends on whether the package is installed locally. ahk init checks that first, before anything else:

Local installGenerated configWhy
Not installed (global-only CLI)agent-harness-kit.config.jsonYour project cannot resolve @cardor/agent-harness-kit, so a TypeScript config's import type would red-underline in your editor and fail tsc --noEmit on a package that isn't there. JSON has no imports and no types — nothing to resolve, zero editor errors.
Installed (npm install --save-dev @cardor/agent-harness-kit).ts, .mjs or .cjsThe package resolves, so you get the full typed config with editor autocompletion. Which of the three is picked is unchanged: .ts when a tsconfig.json is present, otherwise .mjs/.cjs based on package.json type.

The trade-off is autocompletion: a JSON config has no type information behind it, so your editor cannot suggest fields. Installing the package locally and switching to a .ts config gets that back. There is no $schema key in the generated JSON — no JSON Schema for HarnessConfig is published yet, and pointing at a URL that doesn't resolve would only swap a type error for a fetch error.

Existing projects are never converted. If a config of any extension already exists, it keeps working and keeps its format — installing or removing the package locally will not silently rewrite it. loadConfig() reads all five formats, and ahk init stops when it finds any of them.

A local install is still recommended even though it is no longer required: it pins the CLI version so behavior stays reproducible across your team and CI instead of drifting with whatever is installed globally on each machine. On a global-only install ahk prints a non-blocking warning suggesting it — the command runs and exits normally either way.

This check also works with Yarn Berry (PnP) projects, which never create a node_modules folder — ahk detects .pnp.cjs/.pnp.loader.mjs and falls back to checking that the package is declared in package.json instead of requiring a node_modules entry.


MCP command per package manager

ahk init and ahk build detect which package manager your project uses and generate the MCP server launch command (.mcp.json, opencode.json, .codex/config.toml, or .grok/config.toml) accordingly, instead of hardcoding npx:

Package managerDetected viaGenerated command
npmpackageManager field, package-lock.json, or fallbacknpx --no ahk serve --port <port>
pnpmpackageManager field or pnpm-lock.yamlpnpm exec ahk serve --port <port>
yarn classic (v1)packageManager field (major 1) or yarn.lock without .yarnrc.ymlyarn run ahk serve --port <port>
yarn berry (v2+, PnP or node-modules)packageManager field (major ≥ 2) or yarn.lock + .yarnrc.ymlyarn run ahk serve --port <port>
bunpackageManager field or bun.lockb/bun.lockbunx --no-install ahk serve --port <port>
any — no local install@cardor/agent-harness-kit is not a dependency of your projectahk serve --port <port>

Detection order: the packageManager field in your package.json (e.g. "packageManager": "pnpm@8.15.0") takes priority when present; otherwise ahk falls back to lockfile heuristics; if nothing is detected, it defaults to npm.

Global installs bypass the package manager entirely. Every command in the table above asks your package manager to resolve a locally installed ahk binary — npx --no deliberately refuses to download one, and pnpm exec/yarn run/bunx --no-install have nothing to point at. If you installed the CLI globally and never added it to the project, all five of those commands fail. So ahk checks for a real local install first and, when there is none, generates the bare ahk serve --port <port> — resolved from your PATH like any other global binary. The package-manager-specific commands are used only when a local install actually exists. If, on that global-install path, ahk is not resolvable on your PATH at generation time, ahk prints a non-blocking warning (the command still succeeds) pointing you at npm i -g @cardor/agent-harness-kit or a local install — moving the "binary not found" failure earlier instead of surfacing it later when the MCP server is spawned.

Working inside the agent-harness-kit repository itself does not count as a local install for this decision: there is no real node_modules/@cardor/agent-harness-kit entry for a package manager to resolve, so self-dev generates the bare global ahk serve --port <port> form, same as any other project with no local install. This is a narrower check than the one deciding your config file format, above (ahk init's .ts/.mjs/.cjs vs. .json choice) — that check still treats self-dev as satisfied, since it only cares whether the package is resolvable for type-checking purposes, not whether a package manager can mediate a spawned command.

Existing projects: if you initialized your project before this change, your .mcp.json/opencode.json/.codex/config.toml/.grok/config.toml may still have a hardcoded npx command. No migration step is needed — ahk build always regenerates (merges) these files from scratch on every run, so the command self-corrects the next time you run ahk build (or ahk build --sync), including if you've since switched package managers.


Commands

ahk init

Interactive scaffold. Asks for your project name, description, AI provider, docs path, storage scope, task adapter, and an optional first task. Creates all harness files in the current directory.

Claude Code only, init asks you to pick a model for each of the 5 core roles (lead, explorer, consultant, builder, reviewer) one at a time: inherit (default), haiku, sonnet, opus, or fable. Each choice is written straight into that role's generated .claude/agents/<role>.md frontmatter as a model: line at scaffold time — it is never persisted to the config file. Picking inherit (the default) emits no model: line at all, leaving Claude Code to apply its own default. Agent files are user-owned once generated (see Agent files are yours below), so after init the model can be changed three ways: hand-editing the model: frontmatter line directly, running ahk models to re-prompt and regenerate just the 5 agent files, or running ahk build --force (which re-prompts too, then regenerates everything --force regenerates).

Codex CLI only, init asks you to pick a model and a reasoning effort for each of the 5 core roles, one role at a time: model choices are gpt-6-astra, gpt-5.6-sol, gpt-5.6-terra (default), gpt-5.6-luna, gpt-5.5, gpt-5.4, gpt-5.4-mini, gpt-5.3-codex-spark; effort choices are minimal, low, medium (default), high, xhigh. Not every model supports every effort level — Codex applies its own per-model behavior for an unsupported combination, so pick deliberately rather than assuming universal compatibility. Both choices are written straight into that role's generated .codex/agents/<role>.toml as model = "..." / model_reasoning_effort = "..." lines at scaffold time — never persisted to config.toml. Agent files are user-owned once generated, so after init the model/effort can only be changed by hand-editing the TOML directly (there is no Codex equivalent of ahk models yet) or running ahk build --force (which re-prompts, then regenerates everything --force regenerates).

Separately, .codex/config.toml always gets a project-wide top-level default — model = "gpt-5.6-terra" and model_reasoning_effort = "medium" — written once and preserved across every subsequent ahk build/ahk init --force: if you hand-edit either value in config.toml, your edit is never overwritten. Per-role model/model_reasoning_effort lines in .codex/agents/<role>.toml (above) act as overrides of this baseline for that one role.

OpenCode and Grok Build are unaffected by either prompt — it never appears for those providers, since neither has a closed model enum to prompt against.

  • local (default) — .harness/harness.db, inside the project.
  • global~/.harness/dbs/<projectId>/harness.db, outside the project tree (useful to keep the DB out of version control entirely, or to centralize storage for many projects). <projectId> is a UUID generated once at init and persisted in agent-harness-kit.config.ts — it's never regenerated on subsequent runs.

Regardless of scope, .harness/storage-state.json is always written to the project — it records the actual current storage state (scope, projectId, dbType, migratedAt), separate from the desired state declared in the config file.

Agent and skill files always live in the project tree, regardless of storage scope — --storage-scope only affects where the harness DB lives.

ahk init

# Skip prompts with flags
ahk init --name "my-app" --provider claude-code --docs ./docs --tasks local --storage-scope local
ahk init --name "my-app" --provider codex-cli   --docs ./docs --tasks local --storage-scope global
ahk init --name "my-app" --provider grok-cli    --docs ./docs --tasks local --storage-scope local

Run this once per project. If the project is already initialized, the command prints an 'already initialized' message with suggested next-step commands (ahk build, ahk build --sync, ahk reset, ahk serve) and exits without overwriting anything.

The config file extension is chosen automatically: .ts if a tsconfig.json is present, .mjs for ESM-only projects ("type": "module" in package.json), or .mjs otherwise.


ahk build

Regenerates AGENTS.md and provider-specific files from your agent-harness-kit.config.ts. Use this after changing config values.

ahk build
ahk build --watch    # watch mode: rebuilds automatically on config changes
ahk build --force    # DESTRUCTIVE: regenerate agent files, discarding your edits
ahk build --sync     # kept for backwards compatibility — now a no-op on every provider

Agent files are yours

ahk build creates agent files that are missing and never modifies ones that already exist. Edit .claude/agents/<role>.md (or .opencode/agents/<role>.md, .codex/agents/<role>.toml, or .grok/agents/<role>.md) freely — change the role prompt, set a model: line, adjust the restriction fields. Rebuilding will not revert your work. ahk doctor does not report hand-edited files either; it checks existence only.

Everything else build writes — MCP config and skills — is derived from your config and is regenerated on every run.

AGENTS.md and CLAUDE.md — derived, but your edits are safe

AGENTS.md (all providers) and CLAUDE.md (Claude Code only) are generated from your config, so a config change should flow into them — but they are also files people hand-edit. build reconciles both concerns with a provenance marker: every generated file ends with a comment holding a checksum of the exact bytes we wrote, e.g.

<!-- ahk:generated 3f7a…c1 -->

On each build the marker lets build tell its own untouched output apart from a human edit, byte-for-byte:

  • Untouched since we wrote it, config changed → the file is regenerated so your config propagates. No prompt, no backup — it was provably our own output.
  • Already up to date → no-op.
  • You edited the body (the checksum no longer matches) or the file has no marker (written by an older version, e.g. a CLAUDE.md you customized before upgrading) → left untouched, and build prints a loud notice naming the file and telling you to run --force if you actually want it regenerated.

Because the checksum is over the exact bytes, any change — even one space — counts as an edit and is preserved. The behavior is identical with or without a terminal (there is no prompt), so it is safe in scripts and CI. Leave the marker comment in place; deleting it just makes build treat the file as hand-edited (preserve it) on the next run.

If you use OpenCode or Codex CLI, your agent files may be out of date right now. Those two providers have always preserved existing agent files on build, which means they have never picked up template improvements shipped in newer versions of this package. Claude Code, by contrast, used to overwrite them on every build — that inconsistency was a bug, and it is now fixed in favour of preserving your edits. To pull in the current templates, run ahk build --force (read the warning below first).

--force

Because build no longer overwrites agent files on any provider, --force is the only way to regenerate them from the packaged templates. It is destructive:

ahk build --force
  • It discards your customizations. Every agent file is rewritten from the template. Prompt edits, model: lines, and restriction tweaks are all lost.
  • It backs up first. Before overwriting anything, the current content of every affected file is copied under .harness/backups/ — agent files to agents-<timestamp>/, hand-edited AGENTS.md/CLAUDE.md to derived-<timestamp>/. If that backup cannot be written, the command aborts and no file is modified — the same fail-safe as ahk migrate storage --force.
  • It names what it touched. The command prints every file it overwrote and the backup location, so you can diff or restore.
  • Claude Code and Codex CLI also re-prompt for models. Before regenerating, ahk build --force runs the same per-role prompt as ahk init for the current provider — the model prompt on Claude Code, or the model and reasoning-effort prompt on Codex CLI (see above) — and injects the fresh choices into the regenerated frontmatter/TOML. Codex proposes gpt-5.6-terra/medium for lead, consultant, builder, and reviewer, and gpt-5.6-luna/medium for explorer; accepting those defaults writes them into the regenerated TOMLs. OpenCode and Grok Build are unaffected — no prompt appears for them, since neither has a closed model enum to prompt against.

--force also regenerates a hand-edited AGENTS.md or CLAUDE.md (backing it up first) — the only time you need it for those files, since an unedited one already re-generates on its own when config changes.

--watch never forces, even if you pass both flags: an automatic rebuild triggered by a file change must not destroy your edits in the background.

--sync used to rewrite the tools: frontmatter of agent files so it matched a canonical allowlist. Agent files no longer declare an allowlist at all — they inherit every tool and declare only restrictions — so there is nothing left to synchronise. Use ahk build --force to regenerate agent files.


ahk models

Claude Code only. Re-runs ahk init's per-role model prompt and regenerates ONLY the 5 .claude/agents/*.md files with the chosen models — nothing else (not AGENTS.md, CLAUDE.md, .mcp.json, .claude/settings.json, your config file, docs path, storage scope, or task adapter).

ahk models
  • Prompts once per role (lead, explorer, consultant, builder, reviewer): inherit (default), haiku, sonnet, opus, or fable — same prompt as ahk init.
  • Always regenerates all 5 agent files, backing up the previous content first under .harness/backups/agents-<timestamp>/ — the same fail-safe --force uses.
  • On a non-Claude-Code project, it prints a one-line no-op message and exits — no prompt.
  • If no agent-harness-kit.config is found, it prints a message pointing at ahk init and exits — no prompt, no stack trace.

ahk dashboard

Opens a local web dashboard to visualize everything stored in the harness database — tasks, agent actions, file operations, tool usage, and live timelines. Updates in real time via WebSocket as agents work.

ahk dashboard                  # opens http://localhost:4242 in your browser
ahk dashboard --port 8080      # custom port
ahk dashboard --no-open        # start server without opening browser

--port must be an integer between 1 and 65535; an invalid value (e.g. ahk dashboard --port abc or `--p

Files in the repo

Repository payload30 top-level entries
  • .agents
  • .codex
  • .github
  • .husky
  • .opencode
  • assets
  • bin
  • dashboard
  • docs
  • scripts
  • src
  • .gitignore
  • .npmrc
  • .prettierignore
  • .prettierrc
  • agent-harness-kit.config.ts
  • AGENTS.md
  • commitlint.config.js
  • eslint.config.js
  • health.sh
  • LICENSE
  • opencode.json
  • package.json
  • pnpm-lock.yaml
  • pnpm-workspace.yaml
  • README.md
  • SECURITY.md
  • skills-lock.json
  • tsconfig.json
  • tsup.config.ts

Discussion (0)

Ask about usage, or say what you built with it

Sign in to join the discussion.

No comments yet. Be the first to say what this is good for.

More harnesses

affaan-m/
ECC
affaan-m/ECCHarnesses

The agent harness performance optimization system. Skills, instincts, memory, security, and research-first development for Claude Code, Codex, Opencode, Cursor and beyond.

258k
ruvnet/rufloHarnesses

🌊 The original agent meta-harness. Deploy intelligent multi-player swarms, coordinate autonomous workflows, and build conversational AI systems. Features adaptive memory, self-learning intelligence, RAG integration, and native Claude Code / Codex / Hermes and many more Integrated

72k

Practical patterns, starters & CLI tools for loop engineering with AI coding agents. Design systems that prompt and orchestrate agents (inspired by Addy Osmani and Boris Cherny). Includes loop-audit, loop-init, loop-cost.

11k