@paths.design/caws-cli 8.2.1 → 8.3.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 (51) hide show
  1. package/dist/budget-derivation.js +10 -10
  2. package/dist/commands/archive.js +22 -22
  3. package/dist/commands/burnup.js +7 -7
  4. package/dist/commands/diagnose.js +25 -25
  5. package/dist/commands/evaluate.js +20 -20
  6. package/dist/commands/init.js +71 -72
  7. package/dist/commands/iterate.js +21 -21
  8. package/dist/commands/mode.js +11 -11
  9. package/dist/commands/plan.js +5 -5
  10. package/dist/commands/provenance.js +86 -86
  11. package/dist/commands/quality-gates.js +3 -3
  12. package/dist/commands/quality-monitor.js +17 -17
  13. package/dist/commands/session.js +312 -0
  14. package/dist/commands/specs.js +44 -44
  15. package/dist/commands/status.js +43 -43
  16. package/dist/commands/templates.js +14 -14
  17. package/dist/commands/tool.js +1 -1
  18. package/dist/commands/troubleshoot.js +11 -11
  19. package/dist/commands/tutorial.js +119 -119
  20. package/dist/commands/validate.js +6 -6
  21. package/dist/commands/waivers.js +93 -60
  22. package/dist/commands/workflow.js +17 -17
  23. package/dist/commands/worktree.js +13 -13
  24. package/dist/config/index.js +5 -5
  25. package/dist/config/modes.js +7 -7
  26. package/dist/constants/spec-types.js +5 -5
  27. package/dist/error-handler.js +4 -4
  28. package/dist/generators/jest-config-generator.js +3 -3
  29. package/dist/generators/working-spec.js +4 -4
  30. package/dist/index.js +79 -27
  31. package/dist/minimal-cli.js +9 -9
  32. package/dist/policy/PolicyManager.js +1 -1
  33. package/dist/scaffold/claude-hooks.js +7 -7
  34. package/dist/scaffold/cursor-hooks.js +8 -8
  35. package/dist/scaffold/git-hooks.js +152 -152
  36. package/dist/scaffold/index.js +48 -48
  37. package/dist/session/session-manager.js +548 -0
  38. package/dist/test-analysis.js +20 -20
  39. package/dist/utils/command-wrapper.js +8 -8
  40. package/dist/utils/detection.js +7 -7
  41. package/dist/utils/finalization.js +21 -21
  42. package/dist/utils/git-lock.js +3 -3
  43. package/dist/utils/gitignore-updater.js +1 -1
  44. package/dist/utils/project-analysis.js +7 -7
  45. package/dist/utils/quality-gates-utils.js +35 -35
  46. package/dist/utils/spec-resolver.js +8 -8
  47. package/dist/utils/typescript-detector.js +5 -5
  48. package/dist/utils/yaml-validation.js +1 -1
  49. package/dist/validation/spec-validation.js +4 -4
  50. package/dist/worktree/worktree-manager.js +11 -5
  51. package/package.json +1 -1
@@ -209,13 +209,13 @@ function validateGeneratedSpec(specContent, _answers) {
209
209
  const isValid = validateWorkingSpec(spec);
210
210
 
211
211
  if (!isValid) {
212
- console.error(chalk.red('āŒ Generated working spec failed validation:'));
212
+ console.error(chalk.red('Generated working spec failed validation:'));
213
213
  validateWorkingSpec.errors.forEach((error) => {
214
214
  console.error(` - ${error.instancePath || 'root'}: ${error.message}`);
215
215
  });
216
216
 
217
217
  // Provide helpful guidance
218
- console.log(chalk.blue('\nšŸ’” Validation Tips:'));
218
+ console.log(chalk.blue('\nValidation Tips:'));
219
219
  console.log(' - Ensure risk_tier is 1, 2, or 3');
220
220
  console.log(' - Check that scope.in is not empty');
221
221
  console.log(' - Verify invariants and acceptance criteria are provided');
@@ -224,9 +224,9 @@ function validateGeneratedSpec(specContent, _answers) {
224
224
  process.exit(1);
225
225
  }
226
226
 
227
- console.log(chalk.green('āœ… Generated working spec passed validation'));
227
+ console.log(chalk.green('Generated working spec passed validation'));
228
228
  } catch (error) {
229
- console.error(chalk.red('āŒ Error validating working spec:'), error.message);
229
+ console.error(chalk.red('Error validating working spec:'), error.message);
230
230
  process.exit(1);
231
231
  }
232
232
  }
