@cardor/agent-harness-kit 2.4.0 → 2.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.
- package/README.md +22 -2
- package/dist/agent-templates/builder.md +10 -0
- package/dist/agent-templates/consultant.md +53 -0
- package/dist/agent-templates/explorer.md +16 -1
- package/dist/agent-templates/lead.md +28 -1
- package/dist/agent-templates/reviewer.md +6 -1
- package/dist/cli.js +252 -152
- package/dist/cli.js.map +1 -1
- package/dist/skills/ahk-test/SKILL.md +61 -0
- package/package.json +1 -2
package/dist/cli.js
CHANGED
|
@@ -36,6 +36,51 @@ var write = (cwd2, relPath, content, mode) => {
|
|
|
36
36
|
writeFileSync(abs, content, { encoding: "utf8", mode });
|
|
37
37
|
};
|
|
38
38
|
|
|
39
|
+
// src/core/materializer/delegation-guidance.ts
|
|
40
|
+
var PROVIDER_DELEGATION_GUIDANCE = {
|
|
41
|
+
"claude-code": {
|
|
42
|
+
invoke: ["@mention"],
|
|
43
|
+
sequential: "Use @<role-name> to delegate to a specific agent. Claude selects the subagent by role name.",
|
|
44
|
+
parallel: "Launch multiple @mentions in a single message for parallel work.",
|
|
45
|
+
contextTransfer: "Pass a self-contained objective, scope, known context, restrictions, and output contract with each @mention.",
|
|
46
|
+
waitForCompletion: "Wait for each @mention to complete before proceeding to the next step."
|
|
47
|
+
},
|
|
48
|
+
opencode: {
|
|
49
|
+
invoke: ["@mention"],
|
|
50
|
+
sequential: "Use @<role-name> to delegate to a specific agent. Child sessions need a self-contained objective.",
|
|
51
|
+
parallel: "Launch multiple @mentions in a single message for parallel work.",
|
|
52
|
+
contextTransfer: "Each child session needs: objective, scope, known context, restrictions, output contract.",
|
|
53
|
+
waitForCompletion: "Wait for each @mention to complete before proceeding."
|
|
54
|
+
},
|
|
55
|
+
"codex-cli": {
|
|
56
|
+
invoke: ["spawn", "delegate", "parallel", "wait", "summarize"],
|
|
57
|
+
sequential: "Use spawn \u2192 delegate \u2192 wait \u2192 summarize pattern. Explicit commands for each step.",
|
|
58
|
+
parallel: "Use parallel spawns for independent agents. Wait for all to complete.",
|
|
59
|
+
contextTransfer: "Provide full context in the spawn command \u2014 no shared state between children.",
|
|
60
|
+
waitForCompletion: "Use explicit wait after spawning parallel tasks.",
|
|
61
|
+
inspectProgress: "Check progress via status commands between waits."
|
|
62
|
+
},
|
|
63
|
+
"grok-cli": {
|
|
64
|
+
invoke: ["project subagent", "/tasks"],
|
|
65
|
+
sequential: "Refer to project-defined subagents by role name.",
|
|
66
|
+
parallel: "Launch multiple project subagents by role for parallel work.",
|
|
67
|
+
contextTransfer: "Provide bounded context when delegating to subagents.",
|
|
68
|
+
waitForCompletion: "Wait for subagent completion before proceeding.",
|
|
69
|
+
inspectProgress: "Use /tasks to check progress of running subagents."
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
function renderDelegationGuidance(provider, _audience = "lead") {
|
|
73
|
+
const guidance = PROVIDER_DELEGATION_GUIDANCE[provider];
|
|
74
|
+
if (!guidance) return "";
|
|
75
|
+
const lines = [];
|
|
76
|
+
for (const [key, value] of Object.entries(guidance)) {
|
|
77
|
+
if (key === "invoke") continue;
|
|
78
|
+
const label = key.replace(/([A-Z])/g, " $1").replace(/^./, (s) => s.toUpperCase());
|
|
79
|
+
lines.push(`- ${label}: ${value}`);
|
|
80
|
+
}
|
|
81
|
+
return lines.join("\n");
|
|
82
|
+
}
|
|
83
|
+
|
|
39
84
|
// src/core/materializer/detect-package-manager.ts
|
|
40
85
|
import { existsSync as existsSync3, readFileSync as readFileSync2 } from "fs";
|
|
41
86
|
import { join as join4 } from "path";
|
|
@@ -207,15 +252,12 @@ var MCP_CLAUDE_PERMISSIONS_LEAD = [
|
|
|
207
252
|
"mcp__agent-harness-kit__actions_write",
|
|
208
253
|
"mcp__agent-harness-kit__actions_complete",
|
|
209
254
|
"mcp__agent-harness-kit__actions_get",
|
|
210
|
-
"mcp__agent-harness-
|
|
211
|
-
"mcp__agent-harness-
|
|
212
|
-
"mcp__agent-harness-
|
|
213
|
-
"mcp__agent-harness-
|
|
214
|
-
"mcp__agent-harness-
|
|
215
|
-
"mcp__agent-harness-
|
|
216
|
-
"mcp__agent-harness-kit__tasks_edit",
|
|
217
|
-
"mcp__agent-harness-kit__tasks_archive",
|
|
218
|
-
"mcp__agent-harness-kit__tasks_unarchive",
|
|
255
|
+
"mcp__agent-harness-kit__actions_get_by_id",
|
|
256
|
+
"mcp__agent-harness-kit__actions_handoff_get",
|
|
257
|
+
"mcp__agent-harness-kit__actions_handoff_write",
|
|
258
|
+
"mcp__agent-harness-kit__actions_list",
|
|
259
|
+
"mcp__agent-harness-kit__actions_sections_get",
|
|
260
|
+
"mcp__agent-harness-kit__actions_sections_list",
|
|
219
261
|
"mcp__agent-harness-kit__tasks_acceptance_get",
|
|
220
262
|
"mcp__agent-harness-kit__docs_search",
|
|
221
263
|
"mcp__agent-harness-kit__ahk_doctor"
|
|
@@ -225,6 +267,12 @@ var MCP_CLAUDE_PERMISSIONS_EXPLORER = [
|
|
|
225
267
|
"mcp__agent-harness-kit__actions_write",
|
|
226
268
|
"mcp__agent-harness-kit__actions_complete",
|
|
227
269
|
"mcp__agent-harness-kit__actions_get",
|
|
270
|
+
"mcp__agent-harness-kit__actions_get_by_id",
|
|
271
|
+
"mcp__agent-harness-kit__actions_handoff_get",
|
|
272
|
+
"mcp__agent-harness-kit__actions_handoff_write",
|
|
273
|
+
"mcp__agent-harness-kit__actions_list",
|
|
274
|
+
"mcp__agent-harness-kit__actions_sections_get",
|
|
275
|
+
"mcp__agent-harness-kit__actions_sections_list",
|
|
228
276
|
"mcp__agent-harness-kit__actions_record_file",
|
|
229
277
|
"mcp__agent-harness-kit__actions_record_tool",
|
|
230
278
|
"mcp__agent-harness-kit__tasks_get",
|
|
@@ -238,6 +286,12 @@ var MCP_CLAUDE_PERMISSIONS_BUILDER = [
|
|
|
238
286
|
"mcp__agent-harness-kit__actions_write",
|
|
239
287
|
"mcp__agent-harness-kit__actions_complete",
|
|
240
288
|
"mcp__agent-harness-kit__actions_get",
|
|
289
|
+
"mcp__agent-harness-kit__actions_get_by_id",
|
|
290
|
+
"mcp__agent-harness-kit__actions_handoff_get",
|
|
291
|
+
"mcp__agent-harness-kit__actions_handoff_write",
|
|
292
|
+
"mcp__agent-harness-kit__actions_list",
|
|
293
|
+
"mcp__agent-harness-kit__actions_sections_get",
|
|
294
|
+
"mcp__agent-harness-kit__actions_sections_list",
|
|
241
295
|
"mcp__agent-harness-kit__actions_record_file",
|
|
242
296
|
"mcp__agent-harness-kit__actions_record_tool",
|
|
243
297
|
"mcp__agent-harness-kit__tasks_get",
|
|
@@ -256,6 +310,12 @@ var MCP_CLAUDE_PERMISSIONS_REVIEWER = [
|
|
|
256
310
|
"mcp__agent-harness-kit__actions_write",
|
|
257
311
|
"mcp__agent-harness-kit__actions_complete",
|
|
258
312
|
"mcp__agent-harness-kit__actions_get",
|
|
313
|
+
"mcp__agent-harness-kit__actions_get_by_id",
|
|
314
|
+
"mcp__agent-harness-kit__actions_handoff_get",
|
|
315
|
+
"mcp__agent-harness-kit__actions_handoff_write",
|
|
316
|
+
"mcp__agent-harness-kit__actions_list",
|
|
317
|
+
"mcp__agent-harness-kit__actions_sections_get",
|
|
318
|
+
"mcp__agent-harness-kit__actions_sections_list",
|
|
259
319
|
"mcp__agent-harness-kit__actions_record_file",
|
|
260
320
|
"mcp__agent-harness-kit__actions_record_tool",
|
|
261
321
|
"mcp__agent-harness-kit__tasks_get",
|
|
@@ -275,6 +335,12 @@ var MCP_CLAUDE_PERMISSIONS_CONSULTANT = [
|
|
|
275
335
|
"mcp__agent-harness-kit__actions_write",
|
|
276
336
|
"mcp__agent-harness-kit__actions_complete",
|
|
277
337
|
"mcp__agent-harness-kit__actions_get",
|
|
338
|
+
"mcp__agent-harness-kit__actions_get_by_id",
|
|
339
|
+
"mcp__agent-harness-kit__actions_handoff_get",
|
|
340
|
+
"mcp__agent-harness-kit__actions_handoff_write",
|
|
341
|
+
"mcp__agent-harness-kit__actions_list",
|
|
342
|
+
"mcp__agent-harness-kit__actions_sections_get",
|
|
343
|
+
"mcp__agent-harness-kit__actions_sections_list",
|
|
278
344
|
"mcp__agent-harness-kit__actions_record_file",
|
|
279
345
|
"mcp__agent-harness-kit__actions_record_tool",
|
|
280
346
|
"mcp__agent-harness-kit__tasks_get",
|
|
@@ -417,6 +483,37 @@ function mergeGrokConfigToml(filePath, port, cwd2, pm = "npm") {
|
|
|
417
483
|
writeFileSync2(filePath, content, "utf8");
|
|
418
484
|
}
|
|
419
485
|
|
|
486
|
+
// src/core/materializer/provider-research-capabilities.ts
|
|
487
|
+
var capabilities = {
|
|
488
|
+
"claude-code": { context7: true, mintlifyIndex: false, webSearch: true },
|
|
489
|
+
opencode: { context7: true, mintlifyIndex: true, webSearch: true },
|
|
490
|
+
"codex-cli": { context7: true, mintlifyIndex: false, webSearch: true },
|
|
491
|
+
"grok-cli": { context7: true, mintlifyIndex: false, webSearch: true }
|
|
492
|
+
};
|
|
493
|
+
function getResearchCapabilities(provider) {
|
|
494
|
+
return capabilities[provider];
|
|
495
|
+
}
|
|
496
|
+
function buildCapabilityHints(provider) {
|
|
497
|
+
const caps = getResearchCapabilities(provider);
|
|
498
|
+
const hints = [];
|
|
499
|
+
if (caps.context7) {
|
|
500
|
+
hints.push("- Context7 MCP tools available: resolve library ID before querying docs");
|
|
501
|
+
} else {
|
|
502
|
+
hints.push("- Context7 MCP tools NOT available \u2014 use official web documentation");
|
|
503
|
+
}
|
|
504
|
+
if (caps.mintlifyIndex) {
|
|
505
|
+
hints.push("- Mintlify Index available for publisher-maintained technical documentation");
|
|
506
|
+
} else {
|
|
507
|
+
hints.push("- Mintlify Index NOT available \u2014 fall back to official web documentation");
|
|
508
|
+
}
|
|
509
|
+
if (caps.webSearch) {
|
|
510
|
+
hints.push("- Web search available for current information outside documentation indexes");
|
|
511
|
+
} else {
|
|
512
|
+
hints.push("- Web search NOT available \u2014 report proof boundary, do not describe remembered behavior as current");
|
|
513
|
+
}
|
|
514
|
+
return hints.join("\n");
|
|
515
|
+
}
|
|
516
|
+
|
|
420
517
|
// src/core/materializer/scaffold-utils.ts
|
|
421
518
|
import { createHash } from "crypto";
|
|
422
519
|
import { existsSync as existsSync5, mkdirSync as mkdirSync3, readFileSync as readFileSync5, writeFileSync as writeFileSync3 } from "fs";
|
|
@@ -489,12 +586,12 @@ echo "Edit this file with your project's health checks."
|
|
|
489
586
|
echo "It must exit 0 for agents to start working."
|
|
490
587
|
exit 1
|
|
491
588
|
`;
|
|
492
|
-
function
|
|
589
|
+
function agentsMdBody(config, fileName, extraInitLines = "", orchestratingOverride) {
|
|
493
590
|
const { name, description, docsPath } = config.project;
|
|
494
591
|
const port = config.tools.mcp.port;
|
|
495
|
-
|
|
592
|
+
let body = `# ${fileName} \u2014 ${name}
|
|
496
593
|
|
|
497
|
-
|
|
594
|
+
**Read this file first.** It is the navigation map for every AI agent working in this repository.
|
|
498
595
|
|
|
499
596
|
## Project
|
|
500
597
|
|
|
@@ -526,7 +623,12 @@ actions.write actionId section text \u2192 record a sect
|
|
|
526
623
|
actions.record_tool actionId calls[] \u2192 batch-log tool calls to the Tools dashboard (array, min 1)
|
|
527
624
|
actions.record_file actionId files[] \u2192 batch-log file touches to the Files dashboard (array, min 1)
|
|
528
625
|
actions.complete actionId summary \u2192 close the action
|
|
529
|
-
actions.
|
|
626
|
+
actions.list taskId [agent] [status] [limit] [cursor] \u2192 compact newest-first action index with pagination
|
|
627
|
+
actions.get_by_id actionId \u2192 single action with section index (no content)
|
|
628
|
+
actions.sections_list actionId [types] [limit] [cursor] \u2192 compact section index with type filtering
|
|
629
|
+
actions.sections_get sectionId [length] [offset] \u2192 ranged section content reader
|
|
630
|
+
actions.handoff.get taskId [recipient] \u2192 newest completed canonical handoff
|
|
631
|
+
actions.handoff.write actionId recipient ... \u2192 recipient-directed bounded handoff
|
|
530
632
|
tasks.add title [slug] [description] [acceptance] \u2192 create a new task from natural language
|
|
531
633
|
tasks.get [status] \u2192 list tasks (pending | in_progress | done | blocked)
|
|
532
634
|
tasks.claim id \u2192 atomically claim a pending task
|
|
@@ -542,15 +644,15 @@ docs.search query \u2192 search ${docs
|
|
|
542
644
|
- Assess user intent: only run health.sh if changes are needed
|
|
543
645
|
- tasks.get('in_progress') \u2192 resume if something is in progress
|
|
544
646
|
- tasks.get('pending') \u2192 pick lowest id
|
|
545
|
-
|
|
647
|
+
${extraInitLines ? "\n" : ""}${extraInitLines}
|
|
546
648
|
2. WORK (lead \u2192 explorer \u2192 consultant \u2192 builder \u2192 reviewer)
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
649
|
+
- Each agent calls actions.start(taskId, agentName) \u2192 numeric actionId
|
|
650
|
+
- Accumulate tool calls / file touches as you work; flush periodically (every few calls or at a phase boundary) via actions.record_tool(actionId, calls: [...]) and actions.record_file(actionId, files: [...]) \u2014 both are batch-only, even a single entry goes through as a one-element array
|
|
651
|
+
- Closes with actions.complete(actionId, summary)
|
|
550
652
|
|
|
551
653
|
3. CLOSE
|
|
552
|
-
|
|
553
|
-
|
|
654
|
+
- tasks.update(taskId, 'done')
|
|
655
|
+
- Run health.sh (if changes were made) \u2192 must be green before closing
|
|
554
656
|
\`\`\`
|
|
555
657
|
|
|
556
658
|
## Agent roles
|
|
@@ -568,93 +670,39 @@ docs.search query \u2192 search ${docs
|
|
|
568
670
|
\`\`\`
|
|
569
671
|
Always: .harness/current.md (or MCP tasks.get)
|
|
570
672
|
If implementing: ${docsPath}/
|
|
571
|
-
If orchestrating: Agent definition files in your provider's agents directory
|
|
673
|
+
If orchestrating: ${orchestratingOverride ?? "Agent definition files in your provider's agents directory"}
|
|
572
674
|
\`\`\`
|
|
573
675
|
`;
|
|
676
|
+
if (extraInitLines) {
|
|
677
|
+
body = body.replace(
|
|
678
|
+
" - tasks.get('pending') \u2192 pick lowest id\n",
|
|
679
|
+
` - tasks.get('pending') \u2192 pick lowest id
|
|
680
|
+
${extraInitLines}
|
|
681
|
+
`
|
|
682
|
+
);
|
|
683
|
+
}
|
|
684
|
+
return body;
|
|
574
685
|
}
|
|
575
|
-
function
|
|
576
|
-
const
|
|
577
|
-
const port = config.tools.mcp.port;
|
|
578
|
-
return `# CLAUDE.md \u2014 ${name}
|
|
579
|
-
|
|
580
|
-
> **Read this file first.** It is the navigation map for every AI agent working in this repository.
|
|
581
|
-
|
|
582
|
-
## Project
|
|
583
|
-
|
|
584
|
-
**${name}** \u2014 ${description}
|
|
686
|
+
function agentsMd(config, capabilityHints = "") {
|
|
687
|
+
const capabilityBlock = capabilityHints ? `## Available Research Tools
|
|
585
688
|
|
|
586
|
-
|
|
689
|
+
${capabilityHints}
|
|
587
690
|
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
## Harness data (source of truth)
|
|
595
|
-
|
|
596
|
-
| File | Purpose |
|
|
597
|
-
|------|---------|
|
|
598
|
-
| \`.harness/harness.db\` | SQLite: all tasks, actions, file changes, tool calls |
|
|
599
|
-
| \`.harness/current.md\` | Markdown fallback \u2014 read this if MCP server is unavailable |
|
|
600
|
-
| \`.harness/feature_list.json\` | Human-editable task seed list |
|
|
601
|
-
|
|
602
|
-
## MCP tools (preferred)
|
|
603
|
-
|
|
604
|
-
The harness exposes tools via MCP server on port ${port}. Use these instead of reading files directly.
|
|
605
|
-
|
|
606
|
-
\`\`\`
|
|
607
|
-
actions.start taskId agent \u2192 start an action, returns a numeric actionId
|
|
608
|
-
actions.write actionId section text \u2192 record a section (result, blockers, ...)
|
|
609
|
-
actions.record_tool actionId calls[] \u2192 batch-log tool calls to the Tools dashboard (array, min 1)
|
|
610
|
-
actions.record_file actionId files[] \u2192 batch-log file touches to the Files dashboard (array, min 1)
|
|
611
|
-
actions.complete actionId summary \u2192 close the action
|
|
612
|
-
actions.get taskId \u2192 full action history for a task
|
|
613
|
-
tasks.add title [slug] [description] [acceptance] \u2192 create a new task from natural language
|
|
614
|
-
tasks.get [status] \u2192 list tasks (pending | in_progress | done | blocked)
|
|
615
|
-
tasks.claim id \u2192 atomically claim a pending task
|
|
616
|
-
tasks.update id status \u2192 change task status
|
|
617
|
-
tasks.acceptance.update criterionId \u2192 mark an acceptance criterion as met
|
|
618
|
-
docs.search query \u2192 search ${docsPath} for relevant content
|
|
619
|
-
\`\`\`
|
|
620
|
-
|
|
621
|
-
## Workflow
|
|
622
|
-
|
|
623
|
-
\`\`\`
|
|
624
|
-
1. INIT
|
|
625
|
-
- Assess user intent: only run health.sh if changes are needed
|
|
626
|
-
- tasks.get('in_progress') \u2192 resume if something is in progress
|
|
627
|
-
- tasks.get('pending') \u2192 pick lowest id
|
|
628
|
-
- No pending tasks? \u2192 ask user, infer fields, call tasks.add, then tasks.claim
|
|
629
|
-
|
|
630
|
-
2. WORK (lead \u2192 explorer \u2192 consultant \u2192 builder \u2192 reviewer)
|
|
631
|
-
- Each agent calls actions.start(taskId, agentName) \u2192 numeric actionId
|
|
632
|
-
- Accumulate tool calls / file touches as you work; flush periodically (every few calls or at a phase boundary) via actions.record_tool(actionId, calls: [...]) and actions.record_file(actionId, files: [...]) \u2014 both are batch-only, even a single entry goes through as a one-element array
|
|
633
|
-
- Closes with actions.complete(actionId, summary)
|
|
634
|
-
|
|
635
|
-
3. CLOSE
|
|
636
|
-
- tasks.update(taskId, 'done')
|
|
637
|
-
- Run health.sh (if changes were made) \u2192 must be green before closing
|
|
638
|
-
\`\`\`
|
|
639
|
-
|
|
640
|
-
## Agent roles
|
|
641
|
-
|
|
642
|
-
| Agent | Responsibility |
|
|
643
|
-
|-------|---------------|
|
|
644
|
-
| lead | Decomposes the task into a plan, assigns sub-agents |
|
|
645
|
-
| explorer | Reads and maps relevant code, never writes |
|
|
646
|
-
| consultant | Technical advisor, runs after explorer, before builder. Never writes code. |
|
|
647
|
-
| builder | Implements the plan, writes files |
|
|
648
|
-
| reviewer | Verifies acceptance criteria, approves or blocks |
|
|
691
|
+
` : "";
|
|
692
|
+
return `${capabilityBlock}${agentsMdBody(config, "AGENTS.md")}`;
|
|
693
|
+
}
|
|
694
|
+
function claudeMd(config, capabilityHints = "") {
|
|
695
|
+
const capabilityBlock = capabilityHints ? `## Available Research Tools
|
|
649
696
|
|
|
650
|
-
|
|
697
|
+
${capabilityHints}
|
|
651
698
|
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
699
|
+
` : "";
|
|
700
|
+
return `${capabilityBlock}${agentsMdBody(
|
|
701
|
+
config,
|
|
702
|
+
"CLAUDE.md",
|
|
703
|
+
" - No pending tasks? \u2192 ask user, infer fields, call tasks.add, then tasks.claim",
|
|
704
|
+
"Agent definition files in .claude/agents/"
|
|
705
|
+
)}`;
|
|
658
706
|
}
|
|
659
707
|
function configObjectBody(params) {
|
|
660
708
|
const isGlobal = params.scope === "global";
|
|
@@ -772,20 +820,54 @@ ${configObjectBody(params)}}
|
|
|
772
820
|
module.exports = config
|
|
773
821
|
`;
|
|
774
822
|
}
|
|
775
|
-
function
|
|
776
|
-
|
|
823
|
+
function injectCapabilityHints(md, capabilityHints) {
|
|
824
|
+
if (!capabilityHints) return md;
|
|
825
|
+
const headingMatch = md.match(/^(#\s+.*?\n\n)/m);
|
|
826
|
+
if (!headingMatch) return md;
|
|
827
|
+
return `${headingMatch[1]}## Available Research Tools
|
|
828
|
+
|
|
829
|
+
${capabilityHints}
|
|
830
|
+
|
|
831
|
+
${md.slice(headingMatch[1].length)}`;
|
|
832
|
+
}
|
|
833
|
+
function injectDelegationGuidance(md, delegationGuidance) {
|
|
834
|
+
if (!delegationGuidance) return md;
|
|
835
|
+
const researchSection = md.match(/(## Available Research Tools\n\n[\s\S]*?)\n\n/m);
|
|
836
|
+
if (researchSection) {
|
|
837
|
+
const insertionPoint = researchSection[1].length + "## Available Research Tools\n\n".length;
|
|
838
|
+
const afterResearch = md.slice(insertionPoint);
|
|
839
|
+
return md.slice(0, insertionPoint) + `
|
|
840
|
+
## Provider Delegation Guidance
|
|
841
|
+
|
|
842
|
+
${delegationGuidance}
|
|
843
|
+
|
|
844
|
+
${afterResearch}`;
|
|
845
|
+
}
|
|
846
|
+
const headingMatch = md.match(/^(#\s+.*?\n\n)/m);
|
|
847
|
+
if (!headingMatch) return md;
|
|
848
|
+
return `${headingMatch[1]}## Provider Delegation Guidance
|
|
849
|
+
|
|
850
|
+
${delegationGuidance}
|
|
851
|
+
|
|
852
|
+
${md.slice(headingMatch[1].length)}`;
|
|
853
|
+
}
|
|
854
|
+
function agentLead(opts, capabilityHints = "", delegationGuidance = "") {
|
|
855
|
+
let result = loadAgentTemplate("lead", opts);
|
|
856
|
+
result = injectCapabilityHints(result, capabilityHints);
|
|
857
|
+
result = injectDelegationGuidance(result, delegationGuidance);
|
|
858
|
+
return result;
|
|
777
859
|
}
|
|
778
|
-
function agentExplorer(
|
|
779
|
-
return loadAgentTemplate("explorer",
|
|
860
|
+
function agentExplorer(opts, capabilityHints = "") {
|
|
861
|
+
return injectCapabilityHints(loadAgentTemplate("explorer", opts), capabilityHints);
|
|
780
862
|
}
|
|
781
|
-
function agentBuilder(
|
|
782
|
-
return loadAgentTemplate("builder",
|
|
863
|
+
function agentBuilder(opts, capabilityHints = "") {
|
|
864
|
+
return injectCapabilityHints(loadAgentTemplate("builder", opts), capabilityHints);
|
|
783
865
|
}
|
|
784
|
-
function agentConsultant(
|
|
785
|
-
return loadAgentTemplate("consultant",
|
|
866
|
+
function agentConsultant(opts, capabilityHints = "") {
|
|
867
|
+
return injectCapabilityHints(loadAgentTemplate("consultant", opts), capabilityHints);
|
|
786
868
|
}
|
|
787
|
-
function agentReviewer(
|
|
788
|
-
return loadAgentTemplate("reviewer",
|
|
869
|
+
function agentReviewer(opts, capabilityHints = "") {
|
|
870
|
+
return injectCapabilityHints(loadAgentTemplate("reviewer", opts), capabilityHints);
|
|
789
871
|
}
|
|
790
872
|
function stripFrontmatter(md) {
|
|
791
873
|
const parts = md.split(/^---\s*$/m);
|
|
@@ -828,13 +910,23 @@ ${safe(instructions)}
|
|
|
828
910
|
"""
|
|
829
911
|
`;
|
|
830
912
|
}
|
|
831
|
-
function agentLeadToml(vars, opts) {
|
|
913
|
+
function agentLeadToml(vars, opts, delegationGuidance = "") {
|
|
832
914
|
const { description, body } = stripFrontmatter(loadAgentTemplate("lead", vars));
|
|
833
|
-
|
|
915
|
+
const bodyWithDelegation = delegationGuidance ? `${body}
|
|
916
|
+
|
|
917
|
+
## Provider Delegation Guidance
|
|
918
|
+
|
|
919
|
+
${delegationGuidance}` : body;
|
|
920
|
+
return toCodexToml("lead", "lead", description, bodyWithDelegation, opts);
|
|
834
921
|
}
|
|
835
|
-
function agentLeadAsDefaultToml(vars, opts) {
|
|
922
|
+
function agentLeadAsDefaultToml(vars, opts, delegationGuidance = "") {
|
|
836
923
|
const { description, body } = stripFrontmatter(loadAgentTemplate("lead", vars));
|
|
837
|
-
|
|
924
|
+
const bodyWithDelegation = delegationGuidance ? `${body}
|
|
925
|
+
|
|
926
|
+
## Provider Delegation Guidance
|
|
927
|
+
|
|
928
|
+
${delegationGuidance}` : body;
|
|
929
|
+
return toCodexToml("default", "lead", description, bodyWithDelegation, opts);
|
|
838
930
|
}
|
|
839
931
|
function agentExplorerToml(vars, opts) {
|
|
840
932
|
const { description, body } = stripFrontmatter(loadAgentTemplate("explorer", vars));
|
|
@@ -1056,33 +1148,38 @@ function appendGitignore(cwd2) {
|
|
|
1056
1148
|
function slugify(title) {
|
|
1057
1149
|
return title.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 64);
|
|
1058
1150
|
}
|
|
1059
|
-
function writeSkills(cwd2, skillsDir) {
|
|
1060
|
-
const skillNames = ["ahk-ask", "ahk-consultant", "ahk-triage", "ahk-review"];
|
|
1151
|
+
function writeSkills(cwd2, skillsDir, delegationGuidance) {
|
|
1152
|
+
const skillNames = ["ahk-ask", "ahk-consultant", "ahk-triage", "ahk-review", "ahk-test"];
|
|
1061
1153
|
for (const skillName of skillNames) {
|
|
1062
1154
|
const src = join6(__dirname2, "skills", skillName, "SKILL.md");
|
|
1063
1155
|
const destDir = join6(cwd2, skillsDir, skillName);
|
|
1064
1156
|
const dest = join6(destDir, "SKILL.md");
|
|
1065
1157
|
mkdirSync3(destDir, { recursive: true });
|
|
1066
|
-
|
|
1158
|
+
let content = readFileSync5(src, "utf8");
|
|
1159
|
+
if (delegationGuidance) {
|
|
1160
|
+
content = injectDelegationGuidance(content, delegationGuidance);
|
|
1161
|
+
}
|
|
1162
|
+
writeFileSync3(dest, content, "utf8");
|
|
1067
1163
|
}
|
|
1068
1164
|
}
|
|
1069
1165
|
|
|
1070
1166
|
// src/core/materializer/claude-code.ts
|
|
1071
|
-
function claudeAgentFiles(config, modelsByRole) {
|
|
1167
|
+
function claudeAgentFiles(config, modelsByRole, capabilityHints = "") {
|
|
1072
1168
|
const projectName = config.project.name;
|
|
1073
1169
|
return [
|
|
1074
|
-
{ relPath: ".claude/agents/lead.md", content: translateFrontmatterForClaudeCode(agentLead({ projectName }), "lead", { model: modelsByRole?.lead }) },
|
|
1075
|
-
{ relPath: ".claude/agents/explorer.md", content: translateFrontmatterForClaudeCode(agentExplorer({ projectName }), "explorer", { model: modelsByRole?.explorer }) },
|
|
1076
|
-
{ relPath: ".claude/agents/consultant.md", content: translateFrontmatterForClaudeCode(agentConsultant({ projectName }), "consultant", { model: modelsByRole?.consultant }) },
|
|
1077
|
-
{ relPath: ".claude/agents/builder.md", content: translateFrontmatterForClaudeCode(agentBuilder({ projectName }), "builder", { model: modelsByRole?.builder }) },
|
|
1078
|
-
{ relPath: ".claude/agents/reviewer.md", content: translateFrontmatterForClaudeCode(agentReviewer({ projectName }), "reviewer", { model: modelsByRole?.reviewer }) }
|
|
1170
|
+
{ relPath: ".claude/agents/lead.md", content: translateFrontmatterForClaudeCode(agentLead({ projectName }, capabilityHints, renderDelegationGuidance("claude-code", "lead")), "lead", { model: modelsByRole?.lead }) },
|
|
1171
|
+
{ relPath: ".claude/agents/explorer.md", content: translateFrontmatterForClaudeCode(agentExplorer({ projectName }, capabilityHints), "explorer", { model: modelsByRole?.explorer }) },
|
|
1172
|
+
{ relPath: ".claude/agents/consultant.md", content: translateFrontmatterForClaudeCode(agentConsultant({ projectName }, capabilityHints), "consultant", { model: modelsByRole?.consultant }) },
|
|
1173
|
+
{ relPath: ".claude/agents/builder.md", content: translateFrontmatterForClaudeCode(agentBuilder({ projectName }, capabilityHints), "builder", { model: modelsByRole?.builder }) },
|
|
1174
|
+
{ relPath: ".claude/agents/reviewer.md", content: translateFrontmatterForClaudeCode(agentReviewer({ projectName }, capabilityHints), "reviewer", { model: modelsByRole?.reviewer }) }
|
|
1079
1175
|
];
|
|
1080
1176
|
}
|
|
1081
1177
|
var ClaudeCodeMaterializer = class {
|
|
1082
1178
|
async scaffold(config, opts) {
|
|
1083
1179
|
const { cwd: cwd2, claudeAgentModels } = opts;
|
|
1084
|
-
|
|
1085
|
-
write(cwd2, "
|
|
1180
|
+
const capabilityHints = buildCapabilityHints("claude-code");
|
|
1181
|
+
write(cwd2, "AGENTS.md", stampGenerated(agentsMd(config, capabilityHints)));
|
|
1182
|
+
write(cwd2, "CLAUDE.md", stampGenerated(claudeMd(config, capabilityHints)));
|
|
1086
1183
|
if (!existsSync6(join7(cwd2, "health.sh"))) {
|
|
1087
1184
|
write(cwd2, "health.sh", HEALTH_SH, 493);
|
|
1088
1185
|
}
|
|
@@ -1099,30 +1196,31 @@ No tasks in progress.
|
|
|
1099
1196
|
`
|
|
1100
1197
|
);
|
|
1101
1198
|
}
|
|
1102
|
-
writeAgentFiles(cwd2, claudeAgentFiles(config, claudeAgentModels));
|
|
1199
|
+
writeAgentFiles(cwd2, claudeAgentFiles(config, claudeAgentModels, capabilityHints));
|
|
1103
1200
|
mergeClaudeMcpJson(join7(cwd2, ".mcp.json"), config.tools.mcp.port, cwd2, detectPackageManager(cwd2));
|
|
1104
1201
|
mergeClaudeSettingsJson(join7(cwd2, ".claude/settings.json"));
|
|
1105
1202
|
mergeClaudeSettingsLocalJson(join7(cwd2, ".claude/settings.local.json"));
|
|
1106
1203
|
appendGitignore(cwd2);
|
|
1107
|
-
writeSkills(cwd2, ".claude/skills");
|
|
1204
|
+
writeSkills(cwd2, ".claude/skills", renderDelegationGuidance("claude-code", "coordination-skill"));
|
|
1108
1205
|
}
|
|
1109
1206
|
async build(config, cwd2, opts = {}) {
|
|
1207
|
+
const capabilityHints = buildCapabilityHints("claude-code");
|
|
1110
1208
|
const derived = reconcileGeneratedFiles(
|
|
1111
1209
|
cwd2,
|
|
1112
1210
|
[
|
|
1113
|
-
{ relPath: "AGENTS.md", content: agentsMd(config) },
|
|
1114
|
-
{ relPath: "CLAUDE.md", content: claudeMd(config) }
|
|
1211
|
+
{ relPath: "AGENTS.md", content: agentsMd(config, capabilityHints) },
|
|
1212
|
+
{ relPath: "CLAUDE.md", content: claudeMd(config, capabilityHints) }
|
|
1115
1213
|
],
|
|
1116
1214
|
{ force: opts.force, backupRoot: join7(cwd2, config.storage.dir, "backups") }
|
|
1117
1215
|
);
|
|
1118
|
-
const agents = writeAgentFiles(cwd2, claudeAgentFiles(config, opts.claudeAgentModels), {
|
|
1216
|
+
const agents = writeAgentFiles(cwd2, claudeAgentFiles(config, opts.claudeAgentModels, capabilityHints), {
|
|
1119
1217
|
force: opts.force,
|
|
1120
1218
|
backupRoot: join7(cwd2, config.storage.dir, "backups")
|
|
1121
1219
|
});
|
|
1122
1220
|
mergeClaudeMcpJson(join7(cwd2, ".mcp.json"), config.tools.mcp.port, cwd2, detectPackageManager(cwd2));
|
|
1123
1221
|
mergeClaudeSettingsJson(join7(cwd2, ".claude/settings.json"));
|
|
1124
1222
|
mergeClaudeSettingsLocalJson(join7(cwd2, ".claude/settings.local.json"));
|
|
1125
|
-
writeSkills(cwd2, ".claude/skills");
|
|
1223
|
+
writeSkills(cwd2, ".claude/skills", renderDelegationGuidance("claude-code", "coordination-skill"));
|
|
1126
1224
|
return { agents, derived };
|
|
1127
1225
|
}
|
|
1128
1226
|
async migrate(config, _to, _cwd) {
|
|
@@ -1152,15 +1250,15 @@ No tasks in progress.
|
|
|
1152
1250
|
// src/core/materializer/codex-cli.ts
|
|
1153
1251
|
import { existsSync as existsSync7, mkdirSync as mkdirSync4, writeFileSync as writeFileSync4 } from "fs";
|
|
1154
1252
|
import { join as join8, resolve as resolve3 } from "path";
|
|
1155
|
-
function codexAgentFiles(config, modelsByRole) {
|
|
1253
|
+
function codexAgentFiles(config, modelsByRole, _capabilityHints = "") {
|
|
1156
1254
|
const projectName = config.project.name;
|
|
1157
1255
|
return [
|
|
1158
|
-
{ relPath: ".codex/agents/lead.toml", content: agentLeadToml({ projectName }, modelsByRole?.lead) },
|
|
1256
|
+
{ relPath: ".codex/agents/lead.toml", content: agentLeadToml({ projectName }, modelsByRole?.lead, renderDelegationGuidance("codex-cli", "lead")) },
|
|
1159
1257
|
{ relPath: ".codex/agents/explorer.toml", content: agentExplorerToml({ projectName }, modelsByRole?.explorer) },
|
|
1160
1258
|
{ relPath: ".codex/agents/consultant.toml", content: agentConsultantToml({ projectName }, modelsByRole?.consultant) },
|
|
1161
1259
|
{ relPath: ".codex/agents/builder.toml", content: agentBuilderToml({ projectName }, modelsByRole?.builder) },
|
|
1162
1260
|
{ relPath: ".codex/agents/reviewer.toml", content: agentReviewerToml({ projectName }, modelsByRole?.reviewer) },
|
|
1163
|
-
{ relPath: ".codex/agents/default.toml", content: agentLeadAsDefaultToml({ projectName }, modelsByRole?.lead) }
|
|
1261
|
+
{ relPath: ".codex/agents/default.toml", content: agentLeadAsDefaultToml({ projectName }, modelsByRole?.lead, renderDelegationGuidance("codex-cli", "lead")) }
|
|
1164
1262
|
];
|
|
1165
1263
|
}
|
|
1166
1264
|
var CodexCliMaterializer = class {
|
|
@@ -1190,7 +1288,7 @@ No tasks in progress.
|
|
|
1190
1288
|
writeAgentFiles(cwd2, codexAgentFiles(config, codexAgentModels));
|
|
1191
1289
|
mergeCodexConfigToml(join8(cwd2, ".codex/config.toml"), config.tools.mcp.port, cwd2, detectPackageManager(cwd2));
|
|
1192
1290
|
appendGitignore(cwd2);
|
|
1193
|
-
writeSkills(cwd2, ".agents/skills");
|
|
1291
|
+
writeSkills(cwd2, ".agents/skills", renderDelegationGuidance("codex-cli", "coordination-skill"));
|
|
1194
1292
|
}
|
|
1195
1293
|
async build(config, cwd2, opts = {}) {
|
|
1196
1294
|
const derived = reconcileGeneratedFiles(
|
|
@@ -1203,7 +1301,7 @@ No tasks in progress.
|
|
|
1203
1301
|
backupRoot: join8(cwd2, config.storage.dir, "backups")
|
|
1204
1302
|
});
|
|
1205
1303
|
mergeCodexConfigToml(join8(cwd2, ".codex/config.toml"), config.tools.mcp.port, cwd2, detectPackageManager(cwd2));
|
|
1206
|
-
writeSkills(cwd2, ".agents/skills");
|
|
1304
|
+
writeSkills(cwd2, ".agents/skills", renderDelegationGuidance("codex-cli", "coordination-skill"));
|
|
1207
1305
|
return { agents, derived };
|
|
1208
1306
|
}
|
|
1209
1307
|
async migrate(config, _to, _cwd) {
|
|
@@ -1220,7 +1318,7 @@ import { join as join9, resolve as resolve4 } from "path";
|
|
|
1220
1318
|
function grokAgentFiles(config) {
|
|
1221
1319
|
const projectName = config.project.name;
|
|
1222
1320
|
return [
|
|
1223
|
-
{ relPath: ".grok/agents/lead.md", content: translateFrontmatterForGrok(agentLead({ projectName }), "lead") },
|
|
1321
|
+
{ relPath: ".grok/agents/lead.md", content: translateFrontmatterForGrok(agentLead({ projectName }, "", renderDelegationGuidance("grok-cli", "lead")), "lead") },
|
|
1224
1322
|
{ relPath: ".grok/agents/explorer.md", content: translateFrontmatterForGrok(agentExplorer({ projectName }), "explorer") },
|
|
1225
1323
|
{ relPath: ".grok/agents/consultant.md", content: translateFrontmatterForGrok(agentConsultant({ projectName }), "consultant") },
|
|
1226
1324
|
{ relPath: ".grok/agents/builder.md", content: translateFrontmatterForGrok(agentBuilder({ projectName }), "builder") },
|
|
@@ -1254,7 +1352,7 @@ No tasks in progress.
|
|
|
1254
1352
|
writeAgentFiles(cwd2, grokAgentFiles(config));
|
|
1255
1353
|
mergeGrokConfigToml(join9(cwd2, ".grok/config.toml"), config.tools.mcp.port, cwd2, detectPackageManager(cwd2));
|
|
1256
1354
|
appendGitignore(cwd2);
|
|
1257
|
-
writeSkills(cwd2, ".grok/skills");
|
|
1355
|
+
writeSkills(cwd2, ".grok/skills", renderDelegationGuidance("grok-cli", "coordination-skill"));
|
|
1258
1356
|
}
|
|
1259
1357
|
async build(config, cwd2, opts = {}) {
|
|
1260
1358
|
const derived = reconcileGeneratedFiles(
|
|
@@ -1267,7 +1365,7 @@ No tasks in progress.
|
|
|
1267
1365
|
backupRoot: join9(cwd2, config.storage.dir, "backups")
|
|
1268
1366
|
});
|
|
1269
1367
|
mergeGrokConfigToml(join9(cwd2, ".grok/config.toml"), config.tools.mcp.port, cwd2, detectPackageManager(cwd2));
|
|
1270
|
-
writeSkills(cwd2, ".grok/skills");
|
|
1368
|
+
writeSkills(cwd2, ".grok/skills", renderDelegationGuidance("grok-cli", "coordination-skill"));
|
|
1271
1369
|
return { agents, derived };
|
|
1272
1370
|
}
|
|
1273
1371
|
async migrate(config, _to, _cwd) {
|
|
@@ -1281,25 +1379,26 @@ No tasks in progress.
|
|
|
1281
1379
|
// src/core/materializer/opencode.ts
|
|
1282
1380
|
import { existsSync as existsSync9, mkdirSync as mkdirSync6, writeFileSync as writeFileSync6 } from "fs";
|
|
1283
1381
|
import { join as join10, resolve as resolve5 } from "path";
|
|
1284
|
-
function opencodeAgentFiles(config) {
|
|
1382
|
+
function opencodeAgentFiles(config, capabilityHints = "") {
|
|
1285
1383
|
const projectName = config.project.name;
|
|
1286
1384
|
return [
|
|
1287
|
-
{ relPath: ".opencode/agents/lead.md", content: translateFrontmatterForOpenCode(agentLead({ projectName }), "lead") },
|
|
1288
|
-
{ relPath: ".opencode/agents/explorer.md", content: translateFrontmatterForOpenCode(agentExplorer({ projectName }), "explorer") },
|
|
1289
|
-
{ relPath: ".opencode/agents/consultant.md", content: translateFrontmatterForOpenCode(agentConsultant({ projectName }), "consultant") },
|
|
1290
|
-
{ relPath: ".opencode/agents/builder.md", content: translateFrontmatterForOpenCode(agentBuilder({ projectName }), "builder") },
|
|
1291
|
-
{ relPath: ".opencode/agents/reviewer.md", content: translateFrontmatterForOpenCode(agentReviewer({ projectName }), "reviewer") }
|
|
1385
|
+
{ relPath: ".opencode/agents/lead.md", content: translateFrontmatterForOpenCode(agentLead({ projectName }, capabilityHints, renderDelegationGuidance("opencode", "lead")), "lead") },
|
|
1386
|
+
{ relPath: ".opencode/agents/explorer.md", content: translateFrontmatterForOpenCode(agentExplorer({ projectName }, capabilityHints), "explorer") },
|
|
1387
|
+
{ relPath: ".opencode/agents/consultant.md", content: translateFrontmatterForOpenCode(agentConsultant({ projectName }, capabilityHints), "consultant") },
|
|
1388
|
+
{ relPath: ".opencode/agents/builder.md", content: translateFrontmatterForOpenCode(agentBuilder({ projectName }, capabilityHints), "builder") },
|
|
1389
|
+
{ relPath: ".opencode/agents/reviewer.md", content: translateFrontmatterForOpenCode(agentReviewer({ projectName }, capabilityHints), "reviewer") }
|
|
1292
1390
|
];
|
|
1293
1391
|
}
|
|
1294
1392
|
var OpenCodeMaterializer = class {
|
|
1295
1393
|
async scaffold(config, opts) {
|
|
1296
1394
|
const { cwd: cwd2 } = opts;
|
|
1395
|
+
const capabilityHints = buildCapabilityHints("opencode");
|
|
1297
1396
|
const write2 = (relPath, content, mode) => {
|
|
1298
1397
|
const abs = join10(cwd2, relPath);
|
|
1299
1398
|
mkdirSync6(resolve5(abs, ".."), { recursive: true });
|
|
1300
1399
|
writeFileSync6(abs, content, { encoding: "utf8", mode });
|
|
1301
1400
|
};
|
|
1302
|
-
write2("AGENTS.md", stampGenerated(agentsMd(config)));
|
|
1401
|
+
write2("AGENTS.md", stampGenerated(agentsMd(config, capabilityHints)));
|
|
1303
1402
|
if (!existsSync9(join10(cwd2, "health.sh"))) {
|
|
1304
1403
|
write2("health.sh", HEALTH_SH, 493);
|
|
1305
1404
|
}
|
|
@@ -1315,23 +1414,24 @@ No tasks in progress.
|
|
|
1315
1414
|
`
|
|
1316
1415
|
);
|
|
1317
1416
|
}
|
|
1318
|
-
writeAgentFiles(cwd2, opencodeAgentFiles(config));
|
|
1417
|
+
writeAgentFiles(cwd2, opencodeAgentFiles(config, capabilityHints));
|
|
1319
1418
|
mergeOpencodeJson(join10(cwd2, "opencode.json"), config.tools.mcp.port, cwd2, detectPackageManager(cwd2));
|
|
1320
1419
|
appendGitignore(cwd2);
|
|
1321
|
-
writeSkills(cwd2, ".opencode/skills");
|
|
1420
|
+
writeSkills(cwd2, ".opencode/skills", renderDelegationGuidance("opencode", "coordination-skill"));
|
|
1322
1421
|
}
|
|
1323
1422
|
async build(config, cwd2, opts = {}) {
|
|
1423
|
+
const capabilityHints = buildCapabilityHints("opencode");
|
|
1324
1424
|
const derived = reconcileGeneratedFiles(
|
|
1325
1425
|
cwd2,
|
|
1326
|
-
[{ relPath: "AGENTS.md", content: agentsMd(config) }],
|
|
1426
|
+
[{ relPath: "AGENTS.md", content: agentsMd(config, capabilityHints) }],
|
|
1327
1427
|
{ force: opts.force, backupRoot: join10(cwd2, config.storage.dir, "backups") }
|
|
1328
1428
|
);
|
|
1329
|
-
const agents = writeAgentFiles(cwd2, opencodeAgentFiles(config), {
|
|
1429
|
+
const agents = writeAgentFiles(cwd2, opencodeAgentFiles(config, capabilityHints), {
|
|
1330
1430
|
force: opts.force,
|
|
1331
1431
|
backupRoot: join10(cwd2, config.storage.dir, "backups")
|
|
1332
1432
|
});
|
|
1333
1433
|
mergeOpencodeJson(join10(cwd2, "opencode.json"), config.tools.mcp.port, cwd2, detectPackageManager(cwd2));
|
|
1334
|
-
writeSkills(cwd2, ".opencode/skills");
|
|
1434
|
+
writeSkills(cwd2, ".opencode/skills", renderDelegationGuidance("opencode", "coordination-skill"));
|
|
1335
1435
|
return { agents, derived };
|
|
1336
1436
|
}
|
|
1337
1437
|
async migrate(config, _to, _cwd) {
|
|
@@ -1833,7 +1933,7 @@ var REGISTRY_URL = `https://registry.npmjs.org/${pkg.name}/latest`;
|
|
|
1833
1933
|
var TIMEOUT_MS = 2e3;
|
|
1834
1934
|
var LIB_VERSION_CACHE_TTL_MS = 5 * 60 * 1e3;
|
|
1835
1935
|
var AGENT_NAMES = ["lead", "explorer", "consultant", "builder", "reviewer"];
|
|
1836
|
-
var SKILL_NAMES = ["ahk-ask", "ahk-consultant", "ahk-triage", "ahk-review"];
|
|
1936
|
+
var SKILL_NAMES = ["ahk-ask", "ahk-consultant", "ahk-triage", "ahk-review", "ahk-test"];
|
|
1837
1937
|
var __dirname4 = dirname6(fileURLToPath5(import.meta.url));
|
|
1838
1938
|
var libVersionCache = null;
|
|
1839
1939
|
async function checkLibVersion() {
|
|
@@ -1907,7 +2007,7 @@ function getProviderSkillsDir(provider) {
|
|
|
1907
2007
|
}
|
|
1908
2008
|
}
|
|
1909
2009
|
function checkSkillsAtRoot(skillsRoot) {
|
|
1910
|
-
const skillSourceBase = join13(__dirname4, "skills");
|
|
2010
|
+
const skillSourceBase = join13(__dirname4, "materializer", "skills");
|
|
1911
2011
|
return SKILL_NAMES.map((name) => {
|
|
1912
2012
|
const livePath = join13(skillsRoot, name, "SKILL.md");
|
|
1913
2013
|
const sourcePath = join13(skillSourceBase, name, "SKILL.md");
|