agentopology 0.2.4 → 0.2.5

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 (32) hide show
  1. package/README.md +23 -7
  2. package/dist/bindings/__tests__/bindings.test.js +2 -2
  3. package/dist/bindings/__tests__/claude-code-hybrid.test.d.ts +2 -0
  4. package/dist/bindings/__tests__/claude-code-hybrid.test.d.ts.map +1 -0
  5. package/dist/bindings/__tests__/claude-code-hybrid.test.js +152 -0
  6. package/dist/bindings/__tests__/claude-code-hybrid.test.js.map +1 -0
  7. package/dist/bindings/__tests__/claude-workflow.test.d.ts +2 -0
  8. package/dist/bindings/__tests__/claude-workflow.test.d.ts.map +1 -0
  9. package/dist/bindings/__tests__/claude-workflow.test.js +204 -0
  10. package/dist/bindings/__tests__/claude-workflow.test.js.map +1 -0
  11. package/dist/bindings/__tests__/hybrid-e2e.test.d.ts +15 -0
  12. package/dist/bindings/__tests__/hybrid-e2e.test.d.ts.map +1 -0
  13. package/dist/bindings/__tests__/hybrid-e2e.test.js +94 -0
  14. package/dist/bindings/__tests__/hybrid-e2e.test.js.map +1 -0
  15. package/dist/bindings/claude-code.d.ts.map +1 -1
  16. package/dist/bindings/claude-code.js +307 -1
  17. package/dist/bindings/claude-code.js.map +1 -1
  18. package/dist/bindings/claude-workflow.d.ts +28 -0
  19. package/dist/bindings/claude-workflow.d.ts.map +1 -0
  20. package/dist/bindings/claude-workflow.js +684 -0
  21. package/dist/bindings/claude-workflow.js.map +1 -0
  22. package/dist/bindings/index.d.ts +1 -0
  23. package/dist/bindings/index.d.ts.map +1 -1
  24. package/dist/bindings/index.js +3 -0
  25. package/dist/bindings/index.js.map +1 -1
  26. package/dist/bindings/lib/seam.d.ts +35 -0
  27. package/dist/bindings/lib/seam.d.ts.map +1 -0
  28. package/dist/bindings/lib/seam.js +42 -0
  29. package/dist/bindings/lib/seam.js.map +1 -0
  30. package/examples/matchmat-ship.at +249 -0
  31. package/package.json +1 -1
  32. package/spec/grammar.md +12 -1
package/README.md CHANGED
@@ -12,7 +12,7 @@
12
12
  </p>
13
13
 
14
14
  <p align="center">
15
- <strong>Claude Code</strong> · <strong>OpenClaw</strong> · <strong>Codex</strong> · <strong>Cursor</strong> · <strong>Gemini CLI</strong> · <strong>Copilot</strong> · <strong>Kiro</strong>
15
+ <strong>Claude Code</strong> · <strong>Claude Workflow</strong> · <strong>OpenClaw</strong> · <strong>Codex</strong> · <strong>Cursor</strong> · <strong>Gemini CLI</strong> · <strong>Copilot</strong> · <strong>Kiro</strong>
16
16
  </p>
17
17
 
18
18
  <p align="center">
