@paths.design/caws-cli 3.5.0 → 4.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. package/dist/budget-derivation.d.ts +41 -2
  2. package/dist/budget-derivation.d.ts.map +1 -1
  3. package/dist/budget-derivation.js +417 -30
  4. package/dist/commands/archive.d.ts +50 -0
  5. package/dist/commands/archive.d.ts.map +1 -0
  6. package/dist/commands/archive.js +353 -0
  7. package/dist/commands/iterate.d.ts.map +1 -1
  8. package/dist/commands/iterate.js +12 -13
  9. package/dist/commands/mode.d.ts +24 -0
  10. package/dist/commands/mode.d.ts.map +1 -0
  11. package/dist/commands/mode.js +259 -0
  12. package/dist/commands/plan.d.ts +49 -0
  13. package/dist/commands/plan.d.ts.map +1 -0
  14. package/dist/commands/plan.js +448 -0
  15. package/dist/commands/quality-gates.d.ts +52 -0
  16. package/dist/commands/quality-gates.d.ts.map +1 -0
  17. package/dist/commands/quality-gates.js +490 -0
  18. package/dist/commands/specs.d.ts +71 -0
  19. package/dist/commands/specs.d.ts.map +1 -0
  20. package/dist/commands/specs.js +735 -0
  21. package/dist/commands/status.d.ts +4 -3
  22. package/dist/commands/status.d.ts.map +1 -1
  23. package/dist/commands/status.js +552 -22
  24. package/dist/commands/tutorial.d.ts +55 -0
  25. package/dist/commands/tutorial.d.ts.map +1 -0
  26. package/dist/commands/tutorial.js +481 -0
  27. package/dist/commands/validate.d.ts +10 -2
  28. package/dist/commands/validate.d.ts.map +1 -1
  29. package/dist/commands/validate.js +199 -39
  30. package/dist/config/modes.d.ts +225 -0
  31. package/dist/config/modes.d.ts.map +1 -0
  32. package/dist/config/modes.js +321 -0
  33. package/dist/constants/spec-types.d.ts +41 -0
  34. package/dist/constants/spec-types.d.ts.map +1 -0
  35. package/dist/constants/spec-types.js +42 -0
  36. package/dist/index-new.d.ts +5 -0
  37. package/dist/index-new.d.ts.map +1 -0
  38. package/dist/index-new.js +317 -0
  39. package/dist/index.js +227 -10
  40. package/dist/index.js.backup +4711 -0
  41. package/dist/policy/PolicyManager.d.ts +104 -0
  42. package/dist/policy/PolicyManager.d.ts.map +1 -0
  43. package/dist/policy/PolicyManager.js +399 -0
  44. package/dist/scaffold/cursor-hooks.d.ts.map +1 -1
  45. package/dist/scaffold/cursor-hooks.js +15 -0
  46. package/dist/scaffold/git-hooks.d.ts.map +1 -1
  47. package/dist/scaffold/git-hooks.js +32 -44
  48. package/dist/scaffold/index.d.ts.map +1 -1
  49. package/dist/scaffold/index.js +19 -0
  50. package/dist/spec/SpecFileManager.d.ts +146 -0
  51. package/dist/spec/SpecFileManager.d.ts.map +1 -0
  52. package/dist/spec/SpecFileManager.js +419 -0
  53. package/dist/utils/quality-gates-errors.js +520 -0
  54. package/dist/utils/quality-gates.d.ts +49 -0
  55. package/dist/utils/quality-gates.d.ts.map +1 -0
  56. package/dist/utils/quality-gates.js +361 -0
  57. package/dist/utils/spec-resolver.d.ts +88 -0
  58. package/dist/utils/spec-resolver.d.ts.map +1 -0
  59. package/dist/utils/spec-resolver.js +602 -0
  60. package/dist/validation/spec-validation.d.ts +14 -0
  61. package/dist/validation/spec-validation.d.ts.map +1 -1
  62. package/dist/validation/spec-validation.js +225 -13
  63. package/package.json +6 -5
  64. package/templates/.cursor/hooks/caws-scope-guard.sh +64 -8
  65. package/templates/.cursor/hooks/validate-spec.sh +22 -12
  66. package/templates/.cursor/rules/00-claims-verification.mdc +144 -0
  67. package/templates/.cursor/rules/01-working-style.mdc +50 -0
  68. package/templates/.cursor/rules/02-quality-gates.mdc +370 -0
  69. package/templates/.cursor/rules/03-naming-and-refactor.mdc +33 -0
  70. package/templates/.cursor/rules/04-logging-language-style.mdc +23 -0
  71. package/templates/.cursor/rules/05-safe-defaults-guards.mdc +23 -0
  72. package/templates/.cursor/rules/06-typescript-conventions.mdc +36 -0
  73. package/templates/.cursor/rules/07-process-ops.mdc +20 -0
  74. package/templates/.cursor/rules/08-solid-and-architecture.mdc +16 -0
  75. package/templates/.cursor/rules/09-docstrings.mdc +89 -0
  76. package/templates/.cursor/rules/10-authorship-and-attribution.mdc +15 -0
  77. package/templates/.cursor/rules/11-documentation-quality-standards.mdc +390 -0
  78. package/templates/.cursor/rules/12-scope-management-waivers.mdc +385 -0
  79. package/templates/.cursor/rules/13-implementation-completeness.mdc +516 -0
  80. package/templates/.cursor/rules/14-language-agnostic-standards.mdc +588 -0
  81. package/templates/.cursor/rules/15-sophisticated-todo-detection.mdc +425 -0
  82. package/templates/.cursor/rules/README.md +150 -0
  83. package/templates/apps/tools/caws/prompt-lint.js.backup +274 -0
  84. package/templates/apps/tools/caws/provenance.js.backup +73 -0
  85. package/templates/scripts/quality-gates/check-god-objects.js +146 -0
  86. package/templates/scripts/quality-gates/run-quality-gates.js +50 -0
  87. package/templates/scripts/v3/analysis/todo_analyzer.py +1950 -0
