@polymorphism-tech/morph-spec 4.2.0 → 4.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (140) hide show
  1. package/CLAUDE.md +108 -946
  2. package/bin/morph-spec.js +284 -9
  3. package/bin/task-manager.cjs +102 -14
  4. package/bin/validate.js +4 -4
  5. package/docs/{v3.0 → next-generation}/AGENTS.md +1 -1
  6. package/docs/next-generation/CONTEXT-OPTIMIZATION.md +267 -0
  7. package/docs/next-generation/EXECUTION-FLOW.md +274 -0
  8. package/docs/next-generation/META-PROMPTS.md +235 -0
  9. package/docs/next-generation/MIGRATION-GUIDE.md +253 -0
  10. package/docs/next-generation/THREAD-MANAGEMENT.md +240 -0
  11. package/package.json +5 -5
  12. package/src/commands/agents/agents-fuse.js +97 -0
  13. package/src/commands/agents/micro-agent.js +112 -0
  14. package/src/commands/agents/spawn-team.js +69 -4
  15. package/src/commands/agents/squad-template.js +146 -0
  16. package/src/commands/analytics/analytics.js +176 -0
  17. package/src/commands/context/context-prime.js +63 -0
  18. package/src/commands/context/core-four.js +54 -0
  19. package/src/commands/mcp/mcp.js +102 -0
  20. package/src/commands/project/detect-agents.js +32 -2
  21. package/src/commands/project/detect.js +11 -1
  22. package/src/commands/project/doctor.js +573 -356
  23. package/src/commands/project/init.js +9 -2
  24. package/src/commands/project/update.js +13 -3
  25. package/src/commands/state/advance-phase.js +448 -416
  26. package/src/commands/state/state.js +14 -12
  27. package/src/commands/tasks/task.js +1 -1
  28. package/src/commands/templates/template-render.js +80 -1
  29. package/src/commands/threads/thread-template.js +103 -0
  30. package/src/commands/threads/threads.js +261 -0
  31. package/src/commands/trust/trust.js +205 -0
  32. package/src/{orchestrator.js → core/orchestrator.js} +8 -8
  33. package/src/core/state/state-manager.js +37 -17
  34. package/src/core/workflows/workflow-detector.js +114 -3
  35. package/src/lib/agents/micro-agent-factory.js +161 -0
  36. package/src/lib/analytics/analytics-engine.js +345 -0
  37. package/src/lib/checkpoints/checkpoint-hooks.js +298 -258
  38. package/src/lib/context/context-bundler.js +240 -0
  39. package/src/lib/context/context-optimizer.js +212 -0
  40. package/src/lib/context/context-tracker.js +273 -0
  41. package/src/lib/context/core-four-tracker.js +201 -0
  42. package/src/lib/context/mcp-optimizer.js +200 -0
  43. package/src/lib/detectors/index.js +1 -1
  44. package/src/lib/detectors/standards-generator.js +77 -17
  45. package/src/lib/detectors/structure-detector.js +67 -39
  46. package/src/lib/execution/fusion-executor.js +304 -0
  47. package/src/lib/execution/parallel-executor.js +270 -0
  48. package/src/lib/generators/context-generator.js +3 -3
  49. package/src/lib/generators/recap-generator.js +32 -12
  50. package/src/lib/hooks/hook-executor.js +169 -0
  51. package/src/lib/hooks/stop-hook-executor.js +286 -0
  52. package/src/lib/hops/hop-composer.js +221 -0
  53. package/src/lib/threads/thread-coordinator.js +238 -0
  54. package/src/lib/threads/thread-manager.js +317 -0
  55. package/src/lib/tracking/artifact-trail.js +202 -0
  56. package/src/lib/trust/trust-manager.js +269 -0
  57. package/src/lib/validators/design-system/design-system-validator.js +2 -2
  58. package/src/lib/validators/validation-runner.js +14 -30
  59. package/src/utils/hooks-installer.js +69 -0
  60. package/stacks/blazor-azure/.morph/config/agents.json +72 -3
  61. package/stacks/nextjs-supabase/.morph/config/agents.json +3 -3
  62. package/docs/llm-interaction-config.md +0 -735
  63. package/docs/v3.0/EXECUTION-FLOW.md +0 -1304
  64. package/src/commands/utils/migrate-state.js +0 -158
  65. package/src/commands/utils/upgrade.js +0 -346
  66. package/src/lib/validators/architecture-validator.js +0 -60
  67. package/src/lib/validators/content-validator.js +0 -164
  68. package/src/lib/validators/package-validator.js +0 -61
  69. package/src/lib/validators/ui-contrast-validator.js +0 -44
  70. package/stacks/blazor-azure/.claude/commands/morph-apply.md +0 -221
  71. package/stacks/blazor-azure/.claude/commands/morph-archive.md +0 -79
  72. package/stacks/blazor-azure/.claude/commands/morph-deploy.md +0 -529
  73. package/stacks/blazor-azure/.claude/commands/morph-infra.md +0 -209
  74. package/stacks/blazor-azure/.claude/commands/morph-preflight.md +0 -227
  75. package/stacks/blazor-azure/.claude/commands/morph-proposal.md +0 -122
  76. package/stacks/blazor-azure/.claude/commands/morph-status.md +0 -86
  77. package/stacks/blazor-azure/.claude/commands/morph-troubleshoot.md +0 -122
  78. package/stacks/blazor-azure/.claude/skills/level-0-meta/README.md +0 -7
  79. package/stacks/blazor-azure/.claude/skills/level-0-meta/code-review.md +0 -226
  80. package/stacks/blazor-azure/.claude/skills/level-0-meta/morph-checklist.md +0 -117
  81. package/stacks/blazor-azure/.claude/skills/level-0-meta/simulation-checklist.md +0 -77
  82. package/stacks/blazor-azure/.claude/skills/level-1-workflows/README.md +0 -7
  83. package/stacks/blazor-azure/.claude/skills/level-1-workflows/morph-replicate.md +0 -213
  84. package/stacks/blazor-azure/.claude/skills/level-1-workflows/phase-clarify.md +0 -131
  85. package/stacks/blazor-azure/.claude/skills/level-1-workflows/phase-design.md +0 -213
  86. package/stacks/blazor-azure/.claude/skills/level-1-workflows/phase-setup.md +0 -106
  87. package/stacks/blazor-azure/.claude/skills/level-1-workflows/phase-tasks.md +0 -164
  88. package/stacks/blazor-azure/.claude/skills/level-1-workflows/phase-uiux.md +0 -169
  89. package/stacks/blazor-azure/.claude/skills/level-2-domains/README.md +0 -14
  90. package/stacks/blazor-azure/.claude/skills/level-2-domains/ai-agents/ai-system-architect.md +0 -192
  91. package/stacks/blazor-azure/.claude/skills/level-2-domains/architecture/po-pm-advisor.md +0 -197
  92. package/stacks/blazor-azure/.claude/skills/level-2-domains/architecture/prompt-engineer.md +0 -189
  93. package/stacks/blazor-azure/.claude/skills/level-2-domains/architecture/seo-growth-hacker.md +0 -320
  94. package/stacks/blazor-azure/.claude/skills/level-2-domains/architecture/standards-architect.md +0 -156
  95. package/stacks/blazor-azure/.claude/skills/level-2-domains/backend/api-designer.md +0 -59
  96. package/stacks/blazor-azure/.claude/skills/level-2-domains/backend/dotnet-senior.md +0 -77
  97. package/stacks/blazor-azure/.claude/skills/level-2-domains/backend/ef-modeler.md +0 -58
  98. package/stacks/blazor-azure/.claude/skills/level-2-domains/backend/hangfire-orchestrator.md +0 -126
  99. package/stacks/blazor-azure/.claude/skills/level-2-domains/backend/ms-agent-expert.md +0 -45
  100. package/stacks/blazor-azure/.claude/skills/level-2-domains/frontend/blazor-builder.md +0 -210
  101. package/stacks/blazor-azure/.claude/skills/level-2-domains/frontend/nextjs-expert.md +0 -154
  102. package/stacks/blazor-azure/.claude/skills/level-2-domains/frontend/ui-ux-designer.md +0 -191
  103. package/stacks/blazor-azure/.claude/skills/level-2-domains/infrastructure/azure-architect.md +0 -142
  104. package/stacks/blazor-azure/.claude/skills/level-2-domains/infrastructure/azure-deploy-specialist.md +0 -699
  105. package/stacks/blazor-azure/.claude/skills/level-2-domains/infrastructure/bicep-architect.md +0 -126
  106. package/stacks/blazor-azure/.claude/skills/level-2-domains/infrastructure/container-specialist.md +0 -131
  107. package/stacks/blazor-azure/.claude/skills/level-2-domains/infrastructure/devops-engineer.md +0 -119
  108. package/stacks/blazor-azure/.claude/skills/level-2-domains/integrations/asaas-financial.md +0 -130
  109. package/stacks/blazor-azure/.claude/skills/level-2-domains/integrations/azure-identity.md +0 -142
  110. package/stacks/blazor-azure/.claude/skills/level-2-domains/integrations/clerk-auth.md +0 -108
  111. package/stacks/blazor-azure/.claude/skills/level-2-domains/integrations/hangfire-orchestrator.md +0 -64
  112. package/stacks/blazor-azure/.claude/skills/level-2-domains/integrations/resend-email.md +0 -119
  113. package/stacks/blazor-azure/.claude/skills/level-2-domains/quality/code-analyzer.md +0 -235
  114. package/stacks/blazor-azure/.claude/skills/level-2-domains/quality/testing-specialist.md +0 -126
  115. package/stacks/blazor-azure/.claude/skills/level-3-technologies/README.md +0 -7
  116. package/stacks/blazor-azure/.claude/skills/level-4-patterns/README.md +0 -7
  117. package/stacks/blazor-azure/.morph/archive/.gitkeep +0 -25
  118. package/stacks/blazor-azure/.morph/features/.gitkeep +0 -25
  119. package/stacks/blazor-azure/.morph/schemas/agent.schema.json +0 -296
  120. package/stacks/blazor-azure/.morph/schemas/tasks.schema.json +0 -220
  121. package/stacks/blazor-azure/.morph/specs/.gitkeep +0 -20
  122. package/stacks/blazor-azure/.morph/test-infra/example.bicep +0 -59
  123. package/stacks/nextjs-supabase/.claude/commands/morph-apply.md +0 -221
  124. package/stacks/nextjs-supabase/.claude/commands/morph-archive.md +0 -79
  125. package/stacks/nextjs-supabase/.claude/commands/morph-deploy.md +0 -529
  126. package/stacks/nextjs-supabase/.claude/commands/morph-infra.md +0 -209
  127. package/stacks/nextjs-supabase/.claude/commands/morph-preflight.md +0 -227
  128. package/stacks/nextjs-supabase/.claude/commands/morph-proposal.md +0 -122
  129. package/stacks/nextjs-supabase/.claude/commands/morph-status.md +0 -86
  130. package/stacks/nextjs-supabase/.claude/commands/morph-troubleshoot.md +0 -122
  131. package/stacks/nextjs-supabase/.claude/settings.local.json +0 -6
  132. package/stacks/nextjs-supabase/.claude/skills/level-2-domains/backend/dotnet-supabase.md +0 -244
  133. package/stacks/nextjs-supabase/.claude/skills/level-2-domains/frontend/nextjs-supabase.md +0 -335
  134. package/stacks/nextjs-supabase/.claude/skills/level-2-domains/infrastructure/easypanel-deployer.md +0 -189
  135. package/stacks/nextjs-supabase/.claude/skills/level-2-domains/integrations/supabase-expert.md +0 -50
  136. /package/docs/{v3.0 → next-generation}/ANALYSIS.md +0 -0
  137. /package/docs/{v3.0 → next-generation}/ARCHITECTURE.md +0 -0
  138. /package/docs/{v3.0 → next-generation}/FEATURES.md +0 -0
  139. /package/docs/{v3.0 → next-generation}/README.md +0 -0
  140. /package/docs/{v3.0 → next-generation}/ROADMAP.md +0 -0
