@cardor/agent-harness-kit 0.3.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/README.md +2 -0
  2. package/dist/cli.js.map +1 -1
  3. package/dist/commands/build.js.map +1 -1
  4. package/dist/commands/init.d.ts.map +1 -1
  5. package/dist/commands/init.js +1 -7
  6. package/dist/commands/init.js.map +1 -1
  7. package/dist/commands/task/add.d.ts.map +1 -1
  8. package/dist/commands/task/add.js +1 -7
  9. package/dist/commands/task/add.js.map +1 -1
  10. package/dist/core/materializer/agent-templates/builder.md +110 -0
  11. package/dist/core/materializer/agent-templates/explorer.md +111 -0
  12. package/dist/core/materializer/agent-templates/lead.md +119 -0
  13. package/dist/core/materializer/agent-templates/reviewer.md +120 -0
  14. package/dist/core/materializer/agent-templates/test123.txt +0 -0
  15. package/dist/core/materializer/claude-code.d.ts.map +1 -1
  16. package/dist/core/materializer/claude-code.js +18 -35
  17. package/dist/core/materializer/claude-code.js.map +1 -1
  18. package/dist/core/materializer/mcp-merge.d.ts +3 -0
  19. package/dist/core/materializer/mcp-merge.d.ts.map +1 -0
  20. package/dist/core/materializer/mcp-merge.js +55 -0
  21. package/dist/core/materializer/mcp-merge.js.map +1 -0
  22. package/dist/core/materializer/opencode.d.ts.map +1 -1
  23. package/dist/core/materializer/opencode.js +18 -35
  24. package/dist/core/materializer/opencode.js.map +1 -1
  25. package/dist/core/materializer/scaffold-utils.d.ts +4 -0
  26. package/dist/core/materializer/scaffold-utils.d.ts.map +1 -0
  27. package/dist/core/materializer/scaffold-utils.js +28 -0
  28. package/dist/core/materializer/scaffold-utils.js.map +1 -0
  29. package/dist/core/materializer/templates.d.ts +14 -6
  30. package/dist/core/materializer/templates.d.ts.map +1 -1
  31. package/dist/core/materializer/templates.js +27 -160
  32. package/dist/core/materializer/templates.js.map +1 -1
  33. package/dist/tests/slugify.test.js +1 -8
  34. package/dist/tests/slugify.test.js.map +1 -1
  35. package/dist/tests/templates.test.js +2 -1
  36. package/dist/tests/templates.test.js.map +1 -1
  37. package/package.json +3 -2
@@ -1,6 +1,8 @@
1
- import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
1
+ import { existsSync, mkdirSync, writeFileSync } from 'node:fs';
2
2
  import { join, resolve } from 'node:path';
