claude-flow-novice 2.15.9 → 2.15.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. package/.claude/skills/cfn-loop-orchestration/IMPLEMENTATION_SUMMARY.md +519 -0
  2. package/.claude/skills/cfn-loop-orchestration/ORCHESTRATOR_IMPLEMENTATION.md +493 -0
  3. package/.claude/skills/cfn-loop-orchestration/ORCHESTRATOR_QUICK_START.md +499 -0
  4. package/.claude/skills/cfn-loop-orchestration/helpers/orchestrate-ts.sh +104 -0
  5. package/.claude/skills/cfn-loop-orchestration/orchestrate.sh +2 -2
  6. package/.claude/skills/cfn-loop-orchestration/src/orchestrate.ts +648 -0
  7. package/.claude/skills/cfn-loop-orchestration/tests/orchestrate.test.ts +836 -0
  8. package/README.md +205 -10
  9. package/claude-assets/agents/cfn-dev-team/CLAUDE.md +9 -81
  10. package/claude-assets/agents/cfn-dev-team/architecture/base-template-generator.md +4 -4
  11. package/claude-assets/agents/cfn-dev-team/architecture/planner.md +4 -4
  12. package/claude-assets/agents/cfn-dev-team/architecture/system-architect.md +5 -5
  13. package/claude-assets/agents/cfn-dev-team/coordinators/cfn-v3-coordinator.md +184 -229
  14. package/claude-assets/agents/cfn-dev-team/dev-ops/devops-engineer.md +4 -4
  15. package/claude-assets/agents/cfn-dev-team/dev-ops/docker-specialist.md +9 -37
  16. package/claude-assets/agents/cfn-dev-team/dev-ops/kubernetes-specialist.md +9 -37
  17. package/claude-assets/agents/cfn-dev-team/dev-ops/monitoring-specialist.md +4 -4
  18. package/claude-assets/agents/cfn-dev-team/developers/api-gateway-specialist.md +10 -40
  19. package/claude-assets/agents/cfn-dev-team/developers/database/database-architect.md +3 -0
  20. package/claude-assets/agents/cfn-dev-team/developers/frontend/mobile-dev.md +4 -1
  21. package/claude-assets/agents/cfn-dev-team/developers/frontend/react-frontend-engineer.md +4 -1
  22. package/claude-assets/agents/cfn-dev-team/developers/frontend/typescript-specialist.md +4 -1
  23. package/claude-assets/agents/cfn-dev-team/developers/frontend/ui-designer.md +5 -0
  24. package/claude-assets/agents/cfn-dev-team/developers/graphql-specialist.md +2 -1
  25. package/claude-assets/agents/cfn-dev-team/developers/rust-developer.md +2 -1
  26. package/claude-assets/agents/cfn-dev-team/documentation/pseudocode.md +2 -7
  27. package/claude-assets/agents/cfn-dev-team/product-owners/accessibility-advocate-persona.md +4 -4
  28. package/claude-assets/agents/cfn-dev-team/product-owners/cto-agent.md +4 -4
  29. package/claude-assets/agents/cfn-dev-team/product-owners/power-user-persona.md +4 -4
  30. package/claude-assets/agents/cfn-dev-team/product-owners/product-owner.md +18 -22
  31. package/claude-assets/agents/cfn-dev-team/reviewers/code-reviewer.md +1 -1
  32. package/claude-assets/agents/cfn-dev-team/reviewers/quality/code-quality-validator.md +1 -1
  33. package/claude-assets/agents/cfn-dev-team/reviewers/quality/perf-analyzer.md +1 -1
  34. package/claude-assets/agents/cfn-dev-team/reviewers/quality/performance-benchmarker.md +1 -1
  35. package/claude-assets/agents/cfn-dev-team/reviewers/quality/security-specialist.md +1 -1
  36. package/claude-assets/agents/cfn-dev-team/testers/api-testing-specialist.md +7 -35
  37. package/claude-assets/agents/cfn-dev-team/testers/chaos-engineering-specialist.md +17 -36
  38. package/claude-assets/agents/cfn-dev-team/testers/contract-tester.md +10 -11
  39. package/claude-assets/agents/cfn-dev-team/testers/e2e/playwright-tester.md +5 -5
  40. package/claude-assets/agents/cfn-dev-team/testers/integration-tester.md +10 -12
  41. package/claude-assets/agents/cfn-dev-team/testers/interaction-tester.md +7 -36
  42. package/claude-assets/agents/cfn-dev-team/testers/load-testing-specialist.md +10 -12
  43. package/claude-assets/agents/cfn-dev-team/testers/mutation-testing-specialist.md +10 -12
  44. package/claude-assets/agents/cfn-dev-team/testers/playwright-tester.md +7 -37
  45. package/claude-assets/agents/cfn-dev-team/testers/tester.md +7 -33
  46. package/claude-assets/agents/cfn-dev-team/testers/unit/tdd-london-unit-swarm.md +5 -5
  47. package/claude-assets/agents/cfn-dev-team/testers/validation/validation-production-validator.md +4 -4
  48. package/claude-assets/agents/cfn-dev-team/testing/test-validation-agent.md +4 -4
  49. package/claude-assets/agents/cfn-dev-team/utility/agent-builder.md +16 -16
  50. package/claude-assets/agents/cfn-dev-team/utility/analyst.md +4 -4
  51. package/claude-assets/agents/cfn-dev-team/utility/code-booster.md +4 -4
  52. package/claude-assets/agents/cfn-dev-team/utility/context-curator.md +4 -4
  53. package/claude-assets/agents/cfn-dev-team/utility/epic-creator.md +7 -85
  54. package/claude-assets/agents/cfn-dev-team/utility/memory-leak-specialist.md +7 -93
  55. package/claude-assets/agents/cfn-dev-team/utility/researcher.md +4 -4
  56. package/claude-assets/agents/cfn-dev-team/utility/z-ai-specialist.md +7 -84
  57. package/claude-assets/skills/cfn-loop-orchestration/IMPLEMENTATION_SUMMARY.md +519 -0
  58. package/claude-assets/skills/cfn-loop-orchestration/ORCHESTRATOR_IMPLEMENTATION.md +493 -0
  59. package/claude-assets/skills/cfn-loop-orchestration/ORCHESTRATOR_QUICK_START.md +499 -0
  60. package/claude-assets/skills/cfn-loop-orchestration/helpers/orchestrate-ts.sh +104 -0
  61. package/claude-assets/skills/cfn-loop-orchestration/orchestrate.sh +2 -2
  62. package/claude-assets/skills/cfn-loop-orchestration/src/orchestrate.ts +648 -0
  63. package/claude-assets/skills/cfn-loop-orchestration/tests/orchestrate.test.ts +836 -0
  64. package/dist/cli/agent-definition-parser.js +37 -4
  65. package/dist/cli/agent-definition-parser.js.map +1 -1
  66. package/dist/cli/agent-executor.js +32 -2
  67. package/dist/cli/agent-executor.js.map +1 -1
  68. package/dist/coordination/coordinate.js +369 -0
  69. package/dist/coordination/coordinate.js.map +1 -0
  70. package/dist/coordination/spawn-agent.js +364 -0
  71. package/dist/coordination/spawn-agent.js.map +1 -0
  72. package/dist/coordination/types-export.js +38 -0
  73. package/dist/coordination/types-export.js.map +1 -0
  74. package/package.json +1 -1