@@ -4,7 +4,7 @@
4
4
  */
5
5
  export function statusCommand(options?: any): Promise<any>;
6
6
  /**
7
- * Load working specification
7
+ * Load working specification (legacy single file approach)
8
8
  * @param {string} specPath - Path to working spec
9
9
  * @returns {Promise<Object|null>} Parsed spec or null
10
10
  */
@@ -35,9 +35,10 @@ export function checkQualityGates(): Promise<any>;
35
35
  */
36
36
  export function displayStatus(data: any): void;
37
37
  /**
38
- * Generate actionable suggestions based on status
38
+ * Generate actionable suggestions based on status and mode
39
39
  * @param {Object} data - Status data
40
+ * @param {string} currentMode - Current CAWS mode
40
41
  * @returns {string[]} Array of suggestions
41
42
  */
42
- export function generateSuggestions(data: any): string[];
43
+ export function generateSuggestions(data: any, currentMode: string): string[];
43
44
  //# sourceMappingURL=status.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/commands/status.js"],"names":[],"mappings":"AAuUA;;;GAGG;AACH,2DAiCC;AAhWD;;;;GAIG;AACH,2CAHW,MAAM,GACJ,OAAO,CAAC,MAAO,IAAI,CAAC,CAahC;AAED;;;GAGG;AACH,iCAFa,OAAO,KAAQ,CAgC3B;AAED;;;GAGG;AACH,uCAFa,OAAO,KAAQ,CA+B3B;AAED;;;GAGG;AACH,oCAFa,OAAO,KAAQ,CA0D3B;AAED;;;GAGG;AACH,qCAFa,OAAO,KAAQ,CAS3B;AAwBD;;;GAGG;AACH,+CAgGC;AAED;;;;GAIG;AACH,gDAFa,MAAM,EAAE,CAsBpB"}
1
+ {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/commands/status.js"],"names":[],"mappings":"AA6uBA;;;GAGG;AACH,2DA6IC;AAl3BD;;;;GAIG;AACH,2CAHW,MAAM,GACJ,OAAO,CAAC,MAAO,IAAI,CAAC,CAahC;AAgBD;;;GAGG;AACH,iCAFa,OAAO,KAAQ,CAgC3B;AAED;;;GAGG;AACH,uCAFa,OAAO,KAAQ,CA+B3B;AAED;;;GAGG;AACH,oCAFa,OAAO,KAAQ,CA0D3B;AAED;;;GAGG;AACH,qCAFa,OAAO,KAAQ,CAS3B;AAwBD;;;GAGG;AACH,+CAgGC;AAED;;;;;GAKG;AACH,4DAHW,MAAM,GACJ,MAAM,EAAE,CAoCpB"}
@@ -11,7 +11,7 @@ const chalk = require('chalk');
11
11
  const { safeAsync, outputResult } = require('../error-handler');
12
12
 
13
13
  /**
14
- * Load working specification
14
+ * Load working specification (legacy single file approach)
15
15
  * @param {string} specPath - Path to working spec
16
16
  * @returns {Promise<Object|null>} Parsed spec or null
17
17
  */
@@ -28,6 +28,20 @@ async function loadWorkingSpec(specPath = '.caws/working-spec.yaml') {
28
28
  }
29
29
  }