3
- import { HEALTH_SH, GITIGNORE_ENTRIES, agentsMd, mergeClaudeMcpJson, featureListJson, AGENT_LEAD, AGENT_EXPLORER, AGENT_BUILDER, AGENT_REVIEWER, } from './templates.js';
3
+ import { HEALTH_SH, agentsMd, featureListJson, agentLead, agentExplorer, agentBuilder, agentReviewer } from './templates.js';
4
+ import { mergeClaudeMcpJson } from './mcp-merge.js';
5
+ import { writeAgentFile, appendGitignore, slugify } from './scaffold-utils.js';
4
6
  export class ClaudeCodeMaterializer {
5
7
  async scaffold(config, opts) {
6
8
  const { cwd } = opts;
@@ -25,10 +27,13 @@ export class ClaudeCodeMaterializer {
25
27
  write(config.storage.markdownFallback.path, `<!-- 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`);
26
28
  }
27
29
  // .claude/agents/ — skip files the dev may have customized
28
- writeAgentFile(cwd, '.claude/agents/lead.md', AGENT_LEAD);
29
- writeAgentFile(cwd, '.claude/agents/explorer.md', AGENT_EXPLORER);
30
- writeAgentFile(cwd, '.claude/agents/builder.md', AGENT_BUILDER);
31
- writeAgentFile(cwd, '.claude/agents/reviewer.md', AGENT_REVIEWER);
30
+ const projectName = config.project.name;
31
+ const allowedPaths = (config.agents.explorer.allowedPaths ?? []).join(', ');
32
+ const writablePaths = (config.agents.builder.writablePaths ?? []).join(', ');
33
+ writeAgentFile(cwd, '.claude/agents/lead.md', agentLead({ projectName }));
34
+ writeAgentFile(cwd, '.claude/agents/explorer.md', agentExplorer({ projectName, allowedPaths }));
35
+ writeAgentFile(cwd, '.claude/agents/builder.md', agentBuilder({ projectName, writablePaths }));
36
+ writeAgentFile(cwd, '.claude/agents/reviewer.md', agentReviewer({ projectName }));
32
37
  // .claude/mcp.json — MERGE, never overwrite whole file
33
38
  mergeClaudeMcpJson(join(cwd, '.claude', 'mcp.json'), config.tools.mcp.port);
34
39
  // .gitignore additions
@@ -43,10 +48,13 @@ export class ClaudeCodeMaterializer {
43
48
  // build always regenerates AGENTS.md (it's derived from config)
44
49
  write('AGENTS.md', agentsMd(config));
45
50
  // Agent files: skip if customized, write if missing
46
- writeAgentFile(cwd, '.claude/agents/lead.md', AGENT_LEAD);
47
- writeAgentFile(cwd, '.claude/agents/explorer.md', AGENT_EXPLORER);
48
- writeAgentFile(cwd, '.claude/agents/builder.md', AGENT_BUILDER);
49
- writeAgentFile(cwd, '.claude/agents/reviewer.md', AGENT_REVIEWER);
51
+ const projectName = config.project.name;
52
+ const allowedPaths = (config.agents.explorer.allowedPaths ?? []).join(', ');
53
+ const writablePaths = (config.agents.builder.writablePaths ?? []).join(', ');
54
+ writeAgentFile(cwd, '.claude/agents/lead.md', agentLead({ projectName }));
55
+ writeAgentFile(cwd, '.claude/agents/explorer.md', agentExplorer({ projectName, allowedPaths }));
56
+ writeAgentFile(cwd, '.claude/agents/builder.md', agentBuilder({ projectName, writablePaths }));
57
+ writeAgentFile(cwd, '.claude/agents/reviewer.md', agentReviewer({ projectName }));
50
58
  // MCP config: always merge
51
59
  mergeClaudeMcpJson(join(cwd, '.claude', 'mcp.json'), config.tools.mcp.port);
52
60
  }
@@ -55,29 +63,4 @@ export class ClaudeCodeMaterializer {
55
63
  // Migration from claude-code is handled by the target materializer
56
64
  }
57
65
  }
58
- // ─── Shared helpers ───────────────────────────────────────────────────────────
59
- function writeAgentFile(cwd, relPath, content) {
60
- const abs = join(cwd, relPath);
61
- if (existsSync(abs))
62
- return; // preserve dev customizations
63
- mkdirSync(resolve(abs, '..'), { recursive: true });
64
- writeFileSync(abs, content, 'utf8');
65
- }
66
- function appendGitignore(cwd) {
67
- const giPath = join(cwd, '.gitignore');
68
- const existing = existsSync(giPath) ? readFileSync(giPath, 'utf8') : '';
69
- const toAdd = GITIGNORE_ENTRIES.split('\n')
70
- .filter((line) => line && !existing.includes(line))
71
- .join('\n');
72
- if (toAdd.trim()) {
73
- writeFileSync(giPath, existing + (existing.endsWith('\n') ? '' : '\n') + toAdd + '\n', 'utf8');
74
- }
75
- }
76
- function slugify(title) {
77
- return title
78
- .toLowerCase()
79
- .replace(/[^a-z0-9]+/g, '-')
80
- .replace(/^-+|-+$/g, '')
81
- .slice(0, 64);
82
- }
83
66
  //# sourceMappingURL=claude-code.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"claude-code.js","sourceRoot":"","sources":["../../../src/core/materializer/claude-code.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"claude-code.js","sourceRoot":"","sources":["../../../src/core/materializer/claude-code.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AAC9D,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAGzC,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,eAAe,EAAE,SAAS,EAAE,aAAa,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AAC5H,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAA;AACnD,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAE9E,MAAM,OAAO,sBAAsB;IACjC,KAAK,CAAC,QAAQ,CAAC,MAAqB,EAAE,IAAqB;QACzD,MAAM,EAAE,GAAG,EAAE,GAAG,IAAI,CAAA;QAEpB,MAAM,KAAK,GAAG,CAAC,OAAe,EAAE,OAAe,EAAE,IAAa,EAAE,EAAE;YAChE,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,OAAO,CAAC,CAAA;YAC9B,SAAS,CAAC,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;YAClD,aAAa,CAAC,GAAG,EAAE,OAAO,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAA;QACzD,CAAC,CAAA;QAED,uDAAuD;QACvD,KAAK,CAAC,WAAW,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAA;QAEpC,8CAA8C;QAC9C,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC,EAAE,CAAC;YACxC,KAAK,CAAC,WAAW,EAAE,SAAS,EAAE,KAAK,CAAC,CAAA;QACtC,CAAC;QAED,6BAA6B;QAC7B,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS;YAC1B,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;YAC9D,CAAC,CAAC,EAAE,CAAA;QACN,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,mBAAmB,CAAC,EAAE,eAAe,CAAC,KAAK,CAAC,CAAC,CAAA;QAE5E,kCAAkC;QAClC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,OAAO,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;YACjE,KAAK,CACH,MAAM,CAAC,OAAO,CAAC,gBAAgB,CAAC,IAAI,EACpC,yJAAyJ,CAC1J,CAAA;QACH,CAAC;QAED,2DAA2D;QAC3D,MAAM,WAAW,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAA;QACvC,MAAM,YAAY,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,YAAY,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAC3E,MAAM,aAAa,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,aAAa,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAC5E,cAAc,CAAC,GAAG,EAAE,wBAAwB,EAAE,SAAS,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,CAAA;QACzE,cAAc,CAAC,GAAG,EAAE,4BAA4B,EAAE,aAAa,CAAC,EAAE,WAAW,EAAE,YAAY,EAAE,CAAC,CAAC,CAAA;QAC/F,cAAc,CAAC,GAAG,EAAE,2BAA2B,EAAE,YAAY,CAAC,EAAE,WAAW,EAAE,aAAa,EAAE,CAAC,CAAC,CAAA;QAC9F,cAAc,CAAC,GAAG,EAAE,4BAA4B,EAAE,aAAa,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,CAAA;QAEjF,uDAAuD;QACvD,kBAAkB,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,EAAE,UAAU,CAAC,EAAE,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;QAE3E,uBAAuB;QACvB,eAAe,CAAC,GAAG,CAAC,CAAA;IACtB,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,MAAqB,EAAE,GAAW;QAC5C,MAAM,KAAK,GAAG,CAAC,OAAe,EAAE,OAAe,EAAE,EAAE;YACjD,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,OAAO,CAAC,CAAA;YAC9B,SAAS,CAAC,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;YAClD,aAAa,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,CAAC,CAAA;QACrC,CAAC,CAAA;QAED,gEAAgE;QAChE,KAAK,CAAC,WAAW,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAA;QAEpC,oDAAoD;QACpD,MAAM,WAAW,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAA;QACvC,MAAM,YAAY,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,YAAY,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAC3E,MAAM,aAAa,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,aAAa,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAC5E,cAAc,CAAC,GAAG,EAAE,wBAAwB,EAAE,SAAS,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,CAAA;QACzE,cAAc,CAAC,GAAG,EAAE,4BAA4B,EAAE,aAAa,CAAC,EAAE,WAAW,EAAE,YAAY,EAAE,CAAC,CAAC,CAAA;QAC/F,cAAc,CAAC,GAAG,EAAE,2BAA2B,EAAE,YAAY,CAAC,EAAE,WAAW,EAAE,aAAa,EAAE,CAAC,CAAC,CAAA;QAC9F,cAAc,CAAC,GAAG,EAAE,4BAA4B,EAAE,aAAa,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,CAAA;QAEjF,2BAA2B;QAC3B,kBAAkB,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,EAAE,UAAU,CAAC,EAAE,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;IAC7E,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,MAAqB,EAAE,GAAa,EAAE,IAAY;QAC9D,KAAK,MAAM,CAAA;QACX,mEAAmE;IACrE,CAAC;CACF"}
@@ -0,0 +1,3 @@
1
+ export declare function mergeClaudeMcpJson(filePath: string, port: number): void;
2
+ export declare function mergeOpencodeJson(filePath: string, port: number): void;
3
+ //# sourceMappingURL=mcp-merge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-merge.d.ts","sourceRoot":"","sources":["../../../src/core/materializer/mcp-merge.ts"],"names":[],"mappings":"AAGA,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAwBvE;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CA6BtE"}
@@ -0,0 +1,55 @@
1
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
2
+ import { dirname } from 'node:path';
3
+ export function mergeClaudeMcpJson(filePath, port) {
4
+ let existing = {};
5
+ if (existsSync(filePath)) {
6
+ try {
7
+ existing = JSON.parse(readFileSync(filePath, 'utf8'));
8
+ }
9
+ catch {
10
+ // Unreadable JSON — start fresh to avoid corrupt state
11
+ }
12
+ }
13
+ const merged = {
14
+ ...existing,
15
+ mcpServers: {
16
+ ...(existing.mcpServers ?? {}),
17
+ 'agent-harness-kit': {
18
+ command: 'npx',
19
+ args: ['ahk', 'serve', '--port', String(port)],
20
+ type: 'stdio',
21
+ },
22
+ },
23
+ };
24
+ mkdirSync(dirname(filePath), { recursive: true });
25
+ writeFileSync(filePath, JSON.stringify(merged, null, 2) + '\n', 'utf8');
26
+ }
27
+ export function mergeOpencodeJson(filePath, port) {
28
+ let existing = {};
29
+ if (existsSync(filePath)) {
30
+ try {
31
+ existing = JSON.parse(readFileSync(filePath, 'utf8'));
32
+ }
33
+ catch {
34
+ // start fresh
35
+ }
36
+ }
37
+ const existingMcp = existing.mcp ?? {};
38
+ const existingServers = existingMcp.servers ?? {};
39
+ const merged = {
40
+ ...existing,
41
+ mcp: {
42
+ ...existingMcp,
43
+ servers: {
44
+ ...existingServers,
45
+ 'agent-harness-kit': {
46
+ command: 'npx',
47
+ args: ['ahk', 'serve', '--port', String(port)],
48
+ type: 'stdio',
49
+ },
50
+ },
51
+ },
52
+ };
53
+ writeFileSync(filePath, JSON.stringify(merged, null, 2) + '\n', 'utf8');
54
+ }
55
+ //# sourceMappingURL=mcp-merge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-merge.js","sourceRoot":"","sources":["../../../src/core/materializer/mcp-merge.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AAC5E,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAEnC,MAAM,UAAU,kBAAkB,CAAC,QAAgB,EAAE,IAAY;IAC/D,IAAI,QAAQ,GAA4B,EAAE,CAAA;IAC1C,IAAI,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QACzB,IAAI,CAAC;YACH,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAA4B,CAAA;QAClF,CAAC;QAAC,MAAM,CAAC;YACP,uDAAuD;QACzD,CAAC;IACH,CAAC;IAED,MAAM,MAAM,GAAG;QACb,GAAG,QAAQ;QACX,UAAU,EAAE;YACV,GAAG,CAAE,QAAQ,CAAC,UAAsC,IAAI,EAAE,CAAC;YAC3D,mBAAmB,EAAE;gBACnB,OAAO,EAAE,KAAK;gBACd,IAAI,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;gBAC9C,IAAI,EAAE,OAAO;aACd;SACF;KACF,CAAA;IAED,SAAS,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IACjD,aAAa,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,MAAM,CAAC,CAAA;AACzE,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,QAAgB,EAAE,IAAY;IAC9D,IAAI,QAAQ,GAA4B,EAAE,CAAA;IAC1C,IAAI,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QACzB,IAAI,CAAC;YACH,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAA4B,CAAA;QAClF,CAAC;QAAC,MAAM,CAAC;YACP,cAAc;QAChB,CAAC;IACH,CAAC;IAED,MAAM,WAAW,GAAI,QAAQ,CAAC,GAA+B,IAAI,EAAE,CAAA;IACnE,MAAM,eAAe,GAAI,WAAW,CAAC,OAAmC,IAAI,EAAE,CAAA;IAE9E,MAAM,MAAM,GAAG;QACb,GAAG,QAAQ;QACX,GAAG,EAAE;YACH,GAAG,WAAW;YACd,OAAO,EAAE;gBACP,GAAG,eAAe;gBAClB,mBAAmB,EAAE;oBACnB,OAAO,EAAE,KAAK;oBACd,IAAI,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;oBAC9C,IAAI,EAAE,OAAO;iBACd;aACF;SACF;KACF,CAAA;IAED,aAAa,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,MAAM,CAAC,CAAA;AACzE,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"opencode.d.ts","sourceRoot":"","sources":["../../../src/core/materializer/opencode.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAC9E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAa9C,qBAAa,oBAAqB,YAAW,YAAY;IACjD,QAAQ,CAAC,MAAM,EAAE,aAAa,EAAE,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IAyCrE,KAAK,CAAC,MAAM,EAAE,aAAa,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAiBxD,OAAO,CAAC,MAAM,EAAE,aAAa,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAGjF"}
1
+ {"version":3,"file":"opencode.d.ts","sourceRoot":"","sources":["../../../src/core/materializer/opencode.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAC9E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAK9C,qBAAa,oBAAqB,YAAW,YAAY;IACjD,QAAQ,CAAC,MAAM,EAAE,aAAa,EAAE,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IA4CrE,KAAK,CAAC,MAAM,EAAE,aAAa,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAoBxD,OAAO,CAAC,MAAM,EAAE,aAAa,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAGjF"}
@@ -1,6 +1,8 @@
1
- import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
1
+ import { existsSync, mkdirSync, writeFileSync } from 'node:fs';
2
2
  import { join, resolve } from 'node:path';
3
- import { HEALTH_SH, GITIGNORE_ENTRIES, agentsMd, mergeOpencodeJson, featureListJson, AGENT_LEAD, AGENT_EXPLORER, AGENT_BUILDER, AGENT_REVIEWER, } from './templates.js';
3
+ import { HEALTH_SH, agentsMd, featureListJson, agentLead, agentExplorer, agentBuilder, agentReviewer } from './templates.js';
4
+ import { mergeOpencodeJson } from './mcp-merge.js';
5
+ import { writeAgentFile, appendGitignore, slugify } from './scaffold-utils.js';
4
6
  export class OpenCodeMaterializer {
5
7
  async scaffold(config, opts) {
6
8
  const { cwd } = opts;
@@ -23,10 +25,13 @@ export class OpenCodeMaterializer {
23
25
  write(config.storage.markdownFallback.path, `<!-- 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`);
24
26
  }
25
27
  // .opencode/agents/ — skip files the dev may have customized
26
- writeAgentFile(cwd, '.opencode/agents/lead.md', AGENT_LEAD);
27
- writeAgentFile(cwd, '.opencode/agents/explorer.md', AGENT_EXPLORER);
28
- writeAgentFile(cwd, '.opencode/agents/builder.md', AGENT_BUILDER);
29
- writeAgentFile(cwd, '.opencode/agents/reviewer.md', AGENT_REVIEWER);
28
+ const projectName = config.project.name;
29
+ const allowedPaths = (config.agents.explorer.allowedPaths ?? []).join(', ');
30
+ const writablePaths = (config.agents.builder.writablePaths ?? []).join(', ');
31
+ writeAgentFile(cwd, '.opencode/agents/lead.md', agentLead({ projectName }));
32
+ writeAgentFile(cwd, '.opencode/agents/explorer.md', agentExplorer({ projectName, allowedPaths }));
33
+ writeAgentFile(cwd, '.opencode/agents/builder.md', agentBuilder({ projectName, writablePaths }));
34
+ writeAgentFile(cwd, '.opencode/agents/reviewer.md', agentReviewer({ projectName }));
30
35
  // opencode.json — MERGE, never overwrite whole file
31
36
  mergeOpencodeJson(join(cwd, 'opencode.json'), config.tools.mcp.port);
32
37
  appendGitignore(cwd);
@@ -38,39 +43,17 @@ export class OpenCodeMaterializer {
38
43
  writeFileSync(abs, content, 'utf8');
39
44
  };
40
45
  write('AGENTS.md', agentsMd(config));
41
- writeAgentFile(cwd, '.opencode/agents/lead.md', AGENT_LEAD);
42
- writeAgentFile(cwd, '.opencode/agents/explorer.md', AGENT_EXPLORER);
43
- writeAgentFile(cwd, '.opencode/agents/builder.md', AGENT_BUILDER);
44
- writeAgentFile(cwd, '.opencode/agents/reviewer.md', AGENT_REVIEWER);
46
+ const projectName = config.project.name;
47
+ const allowedPaths = (config.agents.explorer.allowedPaths ?? []).join(', ');
48
+ const writablePaths = (config.agents.builder.writablePaths ?? []).join(', ');
49
+ writeAgentFile(cwd, '.opencode/agents/lead.md', agentLead({ projectName }));
50
+ writeAgentFile(cwd, '.opencode/agents/explorer.md', agentExplorer({ projectName, allowedPaths }));
51
+ writeAgentFile(cwd, '.opencode/agents/builder.md', agentBuilder({ projectName, writablePaths }));
52
+ writeAgentFile(cwd, '.opencode/agents/reviewer.md', agentReviewer({ projectName }));
45
53
  mergeOpencodeJson(join(cwd, 'opencode.json'), config.tools.mcp.port);
46
54
  }
47
55
  async migrate(config, _to, _cwd) {
48
56
  void config;
49
57
  }
50
58
  }
51
- // ─── Shared helpers ───────────────────────────────────────────────────────────
52
- function writeAgentFile(cwd, relPath, content) {
53
- const abs = join(cwd, relPath);
54
- if (existsSync(abs))
55
- return; // preserve dev customizations
56
- mkdirSync(resolve(abs, '..'), { recursive: true });
57
- writeFileSync(abs, content, 'utf8');
58
- }
59
- function appendGitignore(cwd) {
60
- const giPath = join(cwd, '.gitignore');
61
- const existing = existsSync(giPath) ? readFileSync(giPath, 'utf8') : '';
62
- const toAdd = GITIGNORE_ENTRIES.split('\n')
63
- .filter((line) => line && !existing.includes(line))
64
- .join('\n');
65
- if (toAdd.trim()) {
66
- writeFileSync(giPath, existing + (existing.endsWith('\n') ? '' : '\n') + toAdd + '\n', 'utf8');
67
- }
68
- }
69
- function slugify(title) {
70
- return title
71
- .toLowerCase()
72
- .replace(/[^a-z0-9]+/g, '-')
73
- .replace(/^-+|-+$/g, '')
74
- .slice(0, 64);
75
- }
76
59
  //# sourceMappingURL=opencode.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"opencode.js","sourceRoot":"","sources":["../../../src/core/materializer/opencode.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"opencode.js","sourceRoot":"","sources":["../../../src/core/materializer/opencode.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export declare function writeAgentFile(cwd: string, relPath: string, content: string): void;
2
+ export declare function appendGitignore(cwd: string): void;
3
+ export declare function slugify(title: string): string;
4
+ //# sourceMappingURL=scaffold-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scaffold-utils.d.ts","sourceRoot":"","sources":["../../../src/core/materializer/scaffold-utils.ts"],"names":[],"mappings":"AAIA,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAKlF;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAWjD;AAED,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAM7C"}
@@ -0,0 +1,28 @@
1
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
2
+ import { join, resolve } from 'node:path';
3
+ import { GITIGNORE_ENTRIES } from './templates.js';
4
+ export function writeAgentFile(cwd, relPath, content) {
5
+ const abs = join(cwd, relPath);
6
+ if (existsSync(abs))
7
+ return; // preserve dev customizations
8
+ mkdirSync(resolve(abs, '..'), { recursive: true });
9
+ writeFileSync(abs, content, 'utf8');
10
+ }
11
+ export function appendGitignore(cwd) {
12
+ const giPath = join(cwd, '.gitignore');
13
+ const existing = existsSync(giPath) ? readFileSync(giPath, 'utf8') : '';
14
+ const toAdd = GITIGNORE_ENTRIES.split('\n')
15
+ .filter((line) => line && !existing.includes(line))
16
+ .join('\n');
17
+ if (toAdd.trim()) {
18
+ writeFileSync(giPath, existing + (existing.endsWith('\n') ? '' : '\n') + toAdd + '\n', 'utf8');
19
+ }
20
+ }
21
+ export function slugify(title) {
22
+ return title
23
+ .toLowerCase()
24
+ .replace(/[^a-z0-9]+/g, '-')
25
+ .replace(/^-+|-+$/g, '')
26
+ .slice(0, 64);
27
+ }
28
+ //# sourceMappingURL=scaffold-utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scaffold-utils.js","sourceRoot":"","sources":["../../../src/core/materializer/scaffold-utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AAC5E,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACzC,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAA;AAElD,MAAM,UAAU,cAAc,CAAC,GAAW,EAAE,OAAe,EAAE,OAAe;IAC1E,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,OAAO,CAAC,CAAA;IAC9B,IAAI,UAAU,CAAC,GAAG,CAAC;QAAE,OAAM,CAAE,8BAA8B;IAC3D,SAAS,CAAC,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IAClD,aAAa,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,CAAC,CAAA;AACrC,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,GAAW;IACzC,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,EAAE,YAAY,CAAC,CAAA;IACtC,MAAM,QAAQ,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;IAEvE,MAAM,KAAK,GAAG,iBAAiB,CAAC,KAAK,CAAC,IAAI,CAAC;SACxC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;SAClD,IAAI,CAAC,IAAI,CAAC,CAAA;IAEb,IAAI,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC;QACjB,aAAa,CAAC,MAAM,EAAE,QAAQ,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,KAAK,GAAG,IAAI,EAAE,MAAM,CAAC,CAAA;IAChG,CAAC;AACH,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,KAAa;IACnC,OAAO,KAAK;SACT,WAAW,EAAE;SACb,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC;SAC3B,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC;SACvB,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;AACjB,CAAC"}
@@ -9,17 +9,25 @@ export declare function configTs(params: {
9
9
  tasksAdapter: string;
10
10
  port: number;
11
11
  }): string;
12
- export declare const AGENT_LEAD = "---\ndescription: Lead agent \u2014 orchestrates the harness workflow for a single task\n---\n\n# Lead Agent\n\nYou are the **lead agent** in the agent-harness-kit harness. Your job is to decompose a task into a plan and coordinate the other agents.\n\n## Your workflow\n\n1. Read `.harness/current.md` (or call `tasks.get('in_progress')`) to orient yourself.\n2. Call `actions.start(taskId, 'lead')` to register your action.\n3. Decompose the task:\n - What needs to be explored first?\n - What needs to be built?\n - What are the acceptance criteria?\n4. Call `actions.write(actionId, 'result', plan)` with your decomposition.\n5. Call `actions.complete(actionId, 'Plan defined')`.\n6. Delegate to explorer, then builder, then reviewer \u2014 in that order.\n\n## Rules\n\n- Do NOT write code yourself. Delegate to builder.\n- Do NOT read source files yourself. Delegate to explorer.\n- One task at a time. Check `tasks.get('in_progress')` before picking a new one.\n- If the reviewer blocks, coordinate a fix with builder and re-review.\n";
13
- export declare const AGENT_EXPLORER = "---\ndescription: Explorer agent \u2014 reads and maps the codebase, never writes files\n---\n\n# Explorer Agent\n\nYou are the **explorer agent** in the agent-harness-kit harness. Your job is to read and understand the relevant parts of the codebase for the current task. You never write or modify files.\n\n## Your workflow\n\n1. Call `actions.start(taskId, 'explorer')` to register your action.\n2. Read only the files relevant to the current task. Use `docs.search(query)` first.\n3. Record what you find:\n - `actions.write(actionId, 'tools_used', list_of_tools)`\n - `actions.write(actionId, 'result', analysis)`\n4. Call `actions.complete(actionId, 'Analysis done')`.\n\n## Rules\n\n- Never modify files. You are read-only.\n- Use progressive disclosure \u2014 read AGENTS.md, then navigate to specific files.\n- Record every file you read via `actions.write(actionId, 'tools_used', ...)`.\n";
14
- export declare const AGENT_BUILDER = "---\ndescription: Builder agent \u2014 implements the plan produced by explorer and lead\n---\n\n# Builder Agent\n\nYou are the **builder agent** in the agent-harness-kit harness. Your job is to implement the plan from lead, using the analysis from explorer.\n\n## Your workflow\n\n1. Read the lead's plan from `actions.get(taskId)`.\n2. Call `actions.start(taskId, 'builder')` to register your action.\n3. Implement the task. Record every file you touch:\n - `actions.write(actionId, 'files_modified', list)`\n4. Record the result:\n - `actions.write(actionId, 'result', summary_of_changes)`\n5. If you hit a blocker: `actions.write(actionId, 'blockers', description)`\n6. Call `actions.complete(actionId, 'Implementation done')`.\n\n## Rules\n\n- Only write to the paths allowed by your config (writablePaths).\n- If something is unclear, record a blocker and surface it to lead \u2014 don't guess.\n- Run tests after implementing if the project has a test suite.\n";
15
- export declare const AGENT_REVIEWER = "---\ndescription: Reviewer agent \u2014 verifies acceptance criteria before marking a task done\n---\n\n# Reviewer Agent\n\nYou are the **reviewer agent** in the agent-harness-kit harness. Your job is to verify that the builder's work meets all acceptance criteria before the task is marked done.\n\n## Your workflow\n\n1. Call `actions.get(taskId)` to read the full history (lead plan + explorer analysis + builder changes).\n2. Call `actions.start(taskId, 'reviewer')` to register your action.\n3. Verify each acceptance criterion:\n - `actions.write(actionId, 'result', 'APPROVED' or 'BLOCKED: reason')`\n4. If approved:\n - `actions.complete(actionId, 'Task approved')`\n - `tasks.update(taskId, 'done')`\n5. If blocked:\n - `actions.write(actionId, 'blockers', what_is_missing)`\n - `actions.complete(actionId, 'Task blocked: reason')`\n - Notify lead to re-assign to builder.\n\n## Rules\n\n- Never approve unless ALL acceptance criteria are met.\n- Check that health.sh is green before approving.\n- Be specific about what is missing when blocking.\n";
12
+ export declare function agentLead(vars: {
13
+ projectName: string;
14
+ }): string;
15
+ export declare function agentExplorer(vars: {
16
+ projectName: string;
17
+ allowedPaths: string;
18
+ }): string;
19
+ export declare function agentBuilder(vars: {
20
+ projectName: string;
21
+ writablePaths: string;
22
+ }): string;
23
+ export declare function agentReviewer(vars: {
24
+ projectName: string;
25
+ }): string;
16
26
  export declare function featureListJson(tasks: {
17
27
  slug: string;
18
28
  title: string;
19
29
  description?: string;
20
30
  acceptance?: string[];
21
31
  }[]): string;
22
- export declare function mergeClaudeMcpJson(filePath: string, port: number): void;
23
- export declare function mergeOpencodeJson(filePath: string, port: number): void;
24
32
  export declare 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";
25
33
  //# sourceMappingURL=templates.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../../../src/core/materializer/templates.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AAInD,eAAO,MAAM,SAAS,uoBAmBrB,CAAA;AAID,wBAAgB,QAAQ,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM,CA8EtD;AAID,wBAAgB,QAAQ,CAAC,MAAM,EAAE;IAC/B,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;IACnB,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;IAChB,YAAY,EAAE,MAAM,CAAA;IACpB,IAAI,EAAE,MAAM,CAAA;CACb,GAAG,MAAM,CA6CT;AAID,eAAO,MAAM,UAAU,4hCA0BtB,CAAA;AAED,eAAO,MAAM,cAAc,24BAsB1B,CAAA;AAED,eAAO,MAAM,aAAa,g9BAwBzB,CAAA;AAED,eAAO,MAAM,cAAc,kjCA2B1B,CAAA;AAID,wBAAgB,eAAe,CAC7B,KAAK,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,EAAE,GACpF,MAAM,CAER;AAQD,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAwBvE;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CA6BtE;AAID,eAAO,MAAM,iBAAiB,wHAM7B,CAAA"}
1
+ {"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../../../src/core/materializer/templates.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AAqBnD,eAAO,MAAM,SAAS,uoBAmBrB,CAAA;AAID,wBAAgB,QAAQ,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM,CA8EtD;AAID,wBAAgB,QAAQ,CAAC,MAAM,EAAE;IAC/B,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;IACnB,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;IAChB,YAAY,EAAE,MAAM,CAAA;IACpB,IAAI,EAAE,MAAM,CAAA;CACb,GAAG,MAAM,CA6CT;AAID,wBAAgB,SAAS,CAAC,IAAI,EAAE;IAAE,WAAW,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAE/D;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAEzF;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAEzF;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE;IAAE,WAAW,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAEnE;AAID,wBAAgB,eAAe,CAC7B,KAAK,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,EAAE,GACpF,MAAM,CAER;AAID,eAAO,MAAM,iBAAiB,wHAM7B,CAAA"}
@@ -1,3 +1,17 @@
1
+ import { readFileSync } from 'node:fs';
2
+ import { join, dirname } from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
4
+ // ─── Agent template loader ────────────────────────────────────────────────────
5
+ const __dirname = dirname(fileURLToPath(import.meta.url));
6
+ const TEMPLATES_DIR = join(__dirname, 'agent-templates');
7
+ /**
8
+ * Load an agent template file and interpolate {{variables}}.
9
+ * Variables are replaced using a simple {{key}} pattern.
10
+ */
11
+ function loadAgentTemplate(name, vars = {}) {
12
+ const raw = readFileSync(join(TEMPLATES_DIR, `${name}.md`), 'utf8');
13
+ return raw.replace(/\{\{(\w+)\}\}/g, (_, key) => vars[key] ?? `{{${key}}}`);
14
+ }
1
15
  // ─── health.sh — exits 1 until the dev implements it ─────────────────────────
2
16
  export const HEALTH_SH = `#!/usr/bin/env bash
3
17
  # health.sh — project health check for agent-harness-kit
@@ -145,170 +159,23 @@ export default defineHarness({
145
159
  })
146
160
  `;
147
161
  }
148
- // ─── Agent definition templates ───────────────────────────────────────────────
149
- export const AGENT_LEAD = `---
150
- description: Lead agent — orchestrates the harness workflow for a single task
151
- ---
152
-
153
- # Lead Agent
154
-
155
- You are the **lead agent** in the agent-harness-kit harness. Your job is to decompose a task into a plan and coordinate the other agents.
156
-
157
- ## Your workflow
158
-
159
- 1. Read \`.harness/current.md\` (or call \`tasks.get('in_progress')\`) to orient yourself.
160
- 2. Call \`actions.start(taskId, 'lead')\` to register your action.
161
- 3. Decompose the task:
162
- - What needs to be explored first?
163
- - What needs to be built?
164
- - What are the acceptance criteria?
165
- 4. Call \`actions.write(actionId, 'result', plan)\` with your decomposition.
166
- 5. Call \`actions.complete(actionId, 'Plan defined')\`.
167
- 6. Delegate to explorer, then builder, then reviewer — in that order.
168
-
169
- ## Rules
170
-
171
- - Do NOT write code yourself. Delegate to builder.
172
- - Do NOT read source files yourself. Delegate to explorer.
173
- - One task at a time. Check \`tasks.get('in_progress')\` before picking a new one.
174
- - If the reviewer blocks, coordinate a fix with builder and re-review.
175
- `;
176
- export const AGENT_EXPLORER = `---
177
- description: Explorer agent — reads and maps the codebase, never writes files
178
- ---
179
-
180
- # Explorer Agent
181
-
182
- You are the **explorer agent** in the agent-harness-kit harness. Your job is to read and understand the relevant parts of the codebase for the current task. You never write or modify files.
183
-
184
- ## Your workflow
185
-
186
- 1. Call \`actions.start(taskId, 'explorer')\` to register your action.
187
- 2. Read only the files relevant to the current task. Use \`docs.search(query)\` first.
188
- 3. Record what you find:
189
- - \`actions.write(actionId, 'tools_used', list_of_tools)\`
190
- - \`actions.write(actionId, 'result', analysis)\`
191
- 4. Call \`actions.complete(actionId, 'Analysis done')\`.
192
-
193
- ## Rules
194
-
195
- - Never modify files. You are read-only.
196
- - Use progressive disclosure — read AGENTS.md, then navigate to specific files.
197
- - Record every file you read via \`actions.write(actionId, 'tools_used', ...)\`.
198
- `;
199
- export const AGENT_BUILDER = `---
200
- description: Builder agent — implements the plan produced by explorer and lead
201
- ---
202
-
203
- # Builder Agent
204
-
205
- You are the **builder agent** in the agent-harness-kit harness. Your job is to implement the plan from lead, using the analysis from explorer.
206
-
207
- ## Your workflow
208
-
209
- 1. Read the lead's plan from \`actions.get(taskId)\`.
210
- 2. Call \`actions.start(taskId, 'builder')\` to register your action.
211
- 3. Implement the task. Record every file you touch:
212
- - \`actions.write(actionId, 'files_modified', list)\`
213
- 4. Record the result:
214
- - \`actions.write(actionId, 'result', summary_of_changes)\`
215
- 5. If you hit a blocker: \`actions.write(actionId, 'blockers', description)\`
216
- 6. Call \`actions.complete(actionId, 'Implementation done')\`.
217
-
218
- ## Rules
219
-
220
- - Only write to the paths allowed by your config (writablePaths).
221
- - If something is unclear, record a blocker and surface it to lead — don't guess.
222
- - Run tests after implementing if the project has a test suite.
223
- `;
224
- export const AGENT_REVIEWER = `---
225
- description: Reviewer agent — verifies acceptance criteria before marking a task done
226
- ---
227
-
228
- # Reviewer Agent
229
-
230
- You are the **reviewer agent** in the agent-harness-kit harness. Your job is to verify that the builder's work meets all acceptance criteria before the task is marked done.
231
-
232
- ## Your workflow
233
-
234
- 1. Call \`actions.get(taskId)\` to read the full history (lead plan + explorer analysis + builder changes).
235
- 2. Call \`actions.start(taskId, 'reviewer')\` to register your action.
236
- 3. Verify each acceptance criterion:
237
- - \`actions.write(actionId, 'result', 'APPROVED' or 'BLOCKED: reason')\`
238
- 4. If approved:
239
- - \`actions.complete(actionId, 'Task approved')\`
240
- - \`tasks.update(taskId, 'done')\`
241
- 5. If blocked:
242
- - \`actions.write(actionId, 'blockers', what_is_missing)\`
243
- - \`actions.complete(actionId, 'Task blocked: reason')\`
244
- - Notify lead to re-assign to builder.
245
-
246
- ## Rules
247
-
248
- - Never approve unless ALL acceptance criteria are met.
249
- - Check that health.sh is green before approving.
250
- - Be specific about what is missing when blocking.
251
- `;
162
+ // ─── Agent definition templates (loaded from agent-templates/*.md) ─────────────
163
+ export function agentLead(vars) {
164
+ return loadAgentTemplate('lead', vars);
165
+ }
166
+ export function agentExplorer(vars) {
167
+ return loadAgentTemplate('explorer', vars);
168
+ }
169
+ export function agentBuilder(vars) {
170
+ return loadAgentTemplate('builder', vars);
171
+ }
172
+ export function agentReviewer(vars) {
173
+ return loadAgentTemplate('reviewer', vars);
174
+ }
252
175
  // ─── feature_list.json initial seed ──────────────────────────────────────────
253
176
  export function featureListJson(tasks) {
254
177
  return JSON.stringify(tasks, null, 2) + '\n';
255
178
  }
256
- // ─── MCP JSON merge helpers ───────────────────────────────────────────────────
257
- // These do a deep merge so existing provider config is preserved.
258
- import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'node:fs';
259
- import { dirname } from 'node:path';
260
- export function mergeClaudeMcpJson(filePath, port) {
261
- let existing = {};
262
- if (existsSync(filePath)) {
263
- try {
264
- existing = JSON.parse(readFileSync(filePath, 'utf8'));
265
- }
266
- catch {
267
- // Unreadable JSON — start fresh to avoid corrupt state
268
- }
269
- }
270
- const merged = {
271
- ...existing,
272
- mcpServers: {
273
- ...(existing.mcpServers ?? {}),
274
- 'agent-harness-kit': {
275
- command: 'npx',
276
- args: ['ahk', 'serve', '--port', String(port)],
277
- type: 'stdio',
278
- },
279
- },
280
- };
281
- mkdirSync(dirname(filePath), { recursive: true });
282
- writeFileSync(filePath, JSON.stringify(merged, null, 2) + '\n', 'utf8');
283
- }
284
- export function mergeOpencodeJson(filePath, port) {
285
- let existing = {};
286
- if (existsSync(filePath)) {
287
- try {
288
- existing = JSON.parse(readFileSync(filePath, 'utf8'));
289
- }
290
- catch {
291
- // start fresh
292
- }
293
- }
294
- const existingMcp = existing.mcp ?? {};
295
- const existingServers = existingMcp.servers ?? {};
296
- const merged = {
297
- ...existing,
298
- mcp: {
299
- ...existingMcp,
300
- servers: {
301
- ...existingServers,
302
- 'agent-harness-kit': {
303
- command: 'npx',
304
- args: ['ahk', 'serve', '--port', String(port)],
305
- type: 'stdio',
306
- },
307
- },
308
- },
309
- };
310
- writeFileSync(filePath, JSON.stringify(merged, null, 2) + '\n', 'utf8');
311
- }
312
179
  // ─── .gitignore additions ─────────────────────────────────────────────────────
313
180
  export const GITIGNORE_ENTRIES = `
314
181
  # agent-harness-kit
@@ -1 +1 @@
1
- {"version":3,"file":"templates.js","sourceRoot":"","sources":["../../../src/core/materializer/templates.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"templates.js","sourceRoot":"","sources":["../../../src/core/materializer/templates.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AACtC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAGxC,iFAAiF;AAEjF,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAA;AACzD,MAAM,aAAa,GAAG,IAAI,CAAC,SAAS,EAAE,iBAAiB,CAAC,CAAA;AAExD;;;GAGG;AACH,SAAS,iBAAiB,CACxB,IAAkD,EAClD,OAA+B,EAAE;IAEjC,MAAM,GAAG,GAAG,YAAY,CAAC,IAAI,CAAC,aAAa,EAAE,GAAG,IAAI,KAAK,CAAC,EAAE,MAAM,CAAC,CAAA;IACnE,OAAO,GAAG,CAAC,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAAC,EAAE,GAAW,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,KAAK,GAAG,IAAI,CAAC,CAAA;AACrF,CAAC;AAED,gFAAgF;AAEhF,MAAM,CAAC,MAAM,SAAS,GAAG;;;;;;;;;;;;;;;;;;;CAmBxB,CAAA;AAED,iFAAiF;AAEjF,MAAM,UAAU,QAAQ,CAAC,MAAqB;IAC5C,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,GAAG,MAAM,CAAC,OAAO,CAAA;IACtD,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAA;IAElC,OAAO,iBAAiB,IAAI;;;;;;IAM1B,IAAI,QAAQ,WAAW;;;;;;;;;;;;;;;;;;;;mDAoBwB,IAAI;;;;;;;;;;mDAUJ,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;mBAkCxC,QAAQ;;;CAG1B,CAAA;AACD,CAAC;AAED,uFAAuF;AAEvF,MAAM,UAAU,QAAQ,CAAC,MAOxB;IACC,OAAO;;;;aAII,MAAM,CAAC,IAAI;oBACJ,MAAM,CAAC,WAAW;iBACrB,MAAM,CAAC,QAAQ;;;eAGjB,MAAM,CAAC,QAAQ;;;;0DAI4B,MAAM,CAAC,QAAQ;;;;;;;;;0BAS/C,MAAM,CAAC,YAAY;;;;;;;;;;;;;;;;;sCAiBP,MAAM,CAAC,IAAI;;;;CAIhD,CAAA;AACD,CAAC;AAED,kFAAkF;AAElF,MAAM,UAAU,SAAS,CAAC,IAA6B;IACrD,OAAO,iBAAiB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;AACxC,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,IAAmD;IAC/E,OAAO,iBAAiB,CAAC,UAAU,EAAE,IAAI,CAAC,CAAA;AAC5C,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,IAAoD;IAC/E,OAAO,iBAAiB,CAAC,SAAS,EAAE,IAAI,CAAC,CAAA;AAC3C,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,IAA6B;IACzD,OAAO,iBAAiB,CAAC,UAAU,EAAE,IAAI,CAAC,CAAA;AAC5C,CAAC;AAED,gFAAgF;AAEhF,MAAM,UAAU,eAAe,CAC7B,KAAqF;IAErF,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAA;AAC9C,CAAC;AAED,iFAAiF;AAEjF,MAAM,CAAC,MAAM,iBAAiB,GAAG;;;;;;CAMhC,CAAA"}
@@ -1,13 +1,6 @@
1
1
  import { test, describe } from 'node:test';
2
2
  import assert from 'node:assert/strict';
3
- // Inline slugify mirrors the logic in both materializers
4
- function slugify(title) {
5
- return title
6
- .toLowerCase()
7
- .replace(/[^a-z0-9]+/g, '-')
8
- .replace(/^-+|-+$/g, '')
9
- .slice(0, 64);
10
- }
3
+ import { slugify } from '../core/materializer/scaffold-utils.js';
11
4
  describe('slugify', () => {
12
5
  test('lowercases and replaces spaces', () => {
13
6
  assert.equal(slugify('My Feature'), 'my-feature');