@@ -0,0 +1,369 @@
1
+ /**
2
+ * Coordination Layer for Agent Communication and Tracking
3
+ *
4
+ * Provides agent registration, status tracking, message passing, and
5
+ * coordination protocol enforcement with Redis as the backing store.
6
+ *
7
+ * Supports both Task Mode (Redis stubbed) and CLI Mode (full coordination).
8
+ *
9
+ * Key Features:
10
+ * - Agent registration with metadata tracking
11
+ * - Status updates and health checks
12
+ * - Message passing between agents (pub/sub)
13
+ * - Broadcast messages with protocol enforcement
14
+ * - Wait for completion with timeout support
15
+ * - Type-safe interfaces using branded types
16
+ */ import { CoordinationError, CoordinationErrorType } from './types-export';
17
+ /**
18
+ * Coordination Layer Implementation
19
+ *
20
+ * Manages agent lifecycle, status tracking, and inter-agent communication.
21
+ * Gracefully handles Task Mode (no Redis) and CLI Mode (full coordination).
22
+ */ export class CoordinationLayer {
23
+ redis;
24
+ logger;
25
+ canUseRedis;
26
+ executionMode;
27
+ taskId;
28
+ // In-memory registry for Task Mode
29
+ taskModeRegistry = new Map();
30
+ taskModeMessages = new Map();
31
+ constructor(config){
32
+ this.redis = config.redis;
33
+ this.logger = config.logger;
34
+ this.canUseRedis = config.canUseRedis;
35
+ this.executionMode = config.executionMode;
36
+ this.taskId = config.taskId;
37
+ }
38
+ /**
39
+ * Register an agent with the coordination layer
40
+ *
41
+ * Creates tracking record for agent lifecycle.
42
+ */ async registerAgent(agentId, type, metadata, iteration = 1, pid) {
43
+ const now = new Date().toISOString();
44
+ const agentMetadata = {
45
+ agentId,
46
+ type,
47
+ taskId: this.taskId,
48
+ status: 'registered',
49
+ iteration,
50
+ createdAt: now,
51
+ lastHeartbeat: now,
52
+ pid,
53
+ metadata
54
+ };
55
+ if (!this.canUseRedis) {
56
+ // Task Mode: Store in memory
57
+ this.taskModeRegistry.set(agentId, agentMetadata);
58
+ this.logger.info(`Task Mode: Registered agent ${agentId} (type: ${type})`);
59
+ return;
60
+ }
61
+ // CLI Mode: Store in Redis
62
+ const key = `swarm:${this.taskId}:agents:${agentId}`;
63
+ try {
64
+ await this.redis.hset(key, 'type', type, 'status', 'registered', 'iteration', iteration.toString(), 'createdAt', now, 'lastHeartbeat', now, ...pid ? [
65
+ 'pid',
66
+ pid.toString()
67
+ ] : [], ...metadata ? [
68
+ 'metadata',
69
+ JSON.stringify(metadata)
70
+ ] : []);
71
+ // Set 24h TTL
72
+ await this.redis.expire(key, 86400);
73
+ this.logger.debug(`Registered agent ${agentId} in Redis`);
74
+ } catch (error) {
75
+ throw new CoordinationError(CoordinationErrorType.REDIS_ERROR, `Failed to register agent ${agentId}`, this.executionMode, true);
76
+ }
77
+ }
78
+ /**
79
+ * Update agent status
80
+ *
81
+ * Tracks status changes during agent lifecycle.
82
+ */ async updateAgentStatus(agentId, status) {
83
+ const now = new Date().toISOString();
84
+ if (!this.canUseRedis) {
85
+ // Task Mode: Update in memory
86
+ const agent = this.taskModeRegistry.get(agentId);
87
+ if (agent) {
88
+ agent.status = status;
89
+ agent.lastHeartbeat = now;
90
+ this.taskModeRegistry.set(agentId, agent);
91
+ }
92
+ this.logger.debug(`Task Mode: Updated ${agentId} status to ${status}`);
93
+ return;
94
+ }
95
+ // CLI Mode: Update in Redis
96
+ const key = `swarm:${this.taskId}:agents:${agentId}`;
97
+ try {
98
+ await this.redis.hset(key, 'status', status, 'lastHeartbeat', now);
99
+ this.logger.debug(`Updated agent ${agentId} status to ${status}`);
100
+ } catch (error) {
101
+ throw new CoordinationError(CoordinationErrorType.REDIS_ERROR, `Failed to update agent ${agentId} status`, this.executionMode, true);
102
+ }
103
+ }
104
+ /**
105
+ * Send direct message between agents
106
+ *
107
+ * Delivers message from one agent to another.
108
+ */ async sendMessage(from, to, messageType, payload, correlationId) {
109
+ const message = {
110
+ from,
111
+ to,
112
+ type: messageType,
113
+ payload,
114
+ timestamp: new Date().toISOString(),
115
+ correlationId
116
+ };
117
+ if (!this.canUseRedis) {
118
+ // Task Mode: Store in memory
119
+ const key = `${from}:${to}`;
120
+ if (!this.taskModeMessages.has(key)) {
121
+ this.taskModeMessages.set(key, []);
122
+ }
123
+ this.taskModeMessages.get(key).push(message);
124
+ this.logger.debug(`Task Mode: Message from ${from} to ${to}`);
125
+ return;
126
+ }
127
+ // CLI Mode: Store in Redis
128
+ const key = `swarm:${this.taskId}:messages:${from}:${to}`;
129
+ try {
130
+ await this.redis.lpush(key, JSON.stringify(message));
131
+ await this.redis.expire(key, 3600); // 1h TTL for messages
132
+ this.logger.debug(`Message sent from ${from} to ${to}`);
133
+ } catch (error) {
134
+ throw new CoordinationError(CoordinationErrorType.REDIS_ERROR, `Failed to send message from ${from} to ${to}`, this.executionMode, true);
135
+ }
136
+ }
137
+ /**
138
+ * Broadcast message to all agents in task
139
+ *
140
+ * Delivers message to every agent participating in the task.
141
+ * Used for coordination signals (gate passed, iteration started, etc).
142
+ */ async broadcastMessage(from, messageType, payload, correlationId) {
143
+ const message = {
144
+ from,
145
+ taskId: this.taskId,
146
+ type: messageType,
147
+ payload,
148
+ timestamp: new Date().toISOString(),
149
+ correlationId
150
+ };
151
+ if (!this.canUseRedis) {
152
+ // Task Mode: Log broadcast
153
+ this.logger.info(`Task Mode: Broadcast ${messageType} from ${from} (payload: ${JSON.stringify(payload)})`);
154
+ return;
155
+ }
156
+ // CLI Mode: Store in Redis as sorted set for ordering
157
+ const key = `swarm:${this.taskId}:broadcasts`;
158
+ try {
159
+ const timestamp = Date.now();
160
+ await this.redis.zadd(key, timestamp, JSON.stringify(message));
161
+ // Set 1h TTL
162
+ await this.redis.expire(key, 3600);
163
+ this.logger.debug(`Broadcast ${messageType} to all agents in task ${this.taskId}`);
164
+ } catch (error) {
165
+ throw new CoordinationError(CoordinationErrorType.REDIS_ERROR, `Failed to broadcast message`, this.executionMode, true);
166
+ }
167
+ }
168
+ /**
169
+ * Wait for agent completion
170
+ *
171
+ * Blocking wait for one or more agents to complete with timeout.
172
+ * Used by orchestrator to synchronize on agent completion.
173
+ */ async waitForCompletion(agentIds, timeoutMs = 600000 // 10 minutes default
174
+ ) {
175
+ const results = new Map();
176
+ const startTime = Date.now();
177
+ if (!this.canUseRedis) {
178
+ // Task Mode: Poll in-memory registry
179
+ while(Date.now() - startTime < timeoutMs){
180
+ let allComplete = true;
181
+ for (const agentId of agentIds){
182
+ const agent = this.taskModeRegistry.get(agentId);
183
+ const status = agent?.status ?? 'unknown';
184
+ if (status === 'complete' || status === 'failed') {
185
+ results.set(agentId, status);
186
+ } else {
187
+ allComplete = false;
188
+ }
189
+ }
190
+ if (allComplete && results.size === agentIds.length) {
191
+ return results;
192
+ }
193
+ // Wait 100ms before checking again
194
+ await new Promise((resolve)=>setTimeout(resolve, 100));
195
+ }
196
+ // Timeout: Return whatever we have
197
+ for (const agentId of agentIds){
198
+ if (!results.has(agentId)) {
199
+ const agent = this.taskModeRegistry.get(agentId);
200
+ results.set(agentId, agent?.status ?? 'timeout');
201
+ }
202
+ }
203
+ return results;
204
+ }
205
+ // CLI Mode: Wait on Redis with blocking operations
206
+ const channel = `swarm:${this.taskId}:completion`;
207
+ try {
208
+ while(Date.now() - startTime < timeoutMs){
209
+ for (const agentId of agentIds){
210
+ if (results.has(agentId)) continue;
211
+ const key = `swarm:${this.taskId}:agents:${agentId}`;
212
+ const statusStr = await this.redis.hget(key, 'status');
213
+ const status = statusStr ?? 'unknown';
214
+ if (status === 'complete' || status === 'failed' || status === 'timeout') {
215
+ results.set(agentId, status);
216
+ }
217
+ }
218
+ if (results.size === agentIds.length) {
219
+ return results;
220
+ }
221
+ // Wait 100ms before checking again
222
+ await new Promise((resolve)=>setTimeout(resolve, 100));
223
+ }
224
+ // Timeout: Mark remaining as timeout
225
+ for (const agentId of agentIds){
226
+ if (!results.has(agentId)) {
227
+ results.set(agentId, 'timeout');
228
+ }
229
+ }
230
+ return results;
231
+ } catch (error) {
232
+ throw new CoordinationError(CoordinationErrorType.REDIS_ERROR, `Failed to wait for agent completion`, this.executionMode, true);
233
+ }
234
+ }
235
+ /**
236
+ * Get agent status
237
+ *
238
+ * Returns current status for a single agent.
239
+ */ async getAgentStatus(agentId) {
240
+ if (!this.canUseRedis) {
241
+ // Task Mode: Check in-memory registry
242
+ const agent = this.taskModeRegistry.get(agentId);
243
+ return agent?.status ?? 'unknown';
244
+ }
245
+ // CLI Mode: Get from Redis
246
+ const key = `swarm:${this.taskId}:agents:${agentId}`;
247
+ try {
248
+ const status = await this.redis.hget(key, 'status');
249
+ return status ?? 'unknown';
250
+ } catch (error) {
251
+ this.logger.error(`Failed to get agent ${agentId} status`, error);
252
+ return 'unknown';
253
+ }
254
+ }
255
+ /**
256
+ * Get agent metadata
257
+ *
258
+ * Returns full metadata for a registered agent.
259
+ */ async getAgentMetadata(agentId) {
260
+ if (!this.canUseRedis) {
261
+ // Task Mode: Return from in-memory registry
262
+ return this.taskModeRegistry.get(agentId) ?? null;
263
+ }
264
+ // CLI Mode: Get from Redis
265
+ const key = `swarm:${this.taskId}:agents:${agentId}`;
266
+ try {
267
+ const data = await this.redis.hgetall(key);
268
+ if (!data || Object.keys(data).length === 0) {
269
+ return null;
270
+ }
271
+ return {
272
+ agentId,
273
+ type: data.type,
274
+ taskId: this.taskId,
275
+ status: data.status || 'unknown',
276
+ iteration: parseInt(data.iteration || '1', 10),
277
+ createdAt: data.createdAt,
278
+ lastHeartbeat: data.lastHeartbeat,
279
+ pid: data.pid ? parseInt(data.pid, 10) : undefined,
280
+ metadata: data.metadata ? JSON.parse(data.metadata) : undefined
281
+ };
282
+ } catch (error) {
283
+ this.logger.error(`Failed to get agent ${agentId} metadata`, error);
284
+ return null;
285
+ }
286
+ }
287
+ /**
288
+ * Get all agents for a task
289
+ *
290
+ * Returns metadata for all registered agents.
291
+ */ async getAllAgents() {
292
+ if (!this.canUseRedis) {
293
+ // Task Mode: Return from in-memory registry
294
+ return Array.from(this.taskModeRegistry.values());
295
+ }
296
+ // CLI Mode: Scan Redis for all agents
297
+ const agents = [];
298
+ const pattern = `swarm:${this.taskId}:agents:*`;
299
+ try {
300
+ let cursor = '0';
301
+ do {
302
+ const [newCursor, keys] = await this.redis.scan(cursor, 'MATCH', pattern);
303
+ cursor = newCursor;
304
+ for (const key of keys){
305
+ const agentIdMatch = key.match(/agents:(.+)$/);
306
+ if (agentIdMatch) {
307
+ const agentId = agentIdMatch[1];
308
+ const metadata = await this.getAgentMetadata(agentId);
309
+ if (metadata) {
310
+ agents.push(metadata);
311
+ }
312
+ }
313
+ }
314
+ }while (cursor !== '0')
315
+ return agents;
316
+ } catch (error) {
317
+ this.logger.error('Failed to get all agents', error);
318
+ return [];
319
+ }
320
+ }
321
+ /**
322
+ * Health check for agents
323
+ *
324
+ * Returns stale agents that haven't updated status recently.
325
+ */ async getStaleAgents(staleThresholdMs = 600000) {
326
+ const agents = await this.getAllAgents();
327
+ const now = Date.now();
328
+ const stale = [];
329
+ for (const agent of agents){
330
+ const lastHeartbeat = new Date(agent.lastHeartbeat).getTime();
331
+ if (now - lastHeartbeat > staleThresholdMs) {
332
+ stale.push(agent);
333
+ }
334
+ }
335
+ return stale;
336
+ }
337
+ /**
338
+ * Clean up task coordination data
339
+ *
340
+ * Removes all Redis keys associated with a task.
341
+ * Should only be called after task completion.
342
+ */ async cleanupTask() {
343
+ if (!this.canUseRedis) {
344
+ // Task Mode: Clear in-memory structures
345
+ this.taskModeRegistry.clear();
346
+ this.taskModeMessages.clear();
347
+ this.logger.info(`Task Mode: Cleaned up in-memory coordination data`);
348
+ return;
349
+ }
350
+ // CLI Mode: Remove Redis keys
351
+ const pattern = `swarm:${this.taskId}:*`;
352
+ try {
353
+ let cursor = '0';
354
+ const batch = 100;
355
+ do {
356
+ const [newCursor, keys] = await this.redis.scan(cursor, 'MATCH', pattern, 'COUNT', batch.toString());
357
+ cursor = newCursor;
358
+ if (keys.length > 0) {
359
+ await this.redis.del(...keys);
360
+ }
361
+ }while (cursor !== '0')
362
+ this.logger.info(`Cleaned up coordination data for task ${this.taskId}`);
363
+ } catch (error) {
364
+ this.logger.error('Failed to cleanup task coordination data', error);
365
+ }
366
+ }
367
+ }
368
+
369
+ //# sourceMappingURL=coordinate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/coordination/coordinate.ts"],"sourcesContent":["/**\r\n * Coordination Layer for Agent Communication and Tracking\r\n *\r\n * Provides agent registration, status tracking, message passing, and\r\n * coordination protocol enforcement with Redis as the backing store.\r\n *\r\n * Supports both Task Mode (Redis stubbed) and CLI Mode (full coordination).\r\n *\r\n * Key Features:\r\n * - Agent registration with metadata tracking\r\n * - Status updates and health checks\r\n * - Message passing between agents (pub/sub)\r\n * - Broadcast messages with protocol enforcement\r\n * - Wait for completion with timeout support\r\n * - Type-safe interfaces using branded types\r\n */\r\n\r\nimport type Redis from 'ioredis';\r\n// Types from Redis coordination skill\r\nimport type {\r\n TaskId,\r\n AgentId,\r\n CorrelationId,\r\n ExecutionMode,\r\n Logger,\r\n} from './types-export';\r\nimport {\r\n CoordinationError,\r\n CoordinationErrorType,\r\n} from './types-export';\r\n\r\n/**\r\n * Agent Registration Metadata\r\n *\r\n * Tracks agent information for coordination and monitoring.\r\n */\r\nexport interface AgentMetadata {\r\n agentId: AgentId;\r\n type: string;\r\n taskId: TaskId;\r\n status: AgentStatus;\r\n iteration: number;\r\n createdAt: string;\r\n lastHeartbeat: string;\r\n pid?: number;\r\n metadata?: Record<string, unknown>;\r\n}\r\n\r\n/**\r\n * Agent Status\r\n *\r\n * Lifecycle states for agents during execution.\r\n */\r\nexport type AgentStatus =\r\n | 'registered' // Just registered, not yet started\r\n | 'initializing' // Starting up, loading context\r\n | 'working' // Active work in progress\r\n | 'blocked' // Waiting for dependencies\r\n | 'complete' // Work complete\r\n | 'failed' // Execution failed\r\n | 'timeout' // Exceeded timeout\r\n | 'unknown'; // Status unknown\r\n\r\n/**\r\n * Coordination Message\r\n *\r\n * Structured message for agent-to-agent communication.\r\n */\r\nexport interface CoordinationMessage {\r\n from: AgentId;\r\n to: AgentId | 'broadcast';\r\n type: string;\r\n payload: Record<string, unknown>;\r\n timestamp: string;\r\n correlationId: CorrelationId;\r\n}\r\n\r\n/**\r\n * Broadcast Message\r\n *\r\n * Message delivered to all agents in a task.\r\n */\r\nexport interface BroadcastMessage {\r\n from: AgentId | 'orchestrator';\r\n taskId: TaskId;\r\n type: string;\r\n payload: Record<string, unknown>;\r\n timestamp: string;\r\n correlationId: CorrelationId;\r\n}\r\n\r\n/**\r\n * Coordination Layer Configuration\r\n */\r\nexport interface CoordinationConfig {\r\n redis: Redis;\r\n logger: Logger;\r\n canUseRedis: boolean;\r\n executionMode: ExecutionMode;\r\n taskId: TaskId;\r\n}\r\n\r\n/**\r\n * Coordination Layer Implementation\r\n *\r\n * Manages agent lifecycle, status tracking, and inter-agent communication.\r\n * Gracefully handles Task Mode (no Redis) and CLI Mode (full coordination).\r\n */\r\nexport class CoordinationLayer {\r\n private redis: Redis | null;\r\n private logger: Logger;\r\n private canUseRedis: boolean;\r\n private executionMode: ExecutionMode;\r\n private taskId: TaskId;\r\n\r\n // In-memory registry for Task Mode\r\n private taskModeRegistry: Map<AgentId, AgentMetadata> = new Map();\r\n private taskModeMessages: Map<string, CoordinationMessage[]> = new Map();\r\n\r\n constructor(config: CoordinationConfig) {\r\n this.redis = config.redis;\r\n this.logger = config.logger;\r\n this.canUseRedis = config.canUseRedis;\r\n this.executionMode = config.executionMode;\r\n this.taskId = config.taskId;\r\n }\r\n\r\n /**\r\n * Register an agent with the coordination layer\r\n *\r\n * Creates tracking record for agent lifecycle.\r\n */\r\n async registerAgent(\r\n agentId: AgentId,\r\n type: string,\r\n metadata?: Record<string, unknown>,\r\n iteration: number = 1,\r\n pid?: number\r\n ): Promise<void> {\r\n const now = new Date().toISOString();\r\n const agentMetadata: AgentMetadata = {\r\n agentId,\r\n type,\r\n taskId: this.taskId,\r\n status: 'registered',\r\n iteration,\r\n createdAt: now,\r\n lastHeartbeat: now,\r\n pid,\r\n metadata,\r\n };\r\n\r\n if (!this.canUseRedis) {\r\n // Task Mode: Store in memory\r\n this.taskModeRegistry.set(agentId, agentMetadata);\r\n this.logger.info(`Task Mode: Registered agent ${agentId} (type: ${type})`);\r\n return;\r\n }\r\n\r\n // CLI Mode: Store in Redis\r\n const key = `swarm:${this.taskId}:agents:${agentId}`;\r\n try {\r\n await this.redis!.hset(\r\n key,\r\n 'type', type,\r\n 'status', 'registered',\r\n 'iteration', iteration.toString(),\r\n 'createdAt', now,\r\n 'lastHeartbeat', now,\r\n ...(pid ? ['pid', pid.toString()] : []),\r\n ...(metadata ? ['metadata', JSON.stringify(metadata)] : [])\r\n );\r\n\r\n // Set 24h TTL\r\n await this.redis!.expire(key, 86400);\r\n\r\n this.logger.debug(`Registered agent ${agentId} in Redis`);\r\n } catch (error) {\r\n throw new CoordinationError(\r\n CoordinationErrorType.REDIS_ERROR,\r\n `Failed to register agent ${agentId}`,\r\n this.executionMode,\r\n true\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * Update agent status\r\n *\r\n * Tracks status changes during agent lifecycle.\r\n */\r\n async updateAgentStatus(agentId: AgentId, status: AgentStatus): Promise<void> {\r\n const now = new Date().toISOString();\r\n\r\n if (!this.canUseRedis) {\r\n // Task Mode: Update in memory\r\n const agent = this.taskModeRegistry.get(agentId);\r\n if (agent) {\r\n agent.status = status;\r\n agent.lastHeartbeat = now;\r\n this.taskModeRegistry.set(agentId, agent);\r\n }\r\n this.logger.debug(`Task Mode: Updated ${agentId} status to ${status}`);\r\n return;\r\n }\r\n\r\n // CLI Mode: Update in Redis\r\n const key = `swarm:${this.taskId}:agents:${agentId}`;\r\n try {\r\n await this.redis!.hset(\r\n key,\r\n 'status', status,\r\n 'lastHeartbeat', now\r\n );\r\n this.logger.debug(`Updated agent ${agentId} status to ${status}`);\r\n } catch (error) {\r\n throw new CoordinationError(\r\n CoordinationErrorType.REDIS_ERROR,\r\n `Failed to update agent ${agentId} status`,\r\n this.executionMode,\r\n true\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * Send direct message between agents\r\n *\r\n * Delivers message from one agent to another.\r\n */\r\n async sendMessage(\r\n from: AgentId,\r\n to: AgentId,\r\n messageType: string,\r\n payload: Record<string, unknown>,\r\n correlationId: CorrelationId\r\n ): Promise<void> {\r\n const message: CoordinationMessage = {\r\n from,\r\n to,\r\n type: messageType,\r\n payload,\r\n timestamp: new Date().toISOString(),\r\n correlationId,\r\n };\r\n\r\n if (!this.canUseRedis) {\r\n // Task Mode: Store in memory\r\n const key = `${from}:${to}`;\r\n if (!this.taskModeMessages.has(key)) {\r\n this.taskModeMessages.set(key, []);\r\n }\r\n this.taskModeMessages.get(key)!.push(message);\r\n this.logger.debug(`Task Mode: Message from ${from} to ${to}`);\r\n return;\r\n }\r\n\r\n // CLI Mode: Store in Redis\r\n const key = `swarm:${this.taskId}:messages:${from}:${to}`;\r\n try {\r\n await this.redis!.lpush(key, JSON.stringify(message));\r\n await this.redis!.expire(key, 3600); // 1h TTL for messages\r\n this.logger.debug(`Message sent from ${from} to ${to}`);\r\n } catch (error) {\r\n throw new CoordinationError(\r\n CoordinationErrorType.REDIS_ERROR,\r\n `Failed to send message from ${from} to ${to}`,\r\n this.executionMode,\r\n true\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * Broadcast message to all agents in task\r\n *\r\n * Delivers message to every agent participating in the task.\r\n * Used for coordination signals (gate passed, iteration started, etc).\r\n */\r\n async broadcastMessage(\r\n from: AgentId | 'orchestrator',\r\n messageType: string,\r\n payload: Record<string, unknown>,\r\n correlationId: CorrelationId\r\n ): Promise<void> {\r\n const message: BroadcastMessage = {\r\n from,\r\n taskId: this.taskId,\r\n type: messageType,\r\n payload,\r\n timestamp: new Date().toISOString(),\r\n correlationId,\r\n };\r\n\r\n if (!this.canUseRedis) {\r\n // Task Mode: Log broadcast\r\n this.logger.info(\r\n `Task Mode: Broadcast ${messageType} from ${from} (payload: ${JSON.stringify(payload)})`\r\n );\r\n return;\r\n }\r\n\r\n // CLI Mode: Store in Redis as sorted set for ordering\r\n const key = `swarm:${this.taskId}:broadcasts`;\r\n try {\r\n const timestamp = Date.now();\r\n await this.redis!.zadd(\r\n key,\r\n timestamp,\r\n JSON.stringify(message)\r\n );\r\n\r\n // Set 1h TTL\r\n await this.redis!.expire(key, 3600);\r\n\r\n this.logger.debug(`Broadcast ${messageType} to all agents in task ${this.taskId}`);\r\n } catch (error) {\r\n throw new CoordinationError(\r\n CoordinationErrorType.REDIS_ERROR,\r\n `Failed to broadcast message`,\r\n this.executionMode,\r\n true\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * Wait for agent completion\r\n *\r\n * Blocking wait for one or more agents to complete with timeout.\r\n * Used by orchestrator to synchronize on agent completion.\r\n */\r\n async waitForCompletion(\r\n agentIds: AgentId[],\r\n timeoutMs: number = 600000 // 10 minutes default\r\n ): Promise<Map<AgentId, AgentStatus>> {\r\n const results = new Map<AgentId, AgentStatus>();\r\n const startTime = Date.now();\r\n\r\n if (!this.canUseRedis) {\r\n // Task Mode: Poll in-memory registry\r\n while (Date.now() - startTime < timeoutMs) {\r\n let allComplete = true;\r\n\r\n for (const agentId of agentIds) {\r\n const agent = this.taskModeRegistry.get(agentId);\r\n const status = agent?.status ?? 'unknown';\r\n\r\n if (status === 'complete' || status === 'failed') {\r\n results.set(agentId, status);\r\n } else {\r\n allComplete = false;\r\n }\r\n }\r\n\r\n if (allComplete && results.size === agentIds.length) {\r\n return results;\r\n }\r\n\r\n // Wait 100ms before checking again\r\n await new Promise(resolve => setTimeout(resolve, 100));\r\n }\r\n\r\n // Timeout: Return whatever we have\r\n for (const agentId of agentIds) {\r\n if (!results.has(agentId)) {\r\n const agent = this.taskModeRegistry.get(agentId);\r\n results.set(agentId, agent?.status ?? 'timeout');\r\n }\r\n }\r\n return results;\r\n }\r\n\r\n // CLI Mode: Wait on Redis with blocking operations\r\n const channel = `swarm:${this.taskId}:completion`;\r\n\r\n try {\r\n while (Date.now() - startTime < timeoutMs) {\r\n for (const agentId of agentIds) {\r\n if (results.has(agentId)) continue;\r\n\r\n const key = `swarm:${this.taskId}:agents:${agentId}`;\r\n const statusStr = await this.redis!.hget(key, 'status');\r\n const status = (statusStr as AgentStatus) ?? 'unknown';\r\n\r\n if (status === 'complete' || status === 'failed' || status === 'timeout') {\r\n results.set(agentId, status);\r\n }\r\n }\r\n\r\n if (results.size === agentIds.length) {\r\n return results;\r\n }\r\n\r\n // Wait 100ms before checking again\r\n await new Promise(resolve => setTimeout(resolve, 100));\r\n }\r\n\r\n // Timeout: Mark remaining as timeout\r\n for (const agentId of agentIds) {\r\n if (!results.has(agentId)) {\r\n results.set(agentId, 'timeout');\r\n }\r\n }\r\n\r\n return results;\r\n } catch (error) {\r\n throw new CoordinationError(\r\n CoordinationErrorType.REDIS_ERROR,\r\n `Failed to wait for agent completion`,\r\n this.executionMode,\r\n true\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * Get agent status\r\n *\r\n * Returns current status for a single agent.\r\n */\r\n async getAgentStatus(agentId: AgentId): Promise<AgentStatus> {\r\n if (!this.canUseRedis) {\r\n // Task Mode: Check in-memory registry\r\n const agent = this.taskModeRegistry.get(agentId);\r\n return agent?.status ?? 'unknown';\r\n }\r\n\r\n // CLI Mode: Get from Redis\r\n const key = `swarm:${this.taskId}:agents:${agentId}`;\r\n try {\r\n const status = await this.redis!.hget(key, 'status');\r\n return (status as AgentStatus) ?? 'unknown';\r\n } catch (error) {\r\n this.logger.error(`Failed to get agent ${agentId} status`, error);\r\n return 'unknown';\r\n }\r\n }\r\n\r\n /**\r\n * Get agent metadata\r\n *\r\n * Returns full metadata for a registered agent.\r\n */\r\n async getAgentMetadata(agentId: AgentId): Promise<AgentMetadata | null> {\r\n if (!this.canUseRedis) {\r\n // Task Mode: Return from in-memory registry\r\n return this.taskModeRegistry.get(agentId) ?? null;\r\n }\r\n\r\n // CLI Mode: Get from Redis\r\n const key = `swarm:${this.taskId}:agents:${agentId}`;\r\n try {\r\n const data = await this.redis!.hgetall(key);\r\n\r\n if (!data || Object.keys(data).length === 0) {\r\n return null;\r\n }\r\n\r\n return {\r\n agentId,\r\n type: data.type,\r\n taskId: this.taskId,\r\n status: (data.status as AgentStatus) || 'unknown',\r\n iteration: parseInt(data.iteration || '1', 10),\r\n createdAt: data.createdAt,\r\n lastHeartbeat: data.lastHeartbeat,\r\n pid: data.pid ? parseInt(data.pid, 10) : undefined,\r\n metadata: data.metadata ? JSON.parse(data.metadata) : undefined,\r\n };\r\n } catch (error) {\r\n this.logger.error(`Failed to get agent ${agentId} metadata`, error);\r\n return null;\r\n }\r\n }\r\n\r\n /**\r\n * Get all agents for a task\r\n *\r\n * Returns metadata for all registered agents.\r\n */\r\n async getAllAgents(): Promise<AgentMetadata[]> {\r\n if (!this.canUseRedis) {\r\n // Task Mode: Return from in-memory registry\r\n return Array.from(this.taskModeRegistry.values());\r\n }\r\n\r\n // CLI Mode: Scan Redis for all agents\r\n const agents: AgentMetadata[] = [];\r\n const pattern = `swarm:${this.taskId}:agents:*`;\r\n\r\n try {\r\n let cursor = '0';\r\n do {\r\n const [newCursor, keys] = await this.redis!.scan(cursor, 'MATCH', pattern);\r\n cursor = newCursor;\r\n\r\n for (const key of keys) {\r\n const agentIdMatch = key.match(/agents:(.+)$/);\r\n if (agentIdMatch) {\r\n const agentId = agentIdMatch[1] as AgentId;\r\n const metadata = await this.getAgentMetadata(agentId);\r\n if (metadata) {\r\n agents.push(metadata);\r\n }\r\n }\r\n }\r\n } while (cursor !== '0');\r\n\r\n return agents;\r\n } catch (error) {\r\n this.logger.error('Failed to get all agents', error);\r\n return [];\r\n }\r\n }\r\n\r\n /**\r\n * Health check for agents\r\n *\r\n * Returns stale agents that haven't updated status recently.\r\n */\r\n async getStaleAgents(staleThresholdMs: number = 600000): Promise<AgentMetadata[]> {\r\n const agents = await this.getAllAgents();\r\n const now = Date.now();\r\n const stale: AgentMetadata[] = [];\r\n\r\n for (const agent of agents) {\r\n const lastHeartbeat = new Date(agent.lastHeartbeat).getTime();\r\n if (now - lastHeartbeat > staleThresholdMs) {\r\n stale.push(agent);\r\n }\r\n }\r\n\r\n return stale;\r\n }\r\n\r\n /**\r\n * Clean up task coordination data\r\n *\r\n * Removes all Redis keys associated with a task.\r\n * Should only be called after task completion.\r\n */\r\n async cleanupTask(): Promise<void> {\r\n if (!this.canUseRedis) {\r\n // Task Mode: Clear in-memory structures\r\n this.taskModeRegistry.clear();\r\n this.taskModeMessages.clear();\r\n this.logger.info(`Task Mode: Cleaned up in-memory coordination data`);\r\n return;\r\n }\r\n\r\n // CLI Mode: Remove Redis keys\r\n const pattern = `swarm:${this.taskId}:*`;\r\n try {\r\n let cursor = '0';\r\n const batch = 100;\r\n\r\n do {\r\n const [newCursor, keys] = await this.redis!.scan(cursor, 'MATCH', pattern, 'COUNT', batch.toString());\r\n cursor = newCursor;\r\n\r\n if (keys.length > 0) {\r\n await this.redis!.del(...keys);\r\n }\r\n } while (cursor !== '0');\r\n\r\n this.logger.info(`Cleaned up coordination data for task ${this.taskId}`);\r\n } catch (error) {\r\n this.logger.error('Failed to cleanup task coordination data', error);\r\n }\r\n }\r\n}\r\n"],"names":["CoordinationError","CoordinationErrorType","CoordinationLayer","redis","logger","canUseRedis","executionMode","taskId","taskModeRegistry","Map","taskModeMessages","config","registerAgent","agentId","type","metadata","iteration","pid","now","Date","toISOString","agentMetadata","status","createdAt","lastHeartbeat","set","info","key","hset","toString","JSON","stringify","expire","debug","error","REDIS_ERROR","updateAgentStatus","agent","get","sendMessage","from","to","messageType","payload","correlationId","message","timestamp","has","push","lpush","broadcastMessage","zadd","waitForCompletion","agentIds","timeoutMs","results","startTime","allComplete","size","length","Promise","resolve","setTimeout","channel","statusStr","hget","getAgentStatus","getAgentMetadata","data","hgetall","Object","keys","parseInt","undefined","parse","getAllAgents","Array","values","agents","pattern","cursor","newCursor","scan","agentIdMatch","match","getStaleAgents","staleThresholdMs","stale","getTime","cleanupTask","clear","batch","del"],"mappings":"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"}