@@ -54,18 +54,32 @@ topology code-review : [pipeline] {
54
54
  ```
55
55
 
56
56
  ```bash
57
- agentopology scaffold my-team.at --target claude-code # → .claude/agents/
58
- agentopology scaffold my-team.at --target openclaw # → .openclaw/soul.md
59
- agentopology scaffold my-team.at --target codex # → .codex/
60
- agentopology scaffold my-team.at --target cursor # → .cursor/rules/
57
+ agentopology scaffold my-team.at --target claude-code # → .claude/agents/
58
+ agentopology scaffold my-team.at --target claude-workflow # → my-team.workflow.js (+ SEAM/README/LOSSY-REPORT)
59
+ agentopology scaffold my-team.at --target openclaw # → .openclaw/soul.md
60
+ agentopology scaffold my-team.at --target codex # → .codex/
61
+ agentopology scaffold my-team.at --target cursor # → .cursor/rules/
61
62
  ```
62
63
 
63
- One file. Seven platforms. The topology IS the documentation.
64
+ One file. Every platform. The topology IS the documentation.
64
65
 
65
66
  <p align="center">
66
67
  <img src="docs/visualizer-preview.png" alt="AgenTopology Visualizer" width="900" />
67
68
  </p>
68
69
 
70
+ ### Hybrid: host + embedded workflow
71
+
72
+ One `.at` topology can compile to **two coupled targets at once**. `claude-code` is the **host** — the event-driven layer that owns agents, hooks, the Blackboard, concurrent observability, and the human/gate/branching nodes. `claude-workflow` is the embedded **deterministic rung** — the parallel fan-out phases, compiled into a Claude Workflow tool script. The host launches the rung and observes its Blackboard writes live (via a `PostToolUse` hook), so you get concurrent observability the Workflow runtime can't do on its own.
73
+
74
+ Mark a phase for the rung with `extensions { claude-workflow { execution: workflow } }`, then scaffold both:
75
+
76
+ ```bash
77
+ agentopology scaffold my-team.at --target claude-code # the host
78
+ agentopology scaffold my-team.at --target claude-workflow # the embedded rung
79
+ ```
80
+
81
+ The hybrid is opt-in — a topology with no `execution: workflow` marker compiles to pure `claude-code`, unchanged. See [docs/AT_VS_WORKFLOW_STRATEGY.md](docs/AT_VS_WORKFLOW_STRATEGY.md) for why.
82
+
69
83
  ---
70
84
 
71
85
  ## What It Does
@@ -78,6 +92,7 @@ AgenTopology is a **declarative language** (`.at` files) and a **CLI compiler**
78
92
  │ (you write) │ │ Validator │ │ (auto-generated) │
79
93
  └──────────────┘ └────────────┘ └─────────────────────┘
80
94
  ├── .claude/agents/
95
+ ├── <topology>.workflow.js
81
96
  ├── .openclaw/
82
97
  ├── .codex/
83
98
  ├── .cursor/rules/
@@ -244,7 +259,8 @@ This defines three agents, their tools and memory, a quality gate, and a flow wi
244
259
 
245
260
  | Target | Command | What It Generates |
246
261
  |--------|---------|-------------------|
247
- | **Claude Code** | `--target claude-code` | `.claude/agents/`, `.claude/skills/`, `.mcp.json`, `.claude/settings.json` |
262
+ | **Claude Code** | `--target claude-code` | `.claude/agents/`, `.claude/skills/`, `.mcp.json`, `.claude/settings.json` (the event-driven host) |
263
+ | **Claude Workflow** | `--target claude-workflow` | `<topology>.workflow.js` (deterministic fan-out rung) + `-SEAM.md`, `-README.md`, `-LOSSY-REPORT.md` |
248
264
  | **OpenClaw** | `--target openclaw` | `.openclaw/soul.md`, `.openclaw/skills/`, `.openclaw/config.json` |
249
265
  | **Codex** | `--target codex` | `.codex/config.toml`, `AGENTS.md` |
250
266
  | **Cursor** | `--target cursor` | `.cursor/rules/*.mdc`, `.cursor/mcp.json`, `.cursor/hooks.json` |
@@ -156,8 +156,8 @@ function assertStructuralInvariants(files) {
156
156
  // Registry tests
157
157
  // ---------------------------------------------------------------------------
158
158
  describe("Binding registry", () => {
159
- it("contains all 7 bindings", () => {
160
- expect(Object.keys(bindings)).toHaveLength(7);
159
+ it("contains all 8 bindings", () => {
160
+ expect(Object.keys(bindings)).toHaveLength(8);
161
161
  });
162
162
  it("all bindings have a name and description", () => {
163
163
  for (const [key, binding] of Object.entries(bindings)) {
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=claude-code-hybrid.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-code-hybrid.test.d.ts","sourceRoot":"","sources":["../../../src/bindings/__tests__/claude-code-hybrid.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,152 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { readFileSync } from "node:fs";
3
+ import { fileURLToPath } from "node:url";
4
+ import path from "node:path";
5
+ import { parse } from "../../parser/index.js";
6
+ import { claudeCodeBinding, claudeWorkflowBinding } from "../index.js";
7
+ // ---------------------------------------------------------------------------
8
+ // Hybrid-awareness of the claude-code binding (host half of the host+workflow
9
+ // model). Fixture: examples/matchmat-ship.at — builder (phase 2) is
10
+ // execution:workflow; phases 1 & 3 + the human node are host-side.
11
+ // ---------------------------------------------------------------------------
12
+ const here = path.dirname(fileURLToPath(import.meta.url));
13
+ const fixturePath = path.resolve(here, "../../../examples/matchmat-ship.at");
14
+ const source = readFileSync(fixturePath, "utf-8");
15
+ const ast = parse(source);
16
+ const files = claudeCodeBinding.scaffold(ast);
17
+ function find(suffix) {
18
+ return files.find((f) => f.path.endsWith(suffix));
19
+ }
20
+ describe("claude-code binding — HYBRID awareness (matchmat-ship)", () => {
21
+ // (a) workflow-marked agent (builder) is NOT emitted as a host subagent.
22
+ it("does NOT emit .claude/agents/builder/AGENT.md (builder is execution:workflow)", () => {
23
+ const builderAgent = files.find((f) => f.path === ".claude/agents/builder/AGENT.md");
24
+ expect(builderAgent).toBeUndefined();
25
+ });
26
+ // (b) host phase-1 + phase-3 agents ARE still emitted as subagents.
27
+ it("still emits AGENT.md for host phase-1 and phase-3 agents", () => {
28
+ const expected = [
29
+ ".claude/agents/contract-scout/AGENT.md",
30
+ ".claude/agents/blast-radius-mapper/AGENT.md",
31
+ ".claude/agents/boundary-drafter/AGENT.md",
32
+ ".claude/agents/security-verifier/AGENT.md",
33
+ ".claude/agents/contract-verifier/AGENT.md",
34
+ ".claude/agents/closed-loop-verifier/AGENT.md",
35
+ ];
36
+ for (const p of expected) {
37
+ expect(files.find((f) => f.path === p), `expected ${p} to be emitted`).toBeDefined();
38
+ }
39
+ });
40
+ // (c) a launch-workflow stub/skill artifact for the build phase IS emitted.
41
+ it("emits a launch-<phase>-workflow.sh stub for the workflow phase", () => {
42
+ const launch = find("launch-builder-workflow.sh");
43
+ expect(launch).toBeDefined();
44
+ expect(launch.path).toBe(".claude/skills/matchmat-ship/scripts/launch-builder-workflow.sh");
45
+ expect(launch.executable).toBe(true);
46
+ // It's a detectable scaffold stub.
47
+ expect(launch.content).toContain("# AGENTOPOLOGY_STUB");
48
+ // It documents launching the SAME workflow.js filename the sibling binding emits.
49
+ expect(launch.content).toContain("matchmat-ship.workflow.js");
50
+ expect(launch.content).toContain("/workflow matchmat-ship.workflow.js");
51
+ // It points at the shared Blackboard root + the seam doc.
52
+ expect(launch.content).toContain("workspace/");
53
+ expect(launch.content).toContain("matchmat-ship-SEAM.md");
54
+ });
55
+ // (d) CLAUDE.md carries the hybrid run-order block referencing the workflow.js.
56
+ it("emits a Hybrid run order block in CLAUDE.md referencing the workflow.js", () => {
57
+ const ctx = files.find((f) => f.path === ".claude/CLAUDE.md");
58
+ expect(ctx).toBeDefined();
59
+ expect(ctx.content).toContain("## Hybrid run order");
60
+ expect(ctx.content).toContain("matchmat-ship.workflow.js");
61
+ expect(ctx.content).toContain("Host launches");
62
+ // host phases described as in-session; workflow phase described as launched.
63
+ expect(ctx.content).toContain("phase 1 (contract-scout, blast-radius-mapper, boundary-drafter)");
64
+ expect(ctx.content).toContain("phase 2 (builder)");
65
+ expect(ctx.content).toContain("phase 3 (security-verifier, contract-verifier, closed-loop-verifier)");
66
+ // points at the seam doc both bindings honor.
67
+ expect(ctx.content).toContain("matchmat-ship-SEAM.md");
68
+ });
69
+ it("also mirrors the Hybrid run order block into the topology SKILL.md", () => {
70
+ const skill = files.find((f) => f.path === ".claude/skills/matchmat-ship/SKILL.md");
71
+ expect(skill).toBeDefined();
72
+ expect(skill.content).toContain("## Hybrid run order");
73
+ expect(skill.content).toContain("matchmat-ship.workflow.js");
74
+ });
75
+ // (e) the observe-hook is in settings.json (host-layer concurrent observer).
76
+ it("emits a PostToolUse(Write) observe-blackboard hook in settings.json", () => {
77
+ const settings = files.find((f) => f.path === ".claude/settings.json");
78
+ expect(settings).toBeDefined();
79
+ const parsed = JSON.parse(settings.content);
80
+ const postToolUse = parsed.hooks?.PostToolUse;
81
+ expect(postToolUse, "PostToolUse hooks present").toBeDefined();
82
+ const observe = postToolUse.find((h) => h.matcher === "Write" && h.hooks.some((x) => x.command.includes("observe-blackboard.sh")));
83
+ expect(observe, "observe-blackboard PostToolUse(Write) hook present").toBeDefined();
84
+ });
85
+ it("emits the observe-blackboard.sh script the hook points at", () => {
86
+ const observe = find("observe-blackboard.sh");
87
+ expect(observe).toBeDefined();
88
+ expect(observe.path).toBe(".claude/skills/matchmat-ship/scripts/observe-blackboard.sh");
89
+ expect(observe.executable).toBe(true);
90
+ expect(observe.content).toContain("# AGENTOPOLOGY_STUB");
91
+ // documents the Blackboard root it watches.
92
+ expect(observe.content).toContain("workspace/");
93
+ });
94
+ });
95
+ describe("claude-code binding — non-hybrid topologies are unaffected", () => {
96
+ // A topology with no execution:workflow agent must not get any hybrid artifacts.
97
+ const plain = parse(`topology plain-pipe : [pipeline] {
98
+ roles { worker: "do the work" }
99
+ agent worker { role: worker phase: 1 prompt { Do the thing. } }
100
+ flow { worker -> worker }
101
+ }`);
102
+ const plainFiles = claudeCodeBinding.scaffold(plain);
103
+ it("still emits the agent AGENT.md (no workflow seam)", () => {
104
+ expect(plainFiles.find((f) => f.path === ".claude/agents/worker/AGENT.md")).toBeDefined();
105
+ });
106
+ it("emits no launch-*-workflow.sh stub", () => {
107
+ expect(plainFiles.find((f) => f.path.includes("launch-") && f.path.endsWith("-workflow.sh"))).toBeUndefined();
108
+ });
109
+ it("emits no Hybrid run order block", () => {
110
+ const ctx = plainFiles.find((f) => f.path === ".claude/CLAUDE.md");
111
+ if (ctx)
112
+ expect(ctx.content).not.toContain("## Hybrid run order");
113
+ });
114
+ it("emits no synthesized observe-blackboard hook (no Blackboard)", () => {
115
+ expect(plainFiles.find((f) => f.path.endsWith("observe-blackboard.sh"))).toBeUndefined();
116
+ });
117
+ });
118
+ describe("claude-code + claude-workflow — the two bindings AGREE on the seam", () => {
119
+ const hostFiles = claudeCodeBinding.scaffold(ast);
120
+ const wfFiles = claudeWorkflowBinding.scaffold(ast);
121
+ it("host omits builder/AGENT.md while the workflow.js OWNS builder", () => {
122
+ expect(hostFiles.find((f) => f.path === ".claude/agents/builder/AGENT.md")).toBeUndefined();
123
+ const wf = wfFiles.find((f) => f.path.endsWith(".workflow.js"));
124
+ expect(wf).toBeDefined();
125
+ expect(wf.content).toContain("{ phase: 2, agents: ['builder'] }");
126
+ });
127
+ it("both reference the same workflow.js filename", () => {
128
+ const wf = wfFiles.find((f) => f.path.endsWith(".workflow.js"));
129
+ expect(wf.path).toBe("matchmat-ship.workflow.js");
130
+ const ctx = hostFiles.find((f) => f.path === ".claude/CLAUDE.md");
131
+ expect(ctx.content).toContain("matchmat-ship.workflow.js");
132
+ });
133
+ it("both reference the same Blackboard workspace root and SEAM doc", () => {
134
+ const seam = wfFiles.find((f) => f.path.endsWith("-SEAM.md"));
135
+ const ctx = hostFiles.find((f) => f.path === ".claude/CLAUDE.md");
136
+ // workspace root
137
+ expect(seam.content).toContain("`workspace/`");
138
+ expect(ctx.content).toContain("`workspace/`");
139
+ // seam doc filename
140
+ expect(seam.path).toBe("matchmat-ship-SEAM.md");
141
+ expect(ctx.content).toContain("matchmat-ship-SEAM.md");
142
+ });
143
+ it("both use the same 'Host launches ... LIVE' run-order phrasing", () => {
144
+ const seam = wfFiles.find((f) => f.path.endsWith("-SEAM.md"));
145
+ const ctx = hostFiles.find((f) => f.path === ".claude/CLAUDE.md");
146
+ expect(seam.content).toContain("Host launches");
147
+ expect(ctx.content).toContain("Host launches");
148
+ expect(seam.content).toContain("observe those writes LIVE");
149
+ expect(ctx.content).toContain("observe those writes LIVE");
150
+ });
151
+ });
152
+ //# sourceMappingURL=claude-code-hybrid.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-code-hybrid.test.js","sourceRoot":"","sources":["../../../src/bindings/__tests__/claude-code-hybrid.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=claude-workflow.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-workflow.test.d.ts","sourceRoot":"","sources":["../../../src/bindings/__tests__/claude-workflow.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,204 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { readFileSync } from "node:fs";
3
+ import { fileURLToPath } from "node:url";
4
+ import path from "node:path";
5
+ import { parse } from "../../parser/index.js";
6
+ import { bindings, claudeWorkflowBinding } from "../index.js";
7
+ // ---------------------------------------------------------------------------
8
+ // Fixture: the dogfood topology (examples/matchmat-ship.at)
9
+ // ---------------------------------------------------------------------------
10
+ const here = path.dirname(fileURLToPath(import.meta.url));
11
+ const fixturePath = path.resolve(here, "../../../examples/matchmat-ship.at");
12
+ const source = readFileSync(fixturePath, "utf-8");
13
+ const ast = parse(source);
14
+ const files = claudeWorkflowBinding.scaffold(ast);
15
+ function find(suffix) {
16
+ return files.find((f) => f.path.endsWith(suffix));
17
+ }
18
+ describe("claude-workflow binding — registry", () => {
19
+ it("is registered under the 'claude-workflow' key with a matching name", () => {
20
+ expect(bindings["claude-workflow"]).toBeDefined();
21
+ expect(bindings["claude-workflow"].name).toBe("claude-workflow");
22
+ });
23
+ it("scaffold returns a non-empty array of GeneratedFile", () => {
24
+ expect(files.length).toBeGreaterThan(0);
25
+ for (const f of files) {
26
+ expect(f.path).toBeTruthy();
27
+ expect(typeof f.content).toBe("string");
28
+ }
29
+ });
30
+ });
31
+ describe("claude-workflow binding — workflow.js emission (matchmat-ship)", () => {
32
+ // (a) a *.workflow.js file is emitted
33
+ it("emits a <topology>.workflow.js file", () => {
34
+ const wf = find(".workflow.js");
35
+ expect(wf).toBeDefined();
36
+ expect(wf.path).toBe("matchmat-ship.workflow.js");
37
+ });
38
+ const wf = find(".workflow.js");
39
+ // (b) STRICT SEAM: meta.phases contains ONLY the workflow-marked phase (2 / builder).
40
+ it("contains `export const meta` as a pure literal with ONLY the workflow-marked phase", () => {
41
+ expect(wf.content).toContain("export const meta");
42
+ expect(wf.content).toContain("phases:");
43
+ // The meta literal must not contain computed/nondeterministic values
44
+ expect(wf.content).not.toContain("Date.now");
45
+ expect(wf.content).not.toContain("Math.random");
46
+ // Only phase 2 (builder) — not phase 1 or 3.
47
+ expect(wf.content).toContain("{ phase: 2, agents: ['builder'] }");
48
+ expect(wf.content).not.toContain("phase: 1");
49
+ expect(wf.content).not.toContain("phase: 3");
50
+ });
51
+ it("uses parallel(...) for the builder fan-out", () => {
52
+ expect(wf.content).toContain("parallel(");
53
+ });
54
+ it("uses phase() to title the workflow phase", () => {
55
+ expect(wf.content).toContain("phase('Phase 2')");
56
+ });
57
+ it("compiles ONLY the builder (scaled) phase with isolation:'worktree'", () => {
58
+ expect(wf.content).toContain("isolation: 'worktree'");
59
+ // builder has scale {max: 6} → deterministic Array.from fan-out, no random
60
+ expect(wf.content).toContain("Array.from({ length: 6 }");
61
+ expect(wf.content).toMatch(/label: `builder-\$\{i\}`/);
62
+ });
63
+ // STRICT SEAM: the host-side verifier phase (3) must NOT be in the workflow.js.
64
+ it("does NOT contain the host phase-1 agents (contract-scout, blast-radius-mapper, boundary-drafter)", () => {
65
+ expect(wf.content).not.toContain("contract-scout");
66
+ expect(wf.content).not.toContain("blast-radius-mapper");
67
+ expect(wf.content).not.toContain("'boundary-drafter'");
68
+ });
69
+ it("does NOT contain the host phase-3 verifier agents (security-verifier, etc.)", () => {
70
+ expect(wf.content).not.toContain("security-verifier");
71
+ expect(wf.content).not.toContain("contract-verifier");
72
+ expect(wf.content).not.toContain("closed-loop-verifier");
73
+ });
74
+ it("does NOT contain a verifier verdict schema (phase 3 is HOST-side)", () => {
75
+ // The verdict enum belongs to the phase-3 verifiers, which are host-side now.
76
+ expect(wf.content).not.toContain("verdict:");
77
+ });
78
+ it("embeds the builder's Blackboard read/write paths in its prompt (no filesystem)", () => {
79
+ // builder reads contract-delta/blast-radius/contracts-touched, writes build-report.
80
+ expect(wf.content).toContain("workspace/contract-delta.md");
81
+ expect(wf.content).toContain("workspace/build-report.md");
82
+ });
83
+ // STRICT SEAM: verify-gate is between phase 3 and ship-report (host) → NOT in the workflow.
84
+ it("does NOT contain the host-side verify-gate (it sits outside the workflow span)", () => {
85
+ expect(wf.content).not.toContain("bounce-back");
86
+ expect(wf.content).not.toContain("verify-gate");
87
+ expect(wf.content).not.toContain("for (let attempt");
88
+ });
89
+ // (d) the workflow.js does NOT contain the human node — neither as an agent nor a boundary block.
90
+ it("does NOT contain the human 'promote' node as an agent() call", () => {
91
+ expect(wf.content).not.toMatch(/agent\([^)]*label: 'promote'/);
92
+ // Strict seam: the human is host-side downstream — no in-script HUMAN BOUNDARY block.
93
+ expect(wf.content).not.toContain("HUMAN BOUNDARY");
94
+ // It is still surfaced loud as an UNREPRESENTABLE comment, though.
95
+ expect(wf.content).toContain("UNREPRESENTABLE: human 'promote'");
96
+ });
97
+ });
98
+ describe("claude-workflow binding — human split (matchmat-ship)", () => {
99
+ // (c) a human-split README is emitted (topology has a `human promote` node)
100
+ it("emits a <topology>-README.md documenting the human handoff", () => {
101
+ const readme = find("-README.md");
102
+ expect(readme).toBeDefined();
103
+ expect(readme.path).toBe("matchmat-ship-README.md");
104
+ expect(readme.content).toContain("promote");
105
+ expect(readme.content.toLowerCase()).toContain("human");
106
+ expect(readme.content.toLowerCase()).toContain("downstream");
107
+ });
108
+ it("notes regression is a separate downstream workflow", () => {
109
+ const readme = find("-README.md");
110
+ expect(readme.content.toLowerCase()).toContain("separate");
111
+ });
112
+ });
113
+ describe("claude-workflow binding — LOSSY report (matchmat-ship)", () => {
114
+ it("emits a <topology>-LOSSY-REPORT.md", () => {
115
+ const report = find("-LOSSY-REPORT.md");
116
+ expect(report).toBeDefined();
117
+ expect(report.path).toBe("matchmat-ship-LOSSY-REPORT.md");
118
+ });
119
+ it("classifies the human node as UNREPRESENTABLE", () => {
120
+ const report = find("-LOSSY-REPORT.md");
121
+ expect(report.content).toContain("UNREPRESENTABLE");
122
+ expect(report.content).toContain("human");
123
+ });
124
+ it("classifies the host-side verify-gate as LOSSY (not in the workflow.js)", () => {
125
+ const report = find("-LOSSY-REPORT.md");
126
+ expect(report.content).toContain("verify-gate");
127
+ expect(report.content).toContain("HOST-side");
128
+ });
129
+ it("classifies agent.scale as LOSSY", () => {
130
+ const report = find("-LOSSY-REPORT.md");
131
+ expect(report.content).toContain("LOSSY");
132
+ expect(report.content).toContain("agent.scale");
133
+ });
134
+ // STRICT SEAM: phases 1 & 3 are correct HOST phases, NOT 'folded-in lossy' entries.
135
+ it("does NOT contain 'execution:host' folded-in LOSSY entries (strict seam)", () => {
136
+ const report = find("-LOSSY-REPORT.md");
137
+ expect(report.content).not.toContain("execution:host");
138
+ expect(report.content).not.toContain("folded");
139
+ });
140
+ });
141
+ describe("claude-workflow binding — Blackboard seam contract (matchmat-ship)", () => {
142
+ it("emits a <topology>-SEAM.md describing the file-based hand-off", () => {
143
+ const seam = find("-SEAM.md");
144
+ expect(seam).toBeDefined();
145
+ expect(seam.path).toBe("matchmat-ship-SEAM.md");
146
+ });
147
+ it("documents the workspace root and per-agent reads/writes", () => {
148
+ const seam = find("-SEAM.md");
149
+ expect(seam.content).toContain("workspace/");
150
+ expect(seam.content).toContain("builder");
151
+ expect(seam.content).toContain("contract-delta.md");
152
+ });
153
+ it("states the host .claude/ files are emitted by the claude-code binding, not this one", () => {
154
+ const seam = find("-SEAM.md");
155
+ expect(seam.content).toContain("claude-code");
156
+ });
157
+ it("documents the strict run order: host phase 1 → launch workflow build → host phase 3/gate → human promote", () => {
158
+ const seam = find("-SEAM.md");
159
+ expect(seam.content).toContain("STRICT SEAM");
160
+ // The workflow rung is the build; host runs the surrounding phases.
161
+ expect(seam.content).toContain("Host launches `matchmat-ship.workflow.js`");
162
+ expect(seam.content).toContain("build rung");
163
+ expect(seam.content).toContain("phase 1 (contract-scout");
164
+ expect(seam.content).toContain("phase 3 (security-verifier");
165
+ expect(seam.content).toContain("human `promote`");
166
+ });
167
+ });
168
+ describe("claude-workflow binding — UNREPRESENTABLE never dropped silently", () => {
169
+ const wf = find(".workflow.js");
170
+ it("surfaces UNREPRESENTABLE primitives as in-script comments", () => {
171
+ expect(wf.content).toContain("// UNREPRESENTABLE:");
172
+ });
173
+ });
174
+ // ---------------------------------------------------------------------------
175
+ // Edge case: a topology with NO seam marker → no workflow.js, loud note
176
+ // ---------------------------------------------------------------------------
177
+ describe("claude-workflow binding — no execution:workflow marker", () => {
178
+ const NO_SEAM = `
179
+ topology no-seam : [pipeline] {
180
+ meta { version: "1.0.0" description: "no workflow phase" }
181
+ orchestrator { model: opus handles: [intake] }
182
+ action intake { kind: external source: "user" }
183
+ agent solo {
184
+ model: sonnet
185
+ phase: 1
186
+ tools: [Read, Write]
187
+ reads: ["workspace/in.md"]
188
+ writes: ["workspace/out.md"]
189
+ permissions: autonomous
190
+ }
191
+ flow { intake -> solo }
192
+ }
193
+ `;
194
+ const noSeamAst = parse(NO_SEAM);
195
+ const noSeamFiles = claudeWorkflowBinding.scaffold(noSeamAst);
196
+ it("emits no workflow.js but still emits a LOSSY report explaining why", () => {
197
+ const wf = noSeamFiles.find((f) => f.path.endsWith(".workflow.js"));
198
+ expect(wf).toBeUndefined();
199
+ const report = noSeamFiles.find((f) => f.path.endsWith("-LOSSY-REPORT.md"));
200
+ expect(report).toBeDefined();
201
+ expect(report.content).toContain("execution");
202
+ });
203
+ });
204
+ //# sourceMappingURL=claude-workflow.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-workflow.test.js","sourceRoot":"","sources":["../../../src/bindings/__tests__/claude-workflow.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Hybrid end-to-end test.
3
+ *
4
+ * Unit tests check each binding in isolation. THIS test compiles BOTH bindings
5
+ * from the SAME .at file and proves they COMPOSE into one coherent hybrid:
6
+ * - the host (claude-code) and the rung (claude-workflow) partition the agents
7
+ * with no overlap and no gap,
8
+ * - they agree on the seam (workflow filename, Blackboard root, SEAM doc),
9
+ * - the generated workflow.js is syntactically valid JavaScript,
10
+ * - nothing is silently dropped (the LOSSY report exists).
11
+ *
12
+ * This is the real "does the hybrid work end to end" gate.
13
+ */
14
+ export {};
15
+ //# sourceMappingURL=hybrid-e2e.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hybrid-e2e.test.d.ts","sourceRoot":"","sources":["../../../src/bindings/__tests__/hybrid-e2e.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG"}
@@ -0,0 +1,94 @@
1
+ /**
2
+ * Hybrid end-to-end test.
3
+ *
4
+ * Unit tests check each binding in isolation. THIS test compiles BOTH bindings
5
+ * from the SAME .at file and proves they COMPOSE into one coherent hybrid:
6
+ * - the host (claude-code) and the rung (claude-workflow) partition the agents
7
+ * with no overlap and no gap,
8
+ * - they agree on the seam (workflow filename, Blackboard root, SEAM doc),
9
+ * - the generated workflow.js is syntactically valid JavaScript,
10
+ * - nothing is silently dropped (the LOSSY report exists).
11
+ *
12
+ * This is the real "does the hybrid work end to end" gate.
13
+ */
14
+ import { describe, it, expect } from "vitest";
15
+ import { readFileSync, writeFileSync, rmSync } from "node:fs";
16
+ import { fileURLToPath } from "node:url";
17
+ import path from "node:path";
18
+ import os from "node:os";
19
+ import { spawnSync } from "node:child_process";
20
+ import { parse } from "../../parser/index.js";
21
+ import { claudeCodeBinding, claudeWorkflowBinding } from "../index.js";
22
+ import { seamFiles, isWorkflowSeamAgent, isHybridTopology } from "../lib/seam.js";
23
+ const here = path.dirname(fileURLToPath(import.meta.url));
24
+ const fixturePath = path.resolve(here, "../../../examples/matchmat-ship.at");
25
+ const ast = parse(readFileSync(fixturePath, "utf-8"));
26
+ const name = ast.topology.name;
27
+ const hostFiles = claudeCodeBinding.scaffold(ast);
28
+ const wfFiles = claudeWorkflowBinding.scaffold(ast);
29
+ const hostPaths = hostFiles.map((f) => f.path);
30
+ const wfPaths = wfFiles.map((f) => f.path);
31
+ const agents = ast.nodes.filter((n) => n.type === "agent");
32
+ const wfAgents = agents.filter(isWorkflowSeamAgent).map((a) => a.id);
33
+ const hostAgents = agents.filter((a) => !isWorkflowSeamAgent(a)).map((a) => a.id);
34
+ describe("hybrid e2e: matchmat-ship.at → claude-code + claude-workflow", () => {
35
+ it("the fixture is a hybrid topology", () => {
36
+ expect(isHybridTopology(ast)).toBe(true);
37
+ expect(wfAgents.length).toBeGreaterThan(0);
38
+ expect(hostAgents.length).toBeGreaterThan(0);
39
+ });
40
+ it("agents partition cleanly: workflow agents NOT in host, host agents NOT in workflow.js", () => {
41
+ const wfScript = wfFiles.find((f) => f.path === seamFiles.workflowScript(name)).content;
42
+ // workflow-marked agents must NOT have a host AGENT.md
43
+ for (const id of wfAgents) {
44
+ expect(hostPaths).not.toContain(`.claude/agents/${id}/AGENT.md`);
45
+ expect(wfScript).toContain(id); // and they DO appear in the rung
46
+ }
47
+ // host agents must have a host AGENT.md and must NOT be agent() calls in the rung
48
+ for (const id of hostAgents) {
49
+ expect(hostPaths).toContain(`.claude/agents/${id}/AGENT.md`);
50
+ }
51
+ });
52
+ it("both halves agree on the seam (filename, SEAM doc, Blackboard root)", () => {
53
+ const wfFile = seamFiles.workflowScript(name);
54
+ const seamDoc = seamFiles.seamDoc(name);
55
+ // workflow binding emits the rung + the SEAM contract + the LOSSY report
56
+ expect(wfPaths).toContain(wfFile);
57
+ expect(wfPaths).toContain(seamDoc);
58
+ expect(wfPaths).toContain(seamFiles.lossyDoc(name));
59
+ // host references the same workflow filename + seam doc in its CLAUDE.md
60
+ const claudeMd = hostFiles.find((f) => f.path === ".claude/CLAUDE.md").content;
61
+ expect(claudeMd).toContain(wfFile);
62
+ expect(claudeMd).toContain(seamDoc);
63
+ });
64
+ it("the generated workflow.js is syntactically valid JavaScript (ESM)", () => {
65
+ const wfScript = wfFiles.find((f) => f.path === seamFiles.workflowScript(name)).content;
66
+ // The rung is an ES module (export const meta / export default). vm.Script is
67
+ // CommonJS-mode and rejects `export`, so validate via `node --check` on a temp
68
+ // .mjs file (the real syntax gate; we never execute it).
69
+ const tmp = path.join(os.tmpdir(), `at-e2e-${process.pid}.mjs`);
70
+ writeFileSync(tmp, wfScript);
71
+ try {
72
+ const res = spawnSync("node", ["--check", tmp], { encoding: "utf-8" });
73
+ expect(res.status, res.stderr).toBe(0);
74
+ }
75
+ finally {
76
+ rmSync(tmp, { force: true });
77
+ }
78
+ // sanity: pure-literal meta + at least one parallel fan-out
79
+ expect(wfScript).toContain("export const meta");
80
+ expect(wfScript).toMatch(/parallel\(/);
81
+ });
82
+ it("the host wires concurrent observability over the Blackboard (the hybrid's point)", () => {
83
+ const settings = hostFiles.find((f) => f.path === ".claude/settings.json");
84
+ expect(settings).toBeDefined();
85
+ // a PostToolUse observer must exist when the topology has a Blackboard
86
+ expect(settings.content).toMatch(/PostToolUse|observe/i);
87
+ });
88
+ it("nothing is silently dropped: the LOSSY report names the human split", () => {
89
+ const lossy = wfFiles.find((f) => f.path === seamFiles.lossyDoc(name)).content;
90
+ expect(lossy).toMatch(/human/i);
91
+ expect(lossy).toMatch(/UNREPRESENTABLE/);
92
+ });
93
+ });
94
+ //# sourceMappingURL=hybrid-e2e.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hybrid-e2e.test.js","sourceRoot":"","sources":["../../../src/bindings/__tests__/hybrid-e2e.test.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"claude-code.d.ts","sourceRoot":"","sources":["../../src/bindings/claude-code.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAuBH,OAAO,KAAK,EAAE,aAAa,EAAiB,MAAM,YAAY,CAAC;AAs8E/D,kEAAkE;AAClE,eAAO,MAAM,iBAAiB,EAAE,aA0F/B,CAAC"}
1
+ {"version":3,"file":"claude-code.d.ts","sourceRoot":"","sources":["../../src/bindings/claude-code.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAuBH,OAAO,KAAK,EAAE,aAAa,EAAiB,MAAM,YAAY,CAAC;AA0xF/D,kEAAkE;AAClE,eAAO,MAAM,iBAAiB,EAAE,aAkG/B,CAAC"}