@cardor/agent-harness-kit 0.16.0 → 0.16.2

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 CHANGED
@@ -98,10 +98,13 @@ ahk init
98
98
 
99
99
  ### `ahk init`
100
100
 
101
- Interactive scaffold. Asks for your project name, description, AI provider, docs path, and an optional first task. Creates all harness files in the current directory.
101
+ Interactive scaffold. Asks for your project name, AI provider, docs path, task adapter, and an optional first task. Creates all harness files in the current directory.
102
102
 
103
103
  ```bash
104
104
  ahk init
105
+
106
+ # Skip prompts with flags
107
+ ahk init --name "my-app" --provider claude-code --docs ./docs --tasks local
105
108
  ```
106
109
 
107
110
  Run this once per project. Safe to re-run — it will not overwrite files you've customized.
@@ -117,11 +120,37 @@ ahk build
117
120
  ahk build --watch # watch mode: rebuilds automatically on config changes
118
121
  ```
119
122
 
123
+ ---
124
+
125
+ ### `ahk dashboard`
126
+
127
+ 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.
128
+
129
+ ```bash
130
+ ahk dashboard # opens http://localhost:4242 in your browser
131
+ ahk dashboard --port 8080 # custom port
132
+ ahk dashboard --no-open # start server without opening browser
133
+ ```
134
+
135
+ The dashboard includes:
136
+
137
+ | View | What it shows |
138
+ |------|--------------|
139
+ | **Overview** | Status counts, active tasks with acceptance progress, recent agent activity |
140
+ | **Tasks** | Full task list, filterable by status, with acceptance progress bars |
141
+ | **Task detail** | Acceptance criteria, action timeline per agent, files touched, tools used |
142
+ | **Agents** | Per-role breakdown: actions, tasks worked, files touched, completion rate |
143
+ | **Tools** | Top tools bar chart + full log of recent tool calls with args and results |
144
+ | **Files** | Most-touched files with operation breakdown + recent file operation log |
145
+
146
+ ![Dashboard](./assets/ahk-dashboard.png)
147
+
148
+
120
149
  ---
121
150
 
122
151
  ### `ahk status`
123
152
 
124
- Shows the current task table and any active agent actions.
153
+ Shows the current task table and any active agent actions in the terminal.
125
154
 
126
155
  ```bash
127
156
  ahk status
@@ -142,11 +171,14 @@ ahk health
142
171
 
143
172
  ### `ahk sync`
144
173
 
145
- Syncs `.harness/feature_list.json` into the SQLite database. Tasks already in the DB are skipped (by slug). Use this to seed the backlog from the JSON file without duplicating existing tasks.
174
+ Syncs `.harness/feature_list.json` SQLite. Tasks already in the DB are skipped by slug. Use this to seed the backlog from the JSON file without duplicating existing tasks.
146
175
 
147
176
  ```bash
148
- ahk sync
149
- ahk sync --dry-run # preview changes without applying them
177
+ ahk sync # both directions (default)
178
+ ahk sync --direction in # JSON SQLite only
179
+ ahk sync --direction out # SQLite → JSON only
180
+ ahk sync --dry-run # preview changes without applying them
181
+ ahk sync --dry-run --direction in
150
182
  ```
151
183
 
152
184
  ---
@@ -157,7 +189,7 @@ Starts the MCP server on stdio. **You never need to call this manually.** After
157
189
 
158
190
  ```bash
159
191
  ahk serve
160
- ahk serve --port 3456 # default port (used only for config reference)
192
+ ahk serve --port 3456 # store a port hint in config (stdio transport only)
161
193
  ```
162
194
 
163
195
  ---
@@ -182,13 +214,14 @@ ahk task list --status pending
182
214
  ahk task list --status in_progress
183
215
  ahk task list --status done
184
216
  ahk task list --status blocked
217
+ ahk task list --json # machine-readable output
185
218
  ```
186
219
 
187
220
  ---
188
221
 
189
222
  ### `ahk task done <id|slug>`
190
223
 
191
- Marks a task as done. Runs the health check first — if health fails, the task is not closed.
224
+ Marks a task as done. Runs the health check first if health is required — if it fails, the task is not closed.
192
225
 
193
226
  ```bash
194
227
  ahk task done 3
@@ -199,7 +232,7 @@ ahk task done add-auth-flow
199
232
 
200
233
  ### `ahk migrate`
201
234
 
202
- Migrates provider-specific files from one provider to another. Useful when switching from Claude Code to OpenCode or vice versa.
235
+ Migrates provider-specific files from one AI provider to another. Useful when switching from Claude Code to OpenCode or vice versa.
203
236
 
204
237
  ```bash
205
238
  ahk migrate --to opencode
@@ -210,11 +243,13 @@ ahk migrate --to claude-code
210
243
 
211
244
  ### `ahk export`
212
245
 
213
- Exports the full database (tasks, actions, sections) as JSON. Useful for backups or external reporting.
246
+ Exports the full database as JSON or SQL. Useful for backups, external reporting, or migrating data.
214
247
 
215
248
  ```bash
216
- ahk export --json
217
- ahk export --json > snapshot.json
249
+ ahk export --json # JSON to stdout
250
+ ahk export --json --output snapshot.json # JSON to file
251
+ ahk export --sql # SQL dump to stdout
252
+ ahk export --sql --output dump.sql # SQL dump to file
218
253
  ```
219
254
 
220
255
  ---
@@ -435,12 +470,24 @@ The rule: commit inputs (config, task definitions, agent instructions). Ignore o
435
470
  git clone <repo-url>
436
471
  cd agent-harness-kit
437
472
  npm install
438
- npm run build # compile src/ → dist/
439
- npm run dev # watch mode
473
+
474
+ npm run build:ui # build the dashboard SPA (dashboard/ → src/dashboard-dist/)
475
+ npm run build # build:ui + tsc + copy-assets
476
+ npm run dev # watch mode (CLI TypeScript only)
440
477
  npm test # run tests
441
478
  npm link # register ahk globally from local source
442
479
  ```
443
480
 