package/bin/morph-spec.js CHANGED
@@ -60,8 +60,44 @@ import searchPatternsProgram from '../src/commands/learning/search-patterns.js';
60
60
  // Utility commands
61
61
  import troubleshootCommand from '../src/commands/utils/troubleshoot.js';
62
62
  import { sessionSummaryCommand } from '../src/commands/utils/session-summary.js';
63
- import migrateStateProgram from '../src/commands/utils/migrate-state.js';
64
- import upgradeProgram from '../src/commands/utils/upgrade.js';
63
+
64
+ // Thread, Analytics, Core Four commands
65
+ import {
66
+ threadsListCommand, threadsStatusCommand, threadsKillCommand,
67
+ threadsAnalyticsCommand, threadsWaitAllCommand, threadsWaitAnyCommand
68
+ } from '../src/commands/threads/threads.js';
69
+ import {
70
+ analyticsFeatureCommand, analyticsContextCommand, analyticsProjectCommand
71
+ } from '../src/commands/analytics/analytics.js';
72
+ import { coreFourCommand } from '../src/commands/context/core-four.js';
73
+
74
+ // Context Optimization commands
75
+ import { mcpOptimizeCommand, mcpListCommand } from '../src/commands/mcp/mcp.js';
76
+ import {
77
+ microAgentCreateCommand, microAgentListCommand, microAgentShowCommand
78
+ } from '../src/commands/agents/micro-agent.js';
79
+ import { contextPrimeCommand } from '../src/commands/context/context-prime.js';
80
+
81
+ // Parallelization commands
82
+ import {
83
+ squadTemplateListCommand, squadTemplateUseCommand, squadTemplateShowCommand
84
+ } from '../src/commands/agents/squad-template.js';
85
+ import {
86
+ threadTemplateListCommand, threadTemplateUseCommand
87
+ } from '../src/commands/threads/thread-template.js';
88
+ import { spawnTeamParallelCommand } from '../src/commands/agents/spawn-team.js';
89
+
90
+ // Fusion commands
91
+ import { agentsFuseCommand, agentsReviewAggregateCommand } from '../src/commands/agents/agents-fuse.js';
92
+
93
+ // Meta-Prompts (HOP) commands
94
+ import { hopRenderCommand, hopListCommand } from '../src/commands/templates/template-render.js';
95
+
96
+ // Trust commands
97
+ import {
98
+ trustStatusCommand, trustSetCommand, trustHistoryCommand,
99
+ trustAutoCalculateCommand, trustClearCommand
100
+ } from '../src/commands/trust/trust.js';
65
101
 
