claude-flow-novice 2.15.9 → 2.15.10

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 (39) 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/coordinators/cfn-v3-coordinator.md +180 -229
  10. package/claude-assets/agents/cfn-dev-team/dev-ops/docker-specialist.md +2 -0
  11. package/claude-assets/agents/cfn-dev-team/dev-ops/kubernetes-specialist.md +2 -0
  12. package/claude-assets/agents/cfn-dev-team/developers/api-gateway-specialist.md +2 -1
  13. package/claude-assets/agents/cfn-dev-team/developers/database/database-architect.md +3 -0
  14. package/claude-assets/agents/cfn-dev-team/developers/frontend/mobile-dev.md +4 -1
  15. package/claude-assets/agents/cfn-dev-team/developers/frontend/react-frontend-engineer.md +4 -1
  16. package/claude-assets/agents/cfn-dev-team/developers/frontend/typescript-specialist.md +4 -1
  17. package/claude-assets/agents/cfn-dev-team/developers/frontend/ui-designer.md +5 -0
  18. package/claude-assets/agents/cfn-dev-team/developers/graphql-specialist.md +2 -1
  19. package/claude-assets/agents/cfn-dev-team/developers/rust-developer.md +2 -1
  20. package/claude-assets/agents/cfn-dev-team/documentation/pseudocode.md +2 -7
  21. package/claude-assets/agents/cfn-dev-team/utility/epic-creator.md +16 -9
  22. package/claude-assets/agents/cfn-dev-team/utility/memory-leak-specialist.md +16 -9
  23. package/claude-assets/agents/cfn-dev-team/utility/z-ai-specialist.md +16 -9
  24. package/claude-assets/skills/cfn-loop-orchestration/IMPLEMENTATION_SUMMARY.md +519 -0
  25. package/claude-assets/skills/cfn-loop-orchestration/ORCHESTRATOR_IMPLEMENTATION.md +493 -0
  26. package/claude-assets/skills/cfn-loop-orchestration/ORCHESTRATOR_QUICK_START.md +499 -0
  27. package/claude-assets/skills/cfn-loop-orchestration/helpers/orchestrate-ts.sh +104 -0
  28. package/claude-assets/skills/cfn-loop-orchestration/orchestrate.sh +2 -2
  29. package/claude-assets/skills/cfn-loop-orchestration/src/orchestrate.ts +648 -0
  30. package/claude-assets/skills/cfn-loop-orchestration/tests/orchestrate.test.ts +836 -0
  31. package/dist/cli/config-manager.js +91 -109
  32. package/dist/cli/config-manager.js.map +1 -1
  33. package/dist/coordination/coordinate.js +369 -0
  34. package/dist/coordination/coordinate.js.map +1 -0
  35. package/dist/coordination/spawn-agent.js +364 -0
  36. package/dist/coordination/spawn-agent.js.map +1 -0
  37. package/dist/coordination/types-export.js +38 -0
  38. package/dist/coordination/types-export.js.map +1 -0
  39. package/package.json +1 -1
