@mclawnet/swarm 0.1.0 → 0.1.1
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/dist/__tests__/action-parser.test.d.ts +2 -0
- package/dist/__tests__/action-parser.test.d.ts.map +1 -0
- package/dist/__tests__/action-parser.test.js +91 -0
- package/dist/__tests__/action-parser.test.js.map +1 -0
- package/dist/__tests__/migration-roles.test.d.ts +2 -0
- package/dist/__tests__/migration-roles.test.d.ts.map +1 -0
- package/dist/__tests__/migration-roles.test.js +213 -0
- package/dist/__tests__/migration-roles.test.js.map +1 -0
- package/dist/__tests__/retrospective.test.d.ts +2 -0
- package/dist/__tests__/retrospective.test.d.ts.map +1 -0
- package/dist/__tests__/retrospective.test.js +436 -0
- package/dist/__tests__/retrospective.test.js.map +1 -0
- package/dist/__tests__/role-loader.test.d.ts +2 -0
- package/dist/__tests__/role-loader.test.d.ts.map +1 -0
- package/dist/__tests__/role-loader.test.js +217 -0
- package/dist/__tests__/role-loader.test.js.map +1 -0
- package/dist/__tests__/swarm-coordinator-init.test.d.ts +2 -0
- package/dist/__tests__/swarm-coordinator-init.test.d.ts.map +1 -0
- package/dist/__tests__/swarm-coordinator-init.test.js +194 -0
- package/dist/__tests__/swarm-coordinator-init.test.js.map +1 -0
- package/dist/__tests__/swarm-coordinator-roleId.test.d.ts +2 -0
- package/dist/__tests__/swarm-coordinator-roleId.test.d.ts.map +1 -0
- package/dist/__tests__/swarm-coordinator-roleId.test.js +147 -0
- package/dist/__tests__/swarm-coordinator-roleId.test.js.map +1 -0
- package/dist/__tests__/template-loader.test.d.ts +2 -0
- package/dist/__tests__/template-loader.test.d.ts.map +1 -0
- package/dist/__tests__/template-loader.test.js +103 -0
- package/dist/__tests__/template-loader.test.js.map +1 -0
- package/dist/action-parser.d.ts.map +1 -1
- package/dist/action-parser.js +96 -6
- package/dist/action-parser.js.map +1 -1
- package/dist/index.d.ts +7 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -2
- package/dist/index.js.map +1 -1
- package/dist/message-router.d.ts +6 -2
- package/dist/message-router.d.ts.map +1 -1
- package/dist/message-router.js +13 -7
- package/dist/message-router.js.map +1 -1
- package/dist/persistence.d.ts +1 -0
- package/dist/persistence.d.ts.map +1 -1
- package/dist/persistence.js +26 -3
- package/dist/persistence.js.map +1 -1
- package/dist/retrospective.d.ts +33 -0
- package/dist/retrospective.d.ts.map +1 -0
- package/dist/retrospective.js +285 -0
- package/dist/retrospective.js.map +1 -0
- package/dist/roles/role-loader.d.ts +12 -1
- package/dist/roles/role-loader.d.ts.map +1 -1
- package/dist/roles/role-loader.js +160 -7
- package/dist/roles/role-loader.js.map +1 -1
- package/dist/roles/types.d.ts +26 -2
- package/dist/roles/types.d.ts.map +1 -1
- package/dist/swarm-coordinator.d.ts +8 -2
- package/dist/swarm-coordinator.d.ts.map +1 -1
- package/dist/swarm-coordinator.js +193 -38
- package/dist/swarm-coordinator.js.map +1 -1
- package/dist/templates/template-loader.d.ts +20 -0
- package/dist/templates/template-loader.d.ts.map +1 -0
- package/dist/templates/template-loader.js +117 -0
- package/dist/templates/template-loader.js.map +1 -0
- package/dist/templates/types.d.ts +25 -0
- package/dist/templates/types.d.ts.map +1 -0
- package/dist/templates/types.js +2 -0
- package/dist/templates/types.js.map +1 -0
- package/dist/types.d.ts +11 -2
- package/dist/types.d.ts.map +1 -1
- package/package.json +12 -7
- package/roles/analyst-livermore.md +112 -0
- package/roles/designer-rams.md +266 -0
- package/roles/dev-torvalds.md +214 -0
- package/roles/developer.md +22 -1
- package/roles/director-jia.md +286 -0
- package/roles/editor-boyong.md +148 -0
- package/roles/macro-dalio.md +115 -0
- package/roles/planner-maoni.md +306 -0
- package/roles/pm-jobs.md +326 -0
- package/roles/preset-analyst-simons.md +55 -0
- package/roles/preset-architect-knuth.md +55 -0
- package/roles/preset-designer-norman.md +55 -0
- package/roles/preset-designer.md +55 -0
- package/roles/preset-dev-carmack.md +55 -0
- package/roles/preset-dev-gosling.md +55 -0
- package/roles/preset-developer.md +68 -0
- package/roles/preset-manager-grove.md +55 -0
- package/roles/preset-manager-musk.md +55 -0
- package/roles/preset-pm.md +105 -0
- package/roles/preset-researcher-feynman.md +55 -0
- package/roles/preset-reviewer.md +62 -0
- package/roles/preset-strategist-buffett.md +55 -0
- package/roles/preset-strategist-munger.md +55 -0
- package/roles/preset-strategist-sunzi.md +55 -0
- package/roles/preset-tester-beck.md +56 -0
- package/roles/preset-tester.md +63 -0
- package/roles/preset-writer-orwell.md +55 -0
- package/roles/preset-writer.md +55 -0
- package/roles/quant-simons.md +136 -0
- package/roles/queen.md +27 -1
- package/roles/reviewer-martin.md +200 -0
- package/roles/reviewer.md +18 -1
- package/roles/rhythm-tangsan.md +135 -0
- package/roles/risk-taleb.md +112 -0
- package/roles/script-shitiesheng.md +129 -0
- package/roles/storyboard-xuke.md +138 -0
- package/roles/strategist-soros.md +257 -0
- package/roles/tester-beck.md +232 -0
- package/roles/tester.md +19 -1
- package/roles/trader-jones.md +124 -0
- package/roles/vfx-guchangwei.md +129 -0
- package/roles/writer-zhouzi.md +144 -0
- package/templates/dev-team-pro.md +21 -0
- package/templates/dev-team.md +19 -0
- package/templates/minimal.md +14 -0
- package/templates/trading-team.md +22 -0
- package/templates/video-team.md +18 -0
- package/templates/writing-team.md +18 -0
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { parseRoleFile, buildRolePrompt } from "../roles/role-loader.js";
|
|
3
|
+
describe("parseRoleFile", () => {
|
|
4
|
+
it("should parse basic flat fields (backwards compat)", () => {
|
|
5
|
+
const content = `---
|
|
6
|
+
name: developer
|
|
7
|
+
shortName: dev
|
|
8
|
+
type: worker
|
|
9
|
+
description: 全栈开发工程师
|
|
10
|
+
capabilities: [code, debug, test]
|
|
11
|
+
color: "#FF6B35"
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
You are a developer. Your instanceId is {instanceId}.`;
|
|
15
|
+
const role = parseRoleFile(content);
|
|
16
|
+
expect(role.name).toBe("developer");
|
|
17
|
+
expect(role.shortName).toBe("dev");
|
|
18
|
+
expect(role.type).toBe("worker");
|
|
19
|
+
expect(role.description).toBe("全栈开发工程师");
|
|
20
|
+
expect(role.capabilities).toEqual(["code", "debug", "test"]);
|
|
21
|
+
expect(role.color).toBe("#FF6B35");
|
|
22
|
+
expect(role.promptBody).toContain("You are a developer");
|
|
23
|
+
expect(role.delegation).toBeUndefined();
|
|
24
|
+
expect(role.protocol).toBeUndefined();
|
|
25
|
+
});
|
|
26
|
+
it("should parse delegation with all field types", () => {
|
|
27
|
+
const content = `---
|
|
28
|
+
name: queen
|
|
29
|
+
shortName: queen
|
|
30
|
+
type: queen
|
|
31
|
+
description: Manager
|
|
32
|
+
color: "#FFD700"
|
|
33
|
+
delegation:
|
|
34
|
+
reportsTo: user
|
|
35
|
+
delegatesTo:
|
|
36
|
+
- role: developer
|
|
37
|
+
purpose: 编码任务
|
|
38
|
+
- role: reviewer
|
|
39
|
+
purpose: 代码审查
|
|
40
|
+
collaboratesWith:
|
|
41
|
+
- role: tester
|
|
42
|
+
purpose: 测试协调
|
|
43
|
+
canRequestHelp:
|
|
44
|
+
- role: developer
|
|
45
|
+
purpose: 技术咨询
|
|
46
|
+
escalationTarget: true
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
Body text.`;
|
|
50
|
+
const role = parseRoleFile(content);
|
|
51
|
+
expect(role.delegation).toBeDefined();
|
|
52
|
+
expect(role.delegation.reportsTo).toBe("user");
|
|
53
|
+
expect(role.delegation.delegatesTo).toEqual([
|
|
54
|
+
{ role: "developer", purpose: "编码任务" },
|
|
55
|
+
{ role: "reviewer", purpose: "代码审查" },
|
|
56
|
+
]);
|
|
57
|
+
expect(role.delegation.collaboratesWith).toEqual([
|
|
58
|
+
{ role: "tester", purpose: "测试协调" },
|
|
59
|
+
]);
|
|
60
|
+
expect(role.delegation.canRequestHelp).toEqual([
|
|
61
|
+
{ role: "developer", purpose: "技术咨询" },
|
|
62
|
+
]);
|
|
63
|
+
expect(role.delegation.escalationTarget).toBe(true);
|
|
64
|
+
});
|
|
65
|
+
it("should parse protocol list", () => {
|
|
66
|
+
const content = `---
|
|
67
|
+
name: developer
|
|
68
|
+
shortName: dev
|
|
69
|
+
type: worker
|
|
70
|
+
description: Dev
|
|
71
|
+
color: "#FF6B35"
|
|
72
|
+
protocol:
|
|
73
|
+
- 收到任务后先理解需求
|
|
74
|
+
- 编码完成后请求审查
|
|
75
|
+
- 审查通过后汇报
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
Body.`;
|
|
79
|
+
const role = parseRoleFile(content);
|
|
80
|
+
expect(role.protocol).toEqual([
|
|
81
|
+
"收到任务后先理解需求",
|
|
82
|
+
"编码完成后请求审查",
|
|
83
|
+
"审查通过后汇报",
|
|
84
|
+
]);
|
|
85
|
+
});
|
|
86
|
+
it("should parse delegation + protocol together", () => {
|
|
87
|
+
const content = `---
|
|
88
|
+
name: reviewer
|
|
89
|
+
shortName: reviewer
|
|
90
|
+
type: worker
|
|
91
|
+
description: Reviewer
|
|
92
|
+
color: "#8B5CF6"
|
|
93
|
+
delegation:
|
|
94
|
+
reportsTo: queen
|
|
95
|
+
collaboratesWith:
|
|
96
|
+
- role: developer
|
|
97
|
+
purpose: 审查代码
|
|
98
|
+
protocol:
|
|
99
|
+
- 收到审查请求后阅读代码
|
|
100
|
+
- 通过则通知提交者
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
Body.`;
|
|
104
|
+
const role = parseRoleFile(content);
|
|
105
|
+
expect(role.delegation.reportsTo).toBe("queen");
|
|
106
|
+
expect(role.delegation.collaboratesWith).toEqual([
|
|
107
|
+
{ role: "developer", purpose: "审查代码" },
|
|
108
|
+
]);
|
|
109
|
+
expect(role.protocol).toEqual([
|
|
110
|
+
"收到审查请求后阅读代码",
|
|
111
|
+
"通过则通知提交者",
|
|
112
|
+
]);
|
|
113
|
+
});
|
|
114
|
+
it("should handle partial delegation (only reportsTo)", () => {
|
|
115
|
+
const content = `---
|
|
116
|
+
name: worker
|
|
117
|
+
shortName: wrk
|
|
118
|
+
type: worker
|
|
119
|
+
description: Worker
|
|
120
|
+
color: "#888"
|
|
121
|
+
delegation:
|
|
122
|
+
reportsTo: queen
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
Body.`;
|
|
126
|
+
const role = parseRoleFile(content);
|
|
127
|
+
expect(role.delegation).toBeDefined();
|
|
128
|
+
expect(role.delegation.reportsTo).toBe("queen");
|
|
129
|
+
expect(role.delegation.delegatesTo).toBeUndefined();
|
|
130
|
+
expect(role.delegation.collaboratesWith).toBeUndefined();
|
|
131
|
+
});
|
|
132
|
+
it("should throw on missing frontmatter", () => {
|
|
133
|
+
expect(() => parseRoleFile("no frontmatter")).toThrow("missing YAML frontmatter");
|
|
134
|
+
});
|
|
135
|
+
});
|
|
136
|
+
describe("buildRolePrompt", () => {
|
|
137
|
+
it("should substitute placeholders", () => {
|
|
138
|
+
const role = parseRoleFile(`---
|
|
139
|
+
name: dev
|
|
140
|
+
shortName: dev
|
|
141
|
+
type: worker
|
|
142
|
+
description: Dev
|
|
143
|
+
color: "#888"
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
Hello {instanceId}, members: {roleList}.`);
|
|
147
|
+
const prompt = buildRolePrompt(role, "dev-0", "dev-0, queen-0");
|
|
148
|
+
expect(prompt).toContain("Hello dev-0");
|
|
149
|
+
expect(prompt).toContain("members: dev-0, queen-0");
|
|
150
|
+
});
|
|
151
|
+
it("should inject delegation section", () => {
|
|
152
|
+
const role = parseRoleFile(`---
|
|
153
|
+
name: queen
|
|
154
|
+
shortName: queen
|
|
155
|
+
type: queen
|
|
156
|
+
description: Queen
|
|
157
|
+
color: "#FFD700"
|
|
158
|
+
delegation:
|
|
159
|
+
reportsTo: user
|
|
160
|
+
delegatesTo:
|
|
161
|
+
- role: developer
|
|
162
|
+
purpose: 编码
|
|
163
|
+
- role: reviewer
|
|
164
|
+
purpose: 审查
|
|
165
|
+
collaboratesWith:
|
|
166
|
+
- role: tester
|
|
167
|
+
purpose: 测试
|
|
168
|
+
canRequestHelp:
|
|
169
|
+
- role: developer
|
|
170
|
+
purpose: 咨询
|
|
171
|
+
---
|
|
172
|
+
|
|
173
|
+
Base prompt.`);
|
|
174
|
+
const prompt = buildRolePrompt(role, "queen-0", "");
|
|
175
|
+
expect(prompt).toContain("### 协作关系");
|
|
176
|
+
expect(prompt).toContain("汇报给: user");
|
|
177
|
+
expect(prompt).toContain("可委派给: developer(编码)、reviewer(审查)");
|
|
178
|
+
expect(prompt).toContain("协作对象: tester(测试)");
|
|
179
|
+
expect(prompt).toContain("可请求协助: developer(咨询)");
|
|
180
|
+
});
|
|
181
|
+
it("should inject protocol section", () => {
|
|
182
|
+
const role = parseRoleFile(`---
|
|
183
|
+
name: dev
|
|
184
|
+
shortName: dev
|
|
185
|
+
type: worker
|
|
186
|
+
description: Dev
|
|
187
|
+
color: "#888"
|
|
188
|
+
protocol:
|
|
189
|
+
- Step A
|
|
190
|
+
- Step B
|
|
191
|
+
- Step C
|
|
192
|
+
---
|
|
193
|
+
|
|
194
|
+
Base prompt.`);
|
|
195
|
+
const prompt = buildRolePrompt(role, "dev-0", "");
|
|
196
|
+
expect(prompt).toContain("### 标准工作流程");
|
|
197
|
+
expect(prompt).toContain("1. Step A");
|
|
198
|
+
expect(prompt).toContain("2. Step B");
|
|
199
|
+
expect(prompt).toContain("3. Step C");
|
|
200
|
+
});
|
|
201
|
+
it("should not inject sections when delegation/protocol absent", () => {
|
|
202
|
+
const role = parseRoleFile(`---
|
|
203
|
+
name: dev
|
|
204
|
+
shortName: dev
|
|
205
|
+
type: worker
|
|
206
|
+
description: Dev
|
|
207
|
+
color: "#888"
|
|
208
|
+
---
|
|
209
|
+
|
|
210
|
+
Base prompt only.`);
|
|
211
|
+
const prompt = buildRolePrompt(role, "dev-0", "");
|
|
212
|
+
expect(prompt).not.toContain("### 协作关系");
|
|
213
|
+
expect(prompt).not.toContain("### 标准工作流程");
|
|
214
|
+
expect(prompt).toBe("Base prompt only.");
|
|
215
|
+
});
|
|
216
|
+
});
|
|
217
|
+
//# sourceMappingURL=role-loader.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"role-loader.test.js","sourceRoot":"","sources":["../../src/__tests__/role-loader.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"swarm-coordinator-init.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/swarm-coordinator-init.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
import { describe, it, expect, vi, beforeEach } from "vitest";
|
|
2
|
+
// Mock logger
|
|
3
|
+
vi.mock("@mclawnet/logger", () => ({
|
|
4
|
+
createLogger: () => ({
|
|
5
|
+
info: vi.fn(),
|
|
6
|
+
warn: vi.fn(),
|
|
7
|
+
error: vi.fn(),
|
|
8
|
+
debug: vi.fn(),
|
|
9
|
+
}),
|
|
10
|
+
}));
|
|
11
|
+
// Mock persistence
|
|
12
|
+
vi.mock("../persistence.js", () => ({
|
|
13
|
+
saveSwarmSnapshot: vi.fn(),
|
|
14
|
+
deleteSwarmSnapshot: vi.fn(),
|
|
15
|
+
appendMessageLog: vi.fn(),
|
|
16
|
+
loadSwarmSnapshot: vi.fn(),
|
|
17
|
+
readMessageLog: vi.fn(() => []),
|
|
18
|
+
}));
|
|
19
|
+
// Mock retrospective
|
|
20
|
+
vi.mock("../retrospective.js", () => ({
|
|
21
|
+
runRetrospective: vi.fn(async () => ({})),
|
|
22
|
+
}));
|
|
23
|
+
// Mock template-loader for template-based tests
|
|
24
|
+
vi.mock("../templates/template-loader.js", () => ({
|
|
25
|
+
loadTemplate: vi.fn((name) => {
|
|
26
|
+
if (name === "dev-team") {
|
|
27
|
+
return {
|
|
28
|
+
name: "dev-team",
|
|
29
|
+
displayName: "全栈开发团队",
|
|
30
|
+
description: "Standard team",
|
|
31
|
+
roles: [
|
|
32
|
+
{ roleName: "queen", count: 1, eager: true },
|
|
33
|
+
{ roleName: "reviewer", count: 1, eager: true },
|
|
34
|
+
{ roleName: "developer", count: 2 },
|
|
35
|
+
{ roleName: "tester", count: 1 },
|
|
36
|
+
],
|
|
37
|
+
body: "Description",
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
if (name === "minimal") {
|
|
41
|
+
return {
|
|
42
|
+
name: "minimal",
|
|
43
|
+
displayName: "极简团队",
|
|
44
|
+
description: "Minimal team",
|
|
45
|
+
roles: [
|
|
46
|
+
{ roleName: "queen", count: 1, eager: true },
|
|
47
|
+
{ roleName: "developer", count: 1 },
|
|
48
|
+
],
|
|
49
|
+
body: "Minimal",
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
throw new Error(`Template not found: ${name}`);
|
|
53
|
+
}),
|
|
54
|
+
}));
|
|
55
|
+
import { SwarmCoordinator } from "../swarm-coordinator.js";
|
|
56
|
+
function createMockSessionAdapter() {
|
|
57
|
+
const calls = [];
|
|
58
|
+
const inputs = [];
|
|
59
|
+
return {
|
|
60
|
+
_calls: calls,
|
|
61
|
+
_inputs: inputs,
|
|
62
|
+
createSession: vi.fn(async (options) => {
|
|
63
|
+
calls.push(options);
|
|
64
|
+
return `proc-${options.sessionId}`;
|
|
65
|
+
}),
|
|
66
|
+
sendInput: vi.fn((sessionId, input) => {
|
|
67
|
+
inputs.push({ sessionId, input });
|
|
68
|
+
}),
|
|
69
|
+
closeSession: vi.fn(async () => { }),
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
function createMockHubAdapter() {
|
|
73
|
+
const msgs = [];
|
|
74
|
+
return {
|
|
75
|
+
_msgs: msgs,
|
|
76
|
+
send: vi.fn((msg) => msgs.push(msg)),
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
describe("SwarmCoordinator — two-phase initialization", () => {
|
|
80
|
+
let sessionAdapter;
|
|
81
|
+
let hubAdapter;
|
|
82
|
+
let coordinator;
|
|
83
|
+
beforeEach(() => {
|
|
84
|
+
sessionAdapter = createMockSessionAdapter();
|
|
85
|
+
hubAdapter = createMockHubAdapter();
|
|
86
|
+
coordinator = new SwarmCoordinator(sessionAdapter, hubAdapter);
|
|
87
|
+
});
|
|
88
|
+
it("should spawn non-queen eager roles before queen (reviewer before queen)", async () => {
|
|
89
|
+
await coordinator.create("swarm-phase", {
|
|
90
|
+
workDir: "/tmp/test",
|
|
91
|
+
roles: [
|
|
92
|
+
{ roleName: "queen", count: 1, eager: true },
|
|
93
|
+
{ roleName: "reviewer", count: 1, eager: true },
|
|
94
|
+
{ roleName: "developer", count: 1 },
|
|
95
|
+
],
|
|
96
|
+
task: "Build feature",
|
|
97
|
+
});
|
|
98
|
+
// Only eager roles spawned (queen + reviewer), developer is on-demand
|
|
99
|
+
const spawnedSessions = sessionAdapter._calls.map((c) => c.sessionId);
|
|
100
|
+
expect(spawnedSessions).toHaveLength(2);
|
|
101
|
+
// reviewer should be spawned BEFORE queen
|
|
102
|
+
const reviewerIdx = spawnedSessions.findIndex((s) => s.includes("reviewer-"));
|
|
103
|
+
const queenIdx = spawnedSessions.findIndex((s) => s.includes("queen-"));
|
|
104
|
+
expect(reviewerIdx).toBeLessThan(queenIdx);
|
|
105
|
+
});
|
|
106
|
+
it("should create swarm from templateName", async () => {
|
|
107
|
+
await coordinator.create("swarm-tpl", {
|
|
108
|
+
workDir: "/tmp/test",
|
|
109
|
+
templateName: "dev-team",
|
|
110
|
+
task: "Build feature",
|
|
111
|
+
});
|
|
112
|
+
// dev-team has queen(eager) + reviewer(eager) + developer(x2) + tester
|
|
113
|
+
// Only eager ones spawned: reviewer then queen
|
|
114
|
+
const spawnedSessions = sessionAdapter._calls.map((c) => c.sessionId);
|
|
115
|
+
expect(spawnedSessions).toHaveLength(2);
|
|
116
|
+
const reviewerIdx = spawnedSessions.findIndex((s) => s.includes("reviewer-"));
|
|
117
|
+
const queenIdx = spawnedSessions.findIndex((s) => s.includes("queen-"));
|
|
118
|
+
expect(reviewerIdx).toBeGreaterThanOrEqual(0);
|
|
119
|
+
expect(queenIdx).toBeGreaterThanOrEqual(0);
|
|
120
|
+
expect(reviewerIdx).toBeLessThan(queenIdx);
|
|
121
|
+
});
|
|
122
|
+
it("should send init-complete message to queen after all eager roles spawned", async () => {
|
|
123
|
+
await coordinator.create("swarm-init", {
|
|
124
|
+
workDir: "/tmp/test",
|
|
125
|
+
roles: [
|
|
126
|
+
{ roleName: "queen", count: 1, eager: true },
|
|
127
|
+
{ roleName: "reviewer", count: 1, eager: true },
|
|
128
|
+
],
|
|
129
|
+
task: "Build feature",
|
|
130
|
+
});
|
|
131
|
+
// queen should receive init-complete system message + user task via sendInput
|
|
132
|
+
const queenInputs = sessionAdapter._inputs.filter((i) => i.sessionId.includes("queen-"));
|
|
133
|
+
expect(queenInputs.length).toBeGreaterThanOrEqual(2);
|
|
134
|
+
// First message should be the init-complete notification
|
|
135
|
+
const initMsg = queenInputs[0].input;
|
|
136
|
+
expect(initMsg).toContain("蜂群初始化完成");
|
|
137
|
+
expect(initMsg).toContain("reviewer-0");
|
|
138
|
+
// Second message should be the user task
|
|
139
|
+
const taskMsg = queenInputs[1].input;
|
|
140
|
+
expect(taskMsg).toContain("Build feature");
|
|
141
|
+
});
|
|
142
|
+
it("should ensure queen is always eager even if not explicitly marked", async () => {
|
|
143
|
+
await coordinator.create("swarm-queen-eager", {
|
|
144
|
+
workDir: "/tmp/test",
|
|
145
|
+
roles: [
|
|
146
|
+
{ roleName: "queen", count: 1 }, // no eager flag
|
|
147
|
+
{ roleName: "developer", count: 1 },
|
|
148
|
+
],
|
|
149
|
+
task: "Test",
|
|
150
|
+
});
|
|
151
|
+
// Queen should still be spawned (always eager)
|
|
152
|
+
const queenCall = sessionAdapter._calls.find((c) => c.sessionId.includes("queen-"));
|
|
153
|
+
expect(queenCall).toBeDefined();
|
|
154
|
+
});
|
|
155
|
+
it("should not spawn non-eager roles during creation", async () => {
|
|
156
|
+
await coordinator.create("swarm-lazy", {
|
|
157
|
+
workDir: "/tmp/test",
|
|
158
|
+
roles: [
|
|
159
|
+
{ roleName: "queen", count: 1, eager: true },
|
|
160
|
+
{ roleName: "developer", count: 2 },
|
|
161
|
+
{ roleName: "tester", count: 1 },
|
|
162
|
+
],
|
|
163
|
+
task: "Test",
|
|
164
|
+
});
|
|
165
|
+
// Only queen spawned
|
|
166
|
+
expect(sessionAdapter._calls).toHaveLength(1);
|
|
167
|
+
expect(sessionAdapter._calls[0].sessionId).toContain("queen-");
|
|
168
|
+
});
|
|
169
|
+
it("should create minimal template with only queen eager", async () => {
|
|
170
|
+
await coordinator.create("swarm-minimal", {
|
|
171
|
+
workDir: "/tmp/test",
|
|
172
|
+
templateName: "minimal",
|
|
173
|
+
task: "Quick prototype",
|
|
174
|
+
});
|
|
175
|
+
// minimal: queen(eager) + developer (not eager)
|
|
176
|
+
expect(sessionAdapter._calls).toHaveLength(1);
|
|
177
|
+
expect(sessionAdapter._calls[0].sessionId).toContain("queen-");
|
|
178
|
+
});
|
|
179
|
+
it("should include queen's roleList with already-spawned reviewer", async () => {
|
|
180
|
+
await coordinator.create("swarm-rolelist", {
|
|
181
|
+
workDir: "/tmp/test",
|
|
182
|
+
roles: [
|
|
183
|
+
{ roleName: "queen", count: 1, eager: true },
|
|
184
|
+
{ roleName: "reviewer", count: 1, eager: true },
|
|
185
|
+
],
|
|
186
|
+
task: "Test",
|
|
187
|
+
});
|
|
188
|
+
// Queen is spawned last, so her systemPrompt should include reviewer-0
|
|
189
|
+
const queenCall = sessionAdapter._calls.find((c) => c.sessionId.includes("queen-"));
|
|
190
|
+
expect(queenCall).toBeDefined();
|
|
191
|
+
expect(queenCall.systemPrompt).toContain("reviewer-0");
|
|
192
|
+
});
|
|
193
|
+
});
|
|
194
|
+
//# sourceMappingURL=swarm-coordinator-init.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"swarm-coordinator-init.test.js","sourceRoot":"","sources":["../../src/__tests__/swarm-coordinator-init.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAE9D,cAAc;AACd,EAAE,CAAC,IAAI,CAAC,kBAAkB,EAAE,GAAG,EAAE,CAAC,CAAC;IACjC,YAAY,EAAE,GAAG,EAAE,CAAC,CAAC;QACnB,IAAI,EAAE,EAAE,CAAC,EAAE,EAAE;QACb,IAAI,EAAE,EAAE,CAAC,EAAE,EAAE;QACb,KAAK,EAAE,EAAE,CAAC,EAAE,EAAE;QACd,KAAK,EAAE,EAAE,CAAC,EAAE,EAAE;KACf,CAAC;CACH,CAAC,CAAC,CAAC;AAEJ,mBAAmB;AACnB,EAAE,CAAC,IAAI,CAAC,mBAAmB,EAAE,GAAG,EAAE,CAAC,CAAC;IAClC,iBAAiB,EAAE,EAAE,CAAC,EAAE,EAAE;IAC1B,mBAAmB,EAAE,EAAE,CAAC,EAAE,EAAE;IAC5B,gBAAgB,EAAE,EAAE,CAAC,EAAE,EAAE;IACzB,iBAAiB,EAAE,EAAE,CAAC,EAAE,EAAE;IAC1B,cAAc,EAAE,EAAE,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC;CAChC,CAAC,CAAC,CAAC;AAEJ,qBAAqB;AACrB,EAAE,CAAC,IAAI,CAAC,qBAAqB,EAAE,GAAG,EAAE,CAAC,CAAC;IACpC,gBAAgB,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;CAC1C,CAAC,CAAC,CAAC;AAEJ,gDAAgD;AAChD,EAAE,CAAC,IAAI,CAAC,iCAAiC,EAAE,GAAG,EAAE,CAAC,CAAC;IAChD,YAAY,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,IAAY,EAAE,EAAE;QACnC,IAAI,IAAI,KAAK,UAAU,EAAE,CAAC;YACxB,OAAO;gBACL,IAAI,EAAE,UAAU;gBAChB,WAAW,EAAE,QAAQ;gBACrB,WAAW,EAAE,eAAe;gBAC5B,KAAK,EAAE;oBACL,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE;oBAC5C,EAAE,QAAQ,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE;oBAC/C,EAAE,QAAQ,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC,EAAE;oBACnC,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,EAAE;iBACjC;gBACD,IAAI,EAAE,aAAa;aACpB,CAAC;QACJ,CAAC;QACD,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YACvB,OAAO;gBACL,IAAI,EAAE,SAAS;gBACf,WAAW,EAAE,MAAM;gBACnB,WAAW,EAAE,cAAc;gBAC3B,KAAK,EAAE;oBACL,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE;oBAC5C,EAAE,QAAQ,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC,EAAE;iBACpC;gBACD,IAAI,EAAE,SAAS;aAChB,CAAC;QACJ,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,uBAAuB,IAAI,EAAE,CAAC,CAAC;IACjD,CAAC,CAAC;CACH,CAAC,CAAC,CAAC;AAEJ,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAG3D,SAAS,wBAAwB;IAI/B,MAAM,KAAK,GAAe,EAAE,CAAC;IAC7B,MAAM,MAAM,GAAe,EAAE,CAAC;IAC9B,OAAO;QACL,MAAM,EAAE,KAAK;QACb,OAAO,EAAE,MAAM;QACf,aAAa,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;YACrC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACpB,OAAO,QAAQ,OAAO,CAAC,SAAS,EAAE,CAAC;QACrC,CAAC,CAAC;QACF,SAAS,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,SAAS,EAAE,KAAK,EAAE,EAAE;YACpC,MAAM,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC;QACpC,CAAC,CAAC;QACF,YAAY,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,IAAI,EAAE,GAAE,CAAC,CAAC;KACpC,CAAC;AACJ,CAAC;AAED,SAAS,oBAAoB;IAC3B,MAAM,IAAI,GAAU,EAAE,CAAC;IACvB,OAAO;QACL,KAAK,EAAE,IAAI;QACX,IAAI,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;KACrC,CAAC;AACJ,CAAC;AAED,QAAQ,CAAC,6CAA6C,EAAE,GAAG,EAAE;IAC3D,IAAI,cAA2D,CAAC;IAChE,IAAI,UAAmD,CAAC;IACxD,IAAI,WAA6B,CAAC;IAElC,UAAU,CAAC,GAAG,EAAE;QACd,cAAc,GAAG,wBAAwB,EAAE,CAAC;QAC5C,UAAU,GAAG,oBAAoB,EAAE,CAAC;QACpC,WAAW,GAAG,IAAI,gBAAgB,CAAC,cAAc,EAAE,UAAU,CAAC,CAAC;IACjE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yEAAyE,EAAE,KAAK,IAAI,EAAE;QACvF,MAAM,WAAW,CAAC,MAAM,CAAC,aAAa,EAAE;YACtC,OAAO,EAAE,WAAW;YACpB,KAAK,EAAE;gBACL,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE;gBAC5C,EAAE,QAAQ,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE;gBAC/C,EAAE,QAAQ,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC,EAAE;aACpC;YACD,IAAI,EAAE,eAAe;SACtB,CAAC,CAAC;QAEH,sEAAsE;QACtE,MAAM,eAAe,GAAG,cAAc,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;QACtE,MAAM,CAAC,eAAe,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAExC,0CAA0C;QAC1C,MAAM,WAAW,GAAG,eAAe,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC;QAC9E,MAAM,QAAQ,GAAG,eAAe,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;QACxE,MAAM,CAAC,WAAW,CAAC,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;IAC7C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uCAAuC,EAAE,KAAK,IAAI,EAAE;QACrD,MAAM,WAAW,CAAC,MAAM,CAAC,WAAW,EAAE;YACpC,OAAO,EAAE,WAAW;YACpB,YAAY,EAAE,UAAU;YACxB,IAAI,EAAE,eAAe;SACtB,CAAC,CAAC;QAEH,uEAAuE;QACvE,+CAA+C;QAC/C,MAAM,eAAe,GAAG,cAAc,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;QACtE,MAAM,CAAC,eAAe,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAExC,MAAM,WAAW,GAAG,eAAe,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC;QAC9E,MAAM,QAAQ,GAAG,eAAe,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;QACxE,MAAM,CAAC,WAAW,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC;QAC9C,MAAM,CAAC,QAAQ,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC;QAC3C,MAAM,CAAC,WAAW,CAAC,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;IAC7C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0EAA0E,EAAE,KAAK,IAAI,EAAE;QACxF,MAAM,WAAW,CAAC,MAAM,CAAC,YAAY,EAAE;YACrC,OAAO,EAAE,WAAW;YACpB,KAAK,EAAE;gBACL,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE;gBAC5C,EAAE,QAAQ,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE;aAChD;YACD,IAAI,EAAE,eAAe;SACtB,CAAC,CAAC;QAEH,8EAA8E;QAC9E,MAAM,WAAW,GAAG,cAAc,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CACtD,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAC/B,CAAC;QACF,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC;QAErD,yDAAyD;QACzD,MAAM,OAAO,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;QACrC,MAAM,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;QACrC,MAAM,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;QAExC,yCAAyC;QACzC,MAAM,OAAO,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;QACrC,MAAM,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC;IAC7C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mEAAmE,EAAE,KAAK,IAAI,EAAE;QACjF,MAAM,WAAW,CAAC,MAAM,CAAC,mBAAmB,EAAE;YAC5C,OAAO,EAAE,WAAW;YACpB,KAAK,EAAE;gBACL,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,gBAAgB;gBACjD,EAAE,QAAQ,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC,EAAE;aACpC;YACD,IAAI,EAAE,MAAM;SACb,CAAC,CAAC;QAEH,+CAA+C;QAC/C,MAAM,SAAS,GAAG,cAAc,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CACjD,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAC/B,CAAC;QACF,MAAM,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,CAAC;IAClC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kDAAkD,EAAE,KAAK,IAAI,EAAE;QAChE,MAAM,WAAW,CAAC,MAAM,CAAC,YAAY,EAAE;YACrC,OAAO,EAAE,WAAW;YACpB,KAAK,EAAE;gBACL,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE;gBAC5C,EAAE,QAAQ,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC,EAAE;gBACnC,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,EAAE;aACjC;YACD,IAAI,EAAE,MAAM;SACb,CAAC,CAAC;QAEH,qBAAqB;QACrB,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAC9C,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;IACjE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sDAAsD,EAAE,KAAK,IAAI,EAAE;QACpE,MAAM,WAAW,CAAC,MAAM,CAAC,eAAe,EAAE;YACxC,OAAO,EAAE,WAAW;YACpB,YAAY,EAAE,SAAS;YACvB,IAAI,EAAE,iBAAiB;SACxB,CAAC,CAAC;QAEH,gDAAgD;QAChD,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAC9C,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;IACjE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+DAA+D,EAAE,KAAK,IAAI,EAAE;QAC7E,MAAM,WAAW,CAAC,MAAM,CAAC,gBAAgB,EAAE;YACzC,OAAO,EAAE,WAAW;YACpB,KAAK,EAAE;gBACL,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE;gBAC5C,EAAE,QAAQ,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE;aAChD;YACD,IAAI,EAAE,MAAM;SACb,CAAC,CAAC;QAEH,uEAAuE;QACvE,MAAM,SAAS,GAAG,cAAc,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CACjD,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAC/B,CAAC;QACF,MAAM,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,CAAC;QAChC,MAAM,CAAC,SAAU,CAAC,YAAY,CAAC,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;IAC1D,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"swarm-coordinator-roleId.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/swarm-coordinator-roleId.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { describe, it, expect, vi, beforeEach } from "vitest";
|
|
2
|
+
// Mock logger
|
|
3
|
+
vi.mock("@mclawnet/logger", () => ({
|
|
4
|
+
createLogger: () => ({
|
|
5
|
+
info: vi.fn(),
|
|
6
|
+
warn: vi.fn(),
|
|
7
|
+
error: vi.fn(),
|
|
8
|
+
debug: vi.fn(),
|
|
9
|
+
}),
|
|
10
|
+
}));
|
|
11
|
+
// Mock persistence — prevent file system side effects
|
|
12
|
+
vi.mock("../persistence.js", () => ({
|
|
13
|
+
saveSwarmSnapshot: vi.fn(),
|
|
14
|
+
deleteSwarmSnapshot: vi.fn(),
|
|
15
|
+
appendMessageLog: vi.fn(),
|
|
16
|
+
loadSwarmSnapshot: vi.fn(),
|
|
17
|
+
readMessageLog: vi.fn(() => []),
|
|
18
|
+
}));
|
|
19
|
+
// Mock retrospective
|
|
20
|
+
vi.mock("../retrospective.js", () => ({
|
|
21
|
+
runRetrospective: vi.fn(async () => ({})),
|
|
22
|
+
}));
|
|
23
|
+
import { SwarmCoordinator } from "../swarm-coordinator.js";
|
|
24
|
+
import { BUILTIN_ROLES } from "@mclawnet/memory";
|
|
25
|
+
// ── Mock adapters ───────────────────────────────────────────────────
|
|
26
|
+
function createMockSessionAdapter() {
|
|
27
|
+
const calls = [];
|
|
28
|
+
return {
|
|
29
|
+
_calls: calls,
|
|
30
|
+
createSession: vi.fn(async (options) => {
|
|
31
|
+
calls.push(options);
|
|
32
|
+
return `proc-${options.sessionId}`;
|
|
33
|
+
}),
|
|
34
|
+
sendInput: vi.fn(),
|
|
35
|
+
closeSession: vi.fn(async () => { }),
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
function createMockHubAdapter() {
|
|
39
|
+
return { send: vi.fn() };
|
|
40
|
+
}
|
|
41
|
+
// ── Tests ───────────────────────────────────────────────────────────
|
|
42
|
+
describe("SwarmCoordinator — roleId propagation", () => {
|
|
43
|
+
let sessionAdapter;
|
|
44
|
+
let hubAdapter;
|
|
45
|
+
let coordinator;
|
|
46
|
+
beforeEach(() => {
|
|
47
|
+
sessionAdapter = createMockSessionAdapter();
|
|
48
|
+
hubAdapter = createMockHubAdapter();
|
|
49
|
+
coordinator = new SwarmCoordinator(sessionAdapter, hubAdapter);
|
|
50
|
+
});
|
|
51
|
+
it("should pass correct roleId for builtin roles (queen eager, developer on-demand)", async () => {
|
|
52
|
+
await coordinator.create("swarm-1", {
|
|
53
|
+
workDir: "/tmp/test",
|
|
54
|
+
roles: [
|
|
55
|
+
{ roleName: "queen", count: 1 },
|
|
56
|
+
{ roleName: "developer", count: 1 },
|
|
57
|
+
],
|
|
58
|
+
task: "Build something",
|
|
59
|
+
});
|
|
60
|
+
// Only queen is eager-spawned; developer is on-demand
|
|
61
|
+
expect(sessionAdapter._calls.length).toBe(1);
|
|
62
|
+
const queenCall = sessionAdapter._calls.find((c) => c.sessionId.includes("queen-"));
|
|
63
|
+
expect(queenCall).toBeDefined();
|
|
64
|
+
expect(queenCall.roleId).toBe(BUILTIN_ROLES["queen"]?.id ?? "role-queen");
|
|
65
|
+
// Manually spawn developer to verify roleId
|
|
66
|
+
await coordinator.spawnRole("swarm-1", "developer");
|
|
67
|
+
const devCall = sessionAdapter._calls.find((c) => c.sessionId.includes("dev-"));
|
|
68
|
+
expect(devCall).toBeDefined();
|
|
69
|
+
expect(devCall.roleId).toBe(BUILTIN_ROLES["developer"]?.id ?? "role-developer");
|
|
70
|
+
});
|
|
71
|
+
it("should pass systemPrompt without memory prefix (SessionManager handles it)", async () => {
|
|
72
|
+
await coordinator.create("swarm-2", {
|
|
73
|
+
workDir: "/tmp/test",
|
|
74
|
+
roles: [{ roleName: "queen", count: 1 }],
|
|
75
|
+
task: "Build feature",
|
|
76
|
+
});
|
|
77
|
+
const call = sessionAdapter._calls[0];
|
|
78
|
+
expect(call.systemPrompt).toBeDefined();
|
|
79
|
+
// systemPrompt should be the role prompt, NOT prefixed with memory section
|
|
80
|
+
// (that's SessionManager's job via roleId)
|
|
81
|
+
expect(call.systemPrompt).not.toContain("buildMemorySection");
|
|
82
|
+
});
|
|
83
|
+
it("should not pass mcpConfigPath (SessionManager generates it via roleId)", async () => {
|
|
84
|
+
await coordinator.create("swarm-3", {
|
|
85
|
+
workDir: "/tmp/test",
|
|
86
|
+
roles: [{ roleName: "queen", count: 1 }],
|
|
87
|
+
task: "Build feature",
|
|
88
|
+
});
|
|
89
|
+
const call = sessionAdapter._calls[0];
|
|
90
|
+
expect(call.mcpConfigPath).toBeUndefined();
|
|
91
|
+
});
|
|
92
|
+
it("should use fallback roleId for custom/unknown role names", async () => {
|
|
93
|
+
await coordinator.create("swarm-4", {
|
|
94
|
+
workDir: "/tmp/test",
|
|
95
|
+
roles: [
|
|
96
|
+
{ roleName: "queen", count: 1 },
|
|
97
|
+
{
|
|
98
|
+
roleName: "data-engineer",
|
|
99
|
+
count: 1,
|
|
100
|
+
customDefinition: {
|
|
101
|
+
name: "data-engineer",
|
|
102
|
+
shortName: "de",
|
|
103
|
+
description: "Data pipeline engineer",
|
|
104
|
+
capabilities: ["etl", "sql"],
|
|
105
|
+
color: "#00FF00",
|
|
106
|
+
promptBody: "You build data pipelines.",
|
|
107
|
+
},
|
|
108
|
+
},
|
|
109
|
+
],
|
|
110
|
+
task: "Build ETL",
|
|
111
|
+
});
|
|
112
|
+
// Manually spawn custom role (on-demand)
|
|
113
|
+
await coordinator.spawnRole("swarm-4", "data-engineer", undefined, undefined, undefined, {
|
|
114
|
+
name: "data-engineer",
|
|
115
|
+
shortName: "de",
|
|
116
|
+
description: "Data pipeline engineer",
|
|
117
|
+
capabilities: ["etl", "sql"],
|
|
118
|
+
color: "#00FF00",
|
|
119
|
+
promptBody: "You build data pipelines.",
|
|
120
|
+
});
|
|
121
|
+
const call = sessionAdapter._calls.find((c) => c.sessionId.includes("de-"));
|
|
122
|
+
expect(call).toBeDefined();
|
|
123
|
+
expect(call.roleId).toBe("role-data-engineer");
|
|
124
|
+
});
|
|
125
|
+
it("should pass workDir to each role session", async () => {
|
|
126
|
+
await coordinator.create("swarm-5", {
|
|
127
|
+
workDir: "/projects/myapp",
|
|
128
|
+
roles: [{ roleName: "queen", count: 1 }],
|
|
129
|
+
task: "Fix bug",
|
|
130
|
+
});
|
|
131
|
+
const call = sessionAdapter._calls[0];
|
|
132
|
+
expect(call.workDir).toBe("/projects/myapp");
|
|
133
|
+
});
|
|
134
|
+
it("should pass additionalDirs to createSession when provided via spawnRole", async () => {
|
|
135
|
+
await coordinator.create("swarm-dirs", {
|
|
136
|
+
workDir: "/tmp/test",
|
|
137
|
+
roles: [{ roleName: "queen", count: 1 }],
|
|
138
|
+
task: "Build feature",
|
|
139
|
+
});
|
|
140
|
+
// Manually spawn a role with additionalDirs
|
|
141
|
+
await coordinator.spawnRole("swarm-dirs", "developer", undefined, "Extra task", undefined, undefined, ["/extra/dir1", "/extra/dir2"]);
|
|
142
|
+
// Last call should have additionalDirs
|
|
143
|
+
const lastCall = sessionAdapter._calls[sessionAdapter._calls.length - 1];
|
|
144
|
+
expect(lastCall.additionalDirs).toEqual(["/extra/dir1", "/extra/dir2"]);
|
|
145
|
+
});
|
|
146
|
+
});
|
|
147
|
+
//# sourceMappingURL=swarm-coordinator-roleId.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"swarm-coordinator-roleId.test.js","sourceRoot":"","sources":["../../src/__tests__/swarm-coordinator-roleId.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"template-loader.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/template-loader.test.ts"],"names":[],"mappings":""}
|