musubi-sdd 3.6.0 → 3.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -71,7 +71,15 @@ musubi init --windsurf # Windsurf IDE
71
71
 
72
72
  ---
73
73
 
74
- ## šŸ“Š What's New in v3.6.0
74
+ ## šŸ“Š What's New in v3.6.1
75
+
76
+ - šŸš€ **ProactivePathOptimizer** - Continuous path optimization even during successful execution
77
+ - šŸŽÆ **GoalProgressTracker** - Real-time goal progress monitoring with milestone management
78
+ - šŸ”„ **AdaptiveGoalModifier** - Dynamic goal adjustment based on execution context
79
+ - šŸ› ļø **New CLI Commands** - `replan`, `goal`, `optimize`, `path` subcommands for orchestration
80
+ - šŸ“š **Updated Agent Templates** - All 7 platforms with replanning command documentation
81
+
82
+ ### Previous (v3.6.0)
75
83
 
76
84
  - 🧠 **Dynamic Replanning Engine** - AI agents can now dynamically adjust plans when tasks fail
77
85
  - šŸ”Œ **LLM Provider Abstraction** - Multi-provider support (Copilot, Anthropic, OpenAI)
@@ -102,7 +110,7 @@ musubi init --windsurf # Windsurf IDE
102
110
  ## Features
103
111
 
104
112
  - šŸ¤– **Multi-Agent Support** - Works with 7 AI coding agents (Claude Code, GitHub Copilot, Cursor, Gemini CLI, Codex CLI, Qwen Code, Windsurf)
105
- - 🧠 **Dynamic Replanning** - AI agents dynamically adjust plans on failure with LLM-powered alternatives (NEW in v3.6.0)
113
+ - 🧠 **Dynamic Replanning** - AI agents dynamically adjust plans on failure with LLM-powered alternatives (v3.6.0+)
106
114
  - šŸ”Œ **MCP Server Integration** - CodeGraphMCPServer for advanced code analysis (v2.0.0)
107
115
  - šŸ“„ **Flexible Command Formats** - Supports Markdown, TOML, and AGENTS.md formats
108
116
  - šŸŽÆ **25 Specialized Agents (All Platforms)** - Orchestrator, Steering, Requirements, Architecture, Development, Quality, Security, Infrastructure
@@ -26,6 +26,15 @@ const {
26
26
  Priority
27
27
  } = require('../src/orchestration');
28
28
 
29
+ const {
30
+ ReplanningEngine,
31
+ GoalProgressTracker,
32
+ Goal,
33
+ AdaptiveGoalModifier,
34
+ ProactivePathOptimizer,
35
+ ModificationReason
36
+ } = require('../src/orchestration/replanning');
37
+
29
38
  const program = new Command();
30
39
 
31
40
  program
@@ -406,6 +415,306 @@ program
406
415
  }
407
416
  });
408
417
 