package/dist/index.js CHANGED
@@ -50,6 +50,7 @@ const { modeCommand } = require('./commands/mode');
50
50
  const { tutorialCommand } = require('./commands/tutorial');
51
51
  const { planCommand } = require('./commands/plan');
52
52
  const { worktreeCommand } = require('./commands/worktree');
53
+ const { sessionCommand } = require('./commands/session');
53
54
 
54
55
  // Import scaffold functionality
55
56
  const { scaffoldProject, setScaffoldDependencies } = require('./scaffold');
@@ -378,6 +379,56 @@ worktreeCmd
378
379
  .option('--max-age <days>', 'Remove entries older than N days', '30')
379
380
  .action((options) => worktreeCommand('prune', options));
380
381
 
382
+ // Session command group
383
+ const sessionCmd = program
384
+ .command('session')
385
+ .description('Manage session lifecycle and capsules for multi-agent coordination');
386
+
387
+ sessionCmd
388
+ .command('start')
389
+ .description('Start a new tracked session with baseline checkpoint')
390
+ .option('--role <role>', 'Agent role (worker, integrator, qa)', 'worker')
391
+ .option('--spec-id <id>', 'Associated feature spec ID')
392
+ .option('--scope <patterns>', 'Allowed file patterns (comma-separated)')
393
+ .option('--intent <text>', 'What this session intends to accomplish')
394
+ .action((options) => sessionCommand('start', options));
395
+
396
+ sessionCmd
397
+ .command('checkpoint')
398
+ .description('Record a checkpoint in the current session')
399
+ .option('--session-id <id>', 'Specific session ID (uses latest active if omitted)')
400
+ .option('--intent <text>', 'Updated intent description')
401
+ .option('--paths <paths>', 'Files changed (comma-separated)')
402
+ .option('--tests <json>', 'Test results as JSON array [{name, status, evidence}]')
403
+ .option('--issues <json>', 'Known issues as JSON array [{type, description}]')
404
+ .action((options) => sessionCommand('checkpoint', options));
405
+
406
+ sessionCmd
407
+ .command('end')
408
+ .description('End the current session with handoff information')
409
+ .option('--session-id <id>', 'Specific session ID (uses latest active if omitted)')
410
+ .option('--next-actions <actions>', 'Handoff actions (pipe-separated)')
411
+ .option('--risk-notes <notes>', 'Risk notes (pipe-separated)')
412
+ .action((options) => sessionCommand('end', options));
413
+
414
+ sessionCmd
415
+ .command('list')
416
+ .description('List all sessions')
417
+ .option('--status <status>', 'Filter by status (active, completed)')
418
+ .option('--limit <n>', 'Max entries to show')
419
+ .action((options) => sessionCommand('list', options));
420
+
421
+ sessionCmd
422
+ .command('show [id]')
423
+ .description('Show session capsule details (default: latest)')
424
+ .option('--json', 'Output as raw JSON', false)
425
+ .action((id, options) => sessionCommand('show', { ...options, id: id || 'latest' }));
426
+
427
+ sessionCmd
428
+ .command('briefing')
429
+ .description('Show session briefing for hooks/startup')
430
+ .action(() => sessionCommand('briefing'));
431
+
381
432
  // Templates command
382
433
  program
383
434
  .command('templates [subcommand]')
