agentopology 0.2.0 → 0.2.3
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 +7 -5
- package/dist/analyzer/__tests__/observability-gap.test.d.ts +8 -0
- package/dist/analyzer/__tests__/observability-gap.test.d.ts.map +1 -0
- package/dist/analyzer/__tests__/observability-gap.test.js +132 -0
- package/dist/analyzer/__tests__/observability-gap.test.js.map +1 -0
- package/dist/analyzer/index.d.ts +1 -1
- package/dist/analyzer/index.d.ts.map +1 -1
- package/dist/analyzer/index.js +26 -0
- package/dist/analyzer/index.js.map +1 -1
- package/dist/bindings/__tests__/bindings.test.js +288 -11
- package/dist/bindings/__tests__/bindings.test.js.map +1 -1
- package/dist/bindings/__tests__/observability.test.d.ts +9 -0
- package/dist/bindings/__tests__/observability.test.d.ts.map +1 -0
- package/dist/bindings/__tests__/observability.test.js +136 -0
- package/dist/bindings/__tests__/observability.test.js.map +1 -0
- package/dist/bindings/__tests__/stub-generation.test.d.ts +16 -0
- package/dist/bindings/__tests__/stub-generation.test.d.ts.map +1 -0
- package/dist/bindings/__tests__/stub-generation.test.js +117 -0
- package/dist/bindings/__tests__/stub-generation.test.js.map +1 -0
- package/dist/bindings/claude-code.d.ts.map +1 -1
- package/dist/bindings/claude-code.js +159 -110
- package/dist/bindings/claude-code.js.map +1 -1
- package/dist/bindings/codex.d.ts.map +1 -1
- package/dist/bindings/codex.js +1 -12
- package/dist/bindings/codex.js.map +1 -1
- package/dist/bindings/cursor.d.ts.map +1 -1
- package/dist/bindings/cursor.js +0 -12
- package/dist/bindings/cursor.js.map +1 -1
- package/dist/bindings/gemini-cli.d.ts.map +1 -1
- package/dist/bindings/gemini-cli.js +1 -12
- package/dist/bindings/gemini-cli.js.map +1 -1
- package/dist/bindings/kiro.d.ts.map +1 -1
- package/dist/bindings/kiro.js +1 -12
- package/dist/bindings/kiro.js.map +1 -1
- package/dist/bindings/lib/__tests__/stub.test.d.ts +8 -0
- package/dist/bindings/lib/__tests__/stub.test.d.ts.map +1 -0
- package/dist/bindings/lib/__tests__/stub.test.js +66 -0
- package/dist/bindings/lib/__tests__/stub.test.js.map +1 -0
- package/dist/bindings/lib/stub.d.ts +56 -0
- package/dist/bindings/lib/stub.d.ts.map +1 -0
- package/dist/bindings/lib/stub.js +69 -0
- package/dist/bindings/lib/stub.js.map +1 -0
- package/dist/bindings/openclaw.d.ts.map +1 -1
- package/dist/bindings/openclaw.js +1 -12
- package/dist/bindings/openclaw.js.map +1 -1
- package/dist/bindings/types.d.ts +5 -0
- package/dist/bindings/types.d.ts.map +1 -1
- package/dist/bindings/types.js.map +1 -1
- package/dist/cli/index.js +89 -4
- package/dist/cli/index.js.map +1 -1
- package/dist/docs/content.d.ts.map +1 -1
- package/dist/docs/content.js +9 -5
- package/dist/docs/content.js.map +1 -1
- package/dist/import/__tests__/import.test.js +2 -2
- package/dist/import/__tests__/import.test.js.map +1 -1
- package/dist/parser/__tests__/parser.test.js +31 -3
- package/dist/parser/__tests__/parser.test.js.map +1 -1
- package/dist/parser/validator.d.ts.map +1 -1
- package/dist/parser/validator.js +28 -8
- package/dist/parser/validator.js.map +1 -1
- package/dist/scaffold/__tests__/scaffold.test.js +20 -0
- package/dist/scaffold/__tests__/scaffold.test.js.map +1 -1
- package/dist/scaffold/__tests__/settings-merge.test.d.ts +15 -0
- package/dist/scaffold/__tests__/settings-merge.test.d.ts.map +1 -0
- package/dist/scaffold/__tests__/settings-merge.test.js +127 -0
- package/dist/scaffold/__tests__/settings-merge.test.js.map +1 -0
- package/dist/scaffold/incremental.d.ts.map +1 -1
- package/dist/scaffold/incremental.js +11 -2
- package/dist/scaffold/incremental.js.map +1 -1
- package/dist/scaffold/merge.d.ts +16 -0
- package/dist/scaffold/merge.d.ts.map +1 -1
- package/dist/scaffold/merge.js +77 -0
- package/dist/scaffold/merge.js.map +1 -1
- package/dist/scaffold/types.d.ts +2 -0
- package/dist/scaffold/types.d.ts.map +1 -1
- package/examples/simple-pipeline-topology.html +5700 -0
- package/package.json +2 -1
- package/skill/SKILL.md +7 -7
package/README.md
CHANGED
|
@@ -156,7 +156,7 @@ In Claude Code, type `/agentopology` — or just ask naturally:
|
|
|
156
156
|
Say **"I want a code review team with an analyzer, security scanner, and reviewer"** — the skill:
|
|
157
157
|
|
|
158
158
|
1. Generates the `.at` file with the right syntax
|
|
159
|
-
2. Validates it against
|
|
159
|
+
2. Validates it against 82 rules
|
|
160
160
|
3. Scaffolds it to Claude Code, OpenClaw, Cursor, or any target
|
|
161
161
|
|
|
162
162
|
**Full agent team in under 2 minutes.** No docs to read. No syntax to memorize. You describe what you want, the skill handles the rest.
|
|
@@ -452,13 +452,15 @@ You can `agentopology visualize` it into an interactive graph. You can hand it t
|
|
|
452
452
|
## CLI Reference
|
|
453
453
|
|
|
454
454
|
```
|
|
455
|
-
agentopology validate <file> Validate an .at file
|
|
455
|
+
agentopology validate <file> Validate an .at file (82 rules)
|
|
456
456
|
agentopology scaffold <file> --target <t> Generate platform configs
|
|
457
|
+
agentopology sync <file> --target <t> --dir <d> Sync platform files back to .at
|
|
458
|
+
agentopology import --target <t> --dir <d> Reverse-engineer platform files to .at
|
|
457
459
|
agentopology visualize <file> Interactive topology graph
|
|
460
|
+
agentopology export <file> --format <fmt> Export as markdown, mermaid, or json
|
|
461
|
+
agentopology info <file> Topology analysis and suggestions
|
|
458
462
|
agentopology targets List supported platforms
|
|
459
|
-
agentopology docs [topic] Language reference
|
|
460
|
-
agentopology info <file> Topology summary
|
|
461
|
-
agentopology export <file> --format json Export AST as JSON
|
|
463
|
+
agentopology docs [topic] Language reference (42 topics)
|
|
462
464
|
```
|
|
463
465
|
|
|
464
466
|
---
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for Change 2: agentopology info warns about observability gaps.
|
|
3
|
+
*
|
|
4
|
+
* If a topology has agents but no SubagentStop/Stop hook, the analyzer
|
|
5
|
+
* should emit a warning-level suggestion.
|
|
6
|
+
*/
|
|
7
|
+
export {};
|
|
8
|
+
//# sourceMappingURL=observability-gap.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"observability-gap.test.d.ts","sourceRoot":"","sources":["../../../src/analyzer/__tests__/observability-gap.test.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for Change 2: agentopology info warns about observability gaps.
|
|
3
|
+
*
|
|
4
|
+
* If a topology has agents but no SubagentStop/Stop hook, the analyzer
|
|
5
|
+
* should emit a warning-level suggestion.
|
|
6
|
+
*/
|
|
7
|
+
import { describe, it, expect } from "vitest";
|
|
8
|
+
import { parse } from "../../parser/index.js";
|
|
9
|
+
import { analyze } from "../index.js";
|
|
10
|
+
// ---------------------------------------------------------------------------
|
|
11
|
+
// Topology WITHOUT any hooks — should warn
|
|
12
|
+
// ---------------------------------------------------------------------------
|
|
13
|
+
const NO_HOOKS_TOPOLOGY = `
|
|
14
|
+
topology no-hooks : [pipeline] {
|
|
15
|
+
meta { version: "1.0.0" description: "No hooks at all" }
|
|
16
|
+
orchestrator { model: opus handles: [start] }
|
|
17
|
+
action start { kind: inline }
|
|
18
|
+
agent worker-a { model: sonnet phase: 1 prompt { You are worker-a. } }
|
|
19
|
+
agent worker-b { model: haiku phase: 2 prompt { You are worker-b. } }
|
|
20
|
+
flow { start -> worker-a -> worker-b }
|
|
21
|
+
}
|
|
22
|
+
`;
|
|
23
|
+
// Topology WITH SubagentStop hook — should NOT warn
|
|
24
|
+
const WITH_SUBAGENT_STOP_TOPOLOGY = `
|
|
25
|
+
topology with-hooks : [pipeline] {
|
|
26
|
+
meta { version: "1.0.0" description: "Has SubagentStop hook" }
|
|
27
|
+
orchestrator { model: opus handles: [start] }
|
|
28
|
+
action start { kind: inline }
|
|
29
|
+
agent worker { model: sonnet phase: 1 prompt { You are worker. } }
|
|
30
|
+
flow { start -> worker }
|
|
31
|
+
hooks {
|
|
32
|
+
hook log-finish {
|
|
33
|
+
on: SubagentStop
|
|
34
|
+
matcher: "worker"
|
|
35
|
+
run: ".claude/scripts/log.sh"
|
|
36
|
+
type: command
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
`;
|
|
41
|
+
// Topology WITH Stop hook — should NOT warn
|
|
42
|
+
const WITH_STOP_TOPOLOGY = `
|
|
43
|
+
topology with-stop : [pipeline] {
|
|
44
|
+
meta { version: "1.0.0" description: "Has Stop hook" }
|
|
45
|
+
orchestrator { model: opus handles: [start] }
|
|
46
|
+
action start { kind: inline }
|
|
47
|
+
agent worker { model: sonnet phase: 1 prompt { You are worker. } }
|
|
48
|
+
flow { start -> worker }
|
|
49
|
+
hooks {
|
|
50
|
+
hook on-stop {
|
|
51
|
+
on: Stop
|
|
52
|
+
matcher: ""
|
|
53
|
+
run: ".claude/scripts/stop.sh"
|
|
54
|
+
type: command
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
`;
|
|
59
|
+
// Topology WITH enforced gate (compiles to SubagentStop) — should NOT warn
|
|
60
|
+
const WITH_GATE_TOPOLOGY = `
|
|
61
|
+
topology with-gate : [pipeline] {
|
|
62
|
+
meta { version: "1.0.0" description: "Has an enforced gate" }
|
|
63
|
+
orchestrator { model: opus handles: [start] }
|
|
64
|
+
action start { kind: inline }
|
|
65
|
+
agent worker { model: sonnet phase: 1 prompt { You are worker. } }
|
|
66
|
+
flow { start -> worker }
|
|
67
|
+
gates {
|
|
68
|
+
gate quality-check {
|
|
69
|
+
after: worker
|
|
70
|
+
run: "scripts/check.sh"
|
|
71
|
+
checks: [lint]
|
|
72
|
+
on-fail: halt
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
`;
|
|
77
|
+
// Zero-agent topology — should NOT warn
|
|
78
|
+
const ZERO_AGENTS_TOPOLOGY = `
|
|
79
|
+
topology zero-agents : [pipeline] {
|
|
80
|
+
meta { version: "1.0.0" description: "No agents" }
|
|
81
|
+
orchestrator { model: opus handles: [start, done] }
|
|
82
|
+
action start { kind: inline }
|
|
83
|
+
action done { kind: report }
|
|
84
|
+
flow { start -> done }
|
|
85
|
+
}
|
|
86
|
+
`;
|
|
87
|
+
describe("Change 2 — observability gap warning", () => {
|
|
88
|
+
it("warns when topology has agents but NO hooks at all", () => {
|
|
89
|
+
const ast = parse(NO_HOOKS_TOPOLOGY);
|
|
90
|
+
const result = analyze(ast);
|
|
91
|
+
const obsWarning = result.suggestions.find((s) => s.message.includes("Observability gap"));
|
|
92
|
+
expect(obsWarning).toBeDefined();
|
|
93
|
+
expect(obsWarning.level).toBe("warning");
|
|
94
|
+
});
|
|
95
|
+
it("warning message contains agent count", () => {
|
|
96
|
+
const ast = parse(NO_HOOKS_TOPOLOGY);
|
|
97
|
+
const result = analyze(ast);
|
|
98
|
+
const obsWarning = result.suggestions.find((s) => s.message.includes("Observability gap"));
|
|
99
|
+
expect(obsWarning.message).toContain("2");
|
|
100
|
+
});
|
|
101
|
+
it("warning message references SubagentStop", () => {
|
|
102
|
+
const ast = parse(NO_HOOKS_TOPOLOGY);
|
|
103
|
+
const result = analyze(ast);
|
|
104
|
+
const obsWarning = result.suggestions.find((s) => s.message.includes("Observability gap"));
|
|
105
|
+
expect(obsWarning.message).toContain("SubagentStop");
|
|
106
|
+
});
|
|
107
|
+
it("does NOT warn when topology has a SubagentStop hook", () => {
|
|
108
|
+
const ast = parse(WITH_SUBAGENT_STOP_TOPOLOGY);
|
|
109
|
+
const result = analyze(ast);
|
|
110
|
+
const obsWarning = result.suggestions.find((s) => s.message.includes("Observability gap"));
|
|
111
|
+
expect(obsWarning).toBeUndefined();
|
|
112
|
+
});
|
|
113
|
+
it("does NOT warn when topology has a Stop hook", () => {
|
|
114
|
+
const ast = parse(WITH_STOP_TOPOLOGY);
|
|
115
|
+
const result = analyze(ast);
|
|
116
|
+
const obsWarning = result.suggestions.find((s) => s.message.includes("Observability gap"));
|
|
117
|
+
expect(obsWarning).toBeUndefined();
|
|
118
|
+
});
|
|
119
|
+
it("does NOT warn when topology has an enforced gate (compiles to SubagentStop)", () => {
|
|
120
|
+
const ast = parse(WITH_GATE_TOPOLOGY);
|
|
121
|
+
const result = analyze(ast);
|
|
122
|
+
const obsWarning = result.suggestions.find((s) => s.message.includes("Observability gap"));
|
|
123
|
+
expect(obsWarning).toBeUndefined();
|
|
124
|
+
});
|
|
125
|
+
it("does NOT warn for zero-agent topologies", () => {
|
|
126
|
+
const ast = parse(ZERO_AGENTS_TOPOLOGY);
|
|
127
|
+
const result = analyze(ast);
|
|
128
|
+
const obsWarning = result.suggestions.find((s) => s.message.includes("Observability gap"));
|
|
129
|
+
expect(obsWarning).toBeUndefined();
|
|
130
|
+
});
|
|
131
|
+
});
|
|
132
|
+
//# sourceMappingURL=observability-gap.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"observability-gap.test.js","sourceRoot":"","sources":["../../../src/analyzer/__tests__/observability-gap.test.ts"],"names":[],"mappings":"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"}
|
package/dist/analyzer/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/analyzer/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EACV,WAAW,EAOZ,MAAM,kBAAkB,CAAC;AAM1B,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE;QACT,MAAM,EAAE,MAAM,CAAC;QACf,OAAO,EAAE,MAAM,CAAC;QAChB,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,EAAE,MAAM,CAAC;QACf,aAAa,EAAE,MAAM,CAAC;QACtB,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,EAAE,MAAM,EAAE,CAAC;CAC5B;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,UAAU,GAAG,QAAQ,CAAC;IAClC,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,GAAG,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/analyzer/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EACV,WAAW,EAOZ,MAAM,kBAAkB,CAAC;AAM1B,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE;QACT,MAAM,EAAE,MAAM,CAAC;QACf,OAAO,EAAE,MAAM,CAAC;QAChB,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,EAAE,MAAM,CAAC;QACf,aAAa,EAAE,MAAM,CAAC;QACtB,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,EAAE,MAAM,EAAE,CAAC;CAC5B;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,UAAU,GAAG,QAAQ,CAAC;IAClC,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS,CAAC;IAC1C,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,eAAe,CAAC;IACzB,QAAQ,EAAE,eAAe,EAAE,CAAC;IAC5B,MAAM,EAAE,SAAS,EAAE,CAAC;IACpB,WAAW,EAAE,UAAU,EAAE,CAAC;CAC3B;AAuXD,wBAAgB,OAAO,CAAC,GAAG,EAAE,WAAW,GAAG,cAAc,CAuCxD"}
|
package/dist/analyzer/index.js
CHANGED
|
@@ -289,6 +289,32 @@ function generateSuggestions(ast) {
|
|
|
289
289
|
});
|
|
290
290
|
}
|
|
291
291
|
}
|
|
292
|
+
// Observability gap check (Change 2):
|
|
293
|
+
// If a topology has agents but no SubagentStop or Stop hook (global hooks or
|
|
294
|
+
// enforced gates — which compile to SubagentStop), per-agent finish events
|
|
295
|
+
// will never be captured.
|
|
296
|
+
const agentCount = ast.nodes.filter(isAgent).length;
|
|
297
|
+
if (agentCount > 0) {
|
|
298
|
+
const hasObsHook = (ast.hooks ?? []).some((h) => h.on === "SubagentStop" || h.on === "Stop") ||
|
|
299
|
+
ast.nodes.some((n) => isGate(n) && !!n.run && n.behavior !== "advisory");
|
|
300
|
+
if (!hasObsHook) {
|
|
301
|
+
const agentIds = ast.nodes.filter(isAgent).map((a) => a.id);
|
|
302
|
+
const exampleMatcher = agentIds.slice(0, 3).join("|") + (agentIds.length > 3 ? "|..." : "");
|
|
303
|
+
suggestions.push({
|
|
304
|
+
level: "warning",
|
|
305
|
+
message: `Observability gap: topology has ${agentCount} agent${agentCount !== 1 ? "s" : ""} but no SubagentStop/Stop hook. ` +
|
|
306
|
+
`You won't capture per-agent finish events. Consider adding:\n` +
|
|
307
|
+
` hooks {\n` +
|
|
308
|
+
` hook log-subagent-finish {\n` +
|
|
309
|
+
` on: SubagentStop\n` +
|
|
310
|
+
` matcher: "${exampleMatcher}"\n` +
|
|
311
|
+
` run: ".claude/scripts/log-subagent.sh"\n` +
|
|
312
|
+
` type: command\n` +
|
|
313
|
+
` }\n` +
|
|
314
|
+
` }`,
|
|
315
|
+
});
|
|
316
|
+
}
|
|
317
|
+
}
|
|
292
318
|
return suggestions;
|
|
293
319
|
}
|
|
294
320
|
// ---------------------------------------------------------------------------
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/analyzer/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/analyzer/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { describe, it, expect } from "vitest";
|
|
2
2
|
import { parse } from "../../parser/index.js";
|
|
3
3
|
import { bindings, claudeCodeBinding, kiroBinding, cursorBinding, } from "../index.js";
|
|
4
|
+
import { isStubContent, STUB_MARKER } from "../lib/stub.js";
|
|
4
5
|
// ---------------------------------------------------------------------------
|
|
5
6
|
// Minimal but valid .at topology exercising most features
|
|
6
7
|
// ---------------------------------------------------------------------------
|
|
@@ -207,8 +208,8 @@ describe("claude-code binding", () => {
|
|
|
207
208
|
const mcp = JSON.parse(mcpFile.content);
|
|
208
209
|
expect(mcp.mcpServers.filesystem).toBeDefined();
|
|
209
210
|
});
|
|
210
|
-
it("produces a context file (.claude/
|
|
211
|
-
const contextFile = files.find((f) => f.path === ".claude/
|
|
211
|
+
it("produces a context file (.claude/CLAUDE.md, never root CLAUDE.md)", () => {
|
|
212
|
+
const contextFile = files.find((f) => f.path === ".claude/CLAUDE.md");
|
|
212
213
|
expect(contextFile).toBeDefined();
|
|
213
214
|
// Must never generate root-level CLAUDE.md
|
|
214
215
|
const rootClaudeMd = files.find((f) => f.path === "CLAUDE.md");
|
|
@@ -220,12 +221,12 @@ describe("claude-code binding", () => {
|
|
|
220
221
|
expect(builderFile.content).toContain("disallowedTools:");
|
|
221
222
|
expect(builderFile.content).toContain("Edit");
|
|
222
223
|
});
|
|
223
|
-
it("compiles enforced gate to settings.json
|
|
224
|
+
it("compiles enforced gate to settings.json SubagentStop hook with after: agent as matcher", () => {
|
|
224
225
|
const settingsFile = files.find((f) => f.path === ".claude/settings.json");
|
|
225
226
|
expect(settingsFile).toBeDefined();
|
|
226
227
|
const settings = JSON.parse(settingsFile.content);
|
|
227
|
-
expect(settings.hooks.
|
|
228
|
-
const gateHook = settings.hooks.
|
|
228
|
+
expect(settings.hooks.SubagentStop).toBeDefined();
|
|
229
|
+
const gateHook = settings.hooks.SubagentStop.find((h) => h.matcher === "builder" && JSON.stringify(h).includes("gate-quality-check"));
|
|
229
230
|
expect(gateHook).toBeDefined();
|
|
230
231
|
});
|
|
231
232
|
it("does NOT compile advisory gate to settings.json hook", () => {
|
|
@@ -238,12 +239,252 @@ describe("claude-code binding", () => {
|
|
|
238
239
|
const wrapperScript = files.find((f) => f.path.includes("gate-quality-check.sh"));
|
|
239
240
|
expect(wrapperScript).toBeDefined();
|
|
240
241
|
expect(wrapperScript.content).toContain("lint.sh");
|
|
241
|
-
expect(wrapperScript.content).toContain("exit
|
|
242
|
+
expect(wrapperScript.content).toContain("exit 2");
|
|
242
243
|
});
|
|
243
244
|
it("does NOT generate gate wrapper script for advisory gate", () => {
|
|
244
245
|
const advisoryWrapper = files.find((f) => f.path.includes("gate-soft-review.sh"));
|
|
245
246
|
expect(advisoryWrapper).toBeUndefined();
|
|
246
247
|
});
|
|
248
|
+
it("gate stub contains the AGENTOPOLOGY_STUB marker (#4)", () => {
|
|
249
|
+
// The gate's `run` script is a stub generated by shellStub() in the
|
|
250
|
+
// shared lib. It must carry the marker so tooling can detect it.
|
|
251
|
+
const stub = files.find((f) => f.path.endsWith("/scripts/lint.sh"));
|
|
252
|
+
expect(stub).toBeDefined();
|
|
253
|
+
expect(stub.content).toContain(STUB_MARKER);
|
|
254
|
+
expect(isStubContent(stub.content)).toBe(true);
|
|
255
|
+
});
|
|
256
|
+
});
|
|
257
|
+
// ---------------------------------------------------------------------------
|
|
258
|
+
// claude-code — Issue #3: SubagentStop matcher targeting
|
|
259
|
+
//
|
|
260
|
+
// Per https://code.claude.com/docs/en/hooks.md, the SubagentStop hook's
|
|
261
|
+
// `matcher` field is matched against agent_type (the registered subagent
|
|
262
|
+
// name). Only agent and group nodes scaffold a `.claude/agents/<name>/AGENT.md`
|
|
263
|
+
// file and therefore register as subagent_types. Human, action, and
|
|
264
|
+
// orchestrator targets cannot be matched and would produce dead config that
|
|
265
|
+
// never fires. The scaffolder must skip those hooks (and warn) but still
|
|
266
|
+
// generate the wrapper script so the orchestrator can invoke it directly.
|
|
267
|
+
// ---------------------------------------------------------------------------
|
|
268
|
+
describe("claude-code binding — gate SubagentStop targeting (#3)", () => {
|
|
269
|
+
// Build a topology where one gate targets an agent and another targets a
|
|
270
|
+
// human node — proves both branches of isRegisteredSubagentType.
|
|
271
|
+
const GATE_TARGETING_SOURCE = `
|
|
272
|
+
topology gate-target-test : [pipeline] {
|
|
273
|
+
meta {
|
|
274
|
+
version: "1.0.0"
|
|
275
|
+
description: "Gate targeting test"
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
orchestrator { model: opus handles: [intake] }
|
|
279
|
+
action intake { kind: external source: "user" }
|
|
280
|
+
|
|
281
|
+
agent writer {
|
|
282
|
+
model: sonnet
|
|
283
|
+
phase: 1
|
|
284
|
+
tools: [Read, Write]
|
|
285
|
+
reads: ["workspace/input.md"]
|
|
286
|
+
writes: ["workspace/draft.md"]
|
|
287
|
+
permissions: autonomous
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
human approver {
|
|
291
|
+
description: "Approve the draft before publishing"
|
|
292
|
+
timeout: 1h
|
|
293
|
+
on-timeout: skip
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
agent publisher {
|
|
297
|
+
model: sonnet
|
|
298
|
+
phase: 3
|
|
299
|
+
tools: [Read, Bash]
|
|
300
|
+
reads: ["workspace/draft.md"]
|
|
301
|
+
writes: ["workspace/published.md"]
|
|
302
|
+
permissions: autonomous
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
flow {
|
|
306
|
+
intake -> writer
|
|
307
|
+
writer -> approver
|
|
308
|
+
approver -> publisher
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
gates {
|
|
312
|
+
gate gate-on-agent {
|
|
313
|
+
after: writer
|
|
314
|
+
before: approver
|
|
315
|
+
run: "scripts/check-draft.sh"
|
|
316
|
+
on-fail: bounce-back
|
|
317
|
+
behavior: blocking
|
|
318
|
+
}
|
|
319
|
+
gate gate-on-human {
|
|
320
|
+
after: approver
|
|
321
|
+
before: publisher
|
|
322
|
+
run: "scripts/check-approval.sh"
|
|
323
|
+
on-fail: halt
|
|
324
|
+
behavior: blocking
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
`;
|
|
329
|
+
const ast = parse(GATE_TARGETING_SOURCE);
|
|
330
|
+
// Capture warnings emitted during scaffold so tests can assert on them.
|
|
331
|
+
const originalWarn = console.warn;
|
|
332
|
+
const warnings = [];
|
|
333
|
+
console.warn = (...args) => {
|
|
334
|
+
warnings.push(args.map(String).join(" "));
|
|
335
|
+
};
|
|
336
|
+
let files;
|
|
337
|
+
try {
|
|
338
|
+
files = claudeCodeBinding.scaffold(ast);
|
|
339
|
+
}
|
|
340
|
+
finally {
|
|
341
|
+
console.warn = originalWarn;
|
|
342
|
+
}
|
|
343
|
+
const settingsFile = files.find((f) => f.path === ".claude/settings.json");
|
|
344
|
+
const settings = JSON.parse(settingsFile.content);
|
|
345
|
+
it("emits SubagentStop hook when gate.after is an agent", () => {
|
|
346
|
+
expect(settings.hooks.SubagentStop).toBeDefined();
|
|
347
|
+
const agentHook = settings.hooks.SubagentStop.find((h) => h.matcher === "writer");
|
|
348
|
+
expect(agentHook).toBeDefined();
|
|
349
|
+
expect(JSON.stringify(agentHook)).toContain("gate-gate-on-agent");
|
|
350
|
+
});
|
|
351
|
+
it("does NOT emit SubagentStop hook when gate.after is a human node", () => {
|
|
352
|
+
const humanHook = (settings.hooks?.SubagentStop ?? []).find((h) => h.matcher === "approver");
|
|
353
|
+
expect(humanHook).toBeUndefined();
|
|
354
|
+
});
|
|
355
|
+
it("warns at scaffold time when a blocking gate targets a non-agent node", () => {
|
|
356
|
+
const humanWarning = warnings.find((w) => w.includes("gate-on-human") && w.includes("approver"));
|
|
357
|
+
expect(humanWarning).toBeDefined();
|
|
358
|
+
expect(humanWarning).toContain("non-agent");
|
|
359
|
+
});
|
|
360
|
+
it("still generates the gate wrapper script for non-agent-targeted gate", () => {
|
|
361
|
+
// The wrapper must exist so the orchestrator/playbook can invoke it
|
|
362
|
+
// manually at the right step, even when no hook fires.
|
|
363
|
+
const wrapper = files.find((f) => f.path.endsWith("/scripts/gate-gate-on-human.sh"));
|
|
364
|
+
expect(wrapper).toBeDefined();
|
|
365
|
+
});
|
|
366
|
+
it("wrapper script for non-agent-targeted gate documents the limitation", () => {
|
|
367
|
+
const wrapper = files.find((f) => f.path.endsWith("/scripts/gate-gate-on-human.sh"));
|
|
368
|
+
expect(wrapper.content).toContain("NOT wired as a SubagentStop hook");
|
|
369
|
+
expect(wrapper.content).toContain("orchestrator playbook");
|
|
370
|
+
});
|
|
371
|
+
it("wrapper script for agent-targeted gate documents SubagentStop enforcement", () => {
|
|
372
|
+
const wrapper = files.find((f) => f.path.endsWith("/scripts/gate-gate-on-agent.sh"));
|
|
373
|
+
expect(wrapper.content).toContain("SubagentStop hook on agent \"writer\"");
|
|
374
|
+
expect(wrapper.content).toContain("Exit 2 blocks");
|
|
375
|
+
});
|
|
376
|
+
it("scaffolded hook entry uses agent name (not 'Agent' or arbitrary) as matcher", () => {
|
|
377
|
+
// Sanity check: matchers must be exactly the agent id, since Claude Code
|
|
378
|
+
// matches them against agent_type, not against the tool name.
|
|
379
|
+
const hooks = settings.hooks.SubagentStop ?? [];
|
|
380
|
+
for (const h of hooks) {
|
|
381
|
+
// Each matcher must correspond to an agent or group node in the AST.
|
|
382
|
+
const matcher = h.matcher;
|
|
383
|
+
expect(matcher).toBeTruthy();
|
|
384
|
+
const matchingNode = ast.nodes.find((n) => (n.type === "agent" || n.type === "group") && n.id === matcher);
|
|
385
|
+
expect(matchingNode, `matcher "${matcher}" must resolve to an agent or group node`).toBeDefined();
|
|
386
|
+
}
|
|
387
|
+
});
|
|
388
|
+
});
|
|
389
|
+
// ---------------------------------------------------------------------------
|
|
390
|
+
// claude-code — Integration test: youtube-flywheel.at fixture (#3)
|
|
391
|
+
//
|
|
392
|
+
// The real-world failure from agentopology-content: gates with after: human
|
|
393
|
+
// produced dead SubagentStop entries. This integration test pins the fix
|
|
394
|
+
// against the actual fixture and asserts the right hooks fire and the wrong
|
|
395
|
+
// ones don't.
|
|
396
|
+
// ---------------------------------------------------------------------------
|
|
397
|
+
describe("claude-code binding — youtube-flywheel integration (#3)", () => {
|
|
398
|
+
const YOUTUBE_FLYWHEEL_SOURCE = `
|
|
399
|
+
topology youtube-flywheel : [pipeline, fan-out, human-gate] {
|
|
400
|
+
meta { version: "1.0.0" }
|
|
401
|
+
|
|
402
|
+
orchestrator { model: opus handles: [start] }
|
|
403
|
+
action start { kind: inline }
|
|
404
|
+
|
|
405
|
+
agent briefer {
|
|
406
|
+
model: opus
|
|
407
|
+
phase: 4
|
|
408
|
+
tools: [Read, Write]
|
|
409
|
+
reads: ["workspace/idea.json"]
|
|
410
|
+
writes: ["workspace/brief.json"]
|
|
411
|
+
permissions: supervised
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
human approve-brief {
|
|
415
|
+
description: "Review the brief before render"
|
|
416
|
+
timeout: 8h
|
|
417
|
+
on-timeout: skip
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
agent renderer {
|
|
421
|
+
model: sonnet
|
|
422
|
+
phase: 6
|
|
423
|
+
tools: [Read, Write, Bash]
|
|
424
|
+
reads: ["workspace/brief.json"]
|
|
425
|
+
writes: ["workspace/render/"]
|
|
426
|
+
permissions: autonomous
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
flow {
|
|
430
|
+
start -> briefer
|
|
431
|
+
briefer -> approve-brief
|
|
432
|
+
approve-brief -> renderer
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
gates {
|
|
436
|
+
gate brief-schema-valid {
|
|
437
|
+
after: briefer
|
|
438
|
+
before: approve-brief
|
|
439
|
+
run: "scripts/validate-brief.sh"
|
|
440
|
+
on-fail: bounce-back
|
|
441
|
+
behavior: blocking
|
|
442
|
+
}
|
|
443
|
+
gate render-quality {
|
|
444
|
+
after: renderer
|
|
445
|
+
before: start
|
|
446
|
+
run: "scripts/qa-render.sh"
|
|
447
|
+
on-fail: bounce-back
|
|
448
|
+
behavior: blocking
|
|
449
|
+
}
|
|
450
|
+
gate platform-credentials {
|
|
451
|
+
after: approve-brief
|
|
452
|
+
before: renderer
|
|
453
|
+
run: "scripts/check-platform-auth.sh"
|
|
454
|
+
on-fail: halt
|
|
455
|
+
behavior: blocking
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
`;
|
|
460
|
+
const ast = parse(YOUTUBE_FLYWHEEL_SOURCE);
|
|
461
|
+
const originalWarn = console.warn;
|
|
462
|
+
const warnings = [];
|
|
463
|
+
console.warn = (...args) => {
|
|
464
|
+
warnings.push(args.map(String).join(" "));
|
|
465
|
+
};
|
|
466
|
+
let files;
|
|
467
|
+
try {
|
|
468
|
+
files = claudeCodeBinding.scaffold(ast);
|
|
469
|
+
}
|
|
470
|
+
finally {
|
|
471
|
+
console.warn = originalWarn;
|
|
472
|
+
}
|
|
473
|
+
const settingsFile = files.find((f) => f.path === ".claude/settings.json");
|
|
474
|
+
const settings = JSON.parse(settingsFile.content);
|
|
475
|
+
it("emits SubagentStop hooks for the two agent-targeted gates", () => {
|
|
476
|
+
const matchers = (settings.hooks?.SubagentStop ?? []).map((h) => h.matcher);
|
|
477
|
+
expect(matchers).toContain("briefer");
|
|
478
|
+
expect(matchers).toContain("renderer");
|
|
479
|
+
});
|
|
480
|
+
it("does NOT emit a SubagentStop hook for the gate targeting the human 'approve-brief'", () => {
|
|
481
|
+
const matchers = (settings.hooks?.SubagentStop ?? []).map((h) => h.matcher);
|
|
482
|
+
expect(matchers).not.toContain("approve-brief");
|
|
483
|
+
});
|
|
484
|
+
it("warns at scaffold time about the platform-credentials gate", () => {
|
|
485
|
+
const w = warnings.find((m) => m.includes("platform-credentials") && m.includes("approve-brief"));
|
|
486
|
+
expect(w).toBeDefined();
|
|
487
|
+
});
|
|
247
488
|
});
|
|
248
489
|
// ---------------------------------------------------------------------------
|
|
249
490
|
// claude-code — Exotic features: groups, humans, circuit breakers, scale,
|
|
@@ -553,8 +794,8 @@ topology debate-test : [fan-out, debate, pipeline] {
|
|
|
553
794
|
expect(schema).toBeDefined();
|
|
554
795
|
expect(schema.content).toContain("winner");
|
|
555
796
|
});
|
|
556
|
-
it("artifacts documented in
|
|
557
|
-
const ctx = exoticFiles.find((f) => f.path === ".claude/
|
|
797
|
+
it("artifacts documented in CLAUDE.md", () => {
|
|
798
|
+
const ctx = exoticFiles.find((f) => f.path === ".claude/CLAUDE.md");
|
|
558
799
|
expect(ctx.content).toContain("transcript");
|
|
559
800
|
});
|
|
560
801
|
it("skills generate SKILL.md files", () => {
|
|
@@ -571,9 +812,9 @@ topology debate-test : [fan-out, debate, pipeline] {
|
|
|
571
812
|
expect(hook).toBeDefined();
|
|
572
813
|
expect(hook.hooks[0].timeout).toBe(5000);
|
|
573
814
|
});
|
|
574
|
-
it("gate compiles to
|
|
575
|
-
expect(settings.hooks.
|
|
576
|
-
const gateHook = settings.hooks.
|
|
815
|
+
it("gate compiles to SubagentStop hook with after: agent as matcher", () => {
|
|
816
|
+
expect(settings.hooks.SubagentStop).toBeDefined();
|
|
817
|
+
const gateHook = settings.hooks.SubagentStop.find((h) => JSON.stringify(h).includes("fact-check"));
|
|
577
818
|
expect(gateHook).toBeDefined();
|
|
578
819
|
});
|
|
579
820
|
});
|
|
@@ -2086,4 +2327,40 @@ topology debate-test : [fan-out, debate, pipeline] {
|
|
|
2086
2327
|
});
|
|
2087
2328
|
});
|
|
2088
2329
|
});
|
|
2330
|
+
// ---------------------------------------------------------------------------
|
|
2331
|
+
// Cross-binding: AGENTOPOLOGY_STUB marker uniformity (#4)
|
|
2332
|
+
//
|
|
2333
|
+
// All bindings that scaffold gate scripts must emit them via the shared
|
|
2334
|
+
// shellStub() util — which embeds the AGENTOPOLOGY_STUB marker. This test
|
|
2335
|
+
// loops over every binding and verifies that at least one stub file in its
|
|
2336
|
+
// scaffold output is detectable by isStubContent().
|
|
2337
|
+
// ---------------------------------------------------------------------------
|
|
2338
|
+
describe("Stub marker uniformity across bindings (#4)", () => {
|
|
2339
|
+
// The baseline TOPOLOGY_SOURCE at the top of this file has gate
|
|
2340
|
+
// `quality-check` whose `run: "scripts/lint.sh"` becomes a stub. Bindings
|
|
2341
|
+
// that scaffold gates (5 of 7) must produce a stub for it. The two that
|
|
2342
|
+
// don't (copilot-cli, cursor) have no gate-script generation and are
|
|
2343
|
+
// excluded.
|
|
2344
|
+
const stubProducers = ["claude-code", "codex", "gemini-cli", "kiro", "openclaw"];
|
|
2345
|
+
for (const bindingName of stubProducers) {
|
|
2346
|
+
it(`${bindingName} emits at least one stub with the AGENTOPOLOGY_STUB marker`, () => {
|
|
2347
|
+
const files = scaffoldBinding(bindingName);
|
|
2348
|
+
const stubs = files.filter((f) => isStubContent(f.content));
|
|
2349
|
+
expect(stubs.length, `${bindingName} should emit at least one stub`).toBeGreaterThan(0);
|
|
2350
|
+
// Every stub must contain the literal marker string (pinned by the
|
|
2351
|
+
// STUB_MARKER constant — see lib/stub.ts).
|
|
2352
|
+
for (const s of stubs) {
|
|
2353
|
+
expect(s.content).toContain(STUB_MARKER);
|
|
2354
|
+
}
|
|
2355
|
+
});
|
|
2356
|
+
}
|
|
2357
|
+
it("copilot-cli produces NO stubs (no shell-script scaffolds)", () => {
|
|
2358
|
+
// Sanity check — confirms the two non-stub-producing bindings stay
|
|
2359
|
+
// in their respective lanes. If this fails, copilot-cli probably
|
|
2360
|
+
// grew a gate-script path and needs the same marker treatment.
|
|
2361
|
+
const files = scaffoldBinding("copilot-cli");
|
|
2362
|
+
const stubs = files.filter((f) => isStubContent(f.content));
|
|
2363
|
+
expect(stubs).toEqual([]);
|
|
2364
|
+
});
|
|
2365
|
+
});
|
|
2089
2366
|
//# sourceMappingURL=bindings.test.js.map
|