@cardor/agent-harness-kit 1.10.5 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +181 -52
- package/dist/agent-templates/builder.md +27 -23
- package/dist/agent-templates/consultant.md +0 -3
- package/dist/agent-templates/explorer.md +16 -14
- package/dist/agent-templates/lead.md +14 -11
- package/dist/agent-templates/reviewer.md +9 -8
- package/dist/{chunk-6PEIJ2D5.js → chunk-JTACLEGM.js} +45 -16
- package/dist/chunk-JTACLEGM.js.map +1 -0
- package/dist/{chunk-D64KK6UU.js → chunk-U3O77CGE.js} +38 -16
- package/dist/chunk-U3O77CGE.js.map +1 -0
- package/dist/chunk-URMVLD2S.js +147 -0
- package/dist/chunk-URMVLD2S.js.map +1 -0
- package/dist/cli.js +1138 -846
- package/dist/cli.js.map +1 -1
- package/dist/{db-3OXHRFAR.js → db-L3AADJF5.js} +4 -2
- package/dist/index.d.ts +2 -24
- package/dist/index.js +1 -1
- package/dist/{mysql-THKQOXIS.js → mysql-AUPKARWA.js} +11 -5
- package/dist/mysql-AUPKARWA.js.map +1 -0
- package/dist/{postgres-IOQE32DM.js → postgres-BB4GY4PN.js} +11 -5
- package/dist/postgres-BB4GY4PN.js.map +1 -0
- package/dist/{sqlite-TR4D324R.js → sqlite-5OWKTUUZ.js} +11 -5
- package/dist/sqlite-5OWKTUUZ.js.map +1 -0
- package/package.json +2 -1
- package/dist/chunk-6PEIJ2D5.js.map +0 -1
- package/dist/chunk-D64KK6UU.js.map +0 -1
- package/dist/mysql-THKQOXIS.js.map +0 -1
- package/dist/postgres-IOQE32DM.js.map +0 -1
- package/dist/sqlite-TR4D324R.js.map +0 -1
- /package/dist/{db-3OXHRFAR.js.map → db-L3AADJF5.js.map} +0 -0
package/README.md
CHANGED
|
@@ -50,7 +50,7 @@ npx ahk init
|
|
|
50
50
|
- [What each file does](#what-each-file-does)
|
|
51
51
|
- [Tasks schema](#tasks-schema)
|
|
52
52
|
- [What you can customize](#what-you-can-customize)
|
|
53
|
-
- [`agent-harness-kit.config.ts`](#agent-harness-
|
|
53
|
+
- [`agent-harness-kit.config.{json|ts|mjs|cjs}`](#agent-harness-kitconfigjsontsmjscjs)
|
|
54
54
|
- [`health.sh`](#healthsh)
|
|
55
55
|
- [Agent definition files](#agent-definition-files)
|
|
56
56
|
- [`.harness/feature_list.json`](#harnessfeature_listjson)
|
|
@@ -89,7 +89,9 @@ ahk init
|
|
|
89
89
|
|
|
90
90
|
AI tool opens your project
|
|
91
91
|
└── reads .claude/mcp.json, opencode.json, or .codex/config.toml
|
|
92
|
-
└── spawns:
|
|
92
|
+
└── spawns: ahk serve (stdio MCP server)
|
|
93
|
+
via your package manager (npx/pnpm exec/yarn run/bunx) when the
|
|
94
|
+
package is a local dependency, or the bare binary when it isn't
|
|
93
95
|
|
|
94
96
|
Agent starts working
|
|
95
97
|
└── tasks.get() → picks a task from the backlog
|
|
@@ -117,7 +119,7 @@ Everything is stored locally in a SQLite database (`.harness/harness.db`). No cl
|
|
|
117
119
|
- **Markdown fallback** — `current.md` is always regenerated so agents can understand the session state even without the MCP server.
|
|
118
120
|
- **Docs search** — agents can call `docs.search(query)` to find relevant content in your project's docs folder before writing code.
|
|
119
121
|
- **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.
|
|
120
|
-
- **Incremental scaffold** — `ahk init` preserves files you've already customized (agent definitions you've edited are kept). `ahk build`
|
|
122
|
+
- **Incremental scaffold** — `ahk init` preserves files you've already customized (agent definitions you've edited are kept). A hand-written `.harness/feature_list.json` backlog is **merged, never overwritten** — existing tasks survive and any first task you add during init is folded in (deduplicated by slug). `ahk build` also creates missing agent files and never touches existing ones. Use `ahk build --force` to regenerate them from the latest templates, discarding your edits (a backup is written first).
|
|
121
123
|
- **Global installation** — `ahk init` can scaffold the harness into your home directory (`~/.claude` or `~/.config/opencode`) to share it across all projects.
|
|
122
124
|
- **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.
|
|
123
125
|
|
|
@@ -143,7 +145,18 @@ Then run the interactive setup inside your project:
|
|
|
143
145
|
npx ahk init
|
|
144
146
|
```
|
|
145
147
|
|
|
146
|
-
> **
|
|
148
|
+
> **The config file format depends on whether the package is installed locally.** `ahk init` checks that first, before anything else:
|
|
149
|
+
>
|
|
150
|
+
> | Local install | Generated config | Why |
|
|
151
|
+
> | --- | --- | --- |
|
|
152
|
+
> | **Not installed** (global-only CLI) | `agent-harness-kit.config.json` | Your 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. |
|
|
153
|
+
> | **Installed** (`npm install --save-dev @cardor/agent-harness-kit`) | `.ts`, `.mjs` or `.cjs` | The 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`. |
|
|
154
|
+
>
|
|
155
|
+
> 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.
|
|
156
|
+
>
|
|
157
|
+
> **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.
|
|
158
|
+
>
|
|
159
|
+
> **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.
|
|
147
160
|
>
|
|
148
161
|
> 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.
|
|
149
162
|
|
|
@@ -160,9 +173,14 @@ npx ahk init
|
|
|
160
173
|
| yarn classic (v1) | `packageManager` field (major 1) or `yarn.lock` without `.yarnrc.yml` | `yarn run ahk serve --port <port>` |
|
|
161
174
|
| yarn berry (v2+, PnP or node-modules) | `packageManager` field (major ≥ 2) or `yarn.lock` + `.yarnrc.yml` | `yarn run ahk serve --port <port>` |
|
|
162
175
|
| bun | `packageManager` field or `bun.lockb`/`bun.lock` | `bunx --no-install ahk serve --port <port>` |
|
|
176
|
+
| **any — no local install** | `@cardor/agent-harness-kit` is not a dependency of your project | `ahk serve --port <port>` |
|
|
163
177
|
|
|
164
178
|
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.
|
|
165
179
|
|
|
180
|
+
**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 the local install first (the same check that decides your config file format, above) 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.
|
|
181
|
+
|
|
182
|
+
Working inside the `agent-harness-kit` repository itself counts as a local install: the package manager can resolve the workspace binary, so the `pnpm exec` form is generated rather than the bare one.
|
|
183
|
+
|
|
166
184
|
**Existing projects:** if you initialized your project before this change, your `.mcp.json`/`opencode.json`/`.codex/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.
|
|
167
185
|
|
|
168
186
|
---
|
|
@@ -173,10 +191,9 @@ Detection order: the `packageManager` field in your `package.json` (e.g. `"packa
|
|
|
173
191
|
|
|
174
192
|
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.
|
|
175
193
|
|
|
176
|
-
|
|
194
|
+
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. This prompt only runs during `ahk init`'s one-time scaffold, not on `ahk build` — agent files are user-owned once generated (see [Agent files are yours](#agent-files-are-yours) below), so after init the model is changed the same way as any other edit: hand-editing the `model:` frontmatter line directly.
|
|
177
195
|
|
|
178
|
-
|
|
179
|
-
- Codex CLI: free-text model name per agent — Codex does not validate this value; leaving it blank or under 3 characters means no override is written to that agent's TOML file.
|
|
196
|
+
OpenCode and Codex CLI are unaffected by this prompt — it never appears for those providers. OpenCode has no closed model enum to prompt against, and Codex's model is still set by hand-editing `model = "..."` in its TOML.
|
|
180
197
|
|
|
181
198
|
**Storage scope** — where the harness DB (and its `current.md` fallback) physically lives:
|
|
182
199
|
|
|
@@ -208,9 +225,52 @@ Regenerates `AGENTS.md` and provider-specific files from your `agent-harness-kit
|
|
|
208
225
|
```bash
|
|
209
226
|
ahk build
|
|
210
227
|
ahk build --watch # watch mode: rebuilds automatically on config changes
|
|
211
|
-
ahk build --
|
|
228
|
+
ahk build --force # DESTRUCTIVE: regenerate agent files, discarding your edits
|
|
229
|
+
ahk build --sync # kept for backwards compatibility — now a no-op on every provider
|
|
212
230
|
```
|
|
213
231
|
|
|
232
|
+
### Agent files are yours
|
|
233
|
+
|
|
234
|
+
`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`, or `.codex/agents/<role>.toml`) 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.
|
|
235
|
+
|
|
236
|
+
Everything else `build` writes — MCP config and skills — is derived from your config and **is** regenerated on every run.
|
|
237
|
+
|
|
238
|
+
### `AGENTS.md` and `CLAUDE.md` — derived, but your edits are safe
|
|
239
|
+
|
|
240
|
+
`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.
|
|
241
|
+
|
|
242
|
+
```
|
|
243
|
+
<!-- ahk:generated 3f7a…c1 -->
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
On each build the marker lets `build` tell its own untouched output apart from a human edit, byte-for-byte:
|
|
247
|
+
|
|
248
|
+
- **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.
|
|
249
|
+
- **Already up to date** → no-op.
|
|
250
|
+
- **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.
|
|
251
|
+
|
|
252
|
+
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.
|
|
253
|
+
|
|
254
|
+
> **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).
|
|
255
|
+
|
|
256
|
+
### `--force`
|
|
257
|
+
|
|
258
|
+
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:
|
|
259
|
+
|
|
260
|
+
```bash
|
|
261
|
+
ahk build --force
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
- **It discards your customizations.** Every agent file is rewritten from the template. Prompt edits, `model:` lines, and restriction tweaks are all lost.
|
|
265
|
+
- **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`](#storage-migration).
|
|
266
|
+
- **It names what it touched.** The command prints every file it overwrote and the backup location, so you can diff or restore.
|
|
267
|
+
|
|
268
|
+
`--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.
|
|
269
|
+
|
|
270
|
+
`--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.
|
|
271
|
+
|
|
272
|
+
`--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.
|
|
273
|
+
|
|
214
274
|
---
|
|
215
275
|
|
|
216
276
|
### `ahk dashboard`
|
|
@@ -223,7 +283,11 @@ ahk dashboard --port 8080 # custom port
|
|
|
223
283
|
ahk dashboard --no-open # start server without opening browser
|
|
224
284
|
```
|
|
225
285
|
|
|
226
|
-
|
|
286
|
+
`--port` must be an integer between `1` and `65535`; an invalid value (e.g. `ahk dashboard --port abc` or `--port 99999`) is rejected at the CLI with a clear error naming the flag and the valid range, rather than silently failing.
|
|
287
|
+
|
|
288
|
+
If the requested port (default `4242`) is already in use, `ahk dashboard` automatically tries up to 10 sequential ports (e.g. `4242 → 4243 → … → 4251`), printing `Port 4242 in use, using 4243`. The actual port opened is printed to the console. If all 10 ports are exhausted, the command exits with a clear error message showing which port range was attempted.
|
|
289
|
+
|
|
290
|
+
Port availability is checked against the same network interface the dashboard actually binds to, so an already-running `ahk dashboard` — or any other server holding that port — is reliably detected. The success banner is printed only after the server has genuinely bound; if the bind fails (for example, the port was claimed by another process in the moment between the check and the bind), the command reports an actionable error instead of crashing.
|
|
227
291
|
|
|
228
292
|
The dashboard includes:
|
|
229
293
|
|
|
@@ -263,7 +327,7 @@ ahk health
|
|
|
263
327
|
|
|
264
328
|
### `ahk doctor`
|
|
265
329
|
|
|
266
|
-
Checks
|
|
330
|
+
Checks the installed lib version, that every agent file is present, and that the harness skills are in sync.
|
|
267
331
|
|
|
268
332
|
```bash
|
|
269
333
|
ahk doctor
|
|
@@ -272,7 +336,7 @@ ahk doctor
|
|
|
272
336
|
Reports three categories:
|
|
273
337
|
|
|
274
338
|
- **lib version** — compares installed version against the latest on npm. Shows `[✓]` if up to date, `[!]` if an update is available, or `[~]` if the registry could not be reached.
|
|
275
|
-
- **agent files** —
|
|
339
|
+
- **agent files** — checks only that a definition file exists for every role. Reports `[!]` with the file name if one is missing. The contents are never read, so **editing an agent file by hand is a fully supported state and is never reported** — customise the body, the description, or the restrictions freely and `ahk doctor` stays green.
|
|
276
340
|
- **harness skills** — checks that `ahk-ask`, `ahk-consultant`, `ahk-triage`, and `ahk-review` skills exist and match the bundled source. Reports `[!]` if missing or outdated.
|
|
277
341
|
|
|
278
342
|
Run `ahk build` to fix any reported issues.
|
|
@@ -302,6 +366,8 @@ ahk serve
|
|
|
302
366
|
ahk serve --port 3456 # store a port hint in config (stdio transport only)
|
|
303
367
|
```
|
|
304
368
|
|
|
369
|
+
`--port` must be an integer between `1` and `65535`; an invalid value is rejected at the CLI with a clear error.
|
|
370
|
+
|
|
305
371
|
---
|
|
306
372
|
|
|
307
373
|
### `ahk task add`
|
|
@@ -427,7 +493,7 @@ ahk export --sql --output dump.sql # SQL dump to file
|
|
|
427
493
|
|
|
428
494
|
```
|
|
429
495
|
your-project/
|
|
430
|
-
├── agent-harness-kit.config.{ts|mjs|cjs}
|
|
496
|
+
├── agent-harness-kit.config.{json|ts|mjs|cjs}
|
|
431
497
|
├── AGENTS.md
|
|
432
498
|
├── CLAUDE.md
|
|
433
499
|
├── health.sh
|
|
@@ -450,7 +516,7 @@ your-project/
|
|
|
450
516
|
|
|
451
517
|
```
|
|
452
518
|
your-project/
|
|
453
|
-
├── agent-harness-kit.config.{ts|mjs|cjs}
|
|
519
|
+
├── agent-harness-kit.config.{json|ts|mjs|cjs}
|
|
454
520
|
├── AGENTS.md
|
|
455
521
|
├── health.sh
|
|
456
522
|
├── opencode.json ← MCP server + default_agent + compaction config
|
|
@@ -467,7 +533,7 @@ your-project/
|
|
|
467
533
|
|
|
468
534
|
```
|
|
469
535
|
your-project/
|
|
470
|
-
├── agent-harness-kit.config.{ts|mjs|cjs}
|
|
536
|
+
├── agent-harness-kit.config.{json|ts|mjs|cjs}
|
|
471
537
|
├── AGENTS.md
|
|
472
538
|
├── health.sh
|
|
473
539
|
├── .harness/
|
|
@@ -485,19 +551,19 @@ your-project/
|
|
|
485
551
|
|
|
486
552
|
| File | Purpose | Edit it? |
|
|
487
553
|
| ----------------------------- | ------------------------------------------------------------------------------------- | ----------------------------------------------------------- |
|
|
488
|
-
| `agent-harness-kit.config.ts` | Defines project metadata, provider, storage paths, MCP port
|
|
554
|
+
| `agent-harness-kit.config.{json\|ts\|mjs\|cjs}` | Defines project metadata, provider, storage paths, MCP port. JSON when the package isn't installed locally, otherwise `.ts`/`.mjs`/`.cjs` | Yes — it's yours |
|
|
489
555
|
| `AGENTS.md` | Navigation map agents read first. Regenerated by `ahk build` | No — changes will be overwritten |
|
|
490
556
|
| `health.sh` | Shell script agents run before starting work. Must exit 0 | **Yes — implement your checks here** |
|
|
491
557
|
| `.harness/feature_list.json` | Task backlog in JSON. Humans edit this, `ahk sync` loads it into SQLite | Yes — add tasks here |
|
|
492
558
|
| `.harness/harness.db` | SQLite database (local scope only). Source of truth for tasks, actions, sections | No — managed by the harness |
|
|
493
559
|
| `.harness/current.md` | Auto-generated session snapshot for agents without MCP access (local scope only) | No — regenerated automatically |
|
|
494
560
|
| `.harness/storage-state.json` | Always project-local. Records the REAL current storage state (`scope`, `projectId`, `dbType`, `migratedAt`) — used by migration tooling | No — managed by the harness |
|
|
495
|
-
| `.claude/agents/*.md` | Agent role definitions (Claude Code). Created once, never overwritten | **Yes — customize agent behavior** |
|
|
561
|
+
| `.claude/agents/*.md` | Agent role definitions (Claude Code). Created once, never overwritten (`ahk build --force` regenerates) | **Yes — customize agent behavior** |
|
|
496
562
|
| `.claude/mcp.json` | MCP server registration for Claude Code. Merged by `ahk build` | Yes, carefully — don't remove the `agent-harness-kit` entry |
|
|
497
563
|
| `.claude/settings.json` | Sets `agent: "lead"` so lead runs as the default session agent. Merged by `ahk build` | Yes, carefully |
|
|
498
|
-
| `.opencode/agents/*.md` | Agent role definitions (OpenCode). Created once, never overwritten | **Yes — customize agent behavior** |
|
|
564
|
+
| `.opencode/agents/*.md` | Agent role definitions (OpenCode). Created once, never overwritten (`ahk build --force` regenerates) | **Yes — customize agent behavior** |
|
|
499
565
|
| `opencode.json` | MCP server + `default_agent` + compaction config for OpenCode. Merged by `ahk build` | Yes, carefully |
|
|
500
|
-
| `.codex/agents/*.toml` | Agent role definitions (Codex CLI). Created once, never overwritten | **Yes — customize agent behavior** |
|
|
566
|
+
| `.codex/agents/*.toml` | Agent role definitions (Codex CLI). Created once, never overwritten (`ahk build --force` regenerates) | **Yes — customize agent behavior** |
|
|
501
567
|
| `.codex/config.toml` | MCP server registration for Codex CLI. Merged by `ahk build` | Yes, carefully |
|
|
502
568
|
|
|
503
569
|
---
|
|
@@ -510,9 +576,9 @@ The `tasks` table includes an `updated_at` timestamp column, set on creation and
|
|
|
510
576
|
|
|
511
577
|
## What you can customize
|
|
512
578
|
|
|
513
|
-
### `agent-harness-kit.config.ts`
|
|
579
|
+
### `agent-harness-kit.config.{json|ts|mjs|cjs}`
|
|
514
580
|
|
|
515
|
-
Everything in the config file is yours to change:
|
|
581
|
+
Everything in the config file is yours to change. The example below is the TypeScript form, generated when the package is installed locally in your project:
|
|
516
582
|
|
|
517
583
|
```ts
|
|
518
584
|
import type { HarnessConfig } from '@cardor/agent-harness-kit'
|
|
@@ -526,14 +592,8 @@ const config: HarnessConfig = {
|
|
|
526
592
|
|
|
527
593
|
provider: 'claude-code', // 'claude-code' | 'opencode' | 'codex-cli'
|
|
528
594
|
|
|
529
|
-
agents
|
|
530
|
-
|
|
531
|
-
explorer: { instructionsPath: null, allowedPaths: ['./docs', './src'], model: 'haiku' },
|
|
532
|
-
builder: { instructionsPath: null, writablePaths: ['./src', './tests'] },
|
|
533
|
-
reviewer: { instructionsPath: null },
|
|
534
|
-
consultant: { instructionsPath: null, model: 'haiku' },
|
|
535
|
-
custom: [], // define extra agents here
|
|
536
|
-
},
|
|
595
|
+
// There is no `agents` key. Per-agent settings live in the generated agent
|
|
596
|
+
// file itself, which is yours to edit — see "Agent files are yours" below.
|
|
537
597
|
|
|
538
598
|
// ── Database ──────────────────────────────────────────────────────────────
|
|
539
599
|
// SQLite (default — zero native deps, Node 22+ or Bun). Note: `database`
|
|
@@ -581,6 +641,41 @@ const config: HarnessConfig = {
|
|
|
581
641
|
export default config
|
|
582
642
|
```
|
|
583
643
|
|
|
644
|
+
**The JSON form** (`agent-harness-kit.config.json`, generated when the package is *not* installed locally) holds exactly the same values, minus the comments and the type annotation:
|
|
645
|
+
|
|
646
|
+
```json
|
|
647
|
+
{
|
|
648
|
+
"project": {
|
|
649
|
+
"name": "My App",
|
|
650
|
+
"description": "What this project does",
|
|
651
|
+
"docsPath": "./docs"
|
|
652
|
+
},
|
|
653
|
+
"provider": "claude-code",
|
|
654
|
+
"database": { "type": "sqlite" },
|
|
655
|
+
"storage": {
|
|
656
|
+
"dir": ".harness",
|
|
657
|
+
"tasks": { "adapter": "local" },
|
|
658
|
+
"sections": {
|
|
659
|
+
"toolsUsed": true,
|
|
660
|
+
"filesModified": true,
|
|
661
|
+
"result": true,
|
|
662
|
+
"blockers": true,
|
|
663
|
+
"nextSteps": false
|
|
664
|
+
},
|
|
665
|
+
"markdownFallback": { "enabled": true, "path": ".harness/current.md" },
|
|
666
|
+
"scope": "local",
|
|
667
|
+
"projectId": "5f2c..."
|
|
668
|
+
},
|
|
669
|
+
"health": { "scriptPath": "./health.sh", "required": true },
|
|
670
|
+
"tools": {
|
|
671
|
+
"mcp": { "enabled": true, "port": 3742 },
|
|
672
|
+
"scripts": { "enabled": true, "outputDir": "./.harness/scripts" }
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
```
|
|
676
|
+
|
|
677
|
+
Every option documented below applies to both forms — the same keys, the same defaults, the same runtime normalization. The only difference is that the JSON form has no type checking or autocompletion behind it, since there is no package to resolve them from. To switch a JSON config to TypeScript, install the package locally (`npm install --save-dev @cardor/agent-harness-kit`) and rename the file to `agent-harness-kit.config.ts`, wrapping the object as shown above. `ahk` will not convert it for you — an existing config always keeps its format.
|
|
678
|
+
|
|
584
679
|
**`scope: 'global'`** — DB and current.md live under `~/.harness/dbs/<projectId>/`, outside the project tree. Under this scope, `sqlitePath` and `markdownFallback.path` don't exist on the type at all (a type error, not just a no-op) — there's nothing local to declare a path for:
|
|
585
680
|
|
|
586
681
|
```ts
|
|
@@ -620,32 +715,56 @@ echo "All checks passed."
|
|
|
620
715
|
|
|
621
716
|
### Agent definition files
|
|
622
717
|
|
|
623
|
-
|
|
718
|
+
**These files belong to you.** `ahk init` and `ahk build` both create them when missing and **never modify them once they exist**. Customise them freely: rewrite the role prompt, add a `model:` line, adjust the restriction fields. Nothing in the normal workflow will revert your edits, and `ahk doctor` never reports a hand-edited file as drift — it checks existence only.
|
|
624
719
|
|
|
625
|
-
|
|
720
|
+
The trade-off is that you do not automatically receive template improvements from new versions of this package. `ahk build --force` is the only way to pull them in, and it **discards your customisations** (writing a backup to `.harness/backups/agents-<timestamp>/` first). Keep customisations in source control so you can diff against a forced regeneration.
|
|
721
|
+
|
|
722
|
+
There is no `agents` key in `agent-harness-kit.config.ts`. Per-agent settings live here, in the file itself — set the model on the `model:` frontmatter line (`model = "..."` for Codex CLI) and write role instructions in the body. When no model line is present, the provider applies its own default.
|
|
723
|
+
|
|
724
|
+
Agent files do not declare a tool allowlist. Each agent inherits the full tool set of the session — including `Task` and every MCP tool — and the file declares only what the role is *not* allowed to do. Each provider expresses that restriction in its own syntax.
|
|
725
|
+
|
|
726
|
+
**Claude Code** (`.claude/agents/*.md`) uses a `disallowedTools` YAML block sequence:
|
|
626
727
|
|
|
627
728
|
```markdown
|
|
628
729
|
---
|
|
629
|
-
name:
|
|
630
|
-
description:
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
edit: true
|
|
635
|
-
bash: true
|
|
636
|
-
permissionMode: acceptEdits
|
|
730
|
+
name: explorer
|
|
731
|
+
description: Explorer agent — reads and maps the codebase, never writes
|
|
732
|
+
disallowedTools:
|
|
733
|
+
- Write
|
|
734
|
+
- Edit
|
|
637
735
|
---
|
|
638
736
|
|
|
639
|
-
#
|
|
737
|
+
# Explorer Agent
|
|
640
738
|
|
|
641
|
-
You are the
|
|
739
|
+
You are the explorer agent for MyApp. Follow these rules:
|
|
642
740
|
|
|
643
|
-
-
|
|
644
|
-
- Never modify
|
|
645
|
-
-
|
|
646
|
-
- Use the existing error handling pattern from `src/lib/errors.ts`
|
|
741
|
+
- Map the modules relevant to the task and report where each concern lives
|
|
742
|
+
- Never modify files — record every file you read
|
|
743
|
+
- Prefer the existing patterns in `src/lib/` when describing conventions
|
|
647
744
|
```
|
|
648
745
|
|
|
746
|
+
**OpenCode** (`.opencode/agents/*.md`) uses a `permission` mapping instead. OpenCode has no separate `write` permission — its `edit` key is defined as "file modifications including write/patch", so a single `edit: deny` covers Write, Edit, and patch:
|
|
747
|
+
|
|
748
|
+
```markdown
|
|
749
|
+
---
|
|
750
|
+
name: explorer
|
|
751
|
+
description: Explorer agent — reads and maps the codebase, never writes
|
|
752
|
+
permission:
|
|
753
|
+
edit: deny
|
|
754
|
+
---
|
|
755
|
+
|
|
756
|
+
# Explorer Agent
|
|
757
|
+
|
|
758
|
+
You are the explorer agent for MyApp. Follow these rules:
|
|
759
|
+
|
|
760
|
+
- Map the modules relevant to the task and report where each concern lives
|
|
761
|
+
- Never modify files — record every file you read
|
|
762
|
+
```
|
|
763
|
+
|
|
764
|
+
> The legacy OpenCode `tools: { write: false }` dict is deprecated upstream in favour of `permission` and is no longer emitted.
|
|
765
|
+
|
|
766
|
+
For the **builder**, which has no restrictions, the key is omitted entirely — no `disallowedTools` under Claude Code, no `permission` under OpenCode.
|
|
767
|
+
|
|
649
768
|
**Codex CLI** (`.codex/agents/*.toml`) uses TOML format:
|
|
650
769
|
|
|
651
770
|
```toml
|
|
@@ -667,12 +786,16 @@ You are the builder agent for MyApp. Follow these rules:
|
|
|
667
786
|
"""
|
|
668
787
|
```
|
|
669
788
|
|
|
670
|
-
|
|
789
|
+
Codex CLI has no per-agent tool denylist, so `sandbox_mode` is the only real mechanism: `"read-only"` for lead, explorer, consultant, and reviewer; `"workspace-write"` for builder. Because Codex keeps the write tools *visible* to the model even under a read-only sandbox, the restriction is additionally restated in prose inside `developer_instructions` — without it the model burns turns on calls the sandbox will reject.
|
|
790
|
+
|
|
791
|
+
The equivalent constraint under Claude Code is expressed as `disallowedTools: [Write, Edit]`, and under OpenCode as `permission: { edit: deny }`.
|
|
671
792
|
|
|
672
793
|
### `.harness/feature_list.json`
|
|
673
794
|
|
|
674
795
|
The human-editable task backlog. Add tasks here, then run `ahk sync` to load them into SQLite.
|
|
675
796
|
|
|
797
|
+
`ahk init` **never clobbers** this file: an existing backlog is merged into SQLite (deduplicated by slug) alongside any first task you add during init, then re-emitted — so a hand-written backlog is preserved. On a fresh project the file is created (empty `[]` if you skip the first-task prompt). If the file contains invalid JSON, init leaves it untouched and warns you to fix it and run `ahk sync`.
|
|
798
|
+
|
|
676
799
|
```json
|
|
677
800
|
[
|
|
678
801
|
{
|
|
@@ -708,13 +831,13 @@ The harness exposes these tools via MCP. Agents use them instead of reading file
|
|
|
708
831
|
| `actions.write` | `actionId, sectionType, content` | Record a text section: `result \| tools_used \| blockers \| next_steps`. Does **not** populate the Files dashboard — use `actions.record_file` for that |
|
|
709
832
|
| `actions.complete` | `actionId, summary` | Close an action with a one-line summary |
|
|
710
833
|
| `actions.get` | `taskId` | Full action history for a task (all agents, all sections) |
|
|
711
|
-
| `actions.record_file` | `actionId, filePath, operation, notes
|
|
712
|
-
| `actions.record_tool` | `actionId, toolName, argsJson?, resultSummary
|
|
834
|
+
| `actions.record_file` | `actionId, files: [{ filePath, operation, notes? }, ...]` | Batch-register one or more file touches, atomically. The **only** way to populate the Files dashboard. `operation`: `read \| created \| modified \| deleted`. Batch-only — `files` requires at least one entry; a single touch is still a one-element array |
|
|
835
|
+
| `actions.record_tool` | `actionId, calls: [{ toolName, argsJson?, resultSummary? }, ...]` | Batch-register one or more tool calls, atomically. The **only** way to populate the Tools dashboard. Batch-only — `calls` requires at least one entry; a single call is still a one-element array |
|
|
713
836
|
| `docs.search` | `query` | Search the `docsPath` folder for content matching the query |
|
|
714
837
|
| `tasks.acceptance_get` | `taskId` | Returns all acceptance criteria for a task with their `id`, `task_id`, `criterion` text, and `met` status. Use the returned `id` values with `tasks.acceptance.update` |
|
|
715
838
|
| `deps.snapshot` | _(none)_ | Snapshot current `package.json` dependencies to `.harness/deps-lock.json` |
|
|
716
839
|
| `deps.check` | _(none)_ | Compare current `package.json` against `.harness/deps-lock.json`. Returns `{ significant, added, removed, majorBumps, advisory }` |
|
|
717
|
-
| `ahk.doctor` | _(none)_ | Check lib version, agent
|
|
840
|
+
| `ahk.doctor` | _(none)_ | Check lib version, agent file presence, and harness skills sync status. Returns `{ lib: { current, latest, outdated }, agents: { missing, ok }, skills: { missing, outdated, ok } }`. Agents are existence-checked only, so there is no `outdated` bucket for them; `skills` still has all three. The `lib` version lookup (npm registry check) is cached in-memory with a 5-minute TTL — repeated calls within that window do not hit the network again. |
|
|
718
841
|
|
|
719
842
|
---
|
|
720
843
|
|
|
@@ -725,12 +848,18 @@ The harness exposes these tools via MCP. Agents use them instead of reading file
|
|
|
725
848
|
| **lead** | Decomposes the task into a plan, assigns sub-agents. Does not write code or read source files. |
|
|
726
849
|
| **explorer** | Reads and maps the codebase. Never writes files. Records every file read. |
|
|
727
850
|
| **consultant** | Provides structured technical advisory after explorer. Runs conditionally. Never writes code. Writes advisory to harness via actions.write. |
|
|
728
|
-
| **builder** | Implements the plan.
|
|
851
|
+
| **builder** | Implements the plan. The only role that writes — its write tools are enabled where every other role's are disabled. Records every file modified. |
|
|
729
852
|
| **reviewer** | Verifies all acceptance criteria are met. Approves or blocks. Runs health check before approving. |
|
|
730
853
|
|
|
854
|
+
> **Scope note.** What a role may not do is enforced **per tool, not per path**. There is no per-agent path scoping and it is not configurable: the `allowedPaths` / `writablePaths` fields were removed because they were only interpolated into prompt text and no provider ever enforced them — they looked like a security control without being one. The real restriction lives in `src/core/materializer/agent-restrictions.ts`, which each provider translates natively: `disallowedTools` in Claude Code, `permission.edit` in OpenCode, `sandbox_mode` in Codex CLI. If a config still declares the removed fields they are stripped at load time with a warning.
|
|
855
|
+
>
|
|
856
|
+
> **The entire `agents` config key has since been removed too**, for the same underlying reason: everything left in it was either dead or better expressed elsewhere. `instructionsPath`, `context` and `custom` were written by the generator and never read by anything; `model` was the only field with an effect, and it now belongs in the agent file's frontmatter alongside the role prompt, since that file is user-owned. A config that still declares `agents` loads normally — the key is ignored, with one aggregated warning pointing at the agent file.
|
|
857
|
+
>
|
|
858
|
+
> **Breaking change for library consumers (compile time).** The `AgentConfig`, `AgentsConfig` and `CustomAgentConfig` types are no longer exported from the package, and `HarnessConfig` no longer has an `agents` property. If you import those types, remove the import; if you construct a `HarnessConfig` in TypeScript, drop the `agents` property. This is separate from the runtime tolerance above: existing config *files* keep loading, but code that references the removed types will not compile. The `AgentName` type is unrelated and unaffected.
|
|
859
|
+
|
|
731
860
|
### MCP tool permissions by role
|
|
732
861
|
|
|
733
|
-
|
|
862
|
+
> **Scope note.** This table describes the *intended* division of labour between roles, not a restriction enforced by the agent files. Agent definitions no longer declare a tool allowlist, so every role inherits **all** MCP tools. The per-role `MCP_CLAUDE_PERMISSIONS_*` arrays still exist, but they are only unioned together to populate the allow list in `.claude/settings.local.json` — they are not applied per agent. Treat the table as the convention each role's prompt asks it to follow.
|
|
734
863
|
|
|
735
864
|
| Tool | lead | explorer | consultant | builder | reviewer |
|
|
736
865
|
| ----------------------------- | :--: | :------: | :--------: | :-----: | :------: |
|
|
@@ -754,7 +883,7 @@ Each agent role has a scoped set of MCP tools enforced through the agent definit
|
|
|
754
883
|
**lead** and **builder** have identical access, both excluding `tasks.acceptance.update`.
|
|
755
884
|
**consultant** is advisory-only — reads code, writes to harness, and can call deps tools. Never modifies the codebase.
|
|
756
885
|
|
|
757
|
-
`permissions.check`
|
|
886
|
+
`permissions.check` verifies only that a `.claude/agents/*.md` definition file **exists** for every role. Returns `{ in_sync: bool, agents: { lead, explorer, consultant, builder, reviewer } }` where each agent is `{ ok: true }` or `{ ok: false, reason: 'missing_file' }`. Agent file contents are never inspected — they are meant to be customised freely — so this never reports drift, only absence. Run `ahk build` to restore a missing file.
|
|
758
887
|
|
|
759
888
|
---
|
|
760
889
|
|
|
@@ -762,7 +891,7 @@ Each agent role has a scoped set of MCP tools enforced through the agent definit
|
|
|
762
891
|
|
|
763
892
|
| File | Commit? |
|
|
764
893
|
| ----------------------------- | ------------------- |
|
|
765
|
-
| `agent-harness-kit.config.ts` | Yes |
|
|
894
|
+
| `agent-harness-kit.config.{json\|ts\|mjs\|cjs}` | Yes |
|
|
766
895
|
| `AGENTS.md` | Yes |
|
|
767
896
|
| `CLAUDE.md` | Yes |
|
|
768
897
|
| `health.sh` | Yes |
|
|
@@ -5,11 +5,6 @@ description: >
|
|
|
5
5
|
and analyzed by explorer. The builder writes, edits, and creates files based on the plan
|
|
6
6
|
and the explorer's analysis. Invoke only after the explorer has completed its action.
|
|
7
7
|
Never invoke without a lead plan and explorer analysis available in actions.get(taskId).
|
|
8
|
-
tools:
|
|
9
|
-
- Read
|
|
10
|
-
- Write
|
|
11
|
-
- Edit
|
|
12
|
-
- Bash
|
|
13
8
|
---
|
|
14
9
|
|
|
15
10
|
# Builder Agent — {{projectName}}
|
|
@@ -24,46 +19,55 @@ You are the **builder agent** for `{{projectName}}`. Your job is to implement
|
|
|
24
19
|
- Run tests after implementing to catch regressions early
|
|
25
20
|
- Surface blockers clearly rather than guessing through them
|
|
26
21
|
|
|
27
|
-
##
|
|
22
|
+
## Scope
|
|
28
23
|
|
|
29
|
-
You may
|
|
24
|
+
You may write anywhere inside the project.
|
|
30
25
|
|
|
31
|
-
|
|
26
|
+
You are the only role that writes. Stay inside the project root — never edit files
|
|
27
|
+
outside it. Breadth of access is not licence to widen scope: implement what the plan
|
|
28
|
+
asks and nothing more. If a change genuinely belongs outside the project root, record
|
|
29
|
+
a blocker and stop.
|
|
32
30
|
|
|
33
31
|
---
|
|
34
32
|
|
|
35
33
|
## !! MANDATORY TRACKING — DO THIS FOR EVERY ACTION, NO EXCEPTIONS !!
|
|
36
34
|
|
|
37
|
-
These
|
|
35
|
+
These calls are **not optional**. The dashboard cannot display what you do not report. Missing them is a failure of your role.
|
|
36
|
+
|
|
37
|
+
Both `actions.record_tool` and `actions.record_file` are **batch-only** — each takes an array of entries, never a single bespoke call. Accumulate as you work and flush periodically (every few tool calls, or at a natural checkpoint/phase boundary) rather than round-tripping once per individual tool use. Even a single entry must still go through the array shape — a one-element array, never a bespoke single-call form, since that form no longer exists.
|
|
38
38
|
|
|
39
39
|
### 1. Log every tool call you make
|
|
40
40
|
|
|
41
|
-
|
|
41
|
+
Accumulate each tool invocation (Read, Edit, Write, Bash) as you go, then flush with:
|
|
42
42
|
|
|
43
43
|
```
|
|
44
|
-
actions.record_tool(actionId,
|
|
44
|
+
actions.record_tool(actionId, calls: [
|
|
45
|
+
{ toolName: '<ToolName>', argsJson: '<args-summary>', resultSummary: '<why>' },
|
|
46
|
+
...
|
|
47
|
+
])
|
|
45
48
|
```
|
|
46
49
|
|
|
47
|
-
|
|
48
|
-
- `actions.record_tool(actionId, 'Read', 'src/auth/middleware.ts', 'understand existing JWT pattern')`
|
|
49
|
-
- `actions.record_tool(actionId, 'Bash', 'npm test --testPathPattern=auth', 'verify auth tests pass')`
|
|
50
|
-
- `actions.record_tool(actionId, 'Edit', 'src/auth/middleware.ts:45-78', 'add refresh token validation')`
|
|
50
|
+
Example flush after a few calls:
|
|
51
|
+
- `actions.record_tool(actionId, calls: [{ toolName: 'Read', argsJson: 'src/auth/middleware.ts', resultSummary: 'understand existing JWT pattern' }, { toolName: 'Edit', argsJson: 'src/auth/middleware.ts:45-78', resultSummary: 'add refresh token validation' }, { toolName: 'Bash', argsJson: 'npm test --testPathPattern=auth', resultSummary: 'verify auth tests pass' }])`
|
|
51
52
|
|
|
52
53
|
### 2. Log every file you touch
|
|
53
54
|
|
|
54
|
-
|
|
55
|
+
Accumulate each file modification (Edit, Write) as you go, then flush with:
|
|
55
56
|
|
|
56
57
|
```
|
|
57
|
-
actions.record_file(actionId,
|
|
58
|
+
actions.record_file(actionId, files: [
|
|
59
|
+
{ filePath: '<file-path>', operation: '<operation>', notes: '<what changed and why>' },
|
|
60
|
+
...
|
|
61
|
+
])
|
|
58
62
|
```
|
|
59
63
|
|
|
60
64
|
Operations: `created` | `modified` | `deleted`
|
|
61
65
|
|
|
62
|
-
Example: `actions.record_file(actionId, 'src/auth/middleware.ts', 'modified', 'added refresh token expiry check in validateToken()')`
|
|
66
|
+
Example: `actions.record_file(actionId, files: [{ filePath: 'src/auth/middleware.ts', operation: 'modified', notes: 'added refresh token expiry check in validateToken()' }])`
|
|
63
67
|
|
|
64
68
|
### 3. Do not complete your action without both logs being up to date
|
|
65
69
|
|
|
66
|
-
If you touched 5 files and made 12 tool calls,
|
|
70
|
+
If you touched 5 files and made 12 tool calls across the session, every one of those must appear as an entry inside some `actions.record_file`/`actions.record_tool` batch call before you call `actions.complete` — it doesn't need to be 5 and 12 separate MCP round-trips, but the union of all your batched arrays must account for all 5 files and all 12 tool calls.
|
|
67
71
|
|
|
68
72
|
---
|
|
69
73
|
|
|
@@ -85,7 +89,7 @@ actions.start(taskId, 'builder') → save the returned actionId
|
|
|
85
89
|
|
|
86
90
|
### 3. Implement in small, verifiable steps
|
|
87
91
|
|
|
88
|
-
Work through the plan item by item.
|
|
92
|
+
Work through the plan item by item. Accumulate each tool call and each file touched as described in the **MANDATORY TRACKING** section above, and flush in batches as you go — do not wait until the very end of the session to record everything at once.
|
|
89
93
|
|
|
90
94
|
### 4. Follow existing patterns
|
|
91
95
|
|
|
@@ -168,9 +172,9 @@ Before writing a commit message, detect whether the repo already enforces a comm
|
|
|
168
172
|
## Hard rules
|
|
169
173
|
|
|
170
174
|
- **Read the plan and analysis first.** Never implement cold.
|
|
171
|
-
- **
|
|
172
|
-
- **Log every file you touch.**
|
|
173
|
-
- **Log every tool call.**
|
|
175
|
+
- **Stay inside the project.** Never write outside the project root.
|
|
176
|
+
- **Log every file you touch.** Accumulate entries and flush via `actions.record_file(actionId, files: [...])` periodically as you Edit/Write — batch-only, even one file goes through as a one-element array.
|
|
177
|
+
- **Log every tool call.** Accumulate entries and flush via `actions.record_tool(actionId, calls: [...])` periodically as you Read, Edit, Write, Bash — batch-only, even one call goes through as a one-element array.
|
|
174
178
|
- **Leave tests green.** If tests fail after your changes, fix them before completing.
|
|
175
179
|
- **Do not refactor beyond the task scope.** Implement what was asked, nothing more.
|
|
176
180
|
- **If blocked, say so.** Do not invent workarounds for unclear requirements.
|
|
@@ -4,9 +4,6 @@ description: >
|
|
|
4
4
|
Technical advisor agent for {{projectName}}. Runs after the explorer and before the builder.
|
|
5
5
|
Provides structured advisory — patterns, best practices, warnings, and risks — written
|
|
6
6
|
directly to the harness so the builder can read it via actions.get. Never writes code.
|
|
7
|
-
tools:
|
|
8
|
-
- Read
|
|
9
|
-
- Bash
|
|
10
7
|
---
|
|
11
8
|
|
|
12
9
|
# Consultant Agent — {{projectName}}
|