@@ -0,0 +1,648 @@
1
+ /**
2
+ * CFN Loop Orchestrator - Complete TypeScript Implementation
3
+ * Orchestrates the Fail Never (CFN) Loop workflow with test-driven validation
4
+ * Supports MVP, Standard, and Enterprise execution modes
5
+ *
6
+ * Version: 3.0.0
7
+ */
8
+
9
+ import { gateCheck, GateCheckParams } from './helpers/gate-check';
10
+ import { collectConsensus, validateConsensus } from './helpers/consensus';
11
+ import { TestResult, ExecutionMode } from './types';
12
+
13
+ /**
14
+ * Execution phases in the CFN Loop
15
+ */
16
+ export type LoopPhase = 'loop3' | 'loop2' | 'product-owner' | 'complete';
17
+
18
+ /**
19
+ * Product owner decision outcomes
20
+ */
21
+ export type ProductOwnerDecision = 'PROCEED' | 'ITERATE' | 'ABORT' | null;
22
+
23
+ /**
24
+ * Orchestration configuration
25
+ */
26
+ export interface OrchestrationConfig {
27
+ taskId: string;
28
+ mode: ExecutionMode;
29
+ maxIterations: number;
30
+ aceReflect?: boolean;
31
+ }
32
+
33
+ /**
34
+ * Agent execution context
35
+ */
36
+ export interface AgentExecutionContext {
37
+ agentId: string;
38
+ agentType: string;
39
+ loopType: 'loop3' | 'loop2';
40
+ iteration: number;
41
+ taskId: string;
42
+ timestamp: number;
43
+ }
44
+
45
+ /**
46
+ * Phase transition tracking
47
+ */
48
+ export interface PhaseTransition {
49
+ fromPhase: LoopPhase;
50
+ toPhase: LoopPhase;
51
+ timestamp: number;
52
+ iteration: number;
53
+ }
54
+
55
+ /**
56
+ * Gate check result
57
+ */
58
+ export interface GateCheckResult {
59
+ passed: boolean;
60
+ passRate: number;
61
+ threshold: number;
62
+ gap: number;
63
+ }
64
+
65
+ /**
66
+ * Consensus validation result
67
+ */
68
+ export interface ConsensusValidationResult {
69
+ passed: boolean;
70
+ average: number;
71
+ threshold: number;
72
+ gap: number;
73
+ }
74
+
75
+ /**
76
+ * Test result aggregation
77
+ */
78
+ export interface AggregatedTestResults {
79
+ totalPass: number;
80
+ totalFail: number;
81
+ totalSkip: number;
82
+ passRate: number;
83
+ agentCount: number;
84
+ }
85
+
86
+ /**
87
+ * Orchestration state tracking
88
+ */
89
+ export interface OrchestrationState {
90
+ taskId: string;
91
+ mode: ExecutionMode;
92
+ iteration: number;
93
+ currentPhase: LoopPhase;
94
+ completedAgents: Set<string>;
95
+ failedAgents: Set<string>;
96
+ startTime: number;
97
+ lastUpdateTime: number;
98
+ }
99
+
100
+ /**
101
+ * Feedback for next iteration
102
+ */
103
+ export interface IterationFeedback {
104
+ gatePassRate?: number;
105
+ consensusAverage?: number;
106
+ previousFailures?: string[];
107
+ reasons?: string[];
108
+ timestamp?: number;
109
+ }
110
+
111
+ /**
112
+ * Mode-specific configuration
113
+ */
114
+ interface ModeThresholds {
115
+ gateThreshold: number;
116
+ consensusThreshold: number;
117
+ maxIterations: number;
118
+ }
119
+
120
+ const MODE_CONFIG: Record<ExecutionMode, ModeThresholds> = {
121
+ mvp: {
122
+ gateThreshold: 0.70,
123
+ consensusThreshold: 0.80,
124
+ maxIterations: 5,
125
+ },
126
+ standard: {
127
+ gateThreshold: 0.95,
128
+ consensusThreshold: 0.90,
129
+ maxIterations: 10,
130
+ },
131
+ enterprise: {
132
+ gateThreshold: 0.98,
133
+ consensusThreshold: 0.95,
134
+ maxIterations: 15,
135
+ },
136
+ };
137
+
138
+ /**
139
+ * Main orchestrator class
140
+ */
141
+ export class Orchestrator {
142
+ private config: OrchestrationConfig;
143
+ private state: OrchestrationState;
144
+ private testResults: Map<string, TestResult> = new Map();
145
+ private consensusScores: Map<string, number> = new Map();
146
+ private decision: ProductOwnerDecision = null;
147
+ private errors: Map<string, Error> = new Map();
148
+ private phaseHistory: PhaseTransition[] = [];
149
+
150
+ constructor(config: OrchestrationConfig) {
151
+ // Validate configuration
152
+ this.validateConfig(config);
153
+
154
+ this.config = config;
155
+ this.state = this.initializeState(config);
156
+ }
157
+
158
+ /**
159
+ * Validate configuration parameters
160
+ */
161
+ private validateConfig(config: OrchestrationConfig): void {
162
+ if (!config.taskId || config.taskId.trim() === '') {
163
+ throw new Error('Task ID cannot be empty');
164
+ }
165
+
166
+ const validModes: ExecutionMode[] = ['mvp', 'standard', 'enterprise'];
167
+ if (!validModes.includes(config.mode)) {
168
+ throw new Error(`Invalid execution mode: ${config.mode}`);
169
+ }
170
+
171
+ if (!Number.isInteger(config.maxIterations) || config.maxIterations < 1) {
172
+ throw new Error('Max iterations must be at least 1');
173
+ }
174
+
175
+ if (config.maxIterations > 100) {
176
+ throw new Error('Max iterations cannot exceed 100');
177
+ }
178
+ }
179
+
180
+ /**
181
+ * Initialize orchestration state
182
+ */
183
+ private initializeState(config: OrchestrationConfig): OrchestrationState {
184
+ const now = Date.now();
185
+
186
+ return {
187
+ taskId: config.taskId,
188
+ mode: config.mode,
189
+ iteration: 0,
190
+ currentPhase: 'loop3',
191
+ completedAgents: new Set(),
192
+ failedAgents: new Set(),
193
+ startTime: now,
194
+ lastUpdateTime: now,
195
+ };
196
+ }
197
+
198
+ /**
199
+ * Get current orchestration state
200
+ */
201
+ public getState(): OrchestrationState {
202
+ return { ...this.state, completedAgents: new Set(this.state.completedAgents), failedAgents: new Set(this.state.failedAgents) };
203
+ }
204
+
205
+ /**
206
+ * Get task ID
207
+ */
208
+ public getTaskId(): string {
209
+ return this.config.taskId;
210
+ }
211
+
212
+ /**
213
+ * Get execution mode
214
+ */
215
+ public getMode(): ExecutionMode {
216
+ return this.config.mode;
217
+ }
218
+
219
+ /**
220
+ * Get maximum iterations for mode
221
+ */
222
+ public getMaxIterations(): number {
223
+ return this.config.maxIterations;
224
+ }
225
+
226
+ /**
227
+ * Get gate threshold for current mode
228
+ */
229
+ public getGateThreshold(): number {
230
+ return MODE_CONFIG[this.config.mode].gateThreshold;
231
+ }
232
+
233
+ /**
234
+ * Get consensus threshold for current mode
235
+ */
236
+ public getConsensusThreshold(): number {
237
+ return MODE_CONFIG[this.config.mode].consensusThreshold;
238
+ }
239
+
240
+ /**
241
+ * Transition to next phase
242
+ */
243
+ public transitionPhase(newPhase: LoopPhase): void {
244
+ const transition: PhaseTransition = {
245
+ fromPhase: this.state.currentPhase,
246
+ toPhase: newPhase,
247
+ timestamp: Date.now(),
248
+ iteration: this.state.iteration,
249
+ };
250
+
251
+ this.phaseHistory.push(transition);
252
+ this.state.currentPhase = newPhase;
253
+ this.state.lastUpdateTime = Date.now();
254
+ }
255
+
256
+ /**
257
+ * Increment iteration counter
258
+ */
259
+ public incrementIteration(): void {
260
+ this.state.iteration++;
261
+ this.state.lastUpdateTime = Date.now();
262
+ }
263
+
264
+ /**
265
+ * Check if can continue iterating
266
+ */
267
+ public canContinueIterating(): boolean {
268
+ return this.state.iteration < this.config.maxIterations;
269
+ }
270
+
271
+ /**
272
+ * Check if orchestration should terminate
273
+ */
274
+ public shouldTerminate(): boolean {
275
+ if (this.decision === 'PROCEED' || this.decision === 'ABORT') {
276
+ return true;
277
+ }
278
+
279
+ if (this.decision === 'ITERATE' && !this.canContinueIterating()) {
280
+ return true;
281
+ }
282
+
283
+ return false;
284
+ }
285
+
286
+ /**
287
+ * Mark agent as completed
288
+ */
289
+ public markAgentComplete(agentId: string, _loopType: 'loop3' | 'loop2'): void {
290
+ this.state.completedAgents.add(agentId);
291
+ this.state.failedAgents.delete(agentId);
292
+ this.state.lastUpdateTime = Date.now();
293
+ }
294
+
295
+ /**
296
+ * Mark agent as failed
297
+ */
298
+ public markAgentFailed(agentId: string, _loopType: 'loop3' | 'loop2'): void {
299
+ this.state.failedAgents.add(agentId);
300
+ this.state.completedAgents.delete(agentId);
301
+ this.state.lastUpdateTime = Date.now();
302
+ }
303
+
304
+ /**
305
+ * Record execution error for agent
306
+ */
307
+ public recordExecutionError(agentId: string, error: Error): void {
308
+ this.errors.set(agentId, error);
309
+ this.markAgentFailed(agentId, 'loop3');
310
+ }
311
+
312
+ /**
313
+ * Record timeout for agent
314
+ */
315
+ public recordTimeout(agentId: string, timeoutSeconds: number): void {
316
+ const error = new Error(`Agent timeout after ${timeoutSeconds}s`);
317
+ this.recordExecutionError(agentId, error);
318
+ }
319
+
320
+ /**
321
+ * Record test results for agent
322
+ */
323
+ public recordTestResult(agentId: string, result: TestResult): void {
324
+ this.testResults.set(agentId, result);
325
+ this.state.lastUpdateTime = Date.now();
326
+ }
327
+
328
+ /**
329
+ * Get test result for agent
330
+ */
331
+ public getTestResult(agentId: string): TestResult | undefined {
332
+ return this.testResults.get(agentId);
333
+ }
334
+
335
+ /**
336
+ * Aggregate test results across all agents
337
+ */
338
+ public aggregateTestResults(): AggregatedTestResults {
339
+ let totalPass = 0;
340
+ let totalFail = 0;
341
+ let totalSkip = 0;
342
+
343
+ for (const result of this.testResults.values()) {
344
+ totalPass += result.pass;
345
+ totalFail += result.fail;
346
+ totalSkip += result.skip ?? 0;
347
+ }
348
+
349
+ const total = totalPass + totalFail + totalSkip;
350
+ const passRate = total === 0 ? 0 : totalPass / total;
351
+
352
+ return {
353
+ totalPass,
354
+ totalFail,
355
+ totalSkip,
356
+ passRate,
357
+ agentCount: this.testResults.size,
358
+ };
359
+ }
360
+
361
+ /**
362
+ * Check gate (Loop 3 → Loop 2 transition)
363
+ */
364
+ public checkGate(passRate: number): GateCheckResult {
365
+ const threshold = this.getGateThreshold();
366
+
367
+ const params: GateCheckParams = {
368
+ passRate,
369
+ mode: this.config.mode,
370
+ threshold,
371
+ };
372
+
373
+ const result = gateCheck(params);
374
+
375
+ return {
376
+ passed: result.passed,
377
+ passRate: result.passRate,
378
+ threshold: result.threshold,
379
+ gap: result.gap,
380
+ };
381
+ }
382
+
383
+ /**
384
+ * Record consensus score from validator
385
+ */
386
+ public recordConsensusScore(validatorId: string, score: number): void {
387
+ if (score < 0 || score > 1) {
388
+ throw new Error(`Invalid consensus score: ${score} (must be 0.0-1.0)`);
389
+ }
390
+
391
+ this.consensusScores.set(validatorId, score);
392
+ this.state.lastUpdateTime = Date.now();
393
+ }
394
+
395
+ /**
396
+ * Get all consensus scores
397
+ */
398
+ public getConsensusScores(): number[] {
399
+ return Array.from(this.consensusScores.values());
400
+ }
401
+
402
+ /**
403
+ * Get consensus average
404
+ */
405
+ public getConsensusAverage(): number {
406
+ const scores = this.getConsensusScores();
407
+
408
+ if (scores.length === 0) {
409
+ throw new Error('No consensus scores recorded');
410
+ }
411
+
412
+ const sum = scores.reduce((a, b) => a + b, 0);
413
+ return sum / scores.length;
414
+ }
415
+
416
+ /**
417
+ * Validate consensus against threshold
418
+ */
419
+ public validateConsensus(): ConsensusValidationResult {
420
+ const scores = this.getConsensusScores();
421
+
422
+ if (scores.length === 0) {
423
+ throw new Error('No consensus scores recorded');
424
+ }
425
+
426
+ const result = collectConsensus(scores);
427
+ const validation = validateConsensus({
428
+ average: result.average,
429
+ mode: this.config.mode,
430
+ threshold: this.getConsensusThreshold(),
431
+ });
432
+
433
+ return {
434
+ passed: validation.passed,
435
+ average: validation.average,
436
+ threshold: validation.threshold,
437
+ gap: validation.gap,
438
+ };
439
+ }
440
+
441
+ /**
442
+ * Record product owner decision
443
+ */
444
+ public recordDecision(decision: ProductOwnerDecision): void {
445
+ this.decision = decision;
446
+ this.state.lastUpdateTime = Date.now();
447
+ }
448
+
449
+ /**
450
+ * Get recorded decision
451
+ */
452
+ public getDecision(): ProductOwnerDecision {
453
+ return this.decision;
454
+ }
455
+
456
+ /**
457
+ * Parse decision from agent output
458
+ */
459
+ public parseDecisionFromOutput(output: string): ProductOwnerDecision {
460
+ const normalizedOutput = output.toUpperCase();
461
+
462
+ if (normalizedOutput.includes('PROCEED')) {
463
+ return 'PROCEED';
464
+ }
465
+
466
+ if (normalizedOutput.includes('ITERATE')) {
467
+ return 'ITERATE';
468
+ }
469
+
470
+ if (normalizedOutput.includes('ABORT')) {
471
+ return 'ABORT';
472
+ }
473
+
474
+ return null;
475
+ }
476
+
477
+ /**
478
+ * Spawn Loop 3 (implementer) agents
479
+ */
480
+ public async spawnLoop3Agents(agentTypes: string[]): Promise<AgentExecutionContext[]> {
481
+ const agents: AgentExecutionContext[] = [];
482
+ const now = Date.now();
483
+
484
+ agentTypes.forEach((agentType, index) => {
485
+ agents.push({
486
+ agentId: `${agentType}-${this.state.iteration + 1}-${index + 1}`,
487
+ agentType,
488
+ loopType: 'loop3',
489
+ iteration: this.state.iteration + 1,
490
+ taskId: this.config.taskId,
491
+ timestamp: now,
492
+ });
493
+ });
494
+
495
+ return agents;
496
+ }
497
+
498
+ /**
499
+ * Spawn Loop 2 (validator) agents
500
+ */
501
+ public async spawnLoop2Validators(validatorTypes: string[]): Promise<AgentExecutionContext[]> {
502
+ const validators: AgentExecutionContext[] = [];
503
+ const now = Date.now();
504
+
505
+ validatorTypes.forEach((validatorType, index) => {
506
+ validators.push({
507
+ agentId: `${validatorType}-${this.state.iteration + 1}-${index + 1}`,
508
+ agentType: validatorType,
509
+ loopType: 'loop2',
510
+ iteration: this.state.iteration + 1,
511
+ taskId: this.config.taskId,
512
+ timestamp: now,
513
+ });
514
+ });
515
+
516
+ return validators;
517
+ }
518
+
519
+ /**
520
+ * Build agent context for spawning
521
+ */
522
+ public buildAgentContext(
523
+ agentId: string,
524
+ loopType: 'loop3' | 'loop2',
525
+ iteration: number,
526
+ _feedback?: IterationFeedback
527
+ ): AgentExecutionContext {
528
+ return {
529
+ agentId,
530
+ agentType: 'unknown',
531
+ loopType,
532
+ iteration,
533
+ taskId: this.config.taskId,
534
+ timestamp: Date.now(),
535
+ };
536
+ }
537
+
538
+ /**
539
+ * Prepare feedback for next iteration
540
+ */
541
+ public prepareFeedback(feedback: IterationFeedback): IterationFeedback {
542
+ return {
543
+ ...feedback,
544
+ timestamp: Date.now(),
545
+ };
546
+ }
547
+
548
+ /**
549
+ * Get phase history
550
+ */
551
+ public getPhaseHistory(): PhaseTransition[] {
552
+ return [...this.phaseHistory];
553
+ }
554
+
555
+ /**
556
+ * Get execution errors
557
+ */
558
+ public getErrors(): Map<string, Error> {
559
+ return new Map(this.errors);
560
+ }
561
+
562
+ /**
563
+ * Reset state for new iteration
564
+ */
565
+ public resetForIteration(): void {
566
+ this.testResults.clear();
567
+ this.consensusScores.clear();
568
+ this.decision = null;
569
+ this.errors.clear();
570
+ this.state.completedAgents.clear();
571
+ this.state.failedAgents.clear();
572
+ }
573
+
574
+ /**
575
+ * Get orchestration summary
576
+ */
577
+ public getSummary(): {
578
+ taskId: string;
579
+ mode: ExecutionMode;
580
+ iteration: number;
581
+ totalAgentsCompleted: number;
582
+ totalAgentsFailed: number;
583
+ decision: ProductOwnerDecision;
584
+ duration: number;
585
+ } {
586
+ return {
587
+ taskId: this.config.taskId,
588
+ mode: this.config.mode,
589
+ iteration: this.state.iteration,
590
+ totalAgentsCompleted: this.state.completedAgents.size,
591
+ totalAgentsFailed: this.state.failedAgents.size,
592
+ decision: this.decision,
593
+ duration: Date.now() - this.state.startTime,
594
+ };
595
+ }
596
+ }
597
+
598
+ /**
599
+ * CLI entry point for orchestrator
600
+ */
601
+ if (require.main === module) {
602
+ const args = process.argv.slice(2);
603
+
604
+ // Parse command line arguments
605
+ let taskId = '';
606
+ let mode: ExecutionMode = 'standard';
607
+ let maxIterations = 10;
608
+
609
+ for (let i = 0; i < args.length; i++) {
610
+ const arg = args[i];
611
+ if (!arg) continue;
612
+
613
+ switch (arg) {
614
+ case '--task-id': {
615
+ const nextArg = args[++i];
616
+ if (nextArg) taskId = nextArg;
617
+ break;
618
+ }
619
+ case '--mode': {
620
+ const nextArg = args[++i];
621
+ if (nextArg) mode = nextArg as ExecutionMode;
622
+ break;
623
+ }
624
+ case '--max-iterations': {
625
+ const nextArg = args[++i];
626
+ if (nextArg) maxIterations = parseInt(nextArg, 10);
627
+ break;
628
+ }
629
+ }
630
+ }
631
+
632
+ if (!taskId) {
633
+ console.error('Error: --task-id is required');
634
+ process.exit(1);
635
+ }
636
+
637
+ const config: OrchestrationConfig = {
638
+ taskId,
639
+ mode,
640
+ maxIterations,
641
+ };
642
+
643
+ const orchestrator = new Orchestrator(config);
644
+ console.log(JSON.stringify(orchestrator.getState(), null, 2));
645
+ process.exit(0);
646
+ }
647
+
648
+ export default Orchestrator;