@@ -566,15 +617,15 @@ hooksCmd
566
617
  try {
567
618
  const result = await scaffoldGitHooks(process.cwd(), hookOptions);
568
619
  if (result.added > 0) {
569
- console.log(`āœ… Successfully installed ${result.added} git hooks`);
620
+ console.log(`Successfully installed ${result.added} git hooks`);
570
621
  if (result.skipped > 0) {
571
- console.log(`ā­ļø Skipped ${result.skipped} existing hooks`);
622
+ console.log(`Skipped ${result.skipped} existing hooks`);
572
623
  }
573
624
  } else {
574
- console.log('ā„¹ļø All hooks already configured');
625
+ console.log('All hooks already configured');
575
626
  }
576
627
  } catch (error) {
577
- console.error(`āŒ Failed to install git hooks: ${error.message}`);
628
+ console.error(`Failed to install git hooks: ${error.message}`);
578
629
  process.exit(1);
579
630
  }
580
631
  });
@@ -586,7 +637,7 @@ hooksCmd
586
637
  try {
587
638
  await removeGitHooks(process.cwd());
588
639
  } catch (error) {
589
- console.error(`āŒ Failed to remove git hooks: ${error.message}`);
640
+ console.error(`Failed to remove git hooks: ${error.message}`);
590
641
  process.exit(1);
591
642
  }
592
643
  });
@@ -598,7 +649,7 @@ hooksCmd
598
649
  try {
599
650
  await checkGitHooksStatus(process.cwd());
600
651
  } catch (error) {
601
- console.error(`āŒ Failed to check git hooks status: ${error.message}`);
652
+ console.error(`Failed to check git hooks status: ${error.message}`);
602
653
  process.exit(1);
603
654
  }
604
655
  });