481
+ To work on the dashboard UI with hot reload:
482
+
483
+ ```bash
484
+ # Terminal 1 — CLI server (no browser open)
485
+ cd your-test-project && ahk dashboard --no-open --port 4242
486
+
487
+ # Terminal 2 — Vite dev server with HMR
488
+ cd dashboard && npm run dev # http://localhost:5173, proxies /api and /ws → :4242
489
+ ```
490
+
444
491
  Commit messages follow [Conventional Commits](https://www.conventionalcommits.org/) with a required scope:
445
492
 
446
493
  ```
@@ -455,11 +502,9 @@ Types: `feat fix chore refactor docs test perf style build ci revert`
455
502
 
456
503
  ## Roadmap
457
504
 
458
- These are planned features, not yet released:
459
-
505
+ - **`ahk dashboard`** — local web UI with real-time WebSocket updates. Shows tasks, action timelines, file activity, tool usage, and per-agent breakdowns. Run `ahk dashboard` in any initialized project.
506
+ - **Open Telemetry integration** — emit OpenTelemetry spans for all agent actions, file operations, and tool calls. Enables distributed tracing and integration with any OT-compatible observability platform.
507
+ - **Jira task adapter** — pull tasks directly from Jira instead of maintaining `feature_list.json` manually. The `tasks.adapter` config key is already wired for this.
508
+ - **Linear task adapter** — same as Jira, for Linear.
509
+ - **GitHub Issues adapter** — same, for GitHub Issues.
460
510
  - **Remote MCP adapter** — connect to a hosted MCP server instead of a local SQLite file. Enables shared task state across machines and team members without syncing a DB file.
461
- - **Shared action log** — a web interface (or CLI dashboard) to view the full history of what every agent did, across all sessions, for a given project. Useful for team retrospectives and debugging agent behavior.
462
- - **Jira / Linear task adapter** — pull tasks directly from your existing issue tracker instead of maintaining `feature_list.json` manually. The `tasks.adapter` config key is already wired for this.
463
- - **Agent telemetry** — per-session statistics on tool usage, files touched, and time spent per role. Exported as JSON or pushed to a remote endpoint.
464
- - **Multi-project harness** — a single MCP server managing multiple projects, with project-scoped task isolation.
465
- - **Custom agent roles** — the config already has a `custom: []` field. The roadmap item is full CLI support for generating, registering, and routing tasks to custom-named agents beyond the default four.
package/dist/cli.js CHANGED
@@ -17,6 +17,13 @@ import { join as join3, resolve as resolve2 } from "path";
17
17
  // src/core/materializer/mcp-merge.ts
18
18
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
19
19
  import { dirname } from "path";
20
+ var compactionConfig = {
21
+ compaction: {
22
+ auto: true,
23
+ prune: true,
24
+ reserved: 1e4
25
+ }
26
+ };
20
27
  function mergeClaudeMcpJson(filePath, port) {
21
28
  const folderPath = dirname(filePath);
22
29
  if (!existsSync(folderPath)) {
@@ -29,15 +36,17 @@ function mergeClaudeMcpJson(filePath, port) {
29
36
  } catch {
30
37
  }
31
38
  }
39
+ const agentHarnessKitConfig = {
40
+ type: "stdio",
41
+ command: "npx",
42
+ args: ["ahk", "serve", "--port", String(port)]
43
+ };
32
44
  const merged = {
33
45
  ...existing,
46
+ compaction: existing.compaction ?? compactionConfig.compaction,
34
47
  mcpServers: {
35
48
  ...existing.mcpServers ?? {},
36
- "agent-harness-kit": {
37
- type: "stdio",
38
- command: "npx",
39
- args: ["ahk", "serve", "--port", String(port)]
40
- }
49
+ "agent-harness-kit": agentHarnessKitConfig
41
50
  }
42
51
  };
43
52
  mkdirSync(dirname(filePath), { recursive: true });
@@ -56,15 +65,17 @@ function mergeOpencodeJson(filePath, port) {
56
65
  }
57
66
  }
58
67
  const existingMcp = existing.mcp ?? {};
68
+ const agentHarnessKitConfig = {
69
+ enabled: true,
70
+ type: "local",
71
+ command: ["npx", "ahk", "serve", "--port", String(port)]
72
+ };
59
73
  const merged = {
60
74
  ...existing,
75
+ compaction: existing.compaction ?? compactionConfig.compaction,
61
76
  mcp: {
62
77
  ...existingMcp,
63
- "agent-harness-kit": {
64
- enabled: true,
65
- type: "local",
66
- command: ["npx", "ahk", "serve", "--port", String(port)]
67
- }
78
+ "agent-harness-kit": agentHarnessKitConfig
68
79
  }
69
80
  };
70
81
  writeFileSync(filePath, JSON.stringify(merged, null, 2) + "\n", "utf8");
@@ -1328,7 +1339,7 @@ async function runInit(cwd2, flags) {
1328
1339
  process.exit(1);
1329
1340
  }
1330
1341
  const agentsDir = provider === "claude-code" ? ".claude/agents/" : ".opencode/agents/";
1331
- const mcpFile = provider === "claude-code" ? ".claude/mcp.json" : "./opencode/opencode.json";
1342
+ const mcpFile = provider === "claude-code" ? ".claude/mcp.json" : "./opencode.json";
1332
1343
  console.log("");
1333
1344
  console.log(pc5.green("\u2713 agent-harness-kit.config.ts"));
1334
1345
  console.log(pc5.green("\u2713 AGENTS.md"));
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli.ts","../src/commands/build.ts","../src/core/materializer/claude-code.ts","../src/core/materializer/mcp-merge.ts","../src/core/materializer/scaffold-utils.ts","../src/core/materializer/templates.ts","../src/core/materializer/opencode.ts","../src/core/materializer/index.ts","../src/commands/dashboard.ts","../src/core/dashboard-server.ts","../src/core/db.ts","../src/core/sqlite-adapter.ts","../src/commands/export.ts","../src/commands/health.ts","../src/commands/init.ts","../src/commands/init-helpers.ts","../src/commands/migrate.ts","../src/core/mcp-server.ts","../src/commands/serve.ts","../src/commands/status.ts","../src/commands/sync.ts","../src/commands/task/add.ts","../src/commands/task/done.ts","../src/commands/task/list.ts","../src/core/package-data.ts","../src/core/update-check.ts"],"sourcesContent":["import { Command } from 'commander'\n\nimport { runBuild } from '@/commands/build'\nimport { runDashboard } from '@/commands/dashboard'\nimport { runExport } from '@/commands/export'\nimport { runHealth } from '@/commands/health'\nimport { runInit } from '@/commands/init'\nimport { runMigrate } from '@/commands/migrate'\nimport { runServe } from '@/commands/serve'\nimport { runStatus } from '@/commands/status'\nimport { runSync } from '@/commands/sync'\nimport { runTaskAdd, runTaskDone, runTaskList } from '@/commands/task/index'\nimport { pkg } from '@/core/package-data'\nimport { checkForUpdate, printUpdateMessage } from '@/core/update-check'\n\nconst cwd = process.cwd()\n\nconst updateCheck = checkForUpdate(pkg.version)\n\nconst program = new Command()\n\nprogram\n .name('ahk')\n .description('agent-harness-kit — CLI scaffolding for multi-agent harness systems')\n .version(pkg.version, '-v, --version')\n\n// ─── init ─────────────────────────────────────────────────────────────────────\nprogram\n .command('init')\n .description('Scaffold a harness interactively in the current directory')\n .option('--name <name>', 'Project name (skip prompt)')\n .option('--provider <provider>', 'AI provider: claude-code | opencode (skip prompt)')\n .option('--docs <path>', 'Docs folder path (skip prompt)')\n .option('--tasks <adapter>', 'Task adapter: local | jira | linear (skip prompt)')\n .action(async (opts) => {\n await runInit(cwd, opts)\n })\n\n// ─── build ────────────────────────────────────────────────────────────────────\nprogram\n .command('build')\n .description('Regenerate AGENTS.md and provider files from agent-harness-kit.config.ts')\n .option('--watch', 'Rebuild on config changes')\n .action(async (opts) => {\n await runBuild(cwd, opts)\n })\n\n// ─── health ───────────────────────────────────────────────────────────────────\nprogram\n .command('health')\n .description('Run health.sh and report result')\n .action(async () => {\n await runHealth(cwd)\n })\n\n// ─── status ───────────────────────────────────────────────────────────────────\nprogram\n .command('status')\n .description('Show task table and active actions')\n .option('--json', 'Output as JSON')\n .action(async (opts) => {\n await runStatus(cwd, opts)\n })\n\n// ─── sync ─────────────────────────────────────────────────────────────────────\nprogram\n .command('sync')\n .description('Sync feature_list.json ↔ SQLite')\n .option('--dry-run', 'Show what would change without applying')\n .option('--direction <direction>', 'in | out | both (default: both)')\n .action(async (opts) => {\n await runSync(cwd, { dryRun: opts['dry-run'], direction: opts.direction })\n })\n\n// ─── serve ────────────────────────────────────────────────────────────────────\nprogram\n .command('serve')\n .description('Start the MCP server (stdio)')\n .option('--port <port>', 'Port hint stored in config (default: 3742)', parseInt)\n .action(async (opts) => {\n await runServe(cwd, { port: opts.port })\n })\n\n// ─── task ─────────────────────────────────────────────────────────────────────\nconst task = program.command('task').description('Manage tasks')\n\ntask\n .command('add')\n .description('Add a task interactively')\n .action(async () => {\n await runTaskAdd(cwd)\n })\n\ntask\n .command('list')\n .description('List tasks')\n .option('--status <status>', 'Filter by status: pending | in_progress | done | blocked')\n .option('--json', 'Output as JSON')\n .action(async (opts) => {\n await runTaskList(cwd, opts)\n })\n\ntask\n .command('done <id|slug>')\n .description('Mark a task as done')\n .action(async (idOrSlug: string) => {\n await runTaskDone(cwd, idOrSlug)\n })\n\n// ─── dashboard ────────────────────────────────────────────────────────────────\nprogram\n .command('dashboard')\n .description('Open web dashboard to visualize harness data')\n .option('-p, --port <port>', 'Port to listen on', '4242')\n .option('--no-open', 'Do not open browser automatically')\n .action(async (opts: { port: string; open: boolean }) => {\n await runDashboard(cwd, { port: parseInt(opts.port), open: opts.open })\n })\n\n// ─── migrate ──────────────────────────────────────────────────────────────────\nprogram\n .command('migrate')\n .description('Migrate provider-specific files to a different provider')\n .option('--to <provider>', 'Target provider: claude-code | opencode')\n .action(async (opts) => {\n await runMigrate(cwd, opts)\n })\n\n// ─── export ───────────────────────────────────────────────────────────────────\nprogram\n .command('export')\n .description('Export the database')\n .option('--sql', 'SQL dump')\n .option('--json', 'JSON export of tasks and actions')\n .option('--output <path>', 'Output file path (default: stdout)')\n .action(async (opts) => {\n await runExport(cwd, opts)\n })\n\nprogram.hook('postAction', async () => {\n const update = await updateCheck\n if (update) printUpdateMessage(update)\n})\n\nprogram.parse()\n","import { watch } from 'node:fs'\nimport * as p from '@clack/prompts'\nimport pc from 'picocolors'\n\nimport { loadConfig } from '@/core/config'\nimport { getMaterializer } from '@/core/materializer/index'\n\ninterface BuildOptions {\n watch?: boolean\n}\n\nexport async function runBuild(cwd: string, opts: BuildOptions): Promise<void> {\n await buildOnce(cwd)\n\n if (opts.watch) {\n p.log.info(`Watching agent-harness-kit.config.ts for changes...`)\n watch(cwd, { recursive: false }, async (_, filename) => {\n if (filename?.startsWith('agent-harness-kit.config')) {\n p.log.step('Config changed — rebuilding...')\n await buildOnce(cwd)\n }\n })\n // Keep process alive\n await new Promise(() => { })\n }\n}\n\nasync function buildOnce(cwd: string): Promise<void> {\n const spinner = p.spinner()\n spinner.start('Loading config...')\n\n try {\n const config = await loadConfig(cwd)\n spinner.message('Rebuilding files...')\n const materializer = getMaterializer(config.provider)\n await materializer.build(config, cwd)\n spinner.stop(pc.green('Build complete'))\n p.log.success('AGENTS.md')\n p.log.success(`Agent definitions (${config.provider})`)\n p.log.success('MCP config')\n } catch (err) {\n spinner.stop(pc.red('Build failed'))\n p.log.error(err instanceof Error ? err.message : String(err))\n process.exit(1)\n }\n}\n","import { existsSync, mkdirSync, writeFileSync } from 'fs'\nimport { join, resolve } from 'path'\n\nimport { mergeClaudeMcpJson } from './mcp-merge'\nimport { appendGitignore, slugify, writeAgentFile } from './scaffold-utils'\nimport { agentBuilder, agentExplorer, agentLead, agentReviewer, agentsMd, featureListJson, HEALTH_SH } from './templates'\n\nimport type { HarnessConfig, Provider, ScaffoldOptions } from '@/types'\nimport type { Materializer } from './index'\n\nexport class ClaudeCodeMaterializer implements Materializer {\n async scaffold(config: HarnessConfig, opts: ScaffoldOptions): Promise<void> {\n const { cwd } = opts\n\n const write = (relPath: string, content: string, mode?: number) => {\n const abs = join(cwd, relPath)\n mkdirSync(resolve(abs, '..'), { recursive: true })\n writeFileSync(abs, content, { encoding: 'utf8', mode })\n }\n\n // AGENTS.md — always overwrite (generated from config)\n write('AGENTS.md', agentsMd(config))\n\n // health.sh — only create if it doesn't exist\n if (!existsSync(join(cwd, 'health.sh'))) {\n write('health.sh', HEALTH_SH, 0o755)\n }\n\n // .harness/feature_list.json\n const tasks = opts.firstTask\n ? [{ slug: slugify(opts.firstTask.title), ...opts.firstTask }]\n : []\n write(join(config.storage.dir, 'feature_list.json'), featureListJson(tasks))\n\n // .harness/current.md placeholder\n if (!existsSync(join(cwd, config.storage.markdownFallback.path))) {\n write(\n config.storage.markdownFallback.path,\n `<!-- AUTO-GENERATED by agent-harness-kit — DO NOT EDIT MANUALLY -->\\n<!-- Run ahk status to refresh -->\\n\\n# Current Session\\n\\nNo tasks in progress.\\n`\n )\n }\n\n // .claude/agents/ — skip files the dev may have customized\n const projectName = config.project.name\n const allowedPaths = (config.agents.explorer.allowedPaths ?? []).join(', ')\n const writablePaths = (config.agents.builder.writablePaths ?? []).join(', ')\n writeAgentFile(cwd, '.claude/agents/lead.md', agentLead({ projectName }))\n writeAgentFile(cwd, '.claude/agents/explorer.md', agentExplorer({ projectName, allowedPaths }))\n writeAgentFile(cwd, '.claude/agents/builder.md', agentBuilder({ projectName, writablePaths }))\n writeAgentFile(cwd, '.claude/agents/reviewer.md', agentReviewer({ projectName }))\n\n // .mcp.json — MERGE, never overwrite whole file\n mergeClaudeMcpJson(join(cwd, '.mcp.json'), config.tools.mcp.port)\n\n // .gitignore additions\n appendGitignore(cwd)\n }\n\n async build(config: HarnessConfig, cwd: string): Promise<void> {\n const write = (relPath: string, content: string) => {\n const abs = join(cwd, relPath)\n mkdirSync(resolve(abs, '..'), { recursive: true })\n writeFileSync(abs, content, 'utf8')\n }\n\n // build always regenerates AGENTS.md (it's derived from config)\n write('AGENTS.md', agentsMd(config))\n\n // Agent files: skip if customized, write if missing\n const projectName = config.project.name\n const allowedPaths = (config.agents.explorer.allowedPaths ?? []).join(', ')\n const writablePaths = (config.agents.builder.writablePaths ?? []).join(', ')\n writeAgentFile(cwd, '.claude/agents/lead.md', agentLead({ projectName }))\n writeAgentFile(cwd, '.claude/agents/explorer.md', agentExplorer({ projectName, allowedPaths }))\n writeAgentFile(cwd, '.claude/agents/builder.md', agentBuilder({ projectName, writablePaths }))\n writeAgentFile(cwd, '.claude/agents/reviewer.md', agentReviewer({ projectName }))\n\n // MCP config: always merge\n mergeClaudeMcpJson(join(cwd, '.mcp.json'), config.tools.mcp.port)\n }\n\n async migrate(config: HarnessConfig, _to: Provider, _cwd: string): Promise<void> {\n void config\n // Migration from claude-code is handled by the target materializer\n }\n}\n\n","import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs'\nimport { dirname } from 'node:path'\n\nexport function mergeClaudeMcpJson(filePath: string, port: number): void {\n const folderPath = dirname(filePath)\n if (!existsSync(folderPath)) {\n mkdirSync(folderPath, { recursive: true })\n }\n\n let existing: Record<string, unknown> = {}\n if (existsSync(filePath)) {\n try {\n existing = JSON.parse(readFileSync(filePath, 'utf8')) as Record<string, unknown>\n } catch {\n // Unreadable JSON — start fresh to avoid corrupt state\n }\n }\n\n const merged = {\n ...existing,\n mcpServers: {\n ...((existing.mcpServers as Record<string, unknown>) ?? {}),\n 'agent-harness-kit': {\n type: 'stdio',\n command: 'npx',\n args: ['ahk', 'serve', '--port', String(port)],\n },\n },\n }\n\n mkdirSync(dirname(filePath), { recursive: true })\n writeFileSync(filePath, JSON.stringify(merged, null, 2) + '\\n', 'utf8')\n}\n\nexport function mergeOpencodeJson(filePath: string, port: number): void {\n const folderPath = dirname(filePath)\n if (!existsSync(folderPath)) {\n mkdirSync(folderPath, { recursive: true })\n }\n\n let existing: Record<string, unknown> = {}\n if (existsSync(filePath)) {\n try {\n existing = JSON.parse(readFileSync(filePath, 'utf8')) as Record<string, unknown>\n } catch {\n // start fresh\n }\n }\n\n const existingMcp = (existing.mcp as Record<string, unknown>) ?? {}\n\n const merged = {\n ...existing,\n mcp: {\n ...existingMcp,\n 'agent-harness-kit': {\n enabled: true,\n type: 'local',\n command: ['npx', 'ahk', 'serve', '--port', String(port)],\n },\n },\n }\n\n writeFileSync(filePath, JSON.stringify(merged, null, 2) + '\\n', 'utf8')\n}\n","import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs'\nimport { join, resolve } from 'node:path'\n\nimport { GITIGNORE_ENTRIES } from './templates'\n\nexport function writeAgentFile(cwd: string, relPath: string, content: string): void {\n const abs = join(cwd, relPath)\n if (existsSync(abs)) return // preserve dev customizations\n mkdirSync(resolve(abs, '..'), { recursive: true })\n writeFileSync(abs, content, 'utf8')\n}\n\nexport function appendGitignore(cwd: string): void {\n const giPath = join(cwd, '.gitignore')\n const existing = existsSync(giPath) ? readFileSync(giPath, 'utf8') : ''\n\n const toAdd = GITIGNORE_ENTRIES.split('\\n')\n .filter((line) => line && !existing.includes(line))\n .join('\\n')\n\n if (toAdd.trim()) {\n writeFileSync(giPath, existing + (existing.endsWith('\\n') ? '' : '\\n') + toAdd + '\\n', 'utf8')\n }\n}\n\nexport function slugify(title: string): string {\n return title\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '')\n .slice(0, 64)\n}\n","import { readFileSync } from 'node:fs'\nimport { dirname, join } from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nimport type { HarnessConfig } from '@/types'\n\n// ─── Agent template loader ────────────────────────────────────────────────────\n\nconst __dirname = dirname(fileURLToPath(import.meta.url))\nconst TEMPLATES_DIR = join(__dirname, 'agent-templates')\n\n/**\n * Load an agent template file and interpolate {{variables}}.\n * Variables are replaced using a simple {{key}} pattern.\n */\nfunction loadAgentTemplate(\n name: 'lead' | 'explorer' | 'builder' | 'reviewer',\n vars: Record<string, string> = {}\n): string {\n const raw = readFileSync(join(TEMPLATES_DIR, `${name}.md`), 'utf8')\n return raw.replace(/\\{\\{(\\w+)\\}\\}/g, (_, key: string) => vars[key] ?? `{{${key}}}`)\n}\n\n// ─── health.sh — exits 1 until the dev implements it ─────────────────────────\n\nexport const HEALTH_SH = `#!/usr/bin/env bash\n# health.sh — project health check for agent-harness-kit\n#\n# This script must exit 0 when the project is healthy.\n# Agents will run this before starting work.\n#\n# TODO: implement your project's health checks below.\n# Examples:\n# npm test\n# docker compose ps | grep -q \"running\"\n# psql -c \"SELECT 1\" > /dev/null 2>&1\n#\n# Until you implement it, this script intentionally exits 1\n# so agents know the environment is not verified.\n\necho \"health.sh not implemented yet.\"\necho \"Edit this file with your project's health checks.\"\necho \"It must exit 0 for agents to start working.\"\nexit 1\n`\n\n// ─── AGENTS.md template ───────────────────────────────────────────────────────\n\nexport function agentsMd(config: HarnessConfig): string {\n const { name, description, docsPath } = config.project\n const port = config.tools.mcp.port\n\n return `# AGENTS.md — ${name}\n\n> **Read this file first.** It is the navigation map for every AI agent working in this repository.\n\n## Project\n\n**${name}** — ${description}\n\n## Health check (run before starting)\n\n\\`\\`\\`bash\nbash health.sh\n\\`\\`\\`\n\nIf it exits non-zero, stop and report the issue. Do not proceed with tasks until health is green.\n\n## Harness data (source of truth)\n\n| File | Purpose |\n|------|---------|\n| \\`.harness/harness.db\\` | SQLite: all tasks, actions, file changes, tool calls |\n| \\`.harness/current.md\\` | Markdown fallback — read this if MCP server is unavailable |\n| \\`.harness/feature_list.json\\` | Human-editable task seed list |\n\n## MCP tools (preferred)\n\nThe harness exposes tools via MCP server on port ${port}. Use these instead of reading files directly.\n\n\\`\\`\\`\nactions.start taskId agent → start an action, returns actionId\nactions.write actionId section text → record a section (result, tools_used, ...)\nactions.complete actionId summary → close the action\nactions.get taskId → full action history for a task\ntasks.get [status] → list tasks (pending | in_progress | done | blocked)\ntasks.claim id → atomically claim a pending task\ntasks.update id status → change task status\ndocs.search query → search ${docsPath} for relevant content\n\\`\\`\\`\n\n## Workflow\n\n\\`\\`\\`\n1. INIT\n - Run health.sh → exit 1 means stop\n - tasks.get('in_progress') → resume if something is in progress\n - tasks.get('pending') → pick lowest id\n\n2. WORK (lead → explorer → builder → reviewer)\n - Each agent calls actions.start(taskId, agentName) → actionId\n - Records work with actions.write(actionId, section, content)\n - Closes with actions.complete(actionId, summary)\n\n3. CLOSE\n - tasks.update(taskId, 'done')\n - Run health.sh → must be green before closing\n\\`\\`\\`\n\n## Agent roles\n\n| Agent | Responsibility |\n|-------|---------------|\n| lead | Decomposes the task into a plan, assigns sub-agents |\n| explorer | Reads and maps relevant code, never writes |\n| builder | Implements the plan, writes files |\n| reviewer | Verifies acceptance criteria, approves or blocks |\n\n## What to read\n\n\\`\\`\\`\nAlways: .harness/current.md (or MCP tasks.get)\nIf implementing: ${docsPath}/\nIf orchestrating: Agent definition files in your provider's agents directory\n\\`\\`\\`\n`\n}\n\n// ─── agent-harness-kit.config.ts template ───────────────────────────────────────────\n\nexport function configTs(params: {\n name: string\n description: string\n provider: string\n docsPath: string\n tasksAdapter: string\n port: number\n}): string {\n return `import { defineHarness } from '@cardor/agent-harness-kit'\n\nexport default defineHarness({\n project: {\n name: '${params.name}',\n description: '${params.description}',\n docsPath: '${params.docsPath}',\n },\n\n provider: '${params.provider}',\n\n agents: {\n lead: { instructionsPath: null },\n explorer: { instructionsPath: null, allowedPaths: ['${params.docsPath}', './src'] },\n builder: { instructionsPath: null, writablePaths: ['./src', './tests'] },\n reviewer: { instructionsPath: null },\n custom: [],\n },\n\n storage: {\n dir: '.harness',\n dbPath: '.harness/harness.db',\n tasks: { adapter: '${params.tasksAdapter}' },\n sections: {\n toolsUsed: true,\n filesModified: true,\n result: true,\n blockers: true,\n nextSteps: false,\n },\n markdownFallback: { enabled: true, path: '.harness/current.md' },\n },\n\n health: {\n scriptPath: './health.sh',\n required: true,\n },\n\n tools: {\n mcp: { enabled: true, port: ${params.port} },\n scripts: { enabled: true, outputDir: './.harness/scripts' },\n },\n})\n`\n}\n\n// ─── Agent definition templates (loaded from agent-templates/*.md) ─────────────\n\nexport function agentLead(vars: { projectName: string }): string {\n return loadAgentTemplate('lead', vars)\n}\n\nexport function agentExplorer(vars: { projectName: string; allowedPaths: string }): string {\n return loadAgentTemplate('explorer', vars)\n}\n\nexport function agentBuilder(vars: { projectName: string; writablePaths: string }): string {\n return loadAgentTemplate('builder', vars)\n}\n\nexport function agentReviewer(vars: { projectName: string }): string {\n return loadAgentTemplate('reviewer', vars)\n}\n\n// ─── feature_list.json initial seed ──────────────────────────────────────────\n\nexport function featureListJson(\n tasks: { slug: string; title: string; description?: string; acceptance?: string[] }[]\n): string {\n return JSON.stringify(tasks, null, 2) + '\\n'\n}\n\n// ─── .gitignore additions ─────────────────────────────────────────────────────\n\nexport const GITIGNORE_ENTRIES = `\n# agent-harness-kit\n.harness/harness.db\n.harness/harness.db-shm\n.harness/harness.db-wal\n.harness/current.md\n`\n","import { existsSync, mkdirSync, writeFileSync } from 'node:fs'\nimport { join, resolve } from 'node:path'\n\nimport { mergeOpencodeJson } from './mcp-merge'\nimport { appendGitignore, slugify, writeAgentFile } from './scaffold-utils'\nimport { agentBuilder, agentExplorer, agentLead, agentReviewer, agentsMd, featureListJson, HEALTH_SH } from './templates'\n\nimport type { HarnessConfig, Provider, ScaffoldOptions } from '@/types'\nimport type { Materializer } from './index'\n\nexport class OpenCodeMaterializer implements Materializer {\n async scaffold(config: HarnessConfig, opts: ScaffoldOptions): Promise<void> {\n const { cwd } = opts\n\n const write = (relPath: string, content: string, mode?: number) => {\n const abs = join(cwd, relPath)\n mkdirSync(resolve(abs, '..'), { recursive: true })\n writeFileSync(abs, content, { encoding: 'utf8', mode })\n }\n\n // AGENTS.md — always overwrite (generated from config)\n write('AGENTS.md', agentsMd(config))\n\n // health.sh — only create if it doesn't exist\n if (!existsSync(join(cwd, 'health.sh'))) {\n write('health.sh', HEALTH_SH, 0o755)\n }\n\n const tasks = opts.firstTask\n ? [{ slug: slugify(opts.firstTask.title), ...opts.firstTask }]\n : []\n write(join(config.storage.dir, 'feature_list.json'), featureListJson(tasks))\n\n if (!existsSync(join(cwd, config.storage.markdownFallback.path))) {\n write(\n config.storage.markdownFallback.path,\n `<!-- AUTO-GENERATED by agent-harness-kit — DO NOT EDIT MANUALLY -->\\n<!-- Run ahk status to refresh -->\\n\\n# Current Session\\n\\nNo tasks in progress.\\n`\n )\n }\n\n // .opencode/agents/ — skip files the dev may have customized\n const projectName = config.project.name\n const allowedPaths = (config.agents.explorer.allowedPaths ?? []).join(', ')\n const writablePaths = (config.agents.builder.writablePaths ?? []).join(', ')\n writeAgentFile(cwd, '.opencode/agents/lead.md', agentLead({ projectName }))\n writeAgentFile(cwd, '.opencode/agents/explorer.md', agentExplorer({ projectName, allowedPaths }))\n writeAgentFile(cwd, '.opencode/agents/builder.md', agentBuilder({ projectName, writablePaths }))\n writeAgentFile(cwd, '.opencode/agents/reviewer.md', agentReviewer({ projectName }))\n\n // opencode.json — MERGE, never overwrite whole file\n mergeOpencodeJson(join(cwd, 'opencode.json'), config.tools.mcp.port)\n\n appendGitignore(cwd)\n }\n\n async build(config: HarnessConfig, cwd: string): Promise<void> {\n const write = (relPath: string, content: string) => {\n const abs = join(cwd, relPath)\n mkdirSync(resolve(abs, '..'), { recursive: true })\n writeFileSync(abs, content, 'utf8')\n }\n\n write('AGENTS.md', agentsMd(config))\n\n const projectName = config.project.name\n const allowedPaths = (config.agents.explorer.allowedPaths ?? []).join(', ')\n const writablePaths = (config.agents.builder.writablePaths ?? []).join(', ')\n writeAgentFile(cwd, '.opencode/agents/lead.md', agentLead({ projectName }))\n writeAgentFile(cwd, '.opencode/agents/explorer.md', agentExplorer({ projectName, allowedPaths }))\n writeAgentFile(cwd, '.opencode/agents/builder.md', agentBuilder({ projectName, writablePaths }))\n writeAgentFile(cwd, '.opencode/agents/reviewer.md', agentReviewer({ projectName }))\n\n mergeOpencodeJson(join(cwd, 'opencode.json'), config.tools.mcp.port)\n }\n\n async migrate(config: HarnessConfig, _to: Provider, _cwd: string): Promise<void> {\n void config\n }\n}\n\n","import { ClaudeCodeMaterializer } from './claude-code'\nimport { OpenCodeMaterializer } from './opencode'\n\nimport type { HarnessConfig, Provider, ScaffoldOptions } from '@/types'\n\nexport interface Materializer {\n scaffold(config: HarnessConfig, opts: ScaffoldOptions): Promise<void>\n build(config: HarnessConfig, cwd: string): Promise<void>\n migrate(config: HarnessConfig, to: Provider, cwd: string): Promise<void>\n}\n\nexport function getMaterializer(provider: Provider): Materializer {\n switch (provider) {\n case 'claude-code':\n return new ClaudeCodeMaterializer()\n case 'opencode':\n return new OpenCodeMaterializer()\n default:\n throw new Error(`Unknown provider: ${provider as string}`)\n }\n}\n","import { dirname, join, resolve } from 'node:path'\nimport { fileURLToPath } from 'node:url'\nimport pc from 'picocolors'\n\nimport { loadConfig } from '@/core/config'\nimport { startDashboardServer } from '@/core/dashboard-server'\nimport { openDB } from '@/core/db'\n\nconst __dirname = dirname(fileURLToPath(import.meta.url))\n\ninterface DashboardOptions {\n port: number\n open: boolean\n}\n\nexport async function runDashboard(cwd: string, opts: DashboardOptions): Promise<void> {\n const config = await loadConfig(cwd)\n const db = openDB(config, cwd)\n const dbPath = resolve(cwd, config.storage.dbPath)\n const staticPath = join(__dirname, 'dashboard-dist')\n\n const { url } = startDashboardServer(db, dbPath, staticPath, opts.port)\n\n console.log(pc.green(`✓`) + ` Dashboard running at ${pc.bold(pc.cyan(url))}`)\n console.log(pc.dim(` WebSocket live updates enabled`))\n console.log(pc.dim(` Press Ctrl+C to stop`))\n\n if (opts.open) {\n const { default: open } = await import('open')\n await open(url)\n }\n\n process.on('SIGINT', () => {\n process.exit(0)\n })\n\n // Keep process alive until SIGINT\n await new Promise<void>(() => { })\n}\n","import { watch } from 'node:fs'\nimport { existsSync, readFileSync } from 'node:fs'\nimport { extname,join } from 'node:path'\nimport { serve } from '@hono/node-server'\nimport { Hono } from 'hono'\nimport { WebSocketServer } from 'ws'\n\nimport type { HarnessDB } from './db'\nimport type {\n AgentStatRow,\n CountRow,\n RecentFileRow,\n RecentToolRow,\n TaskListRow,\n TimelineRow,\n TopFileRow,\n} from './server-types'\nimport type { IncomingMessage } from 'node:http'\nimport type { Socket } from 'node:net'\n\nconst AGENT_ORDER = ['lead', 'explorer', 'builder', 'reviewer']\n\n// ─── Static file serving ──────────────────────────────────────────────────────\n\nconst MIME: Record<string, string> = {\n '.html': 'text/html; charset=utf-8',\n '.js': 'application/javascript; charset=utf-8',\n '.mjs': 'application/javascript; charset=utf-8',\n '.css': 'text/css; charset=utf-8',\n '.json': 'application/json; charset=utf-8',\n '.svg': 'image/svg+xml',\n '.png': 'image/png',\n '.ico': 'image/x-icon',\n '.woff': 'font/woff',\n '.woff2': 'font/woff2',\n '.ttf': 'font/ttf',\n}\n\nfunction fileResponse(filePath: string): Response {\n const content = readFileSync(filePath)\n const mime = MIME[extname(filePath)] ?? 'application/octet-stream'\n return new Response(content, {\n headers: { 'Content-Type': mime, 'Cache-Control': 'no-cache' },\n })\n}\n\n// ─── Server ───────────────────────────────────────────────────────────────────\n\nexport interface DashboardServerResult {\n url: string\n close: () => void\n}\n\nexport function startDashboardServer(\n db: HarnessDB,\n dbPath: string,\n staticPath: string,\n port: number,\n): DashboardServerResult {\n const app = new Hono()\n\n // ─── CORS ─────────────────────────────────────────────────────────────────\n app.use('/api/*', async (c, next) => {\n await next()\n c.res.headers.set('Access-Control-Allow-Origin', '*')\n })\n\n // ─── Stats overview ───────────────────────────────────────────────────────\n app.get('/api/stats', (c) => {\n const summary = db.getStatusSummary()\n const byStatus: Record<string, number> = { pending: 0, in_progress: 0, done: 0, blocked: 0 }\n for (const { status, total } of summary) byStatus[status] = total\n\n const [{ total: totalActions }] = db.queryRaw<CountRow>(`SELECT COUNT(*) as total FROM actions`)\n const [{ total: totalFiles }] = db.queryRaw<CountRow>(`SELECT COUNT(*) as total FROM action_files`)\n const [{ total: uniqueTools }] = db.queryRaw<CountRow>(`SELECT COUNT(DISTINCT tool_name) as total FROM action_tools`)\n const [{ total: activeAgents }] = db.queryRaw<CountRow>(\n `SELECT COUNT(DISTINCT agent) as total FROM actions WHERE status = 'in_progress'`,\n )\n\n return c.json({ byStatus, totalActions, totalFiles, uniqueTools, activeAgents })\n })\n\n // ─── Meta ─────────────────────────────────────────────────────────────────\n app.get('/api/meta', (c) => {\n return c.json({ ok: true })\n })\n\n // ─── Tasks list ───────────────────────────────────────────────────────────\n app.get('/api/tasks', (c) => {\n const rows = db.queryRaw<TaskListRow>(`\n SELECT t.*,\n COUNT(ta.id) as acceptance_total,\n COALESCE(SUM(ta.met), 0) as acceptance_met\n FROM tasks t\n LEFT JOIN task_acceptance ta ON ta.task_id = t.id\n GROUP BY t.id\n ORDER BY t.id\n `)\n return c.json(rows)\n })\n\n // ─── Task detail ──────────────────────────────────────────────────────────\n app.get('/api/tasks/:id', (c) => {\n const id = parseInt(c.req.param('id'))\n const task = db.getTaskById(id)\n if (!task) return c.json({ error: 'Not found' }, 404)\n\n const acceptance = db.getTaskAcceptance(id)\n const actions = db.getActionsForTask(id).map((action) => ({\n ...action,\n sections: db.getActionSections(action.id),\n files: db.queryRaw(`SELECT * FROM action_files WHERE action_id = ?`, action.id),\n tools: db.queryRaw(`SELECT * FROM action_tools WHERE action_id = ? ORDER BY called_at`, action.id),\n }))\n\n return c.json({ ...task, acceptance, actions })\n })\n\n // ─── Tools top ────────────────────────────────────────────────────────────\n app.get('/api/tools/top', (c) => {\n const limit = parseInt(c.req.query('limit') ?? '20')\n return c.json(db.getTopTools(limit))\n })\n\n // ─── Tools recent ─────────────────────────────────────────────────────────\n app.get('/api/tools/recent', (c) => {\n const limit = parseInt(c.req.query('limit') ?? '50')\n const rows = db.queryRaw<RecentToolRow>(`\n SELECT at.*, t.id as task_id, t.title as task_title, t.slug as task_slug, a.agent\n FROM action_tools at\n JOIN actions a ON at.action_id = a.id\n JOIN tasks t ON a.task_id = t.id\n ORDER BY at.called_at DESC\n LIMIT ?\n `, limit)\n return c.json(rows)\n })\n\n // ─── Files top ────────────────────────────────────────────────────────────\n app.get('/api/files/top', (c) => {\n const limit = parseInt(c.req.query('limit') ?? '20')\n const rows = db.queryRaw<TopFileRow>(`\n SELECT\n file_path,\n COUNT(*) as total,\n SUM(CASE WHEN operation='read' THEN 1 ELSE 0 END) as read,\n SUM(CASE WHEN operation='created' THEN 1 ELSE 0 END) as created,\n SUM(CASE WHEN operation='modified' THEN 1 ELSE 0 END) as modified,\n SUM(CASE WHEN operation='deleted' THEN 1 ELSE 0 END) as deleted\n FROM action_files\n GROUP BY file_path\n ORDER BY total DESC\n LIMIT ?\n `, limit)\n return c.json(rows)\n })\n\n // ─── Files recent ─────────────────────────────────────────────────────────\n app.get('/api/files/recent', (c) => {\n const limit = parseInt(c.req.query('limit') ?? '50')\n const rows = db.queryRaw<RecentFileRow>(`\n SELECT af.*, t.id as task_id, t.title as task_title, t.slug as task_slug,\n a.agent, a.created_at as called_at\n FROM action_files af\n JOIN actions a ON af.action_id = a.id\n JOIN tasks t ON a.task_id = t.id\n ORDER BY a.created_at DESC\n LIMIT ?\n `, limit)\n return c.json(rows)\n })\n\n // ─── Agents stats ─────────────────────────────────────────────────────────\n app.get('/api/agents/stats', (c) => {\n const rows = db.queryRaw<AgentStatRow>(`\n SELECT\n a.agent,\n COUNT(*) as actions_total,\n SUM(CASE WHEN a.status='completed' THEN 1 ELSE 0 END) as actions_done,\n SUM(CASE WHEN a.status='blocked' THEN 1 ELSE 0 END) as actions_blocked,\n COUNT(DISTINCT a.task_id) as tasks_worked,\n COUNT(DISTINCT af.file_path) as files_touched\n FROM actions a\n LEFT JOIN action_files af ON af.action_id = a.id\n GROUP BY a.agent\n ORDER BY actions_total DESC\n `)\n const sorted = rows.sort((a, b) => {\n const ai = AGENT_ORDER.indexOf(a.agent)\n const bi = AGENT_ORDER.indexOf(b.agent)\n if (ai === -1 && bi === -1) return 0\n if (ai === -1) return 1\n if (bi === -1) return -1\n return ai - bi\n })\n return c.json(sorted)\n })\n\n // ─── Timeline ─────────────────────────────────────────────────────────────\n app.get('/api/timeline', (c) => {\n const limit = parseInt(c.req.query('limit') ?? '50')\n const rows = db.queryRaw<TimelineRow>(`\n SELECT a.*, t.title as task_title, t.slug as task_slug, t.status as task_status\n FROM actions a\n JOIN tasks t ON a.task_id = t.id\n ORDER BY a.created_at DESC\n LIMIT ?\n `, limit)\n return c.json(rows)\n })\n\n // ─── Static SPA ───────────────────────────────────────────────────────────\n app.get('/*', (c) => {\n const urlPath = c.req.path\n if (urlPath !== '/') {\n const candidate = join(staticPath, urlPath)\n if (existsSync(candidate)) {\n try { return fileResponse(candidate) } catch { /* fall through */ }\n }\n }\n return fileResponse(join(staticPath, 'index.html'))\n })\n\n // ─── Start HTTP server ────────────────────────────────────────────────────\n const httpServer = serve({ fetch: app.fetch, port })\n\n // ─── WebSocket ────────────────────────────────────────────────────────────\n const wss = new WebSocketServer({ noServer: true })\n\n httpServer.on('upgrade', (req: IncomingMessage, socket: Socket, head: Buffer) => {\n if (req.url === '/ws') {\n wss.handleUpgrade(req, socket, head, (ws) => {\n wss.emit('connection', ws, req)\n })\n } else {\n socket.destroy()\n }\n })\n\n // ─── DB file watcher → broadcast update ──────────────────────────────────\n let debounce: ReturnType<typeof setTimeout>\n\n const broadcast = () => {\n clearTimeout(debounce)\n debounce = setTimeout(() => {\n for (const client of wss.clients) {\n if (client.readyState === 1) {\n client.send(JSON.stringify({ type: 'update' }))\n }\n }\n }, 150)\n }\n\n // Watch WAL file for writes (more responsive in WAL mode)\n const walPath = `${dbPath}-wal`\n const watchTarget = existsSync(walPath) ? walPath : dbPath\n const watcher = watch(watchTarget, broadcast)\n\n return {\n url: `http://localhost:${port}`,\n close: () => {\n clearTimeout(debounce)\n watcher.close()\n wss.close()\n httpServer.close()\n },\n }\n}\n","import { randomUUID } from 'node:crypto'\nimport { mkdirSync, writeFileSync } from 'node:fs'\nimport { dirname, join, resolve } from 'node:path'\n\nimport { lastInsertId, openSQLite, type SQLiteDB } from './sqlite-adapter'\n\nimport type {\n ActionFileRow,\n ActionRow,\n ActionSectionRow,\n AgentName,\n HarnessConfig,\n TaskAcceptanceRow,\n TaskRow,\n TaskStatus,\n} from '@/types'\n\n// ─── Schema ───────────────────────────────────────────────────────────────────\n\nconst SCHEMA = `\nCREATE TABLE IF NOT EXISTS tasks (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n slug TEXT NOT NULL UNIQUE,\n title TEXT NOT NULL,\n description TEXT,\n status TEXT NOT NULL DEFAULT 'pending'\n CHECK(status IN ('pending','in_progress','done','blocked')),\n assigned_to TEXT,\n created_at TEXT NOT NULL,\n started_at TEXT,\n completed_at TEXT\n);\n\nCREATE TABLE IF NOT EXISTS task_acceptance (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n task_id INTEGER NOT NULL REFERENCES tasks(id) ON DELETE CASCADE,\n criterion TEXT NOT NULL,\n met INTEGER NOT NULL DEFAULT 0\n);\n\nCREATE TABLE IF NOT EXISTS actions (\n id TEXT PRIMARY KEY,\n task_id INTEGER NOT NULL REFERENCES tasks(id) ON DELETE CASCADE,\n agent TEXT NOT NULL\n CHECK(agent IN ('lead','explorer','builder','reviewer') OR agent LIKE 'custom:%'),\n status TEXT NOT NULL DEFAULT 'in_progress'\n CHECK(status IN ('in_progress','completed','blocked')),\n created_at TEXT NOT NULL,\n completed_at TEXT,\n summary TEXT\n);\n\nCREATE TABLE IF NOT EXISTS action_sections (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n action_id TEXT NOT NULL REFERENCES actions(id) ON DELETE CASCADE,\n section_type TEXT NOT NULL,\n content TEXT NOT NULL,\n created_at TEXT NOT NULL\n);\n\nCREATE TABLE IF NOT EXISTS action_files (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n action_id TEXT NOT NULL REFERENCES actions(id) ON DELETE CASCADE,\n file_path TEXT NOT NULL,\n operation TEXT NOT NULL\n CHECK(operation IN ('read','created','modified','deleted')),\n notes TEXT\n);\n\nCREATE TABLE IF NOT EXISTS action_tools (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n action_id TEXT NOT NULL REFERENCES actions(id) ON DELETE CASCADE,\n tool_name TEXT NOT NULL,\n args_json TEXT,\n result_summary TEXT,\n called_at TEXT NOT NULL\n);\n\nCREATE INDEX IF NOT EXISTS idx_tasks_status ON tasks(status);\nCREATE INDEX IF NOT EXISTS idx_actions_task_id ON actions(task_id);\nCREATE INDEX IF NOT EXISTS idx_actions_agent ON actions(agent);\nCREATE INDEX IF NOT EXISTS idx_actions_status ON actions(status);\nCREATE INDEX IF NOT EXISTS idx_action_files_path ON action_files(file_path);\nCREATE INDEX IF NOT EXISTS idx_action_tools_name ON action_tools(tool_name);\n`\n\n// ─── DB class ─────────────────────────────────────────────────────────────────\n\nexport class HarnessDB {\n private db: SQLiteDB\n private config: HarnessConfig\n\n constructor(dbPath: string, config: HarnessConfig) {\n this.config = config\n const abs = resolve(dbPath)\n mkdirSync(dirname(abs), { recursive: true })\n this.db = openSQLite(abs)\n this.db.exec(`PRAGMA journal_mode = WAL`)\n this.db.exec(`PRAGMA foreign_keys = ON`)\n this.db.exec(SCHEMA)\n }\n\n // ─── Tasks ────────────────────────────────────────────────────────────────\n\n addTask(params: {\n slug: string\n title: string\n description?: string\n acceptance?: string[]\n }): TaskRow {\n const now = new Date().toISOString()\n this.db\n .prepare(\n `INSERT INTO tasks (slug, title, description, status, created_at)\n VALUES (@slug, @title, @description, 'pending', @created_at)`\n )\n .run({\n slug: params.slug,\n title: params.title,\n description: params.description ?? null,\n created_at: now,\n })\n\n const taskId = lastInsertId(this.db)\n\n if (params.acceptance?.length) {\n const accStmt = this.db.prepare(\n `INSERT INTO task_acceptance (task_id, criterion) VALUES (?, ?)`\n )\n for (const criterion of params.acceptance) {\n accStmt.run(taskId, criterion)\n }\n }\n\n this.regenerateCurrentMd()\n return this.getTaskById(taskId)!\n }\n\n getTasks(status?: TaskStatus): TaskRow[] {\n if (status) {\n return this.db\n .prepare(`SELECT * FROM tasks WHERE status = ? ORDER BY id`)\n .all(status) as unknown as TaskRow[]\n }\n return this.db.prepare(`SELECT * FROM tasks ORDER BY id`).all() as unknown as TaskRow[]\n }\n\n getTaskById(id: number): TaskRow | null {\n return (this.db.prepare(`SELECT * FROM tasks WHERE id = ?`).get(id) as unknown as TaskRow) ?? null\n }\n\n getTaskBySlug(slug: string): TaskRow | null {\n return (this.db.prepare(`SELECT * FROM tasks WHERE slug = ?`).get(slug) as unknown as TaskRow) ?? null\n }\n\n getTaskAcceptance(taskId: number): TaskAcceptanceRow[] {\n return this.db\n .prepare(`SELECT * FROM task_acceptance WHERE task_id = ?`)\n .all(taskId) as unknown as TaskAcceptanceRow[]\n }\n\n updateTaskStatus(idOrSlug: number | string, status: TaskStatus): TaskRow {\n const now = new Date().toISOString()\n const task =\n typeof idOrSlug === 'number' ? this.getTaskById(idOrSlug) : this.getTaskBySlug(idOrSlug)\n if (!task) throw new Error(`Task not found: ${idOrSlug}`)\n\n if (status === 'in_progress' && !task.started_at) {\n this.db\n .prepare(\n `UPDATE tasks SET status = ?, started_at = ? WHERE id = ?`\n )\n .run(status, now, task.id)\n } else if (status === 'done') {\n this.db\n .prepare(\n `UPDATE tasks SET status = ?, completed_at = ? WHERE id = ?`\n )\n .run(status, now, task.id)\n } else {\n this.db.prepare(`UPDATE tasks SET status = ? WHERE id = ?`).run(status, task.id)\n }\n\n this.regenerateCurrentMd()\n return this.getTaskById(task.id)!\n }\n\n claimTask(id: number, agent: string): TaskRow | null {\n const now = new Date().toISOString()\n this.db.exec('BEGIN IMMEDIATE')\n try {\n this.db\n .prepare(\n `UPDATE tasks SET status = 'in_progress', assigned_to = ?, started_at = ?\n WHERE id = ? AND status = 'pending'`\n )\n .run(agent, now, id)\n this.db.exec('COMMIT')\n\n // Verify the claim succeeded by reading back — if status changed, we own it\n const task = this.getTaskById(id)\n if (!task || task.status !== 'in_progress' || task.assigned_to !== agent) return null\n\n this.regenerateCurrentMd()\n return task\n } catch (err) {\n this.db.exec('ROLLBACK')\n throw err\n }\n }\n\n // ─── Actions ──────────────────────────────────────────────────────────────\n\n startAction(taskId: number, agent: AgentName): ActionRow {\n const now = new Date().toISOString()\n const id = randomUUID()\n this.db\n .prepare(\n `INSERT INTO actions (id, task_id, agent, status, created_at)\n VALUES (?, ?, ?, 'in_progress', ?)`\n )\n .run(id, taskId, agent, now)\n\n this.regenerateCurrentMd()\n return this.getAction(id)!\n }\n\n writeSection(actionId: string, sectionType: string, content: string): void {\n const now = new Date().toISOString()\n this.db\n .prepare(\n `INSERT INTO action_sections (action_id, section_type, content, created_at)\n VALUES (?, ?, ?, ?)`\n )\n .run(actionId, sectionType, content, now)\n\n this.regenerateCurrentMd()\n }\n\n completeAction(actionId: string, summary: string): ActionRow {\n const now = new Date().toISOString()\n this.db\n .prepare(\n `UPDATE actions SET status = 'completed', completed_at = ?, summary = ?\n WHERE id = ?`\n )\n .run(now, summary, actionId)\n\n this.regenerateCurrentMd()\n return this.getAction(actionId)!\n }\n\n getAction(actionId: string): ActionRow | null {\n return (\n (this.db.prepare(`SELECT * FROM actions WHERE id = ?`).get(actionId) as unknown as ActionRow) ?? null\n )\n }\n\n getActionsForTask(taskId: number): ActionRow[] {\n return this.db\n .prepare(`SELECT * FROM actions WHERE task_id = ? ORDER BY created_at`)\n .all(taskId) as unknown as ActionRow[]\n }\n\n getActionSections(actionId: string): ActionSectionRow[] {\n return this.db\n .prepare(\n `SELECT * FROM action_sections WHERE action_id = ? ORDER BY created_at`\n )\n .all(actionId) as unknown as ActionSectionRow[]\n }\n\n recordFile(\n actionId: string,\n filePath: string,\n operation: ActionFileRow['operation'],\n notes?: string\n ): void {\n this.db\n .prepare(\n `INSERT INTO action_files (action_id, file_path, operation, notes)\n VALUES (?, ?, ?, ?)`\n )\n .run(actionId, filePath, operation, notes ?? null)\n }\n\n recordTool(\n actionId: string,\n toolName: string,\n argsJson?: string,\n resultSummary?: string\n ): void {\n const now = new Date().toISOString()\n this.db\n .prepare(\n `INSERT INTO action_tools (action_id, tool_name, args_json, result_summary, called_at)\n VALUES (?, ?, ?, ?, ?)`\n )\n .run(actionId, toolName, argsJson ?? null, resultSummary ?? null, now)\n }\n\n getFilesForTask(taskId: number): (ActionFileRow & { agent: AgentName })[] {\n return this.db\n .prepare(\n `SELECT af.*, a.agent\n FROM action_files af\n JOIN actions a ON af.action_id = a.id\n WHERE a.task_id = ?\n ORDER BY a.agent, af.operation`\n )\n .all(taskId) as unknown as (ActionFileRow & { agent: AgentName })[]\n }\n\n getTopTools(limit = 10): { tool_name: string; uses: number }[] {\n return this.db\n .prepare(\n `SELECT tool_name, COUNT(*) as uses\n FROM action_tools\n GROUP BY tool_name\n ORDER BY uses DESC\n LIMIT ?`\n )\n .all(limit) as { tool_name: string; uses: number }[]\n }\n\n getStatusSummary(): { status: string; total: number }[] {\n return this.db\n .prepare(`SELECT status, COUNT(*) as total FROM tasks GROUP BY status`)\n .all() as { status: string; total: number }[]\n }\n\n // ─── current.md fallback ──────────────────────────────────────────────────\n\n regenerateCurrentMd(): void {\n if (!this.config.storage.markdownFallback.enabled) return\n\n const mdPath = resolve(this.config.storage.markdownFallback.path)\n mkdirSync(dirname(mdPath), { recursive: true })\n\n const inProgress = this.getTasks('in_progress')\n const now = new Date().toISOString()\n\n let md = `<!-- AUTO-GENERATED by agent-harness-kit — DO NOT EDIT MANUALLY -->\\n`\n md += `<!-- Last updated: ${now} -->\\n\\n`\n md += `# Current Session\\n\\n`\n\n if (inProgress.length === 0) {\n md += `## No tasks in progress\\n\\n`\n const pending = this.getTasks('pending')\n if (pending.length > 0) {\n md += `### Next pending tasks\\n`\n for (const t of pending.slice(0, 5)) {\n md += `- **#${t.id}** ${t.title} (\\`${t.slug}\\`)\\n`\n }\n }\n } else {\n for (const task of inProgress) {\n md += `## Active Task\\n`\n md += `- **ID:** ${task.id}\\n`\n md += `- **Slug:** ${task.slug}\\n`\n md += `- **Status:** ${task.status}\\n`\n md += `- **Started:** ${task.started_at ?? 'unknown'}\\n\\n`\n\n const actions = this.getActionsForTask(task.id)\n if (actions.length > 0) {\n md += `## Actions this session\\n`\n md += `| Agent | Status | Summary | Started |\\n`\n md += `|----------|-------------|----------------------------------|-------------|\\n`\n for (const a of actions) {\n const started = a.created_at.slice(11, 16)\n const summary = (a.summary ?? '').slice(0, 34).padEnd(34)\n md += `| ${a.agent.padEnd(8)} | ${a.status.padEnd(11)} | ${summary} | ${started} |\\n`\n }\n md += `\\n`\n }\n\n const acceptance = this.getTaskAcceptance(task.id)\n if (acceptance.length > 0) {\n md += `## Acceptance Criteria\\n`\n for (const a of acceptance) {\n md += `- [${a.met ? 'x' : ' '}] ${a.criterion}\\n`\n }\n md += `\\n`\n }\n }\n }\n\n writeFileSync(mdPath, md, 'utf8')\n }\n\n // ─── Raw query (dashboard / analytics) ───────────────────────────────────\n\n queryRaw<T = Record<string, unknown>>(sql: string, ...params: unknown[]): T[] {\n return this.db.prepare(sql).all(...params) as unknown as T[]\n }\n\n // ─── Export helpers ───────────────────────────────────────────────────────\n\n exportJson(): { tasks: TaskRow[]; actions: ActionRow[]; sections: ActionSectionRow[] } {\n return {\n tasks: this.getTasks(),\n actions: this.db\n .prepare(`SELECT * FROM actions ORDER BY created_at`)\n .all() as unknown as ActionRow[],\n sections: this.db\n .prepare(`SELECT * FROM action_sections ORDER BY created_at`)\n .all() as unknown as ActionSectionRow[],\n }\n }\n\n close(): void {\n this.db.close()\n }\n\n // ─── feature_list.json sync ───────────────────────────────────────────────\n\n syncFromFeatureList(\n tasks: {\n slug: string\n title: string\n description?: string\n acceptance?: string[]\n }[]\n ): { added: number; skipped: number } {\n let added = 0\n let skipped = 0\n\n for (const t of tasks) {\n if (this.getTaskBySlug(t.slug)) {\n skipped++\n continue\n }\n this.addTask(t)\n added++\n }\n\n return { added, skipped }\n }\n\n writeFeatureList(cwd: string): void {\n const tasks = this.getTasks()\n const list = tasks.map((t) => ({\n slug: t.slug,\n title: t.title,\n description: t.description ?? undefined,\n acceptance: this.getTaskAcceptance(t.id).map((a) => a.criterion),\n status: t.status,\n }))\n\n const path = join(resolve(cwd), this.config.storage.dir, 'feature_list.json')\n mkdirSync(dirname(path), { recursive: true })\n writeFileSync(path, JSON.stringify(list, null, 2) + '\\n', 'utf8')\n }\n}\n\nexport function openDB(config: HarnessConfig, cwd: string): HarnessDB {\n const dbPath = join(resolve(cwd), config.storage.dbPath)\n return new HarnessDB(dbPath, config)\n}\n","import { createRequire } from 'node:module'\n\nconst _require = createRequire(import.meta.url)\nconst isBun = 'bun' in process.versions\n\n// ─── Shared interface ─────────────────────────────────────────────────────────\n// Both node:sqlite (DatabaseSync) and bun:sqlite (Database) expose this surface.\n\nexport type SQLRow = Record<string, unknown>\n\nexport interface SQLStatement {\n run(...args: unknown[]): unknown\n get(...args: unknown[]): SQLRow | undefined\n all(...args: unknown[]): SQLRow[]\n}\n\nexport interface SQLiteDB {\n exec(sql: string): void\n prepare(sql: string): SQLStatement\n close(): void\n}\n\n// ─── Factory ─────────────────────────────────────────────────────────────────\n\nexport function openSQLite(path: string): SQLiteDB {\n if (isBun) {\n const { Database } = _require('bun:sqlite') as {\n Database: new (path: string) => unknown\n }\n return new Database(path) as unknown as SQLiteDB\n }\n\n const { DatabaseSync } = _require('node:sqlite') as {\n DatabaseSync: new (path: string) => unknown\n }\n return new DatabaseSync(path) as unknown as SQLiteDB\n}\n\n// ─── last_insert_rowid() helper ───────────────────────────────────────────────\n// Both bun:sqlite and node:sqlite have different return types for stmt.run().\n// Reading last_insert_rowid() directly avoids the inconsistency.\n\nexport function lastInsertId(db: SQLiteDB): number {\n const row = db.prepare('SELECT last_insert_rowid() AS id').get() as { id: number }\n return row.id\n}\n","import { writeFileSync } from 'node:fs'\nimport pc from 'picocolors'\n\nimport { loadConfig } from '@/core/config'\nimport { openDB } from '@/core/db'\n\ninterface ExportOptions {\n sql?: boolean\n json?: boolean\n output?: string\n}\n\nexport async function runExport(cwd: string, opts: ExportOptions): Promise<void> {\n if (!opts.sql && !opts.json) {\n console.error(pc.red('Specify --sql or --json'))\n process.exit(1)\n }\n\n const config = await loadConfig(cwd)\n const db = openDB(config, cwd)\n\n try {\n if (opts.json) {\n const data = db.exportJson()\n const out = JSON.stringify(data, null, 2) + '\\n'\n if (opts.output) {\n writeFileSync(opts.output, out, 'utf8')\n console.log(pc.green(`✓ Exported JSON → ${opts.output}`))\n } else {\n process.stdout.write(out)\n }\n }\n\n if (opts.sql) {\n console.error(pc.dim('SQL dump requires direct SQLite access — use: sqlite3 .harness/harness.db .dump'))\n process.exit(1)\n }\n } finally {\n db.close()\n }\n}\n","import { spawnSync } from 'node:child_process'\nimport { existsSync } from 'node:fs'\nimport { join, resolve } from 'node:path'\nimport pc from 'picocolors'\n\nimport { loadConfig } from '@/core/config'\n\nfunction checkLine(label: string | null, ok: boolean, message: string, indent = 0): void {\n const prefix = label ? pc.cyan(`[${label}] `) : ' '.repeat(indent)\n const icon = ok ? pc.green('✓') : pc.red('✗')\n console.log(prefix + icon + ' ' + (ok ? pc.green(message) : pc.red(message)))\n}\n\nexport async function runHealth(cwd: string): Promise<void> {\n let config\n try {\n config = await loadConfig(cwd)\n } catch {\n console.error(pc.red('✗ No config found. Run: ahk init'))\n process.exit(1)\n }\n\n let allOk = true\n\n // ─── [checking DB] ──────────────────────────────────────────────────────────\n const dbPath = resolve(cwd, config.storage.dbPath)\n const dbOk = existsSync(dbPath)\n checkLine('checking DB', dbOk, `${config.storage.dbPath} reachable`)\n if (!dbOk) allOk = false\n\n // ─── [checking agents] ──────────────────────────────────────────────────────\n const agentsDir = config.provider === 'claude-code' ? '.claude/agents' : '.opencode/agents'\n const agentNames = ['lead', 'explorer', 'builder', 'reviewer']\n\n const agentsLabelWidth = '[checking agents] '.length\n for (let i = 0; i < agentNames.length; i++) {\n const name = agentNames[i]\n const agentPath = join(cwd, agentsDir, `${name}.md`)\n const ok = existsSync(agentPath)\n checkLine(i === 0 ? 'checking agents' : null, ok, `${name}.md present`, agentsLabelWidth)\n if (!ok) allOk = false\n }\n\n // ─── [checking MCP] ─────────────────────────────────────────────────────────\n if (config.tools.mcp.enabled) {\n const mcpFile = config.provider === 'claude-code' ? '.claude/mcp.json' : 'opencode.json'\n const mcpPath = resolve(cwd, mcpFile)\n const mcpOk = existsSync(mcpPath)\n checkLine('checking MCP', mcpOk, `${mcpFile} valid`)\n if (!mcpOk) allOk = false\n }\n\n if (!allOk) {\n console.log('')\n console.error(pc.red('✗ Harness checks failed — fix the above before running health.sh'))\n process.exit(1)\n }\n\n // ─── Run health.sh ──────────────────────────────────────────────────────────\n const scriptPath = resolve(cwd, config.health.scriptPath)\n\n if (!existsSync(scriptPath)) {\n console.error(pc.red(`✗ health.sh not found: ${scriptPath}`))\n console.error(' Run ahk init first.')\n process.exit(1)\n }\n\n const result = spawnSync('bash', [scriptPath], {\n cwd,\n stdio: 'inherit',\n encoding: 'utf8',\n })\n\n if (result.error) {\n console.error(pc.red(`✗ Failed to run health.sh: ${result.error.message}`))\n process.exit(1)\n }\n\n if (result.status === 0) {\n console.log(pc.green('✓ Health check passed'))\n process.exit(0)\n } else {\n console.error(pc.red(`✗ Health check failed (exit ${result.status ?? 'unknown'})`))\n process.exit(result.status ?? 1)\n }\n}\n","import { mkdirSync, writeFileSync } from 'node:fs'\nimport { join } from 'node:path'\nimport * as p from '@clack/prompts'\nimport pc from 'picocolors'\n\nimport { openDB } from '@/core/db'\nimport { getMaterializer } from '@/core/materializer/index'\nimport { slugify } from '@/core/materializer/scaffold-utils'\nimport { configTs } from '@/core/materializer/templates'\nimport { applyConfigDefaults } from './init-helpers'\n\nimport type { Provider } from '@/types'\n\ninterface InitOptions {\n name?: string\n provider?: string\n docs?: string\n tasks?: string\n}\n\nexport async function runInit(cwd: string, flags: InitOptions): Promise<void> {\n p.intro(pc.bold('agent-harness-kit — harness scaffolding'))\n\n // ─── Project name ────────────────────────────────────────────────────────\n let name: string\n if (flags.name) {\n name = flags.name\n } else {\n const val = await p.text({\n message: 'Project name',\n placeholder: 'my-app',\n validate: (v) => (v.trim() ? undefined : 'Project name is required'),\n })\n if (p.isCancel(val)) { p.cancel('Cancelled.'); process.exit(0) }\n name = val as string\n }\n\n // ─── Description ─────────────────────────────────────────────────────────\n const descVal = await p.text({\n message: 'Short description (shown to agents as context)',\n placeholder: 'A REST API for managing notes',\n })\n if (p.isCancel(descVal)) { p.cancel('Cancelled.'); process.exit(0) }\n const description = (descVal as string).trim() || name\n\n // ─── Provider ─────────────────────────────────────────────────────────────\n let provider: Provider\n if (flags.provider && ['claude-code', 'opencode'].includes(flags.provider)) {\n provider = flags.provider as Provider\n } else {\n const val = await p.select({\n message: 'AI provider',\n options: [\n { value: 'claude-code', label: 'Claude Code' },\n { value: 'opencode', label: 'OpenCode' },\n ],\n })\n if (p.isCancel(val)) { p.cancel('Cancelled.'); process.exit(0) }\n provider = val as Provider\n }\n\n // ─── Docs path ────────────────────────────────────────────────────────────\n let docsPath: string\n if (flags.docs) {\n docsPath = flags.docs\n } else {\n const val = await p.text({\n message: 'Docs folder path (agents will search here)',\n initialValue: './docs',\n })\n if (p.isCancel(val)) { p.cancel('Cancelled.'); process.exit(0) }\n docsPath = (val as string).trim() || './docs'\n }\n\n // ─── Task adapter ─────────────────────────────────────────────────────────\n let tasksAdapter: string\n if (flags.tasks && ['local', 'jira', 'linear'].includes(flags.tasks)) {\n tasksAdapter = flags.tasks\n } else {\n const val = await p.select({\n message: 'Task adapter',\n options: [\n { value: 'local', label: 'Local (feature_list.json)' },\n { value: 'jira', label: 'Jira (coming soon)' },\n { value: 'linear', label: 'Linear (coming soon)' },\n ],\n })\n if (p.isCancel(val)) { p.cancel('Cancelled.'); process.exit(0) }\n tasksAdapter = val as string\n }\n\n // ─── Optional first task ──────────────────────────────────────────────────\n const addFirstTask = await p.confirm({ message: 'Add your first task now?', initialValue: true })\n if (p.isCancel(addFirstTask)) { p.cancel('Cancelled.'); process.exit(0) }\n\n let firstTask: { title: string; description: string; acceptance: string[] } | undefined\n\n if (addFirstTask) {\n const titleVal = await p.text({\n message: 'Task title',\n validate: (v) => (v.trim() ? undefined : 'Title is required'),\n })\n if (p.isCancel(titleVal)) { p.cancel('Cancelled.'); process.exit(0) }\n const taskTitle = (titleVal as string).trim()\n\n const taskDescVal = await p.text({\n message: 'Task description',\n placeholder: 'What and why',\n })\n if (p.isCancel(taskDescVal)) { p.cancel('Cancelled.'); process.exit(0) }\n const taskDesc = (taskDescVal as string).trim()\n\n const acceptance: string[] = []\n p.log.info('Acceptance criteria — one per line, empty line to finish')\n while (true) {\n const criterionVal = await p.text({\n message: '>',\n placeholder: 'Criterion (or press Enter to finish)',\n })\n if (p.isCancel(criterionVal) || !(criterionVal as string).trim()) break\n acceptance.push((criterionVal as string).trim())\n }\n\n firstTask = { title: taskTitle, description: taskDesc, acceptance }\n }\n\n // ─── Scaffold ─────────────────────────────────────────────────────────────\n const spinner = p.spinner()\n spinner.start('Scaffolding...')\n\n try {\n const config = applyConfigDefaults({ name, description, provider, docsPath, tasksAdapter })\n const materializer = getMaterializer(provider)\n\n // Write config file\n const configContent = configTs({\n name,\n description,\n provider,\n docsPath,\n tasksAdapter,\n port: config.tools.mcp.port,\n })\n writeFileSync(join(cwd, 'agent-harness-kit.config.ts'), configContent, 'utf8')\n\n // Create .harness dir\n mkdirSync(join(cwd, config.storage.dir), { recursive: true })\n\n // Initialize SQLite DB\n const db = openDB(config, cwd)\n\n // Scaffold provider-specific files\n await materializer.scaffold(config, { cwd, firstTask })\n\n // Seed first task into DB if provided\n if (firstTask) {\n const slug = slugify(firstTask.title)\n db.addTask({\n slug,\n title: firstTask.title,\n description: firstTask.description,\n acceptance: firstTask.acceptance,\n })\n }\n\n db.close()\n spinner.stop('')\n } catch (err) {\n spinner.stop('Failed')\n p.log.error(err instanceof Error ? err.message : String(err))\n process.exit(1)\n }\n\n // ─── Summary ──────────────────────────────────────────────────────────────\n const agentsDir = provider === 'claude-code' ? '.claude/agents/' : '.opencode/agents/'\n const mcpFile = provider === 'claude-code' ? '.claude/mcp.json' : './opencode/opencode.json'\n\n console.log('')\n console.log(pc.green('✓ agent-harness-kit.config.ts'))\n console.log(pc.green('✓ AGENTS.md'))\n console.log(pc.green('✓ health.sh'))\n console.log(pc.green('✓ .harness/harness.db'))\n console.log(pc.green('✓ .harness/current.md'))\n console.log(pc.green(`✓ ${agentsDir}lead.md`))\n console.log(pc.green(`✓ ${agentsDir}explorer.md`))\n console.log(pc.green(`✓ ${agentsDir}builder.md`))\n console.log(pc.green(`✓ ${agentsDir}reviewer.md`))\n console.log(pc.green(`✓ ${mcpFile}`))\n console.log(pc.green('✓ .gitignore entries added'))\n console.log('')\n console.log(pc.cyan('→') + ` Edit ${pc.cyan('health.sh')} with your project checks`)\n console.log(pc.cyan('→') + ` ${pc.cyan('ahk task add')} to queue work for agents`)\n}\n\n","import type { HarnessConfig, Provider } from '@/types'\n\nexport function applyConfigDefaults(params: {\n name: string\n description: string\n provider: Provider\n docsPath: string\n tasksAdapter: string\n}): HarnessConfig {\n return {\n provider: params.provider,\n project: {\n name: params.name,\n description: params.description,\n docsPath: params.docsPath,\n agentsMd: './AGENTS.md',\n },\n agents: {\n lead: { instructionsPath: null },\n explorer: { instructionsPath: null, allowedPaths: [params.docsPath, './src'] },\n builder: { instructionsPath: null, writablePaths: ['./src', './tests'] },\n reviewer: { instructionsPath: null },\n custom: [],\n },\n storage: {\n dir: '.harness',\n dbPath: '.harness/harness.db',\n tasks: { adapter: params.tasksAdapter as 'local' },\n sections: {\n toolsUsed: true,\n filesModified: true,\n result: true,\n blockers: true,\n nextSteps: false,\n },\n markdownFallback: { enabled: true, path: '.harness/current.md' },\n },\n health: {\n scriptPath: './health.sh',\n required: true,\n },\n tools: {\n mcp: { enabled: true, port: 3742 },\n scripts: { enabled: true, outputDir: './.harness/scripts' },\n },\n }\n}\n","import * as p from '@clack/prompts'\nimport pc from 'picocolors'\n\nimport { loadConfig } from '@/core/config'\nimport { getMaterializer } from '@/core/materializer/index'\n\nimport type { Provider } from '@/types'\n\ninterface MigrateOptions {\n to?: string\n}\n\nexport async function runMigrate(cwd: string, opts: MigrateOptions): Promise<void> {\n const config = await loadConfig(cwd)\n\n let target: Provider\n if (opts.to && ['claude-code', 'opencode'].includes(opts.to)) {\n target = opts.to as Provider\n } else {\n const val = await p.select({\n message: 'Migrate to provider',\n options: [\n { value: 'claude-code', label: 'Claude Code' },\n { value: 'opencode', label: 'OpenCode' },\n ],\n })\n if (p.isCancel(val)) { p.cancel('Cancelled.'); process.exit(0) }\n target = val as Provider\n }\n\n if (target === config.provider) {\n console.log(pc.dim(`Already on ${target} — nothing to migrate.`))\n return\n }\n\n const spinner = p.spinner()\n spinner.start(`Migrating from ${config.provider} to ${target}...`)\n\n try {\n // Scaffold the new provider's files\n const targetMaterializer = getMaterializer(target)\n await targetMaterializer.build(config, cwd)\n\n spinner.stop(pc.green(`Migrated to ${target}`))\n p.log.warn(`Update agent-harness-kit.config.ts: set provider: '${target}'`)\n p.log.warn(`Then run: ahk build`)\n } catch (err) {\n spinner.stop(pc.red('Migration failed'))\n p.log.error(err instanceof Error ? err.message : String(err))\n process.exit(1)\n }\n}\n","import { readdirSync, readFileSync, statSync } from 'node:fs'\nimport { join, resolve } from 'node:path'\nimport { Server } from '@modelcontextprotocol/sdk/server'\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'\nimport {\n CallToolRequestSchema,\n type CallToolResult,\n ListToolsRequestSchema,\n} from '@modelcontextprotocol/sdk/types.js'\n\nimport { type HarnessDB, openDB } from './db'\n\nimport type { AgentName, HarnessConfig, TaskStatus } from '@/types'\n\nconst VERSION = '0.1.0'\n\n// ─── Tool schemas ─────────────────────────────────────────────────────────────\n\nconst TOOLS = [\n {\n name: 'actions.start',\n description: 'Start a new action for a task. Returns an actionId (UUID).',\n inputSchema: {\n type: 'object',\n properties: {\n taskId: { type: 'number', description: 'The task ID from tasks.get' },\n agent: {\n type: 'string',\n description: 'Agent name: lead | explorer | builder | reviewer | custom:<name>',\n },\n },\n required: ['taskId', 'agent'],\n },\n },\n {\n name: 'actions.write',\n description:\n 'Record a section in an action. Standard sections: result, tools_used, files_modified, blockers, next_steps.',\n inputSchema: {\n type: 'object',\n properties: {\n actionId: { type: 'string', description: 'UUID returned by actions.start' },\n sectionType: {\n type: 'string',\n description: 'Section name: result | tools_used | files_modified | blockers | next_steps | <custom>',\n },\n content: { type: 'string', description: 'Content for this section' },\n },\n required: ['actionId', 'sectionType', 'content'],\n },\n },\n {\n name: 'actions.complete',\n description: 'Close an action with a one-line summary.',\n inputSchema: {\n type: 'object',\n properties: {\n actionId: { type: 'string', description: 'UUID of the action to close' },\n summary: { type: 'string', description: 'One-line summary of what was done' },\n },\n required: ['actionId', 'summary'],\n },\n },\n {\n name: 'actions.get',\n description: 'Get the full action history for a task (all agents, all sections).',\n inputSchema: {\n type: 'object',\n properties: {\n taskId: { type: 'number', description: 'Task ID' },\n },\n required: ['taskId'],\n },\n },\n {\n name: 'tasks.get',\n description: 'List tasks, optionally filtered by status.',\n inputSchema: {\n type: 'object',\n properties: {\n status: {\n type: 'string',\n enum: ['pending', 'in_progress', 'done', 'blocked'],\n description: 'Filter by status (omit for all tasks)',\n },\n },\n },\n },\n {\n name: 'tasks.claim',\n description:\n 'Atomically claim a pending task. Returns task_already_claimed if another agent got it first.',\n inputSchema: {\n type: 'object',\n properties: {\n id: { type: 'number', description: 'Task ID to claim' },\n agent: { type: 'string', description: 'Your agent name' },\n },\n required: ['id', 'agent'],\n },\n },\n {\n name: 'tasks.update',\n description: 'Change the status of a task.',\n inputSchema: {\n type: 'object',\n properties: {\n id: { type: 'number', description: 'Task ID' },\n status: {\n type: 'string',\n enum: ['pending', 'in_progress', 'done', 'blocked'],\n },\n },\n required: ['id', 'status'],\n },\n },\n {\n name: 'docs.search',\n description: 'Search the project docs folder for content matching a query.',\n inputSchema: {\n type: 'object',\n properties: {\n query: { type: 'string', description: 'Search terms' },\n },\n required: ['query'],\n },\n },\n] as const\n\n// ─── Server ───────────────────────────────────────────────────────────────────\n\nexport async function startMcpServer(config: HarnessConfig, cwd: string): Promise<void> {\n const db = openDB(config, cwd)\n const docsPath = resolve(cwd, config.project.docsPath)\n\n const server = new Server(\n { name: 'agent-harness-kit', version: VERSION },\n { capabilities: { tools: {} } }\n )\n\n server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: TOOLS }))\n\n server.setRequestHandler(CallToolRequestSchema, async (request) => {\n const { name, arguments: args } = request.params\n const a = (args ?? {}) as Record<string, unknown>\n\n try {\n const result = await dispatch(name, a, db, docsPath)\n return result\n } catch (err) {\n return ok(`Error: ${err instanceof Error ? err.message : String(err)}`, true)\n }\n })\n\n const transport = new StdioServerTransport()\n await server.connect(transport)\n}\n\n// ─── Dispatch ─────────────────────────────────────────────────────────────────\n\nasync function dispatch(\n name: string,\n args: Record<string, unknown>,\n db: HarnessDB,\n docsPath: string\n): Promise<CallToolResult> {\n switch (name) {\n case 'actions.start': {\n const taskId = num(args, 'taskId')\n const agent = str(args, 'agent') as AgentName\n const action = db.startAction(taskId, agent)\n return ok(JSON.stringify({ actionId: action.id, taskId, agent, status: 'in_progress' }))\n }\n\n case 'actions.write': {\n const actionId = str(args, 'actionId')\n const sectionType = str(args, 'sectionType')\n const content = str(args, 'content')\n db.writeSection(actionId, sectionType, content)\n return ok(JSON.stringify({ actionId, sectionType, recorded: true }))\n }\n\n case 'actions.complete': {\n const actionId = str(args, 'actionId')\n const summary = str(args, 'summary')\n const action = db.completeAction(actionId, summary)\n return ok(JSON.stringify({ actionId, status: action.status, completedAt: action.completed_at }))\n }\n\n case 'actions.get': {\n const taskId = num(args, 'taskId')\n const actions = db.getActionsForTask(taskId)\n const full = actions.map((a) => ({\n ...a,\n sections: db.getActionSections(a.id),\n }))\n return ok(JSON.stringify(full, null, 2))\n }\n\n case 'tasks.get': {\n const status = args['status'] as string | undefined\n const tasks = status\n ? db.getTasks(status as TaskStatus)\n : db.getTasks()\n return ok(JSON.stringify(tasks, null, 2))\n }\n\n case 'tasks.claim': {\n const id = num(args, 'id')\n const agent = str(args, 'agent')\n const task = db.claimTask(id, agent)\n if (!task) {\n return ok(JSON.stringify({ error: 'task_already_claimed', taskId: id }))\n }\n return ok(JSON.stringify(task))\n }\n\n case 'tasks.update': {\n const id = num(args, 'id')\n const status = str(args, 'status') as TaskStatus\n const task = db.updateTaskStatus(id, status)\n return ok(JSON.stringify(task))\n }\n\n case 'docs.search': {\n const query = str(args, 'query')\n const results = searchDocs(docsPath, query)\n return ok(JSON.stringify(results, null, 2))\n }\n\n default:\n return ok(`Unknown tool: ${name}`, true)\n }\n}\n\n// ─── docs.search implementation ───────────────────────────────────────────────\n\ninterface DocSnippet {\n file: string\n line: number\n text: string\n}\n\nfunction searchDocs(docsPath: string, query: string, maxResults = 10): DocSnippet[] {\n const terms = query.toLowerCase().split(/\\s+/).filter(Boolean)\n const results: DocSnippet[] = []\n\n try {\n const files = collectMarkdownFiles(docsPath)\n for (const file of files) {\n if (results.length >= maxResults) break\n try {\n const content = readFileSync(file, 'utf8')\n const lines = content.split('\\n')\n for (let i = 0; i < lines.length; i++) {\n const lower = lines[i].toLowerCase()\n if (terms.every((t) => lower.includes(t))) {\n results.push({ file: file.replace(docsPath + '/', ''), line: i + 1, text: lines[i].trim() })\n if (results.length >= maxResults) break\n }\n }\n } catch {\n // skip unreadable files\n }\n }\n } catch {\n return [{ file: '', line: 0, text: `docs path not found: ${docsPath}` }]\n }\n\n return results\n}\n\nfunction collectMarkdownFiles(dir: string): string[] {\n const files: string[] = []\n try {\n for (const entry of readdirSync(dir)) {\n const full = join(dir, entry)\n const stat = statSync(full)\n if (stat.isDirectory()) {\n files.push(...collectMarkdownFiles(full))\n } else if (entry.endsWith('.md') || entry.endsWith('.txt')) {\n files.push(full)\n }\n }\n } catch {\n // directory may not exist yet\n }\n return files\n}\n\n// ─── Helpers ──────────────────────────────────────────────────────────────────\n\nfunction ok(text: string, isError = false): CallToolResult {\n return { content: [{ type: 'text' as const, text }], isError }\n}\n\nfunction str(args: Record<string, unknown>, key: string): string {\n const v = args[key]\n if (typeof v !== 'string') throw new Error(`${key} must be a string`)\n return v\n}\n\nfunction num(args: Record<string, unknown>, key: string): number {\n const v = args[key]\n if (typeof v !== 'number') throw new Error(`${key} must be a number`)\n return v\n}\n","import { loadConfig } from '@/core/config'\nimport { startMcpServer } from '@/core/mcp-server'\n\ninterface ServeOptions {\n port?: number\n}\n\nexport async function runServe(cwd: string, opts: ServeOptions): Promise<void> {\n const config = await loadConfig(cwd)\n\n if (opts.port) {\n config.tools.mcp.port = opts.port\n }\n\n // MCP server runs on stdio — do not write to stdout after this point.\n // Stderr is used for diagnostics.\n process.stderr.write(`[agent-harness-kit] MCP server starting (stdio)\\n`)\n\n await startMcpServer(config, cwd)\n}\n","import Table from 'cli-table3'\nimport pc from 'picocolors'\n\nimport { loadConfig } from '@/core/config'\nimport { openDB } from '@/core/db'\n\ninterface StatusOptions {\n json?: boolean\n}\n\nconst STATUS_COLOR: Record<string, (s: string) => string> = {\n pending: (s) => pc.dim(s),\n in_progress: (s) => pc.cyan(s),\n done: (s) => pc.green(s),\n blocked: (s) => pc.red(s),\n}\n\nexport async function runStatus(cwd: string, opts: StatusOptions): Promise<void> {\n const config = await loadConfig(cwd)\n const db = openDB(config, cwd)\n\n try {\n const tasks = db.getTasks()\n const summary = db.getStatusSummary()\n\n if (opts.json) {\n const actions = tasks.map((t) => ({\n ...t,\n actions: db.getActionsForTask(t.id),\n acceptance: db.getTaskAcceptance(t.id),\n }))\n console.log(JSON.stringify({ tasks: actions, summary }, null, 2))\n return\n }\n\n if (tasks.length === 0) {\n console.log(pc.dim('No tasks yet. Run: ahk task add'))\n return\n }\n\n const table = new Table({\n head: ['ID', 'Slug', 'Title', 'Status', 'Assigned', 'Started'].map((h) => pc.bold(h)),\n style: { head: [], border: [] },\n })\n\n for (const t of tasks) {\n const colorFn = STATUS_COLOR[t.status] ?? ((s: string) => s)\n table.push([\n String(t.id),\n t.slug,\n t.title.slice(0, 40),\n colorFn(t.status),\n t.assigned_to ?? '—',\n t.started_at ? t.started_at.slice(0, 10) : '—',\n ])\n }\n\n console.log(table.toString())\n\n // Active actions\n const inProgress = tasks.filter((t) => t.status === 'in_progress')\n if (inProgress.length > 0) {\n console.log('')\n console.log(pc.bold('Active actions:'))\n for (const t of inProgress) {\n const actions = db.getActionsForTask(t.id)\n const active = actions.filter((a) => a.status === 'in_progress')\n for (const a of active) {\n console.log(` ${pc.cyan(a.agent.padEnd(10))} → task #${t.id} ${t.slug}`)\n }\n }\n }\n\n // Summary line\n console.log('')\n const parts = summary.map((s) => {\n const fn = STATUS_COLOR[s.status] ?? ((x: string) => x)\n return `${fn(s.status)}: ${s.total}`\n })\n console.log(pc.dim('Tasks — ') + parts.join(pc.dim(' | ')))\n } finally {\n db.close()\n }\n}\n","import { existsSync, readFileSync } from 'node:fs'\nimport { join, resolve } from 'node:path'\nimport pc from 'picocolors'\n\nimport { loadConfig } from '@/core/config'\nimport { openDB } from '@/core/db'\n\nimport type { TaskSeed } from '@/types'\n\ninterface SyncOptions {\n dryRun?: boolean\n direction?: 'in' | 'out' | 'both'\n}\n\nexport async function runSync(cwd: string, opts: SyncOptions): Promise<void> {\n const config = await loadConfig(cwd)\n const direction = opts.direction ?? 'both'\n const featureListPath = resolve(join(cwd, config.storage.dir, 'feature_list.json'))\n\n const db = openDB(config, cwd)\n\n try {\n if (direction === 'in' || direction === 'both') {\n await syncIn(featureListPath, db, opts.dryRun ?? false)\n }\n\n if (direction === 'out' || direction === 'both') {\n syncOut(db, cwd, opts.dryRun ?? false)\n }\n } finally {\n db.close()\n }\n}\n\nasync function syncIn(\n featureListPath: string,\n db: ReturnType<typeof openDB>,\n dryRun: boolean\n): Promise<void> {\n if (!existsSync(featureListPath)) {\n console.log(pc.dim(`feature_list.json not found at ${featureListPath} — skipping in-sync`))\n return\n }\n\n let seeds: TaskSeed[]\n try {\n seeds = JSON.parse(readFileSync(featureListPath, 'utf8')) as TaskSeed[]\n } catch (err) {\n console.error(pc.red(`Failed to parse feature_list.json: ${err}`))\n process.exit(1)\n }\n\n if (dryRun) {\n console.log(pc.bold('Dry run — in-sync (feature_list.json → SQLite):'))\n for (const t of seeds) {\n const existing = db.getTaskBySlug(t.slug)\n console.log(` ${existing ? pc.dim('skip') : pc.green('add ')} ${t.slug}`)\n }\n return\n }\n\n const result = db.syncFromFeatureList(seeds)\n console.log(pc.green(`✓ In-sync: ${result.added} added, ${result.skipped} already existed`))\n}\n\nfunction syncOut(\n db: ReturnType<typeof openDB>,\n cwd: string,\n dryRun: boolean\n): void {\n if (dryRun) {\n const tasks = db.getTasks()\n console.log(pc.bold('Dry run — out-sync (SQLite → feature_list.json):'))\n console.log(` ${tasks.length} tasks would be written`)\n return\n }\n\n db.writeFeatureList(cwd)\n console.log(pc.green('✓ Out-sync: feature_list.json updated'))\n}\n","import * as p from '@clack/prompts'\nimport pc from 'picocolors'\n\nimport { loadConfig } from '@/core/config'\nimport { openDB } from '@/core/db'\nimport { slugify } from '@/core/materializer/scaffold-utils'\n\nexport async function runTaskAdd(cwd: string): Promise<void> {\n p.intro(pc.bold('agent-harness-kit — add task'))\n\n const titleVal = await p.text({\n message: 'Task title',\n validate: (v) => (v.trim() ? undefined : 'Title is required'),\n })\n if (p.isCancel(titleVal)) { p.cancel('Cancelled.'); process.exit(0) }\n const title = (titleVal as string).trim()\n\n const descVal = await p.text({\n message: 'Description (what and why)',\n placeholder: 'Optional',\n })\n if (p.isCancel(descVal)) { p.cancel('Cancelled.'); process.exit(0) }\n const description = (descVal as string).trim()\n\n const acceptance: string[] = []\n p.log.info('Acceptance criteria — one per line, empty line to finish')\n while (true) {\n const val = await p.text({ message: '>', placeholder: 'Criterion (or press Enter to finish)' })\n if (p.isCancel(val) || !val || !(val as string).trim()) break\n acceptance.push((val as string).trim())\n }\n\n const spinner = p.spinner()\n spinner.start('Saving...')\n\n try {\n const config = await loadConfig(cwd)\n const db = openDB(config, cwd)\n\n const slug = slugify(title)\n const task = db.addTask({ slug, title, description: description || undefined, acceptance })\n db.writeFeatureList(cwd)\n db.close()\n\n spinner.stop('')\n console.log(pc.green(`✓ Task #${task.id} added — ${task.slug} (pending)`))\n console.log(pc.cyan('→') + ' ' + pc.cyan('ahk status') + ' to see all tasks')\n } catch (err) {\n spinner.stop(pc.red('Failed'))\n p.log.error(err instanceof Error ? err.message : String(err))\n process.exit(1)\n }\n}\n\n","import { spawnSync } from 'node:child_process'\nimport { existsSync } from 'node:fs'\nimport { resolve } from 'node:path'\nimport pc from 'picocolors'\n\nimport { loadConfig } from '@/core/config'\nimport { openDB } from '@/core/db'\n\nexport async function runTaskDone(cwd: string, idOrSlug: string): Promise<void> {\n const config = await loadConfig(cwd)\n\n // Run health check first if required\n if (config.health.required) {\n const scriptPath = resolve(cwd, config.health.scriptPath)\n if (existsSync(scriptPath)) {\n const result = spawnSync('bash', [scriptPath], { cwd, stdio: 'pipe', encoding: 'utf8' })\n if (result.status !== 0) {\n console.error(pc.red('✗ Health check failed — cannot mark task as done.'))\n if (result.stdout) console.error(result.stdout)\n if (result.stderr) console.error(result.stderr)\n process.exit(1)\n }\n }\n }\n\n const db = openDB(config, cwd)\n\n try {\n const parsed = parseInt(idOrSlug, 10)\n const isId = !isNaN(parsed)\n const task = isId ? db.getTaskById(parsed) : db.getTaskBySlug(idOrSlug)\n\n if (!task) {\n console.error(pc.red(`Task not found: ${idOrSlug}`))\n process.exit(1)\n }\n\n if (task.status === 'done') {\n console.log(pc.dim(`Task #${task.id} is already done.`))\n return\n }\n\n db.updateTaskStatus(task.id, 'done')\n db.writeFeatureList(cwd)\n\n console.log(pc.green(`✓ Task #${task.id} — ${task.slug} marked as done`))\n } finally {\n db.close()\n }\n}\n","import Table from 'cli-table3'\nimport pc from 'picocolors'\n\nimport { loadConfig } from '@/core/config'\nimport { openDB } from '@/core/db'\n\nimport type { TaskStatus } from '@/types'\n\ninterface TaskListOptions {\n status?: string\n json?: boolean\n}\n\nconst STATUS_COLOR: Record<string, (s: string) => string> = {\n pending: (s) => pc.dim(s),\n in_progress: (s) => pc.cyan(s),\n done: (s) => pc.green(s),\n blocked: (s) => pc.red(s),\n}\n\nexport async function runTaskList(cwd: string, opts: TaskListOptions): Promise<void> {\n const config = await loadConfig(cwd)\n const db = openDB(config, cwd)\n\n try {\n const validStatuses: TaskStatus[] = ['pending', 'in_progress', 'done', 'blocked']\n const filterStatus =\n opts.status && validStatuses.includes(opts.status as TaskStatus)\n ? (opts.status as TaskStatus)\n : undefined\n\n const tasks = filterStatus ? db.getTasks(filterStatus) : db.getTasks()\n\n if (opts.json) {\n console.log(JSON.stringify(tasks, null, 2))\n return\n }\n\n if (tasks.length === 0) {\n console.log(pc.dim('No tasks' + (filterStatus ? ` with status: ${filterStatus}` : '') + '.'))\n return\n }\n\n const table = new Table({\n head: ['ID', 'Slug', 'Title', 'Status'].map((h) => pc.bold(h)),\n style: { head: [], border: [] },\n })\n\n for (const t of tasks) {\n const colorFn = STATUS_COLOR[t.status] ?? ((s: string) => s)\n table.push([String(t.id), t.slug, t.title.slice(0, 50), colorFn(t.status)])\n }\n\n console.log(table.toString())\n } finally {\n db.close()\n }\n}\n","import { createRequire } from 'node:module'\nimport { dirname, join } from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nconst require = createRequire(import.meta.url)\n\n// Resolved at runtime relative to the compiled file location:\n// - local dev: dist/cli.js → ../package.json (root)\n// - installed: node_modules/@cardor/agent-harness-kit/dist/cli.js → ../package.json (package root)\nconst pkgPath = join(dirname(fileURLToPath(import.meta.url)), '..', 'package.json')\n\nexport const pkg = require(pkgPath) as { version: string; name: string }\n","// src/core/update-check.ts\nimport pc from 'picocolors'\n\nimport { pkg } from './package-data'\n\nconst REGISTRY_URL = `https://registry.npmjs.org/${pkg.name}/latest`\nconst TIMEOUT_MS = 2500\n\ninterface UpdateInfo {\n current: string\n latest: string\n}\n\nexport function checkForUpdate(currentVersion: string): Promise<UpdateInfo | null> {\n return new Promise((resolve) => {\n const timer = setTimeout(() => resolve(null), TIMEOUT_MS)\n\n fetch(REGISTRY_URL)\n .then((res) => res.json())\n .then((data) => {\n clearTimeout(timer)\n const latest = (data as { version: string }).version\n resolve(isNewer(latest, currentVersion) ? { current: currentVersion, latest } : null)\n })\n .catch(() => {\n clearTimeout(timer)\n resolve(null)\n })\n })\n}\n\nexport function printUpdateMessage({ current, latest }: UpdateInfo): void {\n const lines = [\n ` Update available ${pc.dim(current)} → ${pc.green(latest)} `,\n ` Run: ${pc.cyan(`npm i -g ${pkg.name}@latest`)} `,\n ]\n const width = Math.max(...lines.map((l) => stripAnsi(l).length))\n const border = '─'.repeat(width)\n\n console.log()\n console.log(pc.yellow(`┌${border}┐`))\n for (const line of lines) {\n const pad = width - stripAnsi(line).length\n console.log(pc.yellow('│') + line + ' '.repeat(pad) + pc.yellow('│'))\n }\n console.log(pc.yellow(`└${border}┘`))\n console.log()\n}\n\nfunction isNewer(latest: string, current: string): boolean {\n const toNum = (v: string) => v.split('.').map(Number)\n const [lMaj, lMin, lPat] = toNum(latest)\n const [cMaj, cMin, cPat] = toNum(current)\n\n if (lMaj !== cMaj) return lMaj > cMaj\n if (lMin !== cMin) return lMin > cMin\n\n return lPat > cPat\n}\n\nfunction stripAnsi(str: string): string {\n return str.replace(/\\x1B\\[[0-9;]*m/g, '')\n}"],"mappings":"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","names":["existsSync","mkdirSync","writeFileSync","join","resolve","existsSync","mkdirSync","readFileSync","writeFileSync","join","readFileSync","dirname","cwd","join","existsSync","mkdirSync","writeFileSync","readFileSync","cwd","join","mkdirSync","resolve","writeFileSync","existsSync","existsSync","mkdirSync","writeFileSync","join","resolve","cwd","join","mkdirSync","resolve","writeFileSync","existsSync","cwd","spinner","dirname","join","resolve","fileURLToPath","pc","watch","existsSync","readFileSync","join","task","mkdirSync","writeFileSync","dirname","join","resolve","resolve","mkdirSync","dirname","task","writeFileSync","cwd","join","__dirname","dirname","fileURLToPath","cwd","resolve","join","pc","writeFileSync","pc","cwd","pc","writeFileSync","existsSync","join","resolve","pc","ok","pc","cwd","resolve","existsSync","join","mkdirSync","writeFileSync","join","p","pc","cwd","pc","spinner","writeFileSync","join","mkdirSync","p","pc","cwd","pc","spinner","readFileSync","join","resolve","cwd","resolve","task","readFileSync","join","text","cwd","pc","pc","cwd","existsSync","readFileSync","join","resolve","pc","cwd","resolve","join","existsSync","pc","readFileSync","p","pc","cwd","pc","spinner","task","spawnSync","existsSync","resolve","pc","cwd","resolve","existsSync","spawnSync","pc","task","Table","pc","STATUS_COLOR","pc","cwd","Table","createRequire","dirname","join","fileURLToPath","require","pc","resolve","pc","str"]}
1
+ {"version":3,"sources":["../src/cli.ts","../src/commands/build.ts","../src/core/materializer/claude-code.ts","../src/core/materializer/mcp-merge.ts","../src/core/materializer/scaffold-utils.ts","../src/core/materializer/templates.ts","../src/core/materializer/opencode.ts","../src/core/materializer/index.ts","../src/commands/dashboard.ts","../src/core/dashboard-server.ts","../src/core/db.ts","../src/core/sqlite-adapter.ts","../src/commands/export.ts","../src/commands/health.ts","../src/commands/init.ts","../src/commands/init-helpers.ts","../src/commands/migrate.ts","../src/core/mcp-server.ts","../src/commands/serve.ts","../src/commands/status.ts","../src/commands/sync.ts","../src/commands/task/add.ts","../src/commands/task/done.ts","../src/commands/task/list.ts","../src/core/package-data.ts","../src/core/update-check.ts"],"sourcesContent":["import { Command } from 'commander'\n\nimport { runBuild } from '@/commands/build'\nimport { runDashboard } from '@/commands/dashboard'\nimport { runExport } from '@/commands/export'\nimport { runHealth } from '@/commands/health'\nimport { runInit } from '@/commands/init'\nimport { runMigrate } from '@/commands/migrate'\nimport { runServe } from '@/commands/serve'\nimport { runStatus } from '@/commands/status'\nimport { runSync } from '@/commands/sync'\nimport { runTaskAdd, runTaskDone, runTaskList } from '@/commands/task/index'\nimport { pkg } from '@/core/package-data'\nimport { checkForUpdate, printUpdateMessage } from '@/core/update-check'\n\nconst cwd = process.cwd()\n\nconst updateCheck = checkForUpdate(pkg.version)\n\nconst program = new Command()\n\nprogram\n .name('ahk')\n .description('agent-harness-kit — CLI scaffolding for multi-agent harness systems')\n .version(pkg.version, '-v, --version')\n\n// ─── init ─────────────────────────────────────────────────────────────────────\nprogram\n .command('init')\n .description('Scaffold a harness interactively in the current directory')\n .option('--name <name>', 'Project name (skip prompt)')\n .option('--provider <provider>', 'AI provider: claude-code | opencode (skip prompt)')\n .option('--docs <path>', 'Docs folder path (skip prompt)')\n .option('--tasks <adapter>', 'Task adapter: local | jira | linear (skip prompt)')\n .action(async (opts) => {\n await runInit(cwd, opts)\n })\n\n// ─── build ────────────────────────────────────────────────────────────────────\nprogram\n .command('build')\n .description('Regenerate AGENTS.md and provider files from agent-harness-kit.config.ts')\n .option('--watch', 'Rebuild on config changes')\n .action(async (opts) => {\n await runBuild(cwd, opts)\n })\n\n// ─── health ───────────────────────────────────────────────────────────────────\nprogram\n .command('health')\n .description('Run health.sh and report result')\n .action(async () => {\n await runHealth(cwd)\n })\n\n// ─── status ───────────────────────────────────────────────────────────────────\nprogram\n .command('status')\n .description('Show task table and active actions')\n .option('--json', 'Output as JSON')\n .action(async (opts) => {\n await runStatus(cwd, opts)\n })\n\n// ─── sync ─────────────────────────────────────────────────────────────────────\nprogram\n .command('sync')\n .description('Sync feature_list.json ↔ SQLite')\n .option('--dry-run', 'Show what would change without applying')\n .option('--direction <direction>', 'in | out | both (default: both)')\n .action(async (opts) => {\n await runSync(cwd, { dryRun: opts['dry-run'], direction: opts.direction })\n })\n\n// ─── serve ────────────────────────────────────────────────────────────────────\nprogram\n .command('serve')\n .description('Start the MCP server (stdio)')\n .option('--port <port>', 'Port hint stored in config (default: 3742)', parseInt)\n .action(async (opts) => {\n await runServe(cwd, { port: opts.port })\n })\n\n// ─── task ─────────────────────────────────────────────────────────────────────\nconst task = program.command('task').description('Manage tasks')\n\ntask\n .command('add')\n .description('Add a task interactively')\n .action(async () => {\n await runTaskAdd(cwd)\n })\n\ntask\n .command('list')\n .description('List tasks')\n .option('--status <status>', 'Filter by status: pending | in_progress | done | blocked')\n .option('--json', 'Output as JSON')\n .action(async (opts) => {\n await runTaskList(cwd, opts)\n })\n\ntask\n .command('done <id|slug>')\n .description('Mark a task as done')\n .action(async (idOrSlug: string) => {\n await runTaskDone(cwd, idOrSlug)\n })\n\n// ─── dashboard ────────────────────────────────────────────────────────────────\nprogram\n .command('dashboard')\n .description('Open web dashboard to visualize harness data')\n .option('-p, --port <port>', 'Port to listen on', '4242')\n .option('--no-open', 'Do not open browser automatically')\n .action(async (opts: { port: string; open: boolean }) => {\n await runDashboard(cwd, { port: parseInt(opts.port), open: opts.open })\n })\n\n// ─── migrate ──────────────────────────────────────────────────────────────────\nprogram\n .command('migrate')\n .description('Migrate provider-specific files to a different provider')\n .option('--to <provider>', 'Target provider: claude-code | opencode')\n .action(async (opts) => {\n await runMigrate(cwd, opts)\n })\n\n// ─── export ───────────────────────────────────────────────────────────────────\nprogram\n .command('export')\n .description('Export the database')\n .option('--sql', 'SQL dump')\n .option('--json', 'JSON export of tasks and actions')\n .option('--output <path>', 'Output file path (default: stdout)')\n .action(async (opts) => {\n await runExport(cwd, opts)\n })\n\nprogram.hook('postAction', async () => {\n const update = await updateCheck\n if (update) printUpdateMessage(update)\n})\n\nprogram.parse()\n","import { watch } from 'node:fs'\nimport * as p from '@clack/prompts'\nimport pc from 'picocolors'\n\nimport { loadConfig } from '@/core/config'\nimport { getMaterializer } from '@/core/materializer/index'\n\ninterface BuildOptions {\n watch?: boolean\n}\n\nexport async function runBuild(cwd: string, opts: BuildOptions): Promise<void> {\n await buildOnce(cwd)\n\n if (opts.watch) {\n p.log.info(`Watching agent-harness-kit.config.ts for changes...`)\n watch(cwd, { recursive: false }, async (_, filename) => {\n if (filename?.startsWith('agent-harness-kit.config')) {\n p.log.step('Config changed — rebuilding...')\n await buildOnce(cwd)\n }\n })\n // Keep process alive\n await new Promise(() => { })\n }\n}\n\nasync function buildOnce(cwd: string): Promise<void> {\n const spinner = p.spinner()\n spinner.start('Loading config...')\n\n try {\n const config = await loadConfig(cwd)\n spinner.message('Rebuilding files...')\n const materializer = getMaterializer(config.provider)\n await materializer.build(config, cwd)\n spinner.stop(pc.green('Build complete'))\n p.log.success('AGENTS.md')\n p.log.success(`Agent definitions (${config.provider})`)\n p.log.success('MCP config')\n } catch (err) {\n spinner.stop(pc.red('Build failed'))\n p.log.error(err instanceof Error ? err.message : String(err))\n process.exit(1)\n }\n}\n","import { existsSync, mkdirSync, writeFileSync } from 'fs'\nimport { join, resolve } from 'path'\n\nimport { mergeClaudeMcpJson } from './mcp-merge'\nimport { appendGitignore, slugify, writeAgentFile } from './scaffold-utils'\nimport { agentBuilder, agentExplorer, agentLead, agentReviewer, agentsMd, featureListJson, HEALTH_SH } from './templates'\n\nimport type { Materializer } from './index'\nimport type { HarnessConfig, Provider, ScaffoldOptions } from '@/types'\n\nexport class ClaudeCodeMaterializer implements Materializer {\n async scaffold(config: HarnessConfig, opts: ScaffoldOptions): Promise<void> {\n const { cwd } = opts\n\n const write = (relPath: string, content: string, mode?: number) => {\n const abs = join(cwd, relPath)\n mkdirSync(resolve(abs, '..'), { recursive: true })\n writeFileSync(abs, content, { encoding: 'utf8', mode })\n }\n\n // AGENTS.md — always overwrite (generated from config)\n write('AGENTS.md', agentsMd(config))\n\n // health.sh — only create if it doesn't exist\n if (!existsSync(join(cwd, 'health.sh'))) {\n write('health.sh', HEALTH_SH, 0o755)\n }\n\n // .harness/feature_list.json\n const tasks = opts.firstTask\n ? [{ slug: slugify(opts.firstTask.title), ...opts.firstTask }]\n : []\n write(join(config.storage.dir, 'feature_list.json'), featureListJson(tasks))\n\n // .harness/current.md placeholder\n if (!existsSync(join(cwd, config.storage.markdownFallback.path))) {\n write(\n config.storage.markdownFallback.path,\n `<!-- AUTO-GENERATED by agent-harness-kit — DO NOT EDIT MANUALLY -->\\n<!-- Run ahk status to refresh -->\\n\\n# Current Session\\n\\nNo tasks in progress.\\n`\n )\n }\n\n // .claude/agents/ — skip files the dev may have customized\n const projectName = config.project.name\n const allowedPaths = (config.agents.explorer.allowedPaths ?? []).join(', ')\n const writablePaths = (config.agents.builder.writablePaths ?? []).join(', ')\n writeAgentFile(cwd, '.claude/agents/lead.md', agentLead({ projectName }))\n writeAgentFile(cwd, '.claude/agents/explorer.md', agentExplorer({ projectName, allowedPaths }))\n writeAgentFile(cwd, '.claude/agents/builder.md', agentBuilder({ projectName, writablePaths }))\n writeAgentFile(cwd, '.claude/agents/reviewer.md', agentReviewer({ projectName }))\n\n // .mcp.json — MERGE, never overwrite whole file\n mergeClaudeMcpJson(join(cwd, '.mcp.json'), config.tools.mcp.port)\n\n // .gitignore additions\n appendGitignore(cwd)\n }\n\n async build(config: HarnessConfig, cwd: string): Promise<void> {\n const write = (relPath: string, content: string) => {\n const abs = join(cwd, relPath)\n mkdirSync(resolve(abs, '..'), { recursive: true })\n writeFileSync(abs, content, 'utf8')\n }\n\n // build always regenerates AGENTS.md (it's derived from config)\n write('AGENTS.md', agentsMd(config))\n\n // Agent files: skip if customized, write if missing\n const projectName = config.project.name\n const allowedPaths = (config.agents.explorer.allowedPaths ?? []).join(', ')\n const writablePaths = (config.agents.builder.writablePaths ?? []).join(', ')\n writeAgentFile(cwd, '.claude/agents/lead.md', agentLead({ projectName }))\n writeAgentFile(cwd, '.claude/agents/explorer.md', agentExplorer({ projectName, allowedPaths }))\n writeAgentFile(cwd, '.claude/agents/builder.md', agentBuilder({ projectName, writablePaths }))\n writeAgentFile(cwd, '.claude/agents/reviewer.md', agentReviewer({ projectName }))\n\n // MCP config: always merge\n mergeClaudeMcpJson(join(cwd, '.mcp.json'), config.tools.mcp.port)\n }\n\n async migrate(config: HarnessConfig, _to: Provider, _cwd: string): Promise<void> {\n void config\n // Migration from claude-code is handled by the target materializer\n }\n}\n\n","import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs'\nimport { dirname } from 'node:path'\n\nconst compactionConfig = {\n compaction: {\n auto: true,\n prune: true,\n reserved: 10000\n }\n}\n\nexport function mergeClaudeMcpJson(filePath: string, port: number): void {\n const folderPath = dirname(filePath)\n if (!existsSync(folderPath)) {\n mkdirSync(folderPath, { recursive: true })\n }\n\n let existing: Record<string, unknown> = {}\n if (existsSync(filePath)) {\n try {\n existing = JSON.parse(readFileSync(filePath, 'utf8')) as Record<string, unknown>\n } catch {\n // Unreadable JSON — start fresh to avoid corrupt state\n }\n }\n\n\n\n const agentHarnessKitConfig = {\n type: 'stdio',\n command: 'npx',\n args: ['ahk', 'serve', '--port', String(port)],\n }\n\n const merged = {\n ...existing,\n compaction: existing.compaction ?? compactionConfig.compaction,\n mcpServers: {\n ...((existing.mcpServers as Record<string, unknown>) ?? {}),\n 'agent-harness-kit': agentHarnessKitConfig,\n },\n }\n\n mkdirSync(dirname(filePath), { recursive: true })\n writeFileSync(filePath, JSON.stringify(merged, null, 2) + '\\n', 'utf8')\n}\n\nexport function mergeOpencodeJson(filePath: string, port: number): void {\n const folderPath = dirname(filePath)\n if (!existsSync(folderPath)) {\n mkdirSync(folderPath, { recursive: true })\n }\n\n let existing: Record<string, unknown> = {}\n if (existsSync(filePath)) {\n try {\n existing = JSON.parse(readFileSync(filePath, 'utf8')) as Record<string, unknown>\n } catch {\n // start fresh\n }\n }\n\n const existingMcp = (existing.mcp as Record<string, unknown>) ?? {}\n\n const agentHarnessKitConfig = {\n enabled: true,\n type: 'local',\n command: ['npx', 'ahk', 'serve', '--port', String(port)],\n }\n\n const merged = {\n ...existing,\n compaction: existing.compaction ?? compactionConfig.compaction,\n mcp: {\n ...existingMcp,\n 'agent-harness-kit': agentHarnessKitConfig,\n },\n }\n\n writeFileSync(filePath, JSON.stringify(merged, null, 2) + '\\n', 'utf8')\n}\n","import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs'\nimport { join, resolve } from 'node:path'\n\nimport { GITIGNORE_ENTRIES } from './templates'\n\nexport function writeAgentFile(cwd: string, relPath: string, content: string): void {\n const abs = join(cwd, relPath)\n if (existsSync(abs)) return // preserve dev customizations\n mkdirSync(resolve(abs, '..'), { recursive: true })\n writeFileSync(abs, content, 'utf8')\n}\n\nexport function appendGitignore(cwd: string): void {\n const giPath = join(cwd, '.gitignore')\n const existing = existsSync(giPath) ? readFileSync(giPath, 'utf8') : ''\n\n const toAdd = GITIGNORE_ENTRIES.split('\\n')\n .filter((line) => line && !existing.includes(line))\n .join('\\n')\n\n if (toAdd.trim()) {\n writeFileSync(giPath, existing + (existing.endsWith('\\n') ? '' : '\\n') + toAdd + '\\n', 'utf8')\n }\n}\n\nexport function slugify(title: string): string {\n return title\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '')\n .slice(0, 64)\n}\n","import { readFileSync } from 'node:fs'\nimport { dirname, join } from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nimport type { HarnessConfig } from '@/types'\n\n// ─── Agent template loader ────────────────────────────────────────────────────\n\nconst __dirname = dirname(fileURLToPath(import.meta.url))\nconst TEMPLATES_DIR = join(__dirname, 'agent-templates')\n\n/**\n * Load an agent template file and interpolate {{variables}}.\n * Variables are replaced using a simple {{key}} pattern.\n */\nfunction loadAgentTemplate(\n name: 'lead' | 'explorer' | 'builder' | 'reviewer',\n vars: Record<string, string> = {}\n): string {\n const raw = readFileSync(join(TEMPLATES_DIR, `${name}.md`), 'utf8')\n return raw.replace(/\\{\\{(\\w+)\\}\\}/g, (_, key: string) => vars[key] ?? `{{${key}}}`)\n}\n\n// ─── health.sh — exits 1 until the dev implements it ─────────────────────────\n\nexport const HEALTH_SH = `#!/usr/bin/env bash\n# health.sh — project health check for agent-harness-kit\n#\n# This script must exit 0 when the project is healthy.\n# Agents will run this before starting work.\n#\n# TODO: implement your project's health checks below.\n# Examples:\n# npm test\n# docker compose ps | grep -q \"running\"\n# psql -c \"SELECT 1\" > /dev/null 2>&1\n#\n# Until you implement it, this script intentionally exits 1\n# so agents know the environment is not verified.\n\necho \"health.sh not implemented yet.\"\necho \"Edit this file with your project's health checks.\"\necho \"It must exit 0 for agents to start working.\"\nexit 1\n`\n\n// ─── AGENTS.md template ───────────────────────────────────────────────────────\n\nexport function agentsMd(config: HarnessConfig): string {\n const { name, description, docsPath } = config.project\n const port = config.tools.mcp.port\n\n return `# AGENTS.md — ${name}\n\n> **Read this file first.** It is the navigation map for every AI agent working in this repository.\n\n## Project\n\n**${name}** — ${description}\n\n## Health check (run before starting)\n\n\\`\\`\\`bash\nbash health.sh\n\\`\\`\\`\n\nIf it exits non-zero, stop and report the issue. Do not proceed with tasks until health is green.\n\n## Harness data (source of truth)\n\n| File | Purpose |\n|------|---------|\n| \\`.harness/harness.db\\` | SQLite: all tasks, actions, file changes, tool calls |\n| \\`.harness/current.md\\` | Markdown fallback — read this if MCP server is unavailable |\n| \\`.harness/feature_list.json\\` | Human-editable task seed list |\n\n## MCP tools (preferred)\n\nThe harness exposes tools via MCP server on port ${port}. Use these instead of reading files directly.\n\n\\`\\`\\`\nactions.start taskId agent → start an action, returns actionId\nactions.write actionId section text → record a section (result, tools_used, ...)\nactions.complete actionId summary → close the action\nactions.get taskId → full action history for a task\ntasks.get [status] → list tasks (pending | in_progress | done | blocked)\ntasks.claim id → atomically claim a pending task\ntasks.update id status → change task status\ndocs.search query → search ${docsPath} for relevant content\n\\`\\`\\`\n\n## Workflow\n\n\\`\\`\\`\n1. INIT\n - Run health.sh → exit 1 means stop\n - tasks.get('in_progress') → resume if something is in progress\n - tasks.get('pending') → pick lowest id\n\n2. WORK (lead → explorer → builder → reviewer)\n - Each agent calls actions.start(taskId, agentName) → actionId\n - Records work with actions.write(actionId, section, content)\n - Closes with actions.complete(actionId, summary)\n\n3. CLOSE\n - tasks.update(taskId, 'done')\n - Run health.sh → must be green before closing\n\\`\\`\\`\n\n## Agent roles\n\n| Agent | Responsibility |\n|-------|---------------|\n| lead | Decomposes the task into a plan, assigns sub-agents |\n| explorer | Reads and maps relevant code, never writes |\n| builder | Implements the plan, writes files |\n| reviewer | Verifies acceptance criteria, approves or blocks |\n\n## What to read\n\n\\`\\`\\`\nAlways: .harness/current.md (or MCP tasks.get)\nIf implementing: ${docsPath}/\nIf orchestrating: Agent definition files in your provider's agents directory\n\\`\\`\\`\n`\n}\n\n// ─── agent-harness-kit.config.ts template ───────────────────────────────────────────\n\nexport function configTs(params: {\n name: string\n description: string\n provider: string\n docsPath: string\n tasksAdapter: string\n port: number\n}): string {\n return `import { defineHarness } from '@cardor/agent-harness-kit'\n\nexport default defineHarness({\n project: {\n name: '${params.name}',\n description: '${params.description}',\n docsPath: '${params.docsPath}',\n },\n\n provider: '${params.provider}',\n\n agents: {\n lead: { instructionsPath: null },\n explorer: { instructionsPath: null, allowedPaths: ['${params.docsPath}', './src'] },\n builder: { instructionsPath: null, writablePaths: ['./src', './tests'] },\n reviewer: { instructionsPath: null },\n custom: [],\n },\n\n storage: {\n dir: '.harness',\n dbPath: '.harness/harness.db',\n tasks: { adapter: '${params.tasksAdapter}' },\n sections: {\n toolsUsed: true,\n filesModified: true,\n result: true,\n blockers: true,\n nextSteps: false,\n },\n markdownFallback: { enabled: true, path: '.harness/current.md' },\n },\n\n health: {\n scriptPath: './health.sh',\n required: true,\n },\n\n tools: {\n mcp: { enabled: true, port: ${params.port} },\n scripts: { enabled: true, outputDir: './.harness/scripts' },\n },\n})\n`\n}\n\n// ─── Agent definition templates (loaded from agent-templates/*.md) ─────────────\n\nexport function agentLead(vars: { projectName: string }): string {\n return loadAgentTemplate('lead', vars)\n}\n\nexport function agentExplorer(vars: { projectName: string; allowedPaths: string }): string {\n return loadAgentTemplate('explorer', vars)\n}\n\nexport function agentBuilder(vars: { projectName: string; writablePaths: string }): string {\n return loadAgentTemplate('builder', vars)\n}\n\nexport function agentReviewer(vars: { projectName: string }): string {\n return loadAgentTemplate('reviewer', vars)\n}\n\n// ─── feature_list.json initial seed ──────────────────────────────────────────\n\nexport function featureListJson(\n tasks: { slug: string; title: string; description?: string; acceptance?: string[] }[]\n): string {\n return JSON.stringify(tasks, null, 2) + '\\n'\n}\n\n// ─── .gitignore additions ─────────────────────────────────────────────────────\n\nexport const GITIGNORE_ENTRIES = `\n# agent-harness-kit\n.harness/harness.db\n.harness/harness.db-shm\n.harness/harness.db-wal\n.harness/current.md\n`\n","import { existsSync, mkdirSync, writeFileSync } from 'node:fs'\nimport { join, resolve } from 'node:path'\n\nimport { mergeOpencodeJson } from './mcp-merge'\nimport { appendGitignore, slugify, writeAgentFile } from './scaffold-utils'\nimport { agentBuilder, agentExplorer, agentLead, agentReviewer, agentsMd, featureListJson, HEALTH_SH } from './templates'\n\nimport type { Materializer } from './index'\nimport type { HarnessConfig, Provider, ScaffoldOptions } from '@/types'\n\nexport class OpenCodeMaterializer implements Materializer {\n async scaffold(config: HarnessConfig, opts: ScaffoldOptions): Promise<void> {\n const { cwd } = opts\n\n const write = (relPath: string, content: string, mode?: number) => {\n const abs = join(cwd, relPath)\n mkdirSync(resolve(abs, '..'), { recursive: true })\n writeFileSync(abs, content, { encoding: 'utf8', mode })\n }\n\n // AGENTS.md — always overwrite (generated from config)\n write('AGENTS.md', agentsMd(config))\n\n // health.sh — only create if it doesn't exist\n if (!existsSync(join(cwd, 'health.sh'))) {\n write('health.sh', HEALTH_SH, 0o755)\n }\n\n const tasks = opts.firstTask\n ? [{ slug: slugify(opts.firstTask.title), ...opts.firstTask }]\n : []\n write(join(config.storage.dir, 'feature_list.json'), featureListJson(tasks))\n\n if (!existsSync(join(cwd, config.storage.markdownFallback.path))) {\n write(\n config.storage.markdownFallback.path,\n `<!-- AUTO-GENERATED by agent-harness-kit — DO NOT EDIT MANUALLY -->\\n<!-- Run ahk status to refresh -->\\n\\n# Current Session\\n\\nNo tasks in progress.\\n`\n )\n }\n\n // .opencode/agents/ — skip files the dev may have customized\n const projectName = config.project.name\n const allowedPaths = (config.agents.explorer.allowedPaths ?? []).join(', ')\n const writablePaths = (config.agents.builder.writablePaths ?? []).join(', ')\n writeAgentFile(cwd, '.opencode/agents/lead.md', agentLead({ projectName }))\n writeAgentFile(cwd, '.opencode/agents/explorer.md', agentExplorer({ projectName, allowedPaths }))\n writeAgentFile(cwd, '.opencode/agents/builder.md', agentBuilder({ projectName, writablePaths }))\n writeAgentFile(cwd, '.opencode/agents/reviewer.md', agentReviewer({ projectName }))\n\n // opencode.json — MERGE, never overwrite whole file\n mergeOpencodeJson(join(cwd, 'opencode.json'), config.tools.mcp.port)\n\n appendGitignore(cwd)\n }\n\n async build(config: HarnessConfig, cwd: string): Promise<void> {\n const write = (relPath: string, content: string) => {\n const abs = join(cwd, relPath)\n mkdirSync(resolve(abs, '..'), { recursive: true })\n writeFileSync(abs, content, 'utf8')\n }\n\n write('AGENTS.md', agentsMd(config))\n\n const projectName = config.project.name\n const allowedPaths = (config.agents.explorer.allowedPaths ?? []).join(', ')\n const writablePaths = (config.agents.builder.writablePaths ?? []).join(', ')\n writeAgentFile(cwd, '.opencode/agents/lead.md', agentLead({ projectName }))\n writeAgentFile(cwd, '.opencode/agents/explorer.md', agentExplorer({ projectName, allowedPaths }))\n writeAgentFile(cwd, '.opencode/agents/builder.md', agentBuilder({ projectName, writablePaths }))\n writeAgentFile(cwd, '.opencode/agents/reviewer.md', agentReviewer({ projectName }))\n\n mergeOpencodeJson(join(cwd, 'opencode.json'), config.tools.mcp.port)\n }\n\n async migrate(config: HarnessConfig, _to: Provider, _cwd: string): Promise<void> {\n void config\n }\n}\n\n","import { ClaudeCodeMaterializer } from './claude-code'\nimport { OpenCodeMaterializer } from './opencode'\n\nimport type { HarnessConfig, Provider, ScaffoldOptions } from '@/types'\n\nexport interface Materializer {\n scaffold(config: HarnessConfig, opts: ScaffoldOptions): Promise<void>\n build(config: HarnessConfig, cwd: string): Promise<void>\n migrate(config: HarnessConfig, to: Provider, cwd: string): Promise<void>\n}\n\nexport function getMaterializer(provider: Provider): Materializer {\n switch (provider) {\n case 'claude-code':\n return new ClaudeCodeMaterializer()\n case 'opencode':\n return new OpenCodeMaterializer()\n default:\n throw new Error(`Unknown provider: ${provider as string}`)\n }\n}\n","import { dirname, join, resolve } from 'node:path'\nimport { fileURLToPath } from 'node:url'\nimport pc from 'picocolors'\n\nimport { loadConfig } from '@/core/config'\nimport { startDashboardServer } from '@/core/dashboard-server'\nimport { openDB } from '@/core/db'\n\nconst __dirname = dirname(fileURLToPath(import.meta.url))\n\ninterface DashboardOptions {\n port: number\n open: boolean\n}\n\nexport async function runDashboard(cwd: string, opts: DashboardOptions): Promise<void> {\n const config = await loadConfig(cwd)\n const db = openDB(config, cwd)\n const dbPath = resolve(cwd, config.storage.dbPath)\n const staticPath = join(__dirname, 'dashboard-dist')\n\n const { url } = startDashboardServer(db, dbPath, staticPath, opts.port)\n\n console.log(pc.green(`✓`) + ` Dashboard running at ${pc.bold(pc.cyan(url))}`)\n console.log(pc.dim(` WebSocket live updates enabled`))\n console.log(pc.dim(` Press Ctrl+C to stop`))\n\n if (opts.open) {\n const { default: open } = await import('open')\n await open(url)\n }\n\n process.on('SIGINT', () => {\n process.exit(0)\n })\n\n // Keep process alive until SIGINT\n await new Promise<void>(() => { })\n}\n","import { watch } from 'node:fs'\nimport { existsSync, readFileSync } from 'node:fs'\nimport { extname,join } from 'node:path'\nimport { serve } from '@hono/node-server'\nimport { Hono } from 'hono'\nimport { WebSocketServer } from 'ws'\n\nimport type { HarnessDB } from './db'\nimport type {\n AgentStatRow,\n CountRow,\n RecentFileRow,\n RecentToolRow,\n TaskListRow,\n TimelineRow,\n TopFileRow,\n} from './server-types'\nimport type { IncomingMessage } from 'node:http'\nimport type { Socket } from 'node:net'\n\nconst AGENT_ORDER = ['lead', 'explorer', 'builder', 'reviewer']\n\n// ─── Static file serving ──────────────────────────────────────────────────────\n\nconst MIME: Record<string, string> = {\n '.html': 'text/html; charset=utf-8',\n '.js': 'application/javascript; charset=utf-8',\n '.mjs': 'application/javascript; charset=utf-8',\n '.css': 'text/css; charset=utf-8',\n '.json': 'application/json; charset=utf-8',\n '.svg': 'image/svg+xml',\n '.png': 'image/png',\n '.ico': 'image/x-icon',\n '.woff': 'font/woff',\n '.woff2': 'font/woff2',\n '.ttf': 'font/ttf',\n}\n\nfunction fileResponse(filePath: string): Response {\n const content = readFileSync(filePath)\n const mime = MIME[extname(filePath)] ?? 'application/octet-stream'\n return new Response(content, {\n headers: { 'Content-Type': mime, 'Cache-Control': 'no-cache' },\n })\n}\n\n// ─── Server ───────────────────────────────────────────────────────────────────\n\nexport interface DashboardServerResult {\n url: string\n close: () => void\n}\n\nexport function startDashboardServer(\n db: HarnessDB,\n dbPath: string,\n staticPath: string,\n port: number,\n): DashboardServerResult {\n const app = new Hono()\n\n // ─── CORS ─────────────────────────────────────────────────────────────────\n app.use('/api/*', async (c, next) => {\n await next()\n c.res.headers.set('Access-Control-Allow-Origin', '*')\n })\n\n // ─── Stats overview ───────────────────────────────────────────────────────\n app.get('/api/stats', (c) => {\n const summary = db.getStatusSummary()\n const byStatus: Record<string, number> = { pending: 0, in_progress: 0, done: 0, blocked: 0 }\n for (const { status, total } of summary) byStatus[status] = total\n\n const [{ total: totalActions }] = db.queryRaw<CountRow>(`SELECT COUNT(*) as total FROM actions`)\n const [{ total: totalFiles }] = db.queryRaw<CountRow>(`SELECT COUNT(*) as total FROM action_files`)\n const [{ total: uniqueTools }] = db.queryRaw<CountRow>(`SELECT COUNT(DISTINCT tool_name) as total FROM action_tools`)\n const [{ total: activeAgents }] = db.queryRaw<CountRow>(\n `SELECT COUNT(DISTINCT agent) as total FROM actions WHERE status = 'in_progress'`,\n )\n\n return c.json({ byStatus, totalActions, totalFiles, uniqueTools, activeAgents })\n })\n\n // ─── Meta ─────────────────────────────────────────────────────────────────\n app.get('/api/meta', (c) => {\n return c.json({ ok: true })\n })\n\n // ─── Tasks list ───────────────────────────────────────────────────────────\n app.get('/api/tasks', (c) => {\n const rows = db.queryRaw<TaskListRow>(`\n SELECT t.*,\n COUNT(ta.id) as acceptance_total,\n COALESCE(SUM(ta.met), 0) as acceptance_met\n FROM tasks t\n LEFT JOIN task_acceptance ta ON ta.task_id = t.id\n GROUP BY t.id\n ORDER BY t.id\n `)\n return c.json(rows)\n })\n\n // ─── Task detail ──────────────────────────────────────────────────────────\n app.get('/api/tasks/:id', (c) => {\n const id = parseInt(c.req.param('id'))\n const task = db.getTaskById(id)\n if (!task) return c.json({ error: 'Not found' }, 404)\n\n const acceptance = db.getTaskAcceptance(id)\n const actions = db.getActionsForTask(id).map((action) => ({\n ...action,\n sections: db.getActionSections(action.id),\n files: db.queryRaw(`SELECT * FROM action_files WHERE action_id = ?`, action.id),\n tools: db.queryRaw(`SELECT * FROM action_tools WHERE action_id = ? ORDER BY called_at`, action.id),\n }))\n\n return c.json({ ...task, acceptance, actions })\n })\n\n // ─── Tools top ────────────────────────────────────────────────────────────\n app.get('/api/tools/top', (c) => {\n const limit = parseInt(c.req.query('limit') ?? '20')\n return c.json(db.getTopTools(limit))\n })\n\n // ─── Tools recent ─────────────────────────────────────────────────────────\n app.get('/api/tools/recent', (c) => {\n const limit = parseInt(c.req.query('limit') ?? '50')\n const rows = db.queryRaw<RecentToolRow>(`\n SELECT at.*, t.id as task_id, t.title as task_title, t.slug as task_slug, a.agent\n FROM action_tools at\n JOIN actions a ON at.action_id = a.id\n JOIN tasks t ON a.task_id = t.id\n ORDER BY at.called_at DESC\n LIMIT ?\n `, limit)\n return c.json(rows)\n })\n\n // ─── Files top ────────────────────────────────────────────────────────────\n app.get('/api/files/top', (c) => {\n const limit = parseInt(c.req.query('limit') ?? '20')\n const rows = db.queryRaw<TopFileRow>(`\n SELECT\n file_path,\n COUNT(*) as total,\n SUM(CASE WHEN operation='read' THEN 1 ELSE 0 END) as read,\n SUM(CASE WHEN operation='created' THEN 1 ELSE 0 END) as created,\n SUM(CASE WHEN operation='modified' THEN 1 ELSE 0 END) as modified,\n SUM(CASE WHEN operation='deleted' THEN 1 ELSE 0 END) as deleted\n FROM action_files\n GROUP BY file_path\n ORDER BY total DESC\n LIMIT ?\n `, limit)\n return c.json(rows)\n })\n\n // ─── Files recent ─────────────────────────────────────────────────────────\n app.get('/api/files/recent', (c) => {\n const limit = parseInt(c.req.query('limit') ?? '50')\n const rows = db.queryRaw<RecentFileRow>(`\n SELECT af.*, t.id as task_id, t.title as task_title, t.slug as task_slug,\n a.agent, a.created_at as called_at\n FROM action_files af\n JOIN actions a ON af.action_id = a.id\n JOIN tasks t ON a.task_id = t.id\n ORDER BY a.created_at DESC\n LIMIT ?\n `, limit)\n return c.json(rows)\n })\n\n // ─── Agents stats ─────────────────────────────────────────────────────────\n app.get('/api/agents/stats', (c) => {\n const rows = db.queryRaw<AgentStatRow>(`\n SELECT\n a.agent,\n COUNT(*) as actions_total,\n SUM(CASE WHEN a.status='completed' THEN 1 ELSE 0 END) as actions_done,\n SUM(CASE WHEN a.status='blocked' THEN 1 ELSE 0 END) as actions_blocked,\n COUNT(DISTINCT a.task_id) as tasks_worked,\n COUNT(DISTINCT af.file_path) as files_touched\n FROM actions a\n LEFT JOIN action_files af ON af.action_id = a.id\n GROUP BY a.agent\n ORDER BY actions_total DESC\n `)\n const sorted = rows.sort((a, b) => {\n const ai = AGENT_ORDER.indexOf(a.agent)\n const bi = AGENT_ORDER.indexOf(b.agent)\n if (ai === -1 && bi === -1) return 0\n if (ai === -1) return 1\n if (bi === -1) return -1\n return ai - bi\n })\n return c.json(sorted)\n })\n\n // ─── Timeline ─────────────────────────────────────────────────────────────\n app.get('/api/timeline', (c) => {\n const limit = parseInt(c.req.query('limit') ?? '50')\n const rows = db.queryRaw<TimelineRow>(`\n SELECT a.*, t.title as task_title, t.slug as task_slug, t.status as task_status\n FROM actions a\n JOIN tasks t ON a.task_id = t.id\n ORDER BY a.created_at DESC\n LIMIT ?\n `, limit)\n return c.json(rows)\n })\n\n // ─── Static SPA ───────────────────────────────────────────────────────────\n app.get('/*', (c) => {\n const urlPath = c.req.path\n if (urlPath !== '/') {\n const candidate = join(staticPath, urlPath)\n if (existsSync(candidate)) {\n try { return fileResponse(candidate) } catch { /* fall through */ }\n }\n }\n return fileResponse(join(staticPath, 'index.html'))\n })\n\n // ─── Start HTTP server ────────────────────────────────────────────────────\n const httpServer = serve({ fetch: app.fetch, port })\n\n // ─── WebSocket ────────────────────────────────────────────────────────────\n const wss = new WebSocketServer({ noServer: true })\n\n httpServer.on('upgrade', (req: IncomingMessage, socket: Socket, head: Buffer) => {\n if (req.url === '/ws') {\n wss.handleUpgrade(req, socket, head, (ws) => {\n wss.emit('connection', ws, req)\n })\n } else {\n socket.destroy()\n }\n })\n\n // ─── DB file watcher → broadcast update ──────────────────────────────────\n let debounce: ReturnType<typeof setTimeout>\n\n const broadcast = () => {\n clearTimeout(debounce)\n debounce = setTimeout(() => {\n for (const client of wss.clients) {\n if (client.readyState === 1) {\n client.send(JSON.stringify({ type: 'update' }))\n }\n }\n }, 150)\n }\n\n // Watch WAL file for writes (more responsive in WAL mode)\n const walPath = `${dbPath}-wal`\n const watchTarget = existsSync(walPath) ? walPath : dbPath\n const watcher = watch(watchTarget, broadcast)\n\n return {\n url: `http://localhost:${port}`,\n close: () => {\n clearTimeout(debounce)\n watcher.close()\n wss.close()\n httpServer.close()\n },\n }\n}\n","import { randomUUID } from 'node:crypto'\nimport { mkdirSync, writeFileSync } from 'node:fs'\nimport { dirname, join, resolve } from 'node:path'\n\nimport { lastInsertId, openSQLite, type SQLiteDB } from './sqlite-adapter'\n\nimport type {\n ActionFileRow,\n ActionRow,\n ActionSectionRow,\n AgentName,\n HarnessConfig,\n TaskAcceptanceRow,\n TaskRow,\n TaskStatus,\n} from '@/types'\n\n// ─── Schema ───────────────────────────────────────────────────────────────────\n\nconst SCHEMA = `\nCREATE TABLE IF NOT EXISTS tasks (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n slug TEXT NOT NULL UNIQUE,\n title TEXT NOT NULL,\n description TEXT,\n status TEXT NOT NULL DEFAULT 'pending'\n CHECK(status IN ('pending','in_progress','done','blocked')),\n assigned_to TEXT,\n created_at TEXT NOT NULL,\n started_at TEXT,\n completed_at TEXT\n);\n\nCREATE TABLE IF NOT EXISTS task_acceptance (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n task_id INTEGER NOT NULL REFERENCES tasks(id) ON DELETE CASCADE,\n criterion TEXT NOT NULL,\n met INTEGER NOT NULL DEFAULT 0\n);\n\nCREATE TABLE IF NOT EXISTS actions (\n id TEXT PRIMARY KEY,\n task_id INTEGER NOT NULL REFERENCES tasks(id) ON DELETE CASCADE,\n agent TEXT NOT NULL\n CHECK(agent IN ('lead','explorer','builder','reviewer') OR agent LIKE 'custom:%'),\n status TEXT NOT NULL DEFAULT 'in_progress'\n CHECK(status IN ('in_progress','completed','blocked')),\n created_at TEXT NOT NULL,\n completed_at TEXT,\n summary TEXT\n);\n\nCREATE TABLE IF NOT EXISTS action_sections (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n action_id TEXT NOT NULL REFERENCES actions(id) ON DELETE CASCADE,\n section_type TEXT NOT NULL,\n content TEXT NOT NULL,\n created_at TEXT NOT NULL\n);\n\nCREATE TABLE IF NOT EXISTS action_files (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n action_id TEXT NOT NULL REFERENCES actions(id) ON DELETE CASCADE,\n file_path TEXT NOT NULL,\n operation TEXT NOT NULL\n CHECK(operation IN ('read','created','modified','deleted')),\n notes TEXT\n);\n\nCREATE TABLE IF NOT EXISTS action_tools (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n action_id TEXT NOT NULL REFERENCES actions(id) ON DELETE CASCADE,\n tool_name TEXT NOT NULL,\n args_json TEXT,\n result_summary TEXT,\n called_at TEXT NOT NULL\n);\n\nCREATE INDEX IF NOT EXISTS idx_tasks_status ON tasks(status);\nCREATE INDEX IF NOT EXISTS idx_actions_task_id ON actions(task_id);\nCREATE INDEX IF NOT EXISTS idx_actions_agent ON actions(agent);\nCREATE INDEX IF NOT EXISTS idx_actions_status ON actions(status);\nCREATE INDEX IF NOT EXISTS idx_action_files_path ON action_files(file_path);\nCREATE INDEX IF NOT EXISTS idx_action_tools_name ON action_tools(tool_name);\n`\n\n// ─── DB class ─────────────────────────────────────────────────────────────────\n\nexport class HarnessDB {\n private db: SQLiteDB\n private config: HarnessConfig\n\n constructor(dbPath: string, config: HarnessConfig) {\n this.config = config\n const abs = resolve(dbPath)\n mkdirSync(dirname(abs), { recursive: true })\n this.db = openSQLite(abs)\n this.db.exec(`PRAGMA journal_mode = WAL`)\n this.db.exec(`PRAGMA foreign_keys = ON`)\n this.db.exec(SCHEMA)\n }\n\n // ─── Tasks ────────────────────────────────────────────────────────────────\n\n addTask(params: {\n slug: string\n title: string\n description?: string\n acceptance?: string[]\n }): TaskRow {\n const now = new Date().toISOString()\n this.db\n .prepare(\n `INSERT INTO tasks (slug, title, description, status, created_at)\n VALUES (@slug, @title, @description, 'pending', @created_at)`\n )\n .run({\n slug: params.slug,\n title: params.title,\n description: params.description ?? null,\n created_at: now,\n })\n\n const taskId = lastInsertId(this.db)\n\n if (params.acceptance?.length) {\n const accStmt = this.db.prepare(\n `INSERT INTO task_acceptance (task_id, criterion) VALUES (?, ?)`\n )\n for (const criterion of params.acceptance) {\n accStmt.run(taskId, criterion)\n }\n }\n\n this.regenerateCurrentMd()\n return this.getTaskById(taskId)!\n }\n\n getTasks(status?: TaskStatus): TaskRow[] {\n if (status) {\n return this.db\n .prepare(`SELECT * FROM tasks WHERE status = ? ORDER BY id`)\n .all(status) as unknown as TaskRow[]\n }\n return this.db.prepare(`SELECT * FROM tasks ORDER BY id`).all() as unknown as TaskRow[]\n }\n\n getTaskById(id: number): TaskRow | null {\n return (this.db.prepare(`SELECT * FROM tasks WHERE id = ?`).get(id) as unknown as TaskRow) ?? null\n }\n\n getTaskBySlug(slug: string): TaskRow | null {\n return (this.db.prepare(`SELECT * FROM tasks WHERE slug = ?`).get(slug) as unknown as TaskRow) ?? null\n }\n\n getTaskAcceptance(taskId: number): TaskAcceptanceRow[] {\n return this.db\n .prepare(`SELECT * FROM task_acceptance WHERE task_id = ?`)\n .all(taskId) as unknown as TaskAcceptanceRow[]\n }\n\n updateTaskStatus(idOrSlug: number | string, status: TaskStatus): TaskRow {\n const now = new Date().toISOString()\n const task =\n typeof idOrSlug === 'number' ? this.getTaskById(idOrSlug) : this.getTaskBySlug(idOrSlug)\n if (!task) throw new Error(`Task not found: ${idOrSlug}`)\n\n if (status === 'in_progress' && !task.started_at) {\n this.db\n .prepare(\n `UPDATE tasks SET status = ?, started_at = ? WHERE id = ?`\n )\n .run(status, now, task.id)\n } else if (status === 'done') {\n this.db\n .prepare(\n `UPDATE tasks SET status = ?, completed_at = ? WHERE id = ?`\n )\n .run(status, now, task.id)\n } else {\n this.db.prepare(`UPDATE tasks SET status = ? WHERE id = ?`).run(status, task.id)\n }\n\n this.regenerateCurrentMd()\n return this.getTaskById(task.id)!\n }\n\n claimTask(id: number, agent: string): TaskRow | null {\n const now = new Date().toISOString()\n this.db.exec('BEGIN IMMEDIATE')\n try {\n this.db\n .prepare(\n `UPDATE tasks SET status = 'in_progress', assigned_to = ?, started_at = ?\n WHERE id = ? AND status = 'pending'`\n )\n .run(agent, now, id)\n this.db.exec('COMMIT')\n\n // Verify the claim succeeded by reading back — if status changed, we own it\n const task = this.getTaskById(id)\n if (!task || task.status !== 'in_progress' || task.assigned_to !== agent) return null\n\n this.regenerateCurrentMd()\n return task\n } catch (err) {\n this.db.exec('ROLLBACK')\n throw err\n }\n }\n\n // ─── Actions ──────────────────────────────────────────────────────────────\n\n startAction(taskId: number, agent: AgentName): ActionRow {\n const now = new Date().toISOString()\n const id = randomUUID()\n this.db\n .prepare(\n `INSERT INTO actions (id, task_id, agent, status, created_at)\n VALUES (?, ?, ?, 'in_progress', ?)`\n )\n .run(id, taskId, agent, now)\n\n this.regenerateCurrentMd()\n return this.getAction(id)!\n }\n\n writeSection(actionId: string, sectionType: string, content: string): void {\n const now = new Date().toISOString()\n this.db\n .prepare(\n `INSERT INTO action_sections (action_id, section_type, content, created_at)\n VALUES (?, ?, ?, ?)`\n )\n .run(actionId, sectionType, content, now)\n\n this.regenerateCurrentMd()\n }\n\n completeAction(actionId: string, summary: string): ActionRow {\n const now = new Date().toISOString()\n this.db\n .prepare(\n `UPDATE actions SET status = 'completed', completed_at = ?, summary = ?\n WHERE id = ?`\n )\n .run(now, summary, actionId)\n\n this.regenerateCurrentMd()\n return this.getAction(actionId)!\n }\n\n getAction(actionId: string): ActionRow | null {\n return (\n (this.db.prepare(`SELECT * FROM actions WHERE id = ?`).get(actionId) as unknown as ActionRow) ?? null\n )\n }\n\n getActionsForTask(taskId: number): ActionRow[] {\n return this.db\n .prepare(`SELECT * FROM actions WHERE task_id = ? ORDER BY created_at`)\n .all(taskId) as unknown as ActionRow[]\n }\n\n getActionSections(actionId: string): ActionSectionRow[] {\n return this.db\n .prepare(\n `SELECT * FROM action_sections WHERE action_id = ? ORDER BY created_at`\n )\n .all(actionId) as unknown as ActionSectionRow[]\n }\n\n recordFile(\n actionId: string,\n filePath: string,\n operation: ActionFileRow['operation'],\n notes?: string\n ): void {\n this.db\n .prepare(\n `INSERT INTO action_files (action_id, file_path, operation, notes)\n VALUES (?, ?, ?, ?)`\n )\n .run(actionId, filePath, operation, notes ?? null)\n }\n\n recordTool(\n actionId: string,\n toolName: string,\n argsJson?: string,\n resultSummary?: string\n ): void {\n const now = new Date().toISOString()\n this.db\n .prepare(\n `INSERT INTO action_tools (action_id, tool_name, args_json, result_summary, called_at)\n VALUES (?, ?, ?, ?, ?)`\n )\n .run(actionId, toolName, argsJson ?? null, resultSummary ?? null, now)\n }\n\n getFilesForTask(taskId: number): (ActionFileRow & { agent: AgentName })[] {\n return this.db\n .prepare(\n `SELECT af.*, a.agent\n FROM action_files af\n JOIN actions a ON af.action_id = a.id\n WHERE a.task_id = ?\n ORDER BY a.agent, af.operation`\n )\n .all(taskId) as unknown as (ActionFileRow & { agent: AgentName })[]\n }\n\n getTopTools(limit = 10): { tool_name: string; uses: number }[] {\n return this.db\n .prepare(\n `SELECT tool_name, COUNT(*) as uses\n FROM action_tools\n GROUP BY tool_name\n ORDER BY uses DESC\n LIMIT ?`\n )\n .all(limit) as { tool_name: string; uses: number }[]\n }\n\n getStatusSummary(): { status: string; total: number }[] {\n return this.db\n .prepare(`SELECT status, COUNT(*) as total FROM tasks GROUP BY status`)\n .all() as { status: string; total: number }[]\n }\n\n // ─── current.md fallback ──────────────────────────────────────────────────\n\n regenerateCurrentMd(): void {\n if (!this.config.storage.markdownFallback.enabled) return\n\n const mdPath = resolve(this.config.storage.markdownFallback.path)\n mkdirSync(dirname(mdPath), { recursive: true })\n\n const inProgress = this.getTasks('in_progress')\n const now = new Date().toISOString()\n\n let md = `<!-- AUTO-GENERATED by agent-harness-kit — DO NOT EDIT MANUALLY -->\\n`\n md += `<!-- Last updated: ${now} -->\\n\\n`\n md += `# Current Session\\n\\n`\n\n if (inProgress.length === 0) {\n md += `## No tasks in progress\\n\\n`\n const pending = this.getTasks('pending')\n if (pending.length > 0) {\n md += `### Next pending tasks\\n`\n for (const t of pending.slice(0, 5)) {\n md += `- **#${t.id}** ${t.title} (\\`${t.slug}\\`)\\n`\n }\n }\n } else {\n for (const task of inProgress) {\n md += `## Active Task\\n`\n md += `- **ID:** ${task.id}\\n`\n md += `- **Slug:** ${task.slug}\\n`\n md += `- **Status:** ${task.status}\\n`\n md += `- **Started:** ${task.started_at ?? 'unknown'}\\n\\n`\n\n const actions = this.getActionsForTask(task.id)\n if (actions.length > 0) {\n md += `## Actions this session\\n`\n md += `| Agent | Status | Summary | Started |\\n`\n md += `|----------|-------------|----------------------------------|-------------|\\n`\n for (const a of actions) {\n const started = a.created_at.slice(11, 16)\n const summary = (a.summary ?? '').slice(0, 34).padEnd(34)\n md += `| ${a.agent.padEnd(8)} | ${a.status.padEnd(11)} | ${summary} | ${started} |\\n`\n }\n md += `\\n`\n }\n\n const acceptance = this.getTaskAcceptance(task.id)\n if (acceptance.length > 0) {\n md += `## Acceptance Criteria\\n`\n for (const a of acceptance) {\n md += `- [${a.met ? 'x' : ' '}] ${a.criterion}\\n`\n }\n md += `\\n`\n }\n }\n }\n\n writeFileSync(mdPath, md, 'utf8')\n }\n\n // ─── Raw query (dashboard / analytics) ───────────────────────────────────\n\n queryRaw<T = Record<string, unknown>>(sql: string, ...params: unknown[]): T[] {\n return this.db.prepare(sql).all(...params) as unknown as T[]\n }\n\n // ─── Export helpers ───────────────────────────────────────────────────────\n\n exportJson(): { tasks: TaskRow[]; actions: ActionRow[]; sections: ActionSectionRow[] } {\n return {\n tasks: this.getTasks(),\n actions: this.db\n .prepare(`SELECT * FROM actions ORDER BY created_at`)\n .all() as unknown as ActionRow[],\n sections: this.db\n .prepare(`SELECT * FROM action_sections ORDER BY created_at`)\n .all() as unknown as ActionSectionRow[],\n }\n }\n\n close(): void {\n this.db.close()\n }\n\n // ─── feature_list.json sync ───────────────────────────────────────────────\n\n syncFromFeatureList(\n tasks: {\n slug: string\n title: string\n description?: string\n acceptance?: string[]\n }[]\n ): { added: number; skipped: number } {\n let added = 0\n let skipped = 0\n\n for (const t of tasks) {\n if (this.getTaskBySlug(t.slug)) {\n skipped++\n continue\n }\n this.addTask(t)\n added++\n }\n\n return { added, skipped }\n }\n\n writeFeatureList(cwd: string): void {\n const tasks = this.getTasks()\n const list = tasks.map((t) => ({\n slug: t.slug,\n title: t.title,\n description: t.description ?? undefined,\n acceptance: this.getTaskAcceptance(t.id).map((a) => a.criterion),\n status: t.status,\n }))\n\n const path = join(resolve(cwd), this.config.storage.dir, 'feature_list.json')\n mkdirSync(dirname(path), { recursive: true })\n writeFileSync(path, JSON.stringify(list, null, 2) + '\\n', 'utf8')\n }\n}\n\nexport function openDB(config: HarnessConfig, cwd: string): HarnessDB {\n const dbPath = join(resolve(cwd), config.storage.dbPath)\n return new HarnessDB(dbPath, config)\n}\n","import { createRequire } from 'node:module'\n\nconst _require = createRequire(import.meta.url)\nconst isBun = 'bun' in process.versions\n\n// ─── Shared interface ─────────────────────────────────────────────────────────\n// Both node:sqlite (DatabaseSync) and bun:sqlite (Database) expose this surface.\n\nexport type SQLRow = Record<string, unknown>\n\nexport interface SQLStatement {\n run(...args: unknown[]): unknown\n get(...args: unknown[]): SQLRow | undefined\n all(...args: unknown[]): SQLRow[]\n}\n\nexport interface SQLiteDB {\n exec(sql: string): void\n prepare(sql: string): SQLStatement\n close(): void\n}\n\n// ─── Factory ─────────────────────────────────────────────────────────────────\n\nexport function openSQLite(path: string): SQLiteDB {\n if (isBun) {\n const { Database } = _require('bun:sqlite') as {\n Database: new (path: string) => unknown\n }\n return new Database(path) as unknown as SQLiteDB\n }\n\n const { DatabaseSync } = _require('node:sqlite') as {\n DatabaseSync: new (path: string) => unknown\n }\n return new DatabaseSync(path) as unknown as SQLiteDB\n}\n\n// ─── last_insert_rowid() helper ───────────────────────────────────────────────\n// Both bun:sqlite and node:sqlite have different return types for stmt.run().\n// Reading last_insert_rowid() directly avoids the inconsistency.\n\nexport function lastInsertId(db: SQLiteDB): number {\n const row = db.prepare('SELECT last_insert_rowid() AS id').get() as { id: number }\n return row.id\n}\n","import { writeFileSync } from 'node:fs'\nimport pc from 'picocolors'\n\nimport { loadConfig } from '@/core/config'\nimport { openDB } from '@/core/db'\n\ninterface ExportOptions {\n sql?: boolean\n json?: boolean\n output?: string\n}\n\nexport async function runExport(cwd: string, opts: ExportOptions): Promise<void> {\n if (!opts.sql && !opts.json) {\n console.error(pc.red('Specify --sql or --json'))\n process.exit(1)\n }\n\n const config = await loadConfig(cwd)\n const db = openDB(config, cwd)\n\n try {\n if (opts.json) {\n const data = db.exportJson()\n const out = JSON.stringify(data, null, 2) + '\\n'\n if (opts.output) {\n writeFileSync(opts.output, out, 'utf8')\n console.log(pc.green(`✓ Exported JSON → ${opts.output}`))\n } else {\n process.stdout.write(out)\n }\n }\n\n if (opts.sql) {\n console.error(pc.dim('SQL dump requires direct SQLite access — use: sqlite3 .harness/harness.db .dump'))\n process.exit(1)\n }\n } finally {\n db.close()\n }\n}\n","import { spawnSync } from 'node:child_process'\nimport { existsSync } from 'node:fs'\nimport { join, resolve } from 'node:path'\nimport pc from 'picocolors'\n\nimport { loadConfig } from '@/core/config'\n\nfunction checkLine(label: string | null, ok: boolean, message: string, indent = 0): void {\n const prefix = label ? pc.cyan(`[${label}] `) : ' '.repeat(indent)\n const icon = ok ? pc.green('✓') : pc.red('✗')\n console.log(prefix + icon + ' ' + (ok ? pc.green(message) : pc.red(message)))\n}\n\nexport async function runHealth(cwd: string): Promise<void> {\n let config\n try {\n config = await loadConfig(cwd)\n } catch {\n console.error(pc.red('✗ No config found. Run: ahk init'))\n process.exit(1)\n }\n\n let allOk = true\n\n // ─── [checking DB] ──────────────────────────────────────────────────────────\n const dbPath = resolve(cwd, config.storage.dbPath)\n const dbOk = existsSync(dbPath)\n checkLine('checking DB', dbOk, `${config.storage.dbPath} reachable`)\n if (!dbOk) allOk = false\n\n // ─── [checking agents] ──────────────────────────────────────────────────────\n const agentsDir = config.provider === 'claude-code' ? '.claude/agents' : '.opencode/agents'\n const agentNames = ['lead', 'explorer', 'builder', 'reviewer']\n\n const agentsLabelWidth = '[checking agents] '.length\n for (let i = 0; i < agentNames.length; i++) {\n const name = agentNames[i]\n const agentPath = join(cwd, agentsDir, `${name}.md`)\n const ok = existsSync(agentPath)\n checkLine(i === 0 ? 'checking agents' : null, ok, `${name}.md present`, agentsLabelWidth)\n if (!ok) allOk = false\n }\n\n // ─── [checking MCP] ─────────────────────────────────────────────────────────\n if (config.tools.mcp.enabled) {\n const mcpFile = config.provider === 'claude-code' ? '.claude/mcp.json' : 'opencode.json'\n const mcpPath = resolve(cwd, mcpFile)\n const mcpOk = existsSync(mcpPath)\n checkLine('checking MCP', mcpOk, `${mcpFile} valid`)\n if (!mcpOk) allOk = false\n }\n\n if (!allOk) {\n console.log('')\n console.error(pc.red('✗ Harness checks failed — fix the above before running health.sh'))\n process.exit(1)\n }\n\n // ─── Run health.sh ──────────────────────────────────────────────────────────\n const scriptPath = resolve(cwd, config.health.scriptPath)\n\n if (!existsSync(scriptPath)) {\n console.error(pc.red(`✗ health.sh not found: ${scriptPath}`))\n console.error(' Run ahk init first.')\n process.exit(1)\n }\n\n const result = spawnSync('bash', [scriptPath], {\n cwd,\n stdio: 'inherit',\n encoding: 'utf8',\n })\n\n if (result.error) {\n console.error(pc.red(`✗ Failed to run health.sh: ${result.error.message}`))\n process.exit(1)\n }\n\n if (result.status === 0) {\n console.log(pc.green('✓ Health check passed'))\n process.exit(0)\n } else {\n console.error(pc.red(`✗ Health check failed (exit ${result.status ?? 'unknown'})`))\n process.exit(result.status ?? 1)\n }\n}\n","import { mkdirSync, writeFileSync } from 'node:fs'\nimport { join } from 'node:path'\nimport * as p from '@clack/prompts'\nimport pc from 'picocolors'\n\nimport { openDB } from '@/core/db'\nimport { getMaterializer } from '@/core/materializer/index'\nimport { slugify } from '@/core/materializer/scaffold-utils'\nimport { configTs } from '@/core/materializer/templates'\n\nimport { applyConfigDefaults } from './init-helpers'\n\nimport type { Provider } from '@/types'\n\ninterface InitOptions {\n name?: string\n provider?: string\n docs?: string\n tasks?: string\n}\n\nexport async function runInit(cwd: string, flags: InitOptions): Promise<void> {\n p.intro(pc.bold('agent-harness-kit — harness scaffolding'))\n\n // ─── Project name ────────────────────────────────────────────────────────\n let name: string\n if (flags.name) {\n name = flags.name\n } else {\n const val = await p.text({\n message: 'Project name',\n placeholder: 'my-app',\n validate: (v) => (v.trim() ? undefined : 'Project name is required'),\n })\n if (p.isCancel(val)) { p.cancel('Cancelled.'); process.exit(0) }\n name = val as string\n }\n\n // ─── Description ─────────────────────────────────────────────────────────\n const descVal = await p.text({\n message: 'Short description (shown to agents as context)',\n placeholder: 'A REST API for managing notes',\n })\n if (p.isCancel(descVal)) { p.cancel('Cancelled.'); process.exit(0) }\n const description = (descVal as string).trim() || name\n\n // ─── Provider ─────────────────────────────────────────────────────────────\n let provider: Provider\n if (flags.provider && ['claude-code', 'opencode'].includes(flags.provider)) {\n provider = flags.provider as Provider\n } else {\n const val = await p.select({\n message: 'AI provider',\n options: [\n { value: 'claude-code', label: 'Claude Code' },\n { value: 'opencode', label: 'OpenCode' },\n ],\n })\n if (p.isCancel(val)) { p.cancel('Cancelled.'); process.exit(0) }\n provider = val as Provider\n }\n\n // ─── Docs path ────────────────────────────────────────────────────────────\n let docsPath: string\n if (flags.docs) {\n docsPath = flags.docs\n } else {\n const val = await p.text({\n message: 'Docs folder path (agents will search here)',\n initialValue: './docs',\n })\n if (p.isCancel(val)) { p.cancel('Cancelled.'); process.exit(0) }\n docsPath = (val as string).trim() || './docs'\n }\n\n // ─── Task adapter ─────────────────────────────────────────────────────────\n let tasksAdapter: string\n if (flags.tasks && ['local', 'jira', 'linear'].includes(flags.tasks)) {\n tasksAdapter = flags.tasks\n } else {\n const val = await p.select({\n message: 'Task adapter',\n options: [\n { value: 'local', label: 'Local (feature_list.json)' },\n { value: 'jira', label: 'Jira (coming soon)' },\n { value: 'linear', label: 'Linear (coming soon)' },\n ],\n })\n if (p.isCancel(val)) { p.cancel('Cancelled.'); process.exit(0) }\n tasksAdapter = val as string\n }\n\n // ─── Optional first task ──────────────────────────────────────────────────\n const addFirstTask = await p.confirm({ message: 'Add your first task now?', initialValue: true })\n if (p.isCancel(addFirstTask)) { p.cancel('Cancelled.'); process.exit(0) }\n\n let firstTask: { title: string; description: string; acceptance: string[] } | undefined\n\n if (addFirstTask) {\n const titleVal = await p.text({\n message: 'Task title',\n validate: (v) => (v.trim() ? undefined : 'Title is required'),\n })\n if (p.isCancel(titleVal)) { p.cancel('Cancelled.'); process.exit(0) }\n const taskTitle = (titleVal as string).trim()\n\n const taskDescVal = await p.text({\n message: 'Task description',\n placeholder: 'What and why',\n })\n if (p.isCancel(taskDescVal)) { p.cancel('Cancelled.'); process.exit(0) }\n const taskDesc = (taskDescVal as string).trim()\n\n const acceptance: string[] = []\n p.log.info('Acceptance criteria — one per line, empty line to finish')\n while (true) {\n const criterionVal = await p.text({\n message: '>',\n placeholder: 'Criterion (or press Enter to finish)',\n })\n if (p.isCancel(criterionVal) || !(criterionVal as string).trim()) break\n acceptance.push((criterionVal as string).trim())\n }\n\n firstTask = { title: taskTitle, description: taskDesc, acceptance }\n }\n\n // ─── Scaffold ─────────────────────────────────────────────────────────────\n const spinner = p.spinner()\n spinner.start('Scaffolding...')\n\n try {\n const config = applyConfigDefaults({ name, description, provider, docsPath, tasksAdapter })\n const materializer = getMaterializer(provider)\n\n // Write config file\n const configContent = configTs({\n name,\n description,\n provider,\n docsPath,\n tasksAdapter,\n port: config.tools.mcp.port,\n })\n writeFileSync(join(cwd, 'agent-harness-kit.config.ts'), configContent, 'utf8')\n\n // Create .harness dir\n mkdirSync(join(cwd, config.storage.dir), { recursive: true })\n\n // Initialize SQLite DB\n const db = openDB(config, cwd)\n\n // Scaffold provider-specific files\n await materializer.scaffold(config, { cwd, firstTask })\n\n // Seed first task into DB if provided\n if (firstTask) {\n const slug = slugify(firstTask.title)\n db.addTask({\n slug,\n title: firstTask.title,\n description: firstTask.description,\n acceptance: firstTask.acceptance,\n })\n }\n\n db.close()\n spinner.stop('')\n } catch (err) {\n spinner.stop('Failed')\n p.log.error(err instanceof Error ? err.message : String(err))\n process.exit(1)\n }\n\n // ─── Summary ──────────────────────────────────────────────────────────────\n const agentsDir = provider === 'claude-code' ? '.claude/agents/' : '.opencode/agents/'\n const mcpFile = provider === 'claude-code' ? '.claude/mcp.json' : './opencode.json'\n\n console.log('')\n console.log(pc.green('✓ agent-harness-kit.config.ts'))\n console.log(pc.green('✓ AGENTS.md'))\n console.log(pc.green('✓ health.sh'))\n console.log(pc.green('✓ .harness/harness.db'))\n console.log(pc.green('✓ .harness/current.md'))\n console.log(pc.green(`✓ ${agentsDir}lead.md`))\n console.log(pc.green(`✓ ${agentsDir}explorer.md`))\n console.log(pc.green(`✓ ${agentsDir}builder.md`))\n console.log(pc.green(`✓ ${agentsDir}reviewer.md`))\n console.log(pc.green(`✓ ${mcpFile}`))\n console.log(pc.green('✓ .gitignore entries added'))\n console.log('')\n console.log(pc.cyan('→') + ` Edit ${pc.cyan('health.sh')} with your project checks`)\n console.log(pc.cyan('→') + ` ${pc.cyan('ahk task add')} to queue work for agents`)\n}\n\n","import type { HarnessConfig, Provider } from '@/types'\n\nexport function applyConfigDefaults(params: {\n name: string\n description: string\n provider: Provider\n docsPath: string\n tasksAdapter: string\n}): HarnessConfig {\n return {\n provider: params.provider,\n project: {\n name: params.name,\n description: params.description,\n docsPath: params.docsPath,\n agentsMd: './AGENTS.md',\n },\n agents: {\n lead: { instructionsPath: null },\n explorer: { instructionsPath: null, allowedPaths: [params.docsPath, './src'] },\n builder: { instructionsPath: null, writablePaths: ['./src', './tests'] },\n reviewer: { instructionsPath: null },\n custom: [],\n },\n storage: {\n dir: '.harness',\n dbPath: '.harness/harness.db',\n tasks: { adapter: params.tasksAdapter as 'local' },\n sections: {\n toolsUsed: true,\n filesModified: true,\n result: true,\n blockers: true,\n nextSteps: false,\n },\n markdownFallback: { enabled: true, path: '.harness/current.md' },\n },\n health: {\n scriptPath: './health.sh',\n required: true,\n },\n tools: {\n mcp: { enabled: true, port: 3742 },\n scripts: { enabled: true, outputDir: './.harness/scripts' },\n },\n }\n}\n","import * as p from '@clack/prompts'\nimport pc from 'picocolors'\n\nimport { loadConfig } from '@/core/config'\nimport { getMaterializer } from '@/core/materializer/index'\n\nimport type { Provider } from '@/types'\n\ninterface MigrateOptions {\n to?: string\n}\n\nexport async function runMigrate(cwd: string, opts: MigrateOptions): Promise<void> {\n const config = await loadConfig(cwd)\n\n let target: Provider\n if (opts.to && ['claude-code', 'opencode'].includes(opts.to)) {\n target = opts.to as Provider\n } else {\n const val = await p.select({\n message: 'Migrate to provider',\n options: [\n { value: 'claude-code', label: 'Claude Code' },\n { value: 'opencode', label: 'OpenCode' },\n ],\n })\n if (p.isCancel(val)) { p.cancel('Cancelled.'); process.exit(0) }\n target = val as Provider\n }\n\n if (target === config.provider) {\n console.log(pc.dim(`Already on ${target} — nothing to migrate.`))\n return\n }\n\n const spinner = p.spinner()\n spinner.start(`Migrating from ${config.provider} to ${target}...`)\n\n try {\n // Scaffold the new provider's files\n const targetMaterializer = getMaterializer(target)\n await targetMaterializer.build(config, cwd)\n\n spinner.stop(pc.green(`Migrated to ${target}`))\n p.log.warn(`Update agent-harness-kit.config.ts: set provider: '${target}'`)\n p.log.warn(`Then run: ahk build`)\n } catch (err) {\n spinner.stop(pc.red('Migration failed'))\n p.log.error(err instanceof Error ? err.message : String(err))\n process.exit(1)\n }\n}\n","import { readdirSync, readFileSync, statSync } from 'node:fs'\nimport { join, resolve } from 'node:path'\nimport { Server } from '@modelcontextprotocol/sdk/server'\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'\nimport {\n CallToolRequestSchema,\n type CallToolResult,\n ListToolsRequestSchema,\n} from '@modelcontextprotocol/sdk/types.js'\n\nimport { type HarnessDB, openDB } from './db'\n\nimport type { AgentName, HarnessConfig, TaskStatus } from '@/types'\n\nconst VERSION = '0.1.0'\n\n// ─── Tool schemas ─────────────────────────────────────────────────────────────\n\nconst TOOLS = [\n {\n name: 'actions.start',\n description: 'Start a new action for a task. Returns an actionId (UUID).',\n inputSchema: {\n type: 'object',\n properties: {\n taskId: { type: 'number', description: 'The task ID from tasks.get' },\n agent: {\n type: 'string',\n description: 'Agent name: lead | explorer | builder | reviewer | custom:<name>',\n },\n },\n required: ['taskId', 'agent'],\n },\n },\n {\n name: 'actions.write',\n description:\n 'Record a section in an action. Standard sections: result, tools_used, files_modified, blockers, next_steps.',\n inputSchema: {\n type: 'object',\n properties: {\n actionId: { type: 'string', description: 'UUID returned by actions.start' },\n sectionType: {\n type: 'string',\n description: 'Section name: result | tools_used | files_modified | blockers | next_steps | <custom>',\n },\n content: { type: 'string', description: 'Content for this section' },\n },\n required: ['actionId', 'sectionType', 'content'],\n },\n },\n {\n name: 'actions.complete',\n description: 'Close an action with a one-line summary.',\n inputSchema: {\n type: 'object',\n properties: {\n actionId: { type: 'string', description: 'UUID of the action to close' },\n summary: { type: 'string', description: 'One-line summary of what was done' },\n },\n required: ['actionId', 'summary'],\n },\n },\n {\n name: 'actions.get',\n description: 'Get the full action history for a task (all agents, all sections).',\n inputSchema: {\n type: 'object',\n properties: {\n taskId: { type: 'number', description: 'Task ID' },\n },\n required: ['taskId'],\n },\n },\n {\n name: 'tasks.get',\n description: 'List tasks, optionally filtered by status.',\n inputSchema: {\n type: 'object',\n properties: {\n status: {\n type: 'string',\n enum: ['pending', 'in_progress', 'done', 'blocked'],\n description: 'Filter by status (omit for all tasks)',\n },\n },\n },\n },\n {\n name: 'tasks.claim',\n description:\n 'Atomically claim a pending task. Returns task_already_claimed if another agent got it first.',\n inputSchema: {\n type: 'object',\n properties: {\n id: { type: 'number', description: 'Task ID to claim' },\n agent: { type: 'string', description: 'Your agent name' },\n },\n required: ['id', 'agent'],\n },\n },\n {\n name: 'tasks.update',\n description: 'Change the status of a task.',\n inputSchema: {\n type: 'object',\n properties: {\n id: { type: 'number', description: 'Task ID' },\n status: {\n type: 'string',\n enum: ['pending', 'in_progress', 'done', 'blocked'],\n },\n },\n required: ['id', 'status'],\n },\n },\n {\n name: 'docs.search',\n description: 'Search the project docs folder for content matching a query.',\n inputSchema: {\n type: 'object',\n properties: {\n query: { type: 'string', description: 'Search terms' },\n },\n required: ['query'],\n },\n },\n] as const\n\n// ─── Server ───────────────────────────────────────────────────────────────────\n\nexport async function startMcpServer(config: HarnessConfig, cwd: string): Promise<void> {\n const db = openDB(config, cwd)\n const docsPath = resolve(cwd, config.project.docsPath)\n\n const server = new Server(\n { name: 'agent-harness-kit', version: VERSION },\n { capabilities: { tools: {} } }\n )\n\n server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: TOOLS }))\n\n server.setRequestHandler(CallToolRequestSchema, async (request) => {\n const { name, arguments: args } = request.params\n const a = (args ?? {}) as Record<string, unknown>\n\n try {\n const result = await dispatch(name, a, db, docsPath)\n return result\n } catch (err) {\n return ok(`Error: ${err instanceof Error ? err.message : String(err)}`, true)\n }\n })\n\n const transport = new StdioServerTransport()\n await server.connect(transport)\n}\n\n// ─── Dispatch ─────────────────────────────────────────────────────────────────\n\nasync function dispatch(\n name: string,\n args: Record<string, unknown>,\n db: HarnessDB,\n docsPath: string\n): Promise<CallToolResult> {\n switch (name) {\n case 'actions.start': {\n const taskId = num(args, 'taskId')\n const agent = str(args, 'agent') as AgentName\n const action = db.startAction(taskId, agent)\n return ok(JSON.stringify({ actionId: action.id, taskId, agent, status: 'in_progress' }))\n }\n\n case 'actions.write': {\n const actionId = str(args, 'actionId')\n const sectionType = str(args, 'sectionType')\n const content = str(args, 'content')\n db.writeSection(actionId, sectionType, content)\n return ok(JSON.stringify({ actionId, sectionType, recorded: true }))\n }\n\n case 'actions.complete': {\n const actionId = str(args, 'actionId')\n const summary = str(args, 'summary')\n const action = db.completeAction(actionId, summary)\n return ok(JSON.stringify({ actionId, status: action.status, completedAt: action.completed_at }))\n }\n\n case 'actions.get': {\n const taskId = num(args, 'taskId')\n const actions = db.getActionsForTask(taskId)\n const full = actions.map((a) => ({\n ...a,\n sections: db.getActionSections(a.id),\n }))\n return ok(JSON.stringify(full, null, 2))\n }\n\n case 'tasks.get': {\n const status = args['status'] as string | undefined\n const tasks = status\n ? db.getTasks(status as TaskStatus)\n : db.getTasks()\n return ok(JSON.stringify(tasks, null, 2))\n }\n\n case 'tasks.claim': {\n const id = num(args, 'id')\n const agent = str(args, 'agent')\n const task = db.claimTask(id, agent)\n if (!task) {\n return ok(JSON.stringify({ error: 'task_already_claimed', taskId: id }))\n }\n return ok(JSON.stringify(task))\n }\n\n case 'tasks.update': {\n const id = num(args, 'id')\n const status = str(args, 'status') as TaskStatus\n const task = db.updateTaskStatus(id, status)\n return ok(JSON.stringify(task))\n }\n\n case 'docs.search': {\n const query = str(args, 'query')\n const results = searchDocs(docsPath, query)\n return ok(JSON.stringify(results, null, 2))\n }\n\n default:\n return ok(`Unknown tool: ${name}`, true)\n }\n}\n\n// ─── docs.search implementation ───────────────────────────────────────────────\n\ninterface DocSnippet {\n file: string\n line: number\n text: string\n}\n\nfunction searchDocs(docsPath: string, query: string, maxResults = 10): DocSnippet[] {\n const terms = query.toLowerCase().split(/\\s+/).filter(Boolean)\n const results: DocSnippet[] = []\n\n try {\n const files = collectMarkdownFiles(docsPath)\n for (const file of files) {\n if (results.length >= maxResults) break\n try {\n const content = readFileSync(file, 'utf8')\n const lines = content.split('\\n')\n for (let i = 0; i < lines.length; i++) {\n const lower = lines[i].toLowerCase()\n if (terms.every((t) => lower.includes(t))) {\n results.push({ file: file.replace(docsPath + '/', ''), line: i + 1, text: lines[i].trim() })\n if (results.length >= maxResults) break\n }\n }\n } catch {\n // skip unreadable files\n }\n }\n } catch {\n return [{ file: '', line: 0, text: `docs path not found: ${docsPath}` }]\n }\n\n return results\n}\n\nfunction collectMarkdownFiles(dir: string): string[] {\n const files: string[] = []\n try {\n for (const entry of readdirSync(dir)) {\n const full = join(dir, entry)\n const stat = statSync(full)\n if (stat.isDirectory()) {\n files.push(...collectMarkdownFiles(full))\n } else if (entry.endsWith('.md') || entry.endsWith('.txt')) {\n files.push(full)\n }\n }\n } catch {\n // directory may not exist yet\n }\n return files\n}\n\n// ─── Helpers ──────────────────────────────────────────────────────────────────\n\nfunction ok(text: string, isError = false): CallToolResult {\n return { content: [{ type: 'text' as const, text }], isError }\n}\n\nfunction str(args: Record<string, unknown>, key: string): string {\n const v = args[key]\n if (typeof v !== 'string') throw new Error(`${key} must be a string`)\n return v\n}\n\nfunction num(args: Record<string, unknown>, key: string): number {\n const v = args[key]\n if (typeof v !== 'number') throw new Error(`${key} must be a number`)\n return v\n}\n","import { loadConfig } from '@/core/config'\nimport { startMcpServer } from '@/core/mcp-server'\n\ninterface ServeOptions {\n port?: number\n}\n\nexport async function runServe(cwd: string, opts: ServeOptions): Promise<void> {\n const config = await loadConfig(cwd)\n\n if (opts.port) {\n config.tools.mcp.port = opts.port\n }\n\n // MCP server runs on stdio — do not write to stdout after this point.\n // Stderr is used for diagnostics.\n process.stderr.write(`[agent-harness-kit] MCP server starting (stdio)\\n`)\n\n await startMcpServer(config, cwd)\n}\n","import Table from 'cli-table3'\nimport pc from 'picocolors'\n\nimport { loadConfig } from '@/core/config'\nimport { openDB } from '@/core/db'\n\ninterface StatusOptions {\n json?: boolean\n}\n\nconst STATUS_COLOR: Record<string, (s: string) => string> = {\n pending: (s) => pc.dim(s),\n in_progress: (s) => pc.cyan(s),\n done: (s) => pc.green(s),\n blocked: (s) => pc.red(s),\n}\n\nexport async function runStatus(cwd: string, opts: StatusOptions): Promise<void> {\n const config = await loadConfig(cwd)\n const db = openDB(config, cwd)\n\n try {\n const tasks = db.getTasks()\n const summary = db.getStatusSummary()\n\n if (opts.json) {\n const actions = tasks.map((t) => ({\n ...t,\n actions: db.getActionsForTask(t.id),\n acceptance: db.getTaskAcceptance(t.id),\n }))\n console.log(JSON.stringify({ tasks: actions, summary }, null, 2))\n return\n }\n\n if (tasks.length === 0) {\n console.log(pc.dim('No tasks yet. Run: ahk task add'))\n return\n }\n\n const table = new Table({\n head: ['ID', 'Slug', 'Title', 'Status', 'Assigned', 'Started'].map((h) => pc.bold(h)),\n style: { head: [], border: [] },\n })\n\n for (const t of tasks) {\n const colorFn = STATUS_COLOR[t.status] ?? ((s: string) => s)\n table.push([\n String(t.id),\n t.slug,\n t.title.slice(0, 40),\n colorFn(t.status),\n t.assigned_to ?? '—',\n t.started_at ? t.started_at.slice(0, 10) : '—',\n ])\n }\n\n console.log(table.toString())\n\n // Active actions\n const inProgress = tasks.filter((t) => t.status === 'in_progress')\n if (inProgress.length > 0) {\n console.log('')\n console.log(pc.bold('Active actions:'))\n for (const t of inProgress) {\n const actions = db.getActionsForTask(t.id)\n const active = actions.filter((a) => a.status === 'in_progress')\n for (const a of active) {\n console.log(` ${pc.cyan(a.agent.padEnd(10))} → task #${t.id} ${t.slug}`)\n }\n }\n }\n\n // Summary line\n console.log('')\n const parts = summary.map((s) => {\n const fn = STATUS_COLOR[s.status] ?? ((x: string) => x)\n return `${fn(s.status)}: ${s.total}`\n })\n console.log(pc.dim('Tasks — ') + parts.join(pc.dim(' | ')))\n } finally {\n db.close()\n }\n}\n","import { existsSync, readFileSync } from 'node:fs'\nimport { join, resolve } from 'node:path'\nimport pc from 'picocolors'\n\nimport { loadConfig } from '@/core/config'\nimport { openDB } from '@/core/db'\n\nimport type { TaskSeed } from '@/types'\n\ninterface SyncOptions {\n dryRun?: boolean\n direction?: 'in' | 'out' | 'both'\n}\n\nexport async function runSync(cwd: string, opts: SyncOptions): Promise<void> {\n const config = await loadConfig(cwd)\n const direction = opts.direction ?? 'both'\n const featureListPath = resolve(join(cwd, config.storage.dir, 'feature_list.json'))\n\n const db = openDB(config, cwd)\n\n try {\n if (direction === 'in' || direction === 'both') {\n await syncIn(featureListPath, db, opts.dryRun ?? false)\n }\n\n if (direction === 'out' || direction === 'both') {\n syncOut(db, cwd, opts.dryRun ?? false)\n }\n } finally {\n db.close()\n }\n}\n\nasync function syncIn(\n featureListPath: string,\n db: ReturnType<typeof openDB>,\n dryRun: boolean\n): Promise<void> {\n if (!existsSync(featureListPath)) {\n console.log(pc.dim(`feature_list.json not found at ${featureListPath} — skipping in-sync`))\n return\n }\n\n let seeds: TaskSeed[]\n try {\n seeds = JSON.parse(readFileSync(featureListPath, 'utf8')) as TaskSeed[]\n } catch (err) {\n console.error(pc.red(`Failed to parse feature_list.json: ${err}`))\n process.exit(1)\n }\n\n if (dryRun) {\n console.log(pc.bold('Dry run — in-sync (feature_list.json → SQLite):'))\n for (const t of seeds) {\n const existing = db.getTaskBySlug(t.slug)\n console.log(` ${existing ? pc.dim('skip') : pc.green('add ')} ${t.slug}`)\n }\n return\n }\n\n const result = db.syncFromFeatureList(seeds)\n console.log(pc.green(`✓ In-sync: ${result.added} added, ${result.skipped} already existed`))\n}\n\nfunction syncOut(\n db: ReturnType<typeof openDB>,\n cwd: string,\n dryRun: boolean\n): void {\n if (dryRun) {\n const tasks = db.getTasks()\n console.log(pc.bold('Dry run — out-sync (SQLite → feature_list.json):'))\n console.log(` ${tasks.length} tasks would be written`)\n return\n }\n\n db.writeFeatureList(cwd)\n console.log(pc.green('✓ Out-sync: feature_list.json updated'))\n}\n","import * as p from '@clack/prompts'\nimport pc from 'picocolors'\n\nimport { loadConfig } from '@/core/config'\nimport { openDB } from '@/core/db'\nimport { slugify } from '@/core/materializer/scaffold-utils'\n\nexport async function runTaskAdd(cwd: string): Promise<void> {\n p.intro(pc.bold('agent-harness-kit — add task'))\n\n const titleVal = await p.text({\n message: 'Task title',\n validate: (v) => (v.trim() ? undefined : 'Title is required'),\n })\n if (p.isCancel(titleVal)) { p.cancel('Cancelled.'); process.exit(0) }\n const title = (titleVal as string).trim()\n\n const descVal = await p.text({\n message: 'Description (what and why)',\n placeholder: 'Optional',\n })\n if (p.isCancel(descVal)) { p.cancel('Cancelled.'); process.exit(0) }\n const description = (descVal as string).trim()\n\n const acceptance: string[] = []\n p.log.info('Acceptance criteria — one per line, empty line to finish')\n while (true) {\n const val = await p.text({ message: '>', placeholder: 'Criterion (or press Enter to finish)' })\n if (p.isCancel(val) || !val || !(val as string).trim()) break\n acceptance.push((val as string).trim())\n }\n\n const spinner = p.spinner()\n spinner.start('Saving...')\n\n try {\n const config = await loadConfig(cwd)\n const db = openDB(config, cwd)\n\n const slug = slugify(title)\n const task = db.addTask({ slug, title, description: description || undefined, acceptance })\n db.writeFeatureList(cwd)\n db.close()\n\n spinner.stop('')\n console.log(pc.green(`✓ Task #${task.id} added — ${task.slug} (pending)`))\n console.log(pc.cyan('→') + ' ' + pc.cyan('ahk status') + ' to see all tasks')\n } catch (err) {\n spinner.stop(pc.red('Failed'))\n p.log.error(err instanceof Error ? err.message : String(err))\n process.exit(1)\n }\n}\n\n","import { spawnSync } from 'node:child_process'\nimport { existsSync } from 'node:fs'\nimport { resolve } from 'node:path'\nimport pc from 'picocolors'\n\nimport { loadConfig } from '@/core/config'\nimport { openDB } from '@/core/db'\n\nexport async function runTaskDone(cwd: string, idOrSlug: string): Promise<void> {\n const config = await loadConfig(cwd)\n\n // Run health check first if required\n if (config.health.required) {\n const scriptPath = resolve(cwd, config.health.scriptPath)\n if (existsSync(scriptPath)) {\n const result = spawnSync('bash', [scriptPath], { cwd, stdio: 'pipe', encoding: 'utf8' })\n if (result.status !== 0) {\n console.error(pc.red('✗ Health check failed — cannot mark task as done.'))\n if (result.stdout) console.error(result.stdout)\n if (result.stderr) console.error(result.stderr)\n process.exit(1)\n }\n }\n }\n\n const db = openDB(config, cwd)\n\n try {\n const parsed = parseInt(idOrSlug, 10)\n const isId = !isNaN(parsed)\n const task = isId ? db.getTaskById(parsed) : db.getTaskBySlug(idOrSlug)\n\n if (!task) {\n console.error(pc.red(`Task not found: ${idOrSlug}`))\n process.exit(1)\n }\n\n if (task.status === 'done') {\n console.log(pc.dim(`Task #${task.id} is already done.`))\n return\n }\n\n db.updateTaskStatus(task.id, 'done')\n db.writeFeatureList(cwd)\n\n console.log(pc.green(`✓ Task #${task.id} — ${task.slug} marked as done`))\n } finally {\n db.close()\n }\n}\n","import Table from 'cli-table3'\nimport pc from 'picocolors'\n\nimport { loadConfig } from '@/core/config'\nimport { openDB } from '@/core/db'\n\nimport type { TaskStatus } from '@/types'\n\ninterface TaskListOptions {\n status?: string\n json?: boolean\n}\n\nconst STATUS_COLOR: Record<string, (s: string) => string> = {\n pending: (s) => pc.dim(s),\n in_progress: (s) => pc.cyan(s),\n done: (s) => pc.green(s),\n blocked: (s) => pc.red(s),\n}\n\nexport async function runTaskList(cwd: string, opts: TaskListOptions): Promise<void> {\n const config = await loadConfig(cwd)\n const db = openDB(config, cwd)\n\n try {\n const validStatuses: TaskStatus[] = ['pending', 'in_progress', 'done', 'blocked']\n const filterStatus =\n opts.status && validStatuses.includes(opts.status as TaskStatus)\n ? (opts.status as TaskStatus)\n : undefined\n\n const tasks = filterStatus ? db.getTasks(filterStatus) : db.getTasks()\n\n if (opts.json) {\n console.log(JSON.stringify(tasks, null, 2))\n return\n }\n\n if (tasks.length === 0) {\n console.log(pc.dim('No tasks' + (filterStatus ? ` with status: ${filterStatus}` : '') + '.'))\n return\n }\n\n const table = new Table({\n head: ['ID', 'Slug', 'Title', 'Status'].map((h) => pc.bold(h)),\n style: { head: [], border: [] },\n })\n\n for (const t of tasks) {\n const colorFn = STATUS_COLOR[t.status] ?? ((s: string) => s)\n table.push([String(t.id), t.slug, t.title.slice(0, 50), colorFn(t.status)])\n }\n\n console.log(table.toString())\n } finally {\n db.close()\n }\n}\n","import { createRequire } from 'node:module'\nimport { dirname, join } from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nconst require = createRequire(import.meta.url)\n\n// Resolved at runtime relative to the compiled file location:\n// - local dev: dist/cli.js → ../package.json (root)\n// - installed: node_modules/@cardor/agent-harness-kit/dist/cli.js → ../package.json (package root)\nconst pkgPath = join(dirname(fileURLToPath(import.meta.url)), '..', 'package.json')\n\nexport const pkg = require(pkgPath) as { version: string; name: string }\n","// src/core/update-check.ts\nimport pc from 'picocolors'\n\nimport { pkg } from './package-data'\n\nconst REGISTRY_URL = `https://registry.npmjs.org/${pkg.name}/latest`\nconst TIMEOUT_MS = 2500\n\ninterface UpdateInfo {\n current: string\n latest: string\n}\n\nexport function checkForUpdate(currentVersion: string): Promise<UpdateInfo | null> {\n return new Promise((resolve) => {\n const timer = setTimeout(() => resolve(null), TIMEOUT_MS)\n\n fetch(REGISTRY_URL)\n .then((res) => res.json())\n .then((data) => {\n clearTimeout(timer)\n const latest = (data as { version: string }).version\n resolve(isNewer(latest, currentVersion) ? { current: currentVersion, latest } : null)\n })\n .catch(() => {\n clearTimeout(timer)\n resolve(null)\n })\n })\n}\n\nexport function printUpdateMessage({ current, latest }: UpdateInfo): void {\n const lines = [\n ` Update available ${pc.dim(current)} → ${pc.green(latest)} `,\n ` Run: ${pc.cyan(`npm i -g ${pkg.name}@latest`)} `,\n ]\n const width = Math.max(...lines.map((l) => stripAnsi(l).length))\n const border = '─'.repeat(width)\n\n console.log()\n console.log(pc.yellow(`┌${border}┐`))\n for (const line of lines) {\n const pad = width - stripAnsi(line).length\n console.log(pc.yellow('│') + line + ' '.repeat(pad) + pc.yellow('│'))\n }\n console.log(pc.yellow(`└${border}┘`))\n console.log()\n}\n\nfunction isNewer(latest: string, current: string): boolean {\n const toNum = (v: string) => v.split('.').map(Number)\n const [lMaj, lMin, lPat] = toNum(latest)\n const [cMaj, cMin, cPat] = toNum(current)\n\n if (lMaj !== cMaj) return lMaj > cMaj\n if (lMin !== cMin) return lMin > cMin\n\n return lPat > cPat\n}\n\nfunction stripAnsi(str: string): string {\n return str.replace(/\\x1B\\[[0-9;]*m/g, '')\n}"],"mappings":"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","names":["existsSync","mkdirSync","writeFileSync","join","resolve","existsSync","mkdirSync","readFileSync","writeFileSync","join","readFileSync","dirname","cwd","join","existsSync","mkdirSync","writeFileSync","readFileSync","cwd","join","mkdirSync","resolve","writeFileSync","existsSync","existsSync","mkdirSync","writeFileSync","join","resolve","cwd","join","mkdirSync","resolve","writeFileSync","existsSync","cwd","spinner","dirname","join","resolve","fileURLToPath","pc","watch","existsSync","readFileSync","join","task","mkdirSync","writeFileSync","dirname","join","resolve","resolve","mkdirSync","dirname","task","writeFileSync","cwd","join","__dirname","dirname","fileURLToPath","cwd","resolve","join","pc","writeFileSync","pc","cwd","pc","writeFileSync","existsSync","join","resolve","pc","ok","pc","cwd","resolve","existsSync","join","mkdirSync","writeFileSync","join","p","pc","cwd","pc","spinner","writeFileSync","join","mkdirSync","p","pc","cwd","pc","spinner","readFileSync","join","resolve","cwd","resolve","task","readFileSync","join","text","cwd","pc","pc","cwd","existsSync","readFileSync","join","resolve","pc","cwd","resolve","join","existsSync","pc","readFileSync","p","pc","cwd","pc","spinner","task","spawnSync","existsSync","resolve","pc","cwd","resolve","existsSync","spawnSync","pc","task","Table","pc","STATUS_COLOR","pc","cwd","Table","createRequire","dirname","join","fileURLToPath","require","pc","resolve","pc","str"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cardor/agent-harness-kit",
3
- "version": "0.16.0",
3
+ "version": "0.16.2",
4
4
  "description": "CLI scaffolding for multi-agent harness systems",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -51,6 +51,7 @@
51
51
  "ws": "^8.18.0"
52
52
  },
53
53
  "devDependencies": {
54
+ "@cardor/agent-harness-kit": "^0.16.0",
54
55
  "@commitlint/cli": "^20.5.3",
55
56
  "@commitlint/config-conventional": "^20.5.3",
56
57
  "@eslint-react/eslint-plugin": "^5.7.1",