beth-copilot 1.0.14 → 1.0.16
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/CHANGELOG.md +195 -177
- package/README.md +528 -185
- package/bin/cli.js +47 -0
- package/dist/cli/commands/doctor.e2e.test.d.ts +8 -0
- package/dist/cli/commands/doctor.e2e.test.d.ts.map +1 -0
- package/dist/cli/commands/doctor.e2e.test.js +428 -0
- package/dist/cli/commands/doctor.e2e.test.js.map +1 -0
- package/dist/cli/commands/doctor.test.js +1 -1
- package/dist/cli/commands/help.e2e.test.d.ts +9 -0
- package/dist/cli/commands/help.e2e.test.d.ts.map +1 -0
- package/dist/cli/commands/help.e2e.test.js +150 -0
- package/dist/cli/commands/help.e2e.test.js.map +1 -0
- package/dist/cli/commands/init.test.d.ts +6 -0
- package/dist/cli/commands/init.test.d.ts.map +1 -0
- package/dist/cli/commands/init.test.js +289 -0
- package/dist/cli/commands/init.test.js.map +1 -0
- package/dist/cli/commands/mcp.e2e.test.d.ts +9 -0
- package/dist/cli/commands/mcp.e2e.test.d.ts.map +1 -0
- package/dist/cli/commands/mcp.e2e.test.js +139 -0
- package/dist/cli/commands/mcp.e2e.test.js.map +1 -0
- package/dist/cli/commands/pipeline.e2e.test.d.ts +9 -0
- package/dist/cli/commands/pipeline.e2e.test.d.ts.map +1 -0
- package/dist/cli/commands/pipeline.e2e.test.js +192 -0
- package/dist/cli/commands/pipeline.e2e.test.js.map +1 -0
- package/dist/cli/commands/quickstart.test.d.ts +6 -0
- package/dist/cli/commands/quickstart.test.d.ts.map +1 -0
- package/dist/cli/commands/quickstart.test.js +232 -0
- package/dist/cli/commands/quickstart.test.js.map +1 -0
- package/dist/core/agents/frontmatter.test.d.ts +8 -0
- package/dist/core/agents/frontmatter.test.d.ts.map +1 -0
- package/dist/core/agents/frontmatter.test.js +589 -0
- package/dist/core/agents/frontmatter.test.js.map +1 -0
- package/dist/core/agents/handoffs.test.d.ts +8 -0
- package/dist/core/agents/handoffs.test.d.ts.map +1 -0
- package/dist/core/agents/handoffs.test.js +320 -0
- package/dist/core/agents/handoffs.test.js.map +1 -0
- package/dist/core/agents/loader.test.js +1 -1
- package/dist/core/agents/suite.test.d.ts +8 -0
- package/dist/core/agents/suite.test.d.ts.map +1 -0
- package/dist/core/agents/suite.test.js +207 -0
- package/dist/core/agents/suite.test.js.map +1 -0
- package/dist/core/agents/tools.test.d.ts +8 -0
- package/dist/core/agents/tools.test.d.ts.map +1 -0
- package/dist/core/agents/tools.test.js +332 -0
- package/dist/core/agents/tools.test.js.map +1 -0
- package/dist/core/context.d.ts +171 -0
- package/dist/core/context.d.ts.map +1 -0
- package/dist/core/context.js +353 -0
- package/dist/core/context.js.map +1 -0
- package/dist/core/context.test.d.ts +8 -0
- package/dist/core/context.test.d.ts.map +1 -0
- package/dist/core/context.test.js +253 -0
- package/dist/core/context.test.js.map +1 -0
- package/dist/core/handoffs.d.ts +151 -0
- package/dist/core/handoffs.d.ts.map +1 -0
- package/dist/core/handoffs.js +220 -0
- package/dist/core/handoffs.js.map +1 -0
- package/dist/core/handoffs.test.d.ts +8 -0
- package/dist/core/handoffs.test.d.ts.map +1 -0
- package/dist/core/handoffs.test.js +231 -0
- package/dist/core/handoffs.test.js.map +1 -0
- package/dist/core/orchestrator.d.ts +246 -0
- package/dist/core/orchestrator.d.ts.map +1 -0
- package/dist/core/orchestrator.js +514 -0
- package/dist/core/orchestrator.js.map +1 -0
- package/dist/core/orchestrator.test.d.ts +8 -0
- package/dist/core/orchestrator.test.d.ts.map +1 -0
- package/dist/core/orchestrator.test.js +517 -0
- package/dist/core/orchestrator.test.js.map +1 -0
- package/dist/core/router.d.ts +102 -0
- package/dist/core/router.d.ts.map +1 -0
- package/dist/core/router.js +178 -0
- package/dist/core/router.js.map +1 -0
- package/dist/core/router.test.d.ts +8 -0
- package/dist/core/router.test.d.ts.map +1 -0
- package/dist/core/router.test.js +215 -0
- package/dist/core/router.test.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -1
- package/dist/init.test.js +288 -0
- package/dist/providers/azure.d.ts +147 -0
- package/dist/providers/azure.d.ts.map +1 -0
- package/dist/providers/azure.js +491 -0
- package/dist/providers/azure.js.map +1 -0
- package/dist/providers/azure.test.d.ts +11 -0
- package/dist/providers/azure.test.d.ts.map +1 -0
- package/dist/providers/azure.test.js +330 -0
- package/dist/providers/azure.test.js.map +1 -0
- package/dist/providers/config.d.ts +87 -0
- package/dist/providers/config.d.ts.map +1 -0
- package/dist/providers/config.js +193 -0
- package/dist/providers/config.js.map +1 -0
- package/dist/providers/config.test.d.ts +7 -0
- package/dist/providers/config.test.d.ts.map +1 -0
- package/dist/providers/config.test.js +370 -0
- package/dist/providers/config.test.js.map +1 -0
- package/dist/providers/index.d.ts +18 -0
- package/dist/providers/index.d.ts.map +1 -0
- package/dist/providers/index.js +14 -0
- package/dist/providers/index.js.map +1 -0
- package/dist/providers/interface.d.ts +191 -0
- package/dist/providers/interface.d.ts.map +1 -0
- package/dist/providers/interface.js +94 -0
- package/dist/providers/interface.js.map +1 -0
- package/dist/providers/retry.d.ts +128 -0
- package/dist/providers/retry.d.ts.map +1 -0
- package/dist/providers/retry.js +205 -0
- package/dist/providers/retry.js.map +1 -0
- package/dist/providers/retry.test.d.ts +7 -0
- package/dist/providers/retry.test.d.ts.map +1 -0
- package/dist/providers/retry.test.js +439 -0
- package/dist/providers/retry.test.js.map +1 -0
- package/dist/providers/streaming.d.ts +157 -0
- package/dist/providers/streaming.d.ts.map +1 -0
- package/dist/providers/streaming.js +233 -0
- package/dist/providers/streaming.js.map +1 -0
- package/dist/providers/streaming.test.d.ts +7 -0
- package/dist/providers/streaming.test.d.ts.map +1 -0
- package/dist/providers/streaming.test.js +372 -0
- package/dist/providers/streaming.test.js.map +1 -0
- package/dist/providers/types.d.ts +209 -0
- package/dist/providers/types.d.ts.map +1 -0
- package/dist/providers/types.js +53 -0
- package/dist/providers/types.js.map +1 -0
- package/dist/providers/types.test.d.ts +7 -0
- package/dist/providers/types.test.d.ts.map +1 -0
- package/dist/providers/types.test.js +141 -0
- package/dist/providers/types.test.js.map +1 -0
- package/dist/tools/cli/beads.d.ts +27 -0
- package/dist/tools/cli/beads.d.ts.map +1 -0
- package/dist/tools/cli/beads.js +172 -0
- package/dist/tools/cli/beads.js.map +1 -0
- package/dist/tools/cli/beads.test.d.ts +8 -0
- package/dist/tools/cli/beads.test.d.ts.map +1 -0
- package/dist/tools/cli/beads.test.js +264 -0
- package/dist/tools/cli/beads.test.js.map +1 -0
- package/dist/tools/cli/editFile.d.ts +17 -0
- package/dist/tools/cli/editFile.d.ts.map +1 -0
- package/dist/tools/cli/editFile.js +125 -0
- package/dist/tools/cli/editFile.js.map +1 -0
- package/dist/tools/cli/editFile.test.d.ts +8 -0
- package/dist/tools/cli/editFile.test.d.ts.map +1 -0
- package/dist/tools/cli/editFile.test.js +177 -0
- package/dist/tools/cli/editFile.test.js.map +1 -0
- package/dist/tools/cli/readFile.d.ts +25 -0
- package/dist/tools/cli/readFile.d.ts.map +1 -0
- package/dist/tools/cli/readFile.js +118 -0
- package/dist/tools/cli/readFile.js.map +1 -0
- package/dist/tools/cli/readFile.test.d.ts +8 -0
- package/dist/tools/cli/readFile.test.d.ts.map +1 -0
- package/dist/tools/cli/readFile.test.js +194 -0
- package/dist/tools/cli/readFile.test.js.map +1 -0
- package/dist/tools/cli/search.d.ts +16 -0
- package/dist/tools/cli/search.d.ts.map +1 -0
- package/dist/tools/cli/search.js +261 -0
- package/dist/tools/cli/search.js.map +1 -0
- package/dist/tools/cli/search.test.d.ts +8 -0
- package/dist/tools/cli/search.test.d.ts.map +1 -0
- package/dist/tools/cli/search.test.js +172 -0
- package/dist/tools/cli/search.test.js.map +1 -0
- package/dist/tools/cli/subagent.d.ts +43 -0
- package/dist/tools/cli/subagent.d.ts.map +1 -0
- package/dist/tools/cli/subagent.js +99 -0
- package/dist/tools/cli/subagent.js.map +1 -0
- package/dist/tools/cli/subagent.test.d.ts +8 -0
- package/dist/tools/cli/subagent.test.d.ts.map +1 -0
- package/dist/tools/cli/subagent.test.js +190 -0
- package/dist/tools/cli/subagent.test.js.map +1 -0
- package/dist/tools/cli/terminal.d.ts +19 -0
- package/dist/tools/cli/terminal.d.ts.map +1 -0
- package/dist/tools/cli/terminal.js +164 -0
- package/dist/tools/cli/terminal.js.map +1 -0
- package/dist/tools/cli/terminal.test.d.ts +8 -0
- package/dist/tools/cli/terminal.test.d.ts.map +1 -0
- package/dist/tools/cli/terminal.test.js +161 -0
- package/dist/tools/cli/terminal.test.js.map +1 -0
- package/dist/tools/index.d.ts +25 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +41 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/interface.d.ts +64 -0
- package/dist/tools/interface.d.ts.map +1 -0
- package/dist/tools/interface.js +37 -0
- package/dist/tools/interface.js.map +1 -0
- package/dist/tools/interface.test.d.ts +7 -0
- package/dist/tools/interface.test.d.ts.map +1 -0
- package/dist/tools/interface.test.js +179 -0
- package/dist/tools/interface.test.js.map +1 -0
- package/dist/tools/mcp/bridge.d.ts +48 -0
- package/dist/tools/mcp/bridge.d.ts.map +1 -0
- package/dist/tools/mcp/bridge.js +128 -0
- package/dist/tools/mcp/bridge.js.map +1 -0
- package/dist/tools/mcp/bridge.test.d.ts +8 -0
- package/dist/tools/mcp/bridge.test.d.ts.map +1 -0
- package/dist/tools/mcp/bridge.test.js +300 -0
- package/dist/tools/mcp/bridge.test.js.map +1 -0
- package/dist/tools/mcp/client.d.ts +135 -0
- package/dist/tools/mcp/client.d.ts.map +1 -0
- package/dist/tools/mcp/client.js +263 -0
- package/dist/tools/mcp/client.js.map +1 -0
- package/dist/tools/mcp/client.test.d.ts +8 -0
- package/dist/tools/mcp/client.test.d.ts.map +1 -0
- package/dist/tools/mcp/client.test.js +390 -0
- package/dist/tools/mcp/client.test.js.map +1 -0
- package/dist/tools/registry.d.ts +82 -0
- package/dist/tools/registry.d.ts.map +1 -0
- package/dist/tools/registry.js +99 -0
- package/dist/tools/registry.js.map +1 -0
- package/dist/tools/registry.test.d.ts +7 -0
- package/dist/tools/registry.test.d.ts.map +1 -0
- package/dist/tools/registry.test.js +199 -0
- package/dist/tools/registry.test.js.map +1 -0
- package/dist/tools/suite.test.d.ts +11 -0
- package/dist/tools/suite.test.d.ts.map +1 -0
- package/dist/tools/suite.test.js +119 -0
- package/dist/tools/suite.test.js.map +1 -0
- package/dist/tools/types.d.ts +75 -0
- package/dist/tools/types.d.ts.map +1 -0
- package/dist/tools/types.js +30 -0
- package/dist/tools/types.js.map +1 -0
- package/dist/tools/types.test.d.ts +7 -0
- package/dist/tools/types.test.d.ts.map +1 -0
- package/dist/tools/types.test.js +178 -0
- package/dist/tools/types.test.js.map +1 -0
- package/package.json +60 -56
- package/sbom.json +3302 -8
- package/templates/.github/agents/beth.agent.md +329 -329
- package/templates/.github/agents/developer.agent.md +572 -572
- package/templates/.github/agents/product-manager.agent.md +272 -272
- package/templates/.github/agents/researcher.agent.md +338 -338
- package/templates/.github/agents/security-reviewer.agent.md +465 -465
- package/templates/.github/agents/tester.agent.md +496 -496
- package/templates/.github/agents/ux-designer.agent.md +393 -393
- package/templates/mcp.json.example +4 -0
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Handoff Validation Tests
|
|
3
|
+
*
|
|
4
|
+
* Tests for agent handoff configuration validation.
|
|
5
|
+
* Handoff interface: { label, agent, prompt, send? }
|
|
6
|
+
*/
|
|
7
|
+
import { describe, it, beforeEach, afterEach } from 'node:test';
|
|
8
|
+
import assert from 'node:assert';
|
|
9
|
+
import { join } from 'node:path';
|
|
10
|
+
import { mkdirSync, writeFileSync, rmSync, existsSync } from 'node:fs';
|
|
11
|
+
import { loadAgent, loadAgents } from './loader.js';
|
|
12
|
+
// Test fixtures directory
|
|
13
|
+
const TEST_DIR = join(process.cwd(), 'test-fixtures-handoffs');
|
|
14
|
+
const TEMPLATES_AGENTS_DIR = join(process.cwd(), 'templates', '.github', 'agents');
|
|
15
|
+
/**
|
|
16
|
+
* Type guard to check if loadAgent result is an error
|
|
17
|
+
*/
|
|
18
|
+
function isError(result) {
|
|
19
|
+
return 'error' in result;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Create agent file with raw YAML content for more control
|
|
23
|
+
*/
|
|
24
|
+
function createTestAgentRaw(filename, yamlContent) {
|
|
25
|
+
const filePath = join(TEST_DIR, filename);
|
|
26
|
+
const content = `---
|
|
27
|
+
${yamlContent}
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
# Test Agent
|
|
31
|
+
|
|
32
|
+
This is a test agent body.
|
|
33
|
+
`;
|
|
34
|
+
writeFileSync(filePath, content, 'utf-8');
|
|
35
|
+
return filePath;
|
|
36
|
+
}
|
|
37
|
+
describe('Handoff Validation', () => {
|
|
38
|
+
beforeEach(() => {
|
|
39
|
+
if (!existsSync(TEST_DIR)) {
|
|
40
|
+
mkdirSync(TEST_DIR, { recursive: true });
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
afterEach(() => {
|
|
44
|
+
if (existsSync(TEST_DIR)) {
|
|
45
|
+
rmSync(TEST_DIR, { recursive: true, force: true });
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
describe('Valid handoff configurations', () => {
|
|
49
|
+
it('1. Valid handoff with all required fields (label, agent, prompt) passes', () => {
|
|
50
|
+
const filePath = createTestAgentRaw('valid-handoff.agent.md', `
|
|
51
|
+
name: Test Agent
|
|
52
|
+
handoffs:
|
|
53
|
+
- label: Switch to Developer
|
|
54
|
+
agent: developer
|
|
55
|
+
prompt: Continue implementing the feature
|
|
56
|
+
`);
|
|
57
|
+
const result = loadAgent(filePath);
|
|
58
|
+
assert.ok(!('error' in result), `Should pass validation: ${JSON.stringify(result)}`);
|
|
59
|
+
const { agent } = result;
|
|
60
|
+
assert.strictEqual(agent.frontmatter.handoffs?.length, 1);
|
|
61
|
+
assert.strictEqual(agent.frontmatter.handoffs[0].label, 'Switch to Developer');
|
|
62
|
+
assert.strictEqual(agent.frontmatter.handoffs[0].agent, 'developer');
|
|
63
|
+
assert.strictEqual(agent.frontmatter.handoffs[0].prompt, 'Continue implementing the feature');
|
|
64
|
+
});
|
|
65
|
+
it('2. Valid handoff with optional send: true passes', () => {
|
|
66
|
+
const filePath = createTestAgentRaw('handoff-send-true.agent.md', `
|
|
67
|
+
name: Test Agent
|
|
68
|
+
handoffs:
|
|
69
|
+
- label: Auto-send to Developer
|
|
70
|
+
agent: developer
|
|
71
|
+
prompt: Start immediately
|
|
72
|
+
send: true
|
|
73
|
+
`);
|
|
74
|
+
const result = loadAgent(filePath);
|
|
75
|
+
assert.ok(!('error' in result), `Should pass validation: ${JSON.stringify(result)}`);
|
|
76
|
+
const { agent } = result;
|
|
77
|
+
assert.strictEqual(agent.frontmatter.handoffs?.[0].send, true);
|
|
78
|
+
});
|
|
79
|
+
it('3. Valid handoff with optional send: false passes', () => {
|
|
80
|
+
const filePath = createTestAgentRaw('handoff-send-false.agent.md', `
|
|
81
|
+
name: Test Agent
|
|
82
|
+
handoffs:
|
|
83
|
+
- label: Prepare for Developer
|
|
84
|
+
agent: developer
|
|
85
|
+
prompt: Review before sending
|
|
86
|
+
send: false
|
|
87
|
+
`);
|
|
88
|
+
const result = loadAgent(filePath);
|
|
89
|
+
assert.ok(!('error' in result), `Should pass validation: ${JSON.stringify(result)}`);
|
|
90
|
+
const { agent } = result;
|
|
91
|
+
assert.strictEqual(agent.frontmatter.handoffs?.[0].send, false);
|
|
92
|
+
});
|
|
93
|
+
it('7. Empty handoffs array is valid', () => {
|
|
94
|
+
const filePath = createTestAgentRaw('empty-handoffs.agent.md', `
|
|
95
|
+
name: Test Agent
|
|
96
|
+
handoffs: []
|
|
97
|
+
`);
|
|
98
|
+
const result = loadAgent(filePath);
|
|
99
|
+
assert.ok(!('error' in result), `Should pass validation: ${JSON.stringify(result)}`);
|
|
100
|
+
const { agent } = result;
|
|
101
|
+
assert.ok(Array.isArray(agent.frontmatter.handoffs));
|
|
102
|
+
assert.strictEqual(agent.frontmatter.handoffs?.length, 0);
|
|
103
|
+
});
|
|
104
|
+
it('8. Multiple handoffs in array all get validated', () => {
|
|
105
|
+
const filePath = createTestAgentRaw('multiple-handoffs.agent.md', `
|
|
106
|
+
name: Test Agent
|
|
107
|
+
handoffs:
|
|
108
|
+
- label: To Developer
|
|
109
|
+
agent: developer
|
|
110
|
+
prompt: Implement this
|
|
111
|
+
- label: To Tester
|
|
112
|
+
agent: tester
|
|
113
|
+
prompt: Test this
|
|
114
|
+
- label: To Designer
|
|
115
|
+
agent: ux-designer
|
|
116
|
+
prompt: Design this
|
|
117
|
+
`);
|
|
118
|
+
const result = loadAgent(filePath);
|
|
119
|
+
assert.ok(!('error' in result), `Should pass validation: ${JSON.stringify(result)}`);
|
|
120
|
+
const { agent } = result;
|
|
121
|
+
assert.strictEqual(agent.frontmatter.handoffs?.length, 3);
|
|
122
|
+
assert.strictEqual(agent.frontmatter.handoffs[0].agent, 'developer');
|
|
123
|
+
assert.strictEqual(agent.frontmatter.handoffs[1].agent, 'tester');
|
|
124
|
+
assert.strictEqual(agent.frontmatter.handoffs[2].agent, 'ux-designer');
|
|
125
|
+
});
|
|
126
|
+
it('13. Handoff with extra fields (ignored) passes', () => {
|
|
127
|
+
const filePath = createTestAgentRaw('handoff-extra-fields.agent.md', `
|
|
128
|
+
name: Test Agent
|
|
129
|
+
handoffs:
|
|
130
|
+
- label: To Developer
|
|
131
|
+
agent: developer
|
|
132
|
+
prompt: Do the thing
|
|
133
|
+
extraField: should be ignored
|
|
134
|
+
anotherExtra: also ignored
|
|
135
|
+
`);
|
|
136
|
+
const result = loadAgent(filePath);
|
|
137
|
+
assert.ok(!('error' in result), `Should pass validation: ${JSON.stringify(result)}`);
|
|
138
|
+
const { agent } = result;
|
|
139
|
+
assert.strictEqual(agent.frontmatter.handoffs?.length, 1);
|
|
140
|
+
// Extra fields should be ignored in the normalized output
|
|
141
|
+
assert.strictEqual(agent.frontmatter.handoffs[0].label, 'To Developer');
|
|
142
|
+
assert.strictEqual(agent.frontmatter.handoffs[0].agent, 'developer');
|
|
143
|
+
assert.strictEqual(agent.frontmatter.handoffs[0].prompt, 'Do the thing');
|
|
144
|
+
});
|
|
145
|
+
});
|
|
146
|
+
describe('Invalid handoff configurations', () => {
|
|
147
|
+
it('4. Handoff missing label fails validation', () => {
|
|
148
|
+
const filePath = createTestAgentRaw('missing-label.agent.md', `
|
|
149
|
+
name: Test Agent
|
|
150
|
+
handoffs:
|
|
151
|
+
- agent: developer
|
|
152
|
+
prompt: Do work
|
|
153
|
+
`);
|
|
154
|
+
const result = loadAgent(filePath);
|
|
155
|
+
assert.ok(isError(result), 'Should fail validation');
|
|
156
|
+
assert.ok(result.error.message.includes('missing required fields') ||
|
|
157
|
+
result.error.message.includes('label'), `Error should mention missing fields: ${result.error.message}`);
|
|
158
|
+
});
|
|
159
|
+
it('5. Handoff missing agent fails validation', () => {
|
|
160
|
+
const filePath = createTestAgentRaw('missing-agent.agent.md', `
|
|
161
|
+
name: Test Agent
|
|
162
|
+
handoffs:
|
|
163
|
+
- label: To Someone
|
|
164
|
+
prompt: Do work
|
|
165
|
+
`);
|
|
166
|
+
const result = loadAgent(filePath);
|
|
167
|
+
assert.ok(isError(result), 'Should fail validation');
|
|
168
|
+
assert.ok(result.error.message.includes('missing required fields') ||
|
|
169
|
+
result.error.message.includes('agent'), `Error should mention missing fields: ${result.error.message}`);
|
|
170
|
+
});
|
|
171
|
+
it('6. Handoff missing prompt fails validation', () => {
|
|
172
|
+
const filePath = createTestAgentRaw('missing-prompt.agent.md', `
|
|
173
|
+
name: Test Agent
|
|
174
|
+
handoffs:
|
|
175
|
+
- label: To Developer
|
|
176
|
+
agent: developer
|
|
177
|
+
`);
|
|
178
|
+
const result = loadAgent(filePath);
|
|
179
|
+
assert.ok(isError(result), 'Should fail validation');
|
|
180
|
+
assert.ok(result.error.message.includes('missing required fields') ||
|
|
181
|
+
result.error.message.includes('prompt'), `Error should mention missing fields: ${result.error.message}`);
|
|
182
|
+
});
|
|
183
|
+
it('9. Handoff with empty string label fails validation', () => {
|
|
184
|
+
const filePath = createTestAgentRaw('empty-label.agent.md', `
|
|
185
|
+
name: Test Agent
|
|
186
|
+
handoffs:
|
|
187
|
+
- label: ""
|
|
188
|
+
agent: developer
|
|
189
|
+
prompt: Do work
|
|
190
|
+
`);
|
|
191
|
+
const result = loadAgent(filePath);
|
|
192
|
+
assert.ok(isError(result), 'Should fail validation for empty label');
|
|
193
|
+
assert.ok(result.error.message.includes('missing required fields') ||
|
|
194
|
+
result.error.message.includes('label'), `Error should mention missing/empty fields: ${result.error.message}`);
|
|
195
|
+
});
|
|
196
|
+
it('10. Handoff with empty string agent fails validation', () => {
|
|
197
|
+
const filePath = createTestAgentRaw('empty-agent.agent.md', `
|
|
198
|
+
name: Test Agent
|
|
199
|
+
handoffs:
|
|
200
|
+
- label: To Someone
|
|
201
|
+
agent: ""
|
|
202
|
+
prompt: Do work
|
|
203
|
+
`);
|
|
204
|
+
const result = loadAgent(filePath);
|
|
205
|
+
assert.ok(isError(result), 'Should fail validation for empty agent');
|
|
206
|
+
assert.ok(result.error.message.includes('missing required fields') ||
|
|
207
|
+
result.error.message.includes('agent'), `Error should mention missing/empty fields: ${result.error.message}`);
|
|
208
|
+
});
|
|
209
|
+
it('11. Handoff with empty string prompt fails validation', () => {
|
|
210
|
+
const filePath = createTestAgentRaw('empty-prompt.agent.md', `
|
|
211
|
+
name: Test Agent
|
|
212
|
+
handoffs:
|
|
213
|
+
- label: To Developer
|
|
214
|
+
agent: developer
|
|
215
|
+
prompt: ""
|
|
216
|
+
`);
|
|
217
|
+
const result = loadAgent(filePath);
|
|
218
|
+
assert.ok(isError(result), 'Should fail validation for empty prompt');
|
|
219
|
+
assert.ok(result.error.message.includes('missing required fields') ||
|
|
220
|
+
result.error.message.includes('prompt'), `Error should mention missing/empty fields: ${result.error.message}`);
|
|
221
|
+
});
|
|
222
|
+
it('12. Non-array handoffs value fails', () => {
|
|
223
|
+
const filePath = createTestAgentRaw('non-array-handoffs.agent.md', `
|
|
224
|
+
name: Test Agent
|
|
225
|
+
handoffs: "not an array"
|
|
226
|
+
`);
|
|
227
|
+
const result = loadAgent(filePath);
|
|
228
|
+
assert.ok(isError(result), 'Should fail validation for non-array handoffs');
|
|
229
|
+
assert.ok(result.error.message.includes('must be an array'), `Error should mention array requirement: ${result.error.message}`);
|
|
230
|
+
});
|
|
231
|
+
it('Non-array handoffs value (object) fails', () => {
|
|
232
|
+
const filePath = createTestAgentRaw('object-handoffs.agent.md', `
|
|
233
|
+
name: Test Agent
|
|
234
|
+
handoffs:
|
|
235
|
+
label: Single handoff as object
|
|
236
|
+
agent: developer
|
|
237
|
+
prompt: This is wrong
|
|
238
|
+
`);
|
|
239
|
+
const result = loadAgent(filePath);
|
|
240
|
+
// YAML interprets this as an object with keys, not an array
|
|
241
|
+
assert.ok(isError(result), 'Should fail validation for object handoffs');
|
|
242
|
+
assert.ok(result.error.message.includes('must be an array'), `Error should mention array requirement: ${result.error.message}`);
|
|
243
|
+
});
|
|
244
|
+
it('8. Multiple handoffs - second one invalid fails entire validation', () => {
|
|
245
|
+
const filePath = createTestAgentRaw('second-invalid.agent.md', `
|
|
246
|
+
name: Test Agent
|
|
247
|
+
handoffs:
|
|
248
|
+
- label: Valid One
|
|
249
|
+
agent: developer
|
|
250
|
+
prompt: This is valid
|
|
251
|
+
- label: Invalid One
|
|
252
|
+
agent: tester
|
|
253
|
+
`);
|
|
254
|
+
const result = loadAgent(filePath);
|
|
255
|
+
assert.ok(isError(result), 'Should fail when any handoff is invalid');
|
|
256
|
+
assert.ok(result.error.message.includes('index 1') ||
|
|
257
|
+
result.error.message.includes('missing required fields'), `Error should indicate which handoff failed: ${result.error.message}`);
|
|
258
|
+
});
|
|
259
|
+
});
|
|
260
|
+
describe('Real agent files validation', () => {
|
|
261
|
+
it('14. Test actual agent files have valid handoffs pointing to existing agents', () => {
|
|
262
|
+
const result = loadAgents(TEMPLATES_AGENTS_DIR);
|
|
263
|
+
// Should load without errors
|
|
264
|
+
assert.strictEqual(result.errors.length, 0, `Agent loading errors: ${JSON.stringify(result.errors)}`);
|
|
265
|
+
// Build set of all agent IDs
|
|
266
|
+
const agentIds = new Set(result.agents.map((a) => a.id.toLowerCase()));
|
|
267
|
+
// Check every handoff references an existing agent
|
|
268
|
+
const handoffErrors = [];
|
|
269
|
+
for (const agent of result.agents) {
|
|
270
|
+
const handoffs = agent.frontmatter.handoffs ?? [];
|
|
271
|
+
for (const handoff of handoffs) {
|
|
272
|
+
const targetAgent = handoff.agent.toLowerCase();
|
|
273
|
+
if (!agentIds.has(targetAgent)) {
|
|
274
|
+
handoffErrors.push(`Agent '${agent.id}' has handoff to non-existent agent '${handoff.agent}'`);
|
|
275
|
+
}
|
|
276
|
+
// Also verify required fields are present and non-empty
|
|
277
|
+
if (!handoff.label || handoff.label.trim() === '') {
|
|
278
|
+
handoffErrors.push(`Agent '${agent.id}' has handoff with empty label`);
|
|
279
|
+
}
|
|
280
|
+
if (!handoff.agent || handoff.agent.trim() === '') {
|
|
281
|
+
handoffErrors.push(`Agent '${agent.id}' has handoff with empty agent`);
|
|
282
|
+
}
|
|
283
|
+
if (!handoff.prompt || handoff.prompt.trim() === '') {
|
|
284
|
+
handoffErrors.push(`Agent '${agent.id}' has handoff with empty prompt`);
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
assert.strictEqual(handoffErrors.length, 0, `Handoff validation errors:\n${handoffErrors.join('\n')}`);
|
|
289
|
+
});
|
|
290
|
+
it('All agents with handoffs have at least label, agent, and prompt', () => {
|
|
291
|
+
const result = loadAgents(TEMPLATES_AGENTS_DIR);
|
|
292
|
+
for (const agent of result.agents) {
|
|
293
|
+
if (!agent.frontmatter.handoffs)
|
|
294
|
+
continue;
|
|
295
|
+
for (let i = 0; i < agent.frontmatter.handoffs.length; i++) {
|
|
296
|
+
const handoff = agent.frontmatter.handoffs[i];
|
|
297
|
+
assert.ok(typeof handoff.label === 'string' && handoff.label.length > 0, `${agent.id} handoff[${i}] should have non-empty label`);
|
|
298
|
+
assert.ok(typeof handoff.agent === 'string' && handoff.agent.length > 0, `${agent.id} handoff[${i}] should have non-empty agent`);
|
|
299
|
+
assert.ok(typeof handoff.prompt === 'string' && handoff.prompt.length > 0, `${agent.id} handoff[${i}] should have non-empty prompt`);
|
|
300
|
+
// send should be boolean or undefined
|
|
301
|
+
if (handoff.send !== undefined) {
|
|
302
|
+
assert.strictEqual(typeof handoff.send, 'boolean', `${agent.id} handoff[${i}].send should be boolean if present`);
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
});
|
|
307
|
+
it('Beth agent has handoffs to all expected specialists', () => {
|
|
308
|
+
const result = loadAgents(TEMPLATES_AGENTS_DIR);
|
|
309
|
+
const beth = result.agents.find((a) => a.id === 'beth');
|
|
310
|
+
assert.ok(beth, 'Beth agent should exist');
|
|
311
|
+
assert.ok(beth.frontmatter.handoffs, 'Beth should have handoffs');
|
|
312
|
+
const handoffTargets = beth.frontmatter.handoffs.map((h) => h.agent.toLowerCase());
|
|
313
|
+
const expectedTargets = ['developer', 'product-manager', 'ux-designer', 'tester', 'researcher'];
|
|
314
|
+
for (const expected of expectedTargets) {
|
|
315
|
+
assert.ok(handoffTargets.includes(expected), `Beth should have handoff to ${expected}`);
|
|
316
|
+
}
|
|
317
|
+
});
|
|
318
|
+
});
|
|
319
|
+
});
|
|
320
|
+
//# sourceMappingURL=handoffs.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handoffs.test.js","sourceRoot":"","sources":["../../../src/core/agents/handoffs.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -37,7 +37,7 @@ describe('Agent Loader', () => {
|
|
|
37
37
|
assert.strictEqual(agent.id, 'beth');
|
|
38
38
|
assert.strictEqual(agent.frontmatter.name, 'Beth');
|
|
39
39
|
assert.ok(agent.frontmatter.description?.includes('orchestrator'));
|
|
40
|
-
assert.strictEqual(agent.frontmatter.model, 'Claude Opus 4.
|
|
40
|
+
assert.strictEqual(agent.frontmatter.model, 'Claude Opus 4.6');
|
|
41
41
|
assert.strictEqual(agent.frontmatter.infer, true);
|
|
42
42
|
assert.ok(Array.isArray(agent.frontmatter.tools));
|
|
43
43
|
assert.ok(Array.isArray(agent.frontmatter.handoffs));
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent Suite Integration Tests
|
|
3
|
+
*
|
|
4
|
+
* Validates the complete Beth agent suite is coherent and functional together.
|
|
5
|
+
* Tests all 7 agents: beth, developer, product-manager, researcher, security-reviewer, tester, ux-designer
|
|
6
|
+
*/
|
|
7
|
+
export {};
|
|
8
|
+
//# sourceMappingURL=suite.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"suite.test.d.ts","sourceRoot":"","sources":["../../../src/core/agents/suite.test.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent Suite Integration Tests
|
|
3
|
+
*
|
|
4
|
+
* Validates the complete Beth agent suite is coherent and functional together.
|
|
5
|
+
* Tests all 7 agents: beth, developer, product-manager, researcher, security-reviewer, tester, ux-designer
|
|
6
|
+
*/
|
|
7
|
+
import { describe, it } from 'node:test';
|
|
8
|
+
import assert from 'node:assert';
|
|
9
|
+
import { join } from 'node:path';
|
|
10
|
+
import { loadAgents, getAgentById, getInferableAgents, } from './loader.js';
|
|
11
|
+
// Test against templates directory - the source of truth for agent definitions
|
|
12
|
+
const TEMPLATES_AGENTS_DIR = join(process.cwd(), 'templates', '.github', 'agents');
|
|
13
|
+
// Expected agent IDs (from filenames)
|
|
14
|
+
const EXPECTED_AGENT_IDS = [
|
|
15
|
+
'beth',
|
|
16
|
+
'developer',
|
|
17
|
+
'product-manager',
|
|
18
|
+
'researcher',
|
|
19
|
+
'security-reviewer',
|
|
20
|
+
'tester',
|
|
21
|
+
'ux-designer',
|
|
22
|
+
];
|
|
23
|
+
const EXPECTED_AGENT_COUNT = 7;
|
|
24
|
+
describe('Agent Suite Integration Tests', () => {
|
|
25
|
+
// Load agents once for all tests
|
|
26
|
+
const result = loadAgents(TEMPLATES_AGENTS_DIR);
|
|
27
|
+
describe('Suite Loading', () => {
|
|
28
|
+
it('1. All 7 agent files load without errors', () => {
|
|
29
|
+
assert.strictEqual(result.errors.length, 0, `Agent loading errors: ${JSON.stringify(result.errors, null, 2)}`);
|
|
30
|
+
assert.strictEqual(result.agents.length, EXPECTED_AGENT_COUNT, `Expected ${EXPECTED_AGENT_COUNT} agents, got ${result.agents.length}`);
|
|
31
|
+
});
|
|
32
|
+
it('15. Agent file count matches expected (7 agents)', () => {
|
|
33
|
+
assert.strictEqual(result.agents.length, EXPECTED_AGENT_COUNT, `Expected exactly ${EXPECTED_AGENT_COUNT} agents`);
|
|
34
|
+
const loadedIds = result.agents.map((a) => a.id).sort();
|
|
35
|
+
const expectedIds = [...EXPECTED_AGENT_IDS].sort();
|
|
36
|
+
assert.deepStrictEqual(loadedIds, expectedIds, 'Agent IDs should match expected set');
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
describe('Required Fields', () => {
|
|
40
|
+
it('2. All agents have required name field', () => {
|
|
41
|
+
for (const agent of result.agents) {
|
|
42
|
+
assert.ok(agent.frontmatter.name, `Agent ${agent.id} is missing required 'name' field`);
|
|
43
|
+
assert.strictEqual(typeof agent.frontmatter.name, 'string', `Agent ${agent.id} 'name' must be a string`);
|
|
44
|
+
assert.ok(agent.frontmatter.name.length > 0, `Agent ${agent.id} 'name' must be non-empty`);
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
it('3. All agents have description field', () => {
|
|
48
|
+
for (const agent of result.agents) {
|
|
49
|
+
assert.ok(agent.frontmatter.description, `Agent ${agent.id} is missing 'description' field`);
|
|
50
|
+
assert.strictEqual(typeof agent.frontmatter.description, 'string', `Agent ${agent.id} 'description' must be a string`);
|
|
51
|
+
assert.ok(agent.frontmatter.description.length > 0, `Agent ${agent.id} 'description' must be non-empty`);
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
it('14. All markdown bodies are non-empty', () => {
|
|
55
|
+
for (const agent of result.agents) {
|
|
56
|
+
assert.ok(agent.body, `Agent ${agent.id} has no body content`);
|
|
57
|
+
assert.ok(agent.body.length > 50, `Agent ${agent.id} body is too short (${agent.body.length} chars), expected substantial instructions`);
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
describe('Beth Agent Specifics', () => {
|
|
62
|
+
it('4. Beth agent has infer: true (can be invoked as subagent)', () => {
|
|
63
|
+
const beth = getAgentById(result, 'beth');
|
|
64
|
+
assert.ok(beth, 'Beth agent must exist');
|
|
65
|
+
assert.strictEqual(beth.frontmatter.infer, true, 'Beth must have infer: true to be invokable as subagent');
|
|
66
|
+
});
|
|
67
|
+
it('5. Beth agent has agent tool for subagent invocation', () => {
|
|
68
|
+
const beth = getAgentById(result, 'beth');
|
|
69
|
+
assert.ok(beth, 'Beth agent must exist');
|
|
70
|
+
assert.ok(Array.isArray(beth.frontmatter.tools), 'Beth must have tools array');
|
|
71
|
+
// The 'agent' tool is what enables spawning subagents in VS Code agents
|
|
72
|
+
assert.ok(beth.frontmatter.tools.includes('agent'), `Beth must have 'agent' tool for subagent invocation. Found tools: ${beth.frontmatter.tools.join(', ')}`);
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
describe('Uniqueness Constraints', () => {
|
|
76
|
+
it('6. All agent names are unique', () => {
|
|
77
|
+
const names = result.agents.map((a) => a.frontmatter.name);
|
|
78
|
+
const uniqueNames = new Set(names);
|
|
79
|
+
assert.strictEqual(uniqueNames.size, names.length, `Duplicate agent names found: ${findDuplicates(names).join(', ')}`);
|
|
80
|
+
});
|
|
81
|
+
it('7. All agent IDs (from filename) are unique', () => {
|
|
82
|
+
const ids = result.agents.map((a) => a.id);
|
|
83
|
+
const uniqueIds = new Set(ids);
|
|
84
|
+
assert.strictEqual(uniqueIds.size, ids.length, `Duplicate agent IDs found: ${findDuplicates(ids).join(', ')}`);
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
describe('Handoff Validation', () => {
|
|
88
|
+
it('8. Handoff references are valid (target agents exist)', () => {
|
|
89
|
+
const agentIds = new Set(result.agents.map((a) => a.id));
|
|
90
|
+
for (const agent of result.agents) {
|
|
91
|
+
const handoffs = agent.frontmatter.handoffs ?? [];
|
|
92
|
+
for (const handoff of handoffs) {
|
|
93
|
+
assert.ok(agentIds.has(handoff.agent), `Agent ${agent.id} has handoff to non-existent agent '${handoff.agent}'. ` +
|
|
94
|
+
`Valid agents: ${[...agentIds].join(', ')}`);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
it('9. No circular handoff chains (single handoff does not create infinite loop)', () => {
|
|
99
|
+
// Build handoff graph
|
|
100
|
+
const handoffGraph = new Map();
|
|
101
|
+
for (const agent of result.agents) {
|
|
102
|
+
const targets = (agent.frontmatter.handoffs ?? []).map((h) => h.agent);
|
|
103
|
+
handoffGraph.set(agent.id, targets);
|
|
104
|
+
}
|
|
105
|
+
// Check for self-referential handoffs (immediate loop)
|
|
106
|
+
for (const agent of result.agents) {
|
|
107
|
+
const targets = handoffGraph.get(agent.id) ?? [];
|
|
108
|
+
assert.ok(!targets.includes(agent.id), `Agent ${agent.id} has self-referential handoff (hands off to itself)`);
|
|
109
|
+
}
|
|
110
|
+
// Note: Bidirectional handoffs (A -> B and B -> A) are allowed
|
|
111
|
+
// They represent valid collaboration patterns, not infinite loops
|
|
112
|
+
// The warning is that a single handoff chain shouldn't loop back
|
|
113
|
+
});
|
|
114
|
+
});
|
|
115
|
+
describe('Subagent Configuration', () => {
|
|
116
|
+
it('10. All agents that can be invoked as subagents have infer: true', () => {
|
|
117
|
+
const inferableAgents = getInferableAgents(result);
|
|
118
|
+
// Verify all returned agents actually have infer: true
|
|
119
|
+
for (const agent of inferableAgents) {
|
|
120
|
+
assert.strictEqual(agent.frontmatter.infer, true, `Agent ${agent.id} returned by getInferableAgents but doesn't have infer: true`);
|
|
121
|
+
}
|
|
122
|
+
// Beth should be in the list
|
|
123
|
+
const bethInferable = inferableAgents.some((a) => a.id === 'beth');
|
|
124
|
+
assert.ok(bethInferable, 'Beth must be inferable (have infer: true)');
|
|
125
|
+
});
|
|
126
|
+
});
|
|
127
|
+
describe('Agent-Specific Tool Requirements', () => {
|
|
128
|
+
it('11. Developer agent has edit tools (editFiles, createFile)', () => {
|
|
129
|
+
const developer = getAgentById(result, 'developer');
|
|
130
|
+
assert.ok(developer, 'Developer agent must exist');
|
|
131
|
+
assert.ok(Array.isArray(developer.frontmatter.tools), 'Developer must have tools array');
|
|
132
|
+
const tools = developer.frontmatter.tools;
|
|
133
|
+
assert.ok(tools.includes('editFiles'), `Developer must have 'editFiles' tool. Found: ${tools.join(', ')}`);
|
|
134
|
+
assert.ok(tools.includes('createFile'), `Developer must have 'createFile' tool. Found: ${tools.join(', ')}`);
|
|
135
|
+
});
|
|
136
|
+
it('12. Security-reviewer agent exists and has appropriate tools', () => {
|
|
137
|
+
const securityReviewer = getAgentById(result, 'security-reviewer');
|
|
138
|
+
assert.ok(securityReviewer, 'Security-reviewer agent must exist');
|
|
139
|
+
assert.ok(securityReviewer.frontmatter.name, 'Security-reviewer must have a name');
|
|
140
|
+
assert.ok(securityReviewer.frontmatter.description, 'Security-reviewer must have a description');
|
|
141
|
+
// Security reviewer should have code analysis tools
|
|
142
|
+
const tools = securityReviewer.frontmatter.tools ?? [];
|
|
143
|
+
assert.ok(tools.length > 0, 'Security-reviewer should have tools for code analysis');
|
|
144
|
+
// Should have at least codebase or textSearch for finding vulnerabilities
|
|
145
|
+
const hasAnalysisTools = tools.some((t) => ['codebase', 'textSearch', 'readFile', 'fileSearch'].includes(t));
|
|
146
|
+
assert.ok(hasAnalysisTools, `Security-reviewer should have analysis tools. Found: ${tools.join(', ')}`);
|
|
147
|
+
});
|
|
148
|
+
});
|
|
149
|
+
describe('Role Differentiation', () => {
|
|
150
|
+
it('13. Product-manager and ux-designer are distinct agents', () => {
|
|
151
|
+
const productManager = getAgentById(result, 'product-manager');
|
|
152
|
+
const uxDesigner = getAgentById(result, 'ux-designer');
|
|
153
|
+
assert.ok(productManager, 'Product-manager agent must exist');
|
|
154
|
+
assert.ok(uxDesigner, 'UX-designer agent must exist');
|
|
155
|
+
// Different IDs
|
|
156
|
+
assert.notStrictEqual(productManager.id, uxDesigner.id, 'Product-manager and UX-designer must have different IDs');
|
|
157
|
+
// Different names
|
|
158
|
+
assert.notStrictEqual(productManager.frontmatter.name, uxDesigner.frontmatter.name, 'Product-manager and UX-designer must have different names');
|
|
159
|
+
// Different descriptions (they serve different purposes)
|
|
160
|
+
assert.notStrictEqual(productManager.frontmatter.description, uxDesigner.frontmatter.description, 'Product-manager and UX-designer should have different descriptions');
|
|
161
|
+
// Different body content (different instructions)
|
|
162
|
+
assert.notStrictEqual(productManager.body, uxDesigner.body, 'Product-manager and UX-designer must have different instructions');
|
|
163
|
+
});
|
|
164
|
+
});
|
|
165
|
+
describe('Cross-Agent Consistency', () => {
|
|
166
|
+
it('All expected agents are present and loadable', () => {
|
|
167
|
+
for (const expectedId of EXPECTED_AGENT_IDS) {
|
|
168
|
+
const agent = getAgentById(result, expectedId);
|
|
169
|
+
assert.ok(agent, `Expected agent '${expectedId}' is missing from the suite`);
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
it('All agents can be found by getAgentById', () => {
|
|
173
|
+
for (const agent of result.agents) {
|
|
174
|
+
const found = getAgentById(result, agent.id);
|
|
175
|
+
assert.ok(found, `Agent ${agent.id} should be findable by ID`);
|
|
176
|
+
assert.strictEqual(found.id, agent.id);
|
|
177
|
+
}
|
|
178
|
+
});
|
|
179
|
+
it('Agent handoff network is well-connected (Beth has handoffs to specialists)', () => {
|
|
180
|
+
const beth = getAgentById(result, 'beth');
|
|
181
|
+
assert.ok(beth, 'Beth must exist');
|
|
182
|
+
const bethHandoffs = beth.frontmatter.handoffs ?? [];
|
|
183
|
+
const handoffTargets = new Set(bethHandoffs.map((h) => h.agent));
|
|
184
|
+
// Beth should be able to hand off to at least the core specialist agents
|
|
185
|
+
const coreSpecialists = ['developer', 'product-manager', 'ux-designer'];
|
|
186
|
+
for (const specialist of coreSpecialists) {
|
|
187
|
+
assert.ok(handoffTargets.has(specialist), `Beth should have handoff to ${specialist}. ` +
|
|
188
|
+
`Found handoffs to: ${[...handoffTargets].join(', ')}`);
|
|
189
|
+
}
|
|
190
|
+
});
|
|
191
|
+
});
|
|
192
|
+
});
|
|
193
|
+
/**
|
|
194
|
+
* Helper to find duplicate values in an array.
|
|
195
|
+
*/
|
|
196
|
+
function findDuplicates(arr) {
|
|
197
|
+
const seen = new Set();
|
|
198
|
+
const duplicates = new Set();
|
|
199
|
+
for (const item of arr) {
|
|
200
|
+
if (seen.has(item)) {
|
|
201
|
+
duplicates.add(item);
|
|
202
|
+
}
|
|
203
|
+
seen.add(item);
|
|
204
|
+
}
|
|
205
|
+
return [...duplicates];
|
|
206
|
+
}
|
|
207
|
+
//# sourceMappingURL=suite.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"suite.test.js","sourceRoot":"","sources":["../../../src/core/agents/suite.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tools.test.d.ts","sourceRoot":"","sources":["../../../src/core/agents/tools.test.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
|