66
102
  // Libraries
67
103
  import { LearningSystem } from '../src/lib/learning/learning-system.js';
@@ -105,6 +141,7 @@ program
105
141
  program
106
142
  .command('doctor')
107
143
  .description('Check MORPH installation health')
144
+ .option('--full', 'Run full health check (lib files, commands, HOPs, standards, agents, state)')
108
145
  .action(doctorCommand);
109
146
 
110
147
  program
@@ -219,7 +256,7 @@ generateCommand
219
256
  .description('Auto-generate recap.md from project data (state, validation, contracts)')
220
257
  .option('--quiet', 'Suppress output')
221
258
  .action(async (feature, options) => {
222
- const { generateRecap } = await import('../src/lib/recap-generator.js');
259
+ const { generateRecap } = await import('../src/lib/generators/recap-generator.js');
223
260
  await generateRecap('.', feature, options);
224
261
  });
225
262
 
@@ -423,6 +460,53 @@ templateCommand
423
460
  .option('-v, --verbose', 'Show detailed validation information')
424
461
  .action(templateValidateCommand);
425
462
 
463
+ // HOP (Higher-Order Prompts) commands
464
+ const hopCommand = program
465
+ .command('hop')
466
+ .description('Higher-Order Prompts — render and manage meta-prompt templates');
467
+
468
+ hopCommand
469
+ .command('list')
470
+ .description('List all available HOP templates')
471
+ .action(hopListCommand);
472
+
473
+ hopCommand
474
+ .command('render <hop-id> [output-path]')
475
+ .description('Render a HOP template with variables')
476
+ .option('--variables <json>', 'Variables JSON string', '{}')
477
+ .option('--dry-run', 'Preview without writing file')
478
+ .action((hopId, outputPath, options) => hopRenderCommand(hopId, outputPath, options.variables, options));
479
+
480
+ // Trust commands
481
+ const trustCommand = program
482
+ .command('trust')
483
+ .description('Trust level management for zero-touch execution');
484
+
485
+ trustCommand
486
+ .command('status [feature]')
487
+ .description('Show trust level and auto-approval status')
488
+ .action(trustStatusCommand);
489
+
490
+ trustCommand
491
+ .command('set <feature> <level> [reason]')
492
+ .description('Manually set trust level (low|medium|high|maximum)')
493
+ .action(trustSetCommand);
494
+
495
+ trustCommand
496
+ .command('history')
497
+ .description('Show trust history for all features')
498
+ .action(trustHistoryCommand);
499
+
500
+ trustCommand
501
+ .command('auto-calculate <feature>')
502
+ .description('Recalculate trust from checkpoint history')
503
+ .action(trustAutoCalculateCommand);
504
+
505
+ trustCommand
506
+ .command('clear <feature>')
507
+ .description('Clear manual trust override (revert to calculated)')
508
+ .action(trustClearCommand);
509
+
426
510
  // Troubleshooting command
