@mclawnet/swarm 0.1.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/dist/action-parser.d.ts +16 -0
- package/dist/action-parser.d.ts.map +1 -0
- package/dist/action-parser.js +81 -0
- package/dist/action-parser.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/message-router.d.ts +33 -0
- package/dist/message-router.d.ts.map +1 -0
- package/dist/message-router.js +54 -0
- package/dist/message-router.js.map +1 -0
- package/dist/persistence.d.ts +23 -0
- package/dist/persistence.d.ts.map +1 -0
- package/dist/persistence.js +61 -0
- package/dist/persistence.js.map +1 -0
- package/dist/recovery.d.ts +5 -0
- package/dist/recovery.d.ts.map +1 -0
- package/dist/recovery.js +36 -0
- package/dist/recovery.js.map +1 -0
- package/dist/roles/role-loader.d.ts +16 -0
- package/dist/roles/role-loader.d.ts.map +1 -0
- package/dist/roles/role-loader.js +103 -0
- package/dist/roles/role-loader.js.map +1 -0
- package/dist/roles/types.d.ts +18 -0
- package/dist/roles/types.d.ts.map +1 -0
- package/dist/roles/types.js +2 -0
- package/dist/roles/types.js.map +1 -0
- package/dist/swarm-coordinator.d.ts +69 -0
- package/dist/swarm-coordinator.d.ts.map +1 -0
- package/dist/swarm-coordinator.js +637 -0
- package/dist/swarm-coordinator.js.map +1 -0
- package/dist/types.d.ts +123 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +31 -0
- package/roles/developer.md +53 -0
- package/roles/queen.md +136 -0
- package/roles/reviewer.md +59 -0
- package/roles/tester.md +53 -0
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { SwarmAction } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Parse ```swarm code blocks from Claude output text.
|
|
4
|
+
* Returns extracted actions and the text with swarm blocks removed.
|
|
5
|
+
*/
|
|
6
|
+
export declare function parseSwarmActions(text: string): {
|
|
7
|
+
actions: SwarmAction[];
|
|
8
|
+
cleanText: string;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Extract a plan object from Queen's output text.
|
|
12
|
+
* Queen outputs plans in ```json code blocks with { "plan": { ... } } format.
|
|
13
|
+
* Also handles inline JSON (no code block) containing a "plan" key.
|
|
14
|
+
*/
|
|
15
|
+
export declare function parsePlanFromText(text: string): unknown | null;
|
|
16
|
+
//# sourceMappingURL=action-parser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"action-parser.d.ts","sourceRoot":"","sources":["../src/action-parser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG;IAC/C,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;CACnB,CAqBA;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,GAAG,IAAI,CAqC9D"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parse ```swarm code blocks from Claude output text.
|
|
3
|
+
* Returns extracted actions and the text with swarm blocks removed.
|
|
4
|
+
*/
|
|
5
|
+
export function parseSwarmActions(text) {
|
|
6
|
+
const actions = [];
|
|
7
|
+
const swarmBlockRegex = /```swarm\s*\n([\s\S]*?)```/g;
|
|
8
|
+
let match;
|
|
9
|
+
while ((match = swarmBlockRegex.exec(text)) !== null) {
|
|
10
|
+
const jsonStr = match[1].trim();
|
|
11
|
+
try {
|
|
12
|
+
const parsed = JSON.parse(jsonStr);
|
|
13
|
+
if (parsed && typeof parsed.action === "string") {
|
|
14
|
+
actions.push(parsed);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
// Malformed JSON in swarm block — skip
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
// Remove swarm blocks from text for clean display
|
|
22
|
+
const cleanText = text.replace(swarmBlockRegex, "").trim();
|
|
23
|
+
return { actions, cleanText };
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Extract a plan object from Queen's output text.
|
|
27
|
+
* Queen outputs plans in ```json code blocks with { "plan": { ... } } format.
|
|
28
|
+
* Also handles inline JSON (no code block) containing a "plan" key.
|
|
29
|
+
*/
|
|
30
|
+
export function parsePlanFromText(text) {
|
|
31
|
+
// Try ```json code blocks first
|
|
32
|
+
const jsonBlockRegex = /```json\s*\n([\s\S]*?)```/g;
|
|
33
|
+
let match;
|
|
34
|
+
while ((match = jsonBlockRegex.exec(text)) !== null) {
|
|
35
|
+
const plan = tryExtractPlan(match[1].trim());
|
|
36
|
+
if (plan)
|
|
37
|
+
return plan;
|
|
38
|
+
}
|
|
39
|
+
// Try inline JSON containing "plan" key (Queen sometimes outputs without code block)
|
|
40
|
+
// Use a bracket-balancing approach to extract complete JSON objects
|
|
41
|
+
const planKeyIdx = text.indexOf('"plan"');
|
|
42
|
+
if (planKeyIdx !== -1) {
|
|
43
|
+
// Find the opening brace before "plan"
|
|
44
|
+
let startIdx = text.lastIndexOf("{", planKeyIdx);
|
|
45
|
+
if (startIdx !== -1) {
|
|
46
|
+
// Balance braces to find the complete JSON object
|
|
47
|
+
let depth = 0;
|
|
48
|
+
let endIdx = startIdx;
|
|
49
|
+
for (let i = startIdx; i < text.length; i++) {
|
|
50
|
+
if (text[i] === "{")
|
|
51
|
+
depth++;
|
|
52
|
+
else if (text[i] === "}") {
|
|
53
|
+
depth--;
|
|
54
|
+
if (depth === 0) {
|
|
55
|
+
endIdx = i + 1;
|
|
56
|
+
break;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
if (depth === 0 && endIdx > startIdx) {
|
|
61
|
+
const plan = tryExtractPlan(text.slice(startIdx, endIdx));
|
|
62
|
+
if (plan)
|
|
63
|
+
return plan;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
function tryExtractPlan(jsonStr) {
|
|
70
|
+
try {
|
|
71
|
+
const parsed = JSON.parse(jsonStr);
|
|
72
|
+
if (parsed && typeof parsed === "object" && parsed.plan && typeof parsed.plan === "object") {
|
|
73
|
+
return parsed.plan;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
// Not valid JSON — skip
|
|
78
|
+
}
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=action-parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"action-parser.js","sourceRoot":"","sources":["../src/action-parser.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export { SwarmCoordinator } from "./swarm-coordinator.js";
|
|
2
|
+
export { LocalMessageRouter } from "./message-router.js";
|
|
3
|
+
export type { MessageRouter } from "./message-router.js";
|
|
4
|
+
export { parseSwarmActions } from "./action-parser.js";
|
|
5
|
+
export { initRoles, loadRole, listRoles, buildRolePrompt } from "./roles/role-loader.js";
|
|
6
|
+
export { saveSwarmSnapshot, loadSwarmSnapshot, deleteSwarmSnapshot, appendMessageLog, listRecoverableSwarmIds, } from "./persistence.js";
|
|
7
|
+
export type { SwarmSnapshot } from "./persistence.js";
|
|
8
|
+
export { listRecoverableSwarms, recoverSwarm } from "./recovery.js";
|
|
9
|
+
export type { SessionAdapter, HubAdapter, SwarmInstance, RoleInstance, SwarmAction, SwarmMessage, SwarmCreateOptions, RouteEndpoint, SwarmStatus, PlanStatus, } from "./types.js";
|
|
10
|
+
export type { RoleDefinition } from "./roles/types.js";
|
|
11
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AACzD,YAAY,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzF,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,mBAAmB,EACnB,gBAAgB,EAChB,uBAAuB,GACxB,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,qBAAqB,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAEpE,YAAY,EACV,cAAc,EACd,UAAU,EACV,aAAa,EACb,YAAY,EACZ,WAAW,EACX,YAAY,EACZ,kBAAkB,EAClB,aAAa,EACb,WAAW,EACX,UAAU,GACX,MAAM,YAAY,CAAC;AAEpB,YAAY,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
// @mclawnet/swarm — Swarm coordination, message routing, and role management
|
|
2
|
+
export { SwarmCoordinator } from "./swarm-coordinator.js";
|
|
3
|
+
export { LocalMessageRouter } from "./message-router.js";
|
|
4
|
+
export { parseSwarmActions } from "./action-parser.js";
|
|
5
|
+
export { initRoles, loadRole, listRoles, buildRolePrompt } from "./roles/role-loader.js";
|
|
6
|
+
export { saveSwarmSnapshot, loadSwarmSnapshot, deleteSwarmSnapshot, appendMessageLog, listRecoverableSwarmIds, } from "./persistence.js";
|
|
7
|
+
export { listRecoverableSwarms, recoverSwarm } from "./recovery.js";
|
|
8
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAE7E,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAEzD,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzF,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,mBAAmB,EACnB,gBAAgB,EAChB,uBAAuB,GACxB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAE,qBAAqB,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { SessionAdapter } from "./types.js";
|
|
2
|
+
import type { SwarmMessage, RouteEndpoint } from "./types.js";
|
|
3
|
+
/**
|
|
4
|
+
* Abstract message router — decouples communication from transport.
|
|
5
|
+
* LocalMessageRouter uses stdin/stdout via SessionAdapter.
|
|
6
|
+
* Future RemoteMessageRouter can use Hub WebSocket relay.
|
|
7
|
+
*/
|
|
8
|
+
export interface MessageRouter {
|
|
9
|
+
/** Send a message to a specific role instance */
|
|
10
|
+
send(targetInstanceId: string, message: SwarmMessage): void;
|
|
11
|
+
/** Broadcast a message to all active role instances */
|
|
12
|
+
broadcast(message: SwarmMessage, excludeInstanceId?: string): void;
|
|
13
|
+
/** Register a role instance in the routing table */
|
|
14
|
+
register(instanceId: string, endpoint: RouteEndpoint): void;
|
|
15
|
+
/** Unregister a role instance */
|
|
16
|
+
unregister(instanceId: string): void;
|
|
17
|
+
/** Check if a route exists */
|
|
18
|
+
has(instanceId: string): boolean;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Routes messages to local Claude CLI processes via SessionAdapter.sendInput().
|
|
22
|
+
*/
|
|
23
|
+
export declare class LocalMessageRouter implements MessageRouter {
|
|
24
|
+
private sessionAdapter;
|
|
25
|
+
private routes;
|
|
26
|
+
constructor(sessionAdapter: SessionAdapter);
|
|
27
|
+
send(targetInstanceId: string, message: SwarmMessage): void;
|
|
28
|
+
broadcast(message: SwarmMessage, excludeInstanceId?: string): void;
|
|
29
|
+
register(instanceId: string, endpoint: RouteEndpoint): void;
|
|
30
|
+
unregister(instanceId: string): void;
|
|
31
|
+
has(instanceId: string): boolean;
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=message-router.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"message-router.d.ts","sourceRoot":"","sources":["../src/message-router.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAO9D;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC5B,iDAAiD;IACjD,IAAI,CAAC,gBAAgB,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,GAAG,IAAI,CAAC;IAE5D,uDAAuD;IACvD,SAAS,CAAC,OAAO,EAAE,YAAY,EAAE,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAEnE,oDAAoD;IACpD,QAAQ,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,aAAa,GAAG,IAAI,CAAC;IAE5D,iCAAiC;IACjC,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAErC,8BAA8B;IAC9B,GAAG,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC;CAClC;AAID;;GAEG;AACH,qBAAa,kBAAmB,YAAW,aAAa;IAG1C,OAAO,CAAC,cAAc;IAFlC,OAAO,CAAC,MAAM,CAAoC;gBAE9B,cAAc,EAAE,cAAc;IAElD,IAAI,CAAC,gBAAgB,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,GAAG,IAAI;IAgB3D,SAAS,CAAC,OAAO,EAAE,YAAY,EAAE,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI;IAQlE,QAAQ,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,aAAa,GAAG,IAAI;IAI3D,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAIpC,GAAG,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO;CAGjC"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { createLogger } from "@mclawnet/logger";
|
|
2
|
+
const log = createLogger({ module: "swarm/router" });
|
|
3
|
+
// ── Local Implementation ────────────────────────────────────────────
|
|
4
|
+
/**
|
|
5
|
+
* Routes messages to local Claude CLI processes via SessionAdapter.sendInput().
|
|
6
|
+
*/
|
|
7
|
+
export class LocalMessageRouter {
|
|
8
|
+
sessionAdapter;
|
|
9
|
+
routes = new Map();
|
|
10
|
+
constructor(sessionAdapter) {
|
|
11
|
+
this.sessionAdapter = sessionAdapter;
|
|
12
|
+
}
|
|
13
|
+
send(targetInstanceId, message) {
|
|
14
|
+
const endpoint = this.routes.get(targetInstanceId);
|
|
15
|
+
if (!endpoint) {
|
|
16
|
+
log.warn({ targetInstanceId }, "no route found");
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
if (endpoint.kind === "local") {
|
|
20
|
+
const formatted = formatMessageForClaude(message);
|
|
21
|
+
this.sessionAdapter.sendInput(endpoint.roleSessionId, formatted);
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
// Remote routing — not yet implemented
|
|
25
|
+
log.warn({ targetInstanceId }, "remote routing not yet implemented");
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
broadcast(message, excludeInstanceId) {
|
|
29
|
+
for (const [instanceId] of this.routes) {
|
|
30
|
+
if (instanceId !== excludeInstanceId) {
|
|
31
|
+
this.send(instanceId, message);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
register(instanceId, endpoint) {
|
|
36
|
+
this.routes.set(instanceId, endpoint);
|
|
37
|
+
}
|
|
38
|
+
unregister(instanceId) {
|
|
39
|
+
this.routes.delete(instanceId);
|
|
40
|
+
}
|
|
41
|
+
has(instanceId) {
|
|
42
|
+
return this.routes.has(instanceId);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
// ── Formatting ──────────────────────────────────────────────────────
|
|
46
|
+
function formatMessageForClaude(message) {
|
|
47
|
+
const parts = [];
|
|
48
|
+
parts.push(`[来自 ${message.from}]`);
|
|
49
|
+
if (message.taskId)
|
|
50
|
+
parts.push(`(任务: ${message.taskId})`);
|
|
51
|
+
parts.push(message.data);
|
|
52
|
+
return parts.join(" ");
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=message-router.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"message-router.js","sourceRoot":"","sources":["../src/message-router.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAEhD,MAAM,GAAG,GAAG,YAAY,CAAC,EAAE,MAAM,EAAE,cAAc,EAAE,CAAC,CAAC;AA0BrD,uEAAuE;AAEvE;;GAEG;AACH,MAAM,OAAO,kBAAkB;IAGT;IAFZ,MAAM,GAAG,IAAI,GAAG,EAAyB,CAAC;IAElD,YAAoB,cAA8B;QAA9B,mBAAc,GAAd,cAAc,CAAgB;IAAG,CAAC;IAEtD,IAAI,CAAC,gBAAwB,EAAE,OAAqB;QAClD,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;QACnD,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,GAAG,CAAC,IAAI,CAAC,EAAE,gBAAgB,EAAE,EAAE,gBAAgB,CAAC,CAAC;YACjD,OAAO;QACT,CAAC;QAED,IAAI,QAAQ,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;YAC9B,MAAM,SAAS,GAAG,sBAAsB,CAAC,OAAO,CAAC,CAAC;YAClD,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,QAAQ,CAAC,aAAa,EAAE,SAAS,CAAC,CAAC;QACnE,CAAC;aAAM,CAAC;YACN,uCAAuC;YACvC,GAAG,CAAC,IAAI,CAAC,EAAE,gBAAgB,EAAE,EAAE,oCAAoC,CAAC,CAAC;QACvE,CAAC;IACH,CAAC;IAED,SAAS,CAAC,OAAqB,EAAE,iBAA0B;QACzD,KAAK,MAAM,CAAC,UAAU,CAAC,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YACvC,IAAI,UAAU,KAAK,iBAAiB,EAAE,CAAC;gBACrC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;YACjC,CAAC;QACH,CAAC;IACH,CAAC;IAED,QAAQ,CAAC,UAAkB,EAAE,QAAuB;QAClD,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;IACxC,CAAC;IAED,UAAU,CAAC,UAAkB;QAC3B,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IACjC,CAAC;IAED,GAAG,CAAC,UAAkB;QACpB,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IACrC,CAAC;CACF;AAED,uEAAuE;AAEvE,SAAS,sBAAsB,CAAC,OAAqB;IACnD,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,CAAC,IAAI,CAAC,OAAO,OAAO,CAAC,IAAI,GAAG,CAAC,CAAC;IACnC,IAAI,OAAO,CAAC,MAAM;QAAE,KAAK,CAAC,IAAI,CAAC,QAAQ,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;IAC1D,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACzB,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACzB,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { SwarmInstance, SwarmStatus, PlanStatus } from "./types.js";
|
|
2
|
+
export interface SwarmSnapshot {
|
|
3
|
+
id: string;
|
|
4
|
+
hubSessionId: string;
|
|
5
|
+
workDir?: string;
|
|
6
|
+
roles: Array<{
|
|
7
|
+
instanceId: string;
|
|
8
|
+
roleName: string;
|
|
9
|
+
status: string;
|
|
10
|
+
currentTask?: string;
|
|
11
|
+
}>;
|
|
12
|
+
plan: unknown;
|
|
13
|
+
nextInstanceSeq: Record<string, number>;
|
|
14
|
+
savedAt: number;
|
|
15
|
+
status?: SwarmStatus;
|
|
16
|
+
planStatus?: PlanStatus;
|
|
17
|
+
}
|
|
18
|
+
export declare function saveSwarmSnapshot(swarm: SwarmInstance): void;
|
|
19
|
+
export declare function loadSwarmSnapshot(swarmId: string): SwarmSnapshot | null;
|
|
20
|
+
export declare function deleteSwarmSnapshot(swarmId: string): void;
|
|
21
|
+
export declare function appendMessageLog(swarmId: string, entry: object): void;
|
|
22
|
+
export declare function listRecoverableSwarmIds(): string[];
|
|
23
|
+
//# sourceMappingURL=persistence.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"persistence.d.ts","sourceRoot":"","sources":["../src/persistence.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAUzE,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,KAAK,CAAC;QACX,UAAU,EAAE,MAAM,CAAC;QACnB,QAAQ,EAAE,MAAM,CAAC;QACjB,MAAM,EAAE,MAAM,CAAC;QACf,WAAW,CAAC,EAAE,MAAM,CAAC;KACtB,CAAC,CAAC;IACH,IAAI,EAAE,OAAO,CAAC;IACd,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACxC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,UAAU,CAAC,EAAE,UAAU,CAAC;CACzB;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI,CAoB5D;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAQvE;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAKzD;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAIrE;AAED,wBAAgB,uBAAuB,IAAI,MAAM,EAAE,CAMlD"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { writeFileSync, readFileSync, existsSync, mkdirSync, appendFileSync, rmSync, readdirSync, } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { homedir } from "node:os";
|
|
4
|
+
function getSwarmsDir() {
|
|
5
|
+
return join(homedir(), ".clawnet", "swarms");
|
|
6
|
+
}
|
|
7
|
+
function getSwarmDir(swarmId) {
|
|
8
|
+
return join(getSwarmsDir(), swarmId);
|
|
9
|
+
}
|
|
10
|
+
export function saveSwarmSnapshot(swarm) {
|
|
11
|
+
const dir = getSwarmDir(swarm.id);
|
|
12
|
+
mkdirSync(dir, { recursive: true });
|
|
13
|
+
const snapshot = {
|
|
14
|
+
id: swarm.id,
|
|
15
|
+
hubSessionId: swarm.hubSessionId,
|
|
16
|
+
workDir: swarm.workDir,
|
|
17
|
+
roles: Array.from(swarm.roles.values()).map((r) => ({
|
|
18
|
+
instanceId: r.instanceId,
|
|
19
|
+
roleName: r.roleName,
|
|
20
|
+
status: r.status,
|
|
21
|
+
currentTask: r.currentTask,
|
|
22
|
+
})),
|
|
23
|
+
plan: swarm.plan,
|
|
24
|
+
nextInstanceSeq: Object.fromEntries(swarm.nextInstanceSeq),
|
|
25
|
+
savedAt: Date.now(),
|
|
26
|
+
status: swarm.status,
|
|
27
|
+
planStatus: swarm.planStatus,
|
|
28
|
+
};
|
|
29
|
+
writeFileSync(join(dir, "recovery.json"), JSON.stringify(snapshot, null, 2));
|
|
30
|
+
}
|
|
31
|
+
export function loadSwarmSnapshot(swarmId) {
|
|
32
|
+
const filePath = join(getSwarmDir(swarmId), "recovery.json");
|
|
33
|
+
if (!existsSync(filePath))
|
|
34
|
+
return null;
|
|
35
|
+
try {
|
|
36
|
+
return JSON.parse(readFileSync(filePath, "utf-8"));
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
export function deleteSwarmSnapshot(swarmId) {
|
|
43
|
+
const dir = getSwarmDir(swarmId);
|
|
44
|
+
if (existsSync(dir)) {
|
|
45
|
+
rmSync(dir, { recursive: true, force: true });
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
export function appendMessageLog(swarmId, entry) {
|
|
49
|
+
const dir = getSwarmDir(swarmId);
|
|
50
|
+
mkdirSync(dir, { recursive: true });
|
|
51
|
+
appendFileSync(join(dir, "messages.jsonl"), JSON.stringify(entry) + "\n");
|
|
52
|
+
}
|
|
53
|
+
export function listRecoverableSwarmIds() {
|
|
54
|
+
const dir = getSwarmsDir();
|
|
55
|
+
if (!existsSync(dir))
|
|
56
|
+
return [];
|
|
57
|
+
return readdirSync(dir, { withFileTypes: true })
|
|
58
|
+
.filter((e) => e.isDirectory() && existsSync(join(dir, e.name, "recovery.json")))
|
|
59
|
+
.map((e) => e.name);
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=persistence.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"persistence.js","sourceRoot":"","sources":["../src/persistence.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { SwarmCoordinator } from "./swarm-coordinator.js";
|
|
2
|
+
import { type SwarmSnapshot } from "./persistence.js";
|
|
3
|
+
export declare function listRecoverableSwarms(): SwarmSnapshot[];
|
|
4
|
+
export declare function recoverSwarm(coordinator: SwarmCoordinator, snapshot: SwarmSnapshot): Promise<void>;
|
|
5
|
+
//# sourceMappingURL=recovery.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recovery.d.ts","sourceRoot":"","sources":["../src/recovery.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,EAGL,KAAK,aAAa,EACnB,MAAM,kBAAkB,CAAC;AAI1B,wBAAgB,qBAAqB,IAAI,aAAa,EAAE,CAUvD;AAED,wBAAsB,YAAY,CAChC,WAAW,EAAE,gBAAgB,EAC7B,QAAQ,EAAE,aAAa,GACtB,OAAO,CAAC,IAAI,CAAC,CAoBf"}
|
package/dist/recovery.js
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { loadSwarmSnapshot, listRecoverableSwarmIds, } from "./persistence.js";
|
|
2
|
+
const RECOVERY_TTL_MS = 24 * 60 * 60 * 1000; // 24h
|
|
3
|
+
export function listRecoverableSwarms() {
|
|
4
|
+
const now = Date.now();
|
|
5
|
+
return listRecoverableSwarmIds()
|
|
6
|
+
.map((id) => loadSwarmSnapshot(id))
|
|
7
|
+
.filter((s) => {
|
|
8
|
+
if (!s)
|
|
9
|
+
return false;
|
|
10
|
+
if (now - s.savedAt > RECOVERY_TTL_MS)
|
|
11
|
+
return false;
|
|
12
|
+
const status = s.status ?? "running"; // old snapshots default to running
|
|
13
|
+
return status === "running" || status === "paused";
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
export async function recoverSwarm(coordinator, snapshot) {
|
|
17
|
+
await coordinator.create(snapshot.hubSessionId, {
|
|
18
|
+
workDir: snapshot.workDir,
|
|
19
|
+
roles: snapshot.roles.map((r) => ({ roleName: r.roleName })),
|
|
20
|
+
});
|
|
21
|
+
const swarm = coordinator.getSwarm(snapshot.hubSessionId);
|
|
22
|
+
if (swarm) {
|
|
23
|
+
if (snapshot.plan) {
|
|
24
|
+
swarm.plan = snapshot.plan;
|
|
25
|
+
}
|
|
26
|
+
// Recovered swarms start paused — user must explicitly resume
|
|
27
|
+
swarm.status = "paused";
|
|
28
|
+
swarm.isPaused = true;
|
|
29
|
+
// Clear the timer that create() started — paused swarms don't need checks
|
|
30
|
+
if (swarm.checkTimer) {
|
|
31
|
+
clearTimeout(swarm.checkTimer);
|
|
32
|
+
swarm.checkTimer = undefined;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=recovery.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recovery.js","sourceRoot":"","sources":["../src/recovery.ts"],"names":[],"mappings":"AACA,OAAO,EACL,iBAAiB,EACjB,uBAAuB,GAExB,MAAM,kBAAkB,CAAC;AAE1B,MAAM,eAAe,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,MAAM;AAEnD,MAAM,UAAU,qBAAqB;IACnC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvB,OAAO,uBAAuB,EAAE;SAC7B,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,CAAC,CAAC;SAClC,MAAM,CAAC,CAAC,CAAC,EAAsB,EAAE;QAChC,IAAI,CAAC,CAAC;YAAE,OAAO,KAAK,CAAC;QACrB,IAAI,GAAG,GAAG,CAAC,CAAC,OAAO,GAAG,eAAe;YAAE,OAAO,KAAK,CAAC;QACpD,MAAM,MAAM,GAAG,CAAC,CAAC,MAAM,IAAI,SAAS,CAAC,CAAC,mCAAmC;QACzE,OAAO,MAAM,KAAK,SAAS,IAAI,MAAM,KAAK,QAAQ,CAAC;IACrD,CAAC,CAAC,CAAC;AACP,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,WAA6B,EAC7B,QAAuB;IAEvB,MAAM,WAAW,CAAC,MAAM,CAAC,QAAQ,CAAC,YAAY,EAAE;QAC9C,OAAO,EAAE,QAAQ,CAAC,OAAO;QACzB,KAAK,EAAE,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC;KAC7D,CAAC,CAAC;IAEH,MAAM,KAAK,GAAG,WAAW,CAAC,QAAQ,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;IAC1D,IAAI,KAAK,EAAE,CAAC;QACV,IAAI,QAAQ,CAAC,IAAI,EAAE,CAAC;YAClB,KAAK,CAAC,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC;QAC7B,CAAC;QACD,8DAA8D;QAC9D,KAAK,CAAC,MAAM,GAAG,QAAQ,CAAC;QACxB,KAAK,CAAC,QAAQ,GAAG,IAAI,CAAC;QACtB,0EAA0E;QAC1E,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC;YACrB,YAAY,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;YAC/B,KAAK,CAAC,UAAU,GAAG,SAAS,CAAC;QAC/B,CAAC;IACH,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { RoleDefinition } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Ensure user role directory exists and preset templates are copied.
|
|
4
|
+
* Returns the user roles directory path.
|
|
5
|
+
*/
|
|
6
|
+
export declare function initRoles(): string;
|
|
7
|
+
/** Load a role definition by name. Reads from ~/.clawnet/roles/{name}/CLAUDE.md first, falls back to preset. */
|
|
8
|
+
export declare function loadRole(roleName: string): RoleDefinition;
|
|
9
|
+
/** List all available role names (from user dir + presets). */
|
|
10
|
+
export declare function listRoles(): string[];
|
|
11
|
+
/**
|
|
12
|
+
* Build the full system prompt for a role instance.
|
|
13
|
+
* Substitutes {instanceId} and {roleList} placeholders.
|
|
14
|
+
*/
|
|
15
|
+
export declare function buildRolePrompt(definition: RoleDefinition, instanceId: string, roleList: string): string;
|
|
16
|
+
//# sourceMappingURL=role-loader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"role-loader.d.ts","sourceRoot":"","sources":["../../src/roles/role-loader.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AA0CjD;;;GAGG;AACH,wBAAgB,SAAS,IAAI,MAAM,CAmBlC;AAED,gHAAgH;AAChH,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,cAAc,CAYzD;AAED,+DAA+D;AAC/D,wBAAgB,SAAS,IAAI,MAAM,EAAE,CAoBpC;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,UAAU,EAAE,cAAc,EAC1B,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,GACf,MAAM,CAIR"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { readFileSync, existsSync, mkdirSync, writeFileSync, readdirSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { homedir } from "node:os";
|
|
4
|
+
const PRESET_DIR = join(import.meta.dirname ?? __dirname, "../../roles");
|
|
5
|
+
const USER_ROLES_DIR = join(homedir(), ".clawnet", "roles");
|
|
6
|
+
/** Parse YAML frontmatter + markdown body from a role file. */
|
|
7
|
+
function parseRoleFile(content) {
|
|
8
|
+
const fmMatch = content.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/);
|
|
9
|
+
if (!fmMatch) {
|
|
10
|
+
throw new Error("Invalid role file: missing YAML frontmatter");
|
|
11
|
+
}
|
|
12
|
+
const frontmatter = fmMatch[1];
|
|
13
|
+
const body = fmMatch[2].trim();
|
|
14
|
+
// Simple YAML parser (no dependency) — handles flat key: value + arrays
|
|
15
|
+
const meta = {};
|
|
16
|
+
for (const line of frontmatter.split("\n")) {
|
|
17
|
+
const m = line.match(/^(\w+):\s*(.+)$/);
|
|
18
|
+
if (!m)
|
|
19
|
+
continue;
|
|
20
|
+
const [, key, rawVal] = m;
|
|
21
|
+
// Array value: [a, b, c]
|
|
22
|
+
const arrMatch = rawVal.match(/^\[(.*)\]$/);
|
|
23
|
+
if (arrMatch) {
|
|
24
|
+
meta[key] = arrMatch[1].split(",").map((s) => s.trim());
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
// Strip surrounding quotes
|
|
28
|
+
meta[key] = rawVal.replace(/^["']|["']$/g, "");
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return {
|
|
32
|
+
name: meta.name ?? "unknown",
|
|
33
|
+
shortName: meta.shortName ?? meta.name?.slice(0, 3) ?? "unk",
|
|
34
|
+
type: meta.type ?? "worker",
|
|
35
|
+
description: meta.description ?? "",
|
|
36
|
+
capabilities: Array.isArray(meta.capabilities) ? meta.capabilities : [],
|
|
37
|
+
color: meta.color ?? "#888888",
|
|
38
|
+
promptBody: body,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Ensure user role directory exists and preset templates are copied.
|
|
43
|
+
* Returns the user roles directory path.
|
|
44
|
+
*/
|
|
45
|
+
export function initRoles() {
|
|
46
|
+
mkdirSync(USER_ROLES_DIR, { recursive: true });
|
|
47
|
+
if (!existsSync(PRESET_DIR))
|
|
48
|
+
return USER_ROLES_DIR;
|
|
49
|
+
for (const file of readdirSync(PRESET_DIR)) {
|
|
50
|
+
if (!file.endsWith(".md"))
|
|
51
|
+
continue;
|
|
52
|
+
const roleName = file.replace(/\.md$/, "");
|
|
53
|
+
const userRoleDir = join(USER_ROLES_DIR, roleName);
|
|
54
|
+
const userFile = join(userRoleDir, "CLAUDE.md");
|
|
55
|
+
if (!existsSync(userFile)) {
|
|
56
|
+
mkdirSync(userRoleDir, { recursive: true });
|
|
57
|
+
const content = readFileSync(join(PRESET_DIR, file), "utf-8");
|
|
58
|
+
writeFileSync(userFile, content, "utf-8");
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return USER_ROLES_DIR;
|
|
62
|
+
}
|
|
63
|
+
/** Load a role definition by name. Reads from ~/.clawnet/roles/{name}/CLAUDE.md first, falls back to preset. */
|
|
64
|
+
export function loadRole(roleName) {
|
|
65
|
+
const userFile = join(USER_ROLES_DIR, roleName, "CLAUDE.md");
|
|
66
|
+
if (existsSync(userFile)) {
|
|
67
|
+
return parseRoleFile(readFileSync(userFile, "utf-8"));
|
|
68
|
+
}
|
|
69
|
+
const presetFile = join(PRESET_DIR, `${roleName}.md`);
|
|
70
|
+
if (existsSync(presetFile)) {
|
|
71
|
+
return parseRoleFile(readFileSync(presetFile, "utf-8"));
|
|
72
|
+
}
|
|
73
|
+
throw new Error(`Role not found: ${roleName}`);
|
|
74
|
+
}
|
|
75
|
+
/** List all available role names (from user dir + presets). */
|
|
76
|
+
export function listRoles() {
|
|
77
|
+
const roles = new Set();
|
|
78
|
+
if (existsSync(USER_ROLES_DIR)) {
|
|
79
|
+
for (const entry of readdirSync(USER_ROLES_DIR, { withFileTypes: true })) {
|
|
80
|
+
if (entry.isDirectory() && existsSync(join(USER_ROLES_DIR, entry.name, "CLAUDE.md"))) {
|
|
81
|
+
roles.add(entry.name);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
if (existsSync(PRESET_DIR)) {
|
|
86
|
+
for (const file of readdirSync(PRESET_DIR)) {
|
|
87
|
+
if (file.endsWith(".md")) {
|
|
88
|
+
roles.add(file.replace(/\.md$/, ""));
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return [...roles].sort();
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Build the full system prompt for a role instance.
|
|
96
|
+
* Substitutes {instanceId} and {roleList} placeholders.
|
|
97
|
+
*/
|
|
98
|
+
export function buildRolePrompt(definition, instanceId, roleList) {
|
|
99
|
+
return definition.promptBody
|
|
100
|
+
.replace(/\{instanceId\}/g, instanceId)
|
|
101
|
+
.replace(/\{roleList\}/g, roleList);
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=role-loader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"role-loader.js","sourceRoot":"","sources":["../../src/roles/role-loader.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/** Parsed role definition from a markdown + YAML frontmatter file. */
|
|
2
|
+
export interface RoleDefinition {
|
|
3
|
+
/** Role template name, e.g. "developer" */
|
|
4
|
+
name: string;
|
|
5
|
+
/** Short name for instanceId prefix, e.g. "dev" */
|
|
6
|
+
shortName: string;
|
|
7
|
+
/** Role type */
|
|
8
|
+
type: "queen" | "worker";
|
|
9
|
+
/** Human-readable description */
|
|
10
|
+
description: string;
|
|
11
|
+
/** Capability tags */
|
|
12
|
+
capabilities: string[];
|
|
13
|
+
/** Badge color for UI */
|
|
14
|
+
color: string;
|
|
15
|
+
/** Full prompt body (markdown after frontmatter) */
|
|
16
|
+
promptBody: string;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/roles/types.ts"],"names":[],"mappings":"AAAA,sEAAsE;AACtE,MAAM,WAAW,cAAc;IAC7B,2CAA2C;IAC3C,IAAI,EAAE,MAAM,CAAC;IACb,mDAAmD;IACnD,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB;IAChB,IAAI,EAAE,OAAO,GAAG,QAAQ,CAAC;IACzB,iCAAiC;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,sBAAsB;IACtB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,yBAAyB;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,oDAAoD;IACpD,UAAU,EAAE,MAAM,CAAC;CACpB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/roles/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import type { SessionAdapter, HubAdapter } from "./types.js";
|
|
2
|
+
import type { MessageRouter } from "./message-router.js";
|
|
3
|
+
import type { SwarmInstance, RoleInstance, SwarmCreateOptions, CustomRoleDefinition } from "./types.js";
|
|
4
|
+
/**
|
|
5
|
+
* SwarmCoordinator — orchestrates multi-role Claude CLI swarms.
|
|
6
|
+
*
|
|
7
|
+
* Composes (not replaces) SessionAdapter. Each role instance is a separate
|
|
8
|
+
* session in SessionAdapter. Communication between roles goes through
|
|
9
|
+
* MessageRouter (currently LocalMessageRouter using stdin/stdout).
|
|
10
|
+
*/
|
|
11
|
+
export declare class SwarmCoordinator {
|
|
12
|
+
private sessionAdapter;
|
|
13
|
+
private hub;
|
|
14
|
+
private swarms;
|
|
15
|
+
constructor(sessionAdapter: SessionAdapter, hub: HubAdapter);
|
|
16
|
+
/** Create a new swarm and spawn initial roles. */
|
|
17
|
+
create(swarmSessionId: string, options: SwarmCreateOptions): Promise<void>;
|
|
18
|
+
/** Handle user message directed at the swarm. */
|
|
19
|
+
handleUserMessage(swarmSessionId: string, content: string, targetInstance?: string): Promise<void>;
|
|
20
|
+
/**
|
|
21
|
+
* Handle output from a role's Claude CLI process.
|
|
22
|
+
* Called by the onOutput callback wired in start.ts.
|
|
23
|
+
*
|
|
24
|
+
* Returns true if the sessionId belongs to a swarm role.
|
|
25
|
+
*/
|
|
26
|
+
handleRoleOutput(roleSessionId: string, data: unknown): boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Handle turn completion from a role's Claude CLI process.
|
|
29
|
+
* Returns true if the sessionId belongs to a swarm role.
|
|
30
|
+
*/
|
|
31
|
+
handleRoleTurnComplete(roleSessionId: string, info: {
|
|
32
|
+
claudeSessionId?: string;
|
|
33
|
+
cost?: number;
|
|
34
|
+
duration?: number;
|
|
35
|
+
contextUsage?: {
|
|
36
|
+
used: number;
|
|
37
|
+
total: number;
|
|
38
|
+
};
|
|
39
|
+
}): boolean;
|
|
40
|
+
/** Spawn a new role instance in a swarm. */
|
|
41
|
+
spawnRole(swarmId: string, roleName: string, router?: MessageRouter, taskPrompt?: string, customPrompt?: string, customDefinition?: CustomRoleDefinition): Promise<RoleInstance>;
|
|
42
|
+
/** Stop a role instance. */
|
|
43
|
+
stopRole(swarmId: string, instanceId: string): Promise<void>;
|
|
44
|
+
/** Destroy an entire swarm. */
|
|
45
|
+
destroy(swarmId: string): Promise<void>;
|
|
46
|
+
/** Check if a session ID belongs to any swarm. */
|
|
47
|
+
isSwarmSession(sessionId: string): boolean;
|
|
48
|
+
/** Check if a hub session ID is a swarm. */
|
|
49
|
+
hasSwarm(swarmSessionId: string): boolean;
|
|
50
|
+
/** Get a swarm instance by hub session ID. */
|
|
51
|
+
getSwarm(swarmSessionId: string): SwarmInstance | undefined;
|
|
52
|
+
/** Mark a swarm as completed. Releases all resources — closes sessions, deletes snapshot, removes from memory. */
|
|
53
|
+
complete(swarmId: string): Promise<void>;
|
|
54
|
+
/** Mark a swarm as failed. Releases all resources — closes sessions, deletes snapshot, removes from memory. */
|
|
55
|
+
fail(swarmId: string): Promise<void>;
|
|
56
|
+
private findQueen;
|
|
57
|
+
private findReviewer;
|
|
58
|
+
/** Send plan to reviewer for review. Auto-approves if no reviewer available. */
|
|
59
|
+
private requestPlanReview;
|
|
60
|
+
/** Handle plan review result from reviewer. */
|
|
61
|
+
private handlePlanReviewResult;
|
|
62
|
+
private findByRoleSessionId;
|
|
63
|
+
private executeAction;
|
|
64
|
+
private startQueenCheck;
|
|
65
|
+
private buildRoleListString;
|
|
66
|
+
private buildStatusPayload;
|
|
67
|
+
private sendStatusUpdate;
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=swarm-coordinator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"swarm-coordinator.d.ts","sourceRoot":"","sources":["../src/swarm-coordinator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAMzD,OAAO,KAAK,EACV,aAAa,EACb,YAAY,EACZ,kBAAkB,EAGlB,oBAAoB,EACrB,MAAM,YAAY,CAAC;AAOpB;;;;;;GAMG;AACH,qBAAa,gBAAgB;IAIzB,OAAO,CAAC,cAAc;IACtB,OAAO,CAAC,GAAG;IAJb,OAAO,CAAC,MAAM,CAAoC;gBAGxC,cAAc,EAAE,cAAc,EAC9B,GAAG,EAAE,UAAU;IAKzB,kDAAkD;IAC5C,MAAM,CAAC,cAAc,EAAE,MAAM,EAAE,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC;IAwDhF,iDAAiD;IAC3C,iBAAiB,CACrB,cAAc,EAAE,MAAM,EACtB,OAAO,EAAE,MAAM,EACf,cAAc,CAAC,EAAE,MAAM,GACtB,OAAO,CAAC,IAAI,CAAC;IAwChB;;;;;OAKG;IACH,gBAAgB,CAAC,aAAa,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,OAAO;IAwD/D;;;OAGG;IACH,sBAAsB,CACpB,aAAa,EAAE,MAAM,EACrB,IAAI,EAAE;QAAE,eAAe,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,YAAY,CAAC,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,CAAA;SAAE,CAAA;KAAE,GACnH,OAAO;IAoBV,4CAA4C;IACtC,SAAS,CACb,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,MAAM,CAAC,EAAE,aAAa,EACtB,UAAU,CAAC,EAAE,MAAM,EACnB,YAAY,CAAC,EAAE,MAAM,EACrB,gBAAgB,CAAC,EAAE,oBAAoB,GACtC,OAAO,CAAC,YAAY,CAAC;IAsExB,4BAA4B;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAsBlE,+BAA+B;IACzB,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAkB7C,kDAAkD;IAClD,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO;IAI1C,4CAA4C;IAC5C,QAAQ,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO;IAIzC,8CAA8C;IAC9C,QAAQ,CAAC,cAAc,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS;IAI3D,kHAAkH;IAC5G,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAoB9C,+GAA+G;IACzG,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAsB1C,OAAO,CAAC,SAAS;IAOjB,OAAO,CAAC,YAAY;IAOpB,gFAAgF;IAChF,OAAO,CAAC,iBAAiB;IA2CzB,+CAA+C;IAC/C,OAAO,CAAC,sBAAsB;IAyC9B,OAAO,CAAC,mBAAmB;IAe3B,OAAO,CAAC,aAAa;IAkHrB,OAAO,CAAC,eAAe;IA8DvB,OAAO,CAAC,mBAAmB;IAQ3B,OAAO,CAAC,kBAAkB;IAgB1B,OAAO,CAAC,gBAAgB;CAWzB"}
|