@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
@@ -36,11 +36,11 @@ async function initProject(projectName, options) {
36
36
  const isCurrentDirInit = shouldInitInCurrentDirectory(projectName, currentDir);
37
37
 
38
38
  if (!isCurrentDirInit && projectName !== '.') {
39
- console.log(chalk.cyan(`šŸš€ Initializing new CAWS project: ${projectName}`));
39
+ console.log(chalk.cyan(`Initializing new CAWS project: ${projectName}`));
40
40
  console.log(chalk.gray(` (Creating subdirectory: ${projectName}/)`));
41
41
  } else {
42
42
  console.log(
43
- chalk.cyan(`šŸš€ Initializing CAWS in current project: ${path.basename(currentDir)}`)
43
+ chalk.cyan(`Initializing CAWS in current project: ${path.basename(currentDir)}`)
44
44
  );
45
45
  console.log(chalk.gray(` (Adding CAWS files to existing project)`));
46
46
  }
@@ -50,8 +50,8 @@ async function initProject(projectName, options) {
50
50
  try {
51
51
  // Validate project name
52
52
  if (!projectName || projectName.trim() === '') {
53
- console.error(chalk.red('āŒ Project name is required'));
54
- console.error(chalk.blue('šŸ’” Usage: caws init <project-name>'));
53
+ console.error(chalk.red('Project name is required'));
54
+ console.error(chalk.blue('Usage: caws init <project-name>'));
55
55
  process.exit(1);
56
56
  }
57
57
 
@@ -60,30 +60,30 @@ async function initProject(projectName, options) {
60
60
  // Sanitize project name
61
61
  const sanitizedName = projectName.replace(/[^a-zA-Z0-9-_]/g, '-').toLowerCase();
62
62
  if (sanitizedName !== projectName) {
63
- console.warn(chalk.yellow(`āš ļø Project name sanitized to: ${sanitizedName}`));
63
+ console.warn(chalk.yellow(`Project name sanitized to: ${sanitizedName}`));
64
64
  projectName = sanitizedName;
65
65
  }
66
66
  }
67
67
 
68
68
  // Validate project name length
69
69
  if (projectName.length > 50) {
70
- console.error(chalk.red('āŒ Project name is too long (max 50 characters)'));
71
- console.error(chalk.blue('šŸ’” Usage: caws init <project-name>'));
70
+ console.error(chalk.red('Project name is too long (max 50 characters)'));
71
+ console.error(chalk.blue('Usage: caws init <project-name>'));
72
72
  process.exit(1);
73
73
  }
74
74
 
75
75
  // Validate project name format
76
76
  if (projectName.length === 0) {
77
- console.error(chalk.red('āŒ Project name cannot be empty'));
78
- console.error(chalk.blue('šŸ’” Usage: caws init <project-name>'));
77
+ console.error(chalk.red('Project name cannot be empty'));
78
+ console.error(chalk.blue('Usage: caws init <project-name>'));
79
79
  process.exit(1);
80
80
  }
81
81
 
82
82
  // Check for invalid characters that should cause immediate failure
83
83
  if (projectName.includes('/') || projectName.includes('\\') || projectName.includes('..')) {
84
- console.error(chalk.red('āŒ Project name contains invalid characters'));
85
- console.error(chalk.blue('šŸ’” Usage: caws init <project-name>'));
86
- console.error(chalk.blue('šŸ’” Project name should not contain: / \\ ..'));
84
+ console.error(chalk.red('Project name contains invalid characters'));
85
+ console.error(chalk.blue('Usage: caws init <project-name>'));
86
+ console.error(chalk.blue('Project name should not contain: / \\ ..'));
87
87
  process.exit(1);
88
88
  }
89
89
 
@@ -95,10 +95,10 @@ async function initProject(projectName, options) {
95
95
  if (!initInCurrentDir && fs.existsSync(projectName)) {
96
96
  const existingFiles = fs.readdirSync(projectName);
97
97
  if (existingFiles.length > 0) {
98
- console.error(chalk.red(`āŒ Directory '${projectName}' already exists and contains files`));
99
- console.error(chalk.blue('šŸ’” To initialize CAWS in current directory instead:'));
98
+ console.error(chalk.red(`Directory '${projectName}' already exists and contains files`));
99
+ console.error(chalk.blue('To initialize CAWS in current directory instead:'));
100
100
  console.error(` ${chalk.cyan('caws init .')}`);
101
- console.error(chalk.blue('šŸ’” Or choose a different name/remove existing directory'));
101
+ console.error(chalk.blue('Or choose a different name/remove existing directory'));
102
102
  process.exit(1);
103
103
  }
104
104
  }
@@ -111,9 +111,9 @@ async function initProject(projectName, options) {
111
111
  );
112
112
 
113
113
  if (hasProjectFiles && !options.nonInteractive) {
114
- console.warn(chalk.yellow('āš ļø Current directory contains project files'));
114
+ console.warn(chalk.yellow('Current directory contains project files'));
115
115
  console.warn(
116
- chalk.blue('šŸ’” You might want to initialize CAWS in current directory instead:')
116
+ chalk.blue('You might want to initialize CAWS in current directory instead:')
117
117
  );
118
118
  console.warn(` ${chalk.cyan('caws init .')}`);
119
119
  console.warn(chalk.blue(' Or continue to create subdirectory (Ctrl+C to cancel)'));
@@ -133,9 +133,9 @@ async function initProject(projectName, options) {
133
133
  if (!initInCurrentDir) {
134
134
  await fs.ensureDir(projectName);
135
135
  process.chdir(projectName);
136
- console.log(chalk.green(`šŸ“ Created project directory: ${projectName}`));
136
+ console.log(chalk.green(`Created project directory: ${projectName}`));
137
137
  } else {
138
- console.log(chalk.green(`šŸ“ Initializing in current directory`));
138
+ console.log(chalk.green(`Initializing in current directory`));
139
139
  }
140
140
 
141
141
  // Detect and adapt to existing setup
@@ -145,7 +145,7 @@ async function initProject(projectName, options) {
145
145
  // Create minimal CAWS structure
146
146
  await fs.ensureDir('.caws');
147
147
  await fs.ensureDir('.agent');
148
- console.log(chalk.blue('ā„¹ļø Created basic CAWS structure'));
148
+ console.log(chalk.blue('Created basic CAWS structure'));
149
149
 
150
150
  // Copy AGENTS.md guide if templates are available
151
151
  if (originalTemplateDir) {
@@ -190,12 +190,12 @@ async function initProject(projectName, options) {
190
190
  }
191
191
  } else {
192
192
  // Already has CAWS setup
193
- console.log(chalk.green('āœ… CAWS project detected - skipping template copy'));
193
+ console.log(chalk.green('CAWS project detected - skipping template copy'));
194
194
  }
195
195
 
196
196
  // Handle lite mode init path
197
197
  if (options.mode === 'lite') {
198
- console.log(chalk.magenta('šŸ›”ļø CAWS Lite Mode — guardrails without YAML specs'));
198
+ console.log(chalk.magenta('CAWS Lite Mode — guardrails without YAML specs'));
199
199
 
200
200
  // Detect allowed directories
201
201
  const detectedDirs = [];
@@ -213,13 +213,13 @@ async function initProject(projectName, options) {
213
213
  {
214
214
  type: 'input',
215
215
  name: 'projectName',
216
- message: 'šŸ“ Project name:',
216
+ message: 'Project name:',
217
217
  default: path.basename(process.cwd()),
218
218
  },
219
219
  {
220
220
  type: 'input',
221
221
  name: 'allowedDirs',
222
- message: 'šŸ“ Allowed directories (comma-separated):',
222
+ message: 'Allowed directories (comma-separated):',
223
223
  default: allowedDirs.join(', '),
224
224
  },
225
225
  ]);
@@ -234,25 +234,25 @@ async function initProject(projectName, options) {
234
234
  path.join('.caws', 'scope.json'),
235
235
  JSON.stringify(scopeConfig, null, 2)
236
236
  );
237
- console.log(chalk.green('āœ… Created .caws/scope.json'));
237
+ console.log(chalk.green('Created .caws/scope.json'));
238
238
 
239
239
  // Set mode to lite
240
240
  await setCurrentMode('lite');
241
- console.log(chalk.green('āœ… Set mode to lite in .caws/mode.json'));
241
+ console.log(chalk.green('Set mode to lite in .caws/mode.json'));
242
242
 
243
243
  // Scaffold hooks: block-dangerous + scope-guard + lite-sprawl-check + simplification-guard
244
244
  const liteIDEs = options.ide ? parseIDESelection(options.ide) : ['claude'];
245
245
  if (liteIDEs.includes('claude')) {
246
- console.log(chalk.blue('šŸ”§ Setting up lite-mode hooks...'));
246
+ console.log(chalk.blue('Setting up lite-mode hooks...'));
247
247
  await scaffoldClaudeHooks(process.cwd(), ['safety', 'scope', 'lite']);
248
248
  }
249
249
 
250
250
  // Update .gitignore
251
- console.log(chalk.blue('šŸ“ Updating .gitignore...'));
251
+ console.log(chalk.blue('Updating .gitignore...'));
252
252
  await updateGitignore(process.cwd());
253
253
 
254
254
  // Success
255
- console.log(chalk.green('\nšŸŽ‰ CAWS Lite mode initialized!'));
255
+ console.log(chalk.green('\nCAWS Lite mode initialized!'));
256
256
  console.log(chalk.blue('\nGuardrails active:'));
257
257
  console.log(' - Destructive command blocking (git push --force, rm -rf, etc.)');
258
258
  console.log(' - Scope fencing (edits outside allowed directories require confirmation)');
@@ -267,8 +267,8 @@ async function initProject(projectName, options) {
267
267
 
268
268
  // Handle interactive wizard or template-based setup
269
269
  if (options.interactive && !options.nonInteractive) {
270
- console.log(chalk.cyan('šŸŽÆ CAWS Interactive Setup Wizard'));
271
- console.log(chalk.blue('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'));
270
+ console.log(chalk.cyan('CAWS Interactive Setup Wizard'));
271
+ console.log(chalk.blue('========================================'));
272
272
  console.log(chalk.gray('This wizard will guide you through creating a CAWS working spec\n'));
273
273
 
274
274
  // Detect active IDEs for pre-selecting the IDE prompt
@@ -281,7 +281,7 @@ async function initProject(projectName, options) {
281
281
 
282
282
  // Detect project type
283
283
  const detectedType = detectProjectType(process.cwd());
284
- console.log(chalk.blue(`šŸ“¦ Detected project type: ${chalk.cyan(detectedType)}`));
284
+ console.log(chalk.blue(`Detected project type: ${chalk.cyan(detectedType)}`));
285
285
 
286
286
  // Get package.json info if available
287
287
  let packageJson = {};
@@ -295,50 +295,50 @@ async function initProject(projectName, options) {
295
295
  {
296
296
  type: 'list',
297
297
  name: 'projectType',
298
- message: 'ā“ What type of project is this?',
298
+ message: 'What type of project is this?',
299
299
  choices: [
300
300
  {
301
- name: 'šŸ”Œ VS Code Extension (webview, commands, integrations)',
301
+ name: 'VS Code Extension (webview, commands, integrations)',
302
302
  value: 'extension',
303
303
  short: 'VS Code Extension',
304
304
  },
305
305
  {
306
- name: 'šŸ“š Library/Package (reusable components, utilities)',
306
+ name: 'Library/Package (reusable components, utilities)',
307
307
  value: 'library',
308
308
  short: 'Library',
309
309
  },
310
310
  {
311
- name: '🌐 Web Application (frontend/backend, full-stack)',
311
+ name: 'Web Application (frontend/backend, full-stack)',
312
312
  value: 'application',
313
313
  short: 'Web Application',
314
314
  },
315
315
  {
316
- name: 'šŸ–„ļø CLI Tool (command-line interface, scripts)',
316
+ name: 'CLI Tool (command-line interface, scripts)',
317
317
  value: 'cli',
318
318
  short: 'CLI Tool',
319
319
  },
320
320
  {
321
- name: 'šŸ“± Mobile App (iOS/Android, React Native, etc.)',
321
+ name: 'Mobile App (iOS/Android, React Native, etc.)',
322
322
  value: 'mobile',
323
323
  short: 'Mobile App',
324
324
  },
325
325
  {
326
- name: 'šŸ› ļø Infrastructure (DevOps, deployment, cloud)',
326
+ name: 'Infrastructure (DevOps, deployment, cloud)',
327
327
  value: 'infrastructure',
328
328
  short: 'Infrastructure',
329
329
  },
330
330
  {
331
- name: 'šŸ“Š Data/Analytics (ETL, ML, dashboards)',
331
+ name: 'Data/Analytics (ETL, ML, dashboards)',
332
332
  value: 'data',
333
333
  short: 'Data/Analytics',
334
334
  },
335
335
  {
336
- name: 'šŸŽ® Game Development (Unity, Godot, custom engine)',
336
+ name: 'Game Development (Unity, Godot, custom engine)',
337
337
  value: 'game',
338
338
  short: 'Game',
339
339
  },
340
340
  {
341
- name: 'šŸ”§ Other/Custom (please specify)',
341
+ name: 'Other/Custom (please specify)',
342
342
  value: 'other',
343
343
  short: 'Other',
344
344
  },
@@ -348,7 +348,7 @@ async function initProject(projectName, options) {
348
348
  {
349
349
  type: 'input',
350
350
  name: 'projectTitle',
351
- message: 'šŸ“ What is the project title?',
351
+ message: 'What is the project title?',
352
352
  default: packageJson.name || path.basename(process.cwd()),
353
353
  validate: (input) => {
354
354
  if (input.trim().length < 3) {
@@ -363,7 +363,7 @@ async function initProject(projectName, options) {
363
363
  {
364
364
  type: 'input',
365
365
  name: 'projectDescription',
366
- message: 'šŸ“– Provide a brief project description (1-2 sentences):',
366
+ message: 'Provide a brief project description (1-2 sentences):',
367
367
  default: packageJson.description || '',
368
368
  validate: (input) => {
369
369
  if (input.trim().length < 10) {
@@ -378,20 +378,20 @@ async function initProject(projectName, options) {
378
378
  {
379
379
  type: 'list',
380
380
  name: 'riskTier',
381
- message: 'āš ļø What risk tier does this project fall into?',
381
+ message: 'What risk tier does this project fall into?',
382
382
  choices: [
383
383
  {
384
- name: 'šŸ”“ Tier 1 - High Risk (auth, billing, migrations, critical infrastructure)',
384
+ name: 'Tier 1 - High Risk (auth, billing, migrations, critical infrastructure)',
385
385
  value: 1,
386
386
  short: 'High Risk (T1)',
387
387
  },
388
388
  {
389
- name: '🟔 Tier 2 - Medium Risk (features, APIs, data writes)',
389
+ name: 'Tier 2 - Medium Risk (features, APIs, data writes)',
390
390
  value: 2,
391
391
  short: 'Medium Risk (T2)',
392
392
  },
393
393
  {
394
- name: '🟢 Tier 3 - Low Risk (UI, internal tools, docs)',
394
+ name: 'Tier 3 - Low Risk (UI, internal tools, docs)',
395
395
  value: 3,
396
396
  short: 'Low Risk (T3)',
397
397
  },
@@ -401,7 +401,7 @@ async function initProject(projectName, options) {
401
401
  {
402
402
  type: 'input',
403
403
  name: 'projectId',
404
- message: 'šŸ†” Project ID (e.g., PROJ-001, FEAT-123):',
404
+ message: 'Project ID (e.g., PROJ-001, FEAT-123):',
405
405
  default: () => {
406
406
  const randomNum = Math.floor(Math.random() * 1000) + 1;
407
407
  return `PROJ-${randomNum.toString().padStart(3, '0')}`;
@@ -480,7 +480,7 @@ async function initProject(projectName, options) {
480
480
  {
481
481
  type: 'confirm',
482
482
  name: 'generateExamples',
483
- message: 'šŸ“‹ Generate example code and documentation?',
483
+ message: 'Generate example code and documentation?',
484
484
  default: true,
485
485
  },
486
486
  ];
@@ -489,13 +489,13 @@ async function initProject(projectName, options) {
489
489
  answers = await inquirer.prompt(wizardQuestions);
490
490
 
491
491
  // Generate working spec
492
- console.log(chalk.blue('\nšŸ“„ Generating CAWS working spec...'));
492
+ console.log(chalk.blue('\nGenerating CAWS working spec...'));
493
493
  const specContent = generateWorkingSpec(answers);
494
494
 
495
495
  // Write working spec
496
496
  await fs.ensureDir('.caws');
497
497
  await fs.writeFile(path.join('.caws', 'working-spec.yaml'), specContent);
498
- console.log(chalk.green('āœ… Created .caws/working-spec.yaml'));
498
+ console.log(chalk.green('Created .caws/working-spec.yaml'));
499
499
 
500
500
  // Optionally create policy.yaml (optional - defaults work fine)
501
501
  const policyPath = path.join('.caws', 'policy.yaml');
@@ -506,12 +506,12 @@ async function initProject(projectName, options) {
506
506
  const yaml = require('js-yaml');
507
507
  const policyContent = yaml.dump(defaultPolicy, { indent: 2 });
508
508
  await fs.writeFile(policyPath, policyContent);
509
- console.log(chalk.green('āœ… Created .caws/policy.yaml (optional - defaults work fine)'));
509
+ console.log(chalk.green('Created .caws/policy.yaml (optional - defaults work fine)'));
510
510
  }
511
511
 
512
512
  // Generate additional files if requested
513
513
  if (answers.generateExamples) {
514
- console.log(chalk.blue('šŸ“ Generating example files...'));
514
+ console.log(chalk.blue('Generating example files...'));
515
515
 
516
516
  // Generate .caws/getting-started.md
517
517
  const gettingStartedGuide = `# ${answers.projectTitle} - Getting Started
@@ -532,11 +532,10 @@ ${answers.projectDescription}
532
532
  - **Mutation Score**: ${answers.riskTier === 1 ? '70%+' : answers.riskTier === 2 ? '50%+' : '30%+'}
533
533
  - **Review**: ${answers.riskTier === 1 ? 'Manual' : 'Optional'}
534
534
 
535
- Happy coding! šŸŽÆ
536
- `;
535
+ Happy coding! `;
537
536
 
538
537
  await fs.writeFile(path.join('.caws', 'getting-started.md'), gettingStartedGuide);
539
- console.log(chalk.green('āœ… Created .caws/getting-started.md'));
538
+ console.log(chalk.green('Created .caws/getting-started.md'));
540
539
 
541
540
  // Generate basic directory structure
542
541
  await fs.ensureDir('tests');
@@ -544,7 +543,7 @@ Happy coding! šŸŽÆ
544
543
  await fs.ensureDir('tests/integration');
545
544
  await fs.ensureDir('tests/e2e');
546
545
  await fs.ensureDir('docs');
547
- console.log(chalk.green('āœ… Created test and docs directories'));
546
+ console.log(chalk.green('Created test and docs directories'));
548
547
  }
549
548
 
550
549
  // Setup selected IDE integrations
@@ -563,10 +562,10 @@ Happy coding! šŸŽÆ
563
562
  }
564
563
 
565
564
  // Update .gitignore to exclude CAWS local runtime files
566
- console.log(chalk.blue('šŸ“ Updating .gitignore...'));
565
+ console.log(chalk.blue('Updating .gitignore...'));
567
566
  const gitignoreUpdated = await updateGitignore(process.cwd());
568
567
  if (gitignoreUpdated) {
569
- console.log(chalk.green('āœ… Updated .gitignore to exclude CAWS local runtime files'));
568
+ console.log(chalk.green('Updated .gitignore to exclude CAWS local runtime files'));
570
569
  console.log(
571
570
  chalk.gray(' Tracked: Specs, policy, waivers, provenance, plans (shared with team)')
572
571
  );
@@ -577,7 +576,7 @@ Happy coding! šŸŽÆ
577
576
  await finalizeProject(projectName, options, answers);
578
577
  } else {
579
578
  // Non-interactive mode - generate basic spec with defaults
580
- console.log(chalk.blue('šŸ“„ Generating basic CAWS working spec...'));
579
+ console.log(chalk.blue('Generating basic CAWS working spec...'));
581
580
 
582
581
  const detectedType = detectProjectType(process.cwd());
583
582
  const defaultAnswers = {
@@ -626,7 +625,7 @@ Happy coding! šŸŽÆ
626
625
  const specContent = generateWorkingSpec(defaultAnswers);
627
626
  await fs.ensureDir('.caws');
628
627
  await fs.writeFile(path.join('.caws', 'working-spec.yaml'), specContent);
629
- console.log(chalk.green('āœ… Created .caws/working-spec.yaml'));
628
+ console.log(chalk.green('Created .caws/working-spec.yaml'));
630
629
 
631
630
  // Optionally create policy.yaml (optional - defaults work fine)
632
631
  const policyPath = path.join('.caws', 'policy.yaml');
@@ -637,7 +636,7 @@ Happy coding! šŸŽÆ
637
636
  const yaml = require('js-yaml');
638
637
  const policyContent = yaml.dump(defaultPolicy, { indent: 2 });
639
638
  await fs.writeFile(policyPath, policyContent);
640
- console.log(chalk.green('āœ… Created .caws/policy.yaml (optional - defaults work fine)'));
639
+ console.log(chalk.green('Created .caws/policy.yaml (optional - defaults work fine)'));
641
640
  }
642
641
 
643
642
  // Setup IDE integrations based on --ide flag or auto-detection
@@ -654,10 +653,10 @@ Happy coding! šŸŽÆ
654
653
  }
655
654
 
656
655
  // Update .gitignore to exclude CAWS local runtime files
657
- console.log(chalk.blue('šŸ“ Updating .gitignore...'));
656
+ console.log(chalk.blue('Updating .gitignore...'));
658
657
  const gitignoreUpdated = await updateGitignore(process.cwd());
659
658
  if (gitignoreUpdated) {
660
- console.log(chalk.green('āœ… Updated .gitignore to exclude CAWS local runtime files'));
659
+ console.log(chalk.green('Updated .gitignore to exclude CAWS local runtime files'));
661
660
  console.log(
662
661
  chalk.gray(' Tracked: Specs, policy, waivers, provenance, plans (shared with team)')
663
662
  );
@@ -669,7 +668,7 @@ Happy coding! šŸŽÆ
669
668
  }
670
669
 
671
670
  // Success message
672
- console.log(chalk.green('\nšŸŽ‰ CAWS project initialized successfully!'));
671
+ console.log(chalk.green('\nCAWS project initialized successfully!'));
673
672
  console.log(chalk.blue('\nNext steps:'));
674
673
  console.log('1. Review .caws/working-spec.yaml');
675
674
  console.log('2. Customize the specification for your needs');
@@ -678,7 +677,7 @@ Happy coding! šŸŽÆ
678
677
  // Use answers if available (interactive mode), otherwise default to 2
679
678
  const riskTier = answers?.riskTier || 2;
680
679
  if (riskTier === 1 || riskTier === 2) {
681
- console.log(chalk.yellow('\nāš ļø Important: Contract Requirements'));
680
+ console.log(chalk.yellow('\nImportant: Contract Requirements'));
682
681
  console.log(` Tier ${riskTier} changes require at least one contract.`);
683
682
  console.log(' For infrastructure/setup work, add a minimal contract:');
684
683
  console.log(chalk.gray(' contracts:'));
@@ -688,7 +687,7 @@ Happy coding! šŸŽÆ
688
687
  console.log(' Or use "chore" mode for maintenance work (mode: chore)');
689
688
  }
690
689
 
691
- console.log('\nšŸ“‹ Recommended Setup Workflow:');
690
+ console.log('\nRecommended Setup Workflow:');
692
691
  console.log(' 1. Review .caws/working-spec.yaml');
693
692
  console.log(' 2. Run: caws scaffold (adds tools and templates)');
694
693
  console.log(' 3. Run: caws validate (verify setup)');
@@ -698,9 +697,9 @@ Happy coding! šŸŽÆ
698
697
  if (finalIDEs.includes('cursor') || finalIDEs.includes('claude') || options.interactive === false) {
699
698
  console.log(' 6. Restart your IDE to activate quality gates');
700
699
  }
701
- console.log('\nšŸ’” Quick start: caws scaffold && caws validate && caws diagnose');
700
+ console.log('\nQuick start: caws scaffold && caws validate && caws diagnose');
702
701
  } catch (error) {
703
- console.error(chalk.red('āŒ Error during initialization:'), error.message);
702
+ console.error(chalk.red('Error during initialization:'), error.message);
704
703
  if (error.stack) {
705
704
  console.error(chalk.gray(error.stack));
706
705
  }
@@ -709,10 +708,10 @@ Happy coding! šŸŽÆ
709
708
  if (projectName && projectName !== '.' && fs.existsSync(projectName)) {
710
709
  try {
711
710
  await fs.remove(projectName);
712
- console.log(chalk.green('āœ… Cleanup completed'));
711
+ console.log(chalk.green('Cleanup completed'));
713
712
  } catch (cleanupError) {
714
713
  console.warn(
715
- chalk.yellow('āš ļø Could not clean up:'),
714
+ chalk.yellow('Could not clean up:'),
716
715
  cleanupError?.message || cleanupError
717
716
  );
718
717
  }
@@ -32,11 +32,11 @@ async function iterateCommand(specFile = '.caws/working-spec.yaml', options = {}
32
32
 
33
33
  const { spec } = resolved;
34
34
 
35
- console.log('šŸ” Detecting CAWS setup...');
35
+ console.log('Detecting CAWS setup...');
36
36
  const setup = initializeGlobalSetup();
37
37
 
38
38
  if (setup.hasWorkingSpec) {
39
- console.log(`āœ… Detected ${setup.setupType} CAWS setup`);
39
+ console.log(`Detected ${setup.setupType} CAWS setup`);
40
40
  console.log(` Capabilities: ${setup.capabilities.join(', ')}`);
41
41
  }
42
42
 
@@ -44,8 +44,8 @@ async function iterateCommand(specFile = '.caws/working-spec.yaml', options = {}
44
44
  const currentState = options.currentState ? JSON.parse(options.currentState) : {};
45
45
  const stateDescription = currentState.description || 'Starting implementation';
46
46
 
47
- console.log(chalk.blue('\nšŸ”„ Iterative Development Guidance\n'));
48
- console.log('─'.repeat(60));
47
+ console.log(chalk.blue('\nIterative Development Guidance\n'));
48
+ console.log('-'.repeat(60));
49
49
  console.log(chalk.bold(`\nProject: ${spec.title}`));
50
50
  console.log(`ID: ${spec.id} | Tier: ${spec.risk_tier} | Mode: ${spec.mode}`);
51
51
  console.log(`Current State: ${stateDescription}\n`);
@@ -54,34 +54,34 @@ async function iterateCommand(specFile = '.caws/working-spec.yaml', options = {}
54
54
  const guidance = generateGuidance(spec, currentState, options);
55
55
 
56
56
  // Display guidance
57
- console.log(chalk.blue('šŸ“‹ Current Phase:\n'));
57
+ console.log(chalk.blue('Current Phase:\n'));
58
58
  console.log(` ${guidance.phase}\n`);
59
59
 
60
- console.log(chalk.blue('āœ… Completed Steps:\n'));
60
+ console.log(chalk.blue('Completed Steps:\n'));
61
61
  guidance.completed.forEach((step) => {
62
- console.log(chalk.green(` āœ“ ${step}`));
62
+ console.log(chalk.green(` [done] ${step}`));
63
63
  });
64
64
 
65
- console.log(chalk.blue('\nšŸŽÆ Next Actions:\n'));
65
+ console.log(chalk.blue('\nNext Actions:\n'));
66
66
  guidance.nextActions.forEach((action, index) => {
67
67
  console.log(chalk.yellow(` ${index + 1}. ${action}`));
68
68
  });
69
69
 
70
70
  if (guidance.blockers.length > 0) {
71
- console.log(chalk.red('\nāš ļø Blockers:\n'));
71
+ console.log(chalk.red('\nBlockers:\n'));
72
72
  guidance.blockers.forEach((blocker) => {
73
- console.log(chalk.red(` āš ļø ${blocker}`));
73
+ console.log(chalk.red(` ${blocker}`));
74
74
  });
75
75
  }
76
76
 
77
- console.log(chalk.blue('\nšŸ’” Recommendations:\n'));
77
+ console.log(chalk.blue('\nRecommendations:\n'));
78
78
  guidance.recommendations.forEach((rec) => {
79
- console.log(chalk.blue(` • ${rec}`));
79
+ console.log(chalk.blue(` - ${rec}`));
80
80
  });
81
81
 
82
82
  // Acceptance criteria checklist with detailed progress
83
83
  if (spec.acceptance && spec.acceptance.length > 0) {
84
- console.log(chalk.blue('\nšŸ“Š Acceptance Criteria Progress:\n'));
84
+ console.log(chalk.blue('\nAcceptance Criteria Progress:\n'));
85
85
 
86
86
  let totalTestsWritten = 0;
87
87
  let totalTestsPassing = 0;
@@ -90,21 +90,21 @@ async function iterateCommand(specFile = '.caws/working-spec.yaml', options = {}
90
90
 
91
91
  spec.acceptance.forEach((criterion, _index) => {
92
92
  // Support both old format (boolean completed) and new format (detailed progress)
93
- let status = '⬜';
93
+ let status = '';
94
94
  let progressInfo = '';
95
95
 
96
96
  if (criterion.status) {
97
97
  // New detailed format
98
98
  switch (criterion.status) {
99
99
  case 'completed':
100
- status = 'āœ…';
100
+ status = '';
101
101
  break;
102
102
  case 'in_progress':
103
- status = 'šŸ”„';
103
+ status = '';
104
104
  break;
105
105
  case 'pending':
106
106
  default:
107
- status = '⬜';
107
+ status = '';
108
108
  break;
109
109
  }
110
110
 
@@ -133,7 +133,7 @@ async function iterateCommand(specFile = '.caws/working-spec.yaml', options = {}
133
133
  }
134
134
  } else if (criterion.completed) {
135
135
  // Backward compatibility with old boolean format
136
- status = 'āœ…';
136
+ status = '';
137
137
  }
138
138
 
139
139
  console.log(` ${status} ${criterion.id}: ${criterion.then}`);
@@ -175,13 +175,13 @@ async function iterateCommand(specFile = '.caws/working-spec.yaml', options = {}
175
175
  }
176
176
 
177
177
  // Quality gates reminder
178
- console.log(chalk.blue('\nšŸ”’ Quality Gates (Risk Tier ' + spec.risk_tier + '):\n'));
178
+ console.log(chalk.blue('\nQuality Gates (Risk Tier ' + spec.risk_tier + '):\n'));
179
179
  const gates = getQualityGates(spec.risk_tier);
180
180
  gates.forEach((gate) => {
181
181
  console.log(` ā–” ${gate}`);
182
182
  });
183
183
 
184
- console.log(chalk.blue('\nšŸ“š Useful Commands:\n'));
184
+ console.log(chalk.blue('\nUseful Commands:\n'));
185
185
  console.log(' caws evaluate - Check quality score');
186
186
  console.log(' caws validate - Validate working spec');
187
187
  console.log(' caws status - View project health');
@@ -189,7 +189,7 @@ async function iterateCommand(specFile = '.caws/working-spec.yaml', options = {}
189
189
  console.log(' npm test - Run test suite');
190
190
  console.log(' npm run coverage - Check test coverage\n');
191
191
  } catch (error) {
192
- console.error(chalk.red(`\nāŒ Iteration guidance failed: ${error.message}`));
192
+ console.error(chalk.red(`\nIteration guidance failed: ${error.message}`));
193
193
  if (options.verbose) {
194
194
  console.error(error.stack);
195
195
  }
@@ -23,8 +23,8 @@ const {
23
23
  function displayCurrentMode(currentMode) {
24
24
  const tier = getTier(currentMode);
25
25
 
26
- console.log(chalk.bold.cyan('\nšŸ”§ CAWS Current Mode'));
27
- console.log(chalk.cyan('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n'));
26
+ console.log(chalk.bold.cyan('\nCAWS Current Mode'));
27
+ console.log(chalk.cyan('==============================================\n'));
28
28
 
29
29
  console.log(chalk.bold(`Active Mode: ${tier.icon} ${tier.color(currentMode)}`));
30
30
  console.log(chalk.gray(`Description: ${tier.description}`));
@@ -56,8 +56,8 @@ function displayModeDetails(mode) {
56
56
  const tierColor = tier.color;
57
57
  const icon = tier.icon;
58
58
 
59
- console.log(chalk.bold.cyan(`\nšŸ“‹ ${icon} ${tierColor(tier.name)} Mode Details`));
60
- console.log(chalk.cyan('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n'));
59
+ console.log(chalk.bold.cyan(`\n${icon} ${tierColor(tier.name)} Mode Details`));
60
+ console.log(chalk.cyan('=================================================================\n'));
61
61
 
62
62
  console.log(`${tierColor(tier.name)} - ${tier.description}\n`);
63
63
 
@@ -81,7 +81,7 @@ function displayModeDetails(mode) {
81
81
  Object.entries(tier.commands)
82
82
  .filter(([, available]) => available)
83
83
  .forEach(([command]) => {
84
- console.log(chalk.gray(` āœ… caws ${command}`));
84
+ console.log(chalk.gray(` caws ${command}`));
85
85
  });
86
86
 
87
87
  const disabledCommands = Object.entries(tier.commands)
@@ -91,7 +91,7 @@ function displayModeDetails(mode) {
91
91
  if (disabledCommands.length > 0) {
92
92
  console.log(chalk.bold('\nDisabled Commands:'));
93
93
  disabledCommands.forEach((command) => {
94
- console.log(chalk.gray(` āŒ caws ${command}`));
94
+ console.log(chalk.gray(` caws ${command}`));
95
95
  });
96
96
  }
97
97
 
@@ -111,8 +111,8 @@ async function interactiveModeSelection() {
111
111
  });
112
112
 
113
113
  return new Promise((resolve) => {
114
- console.log(chalk.bold.cyan('\nšŸ”§ Select CAWS Complexity Tier'));
115
- console.log(chalk.cyan('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n'));
114
+ console.log(chalk.bold.cyan('\nSelect CAWS Complexity Tier'));
115
+ console.log(chalk.cyan('==============================================\n'));
116
116
 
117
117
  const tiers = getAvailableTiers();
118
118
  tiers.forEach((tier, index) => {
@@ -180,7 +180,7 @@ async function modeCommand(action, options = {}) {
180
180
 
181
181
  console.log(
182
182
  chalk.green(
183
- `āœ… Successfully switched to ${getTier(targetMode).icon} ${getTier(targetMode).color(targetMode)} mode`
183
+ `Successfully switched to ${getTier(targetMode).icon} ${getTier(targetMode).color(targetMode)} mode`
184
184
  )
185
185
  );
186
186
 
@@ -210,8 +210,8 @@ async function modeCommand(action, options = {}) {
210
210
  const recommendation = getTierRecommendation(projectInfo);
211
211
  const recommendedTier = getTier(recommendation);
212
212
 
213
- console.log(chalk.bold.cyan('\nšŸŽÆ Recommended CAWS Tier'));
214
- console.log(chalk.cyan('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n'));
213
+ console.log(chalk.bold.cyan('\nRecommended CAWS Tier'));
214
+ console.log(chalk.cyan('==============================================\n'));
215
215
 
216
216
  console.log(
217
217
  `${recommendedTier.icon} ${recommendedTier.color(recommendedTier.name)} - ${recommendedTier.description}`