30
30
 
31
+ /**
32
+ * Load specs from the new multi-spec system
33
+ * @returns {Promise<Array>} Array of spec objects
34
+ */
35
+ async function loadSpecsFromMultiSpec() {
36
+ const { listSpecFiles } = require('./specs');
37
+
38
+ try {
39
+ return await listSpecFiles();
40
+ } catch (error) {
41
+ return [];
42
+ }
43
+ }
44
+
31
45
  /**
32
46
  * Check Git hooks status
33
47
  * @returns {Promise<Object>} Hooks status
@@ -299,32 +313,440 @@ function displayStatus(data) {
299
313
  }
300
314
 
301
315
  /**
302
- * Generate actionable suggestions based on status
316
+ * Generate actionable suggestions based on status and mode
303
317
  * @param {Object} data - Status data
318
+ * @param {string} currentMode - Current CAWS mode
304
319
  * @returns {string[]} Array of suggestions
305
320
  */
306
- function generateSuggestions(data) {
321
+ function generateSuggestions(data, currentMode) {
322
+ const { spec, specs, hooks, provenance, waivers } = data;
323
+ const modes = require('../config/modes');
307
324
  const suggestions = [];
308
325
 
309
- if (!data.spec) {
310
- suggestions.push('Initialize CAWS: caws init .');
326
+ // Basic setup suggestions
327
+ if (!spec && (!specs || specs.length === 0)) {
328
+ suggestions.push('Create a spec: caws specs create <id>');
311
329
  }
312
330
 
313
- if (!data.hooks.installed) {
331
+ // Mode-specific suggestions
332
+ if (modes.isFeatureEnabled('gitHooks', currentMode) && !hooks.installed) {
314
333
  suggestions.push('Install Git hooks: caws hooks install');
315
334
  }
316
335
 
317
- if (!data.provenance.exists) {
336
+ if (modes.isFeatureEnabled('provenance', currentMode) && !provenance.exists) {
318
337
  suggestions.push('Initialize provenance tracking: caws provenance init');
319
338
  }
320
339
 
321
- if (data.spec && !data.hooks.installed && !data.provenance.exists) {
322
- suggestions.push('Complete setup: caws scaffold');
340
+ if (modes.isFeatureEnabled('waivers', currentMode) && !waivers.exists) {
341
+ suggestions.push('Initialize waiver system: caws waivers create (when needed)');
323
342
  }
324
343
 
344
+ // Quality gate suggestions
345
+ if (modes.isFeatureEnabled('qualityGates', currentMode)) {
346
+ if (spec || (specs && specs.length > 0)) {
347
+ suggestions.push('Run quality gates: caws diagnose');
348
+ }
349
+ }
350
+
351
+ // Mode switching suggestion
352
+ suggestions.push('Switch modes: caws mode set --interactive');
353
+
325
354
  return suggestions;
326
355
  }
327
356
 
357
+ /**
358
+ * Create progress bar string
359
+ * @param {number} current - Current value
360
+ * @param {number} total - Total value
361
+ * @param {number} width - Bar width
362
+ * @returns {string} Progress bar string
363
+ */
364
+ function createProgressBar(current, total, width = 20) {
365
+ if (total === 0) return '░'.repeat(width);
366
+
367
+ const percentage = Math.min(current / total, 1);
368
+ const filled = Math.round(percentage * width);
369
+ const empty = width - filled;
370
+
371
+ return '▓'.repeat(filled) + '░'.repeat(empty);
372
+ }
373
+
374
+ /**
375
+ * Get color for progress percentage
376
+ * @param {number} percentage - Progress percentage
377
+ * @returns {string} Chalk color function
378
+ */
379
+ function getProgressColor(percentage) {
380
+ if (percentage >= 80) return chalk.green;
381
+ if (percentage >= 50) return chalk.yellow;
382
+ return chalk.red;
383
+ }
384
+
385
+ /**
386
+ * Display enhanced visual status
387
+ * @param {Object} data - Status data
388
+ * @param {string} currentMode - Current CAWS mode
389
+ */
390
+ function displayVisualStatus(data, currentMode) {
391
+ const { spec, specs, hooks, provenance, waivers, gates } = data;
392
+ const modes = require('../config/modes');
393
+ const tierConfig = modes.getTier(currentMode);
394
+
395
+ console.log(
396
+ chalk.bold.cyan(
397
+ `\n📊 CAWS Project Status (${tierConfig.icon} ${tierConfig.color(currentMode)})`
398
+ )
399
+ );
400
+ console.log(
401
+ chalk.cyan(
402
+ '━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n'
403
+ )
404
+ );
405
+
406
+ // Multi-spec system status
407
+ if (specs && specs.length > 0) {
408
+ console.log(chalk.green(`✅ Specs System (${specs.length} specs)`));
409
+
410
+ // Show active specs first
411
+ const activeSpecs = specs.filter((s) => s.status === 'active');
412
+ const draftSpecs = specs.filter((s) => s.status === 'draft');
413
+ const completedSpecs = specs.filter((s) => s.status === 'completed');
414
+
415
+ if (activeSpecs.length > 0) {
416
+ console.log(
417
+ chalk.gray(` Active: ${activeSpecs.map((s) => `${s.id}(${s.type})`).join(', ')}`)
418
+ );
419
+ }
420
+ if (draftSpecs.length > 0) {
421
+ console.log(
422
+ chalk.gray(` Draft: ${draftSpecs.length} spec${draftSpecs.length > 1 ? 's' : ''}`)
423
+ );
424
+ // Show details for draft specs if not too many
425
+ if (draftSpecs.length <= 3) {
426
+ draftSpecs.forEach((s) => {
427
+ console.log(chalk.gray(` • ${s.id}: ${s.title}`));
428
+ });
429
+ }
430
+ }
431
+ if (completedSpecs.length > 0) {
432
+ console.log(
433
+ chalk.gray(
434
+ ` Completed: ${completedSpecs.length} spec${completedSpecs.length > 1 ? 's' : ''}`
435
+ )
436
+ );
437
+ // Show details for completed specs if not too many
438
+ if (completedSpecs.length <= 3) {
439
+ completedSpecs.forEach((s) => {
440
+ console.log(chalk.gray(` • ${s.id}: ${s.title}`));
441
+ });
442
+ }
443
+ }
444
+
445
+ // Overall specs progress
446
+ const totalSpecs = specs.length;
447
+ const completedSpecsCount = specs.filter((s) => s.status === 'completed').length;
448
+ const activeSpecsCount = specs.filter((s) => s.status === 'active').length;
449
+ const progressPercentage =
450
+ totalSpecs > 0 ? Math.round((completedSpecsCount / totalSpecs) * 100) : 0;
451
+ const progressBar = createProgressBar(completedSpecsCount, totalSpecs);
452
+ const color = getProgressColor(progressPercentage);
453
+
454
+ console.log(
455
+ chalk.gray(
456
+ ` Overall Progress: ${color(`${progressPercentage}%`)} ${progressBar} ${completedSpecsCount}/${totalSpecs} completed`
457
+ )
458
+ );
459
+
460
+ if (activeSpecsCount > 0) {
461
+ console.log(chalk.gray(` Active Features: ${activeSpecsCount} in progress`));
462
+ }
463
+
464
+ // Show risk tier breakdown
465
+ const riskBreakdown = {};
466
+ specs.forEach((s) => {
467
+ const tier = s.risk_tier || 'T3';
468
+ riskBreakdown[tier] = (riskBreakdown[tier] || 0) + 1;
469
+ });
470
+
471
+ if (Object.keys(riskBreakdown).length > 1) {
472
+ const tierDisplay = Object.entries(riskBreakdown)
473
+ .map(([tier, count]) => `${tier}:${count}`)
474
+ .join(', ');
475
+ console.log(chalk.gray(` Risk Distribution: ${tierDisplay}`));
476
+ }
477
+ } else if (spec) {
478
+ // Legacy single spec system
479
+ console.log(chalk.green('✅ Working Spec'));
480
+ console.log(chalk.gray(` ID: ${spec.id} | Tier: ${spec.risk_tier} | Mode: ${spec.mode}`));
481
+ console.log(chalk.gray(` Title: ${spec.title}`));
482
+
483
+ // Acceptance Criteria Progress
484
+ if (spec.acceptance_criteria && spec.acceptance_criteria.length > 0) {
485
+ const total = spec.acceptance_criteria.length;
486
+ const completed = spec.acceptance_criteria.filter((c) => c.completed).length;
487
+ const percentage = Math.round((completed / total) * 100);
488
+
489
+ const color = getProgressColor(percentage);
490
+ const bar = createProgressBar(completed, total);
491
+
492
+ console.log(
493
+ chalk.gray(
494
+ ` Acceptance Criteria: ${color(`${percentage}%`)} ${bar} ${completed}/${total}`
495
+ )
496
+ );
497
+ }
498
+
499
+ // Test Coverage (placeholder for now)
500
+ console.log(
501
+ chalk.gray(
502
+ ` Test Coverage: ${chalk.blue('Calculating...')} ${createProgressBar(0, 100)} 0%`
503
+ )
504
+ );
505
+
506
+ // Risk Tier Indicator
507
+ const riskColor =
508
+ spec.risk_tier === 'T1' ? chalk.red : spec.risk_tier === 'T2' ? chalk.yellow : chalk.green;
509
+ console.log(
510
+ chalk.gray(
511
+ ` Risk Tier: ${riskColor(spec.risk_tier)} (Quality Gates: ${riskColor('Active')})`
512
+ )
513
+ );
514
+ } else {
515
+ console.log(chalk.red('❌ No Specs Found'));
516
+ console.log(chalk.gray(' No working spec or specs directory found'));
517
+ console.log(chalk.yellow(' 💡 Run: caws specs create <id> to create specs'));
518
+ console.log(chalk.yellow(' 💡 Or run: caws init . for legacy single spec'));
519
+ }
520
+
521
+ console.log('');
522
+
523
+ // Git Hooks Status (only show in modes that support it)
524
+ if (modes.isFeatureEnabled('gitHooks', currentMode)) {
525
+ if (hooks.installed) {
526
+ const hookBar = createProgressBar(hooks.count, hooks.total);
527
+ console.log(chalk.green(`✅ Git Hooks`));
528
+ console.log(
529
+ chalk.gray(` ${hookBar} ${hooks.count}/${hooks.total} active: ${hooks.active.join(', ')}`)
530
+ );
531
+ } else {
532
+ console.log(chalk.yellow('⚠️ Git Hooks'));
533
+ console.log(chalk.gray(' No CAWS git hooks installed'));
534
+ console.log(chalk.yellow(' 💡 Run: caws hooks install'));
535
+ }
536
+ }
537
+
538
+ console.log('');
539
+
540
+ // Provenance Status (only show in modes that support it)
541
+ if (modes.isFeatureEnabled('provenance', currentMode)) {
542
+ if (provenance.exists) {
543
+ const provenanceBar = createProgressBar(provenance.count, Math.max(provenance.count, 10));
544
+ console.log(chalk.green('✅ Provenance'));
545
+ console.log(chalk.gray(` ${provenanceBar} ${provenance.count} entries`));
546
+ if (provenance.lastUpdate) {
547
+ console.log(chalk.gray(` Last update: ${getTimeSince(provenance.lastUpdate)}`));
548
+ }
549
+ } else {
550
+ console.log(chalk.yellow('⚠️ Provenance'));
551
+ console.log(chalk.gray(' Provenance tracking not initialized'));
552
+ console.log(chalk.yellow(' 💡 Run: caws provenance init'));
553
+ }
554
+ }
555
+
556
+ console.log('');
557
+
558
+ // Waivers Status (only show in modes that support it)
559
+ if (modes.isFeatureEnabled('waivers', currentMode)) {
560
+ if (waivers.exists && waivers.total > 0) {
561
+ const waiverBar = createProgressBar(waivers.active, waivers.total);
562
+ console.log(chalk.green('✅ Quality Gate Waivers'));
563
+ console.log(
564
+ chalk.gray(
565
+ ` ${waiverBar} ${waivers.active} active, ${waivers.expired} expired, ${waivers.revoked} revoked`
566
+ )
567
+ );
568
+ console.log(chalk.gray(` Total: ${waivers.total} waiver${waivers.total > 1 ? 's' : ''}`));
569
+ } else if (waivers.exists) {
570
+ console.log(chalk.blue('ℹ️ Quality Gate Waivers'));
571
+ console.log(chalk.gray(' No waivers configured'));
572
+ } else {
573
+ console.log(chalk.yellow('⚠️ Quality Gate Waivers'));
574
+ console.log(chalk.gray(' Waiver system not initialized'));
575
+ console.log(chalk.yellow(' 💡 Run: caws waivers create (when needed)'));
576
+ }
577
+ }
578
+
579
+ console.log('');
580
+
581
+ // Quality Gates Status (only show in modes that support it)
582
+ if (modes.isFeatureEnabled('qualityGates', currentMode)) {
583
+ console.log(chalk.blue('🛡️ Quality Gates'));
584
+ if (gates.checked) {
585
+ if (gates.passed) {
586
+ console.log(chalk.green(` ${createProgressBar(1, 1)} All gates passed`));
587
+ gates.results?.forEach((gate) => {
588
+ const gateStatus = gate.status === 'passed' ? chalk.green('✓') : chalk.red('✗');
589
+ console.log(chalk.gray(` ${gateStatus} ${gate.name}: ${gate.message || 'OK'}`));
590
+ });
591
+ } else {
592
+ console.log(
593
+ chalk.red(
594
+ ` ${createProgressBar(0, gates.results?.length || 1)} ${gates.failed || 0} gates failed`
595
+ )
596
+ );
597
+ gates.results?.forEach((gate) => {
598
+ const gateStatus = gate.status === 'passed' ? chalk.green('✓') : chalk.red('✗');
599
+ console.log(chalk.gray(` ${gateStatus} ${gate.name}: ${gate.message || 'Failed'}`));
600
+ });
601
+ }
602
+ } else {
603
+ console.log(chalk.gray(` ${gates.message}`));
604
+ }
605
+ }
606
+
607
+ // Progress Summary
608
+ const overallProgress = calculateOverallProgress(data);
609
+ const progressColor = getProgressColor(overallProgress);
610
+ const progressBar = createProgressBar(overallProgress, 100);
611
+
612
+ console.log('');
613
+ console.log(chalk.bold.blue('📈 Overall Progress'));
614
+ console.log(chalk.gray(` ${progressBar} ${progressColor(`${overallProgress}%`)} complete`));
615
+
616
+ // Suggestions (mode-aware)
617
+ const suggestions = generateSuggestions(data, currentMode);
618
+ if (suggestions.length > 0) {
619
+ console.log(chalk.bold.yellow('\n💡 Next Steps:'));
620
+ suggestions.forEach((suggestion, index) => {
621
+ console.log(chalk.yellow(` ${index + 1}. ${suggestion}`));
622
+ });
623
+ }
624
+
625
+ // Quick Links (mode-aware)
626
+ console.log(chalk.bold.blue('\n📚 Quick Actions:'));
627
+ if (spec || (specs && specs.length > 0)) {
628
+ if (modes.isFeatureEnabled('validate', currentMode)) {
629
+ console.log(chalk.blue(' View specs: caws specs list'));
630
+ }
631
+ if (modes.isFeatureEnabled('validate', currentMode)) {
632
+ console.log(chalk.blue(' Validate: caws validate'));
633
+ }
634
+ }
635
+
636
+ if (modes.isFeatureEnabled('gitHooks', currentMode) && hooks.installed) {
637
+ console.log(chalk.blue(' View hooks: caws hooks status'));
638
+ }
639
+
640
+ if (modes.isFeatureEnabled('provenance', currentMode) && provenance.exists) {
641
+ console.log(chalk.blue(' View provenance: caws provenance show'));
642
+ }
643
+
644
+ if (modes.isFeatureEnabled('waivers', currentMode) && waivers.exists && waivers.total > 0) {
645
+ console.log(chalk.blue(' View waivers: caws waivers list'));
646
+ }
647
+
648
+ console.log(chalk.blue(' Get help: caws help'));
649
+ console.log(chalk.blue(' Switch mode: caws mode set --interactive'));
650
+
651
+ console.log('');
652
+ }
653
+
654
+ /**
655
+ * Calculate overall project progress (mode-aware)
656
+ * @param {Object} data - Status data
657
+ * @returns {number} Overall progress percentage
658
+ */
659
+ function calculateOverallProgress(data) {
660
+ const { spec, specs, hooks, provenance, waivers, currentMode } = data;
661
+ const modes = require('../config/modes');
662
+
663
+ let score = 0;
664
+
665
+ // Multi-spec system
666
+ if (specs && specs.length > 0) {
667
+ // Specs system (40%)
668
+ const completedSpecs = specs.filter((s) => s.status === 'completed').length;
669
+ if (specs.length > 0) {
670
+ const percentage = (completedSpecs / specs.length) * 40;
671
+ score += percentage;
672
+ }
673
+
674
+ // Git hooks (20%) - only if enabled in mode
675
+ if (modes.isFeatureEnabled('gitHooks', currentMode)) {
676
+ if (hooks.installed) score += 20;
677
+ }
678
+
679
+ // Provenance (20%) - only if enabled in mode
680
+ if (modes.isFeatureEnabled('provenance', currentMode)) {
681
+ if (provenance.exists) score += 20;
682
+ }
683
+
684
+ // Waivers (15%) - only if enabled in mode
685
+ if (modes.isFeatureEnabled('waivers', currentMode)) {
686
+ if (waivers.exists) score += 15;
687
+ }
688
+
689
+ // Quality gates (5%) - only if enabled in mode
690
+ if (modes.isFeatureEnabled('qualityGates', currentMode)) {
691
+ if (specs.length > 0) score += 5;
692
+ }
693
+ } else if (spec) {
694
+ // Legacy single spec system (30%)
695
+ if (spec) score += 30;
696
+
697
+ // Acceptance criteria progress (25%)
698
+ if (spec && spec.acceptance_criteria && spec.acceptance_criteria.length > 0) {
699
+ const completed = spec.acceptance_criteria.filter((c) => c.completed).length;
700
+ const percentage = (completed / spec.acceptance_criteria.length) * 25;
701
+ score += percentage;
702
+ }
703
+
704
+ // Git hooks (15%) - only if enabled in mode
705
+ if (modes.isFeatureEnabled('gitHooks', currentMode)) {
706
+ if (hooks.installed) score += 15;
707
+ }
708
+
709
+ // Provenance (15%) - only if enabled in mode
710
+ if (modes.isFeatureEnabled('provenance', currentMode)) {
711
+ if (provenance.exists) score += 15;
712
+ }
713
+
714
+ // Waivers (10%) - only if enabled in mode
715
+ if (modes.isFeatureEnabled('waivers', currentMode)) {
716
+ if (waivers.exists) score += 10;
717
+ }
718
+
719
+ // Quality gates (5%) - only if enabled in mode
720
+ if (modes.isFeatureEnabled('qualityGates', currentMode)) {
721
+ if (spec) score += 5;
722
+ }
723
+ } else {
724
+ // No specs system - check basic setup (mode-aware)
725
+
726
+ // Git hooks (30%) - only if enabled in mode
727
+ if (modes.isFeatureEnabled('gitHooks', currentMode)) {
728
+ if (hooks.installed) score += 30;
729
+ }
730
+
731
+ // Provenance (30%) - only if enabled in mode
732
+ if (modes.isFeatureEnabled('provenance', currentMode)) {
733
+ if (provenance.exists) score += 30;
734
+ }
735
+
736
+ // Waivers (20%) - only if enabled in mode
737
+ if (modes.isFeatureEnabled('waivers', currentMode)) {
738
+ if (waivers.exists) score += 20;
739
+ }
740
+
741
+ // Quality gates (20%) - only if enabled in mode
742
+ if (modes.isFeatureEnabled('qualityGates', currentMode)) {
743
+ if (hooks.installed || provenance.exists) score += 20;
744
+ }
745
+ }
746
+
747
+ return Math.min(Math.round(score), 100);
748
+ }
749
+
328
750
  /**
329
751
  * Status command handler
330
752
  * @param {Object} options - Command options
@@ -332,29 +754,137 @@ function generateSuggestions(data) {
332
754
  async function statusCommand(options = {}) {
333
755
  return safeAsync(
334
756
  async () => {
757
+ // Check current mode and adjust behavior accordingly
758
+ const modes = require('../config/modes');
759
+ const currentMode = await modes.getCurrentMode();
760
+
335
761
  // Load all status data
336
762
  const spec = await loadWorkingSpec(options.spec || '.caws/working-spec.yaml');
763
+ const specs = await loadSpecsFromMultiSpec();
337
764
  const hooks = await checkGitHooks();
338
765
  const provenance = await loadProvenanceChain();
339
766
  const waivers = await loadWaiverStatus();
340
767
  const gates = await checkQualityGates();
341
768
 
342
- // Display status
343
- displayStatus({
344
- spec,
345
- hooks,
346
- provenance,
347
- waivers,
348
- gates,
349
- });
769
+ // Display status (visual mode if requested)
770
+ if (options.visual || options.json) {
771
+ if (options.json) {
772
+ // JSON output for automation
773
+ const result = {
774
+ command: 'status',
775
+ timestamp: new Date().toISOString(),
776
+ system: specs.length > 0 ? 'multi-spec' : 'single-spec',
777
+ specs:
778
+ specs.length > 0
779
+ ? {
780
+ count: specs.length,
781
+ active: specs.filter((s) => s.status === 'active').length,
782
+ draft: specs.filter((s) => s.status === 'draft').length,
783
+ completed: specs.filter((s) => s.status === 'completed').length,
784
+ list: specs.map((s) => ({
785
+ id: s.id,
786
+ type: s.type,
787
+ status: s.status,
788
+ title: s.title,
789
+ })),
790
+ }
791
+ : null,
792
+ legacySpec: spec
793
+ ? {
794
+ id: spec.id,
795
+ title: spec.title,
796
+ riskTier: spec.risk_tier,
797
+ mode: spec.mode,
798
+ acceptanceCriteria: spec.acceptance_criteria?.length || 0,
799
+ completedCriteria:
800
+ spec.acceptance_criteria?.filter((c) => c.completed).length || 0,
801
+ }
802
+ : null,
803
+ hooks: {
804
+ installed: hooks.installed,
805
+ count: hooks.count,
806
+ total: hooks.total,
807
+ active: hooks.active,
808
+ },
809
+ provenance: {
810
+ exists: provenance.exists,
811
+ count: provenance.count,
812
+ lastUpdate: provenance.lastUpdate,
813
+ },
814
+ waivers: {
815
+ exists: waivers.exists,
816
+ active: waivers.active,
817
+ expired: waivers.expired,
818
+ revoked: waivers.revoked,
819
+ total: waivers.total,
820
+ },
821
+ qualityGates: {
822
+ checked: gates.checked,
823
+ passed: gates.passed,
824
+ message: gates.message,
825
+ },
826
+ overallProgress: calculateOverallProgress({
827
+ spec,
828
+ specs,
829
+ hooks,
830
+ provenance,
831
+ waivers,
832
+ gates,
833
+ }),
834
+ };
835
+
836
+ console.log(JSON.stringify(result, null, 2));
837
+ } else {
838
+ // Visual output
839
+ displayVisualStatus(
840
+ {
841
+ spec,
842
+ specs,
843
+ hooks,
844
+ provenance,
845
+ waivers,
846
+ gates,
847
+ },
848
+ currentMode
849
+ );
850
+ }
851
+ } else {
852
+ // Original text-based output
853
+ displayStatus({
854
+ spec,
855
+ hooks,
856
+ provenance,
857
+ waivers,
858
+ gates,
859
+ });
860
+ }
350
861
 
351
862
  const result = outputResult({
352
863
  command: 'status',
353
- spec: spec ? 'loaded' : 'not found',
354
- hooks: hooks.installed,
355
- provenance: provenance.entries?.length || 0,
356
- waivers: waivers.active?.length || 0,
357
- gates: gates.passed ? 'passed' : 'failed',
864
+ mode: options.visual ? 'visual' : options.json ? 'json' : 'text',
865
+ system: specs.length > 0 ? 'multi-spec' : 'single-spec',
866
+ currentMode: currentMode,
867
+ specs: specs.length,
868
+ legacySpec: spec ? 'loaded' : 'not found',
869
+ hooks: modes.isFeatureEnabled('gitHooks', currentMode) ? hooks.installed : null,
870
+ provenance: modes.isFeatureEnabled('provenance', currentMode)
871
+ ? provenance.count || 0
872
+ : null,
873
+ waivers: modes.isFeatureEnabled('waivers', currentMode) ? waivers.active || 0 : null,
874
+ gates: modes.isFeatureEnabled('qualityGates', currentMode)
875
+ ? gates.passed
876
+ ? 'passed'
877
+ : 'failed'
878
+ : null,
879
+ overallProgress: calculateOverallProgress({
880
+ spec,
881
+ specs,
882
+ hooks,
883
+ provenance,
884
+ waivers,
885
+ gates,
886
+ currentMode,
887
+ }),
358
888
  });
359
889
 
360
890
  return result;