427
511
  program
428
512
  .command('troubleshoot <keywords...>')
@@ -467,7 +551,7 @@ program
467
551
  .option('-v, --verbose', 'Show detailed output')
468
552
  .action(rollbackPhaseCommand);
469
553
 
470
- // Approval workflow commands (MORPH-SPEC 3.0)
554
+ // Approval workflow commands
471
555
  program
472
556
  .command('approve <feature> <gate>')
473
557
  .description('Approve a phase gate (design, tasks, uiux, proposal)')
@@ -486,7 +570,7 @@ program
486
570
  .option('--json', 'Output as JSON')
487
571
  .action((feature, options) => approvalStatusCommand(feature, options));
488
572
 
489
- // Agent team spawning (MORPH-SPEC 3.0)
573
+ // Agent team spawning
490
574
  program
491
575
  .command('spawn-team <feature>')
492
576
  .description('Generate agent team configuration for Task tool')
@@ -494,13 +578,204 @@ program
494
578
  .option('--verbose', 'Show detailed team configuration')
495
579
  .action((feature, options) => spawnTeamCommand(feature, options));
496
580
 
497
- // Pattern learning system (MORPH-SPEC 3.0) - Add as subcommands
581
+ // Pattern learning system - Add as subcommands
498
582
  program.addCommand(capturePatternProgram);
499
583
  program.addCommand(searchPatternsProgram);
500
584
 