418
+ // ============================================================================
419
+ // Replanning Commands
420
+ // ============================================================================
421
+
422
+ // Goal tracking command
423
+ program
424
+ .command('goal')
425
+ .description('Manage goals for goal-driven replanning')
426
+ .argument('<action>', 'Action: list, add, update, remove, status')
427
+ .option('-n, --name <name>', 'Goal name')
428
+ .option('-d, --description <desc>', 'Goal description')
429
+ .option('-p, --priority <priority>', 'Priority (1-10)', '5')
430
+ .option('--deadline <date>', 'Deadline (ISO date)')
431
+ .option('--progress <progress>', 'Progress (0-1)')
432
+ .option('--id <id>', 'Goal ID')
433
+ .option('-f, --format <type>', 'Output format (text|json)', 'text')
434
+ .action(async (action, options) => {
435
+ try {
436
+ const tracker = new GoalProgressTracker();
437
+
438
+ switch (action) {
439
+ case 'add': {
440
+ if (!options.name) {
441
+ console.error(chalk.red('Error: --name is required'));
442
+ process.exit(1);
443
+ }
444
+
445
+ const goal = tracker.registerGoal({
446
+ name: options.name,
447
+ description: options.description || '',
448
+ priority: parseInt(options.priority, 10),
449
+ deadline: options.deadline ? new Date(options.deadline).getTime() : null
450
+ });
451
+
452
+ console.log(chalk.green(`\nāœ“ Goal created: ${goal.id}\n`));
453
+ console.log(chalk.cyan(` Name: ${goal.name}`));
454
+ console.log(chalk.dim(` Priority: ${goal.priority}`));
455
+ if (goal.deadline) {
456
+ console.log(chalk.dim(` Deadline: ${new Date(goal.deadline).toISOString()}`));
457
+ }
458
+ console.log('');
459
+ break;
460
+ }
461
+
462
+ case 'list': {
463
+ console.log(chalk.bold('\nšŸŽÆ Registered Goals\n'));
464
+
465
+ const goals = Array.from(tracker.goals.values());
466
+
467
+ if (options.format === 'json') {
468
+ console.log(JSON.stringify(goals.map(g => g.toJSON()), null, 2));
469
+ } else if (goals.length === 0) {
470
+ console.log(chalk.yellow(' No goals registered'));
471
+ } else {
472
+ for (const goal of goals) {
473
+ const statusIcon = goal.isComplete() ? chalk.green('āœ“') :
474
+ goal.status === 'in-progress' ? chalk.yellow('◐') :
475
+ chalk.dim('ā—‹');
476
+ console.log(` ${statusIcon} ${chalk.cyan(goal.name)} (${goal.id})`);
477
+ console.log(chalk.dim(` Progress: ${(goal.progress * 100).toFixed(0)}% | Priority: ${goal.priority} | Status: ${goal.status}`));
478
+ }
479
+ }
480
+ console.log('');
481
+ break;
482
+ }
483
+
484
+ case 'update': {
485
+ if (!options.id) {
486
+ console.error(chalk.red('Error: --id is required'));
487
+ process.exit(1);
488
+ }
489
+
490
+ if (options.progress) {
491
+ tracker.updateProgress(options.id, parseFloat(options.progress));
492
+ console.log(chalk.green(`\nāœ“ Goal ${options.id} updated to ${(parseFloat(options.progress) * 100).toFixed(0)}% progress\n`));
493
+ }
494
+ break;
495
+ }
496
+
497
+ case 'status': {
498
+ console.log(chalk.bold('\nšŸ“Š Goal Tracking Status\n'));
499
+ console.log(` Goals: ${tracker.goals.size}`);
500
+ console.log(` Tracking: ${tracker.isTracking ? chalk.green('Active') : chalk.dim('Inactive')}`);
501
+ console.log('');
502
+ break;
503
+ }
504
+
505
+ default:
506
+ console.error(chalk.red(`Unknown action: ${action}`));
507
+ console.log('Available actions: list, add, update, remove, status');
508
+ process.exit(1);
509
+ }
510
+
511
+ } catch (error) {
512
+ console.error(chalk.red(`\nāœ— Error: ${error.message}\n`));
513
+ process.exit(1);
514
+ }
515
+ });
516
+
517
+ // Replan command
518
+ program
519
+ .command('replan')
520
+ .description('Trigger replanning analysis')
521
+ .option('-p, --plan <json>', 'Current plan as JSON')
522
+ .option('-f, --plan-file <file>', 'Plan file path')
523
+ .option('--trigger <type>', 'Trigger type (failure|timeout|manual|resource)', 'manual')
524
+ .option('--context <json>', 'Execution context as JSON')
525
+ .option('-o, --output <file>', 'Output file for alternatives')
526
+ .option('--format <type>', 'Output format (text|json)', 'text')
527
+ .action(async (options) => {
528
+ try {
529
+ console.log(chalk.bold('\nšŸ”„ Replanning Analysis\n'));
530
+
531
+ let plan;
532
+ if (options.planFile) {
533
+ plan = await fs.readJson(options.planFile);
534
+ } else if (options.plan) {
535
+ plan = JSON.parse(options.plan);
536
+ } else {
537
+ // Demo plan
538
+ plan = {
539
+ id: 'demo-plan',
540
+ name: 'Demo Plan',
541
+ tasks: [
542
+ { id: 't1', skill: 'requirements-analyst', name: 'Analyze Requirements' },
543
+ { id: 't2', skill: 'system-architect', name: 'Design Architecture', dependencies: ['t1'] },
544
+ { id: 't3', skill: 'code-generator', name: 'Generate Code', dependencies: ['t2'] }
545
+ ]
546
+ };
547
+ console.log(chalk.dim(' Using demo plan (provide --plan or --plan-file for custom plan)\n'));
548
+ }
549
+
550
+ const engine = new ReplanningEngine();
551
+ const normalized = engine.normalizePlan(plan);
552
+
553
+ console.log(chalk.bold(' Plan:'));
554
+ console.log(` ID: ${chalk.cyan(normalized.id)}`);
555
+ console.log(` Tasks: ${normalized.tasks.length}`);
556
+
557
+ // Show tasks
558
+ for (const task of normalized.tasks) {
559
+ console.log(chalk.dim(` - ${task.name || task.skill} (${task.id})`));
560
+ }
561
+
562
+ console.log(chalk.bold('\n Analysis:'));
563
+ console.log(` Trigger: ${chalk.yellow(options.trigger)}`);
564
+ console.log(` Status: ${chalk.green('Ready for replanning')}`);
565
+
566
+ if (options.output) {
567
+ await fs.writeJson(options.output, {
568
+ plan: normalized,
569
+ trigger: options.trigger,
570
+ timestamp: new Date().toISOString()
571
+ }, { spaces: 2 });
572
+ console.log(chalk.dim(`\n Output written to: ${options.output}`));
573
+ }
574
+
575
+ console.log('');
576
+
577
+ } catch (error) {
578
+ console.error(chalk.red(`\nāœ— Error: ${error.message}\n`));
579
+ process.exit(1);
580
+ }
581
+ });
582
+
583
+ // Goal modification command
584
+ program
585
+ .command('modify-goal')
586
+ .description('Adaptively modify a goal based on constraints')
587
+ .option('--id <id>', 'Goal ID to modify')
588
+ .option('--reason <reason>', 'Modification reason (time|resource|dependency|priority)', 'time')
589
+ .option('--approve', 'Auto-approve modification')
590
+ .option('-f, --format <type>', 'Output format (text|json)', 'text')
591
+ .action(async (options) => {
592
+ try {
593
+ console.log(chalk.bold('\nšŸ”§ Adaptive Goal Modification\n'));
594
+
595
+ const modifier = new AdaptiveGoalModifier({ requireApproval: !options.approve });
596
+
597
+ // Demo goal if no ID provided
598
+ const goal = modifier.registerGoal({
599
+ id: options.id || 'demo-goal',
600
+ name: 'Demo Goal',
601
+ priority: 'high',
602
+ targetDate: new Date(Date.now() + 86400000 * 7).toISOString(),
603
+ deliverables: [
604
+ { id: 'd1', name: 'Core Feature', priority: 'critical' },
605
+ { id: 'd2', name: 'Documentation', priority: 'normal' }
606
+ ]
607
+ });
608
+
609
+ const reasonMap = {
610
+ time: ModificationReason.TIME_CONSTRAINT,
611
+ resource: ModificationReason.RESOURCE_CONSTRAINT,
612
+ dependency: ModificationReason.DEPENDENCY_FAILURE,
613
+ priority: ModificationReason.PRIORITY_SHIFT
614
+ };
615
+
616
+ const trigger = { reason: reasonMap[options.reason] || ModificationReason.TIME_CONSTRAINT };
617
+
618
+ console.log(chalk.bold(' Goal:'));
619
+ console.log(` ID: ${chalk.cyan(goal.id)}`);
620
+ console.log(` Name: ${goal.name}`);
621
+ console.log(` Priority: ${goal.priority}`);
622
+
623
+ console.log(chalk.bold('\n Trigger:'));
624
+ console.log(` Reason: ${chalk.yellow(trigger.reason)}`);
625
+
626
+ const result = await modifier.triggerModification(goal.id, trigger);
627
+
628
+ console.log(chalk.bold('\n Result:'));
629
+ console.log(` Status: ${result.status === 'applied' ? chalk.green(result.status) : chalk.yellow(result.status)}`);
630
+
631
+ if (result.modification) {
632
+ console.log(` Strategy: ${chalk.cyan(result.modification.strategy.type)}`);
633
+ console.log(` Confidence: ${(result.modification.confidence * 100).toFixed(0)}%`);
634
+
635
+ if (result.modification.impact) {
636
+ console.log(` Impact Score: ${(result.modification.impact.totalScore * 100).toFixed(0)}%`);
637
+ console.log(` Risk Level: ${result.modification.impact.riskLevel}`);
638
+ }
639
+ }
640
+
641
+ if (options.format === 'json') {
642
+ console.log('\n' + JSON.stringify(result, null, 2));
643
+ }
644
+
645
+ console.log('');
646
+
647
+ } catch (error) {
648
+ console.error(chalk.red(`\nāœ— Error: ${error.message}\n`));
649
+ process.exit(1);
650
+ }
651
+ });
652
+
653
+ // Path optimization command
654
+ program
655
+ .command('optimize-path')
656
+ .description('Analyze and optimize execution path')
657
+ .option('-p, --path <json>', 'Execution path as JSON')
658
+ .option('-f, --path-file <file>', 'Path file')
659
+ .option('--format <type>', 'Output format (text|json)', 'text')
660
+ .action(async (options) => {
661
+ try {
662
+ console.log(chalk.bold('\n⚔ Path Optimization Analysis\n'));
663
+
664
+ const optimizer = new ProactivePathOptimizer(null);
665
+
666
+ let pathData;
667
+ if (options.pathFile) {
668
+ pathData = await fs.readJson(options.pathFile);
669
+ } else if (options.path) {
670
+ pathData = JSON.parse(options.path);
671
+ } else {
672
+ // Demo path
673
+ pathData = {
674
+ pending: [
675
+ { id: 't1', name: 'Task 1', estimatedDuration: 10000, dependencies: [] },
676
+ { id: 't2', name: 'Task 2', estimatedDuration: 5000, dependencies: [] },
677
+ { id: 't3', name: 'Task 3', estimatedDuration: 8000, dependencies: ['t1'] },
678
+ { id: 't4', name: 'Task 4', estimatedDuration: 3000, dependencies: ['t2', 't3'] }
679
+ ]
680
+ };
681
+ console.log(chalk.dim(' Using demo path (provide --path or --path-file for custom)\n'));
682
+ }
683
+
684
+ const metrics = optimizer.calculatePathMetrics(pathData);
685
+
686
+ console.log(chalk.bold(' Path Metrics:'));
687
+ console.log(` Estimated Time: ${chalk.cyan(metrics.estimatedTime + 'ms')}`);
688
+ console.log(` Parallelization Factor: ${(metrics.parallelizationFactor * 100).toFixed(0)}%`);
689
+ console.log(` Risk Score: ${metrics.riskScore.toFixed(2)}`);
690
+ console.log(` Overall Score: ${metrics.getScore().toFixed(2)}`);
691
+
692
+ console.log(chalk.bold('\n Tasks:'));
693
+ for (const task of pathData.pending) {
694
+ const deps = task.dependencies?.length ? ` -> [${task.dependencies.join(', ')}]` : '';
695
+ console.log(chalk.dim(` - ${task.name} (${task.id})${deps}`));
696
+ }
697
+
698
+ if (options.format === 'json') {
699
+ console.log('\n' + JSON.stringify({
700
+ path: pathData,
701
+ metrics: {
702
+ estimatedTime: metrics.estimatedTime,
703
+ parallelizationFactor: metrics.parallelizationFactor,
704
+ riskScore: metrics.riskScore,
705
+ score: metrics.getScore()
706
+ }
707
+ }, null, 2));
708
+ }
709
+
710
+ console.log('');
711
+
712
+ } catch (error) {
713
+ console.error(chalk.red(`\nāœ— Error: ${error.message}\n`));
714
+ process.exit(1);
715
+ }
716
+ });
717
+
409
718
  // Status command
410
719
  program
411
720
  .command('status')
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "musubi-sdd",
3
- "version": "3.6.0",
3
+ "version": "3.6.1",
4
4
  "description": "Ultimate Specification Driven Development Tool with 27 Agents for 7 AI Coding Platforms + MCP Integration (Claude Code, GitHub Copilot, Cursor, Gemini CLI, Windsurf, Codex, Qwen Code)",
5
5
  "main": "src/index.js",
6
6
  "bin": {