@@ -647,22 +698,23 @@ program.exitOverride((err) => {
647
698
  'burnup',
648
699
  'tool',
649
700
  'worktree',
701
+ 'session',
650
702
  ];
651
703
  const similar = findSimilarCommand(commandName, validCommands);
652
704
 
653
- console.error(chalk.red(`\nāŒ Unknown command: ${commandName}`));
705
+ console.error(chalk.red(`\nUnknown command: ${commandName}`));
654
706
 
655
707
  if (similar) {
656
- console.error(chalk.yellow(`\nšŸ’” Did you mean: caws ${similar}?`));
708
+ console.error(chalk.yellow(`\nDid you mean: caws ${similar}?`));
657
709
  }
658
710
 
659
711
  console.error(
660
- chalk.yellow('šŸ’” Available commands: init, validate, scaffold, provenance, hooks')
712
+ chalk.yellow('Available commands: init, validate, scaffold, provenance, hooks')
661
713
  );
662
- console.error(chalk.yellow('šŸ’” Try: caws --help for full command list'));
714
+ console.error(chalk.yellow('Try: caws --help for full command list'));
663
715
  console.error(
664
716
  chalk.blue(
665
- '\nšŸ“š Documentation: https://github.com/Paths-Design/coding-agent-working-standard/blob/main/docs/api/cli.md'
717
+ '\nDocumentation: https://github.com/Paths-Design/coding-agent-working-standard/blob/main/docs/api/cli.md'
666
718
  )
667
719
  );
668
720
 
@@ -674,18 +726,18 @@ program.exitOverride((err) => {
674
726
  const optionMatch = err.message.match(/unknown option ['"]([^'"]+)['"]/i);
675
727
  const option = optionMatch ? optionMatch[1] : '';
676
728
 
677
- console.error(chalk.red(`\nāŒ Unknown option: ${option}`));
678
- console.error(chalk.yellow(`\nšŸ’” Try: caws ${commandName || ''} --help for available options`));
729
+ console.error(chalk.red(`\nUnknown option: ${option}`));
730
+ console.error(chalk.yellow(`\nTry: caws ${commandName || ''} --help for available options`));
679
731
 
680
732
  // Provide specific suggestions for common mistakes
681
733
  if (option === '--suggestions' || option === '--suggest') {
682
- console.error(chalk.yellow('šŸ’” Note: Validation includes suggestions by default'));
734
+ console.error(chalk.yellow('Note: Validation includes suggestions by default'));
683
735
  console.error(chalk.yellow(' Just run: caws validate'));
684
736
  }
685
737
 
686
738
  console.error(
687
739
  chalk.blue(
688
- '\nšŸ“š Documentation: https://github.com/Paths-Design/coding-agent-working-standard/blob/main/docs/api/cli.md'
740
+ '\nDocumentation: https://github.com/Paths-Design/coding-agent-working-standard/blob/main/docs/api/cli.md'
689
741
  )
690
742
  );
691
743
 
@@ -693,11 +745,11 @@ program.exitOverride((err) => {
693
745
  }
694
746
 
695
747
  // Generic Commander error
696
- console.error(chalk.red('\nāŒ Error:'), err.message);
697
- console.error(chalk.yellow('\nšŸ’” Try: caws --help for usage information'));
748
+ console.error(chalk.red('\nError:'), err.message);
749
+ console.error(chalk.yellow('\nTry: caws --help for usage information'));
698
750
  console.error(
699
751
  chalk.blue(
700
- '\nšŸ“š Documentation: https://github.com/Paths-Design/coding-agent-working-standard/blob/main/docs/agents/full-guide.md'
752
+ '\nDocumentation: https://github.com/Paths-Design/coding-agent-working-standard/blob/main/docs/agents/full-guide.md'
701
753
  )
702
754
  );
703
755
  process.exit(1);
@@ -743,19 +795,19 @@ if (require.main === module) {
743
795
  ];
744
796
  const similar = findSimilarCommand(commandName, validCommands);
745
797
 
746
- console.error(chalk.red(`\nāŒ Unknown command: ${commandName}`));
798
+ console.error(chalk.red(`\nUnknown command: ${commandName}`));
747
799
 
748
800
  if (similar) {
749
- console.error(chalk.yellow(`\nšŸ’” Did you mean: caws ${similar}?`));
801
+ console.error(chalk.yellow(`\nDid you mean: caws ${similar}?`));
750
802
  }
751
803
 
752
804
  console.error(
753
- chalk.yellow('šŸ’” Available commands: init, validate, scaffold, provenance, hooks')
805
+ chalk.yellow('Available commands: init, validate, scaffold, provenance, hooks')
754
806
  );
755
- console.error(chalk.yellow('šŸ’” Try: caws --help for full command list'));
807
+ console.error(chalk.yellow('Try: caws --help for full command list'));
756
808
  console.error(
757
809
  chalk.blue(
758
- '\nšŸ“š Documentation: https://github.com/Paths-Design/coding-agent-working-standard/blob/main/docs/api/cli.md'
810
+ '\nDocumentation: https://github.com/Paths-Design/coding-agent-working-standard/blob/main/docs/api/cli.md'
759
811
  )
760
812
  );
761
813
 
@@ -767,20 +819,20 @@ if (require.main === module) {
767
819
  const optionMatch = error.message.match(/unknown option ['"]([^'"]+)['"]/i);
768
820
  const option = optionMatch ? optionMatch[1] : '';
769
821
 
770
- console.error(chalk.red(`\nāŒ Unknown option: ${option}`));
822
+ console.error(chalk.red(`\nUnknown option: ${option}`));
771
823
  console.error(
772
- chalk.yellow(`\nšŸ’” Try: caws ${commandName || ''} --help for available options`)
824
+ chalk.yellow(`\nTry: caws ${commandName || ''} --help for available options`)
773
825
  );
774
826
 
775
827
  // Provide specific suggestions for common mistakes
776
828
  if (option === '--suggestions' || option === '--suggest') {
777
- console.error(chalk.yellow('šŸ’” Note: Validation includes suggestions by default'));
829
+ console.error(chalk.yellow('Note: Validation includes suggestions by default'));
778
830
  console.error(chalk.yellow(' Just run: caws validate'));
779
831
  }
780
832
 
781
833
  console.error(
782
834
  chalk.blue(
783
- '\nšŸ“š Documentation: https://github.com/Paths-Design/coding-agent-working-standard/blob/main/docs/api/cli.md'
835
+ '\nDocumentation: https://github.com/Paths-Design/coding-agent-working-standard/blob/main/docs/api/cli.md'
784
836
  )
785
837
  );
786
838
 
@@ -29,24 +29,24 @@ function showVersion() {
29
29
  * Initialize a new project
30
30
  */
31
31
  async function initProject(projectName, _options) {
32
- console.log(chalk.cyan(`šŸš€ Initializing new CAWS project: ${projectName}`));
32
+ console.log(chalk.cyan(`Initializing new CAWS project: ${projectName}`));
33
33
 
34
34
  try {
35
35
  if (!projectName || projectName.trim() === '') {
36
- console.error(chalk.red('āŒ Project name is required'));
37
- console.error(chalk.blue('šŸ’” Usage: caws init <project-name>'));
36
+ console.error(chalk.red('Project name is required'));
37
+ console.error(chalk.blue('Usage: caws init <project-name>'));
38
38
  process.exit(1);
39
39
  }
40
40
 
41
- console.log(chalk.green('āœ… Project initialization started'));
42
- console.log(chalk.bold('\nšŸ“‹ Configuration Summary:'));
41
+ console.log(chalk.green('Project initialization started'));
42
+ console.log(chalk.bold('\nConfiguration Summary:'));
43
43
  console.log(` ${chalk.cyan('Project')}: ${projectName}`);
44
44
  console.log(` ${chalk.cyan('Status')}: Initialized`);
45
45
 
46
- console.log(chalk.green('\nšŸŽ‰ Project initialized successfully!'));
46
+ console.log(chalk.green('\nProject initialized successfully!'));
47
47
  console.log(chalk.blue('\nFor help: caws --help'));
48
48
  } catch (error) {
49
- console.error(chalk.red('āŒ Error during project initialization:'), error.message);
49
+ console.error(chalk.red('Error during project initialization:'), error.message);
50
50
  process.exit(1);
51
51
  }
52
52
  }
@@ -71,7 +71,7 @@ program.exitOverride((err) => {
71
71
  if (err.code === 'commander.help') {
72
72
  process.exit(0);
73
73
  }
74
- console.error(chalk.red('āŒ Error:'), err.message);
74
+ console.error(chalk.red('Error:'), err.message);
75
75
  process.exit(1);
76
76
  });
77
77
 
@@ -82,7 +82,7 @@ try {
82
82
  if (error.code === 'commander.help' || error.code === 'commander.version') {
83
83
  process.exit(0);
84
84
  } else {
85
- console.error(chalk.red('āŒ Error:'), error.message);
85
+ console.error(chalk.red('Error:'), error.message);
86
86
  process.exit(1);
87
87
  }
88
88
  }
@@ -101,7 +101,7 @@ class PolicyManager {
101
101
  // Warn if using legacy location
102
102
  if (policyPath.endsWith('.json')) {
103
103
  console.warn(
104
- 'āš ļø Using legacy policy file location: .caws/policy/tier-policy.json\n' +
104
+ 'Using legacy policy file location: .caws/policy/tier-policy.json\n' +
105
105
  ' Migrate to .caws/policy.yaml for better compatibility\n' +
106
106
  ' Run: caws init --migrate-policy'
107
107
  );
@@ -46,8 +46,8 @@ async function scaffoldClaudeHooks(projectDir, levels = ['safety', 'quality', 's
46
46
  const claudeHooksTemplateDir = path.join(claudeTemplateDir, 'hooks');
47
47
 
48
48
  if (!fs.existsSync(claudeTemplateDir)) {
49
- console.warn(chalk.yellow('āš ļø Claude Code hooks templates not found'));
50
- console.warn(chalk.blue('šŸ’” Skipping Claude Code hooks setup'));
49
+ console.warn(chalk.yellow('Claude Code hooks templates not found'));
50
+ console.warn(chalk.blue('Skipping Claude Code hooks setup'));
51
51
  return;
52
52
  }
53
53
 
@@ -118,7 +118,7 @@ async function scaffoldClaudeHooks(projectDir, levels = ['safety', 'quality', 's
118
118
  }
119
119
  });
120
120
  } catch (error) {
121
- console.warn(chalk.yellow('āš ļø Could not merge existing settings:'), error.message);
121
+ console.warn(chalk.yellow('Could not merge existing settings:'), error.message);
122
122
  }
123
123
  }
124
124
 
@@ -131,15 +131,15 @@ async function scaffoldClaudeHooks(projectDir, levels = ['safety', 'quality', 's
131
131
  await fs.copy(readmePath, path.join(claudeDir, 'README.md'));
132
132
  }
133
133
 
134
- console.log(chalk.green('āœ… Claude Code hooks configured'));
134
+ console.log(chalk.green('Claude Code hooks configured'));
135
135
  console.log(chalk.gray(` Enabled: ${levels.join(', ')}`));
136
136
  console.log(
137
137
  chalk.gray(` Scripts: ${Array.from(enabledHooks).length} hook scripts installed`)
138
138
  );
139
- console.log(chalk.blue('šŸ’” Hooks will activate on next Claude Code session'));
139
+ console.log(chalk.blue('Hooks will activate on next Claude Code session'));
140
140
  } catch (error) {
141
- console.error(chalk.yellow('āš ļø Failed to setup Claude Code hooks:'), error.message);
142
- console.log(chalk.blue('šŸ’” You can manually copy .claude/ directory later'));
141
+ console.error(chalk.yellow('Failed to setup Claude Code hooks:'), error.message);
142
+ console.log(chalk.blue('You can manually copy .claude/ directory later'));
143
143
  }
144
144
  }
145
145
 
@@ -45,8 +45,8 @@ async function scaffoldCursorHooks(projectDir, levels = ['safety', 'quality', 's
45
45
  const cursorHooksTemplateDir = path.join(cursorTemplateDir, 'hooks');
46
46
 
47
47
  if (!fs.existsSync(cursorTemplateDir)) {
48
- console.warn(chalk.yellow('āš ļø Cursor hooks templates not found'));
49
- console.warn(chalk.blue('šŸ’” Skipping Cursor hooks setup'));
48
+ console.warn(chalk.yellow('Cursor hooks templates not found'));
49
+ console.warn(chalk.blue('Skipping Cursor hooks setup'));
50
50
  return;
51
51
  }
52
52
 
@@ -154,22 +154,22 @@ async function scaffoldCursorHooks(projectDir, levels = ['safety', 'quality', 's
154
154
  await fs.ensureDir(rulesDestDir);
155
155
  await fs.copy(rulesTemplateDir, rulesDestDir);
156
156
  const ruleFiles = fs.readdirSync(rulesTemplateDir).filter((file) => file.endsWith('.mdc'));
157
- console.log(chalk.green('āœ… Cursor rules configured'));
157
+ console.log(chalk.green('Cursor rules configured'));
158
158
  console.log(chalk.gray(` Rules: ${ruleFiles.length} rule files installed`));
159
159
  } catch (error) {
160
- console.warn(chalk.yellow('āš ļø Failed to copy Cursor rules:'), error.message);
160
+ console.warn(chalk.yellow('Failed to copy Cursor rules:'), error.message);
161
161
  }
162
162
  }
163
163
 
164
- console.log(chalk.green('āœ… Cursor hooks configured'));
164
+ console.log(chalk.green('Cursor hooks configured'));
165
165
  console.log(chalk.gray(` Enabled: ${levels.join(', ')}`));
166
166
  console.log(
167
167
  chalk.gray(` Scripts: ${Array.from(enabledHooks).length} hook scripts installed`)
168
168
  );
169
- console.log(chalk.blue('šŸ’” Restart Cursor to activate hooks'));
169
+ console.log(chalk.blue('Restart Cursor to activate hooks'));
170
170
  } catch (error) {
171
- console.error(chalk.yellow('āš ļø Failed to setup Cursor hooks:'), error.message);
172
- console.log(chalk.blue('šŸ’” You can manually copy .cursor/ directory later'));
171
+ console.error(chalk.yellow('Failed to setup Cursor hooks:'), error.message);
172
+ console.log(chalk.blue('You can manually copy .cursor/ directory later'));
173
173
  }
174
174
  }
175
175