501
- // Migration and upgrade commands (MORPH-SPEC 3.0) - Add as subcommands
502
- program.addCommand(migrateStateProgram);
503
- program.addCommand(upgradeProgram);
585
+ // ─────────────────────────────────────────────────────────────────────────────
586
+ // Thread Management
587
+ // ─────────────────────────────────────────────────────────────────────────────
588
+ const threadsCommand = program
589
+ .command('threads')
590
+ .description('Thread lifecycle management');
591
+
592
+ threadsCommand
593
+ .command('list')
594
+ .description('List threads (optionally filtered by feature/status/type)')
595
+ .option('--feature <feature>', 'Filter by feature name')
596
+ .option('--status <status>', 'Filter by status (pending|running|completed|failed|killed)')
597
+ .option('--type <type>', 'Filter by type (base|parallel|fusion|long-running|zero-touch)')
598
+ .action((options) => threadsListCommand(options));
599
+
600
+ threadsCommand
601
+ .command('status <id>')
602
+ .description('Show detailed status of a thread')
603
+ .action((id) => threadsStatusCommand(id));
604
+
605
+ threadsCommand
606
+ .command('kill <id>')
607
+ .description('Terminate a running thread')
608
+ .action((id) => threadsKillCommand(id));
609
+
610
+ threadsCommand
611
+ .command('analytics')
612
+ .description('Show thread analytics dashboard for a feature')
613
+ .option('--feature <feature>', 'Feature name (required)')
614
+ .action((options) => threadsAnalyticsCommand(options));
615
+
616
+ threadsCommand
617
+ .command('wait-all <feature>')
618
+ .description('Block until all threads for a feature complete')
619
+ .option('--timeout <minutes>', 'Timeout in minutes (default: 60)', '60')
620
+ .action((feature, options) => threadsWaitAllCommand(feature, options));
621
+
622
+ threadsCommand
623
+ .command('wait-any <feature>')
624
+ .description('Block until any thread for a feature completes')
625
+ .option('--timeout <minutes>', 'Timeout in minutes (default: 60)', '60')
626
+ .action((feature, options) => threadsWaitAnyCommand(feature, options));
627
+
628
+ // ─────────────────────────────────────────────────────────────────────────────
629
+ // Analytics
630
+ // ─────────────────────────────────────────────────────────────────────────────
631
+ const analyticsCommand = program
632
+ .command('analytics')
633
+ .description('Metrics and analytics dashboards');
634
+
635
+ analyticsCommand
636
+ .command('feature <name>')
637
+ .description('Show thread analytics dashboard for a feature')
638
+ .action((name, options) => analyticsFeatureCommand(name, options));
639
+
640
+ analyticsCommand
641
+ .command('context <name>')
642
+ .description('Show context token usage and optimization opportunities')
643
+ .action((name, options) => analyticsContextCommand(name, options));
644
+
645
+ analyticsCommand
646
+ .command('project')
647
+ .description('Show project-wide analytics dashboard (30-day summary)')
648
+ .option('--period <days>', 'Period in days (default: 30)', '30')
649
+ .action((options) => analyticsProjectCommand(options));
650
+
651
+ // ─────────────────────────────────────────────────────────────────────────────
652
+ // Core Four
653
+ // ─────────────────────────────────────────────────────────────────────────────
654
+ program
655
+ .command('core-four <feature>')
656
+ .description('Show Core Four dashboard: Context/Model/Prompt/Tools')
657
+ .option('--json', 'Output as JSON')
658
+ .action((feature, options) => coreFourCommand(feature, options));
659
+
660
+ // ─────────────────────────────────────────────────────────────────────────────
661
+ // MCP Optimizer
662
+ // ─────────────────────────────────────────────────────────────────────────────
663
+ const mcpCommand = program
664
+ .command('mcp')
665
+ .description('MCP server analysis and optimization');
666
+
667
+ mcpCommand
668
+ .command('optimize')
669
+ .description('Analyze MCP servers and suggest optimizations')
670
+ .action((options) => mcpOptimizeCommand(options));
671
+
672
+ mcpCommand
673
+ .command('list')
674
+ .description('List configured MCP servers with usage stats')
675
+ .action((options) => mcpListCommand(options));
676
+
677
+ // ─────────────────────────────────────────────────────────────────────────────
678
+ // Micro Agents
679
+ // ─────────────────────────────────────────────────────────────────────────────
680
+ const microAgentCommand = program
681
+ .command('micro-agent')
682
+ .description('Create and manage ultra-specialized micro-agents');
683
+
684
+ microAgentCommand
685
+ .command('create <name>')
686
+ .description('Create a new micro-agent')
687
+ .option('--base-agent <agent>', 'Base agent ID to specialize from')
688
+ .option('--mission <mission>', 'Single focused mission for this agent')
689
+ .option('--standards <files>', 'Comma-separated standards files to load (1-3 max)')
690
+ .option('--tools <tools>', 'Comma-separated tools to allow (default: Read,Write,Edit)')
691
+ .action((name, options) => microAgentCreateCommand(name, options));
692
+
693
+ microAgentCommand
694
+ .command('list')
695
+ .description('List all micro-agents')
696
+ .action((options) => microAgentListCommand(options));
697
+
698
+ microAgentCommand
699
+ .command('show <name>')
700
+ .description('Show micro-agent details')
701
+ .option('--show-prompt', 'Show the generated system prompt')
702
+ .action((name, options) => microAgentShowCommand(name, options));
703
+
704
+ // ─────────────────────────────────────────────────────────────────────────────
705
+ // Context Prime
706
+ // ─────────────────────────────────────────────────────────────────────────────
707
+ program
708
+ .command('prime [type]')
709
+ .description('Output context priming file (feature|bug|refactor|design|infra)')
710
+ .option('--json', 'Output as JSON')
711
+ .action((type, options) => contextPrimeCommand(type, options));
712
+
713
+ // ─────────────────────────────────────────────────────────────────────────────
714
+ // Fusion (F-Thread)
715
+ // ─────────────────────────────────────────────────────────────────────────────
716
+ const agentsFuseCmd = program
717
+ .command('agents-fuse')
718
+ .description('F-Thread fusion execution: run N agents, aggregate best result');
719
+
720
+ agentsFuseCmd
721
+ .command('run')
722
+ .description('Run fusion: spawn N agents with same prompt, aggregate results')
723
+ .option('--prompt <prompt>', 'Prompt/mission for all fusion agents (required)')
724
+ .option('--count <n>', 'Number of agents to run (default: 3)', '3')
725
+ .option('--strategy <strategy>', 'Aggregation strategy: best-of-n | consensus | manual-select', 'best-of-n')
726
+ .option('--feature <feature>', 'Feature name for tracking')
727
+ .option('--agents <list>', 'Comma-separated agent IDs to use')
728
+ .option('--json', 'Output as JSON')
729
+ .action((options) => agentsFuseCommand(options));
730
+
731
+ agentsFuseCmd
732
+ .command('aggregate-reviews <feature>')
733
+ .description('Aggregate review results from N agents')
734
+ .option('--agents <list>', 'Comma-separated agent IDs (required)')
735
+ .option('--strategy <strategy>', 'Aggregation strategy', 'best-of-n')
736
+ .action((feature, options) => agentsReviewAggregateCommand(feature, options));
737
+
738
+ // ─────────────────────────────────────────────────────────────────────────────
739
+ // Squad Templates
740
+ // ─────────────────────────────────────────────────────────────────────────────
741
+ const squadTemplateCmd = program
742
+ .command('squad-template')
743
+ .description('Squad template management for parallel execution');
744
+
745
+ squadTemplateCmd
746
+ .command('list')
747
+ .description('List available squad templates')
748
+ .action((options) => squadTemplateListCommand(options));
749
+
750
+ squadTemplateCmd
751
+ .command('use <template-id>')
752
+ .description('Configure a feature to use a squad template')
753
+ .option('--feature <feature>', 'Feature name (required)')
754
+ .action((id, options) => squadTemplateUseCommand(id, options));
755
+
756
+ squadTemplateCmd
757
+ .command('show <template-id>')
758
+ .description('Show squad template details')
759
+ .option('--json', 'Output as JSON')
760
+ .action((id, options) => squadTemplateShowCommand(id, options));
761
+
762
+ // ─────────────────────────────────────────────────────────────────────────────
763
+ // Commands — Thread Templates
764
+ // ─────────────────────────────────────────────────────────────────────────────
765
+ const threadTemplateCmd = program
766
+ .command('thread-template')
767
+ .description('Thread type management');
768
+
769
+ threadTemplateCmd
770
+ .command('list')
771
+ .description('List available thread types (B/P/F/L/Z-Thread)')
772
+ .action((options) => threadTemplateListCommand(options));
773
+
774
+ threadTemplateCmd
775
+ .command('use <type>')
776
+ .description('Configure thread type for a feature')
777
+ .option('--feature <feature>', 'Feature name (required)')
778
+ .action((type, options) => threadTemplateUseCommand(type, options));
504
779
 
