agentopology 0.5.2 → 0.7.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 +5 -5
- package/dist/__tests__/e2e/compile.test.d.ts +12 -0
- package/dist/__tests__/e2e/compile.test.d.ts.map +1 -0
- package/dist/__tests__/e2e/compile.test.js +219 -0
- package/dist/__tests__/e2e/compile.test.js.map +1 -0
- package/dist/__tests__/e2e/roundtrip.test.d.ts +16 -0
- package/dist/__tests__/e2e/roundtrip.test.d.ts.map +1 -0
- package/dist/__tests__/e2e/roundtrip.test.js +178 -0
- package/dist/__tests__/e2e/roundtrip.test.js.map +1 -0
- package/dist/__tests__/e2e/scaffold-owns.test.d.ts +10 -0
- package/dist/__tests__/e2e/scaffold-owns.test.d.ts.map +1 -0
- package/dist/__tests__/e2e/scaffold-owns.test.js +163 -0
- package/dist/__tests__/e2e/scaffold-owns.test.js.map +1 -0
- package/dist/__tests__/e2e/sync-cycle.test.d.ts +10 -0
- package/dist/__tests__/e2e/sync-cycle.test.d.ts.map +1 -0
- package/dist/__tests__/e2e/sync-cycle.test.js +49 -0
- package/dist/__tests__/e2e/sync-cycle.test.js.map +1 -0
- package/dist/__tests__/global-setup.d.ts +7 -0
- package/dist/__tests__/global-setup.d.ts.map +1 -0
- package/dist/__tests__/global-setup.js +16 -0
- package/dist/__tests__/global-setup.js.map +1 -0
- package/dist/__tests__/live/claude-code.live.test.d.ts +20 -0
- package/dist/__tests__/live/claude-code.live.test.d.ts.map +1 -0
- package/dist/__tests__/live/claude-code.live.test.js +198 -0
- package/dist/__tests__/live/claude-code.live.test.js.map +1 -0
- package/dist/__tests__/live/zz-debug.test.d.ts +2 -0
- package/dist/__tests__/live/zz-debug.test.d.ts.map +1 -0
- package/dist/__tests__/live/zz-debug.test.js +4 -0
- package/dist/__tests__/live/zz-debug.test.js.map +1 -0
- package/dist/__tests__/open-findings.test.d.ts +10 -0
- package/dist/__tests__/open-findings.test.d.ts.map +1 -0
- package/dist/__tests__/open-findings.test.js +15 -0
- package/dist/__tests__/open-findings.test.js.map +1 -0
- package/dist/__tests__/spec-testing-sync.test.d.ts +10 -0
- package/dist/__tests__/spec-testing-sync.test.d.ts.map +1 -0
- package/dist/__tests__/spec-testing-sync.test.js +57 -0
- package/dist/__tests__/spec-testing-sync.test.js.map +1 -0
- package/dist/bindings/__tests__/bindings.test.js +19 -19
- package/dist/bindings/__tests__/bindings.test.js.map +1 -1
- package/dist/bindings/__tests__/claude-code-hybrid.test.js +5 -5
- package/dist/bindings/__tests__/claude-code-hybrid.test.js.map +1 -1
- package/dist/bindings/__tests__/hook-command.test.d.ts +9 -0
- package/dist/bindings/__tests__/hook-command.test.d.ts.map +1 -0
- package/dist/bindings/__tests__/hook-command.test.js +88 -0
- package/dist/bindings/__tests__/hook-command.test.js.map +1 -0
- package/dist/bindings/__tests__/hybrid-e2e.test.js +1 -1
- package/dist/bindings/__tests__/hybrid-e2e.test.js.map +1 -1
- package/dist/bindings/__tests__/mod-plugin.test.d.ts +9 -0
- package/dist/bindings/__tests__/mod-plugin.test.d.ts.map +1 -0
- package/dist/bindings/__tests__/mod-plugin.test.js +164 -0
- package/dist/bindings/__tests__/mod-plugin.test.js.map +1 -0
- package/dist/bindings/claude-code.d.ts +50 -1
- package/dist/bindings/claude-code.d.ts.map +1 -1
- package/dist/bindings/claude-code.js +636 -231
- package/dist/bindings/claude-code.js.map +1 -1
- package/dist/bindings/index.d.ts +7 -0
- package/dist/bindings/index.d.ts.map +1 -1
- package/dist/bindings/index.js +26 -7
- package/dist/bindings/index.js.map +1 -1
- package/dist/bindings/lib/prompt-fence.d.ts +22 -0
- package/dist/bindings/lib/prompt-fence.d.ts.map +1 -0
- package/dist/bindings/lib/prompt-fence.js +29 -0
- package/dist/bindings/lib/prompt-fence.js.map +1 -0
- package/dist/bindings/types.d.ts +6 -0
- package/dist/bindings/types.d.ts.map +1 -1
- package/dist/bindings/types.js.map +1 -1
- package/dist/cli/__tests__/cli.test.d.ts +1 -1
- package/dist/cli/__tests__/cli.test.js +1 -1
- package/dist/cli/index.js +124 -76
- package/dist/cli/index.js.map +1 -1
- package/dist/docs/content.d.ts.map +1 -1
- package/dist/docs/content.js +39 -3
- package/dist/docs/content.js.map +1 -1
- package/dist/docs/teach.d.ts.map +1 -1
- package/dist/docs/teach.js +46 -0
- package/dist/docs/teach.js.map +1 -1
- package/dist/import/__tests__/import.test.js +21 -9
- package/dist/import/__tests__/import.test.js.map +1 -1
- package/dist/import/claude-code.d.ts.map +1 -1
- package/dist/import/claude-code.js +128 -44
- package/dist/import/claude-code.js.map +1 -1
- package/dist/import/serializer.d.ts.map +1 -1
- package/dist/import/serializer.js +10 -0
- package/dist/import/serializer.js.map +1 -1
- package/dist/parser/__tests__/mod-hooks.test.d.ts +10 -0
- package/dist/parser/__tests__/mod-hooks.test.d.ts.map +1 -0
- package/dist/parser/__tests__/mod-hooks.test.js +136 -0
- package/dist/parser/__tests__/mod-hooks.test.js.map +1 -0
- package/dist/parser/ast.d.ts +29 -2
- package/dist/parser/ast.d.ts.map +1 -1
- package/dist/parser/ast.js.map +1 -1
- package/dist/parser/index.d.ts +6 -1
- package/dist/parser/index.d.ts.map +1 -1
- package/dist/parser/index.js +102 -25
- package/dist/parser/index.js.map +1 -1
- package/dist/parser/paths.d.ts +15 -0
- package/dist/parser/paths.d.ts.map +1 -0
- package/dist/parser/paths.js +34 -0
- package/dist/parser/paths.js.map +1 -0
- package/dist/parser/run.d.ts +45 -0
- package/dist/parser/run.d.ts.map +1 -0
- package/dist/parser/run.js +91 -0
- package/dist/parser/run.js.map +1 -0
- package/dist/parser/validator.d.ts +12 -0
- package/dist/parser/validator.d.ts.map +1 -1
- package/dist/parser/validator.js +268 -2
- package/dist/parser/validator.js.map +1 -1
- package/dist/scaffold/__tests__/safety.test.d.ts +11 -0
- package/dist/scaffold/__tests__/safety.test.d.ts.map +1 -0
- package/dist/scaffold/__tests__/safety.test.js +184 -0
- package/dist/scaffold/__tests__/safety.test.js.map +1 -0
- package/dist/scaffold/__tests__/scaffold.test.js +2 -1
- package/dist/scaffold/__tests__/scaffold.test.js.map +1 -1
- package/dist/scaffold/__tests__/settings-merge.test.js +40 -9
- package/dist/scaffold/__tests__/settings-merge.test.js.map +1 -1
- package/dist/scaffold/diff.d.ts +17 -0
- package/dist/scaffold/diff.d.ts.map +1 -0
- package/dist/scaffold/diff.js +66 -0
- package/dist/scaffold/diff.js.map +1 -0
- package/dist/scaffold/incremental.d.ts +49 -13
- package/dist/scaffold/incremental.d.ts.map +1 -1
- package/dist/scaffold/incremental.js +235 -95
- package/dist/scaffold/incremental.js.map +1 -1
- package/dist/scaffold/manifest.d.ts +8 -1
- package/dist/scaffold/manifest.d.ts.map +1 -1
- package/dist/scaffold/manifest.js +32 -8
- package/dist/scaffold/manifest.js.map +1 -1
- package/dist/scaffold/merge.d.ts +15 -4
- package/dist/scaffold/merge.d.ts.map +1 -1
- package/dist/scaffold/merge.js +123 -18
- package/dist/scaffold/merge.js.map +1 -1
- package/dist/scaffold/types.d.ts +17 -0
- package/dist/scaffold/types.d.ts.map +1 -1
- package/dist/sync/index.d.ts +1 -0
- package/dist/sync/index.d.ts.map +1 -1
- package/dist/sync/index.js +40 -2
- package/dist/sync/index.js.map +1 -1
- package/package.json +1 -1
- package/spec/grammar.md +24 -5
- package/spec/testing.md +85 -0
- package/spec/validation.md +8 -2
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* End to end: scaffold only changes what it owns.
|
|
3
|
+
*
|
|
4
|
+
* Each test runs the built CLI as a user would, against a temporary project
|
|
5
|
+
* that holds the hazards a real harness hit on 2026-10-28. Test names carry
|
|
6
|
+
* the guarantee id from spec/testing.md; spec-testing-sync.test.ts fails if a
|
|
7
|
+
* guarantee there has no test here or elsewhere.
|
|
8
|
+
*/
|
|
9
|
+
import { describe, it, expect, beforeEach, afterEach } from "vitest";
|
|
10
|
+
import { execFileSync } from "node:child_process";
|
|
11
|
+
import * as fs from "node:fs";
|
|
12
|
+
import * as os from "node:os";
|
|
13
|
+
import { resolve, dirname, join } from "node:path";
|
|
14
|
+
import { fileURLToPath } from "node:url";
|
|
15
|
+
const root = resolve(dirname(fileURLToPath(import.meta.url)), "../../..");
|
|
16
|
+
const CLI = resolve(root, "dist/cli/index.js");
|
|
17
|
+
const FIXTURE = resolve(dirname(fileURLToPath(import.meta.url)), "fixtures/hazards.at");
|
|
18
|
+
function cli(args) {
|
|
19
|
+
try {
|
|
20
|
+
const out = execFileSync(process.execPath, [CLI, ...args], {
|
|
21
|
+
encoding: "utf8",
|
|
22
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
23
|
+
});
|
|
24
|
+
return { out, code: 0 };
|
|
25
|
+
}
|
|
26
|
+
catch (err) {
|
|
27
|
+
const e = err;
|
|
28
|
+
return { out: `${e.stdout ?? ""}${e.stderr ?? ""}`, code: e.status ?? 1 };
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
let tmp;
|
|
32
|
+
let project;
|
|
33
|
+
let otherRepo;
|
|
34
|
+
let at;
|
|
35
|
+
const file = (rel) => join(project, rel);
|
|
36
|
+
const read = (rel) => fs.readFileSync(file(rel), "utf-8");
|
|
37
|
+
const put = (rel, content) => {
|
|
38
|
+
fs.mkdirSync(dirname(file(rel)), { recursive: true });
|
|
39
|
+
fs.writeFileSync(file(rel), content);
|
|
40
|
+
};
|
|
41
|
+
const scaffold = (...extra) => cli(["scaffold", at, "--target", "claude-code", "--output", project, ...extra]);
|
|
42
|
+
const USER_SETTINGS = {
|
|
43
|
+
permissions: { ask: ["Bash(git push:*)"], defaultMode: "acceptEdits" },
|
|
44
|
+
hooks: { PreToolUse: [{ matcher: "Bash", hooks: [{ type: "command", command: "bash ./my-guard.sh" }] }] },
|
|
45
|
+
};
|
|
46
|
+
beforeEach(() => {
|
|
47
|
+
tmp = fs.mkdtempSync(join(os.tmpdir(), "at-e2e-"));
|
|
48
|
+
project = join(tmp, "project");
|
|
49
|
+
otherRepo = join(tmp, "other-repo");
|
|
50
|
+
at = join(tmp, "hazards.at");
|
|
51
|
+
fs.copyFileSync(FIXTURE, at);
|
|
52
|
+
// A hand-written skill, a skill linked from another repository, and the
|
|
53
|
+
// user's own settings — what the content repo actually had.
|
|
54
|
+
put(".claude/skills/story/SKILL.md", "REAL STORY SKILL\n");
|
|
55
|
+
fs.mkdirSync(join(otherRepo, "the-book"), { recursive: true });
|
|
56
|
+
fs.writeFileSync(join(otherRepo, "the-book/SKILL.md"), "OTHER REPO BOOK\n");
|
|
57
|
+
fs.symlinkSync(join(otherRepo, "the-book"), file(".claude/skills/the-book"));
|
|
58
|
+
put(".claude/settings.json", JSON.stringify(USER_SETTINGS, null, 2));
|
|
59
|
+
});
|
|
60
|
+
afterEach(() => {
|
|
61
|
+
fs.rmSync(tmp, { recursive: true, force: true });
|
|
62
|
+
});
|
|
63
|
+
describe("scaffold only changes what it owns (e2e)", () => {
|
|
64
|
+
it("[G1] the first scaffold keeps a file it did not create", () => {
|
|
65
|
+
const { out, code } = scaffold();
|
|
66
|
+
expect(code).toBe(0);
|
|
67
|
+
expect(read(".claude/skills/story/SKILL.md")).toBe("REAL STORY SKILL\n");
|
|
68
|
+
expect(out).toContain("exists, not created by scaffold — kept");
|
|
69
|
+
expect(fs.existsSync(file(".claude/agents/writer/AGENT.md"))).toBe(true);
|
|
70
|
+
});
|
|
71
|
+
it("[G2] never writes through a symlink, even with --force", () => {
|
|
72
|
+
scaffold("--force");
|
|
73
|
+
expect(fs.readFileSync(join(otherRepo, "the-book/SKILL.md"), "utf-8")).toBe("OTHER REPO BOOK\n");
|
|
74
|
+
});
|
|
75
|
+
it("[G3] keeps the user's hooks, ask rules and defaultMode across runs", () => {
|
|
76
|
+
scaffold();
|
|
77
|
+
scaffold();
|
|
78
|
+
const settings = JSON.parse(read(".claude/settings.json"));
|
|
79
|
+
expect(settings.permissions.ask).toEqual(["Bash(git push:*)"]);
|
|
80
|
+
expect(settings.permissions.defaultMode).toBe("acceptEdits");
|
|
81
|
+
expect(JSON.stringify(settings.hooks)).toContain("my-guard.sh");
|
|
82
|
+
expect(settings.permissions.allow).toContain("Read");
|
|
83
|
+
});
|
|
84
|
+
it("[C1] --dry-run shows what a config merge would change in settings.json", () => {
|
|
85
|
+
const { out } = scaffold("--dry-run");
|
|
86
|
+
const block = out.slice(out.indexOf(".claude/settings.json"));
|
|
87
|
+
// the topology's own allow rules, added beside the user's
|
|
88
|
+
expect(block).toMatch(/\+ permissions\.allow: \[/);
|
|
89
|
+
// and nothing of the user's is removed
|
|
90
|
+
expect(block).not.toMatch(/^\s+- /m);
|
|
91
|
+
expect(read(".claude/settings.json")).toBe(JSON.stringify(USER_SETTINGS, null, 2));
|
|
92
|
+
});
|
|
93
|
+
it("[G4] a second run changes nothing", () => {
|
|
94
|
+
scaffold();
|
|
95
|
+
const { out } = scaffold();
|
|
96
|
+
expect(out).toMatch(/ 0 created, 0 updated, \d+ unchanged/);
|
|
97
|
+
});
|
|
98
|
+
it("[G5] --dry-run writes nothing", () => {
|
|
99
|
+
const before = fs.readdirSync(project, { recursive: true }).length;
|
|
100
|
+
expect(scaffold("--dry-run").code).toBe(0);
|
|
101
|
+
expect(fs.readdirSync(project, { recursive: true }).length).toBe(before);
|
|
102
|
+
});
|
|
103
|
+
it("[G6] prose in a gate's run fails validate and scaffold, and nothing is written", () => {
|
|
104
|
+
const prose = "pxframes gate mean >= 3.85, no frame < 3; frames 0.0 / 0.5 / 3.0 s differ";
|
|
105
|
+
fs.writeFileSync(at, fs.readFileSync(at, "utf-8").replace('run: "scripts/check-quality.sh"', `run: "${prose}"`));
|
|
106
|
+
const v = cli(["validate", at]);
|
|
107
|
+
expect(v.code).toBe(1);
|
|
108
|
+
expect(v.out).toContain("[V96]");
|
|
109
|
+
const s = scaffold();
|
|
110
|
+
expect(s.code).toBe(1);
|
|
111
|
+
expect(s.out).toContain("Nothing was written");
|
|
112
|
+
expect(fs.existsSync(file(".claude/agents"))).toBe(false);
|
|
113
|
+
});
|
|
114
|
+
it("[G7] an edited file scaffold owns is kept on the next run", () => {
|
|
115
|
+
scaffold();
|
|
116
|
+
put(".claude/rules/hazards.md", read(".claude/rules/hazards.md") + "my own note\n");
|
|
117
|
+
const { out } = scaffold();
|
|
118
|
+
expect(read(".claude/rules/hazards.md")).toContain("my own note");
|
|
119
|
+
expect(out).toContain(".claude/rules/hazards.md (user edited — kept)");
|
|
120
|
+
});
|
|
121
|
+
it("[G8] --prune removes untouched leftovers and keeps edited ones", () => {
|
|
122
|
+
scaffold();
|
|
123
|
+
const wrapper = ".claude/skills/hazards/scripts/gate-quality-check.sh";
|
|
124
|
+
const check = ".claude/skills/hazards/scripts/check-quality.sh";
|
|
125
|
+
expect(fs.existsSync(file(wrapper))).toBe(true);
|
|
126
|
+
put(check, "#!/bin/bash\n# my real check\n");
|
|
127
|
+
// Rename the gate and its script: both old files are now leftovers.
|
|
128
|
+
fs.writeFileSync(at, fs.readFileSync(at, "utf-8")
|
|
129
|
+
.replace("gate quality-check {", "gate quality-check-v2 {")
|
|
130
|
+
.replace('run: "scripts/check-quality.sh"', 'run: "scripts/check-v2.sh"'));
|
|
131
|
+
const { code, out } = scaffold("--prune");
|
|
132
|
+
expect(code, out).toBe(0);
|
|
133
|
+
expect(fs.existsSync(file(wrapper))).toBe(false);
|
|
134
|
+
expect(read(check)).toContain("my real check");
|
|
135
|
+
expect(out).toContain("no longer generated, but edited — kept");
|
|
136
|
+
});
|
|
137
|
+
it("[G9] a second topology in the same project keeps its own manifest", () => {
|
|
138
|
+
scaffold();
|
|
139
|
+
const other = join(tmp, "other.at");
|
|
140
|
+
fs.writeFileSync(other, fs.readFileSync(at, "utf-8").replace("topology hazards :", "topology other :"));
|
|
141
|
+
cli(["scaffold", other, "--target", "claude-code", "--output", project]);
|
|
142
|
+
expect(fs.existsSync(file(".claude/.scaffold-manifest.json"))).toBe(true);
|
|
143
|
+
expect(fs.existsSync(file(".claude/.scaffold-manifest.other.at.json"))).toBe(true);
|
|
144
|
+
// The first topology still owns its files: a rerun changes nothing.
|
|
145
|
+
expect(scaffold().out).toMatch(/ 0 created, 0 updated/);
|
|
146
|
+
});
|
|
147
|
+
});
|
|
148
|
+
describe("every example compiles to files Claude Code can load", () => {
|
|
149
|
+
const examples = fs.readdirSync(resolve(root, "examples")).filter((f) => f.endsWith(".at"));
|
|
150
|
+
it.each(examples)("[G10] %s: no ${…} reference reaches settings env", (name) => {
|
|
151
|
+
const out = join(tmp, name);
|
|
152
|
+
expect(cli(["scaffold", resolve(root, "examples", name), "--target", "claude-code", "--output", out]).code).toBe(0);
|
|
153
|
+
const settingsPath = join(out, ".claude/settings.json");
|
|
154
|
+
if (!fs.existsSync(settingsPath))
|
|
155
|
+
return;
|
|
156
|
+
const env = JSON.parse(fs.readFileSync(settingsPath, "utf-8")).env ?? {};
|
|
157
|
+
for (const [k, v] of Object.entries(env)) {
|
|
158
|
+
expect(String(v), `env.${k}`).not.toContain("${");
|
|
159
|
+
expect(k).not.toMatch(/^#/);
|
|
160
|
+
}
|
|
161
|
+
});
|
|
162
|
+
});
|
|
163
|
+
//# sourceMappingURL=scaffold-owns.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scaffold-owns.test.js","sourceRoot":"","sources":["../../../src/__tests__/e2e/scaffold-owns.test.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACrE,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC;AAC1E,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,EAAE,mBAAmB,CAAC,CAAC;AAC/C,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,qBAAqB,CAAC,CAAC;AAExF,SAAS,GAAG,CAAC,IAAc;IACzB,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,YAAY,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,EAAE;YACzD,QAAQ,EAAE,MAAM;YAChB,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC;SAClC,CAAC,CAAC;QACH,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;IAC1B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,CAAC,GAAG,GAA4D,CAAC;QACvE,OAAO,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,MAAM,IAAI,EAAE,GAAG,CAAC,CAAC,MAAM,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;IAC5E,CAAC;AACH,CAAC;AAED,IAAI,GAAW,CAAC;AAChB,IAAI,OAAe,CAAC;AACpB,IAAI,SAAiB,CAAC;AACtB,IAAI,EAAU,CAAC;AAEf,MAAM,IAAI,GAAG,CAAC,GAAW,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;AACjD,MAAM,IAAI,GAAG,CAAC,GAAW,EAAE,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC;AAClE,MAAM,GAAG,GAAG,CAAC,GAAW,EAAE,OAAe,EAAE,EAAE;IAC3C,EAAE,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACtD,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC;AACvC,CAAC,CAAC;AACF,MAAM,QAAQ,GAAG,CAAC,GAAG,KAAe,EAAE,EAAE,CACtC,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE,EAAE,UAAU,EAAE,aAAa,EAAE,UAAU,EAAE,OAAO,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC;AAElF,MAAM,aAAa,GAAG;IACpB,WAAW,EAAE,EAAE,GAAG,EAAE,CAAC,kBAAkB,CAAC,EAAE,WAAW,EAAE,aAAa,EAAE;IACtE,KAAK,EAAE,EAAE,UAAU,EAAE,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,oBAAoB,EAAE,CAAC,EAAE,CAAC,EAAE;CAC1G,CAAC;AAEF,UAAU,CAAC,GAAG,EAAE;IACd,GAAG,GAAG,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,SAAS,CAAC,CAAC,CAAC;IACnD,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;IAC/B,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;IACpC,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;IAC7B,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IAE7B,wEAAwE;IACxE,4DAA4D;IAC5D,GAAG,CAAC,+BAA+B,EAAE,oBAAoB,CAAC,CAAC;IAC3D,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,EAAE,UAAU,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC/D,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,SAAS,EAAE,mBAAmB,CAAC,EAAE,mBAAmB,CAAC,CAAC;IAC5E,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,SAAS,EAAE,UAAU,CAAC,EAAE,IAAI,CAAC,yBAAyB,CAAC,CAAC,CAAC;IAC7E,GAAG,CAAC,uBAAuB,EAAE,IAAI,CAAC,SAAS,CAAC,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AACvE,CAAC,CAAC,CAAC;AAEH,SAAS,CAAC,GAAG,EAAE;IACb,EAAE,CAAC,MAAM,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;AACnD,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,0CAA0C,EAAE,GAAG,EAAE;IACxD,EAAE,CAAC,wDAAwD,EAAE,GAAG,EAAE;QAChE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,QAAQ,EAAE,CAAC;QACjC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACrB,MAAM,CAAC,IAAI,CAAC,+BAA+B,CAAC,CAAC,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;QACzE,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,wCAAwC,CAAC,CAAC;QAChE,MAAM,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,gCAAgC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC3E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wDAAwD,EAAE,GAAG,EAAE;QAChE,QAAQ,CAAC,SAAS,CAAC,CAAC;QACpB,MAAM,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,SAAS,EAAE,mBAAmB,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;IACnG,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oEAAoE,EAAE,GAAG,EAAE;QAC5E,QAAQ,EAAE,CAAC;QACX,QAAQ,EAAE,CAAC;QACX,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC,CAAC;QAC3D,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC;QAC/D,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QAC7D,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;QAChE,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IACvD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wEAAwE,EAAE,GAAG,EAAE;QAChF,MAAM,EAAE,GAAG,EAAE,GAAG,QAAQ,CAAC,WAAW,CAAC,CAAC;QACtC,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,uBAAuB,CAAC,CAAC,CAAC;QAC9D,0DAA0D;QAC1D,MAAM,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,2BAA2B,CAAC,CAAC;QACnD,uCAAuC;QACvC,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QACrC,MAAM,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IACrF,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mCAAmC,EAAE,GAAG,EAAE;QAC3C,QAAQ,EAAE,CAAC;QACX,MAAM,EAAE,GAAG,EAAE,GAAG,QAAQ,EAAE,CAAC;QAC3B,MAAM,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,sCAAsC,CAAC,CAAC;IAC9D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+BAA+B,EAAE,GAAG,EAAE;QACvC,MAAM,MAAM,GAAG,EAAE,CAAC,WAAW,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC;QACnE,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC3C,MAAM,CAAC,EAAE,CAAC,WAAW,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC3E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gFAAgF,EAAE,GAAG,EAAE;QACxF,MAAM,KAAK,GAAG,2EAA2E,CAAC;QAC1F,EAAE,CAAC,aAAa,CAAC,EAAE,EAAE,EAAE,CAAC,YAAY,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC,OAAO,CAAC,iCAAiC,EAAE,SAAS,KAAK,GAAG,CAAC,CAAC,CAAC;QACjH,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,CAAC;QAChC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACvB,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QACjC,MAAM,CAAC,GAAG,QAAQ,EAAE,CAAC;QACrB,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACvB,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,qBAAqB,CAAC,CAAC;QAC/C,MAAM,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC5D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2DAA2D,EAAE,GAAG,EAAE;QACnE,QAAQ,EAAE,CAAC;QACX,GAAG,CAAC,0BAA0B,EAAE,IAAI,CAAC,0BAA0B,CAAC,GAAG,eAAe,CAAC,CAAC;QACpF,MAAM,EAAE,GAAG,EAAE,GAAG,QAAQ,EAAE,CAAC;QAC3B,MAAM,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;QAClE,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,+CAA+C,CAAC,CAAC;IACzE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gEAAgE,EAAE,GAAG,EAAE;QACxE,QAAQ,EAAE,CAAC;QACX,MAAM,OAAO,GAAG,sDAAsD,CAAC;QACvE,MAAM,KAAK,GAAG,iDAAiD,CAAC;QAChE,MAAM,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAChD,GAAG,CAAC,KAAK,EAAE,gCAAgC,CAAC,CAAC;QAC7C,oEAAoE;QACpE,EAAE,CAAC,aAAa,CACd,EAAE,EACF,EAAE,CAAC,YAAY,CAAC,EAAE,EAAE,OAAO,CAAC;aACzB,OAAO,CAAC,sBAAsB,EAAE,yBAAyB,CAAC;aAC1D,OAAO,CAAC,iCAAiC,EAAE,4BAA4B,CAAC,CAC5E,CAAC;QACF,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC;QAC1C,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC1B,MAAM,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACjD,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC;QAC/C,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,wCAAwC,CAAC,CAAC;IAClE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mEAAmE,EAAE,GAAG,EAAE;QAC3E,QAAQ,EAAE,CAAC;QACX,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;QACpC,EAAE,CAAC,aAAa,CAAC,KAAK,EAAE,EAAE,CAAC,YAAY,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC,OAAO,CAAC,oBAAoB,EAAE,kBAAkB,CAAC,CAAC,CAAC;QACxG,GAAG,CAAC,CAAC,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC,CAAC;QACzE,MAAM,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,iCAAiC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC1E,MAAM,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,0CAA0C,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACnF,oEAAoE;QACpE,MAAM,CAAC,QAAQ,EAAE,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,uBAAuB,CAAC,CAAC;IAC1D,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,sDAAsD,EAAE,GAAG,EAAE;IACpE,MAAM,QAAQ,GAAG,EAAE,CAAC,WAAW,CAAC,OAAO,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;IAE5F,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,kDAAkD,EAAE,CAAC,IAAI,EAAE,EAAE;QAC7E,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QAC5B,MAAM,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,OAAO,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,CAAC,EAAE,UAAU,EAAE,aAAa,EAAE,UAAU,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACpH,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,EAAE,uBAAuB,CAAC,CAAC;QACxD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC;YAAE,OAAO;QACzC,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,IAAI,EAAE,CAAC;QACzE,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;YACzC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;YAClD,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC9B,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* scaffold → sync is a fixed point: with no edits the .at comes back
|
|
3
|
+
* unchanged, and an edit comes back once.
|
|
4
|
+
*
|
|
5
|
+
* Sync used to copy everything from "## Instructions" to the next heading it
|
|
6
|
+
* knew, so generated sections and headings scaffold had pushed one level down
|
|
7
|
+
* went into the .at: the prompt grew on every cycle (N11).
|
|
8
|
+
*/
|
|
9
|
+
export {};
|
|
10
|
+
//# sourceMappingURL=sync-cycle.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync-cycle.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/e2e/sync-cycle.test.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* scaffold → sync is a fixed point: with no edits the .at comes back
|
|
3
|
+
* unchanged, and an edit comes back once.
|
|
4
|
+
*
|
|
5
|
+
* Sync used to copy everything from "## Instructions" to the next heading it
|
|
6
|
+
* knew, so generated sections and headings scaffold had pushed one level down
|
|
7
|
+
* went into the .at: the prompt grew on every cycle (N11).
|
|
8
|
+
*/
|
|
9
|
+
import { describe, it, expect } from "vitest";
|
|
10
|
+
import * as fs from "node:fs";
|
|
11
|
+
import { resolve, dirname } from "node:path";
|
|
12
|
+
import { fileURLToPath } from "node:url";
|
|
13
|
+
import { parse } from "../../parser/index.js";
|
|
14
|
+
import { claudeCodeBinding } from "../../bindings/claude-code.js";
|
|
15
|
+
import { syncFromPlatform } from "../../sync/index.js";
|
|
16
|
+
import { fencedPrompt } from "../../bindings/lib/prompt-fence.js";
|
|
17
|
+
import { mergeAgentFile } from "../../scaffold/merge.js";
|
|
18
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
19
|
+
const source = fs.readFileSync(resolve(here, "fixtures/hazards.at"), "utf-8");
|
|
20
|
+
const agentFiles = (at) => claudeCodeBinding.scaffold(parse(at)).filter((f) => /agents\/[^/]+\/AGENT\.md$/.test(f.path));
|
|
21
|
+
const sync = (at, files) => syncFromPlatform(at, files, "claude-code");
|
|
22
|
+
describe("scaffold then sync is a fixed point", () => {
|
|
23
|
+
it("[N11] with no edits, three cycles leave the .at byte-identical", () => {
|
|
24
|
+
let at = source;
|
|
25
|
+
for (let i = 0; i < 3; i++)
|
|
26
|
+
at = sync(at, agentFiles(at));
|
|
27
|
+
expect(at).toBe(source);
|
|
28
|
+
});
|
|
29
|
+
it("[N11] an edit between the markers comes back once, headings at their own level", () => {
|
|
30
|
+
const files = agentFiles(source).map((f) => f.path.endsWith("researcher/AGENT.md")
|
|
31
|
+
? { ...f, content: f.content.replace("- Prioritize recent and authoritative sources", "- Prefer primary sources") }
|
|
32
|
+
: f);
|
|
33
|
+
const once = sync(source, files);
|
|
34
|
+
const researcher = parse(once).nodes.find((n) => n.id === "researcher");
|
|
35
|
+
expect(researcher.prompt).toContain("- Prefer primary sources");
|
|
36
|
+
expect(researcher.prompt).toContain("## Guidelines");
|
|
37
|
+
expect(researcher.prompt).not.toContain("### Guidelines");
|
|
38
|
+
// and the next cycle changes nothing more
|
|
39
|
+
expect(sync(once, agentFiles(once))).toBe(once);
|
|
40
|
+
});
|
|
41
|
+
it("[N11] re-scaffold keeps the user's text between the markers and regenerates the rest", () => {
|
|
42
|
+
const generated = agentFiles(source).find((f) => f.path.endsWith("writer/AGENT.md")).content;
|
|
43
|
+
const edited = generated.replace(fencedPrompt(generated), "My own instructions.");
|
|
44
|
+
const merged = mergeAgentFile(edited, generated.replace("## Reads", "## Reads\n- workspace/new.md"), "claude-code");
|
|
45
|
+
expect(fencedPrompt(merged)).toBe("My own instructions.");
|
|
46
|
+
expect(merged).toContain("- workspace/new.md");
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
//# sourceMappingURL=sync-cycle.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync-cycle.test.js","sourceRoot":"","sources":["../../../src/__tests__/e2e/sync-cycle.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Build once before any test runs, so tests that execute `dist/cli/index.js`
|
|
3
|
+
* always test the current source. They used to run whatever dist/ happened to
|
|
4
|
+
* be on disk — a change could pass against stale output.
|
|
5
|
+
*/
|
|
6
|
+
export default function setup(): void;
|
|
7
|
+
//# sourceMappingURL=global-setup.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"global-setup.d.ts","sourceRoot":"","sources":["../../src/__tests__/global-setup.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,MAAM,CAAC,OAAO,UAAU,KAAK,IAAI,IAAI,CAMpC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Build once before any test runs, so tests that execute `dist/cli/index.js`
|
|
3
|
+
* always test the current source. They used to run whatever dist/ happened to
|
|
4
|
+
* be on disk — a change could pass against stale output.
|
|
5
|
+
*/
|
|
6
|
+
import { execFileSync } from "node:child_process";
|
|
7
|
+
import { resolve, dirname } from "node:path";
|
|
8
|
+
import { fileURLToPath } from "node:url";
|
|
9
|
+
export default function setup() {
|
|
10
|
+
const root = resolve(dirname(fileURLToPath(import.meta.url)), "../..");
|
|
11
|
+
execFileSync(process.execPath, [resolve(root, "node_modules/typescript/bin/tsc")], {
|
|
12
|
+
cwd: root,
|
|
13
|
+
stdio: "inherit",
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=global-setup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"global-setup.js","sourceRoot":"","sources":["../../src/__tests__/global-setup.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,MAAM,CAAC,OAAO,UAAU,KAAK;IAC3B,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;IACvE,YAAY,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,iCAAiC,CAAC,CAAC,EAAE;QACjF,GAAG,EAAE,IAAI;QACT,KAAK,EAAE,SAAS;KACjB,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Live: real Claude Code loads what scaffold generates.
|
|
3
|
+
*
|
|
4
|
+
* Unit tests check the files we write; only Claude Code can say whether it
|
|
5
|
+
* reads them. This scaffolds every example (and the hazards fixture) into a
|
|
6
|
+
* temporary project, starts a headless `claude -p` session there, and checks
|
|
7
|
+
* the session's init report: every generated agent, skill and command is
|
|
8
|
+
* registered, and the session itself succeeds.
|
|
9
|
+
*
|
|
10
|
+
* It found the first bug the moment it ran: settings `env` carried the literal
|
|
11
|
+
* text "${ANTHROPIC_API_KEY}", which Claude Code applied as the key, so every
|
|
12
|
+
* session in 6 of the 10 example projects failed with "Invalid API key".
|
|
13
|
+
*
|
|
14
|
+
* Opt-in, because it needs the `claude` CLI and makes one small model call per
|
|
15
|
+
* project: AT_LIVE=1 npx vitest run src/__tests__/live
|
|
16
|
+
* The session is isolated from the developer's own setup: user settings (and
|
|
17
|
+
* their hooks), MCP servers and session history are all left out.
|
|
18
|
+
*/
|
|
19
|
+
export {};
|
|
20
|
+
//# sourceMappingURL=claude-code.live.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude-code.live.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/live/claude-code.live.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG"}
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Live: real Claude Code loads what scaffold generates.
|
|
3
|
+
*
|
|
4
|
+
* Unit tests check the files we write; only Claude Code can say whether it
|
|
5
|
+
* reads them. This scaffolds every example (and the hazards fixture) into a
|
|
6
|
+
* temporary project, starts a headless `claude -p` session there, and checks
|
|
7
|
+
* the session's init report: every generated agent, skill and command is
|
|
8
|
+
* registered, and the session itself succeeds.
|
|
9
|
+
*
|
|
10
|
+
* It found the first bug the moment it ran: settings `env` carried the literal
|
|
11
|
+
* text "${ANTHROPIC_API_KEY}", which Claude Code applied as the key, so every
|
|
12
|
+
* session in 6 of the 10 example projects failed with "Invalid API key".
|
|
13
|
+
*
|
|
14
|
+
* Opt-in, because it needs the `claude` CLI and makes one small model call per
|
|
15
|
+
* project: AT_LIVE=1 npx vitest run src/__tests__/live
|
|
16
|
+
* The session is isolated from the developer's own setup: user settings (and
|
|
17
|
+
* their hooks), MCP servers and session history are all left out.
|
|
18
|
+
*/
|
|
19
|
+
import { describe, it, expect } from "vitest";
|
|
20
|
+
import { execFileSync, spawnSync } from "node:child_process";
|
|
21
|
+
import * as fs from "node:fs";
|
|
22
|
+
import * as os from "node:os";
|
|
23
|
+
import { resolve, dirname, join, basename } from "node:path";
|
|
24
|
+
import { fileURLToPath } from "node:url";
|
|
25
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
26
|
+
const root = resolve(here, "../../..");
|
|
27
|
+
const CLI = resolve(root, "dist/cli/index.js");
|
|
28
|
+
const LIVE = process.env.AT_LIVE === "1";
|
|
29
|
+
/**
|
|
30
|
+
* The installed Claude Code, not a copy under some node_modules/.bin: npx puts
|
|
31
|
+
* every ancestor's node_modules/.bin first on PATH, and a stale 1.0.x found
|
|
32
|
+
* there rejected today's flags. AT_CLAUDE_BIN overrides.
|
|
33
|
+
*/
|
|
34
|
+
function claudeBin() {
|
|
35
|
+
if (process.env.AT_CLAUDE_BIN)
|
|
36
|
+
return process.env.AT_CLAUDE_BIN;
|
|
37
|
+
for (const dir of (process.env.PATH ?? "").split(":")) {
|
|
38
|
+
if (dir.includes("node_modules"))
|
|
39
|
+
continue;
|
|
40
|
+
const candidate = join(dir, "claude");
|
|
41
|
+
if (fs.existsSync(candidate))
|
|
42
|
+
return candidate;
|
|
43
|
+
}
|
|
44
|
+
return "claude";
|
|
45
|
+
}
|
|
46
|
+
function runClaude(cwd, prompt = "Reply with the single word OK.", maxTurns = 1) {
|
|
47
|
+
const proc = spawnSync(claudeBin(), [
|
|
48
|
+
"-p",
|
|
49
|
+
prompt,
|
|
50
|
+
"--setting-sources", "project,local",
|
|
51
|
+
"--strict-mcp-config",
|
|
52
|
+
"--no-session-persistence",
|
|
53
|
+
"--model", "haiku",
|
|
54
|
+
"--max-turns", String(maxTurns),
|
|
55
|
+
"--output-format", "stream-json",
|
|
56
|
+
"--verbose",
|
|
57
|
+
], { cwd, encoding: "utf8", timeout: 180_000 });
|
|
58
|
+
const lines = (proc.stdout ?? "").split("\n").filter((l) => l.trim().startsWith("{"));
|
|
59
|
+
const events = lines.map((l) => JSON.parse(l));
|
|
60
|
+
const init = events.find((e) => e.type === "system" && e.subtype === "init");
|
|
61
|
+
const result = events.find((e) => e.type === "result");
|
|
62
|
+
if (!init || !result) {
|
|
63
|
+
throw new Error(`claude produced no init/result (exit ${proc.status}): ${proc.stderr}`);
|
|
64
|
+
}
|
|
65
|
+
return { init, result, stderr: proc.stderr ?? "", events };
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* `name:` from a generated agent file's frontmatter, or null when it has none.
|
|
69
|
+
* Human nodes are written to .claude/agents/<id>/AGENT.md without frontmatter;
|
|
70
|
+
* Claude Code ignores such a file (open finding H1: they should compile to an
|
|
71
|
+
* approval step), so only files that declare a subagent are expected to load.
|
|
72
|
+
*/
|
|
73
|
+
function frontmatterName(path) {
|
|
74
|
+
const m = fs.readFileSync(path, "utf-8").match(/^---\n[\s\S]*?^name:\s*"?([^"\n]+)"?\s*$/m);
|
|
75
|
+
return m ? m[1].trim() : null;
|
|
76
|
+
}
|
|
77
|
+
const projects = [
|
|
78
|
+
...fs.readdirSync(resolve(root, "examples")).filter((f) => f.endsWith(".at")).map((f) => resolve(root, "examples", f)),
|
|
79
|
+
resolve(here, "../e2e/fixtures/hazards.at"),
|
|
80
|
+
];
|
|
81
|
+
describe.skipIf(!LIVE)("[L1] Claude Code loads every scaffolded project", () => {
|
|
82
|
+
it.each(projects.map((p) => [basename(p), p]))("%s", (_name, atFile) => {
|
|
83
|
+
const project = fs.mkdtempSync(join(os.tmpdir(), "at-live-"));
|
|
84
|
+
try {
|
|
85
|
+
execFileSync(process.execPath, [CLI, "scaffold", atFile, "--target", "claude-code", "--output", project], {
|
|
86
|
+
stdio: "ignore",
|
|
87
|
+
});
|
|
88
|
+
const run = runClaude(project);
|
|
89
|
+
const agentsDir = join(project, ".claude/agents");
|
|
90
|
+
const agents = fs.existsSync(agentsDir)
|
|
91
|
+
? fs.readdirSync(agentsDir)
|
|
92
|
+
.map((d) => frontmatterName(join(agentsDir, d, "AGENT.md")))
|
|
93
|
+
.filter((n) => n !== null)
|
|
94
|
+
: [];
|
|
95
|
+
const skillsDir = join(project, ".claude/skills");
|
|
96
|
+
const skills = fs.existsSync(skillsDir)
|
|
97
|
+
? fs.readdirSync(skillsDir).filter((d) => fs.existsSync(join(skillsDir, d, "SKILL.md")))
|
|
98
|
+
: [];
|
|
99
|
+
const commandsDir = join(project, ".claude/commands");
|
|
100
|
+
const commands = fs.existsSync(commandsDir)
|
|
101
|
+
? fs.readdirSync(commandsDir).filter((f) => f.endsWith(".md")).map((f) => f.replace(/\.md$/, ""))
|
|
102
|
+
: [];
|
|
103
|
+
expect(run.result.is_error, `session failed: ${run.result.result}`).toBe(false);
|
|
104
|
+
for (const a of agents)
|
|
105
|
+
expect(run.init.agents, `agent ${a}`).toContain(a);
|
|
106
|
+
for (const s of skills)
|
|
107
|
+
expect(run.init.skills, `skill ${s}`).toContain(s);
|
|
108
|
+
for (const c of commands)
|
|
109
|
+
expect(run.init.slash_commands, `command ${c}`).toContain(c);
|
|
110
|
+
}
|
|
111
|
+
finally {
|
|
112
|
+
fs.rmSync(project, { recursive: true, force: true });
|
|
113
|
+
}
|
|
114
|
+
}, 200_000);
|
|
115
|
+
});
|
|
116
|
+
describe.skipIf(!LIVE)("[L2] Claude Code loads a hand-built project after import then scaffold", () => {
|
|
117
|
+
it("handbuilt fixture", () => {
|
|
118
|
+
const tmp = fs.mkdtempSync(join(os.tmpdir(), "at-live-rt-"));
|
|
119
|
+
const project = join(tmp, "project");
|
|
120
|
+
try {
|
|
121
|
+
fs.cpSync(resolve(here, "../e2e/fixtures/handbuilt"), project, { recursive: true });
|
|
122
|
+
execFileSync(process.execPath, [CLI, "import", "--target", "claude-code", "--dir", project, "--name", "handbuilt", "--output", tmp], { stdio: "ignore" });
|
|
123
|
+
execFileSync(process.execPath, [CLI, "scaffold", join(tmp, "handbuilt.at"), "--target", "claude-code", "--output", project], { stdio: "ignore" });
|
|
124
|
+
const run = runClaude(project);
|
|
125
|
+
expect(run.result.is_error, `session failed: ${run.result.result}`).toBe(false);
|
|
126
|
+
for (const a of ["reviewer", "writer"])
|
|
127
|
+
expect(run.init.agents, `agent ${a}`).toContain(a);
|
|
128
|
+
expect(run.init.skills).toContain("story");
|
|
129
|
+
expect(run.init.slash_commands).toContain("ship");
|
|
130
|
+
}
|
|
131
|
+
finally {
|
|
132
|
+
fs.rmSync(tmp, { recursive: true, force: true });
|
|
133
|
+
}
|
|
134
|
+
}, 200_000);
|
|
135
|
+
});
|
|
136
|
+
describe.skipIf(!LIVE)("[L3] Claude Code reads the phase-3 constructs as meant", () => {
|
|
137
|
+
it("compile.at: a manual agent registers, and a prompt hook fires", () => {
|
|
138
|
+
const project = fs.mkdtempSync(join(os.tmpdir(), "at-live-compile-"));
|
|
139
|
+
try {
|
|
140
|
+
execFileSync(process.execPath, [CLI, "scaffold", resolve(here, "../e2e/fixtures/compile.at"), "--target", "claude-code", "--output", project], {
|
|
141
|
+
stdio: "ignore",
|
|
142
|
+
});
|
|
143
|
+
const run = runClaude(project);
|
|
144
|
+
// drafter carries a regex matcher and a prompt hook in its frontmatter: a
|
|
145
|
+
// YAML error there would drop it. auditor is manual: without a
|
|
146
|
+
// description Claude Code skipped it.
|
|
147
|
+
expect(run.init.agents).toEqual(expect.arrayContaining(["drafter", "auditor"]));
|
|
148
|
+
// The fixture's Stop prompt hook asks for a summary; "OK" is not one, so
|
|
149
|
+
// Claude Code feeds the hook's verdict back: proof the prompt handler ran
|
|
150
|
+
// (as a command it would have failed to execute).
|
|
151
|
+
const fed = run.events.some((e) => e.type === "user" && JSON.stringify(e).includes("Stop hook feedback"));
|
|
152
|
+
expect(fed, "the Stop prompt hook did not run").toBe(true);
|
|
153
|
+
}
|
|
154
|
+
finally {
|
|
155
|
+
fs.rmSync(project, { recursive: true, force: true });
|
|
156
|
+
}
|
|
157
|
+
}, 200_000);
|
|
158
|
+
});
|
|
159
|
+
describe.skipIf(!LIVE)("[L4] Claude Code enforces a gate and an approval step before launching an agent", () => {
|
|
160
|
+
const launch = "Launch the drafter subagent with the task: write one line about tea. Do nothing else.";
|
|
161
|
+
const toolResults = (run) => JSON.stringify(run.events.filter((e) => e.type === "user"));
|
|
162
|
+
it.each([
|
|
163
|
+
["a failing gate blocks the launch", "#!/usr/bin/env bash\necho 'brief missing' >&2\nexit 1\n", "Gate 'brief-check' FAILED"],
|
|
164
|
+
["a passing gate reaches the approval step, which asks (headless: denies with its reason)", "#!/usr/bin/env bash\nexit 0\n", 'Approval step \\"approve\\"'],
|
|
165
|
+
])("%s", (_name, gateScript, expected) => {
|
|
166
|
+
const project = fs.mkdtempSync(join(os.tmpdir(), "at-live-before-"));
|
|
167
|
+
try {
|
|
168
|
+
execFileSync(process.execPath, [CLI, "scaffold", resolve(here, "../e2e/fixtures/compile.at"), "--target", "claude-code", "--output", project], {
|
|
169
|
+
stdio: "ignore",
|
|
170
|
+
});
|
|
171
|
+
fs.writeFileSync(join(project, ".claude/skills/compile/scripts/brief-check.sh"), gateScript);
|
|
172
|
+
const run = runClaude(project, launch, 2);
|
|
173
|
+
const launched = run.events.some((e) => e.type === "assistant" && JSON.stringify(e).includes('"subagent_type":"drafter"'));
|
|
174
|
+
expect(launched, "the model never tried to launch drafter").toBe(true);
|
|
175
|
+
expect(toolResults(run)).toContain(expected);
|
|
176
|
+
}
|
|
177
|
+
finally {
|
|
178
|
+
fs.rmSync(project, { recursive: true, force: true });
|
|
179
|
+
}
|
|
180
|
+
}, 200_000);
|
|
181
|
+
});
|
|
182
|
+
describe.skipIf(!LIVE)("[L5] Claude Code loads the topology context from .claude/rules", () => {
|
|
183
|
+
it("compile.at: a line in .claude/rules/compile.md reaches the session", () => {
|
|
184
|
+
const project = fs.mkdtempSync(join(os.tmpdir(), "at-live-rules-"));
|
|
185
|
+
try {
|
|
186
|
+
execFileSync(process.execPath, [CLI, "scaffold", resolve(here, "../e2e/fixtures/compile.at"), "--target", "claude-code", "--output", project], {
|
|
187
|
+
stdio: "ignore",
|
|
188
|
+
});
|
|
189
|
+
fs.appendFileSync(join(project, ".claude/rules/compile.md"), "\nThe project codeword is TEAPOT-7731.\n");
|
|
190
|
+
const run = runClaude(project, "Without using any tools: what is the project codeword? Reply with just the codeword, or NONE.");
|
|
191
|
+
expect(run.result.result ?? JSON.stringify(run.events)).toContain("TEAPOT-7731");
|
|
192
|
+
}
|
|
193
|
+
finally {
|
|
194
|
+
fs.rmSync(project, { recursive: true, force: true });
|
|
195
|
+
}
|
|
196
|
+
}, 200_000);
|
|
197
|
+
});
|
|
198
|
+
//# sourceMappingURL=claude-code.live.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude-code.live.test.js","sourceRoot":"","sources":["../../../src/__tests__/live/claude-code.live.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"zz-debug.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/live/zz-debug.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { it } from "vitest";
|
|
2
|
+
import { spawnSync } from "node:child_process";
|
|
3
|
+
it("debug", () => { const r = spawnSync("sh", ["-c", "command -v claude; claude --version; echo $PATH | tr ':' '\n' | head -5"], { encoding: "utf8" }); console.log(r.stdout, r.stderr); });
|
|
4
|
+
//# sourceMappingURL=zz-debug.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"zz-debug.test.js","sourceRoot":"","sources":["../../../src/__tests__/live/zz-debug.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,MAAM,CAAC,GAAG,SAAS,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,yEAAyE,CAAC,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What the suite does NOT yet guarantee — visible in every run.
|
|
3
|
+
*
|
|
4
|
+
* Each todo is an open finding from spec/testing.md, under the same id. When
|
|
5
|
+
* one is fixed, replace its todo with a real test (keeping the id in the name)
|
|
6
|
+
* and move the row to Guarantees. spec-testing-sync.test.ts keeps the two
|
|
7
|
+
* lists in step.
|
|
8
|
+
*/
|
|
9
|
+
export {};
|
|
10
|
+
//# sourceMappingURL=open-findings.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"open-findings.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/open-findings.test.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What the suite does NOT yet guarantee — visible in every run.
|
|
3
|
+
*
|
|
4
|
+
* Each todo is an open finding from spec/testing.md, under the same id. When
|
|
5
|
+
* one is fixed, replace its todo with a real test (keeping the id in the name)
|
|
6
|
+
* and move the row to Guarantees. spec-testing-sync.test.ts keeps the two
|
|
7
|
+
* lists in step.
|
|
8
|
+
*/
|
|
9
|
+
import { describe, it } from "vitest";
|
|
10
|
+
describe("open findings (spec/testing.md)", () => {
|
|
11
|
+
it.todo("[B5] An agent's permissions read as per-agent grants; Claude Code allow rules are session-wide");
|
|
12
|
+
it.todo("[F1] Missing first-class fields: agent effort, initialPrompt, omitClaudeMd, cache TTL, color; skill when_to_use, arguments, paths, shell");
|
|
13
|
+
it.todo("[F2] Hooks as a typed union (http, mcp_tool, agent; once, async, if)");
|
|
14
|
+
});
|
|
15
|
+
//# sourceMappingURL=open-findings.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"open-findings.test.js","sourceRoot":"","sources":["../../src/__tests__/open-findings.test.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAEtC,QAAQ,CAAC,iCAAiC,EAAE,GAAG,EAAE;IAC/C,EAAE,CAAC,IAAI,CAAC,gGAAgG,CAAC,CAAC;IAC1G,EAAE,CAAC,IAAI,CAAC,0IAA0I,CAAC,CAAC;IACpJ,EAAE,CAAC,IAAI,CAAC,sEAAsE,CAAC,CAAC;AAClF,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* spec/testing.md and the tests cannot drift apart.
|
|
3
|
+
*
|
|
4
|
+
* Every guarantee id in the spec must name at least one test, and every id a
|
|
5
|
+
* test claims must be in the spec, as a guarantee or as an open finding. Same
|
|
6
|
+
* idea as spec-sync.test.ts for validation rules: drift is a missing test, not
|
|
7
|
+
* a discipline problem.
|
|
8
|
+
*/
|
|
9
|
+
export {};
|
|
10
|
+
//# sourceMappingURL=spec-testing-sync.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spec-testing-sync.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/spec-testing-sync.test.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG"}
|