505
780
  // Wire global --stack flag to stack-resolver before any command executes
506
781
  program.hook('preAction', () => {
@@ -8,6 +8,7 @@
8
8
  */
9
9
 
10
10
  const fs = require('fs').promises;
11
+ const fsSync = require('fs');
11
12
  const path = require('path');
12
13
 
13
14
  // Simple ANSI color helpers (chalk v5 is ESM-only, can't require in CJS)
@@ -22,6 +23,68 @@ const chalk = {
22
23
  bold: (s) => `\x1b[1m${s}\x1b[0m`,
23
24
  };
24
25
 
26
+ // ============================================================================
27
+ // v3 Schema Helpers
28
+ // ============================================================================
29
+
30
+ /**
31
+ * Parse tasks.md to extract task stubs for v3 state format.
32
+ * Looks for headings like: ### T001 — Task title
33
+ */
34
+ async function parseTasksMd(featureName) {
35
+ const tasksPath = path.join(process.cwd(), `.morph/project/outputs/${featureName}/tasks.md`);
36
+ let content = '';
37
+ try {
38
+ content = await fs.readFile(tasksPath, 'utf-8');
39
+ } catch {
40
+ return [];
41
+ }
42
+
43
+ const tasks = [];
44
+ const headingRe = /^###\s+(T\d+)\s+[—–-]\s+(.+)$/gm;
45
+ let match;
46
+ while ((match = headingRe.exec(content)) !== null) {
47
+ tasks.push({
48
+ id: match[1],
49
+ title: match[2].trim(),
50
+ status: 'pending',
51
+ dependencies: [],
52
+ files: [],
53
+ checkpoint: null
54
+ });
55
+ }
56
+ return tasks;
57
+ }
58
+
59
+ /**
60
+ * Ensure feature.taskList exists (array of individual task objects).
61
+ * In v3 state, feature.tasks is a counter object {total, completed, ...}.
62
+ * Individual task objects live in feature.taskList.
63
+ */
64
+ async function ensureTaskList(feature, featureName) {
65
+ if (Array.isArray(feature.tasks)) {
66
+ // v2 format: tasks IS the array
67
+ return feature.tasks;
68
+ }
69
+ // v3 format: use taskList or build from tasks.md
70
+ if (!feature.taskList || feature.taskList.length === 0) {
71
+ feature.taskList = await parseTasksMd(featureName);
72
+ }
73
+ return feature.taskList;
74
+ }
75
+
76
+ /**
77
+ * After modifying taskList, sync counts back to feature.tasks counter.
78
+ */
79
+ function syncCounters(feature) {
80
+ if (Array.isArray(feature.tasks)) return; // v2, nothing to sync
81
+ const list = feature.taskList || [];
82
+ feature.tasks.completed = list.filter(t => t.status === 'completed').length;
83
+ feature.tasks.inProgress = list.filter(t => t.status === 'in_progress').length;
84
+ feature.tasks.pending = list.filter(t => t.status === 'pending').length;
85
+ // Don't touch feature.tasks.total — it is the authoritative count
86
+ }
87
+
25
88
  class TaskManager {
26
89
  constructor(statePath = '.morph/state.json') {
27
90
  this.statePath = statePath;
@@ -46,7 +109,12 @@ class TaskManager {
46
109
  * Save state.json
47
110
  */
48
111
  async saveState(state) {
49
- state.project.updatedAt = new Date().toISOString();
112
+ // v3 state uses metadata.lastUpdated, v2 used project.updatedAt
113
+ if (state.metadata) {
114
+ state.metadata.lastUpdated = new Date().toISOString();
115
+ } else if (state.project) {
116
+ state.project.updatedAt = new Date().toISOString();
117
+ }
50
118
  await fs.writeFile(this.statePath, JSON.stringify(state, null, 2), 'utf-8');
51
119
  }
52
120
 
@@ -65,11 +133,12 @@ class TaskManager {
65
133
  throw new Error(`Feature '${featureName}' not found in state.json`);
66
134
  }
67
135
 
136
+ const taskList = await ensureTaskList(feature, featureName);
68
137
  const results = [];
69
138
  const tasksToComplete = [];
70
139
 
71
140
  for (const taskId of taskIds) {
72
- const task = feature.tasks.find(t => t.id === taskId);
141
+ const task = taskList.find(t => t.id === taskId);
73
142
 
74
143
  if (!task) {
75
144
  console.error(chalk.red(`❌ Task ${taskId} not found`));
@@ -82,7 +151,7 @@ class TaskManager {
82
151
  }
83
152
 
84
153
  // Validate dependencies
85
- const missingDeps = this.checkDependencies(task, feature.tasks);
154
+ const missingDeps = this.checkDependencies(task, taskList);
86
155
  if (missingDeps.length > 0) {
87
156
  console.error(chalk.red(`❌ Cannot complete ${taskId}: missing dependencies: ${missingDeps.join(', ')}`));
88
157
  continue;
@@ -118,11 +187,12 @@ class TaskManager {
118
187
  }
119
188
  }
120
189
 
121
- // Update progress
122
- feature.progress = this.calculateProgress(feature.tasks);
190
+ // Sync v3 counters then compute progress
191
+ syncCounters(feature);
192
+ feature.progress = this.calculateProgress(taskList);
123
193
 
124
194
  // Auto-checkpoint every 3 tasks
125
- const recentCompleted = this.getRecentCompleted(feature.tasks, 3);
195
+ const recentCompleted = this.getRecentCompleted(taskList, 3);
126
196
  if (recentCompleted.length === 3) {
127
197
  const lastCheckpoint = feature.checkpoints[feature.checkpoints.length - 1];
128
198
  const shouldAutoCheckpoint = !lastCheckpoint ||
@@ -138,6 +208,21 @@ class TaskManager {
138
208
  // Save state
139
209
  await this.saveState(state);
140
210
 
211
+ // Run TaskCompleted agent-teams hook for each completed task (non-blocking)
212
+ for (const task of results) {
213
+ try {
214
+ const { executeHook, formatHookResults } = await import('../src/lib/hooks/hook-executor.js');
215
+ const hookResult = await executeHook(process.cwd(), featureName, 'TaskCompleted', {
216
+ taskId: task.id
217
+ });
218
+ if (!hookResult.passed && hookResult.errors.length > 0) {
219
+ console.log(formatHookResults(hookResult, 'TaskCompleted'));
220
+ }
221
+ } catch {
222
+ // Hook executor unavailable — non-blocking
223
+ }
224
+ }
225
+
141
226
  // Auto-generate metadata.json (for quick LLM access)
142
227
  await this.generateMetadata(featureName, feature);
143
228
 
@@ -145,7 +230,7 @@ class TaskManager {
145
230
  this.displayProgress(feature);
146
231
 
147
232
  // Suggest next task
148
- const nextTask = this.getNextTask(feature.tasks);
233
+ const nextTask = this.getNextTask(taskList);
149
234
  if (nextTask) {
150
235
  console.log(chalk.cyan(`\n⏭️ Next: ${nextTask.id} - ${nextTask.title}`));
151
236
  if (nextTask.dependencies && nextTask.dependencies.length > 0) {
@@ -167,7 +252,7 @@ class TaskManager {
167
252
  try {
168
253
  console.log(chalk.cyan('\n🔍 Running code validation...'));
169
254
 
170
- const { runValidation, formatValidationResults } = await import('../src/lib/validation-runner.js');
255
+ const { runValidation, formatValidationResults } = await import('../src/lib/validators/validation-runner.js');
171
256
  const result = await runValidation('.', featureName, { verbose: true });
172
257
 
173
258
  formatValidationResults(result);
@@ -243,7 +328,7 @@ class TaskManager {
243
328
 
244
329
  // Run checkpoint hooks (new enhanced validation system)
245
330
  try {
246
- const { runCheckpointHooks, shouldRunCheckpoint } = await import('../src/lib/checkpoint-hooks.js');
331
+ const { runCheckpointHooks, shouldRunCheckpoint } = await import('../src/lib/checkpoints/checkpoint-hooks.js');
247
332
 
248
333
  if (shouldRunCheckpoint(tasksCompleted, 3)) {
249
334
  checkpointResult = await runCheckpointHooks(featureName, checkpointNum);
@@ -268,7 +353,7 @@ class TaskManager {
268
353
  // Fallback to old validation if checkpoint-hooks not available
269
354
  console.log(chalk.yellow('⚠️ Checkpoint hooks not available, using legacy validation'));
270
355
  try {
271
- const { runValidation } = await import('../src/lib/validation-runner.js');
356
+ const { runValidation } = await import('../src/lib/validators/validation-runner.js');
272
357
  const result = await runValidation('.', featureName, { verbose: false });
273
358
  validationNote = result.passed
274
359
  ? ' | Validation: PASSED'
@@ -333,7 +418,7 @@ class TaskManager {
333
418
  return;
334
419
  }
335
420
 
336
- const { extractFeatureMetadata } = await import('../src/lib/metadata-extractor.js');
421
+ const { extractFeatureMetadata } = await import('../src/lib/generators/metadata-extractor.js');
337
422
  const metadata = extractFeatureMetadata(feature);
338
423
 
339
424
  const outputPath = path.join(
@@ -410,7 +495,8 @@ class TaskManager {
410
495
  throw new Error(`Feature '${featureName}' not found`);
411
496
  }
412
497
 
413
- const task = feature.tasks.find(t => t.id === taskId);
498
+ const taskList = await ensureTaskList(feature, featureName);
499
+ const task = taskList.find(t => t.id === taskId);
414
500
 
415
501
  if (!task) {
416
502
  throw new Error(`Task ${taskId} not found`);
@@ -422,13 +508,14 @@ class TaskManager {
422
508
  }
423
509
 
424
510
  // Validate dependencies
425
- const missingDeps = this.checkDependencies(task, feature.tasks);
511
+ const missingDeps = this.checkDependencies(task, taskList);
426
512
  if (missingDeps.length > 0) {
427
513
  throw new Error(`Cannot start ${taskId}: missing dependencies: ${missingDeps.join(', ')}`);
428
514
  }
429
515
 
430
516
  task.status = 'in_progress';
431
517
  task.startedAt = new Date().toISOString();
518
+ syncCounters(feature);
432
519
 
433
520
  await this.saveState(state);
434
521
 
@@ -446,7 +533,8 @@ class TaskManager {
446
533
  throw new Error(`Feature '${featureName}' not found`);
447
534
  }
448
535
 
449
- const nextTask = this.getNextTask(feature.tasks);
536
+ const taskList = await ensureTaskList(feature, featureName);
537
+ const nextTask = this.getNextTask(taskList);
450
538
 
451
539
  if (nextTask) {
452
540
  console.log(chalk.cyan(`\n⏭️ Next task: ${nextTask.id} - ${nextTask.title}`));
package/bin/validate.js CHANGED
@@ -17,9 +17,9 @@
17
17
  */
18
18
 
19
19
  import chalk from 'chalk';
20
- import { validatePackages } from '../src/lib/validators/package-validator.js';
21
- import { validateArchitecture } from '../src/lib/validators/architecture-validator.js';
22
- import { validateContrast } from '../src/lib/validators/ui-contrast-validator.js';
20
+ import { validatePackages } from '../src/lib/validators/packages/package-validator.js';
21
+ import { validateArchitecture } from '../src/lib/validators/architecture/architecture-validator.js';
22
+ import { validateContrast } from '../src/lib/validators/ui/ui-contrast-validator.js';
23
23
  import { LearningSystem } from '../src/lib/learning/learning-system.js';
24
24
 
25
25
  const VALIDATORS = {
@@ -51,7 +51,7 @@ const VALIDATORS = {
51
51
  async function validateSpecVsTasks(projectPath, options = {}) {
52
52
  const path = await import('path');
53
53
  const fs = await import('fs');
54
- const { loadState } = await import('../src/lib/state-manager.js');
54
+ const { loadState } = await import('../src/core/state/state-manager.js');
55
55
 
56
56
  const results = [];
57
57
  let errors = 0;
@@ -485,7 +485,7 @@
485
485
  ```json
486
486
  {
487
487
  "squadConfigs": {
488
- "full-stack-v3": {
488
+ "full-stack": {
489
489
  "parallel": true,
490
490
  "agents": [
491
491
  "dotnet-senior",