@paths.design/caws-cli 8.2.0 → 8.2.3

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 +4 -4
  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
@@ -181,7 +181,7 @@ async function deriveBudget(spec, projectRoot = process.cwd(), options = {}) {
181
181
 
182
182
  if (policyExists) {
183
183
  console.error(
184
- '⚠️ Policy file exists but not loaded: ' +
184
+ 'Policy file exists but not loaded: ' +
185
185
  expectedPath +
186
186
  '\n' +
187
187
  ' Current working directory: ' +
@@ -230,7 +230,7 @@ async function deriveBudget(spec, projectRoot = process.cwd(), options = {}) {
230
230
  // Validate waiver covers budget_limit gate
231
231
  if (!waiver.gates || !waiver.gates.includes('budget_limit')) {
232
232
  console.warn(
233
- `\n⚠️ Waiver ${waiverId} does not cover 'budget_limit' gate\n` +
233
+ `\nWaiver ${waiverId} does not cover 'budget_limit' gate\n` +
234
234
  ` Current gates: [${waiver.gates ? waiver.gates.join(', ') : 'none'}]\n` +
235
235
  ` Add 'budget_limit' to gates array to apply to budget violations\n`
236
236
  );
@@ -363,7 +363,7 @@ function loadWaiver(waiverId, projectRoot) {
363
363
  // Validate ID format before attempting to load
364
364
  if (!/^WV-\d{4}$/.test(waiverId)) {
365
365
  console.error(
366
- `\n❌ Invalid waiver ID format: ${waiverId}\n` +
366
+ `\nInvalid waiver ID format: ${waiverId}\n` +
367
367
  ` Waiver IDs must be exactly 4 digits: WV-0001 through WV-9999\n` +
368
368
  ` Fix waiver_ids in .caws/working-spec.yaml\n`
369
369
  );
@@ -373,7 +373,7 @@ function loadWaiver(waiverId, projectRoot) {
373
373
  const waiverPath = path.join(projectRoot, '.caws', 'waivers', `${waiverId}.yaml`);
374
374
  if (!fs.existsSync(waiverPath)) {
375
375
  console.error(
376
- `\n❌ Waiver file not found: ${waiverId}\n` +
376
+ `\nWaiver file not found: ${waiverId}\n` +
377
377
  ` Expected location: ${waiverPath}\n` +
378
378
  ` Create waiver with: caws waiver create\n`
379
379
  );
@@ -386,13 +386,13 @@ function loadWaiver(waiverId, projectRoot) {
386
386
  try {
387
387
  validateWaiverStructure(waiver);
388
388
  } catch (error) {
389
- console.error(`\n❌ Invalid waiver ${waiverId}: ${error.message}\n`);
389
+ console.error(`\nInvalid waiver ${waiverId}: ${error.message}\n`);
390
390
  return null;
391
391
  }
392
392
 
393
393
  return waiver;
394
394
  } catch (error) {
395
- console.error(`\n❌ Failed to load waiver ${waiverId}: ${error.message}\n`);
395
+ console.error(`\nFailed to load waiver ${waiverId}: ${error.message}\n`);
396
396
  return null;
397
397
  }
398
398
  }
@@ -534,7 +534,7 @@ function isApproachingBudgetLimit(budgetCompliance, threshold = 80) {
534
534
  */
535
535
  function generateBurnupReport(derivedBudget, currentStats) {
536
536
  const report = [
537
- '📊 CAWS Budget Burn-up Report',
537
+ 'CAWS Budget Burn-up Report',
538
538
  '===============================',
539
539
  '',
540
540
  `Risk Tier: ${currentStats.risk_tier}`,
@@ -568,11 +568,11 @@ function generateBurnupReport(derivedBudget, currentStats) {
568
568
  // Add warnings at different thresholds
569
569
  const overall = Math.max(filePercent, locPercent);
570
570
  if (overall >= 95) {
571
- report.push('', '🚫 CRITICAL: Budget nearly exhausted!');
571
+ report.push('', 'CRITICAL: Budget nearly exhausted!');
572
572
  } else if (overall >= 90) {
573
- report.push('', '⚠️ WARNING: Approaching budget limits');
573
+ report.push('', 'WARNING: Approaching budget limits');
574
574
  } else if (overall >= 80) {
575
- report.push('', '⚠️ Notice: 80% of budget used');
575
+ report.push('', 'Notice: 80% of budget used');
576
576
  }
577
577
 
578
578
  return report.join('\n');
@@ -133,7 +133,7 @@ async function validateQualityGates(_changeId) {
133
133
  }
134
134
  } catch {
135
135
  // JSON parsing failed, check for error indicators in output
136
- if (result.includes('') || result.includes('FAIL')) {
136
+ if (result.includes('') || result.includes('FAIL')) {
137
137
  violations.push({ message: 'Quality gates reported failures', output: result });
138
138
  }
139
139
  }
@@ -141,7 +141,7 @@ async function validateQualityGates(_changeId) {
141
141
  // Command failed - check exit code and output
142
142
  if (execError.status !== 0) {
143
143
  const output = execError.stdout || execError.message;
144
- if (output.includes('violations') || output.includes('')) {
144
+ if (output.includes('violations') || output.includes('')) {
145
145
  violations.push({ message: 'Quality gates failed', output: output.substring(0, 500) });
146
146
  }
147
147
  }
@@ -259,7 +259,7 @@ async function archiveChange(change) {
259
259
  // Move change folder to archive
260
260
  await fs.move(change.path, archivePath);
261
261
 
262
- console.log(chalk.green(` Moved to: ${archivePath}`));
262
+ console.log(chalk.green(` Moved to: ${archivePath}`));
263
263
  }
264
264
 
265
265
  /**
@@ -297,9 +297,9 @@ async function updateProvenance(change) {
297
297
  await fs.ensureDir(provenanceDir);
298
298
  await fs.writeFile(chainPath, JSON.stringify(chain, null, 2));
299
299
 
300
- console.log(chalk.green(` Provenance updated: ${chain.length} total entries`));
300
+ console.log(chalk.green(` Provenance updated: ${chain.length} total entries`));
301
301
  } catch (error) {
302
- console.log(chalk.yellow(` ⚠️ Could not update provenance: ${error.message}`));
302
+ console.log(chalk.yellow(` Could not update provenance: ${error.message}`));
303
303
  }
304
304
  }
305
305
 
@@ -310,15 +310,15 @@ async function updateProvenance(change) {
310
310
  * @param {Object} qualityGates - Quality gates result
311
311
  */
312
312
  function displayArchiveResults(change, validation, qualityGates) {
313
- console.log(chalk.bold.cyan(`\n📦 Archiving Change: ${change.id}`));
314
- console.log(chalk.cyan('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n'));
313
+ console.log(chalk.bold.cyan(`\nArchiving Change: ${change.id}`));
314
+ console.log(chalk.cyan('==============================================\n'));
315
315
 
316
316
  // Validation status
317
317
  if (validation.valid) {
318
- console.log(chalk.green('Acceptance Criteria'));
318
+ console.log(chalk.green('Acceptance Criteria'));
319
319
  console.log(chalk.gray(` ${validation.message}`));
320
320
  } else {
321
- console.log(chalk.red('Acceptance Criteria'));
321
+ console.log(chalk.red('Acceptance Criteria'));
322
322
  console.log(chalk.gray(` ${validation.message}`));
323
323
  }
324
324
 
@@ -326,20 +326,20 @@ function displayArchiveResults(change, validation, qualityGates) {
326
326
 
327
327
  // Quality gates status
328
328
  if (qualityGates.valid) {
329
- console.log(chalk.green('Quality Gates'));
329
+ console.log(chalk.green('Quality Gates'));
330
330
  console.log(chalk.gray(` ${qualityGates.message}`));
331
331
  } else {
332
- console.log(chalk.red('Quality Gates'));
332
+ console.log(chalk.red('Quality Gates'));
333
333
  console.log(chalk.gray(` ${qualityGates.message}`));
334
334
  }
335
335
 
336
336
  console.log('');
337
337
 
338
338
  // Archive action
339
- console.log(chalk.blue('📂 Archive Actions:'));
340
- console.log(chalk.gray(' Moving change folder to archive'));
341
- console.log(chalk.gray(' Updating provenance chain'));
342
- console.log(chalk.gray(' Generating change summary'));
339
+ console.log(chalk.blue('Archive Actions:'));
340
+ console.log(chalk.gray(' - Moving change folder to archive'));
341
+ console.log(chalk.gray(' - Updating provenance chain'));
342
+ console.log(chalk.gray(' - Generating change summary'));
343
343
 
344
344
  console.log('');
345
345
  }
@@ -374,7 +374,7 @@ async function archiveCommand(changeId, options = {}) {
374
374
  workingSpec = resolved.spec;
375
375
  } catch (error) {
376
376
  console.log(
377
- chalk.yellow(`⚠️ Could not load spec '${options.specId}': ${error.message}`)
377
+ chalk.yellow(`Could not load spec '${options.specId}': ${error.message}`)
378
378
  );
379
379
  }
380
380
  }
@@ -390,9 +390,9 @@ async function archiveCommand(changeId, options = {}) {
390
390
 
391
391
  // Check if we should proceed with archival
392
392
  if (!validation.valid) {
393
- console.log(chalk.yellow('⚠️ Cannot archive: Incomplete acceptance criteria'));
393
+ console.log(chalk.yellow('Cannot archive: Incomplete acceptance criteria'));
394
394
  if (!options.force) {
395
- console.log(chalk.yellow('💡 Use --force to archive anyway'));
395
+ console.log(chalk.yellow('Use --force to archive anyway'));
396
396
  return outputResult({
397
397
  command: 'archive',
398
398
  change: changeId,
@@ -403,9 +403,9 @@ async function archiveCommand(changeId, options = {}) {
403
403
  }
404
404
 
405
405
  if (!qualityGates.valid) {
406
- console.log(chalk.yellow('⚠️ Cannot archive: Quality gates not met'));
406
+ console.log(chalk.yellow('Cannot archive: Quality gates not met'));
407
407
  if (!options.force) {
408
- console.log(chalk.yellow('💡 Use --force to archive anyway'));
408
+ console.log(chalk.yellow('Use --force to archive anyway'));
409
409
  return outputResult({
410
410
  command: 'archive',
411
411
  change: changeId,
@@ -416,7 +416,7 @@ async function archiveCommand(changeId, options = {}) {
416
416
  }
417
417
 
418
418
  // Perform archival
419
- console.log(chalk.blue('🔄 Performing archival...'));
419
+ console.log(chalk.blue('Performing archival...'));
420
420
 
421
421
  // Update metadata with completion timestamp
422
422
  change.metadata.completed_at = new Date().toISOString();
@@ -433,7 +433,7 @@ async function archiveCommand(changeId, options = {}) {
433
433
  // Update provenance
434
434
  await updateProvenance(change);
435
435
 
436
- console.log(chalk.green(`\n🎉 Successfully archived change: ${changeId}`));
436
+ console.log(chalk.green(`\nSuccessfully archived change: ${changeId}`));
437
437
 
438
438
  return outputResult({
439
439
  command: 'archive',
@@ -93,14 +93,14 @@ async function burnupCommand(specFile) {
93
93
  let specPath = specFile || path.join('.caws', 'working-spec.yaml');
94
94
 
95
95
  if (!fs.existsSync(specPath)) {
96
- console.error(chalk.red(`❌ Spec file not found: ${specPath}`));
96
+ console.error(chalk.red(`Spec file not found: ${specPath}`));
97
97
  process.exit(1);
98
98
  }
99
99
 
100
100
  const specContent = fs.readFileSync(specPath, 'utf8');
101
101
  const spec = yaml.load(specContent);
102
102
 
103
- console.log(chalk.cyan('📊 Generating CAWS budget burn-up report...'));
103
+ console.log(chalk.cyan('Generating CAWS budget burn-up report...'));
104
104
 
105
105
  // Derive budget
106
106
  const derivedBudget = deriveBudget(spec, path.dirname(specPath));
@@ -121,7 +121,7 @@ async function burnupCommand(specFile) {
121
121
  console.log(chalk.gray(` Analyzing changes since: ${gitStats.base_ref}`));
122
122
  } else {
123
123
  // Fallback if git analysis fails (not in a repo or no commits)
124
- console.log(chalk.yellow(' ⚠️ Could not analyze git history, using zero values'));
124
+ console.log(chalk.yellow(' Could not analyze git history, using zero values'));
125
125
  currentStats = {
126
126
  files_changed: 0,
127
127
  lines_changed: 0,
@@ -137,7 +137,7 @@ async function burnupCommand(specFile) {
137
137
  console.log(report);
138
138
 
139
139
  // Show detailed breakdown
140
- console.log(chalk.gray('\n📈 Detailed Budget Analysis:'));
140
+ console.log(chalk.gray('\nDetailed Budget Analysis:'));
141
141
  console.log(
142
142
  chalk.gray(
143
143
  ` Baseline (Tier ${spec.risk_tier}): ${derivedBudget.baseline.max_files} files, ${derivedBudget.baseline.max_loc} LOC`
@@ -174,12 +174,12 @@ async function burnupCommand(specFile) {
174
174
  );
175
175
 
176
176
  if (filePercent > 90 || locPercent > 90) {
177
- console.log(chalk.yellow('\n⚠️ WARNING: Approaching budget limits'));
177
+ console.log(chalk.yellow('\nWARNING: Approaching budget limits'));
178
178
  } else {
179
- console.log(chalk.green('\n✅ Within budget limits'));
179
+ console.log(chalk.green('\nWithin budget limits'));
180
180
  }
181
181
  } catch (error) {
182
- console.error(chalk.red('Error generating burn-up report:'), error.message);
182
+ console.error(chalk.red('Error generating burn-up report:'), error.message);
183
183
  process.exit(1);
184
184
  }
185
185
  }
@@ -295,7 +295,7 @@ async function runDiagnosis() {
295
295
  { name: 'CAWS tools', fn: checkCAWSTools },
296
296
  ];
297
297
 
298
- console.log(chalk.cyan('\n🔍 Diagnosing CAWS Project...\n'));
298
+ console.log(chalk.cyan('\nDiagnosing CAWS Project...\n'));
299
299
  console.log(chalk.gray('Running checks:'));
300
300
 
301
301
  const results = [];
@@ -309,9 +309,9 @@ async function runDiagnosis() {
309
309
  if (result.skipped) {
310
310
  console.log(chalk.gray('skipped'));
311
311
  } else if (result.passed) {
312
- console.log(chalk.green(''));
312
+ console.log(chalk.green(''));
313
313
  } else {
314
- const icon = result.severity === 'high' ? chalk.red('') : chalk.yellow('⚠️');
314
+ const icon = result.severity === 'high' ? chalk.red('') : chalk.yellow('');
315
315
  console.log(icon);
316
316
  }
317
317
 
@@ -320,7 +320,7 @@ async function runDiagnosis() {
320
320
  ...result,
321
321
  });
322
322
  } catch (error) {
323
- console.log(chalk.red(''));
323
+ console.log(chalk.red(''));
324
324
  results.push({
325
325
  name: check.name,
326
326
  passed: false,
@@ -343,16 +343,16 @@ function displayResults(results) {
343
343
  const issues = results.filter((r) => !r.passed && !r.skipped);
344
344
 
345
345
  if (issues.length === 0) {
346
- console.log(chalk.green('\n✅ No issues found! Your CAWS project is healthy.\n'));
346
+ console.log(chalk.green('\nNo issues found! Your CAWS project is healthy.\n'));
347
347
  return;
348
348
  }
349
349
 
350
350
  console.log(
351
- chalk.bold.yellow(`\n⚠️ Found ${issues.length} issue${issues.length > 1 ? 's' : ''}:\n`)
351
+ chalk.bold.yellow(`\nFound ${issues.length} issue${issues.length > 1 ? 's' : ''}:\n`)
352
352
  );
353
353
 
354
354
  issues.forEach((issue, index) => {
355
- const icon = issue.severity === 'high' ? chalk.red('') : chalk.yellow('⚠️');
355
+ const icon = issue.severity === 'high' ? chalk.red('') : chalk.yellow('');
356
356
  const severity = chalk.gray(`[${issue.severity.toUpperCase()}]`);
357
357
 
358
358
  console.log(`${index + 1}. ${icon} ${issue.name} ${severity}`);
@@ -360,7 +360,7 @@ function displayResults(results) {
360
360
  console.log(chalk.cyan(` Fix: ${issue.fix}`));
361
361
 
362
362
  if (issue.autoFixable) {
363
- console.log(chalk.green(' Auto-fix available'));
363
+ console.log(chalk.green(' Auto-fix available'));
364
364
  }
365
365
 
366
366
  // Show additional details if available
@@ -392,7 +392,7 @@ async function applyAutoFixes(results) {
392
392
  const fixableIssues = results.filter((r) => !r.passed && r.autoFixable && r.autoFix);
393
393
 
394
394
  if (fixableIssues.length === 0) {
395
- console.log(chalk.yellow('\n⚠️ No auto-fixable issues found\n'));
395
+ console.log(chalk.yellow('\nNo auto-fixable issues found\n'));
396
396
  return {
397
397
  applied: 0,
398
398
  skipped: 0,
@@ -400,7 +400,7 @@ async function applyAutoFixes(results) {
400
400
  };
401
401
  }
402
402
 
403
- console.log(chalk.cyan(`\n🔧 Applying ${fixableIssues.length} automatic fixes...\n`));
403
+ console.log(chalk.cyan(`\nApplying ${fixableIssues.length} automatic fixes...\n`));
404
404
 
405
405
  let applied = 0;
406
406
  let failed = 0;
@@ -412,7 +412,7 @@ async function applyAutoFixes(results) {
412
412
  const result = await issue.autoFix();
413
413
 
414
414
  if (result.success) {
415
- console.log(chalk.green(''));
415
+ console.log(chalk.green(''));
416
416
  applied++;
417
417
 
418
418
  if (result.nextSteps && result.nextSteps.length > 0) {
@@ -422,16 +422,16 @@ async function applyAutoFixes(results) {
422
422
  });
423
423
  }
424
424
  } else {
425
- console.log(chalk.red(''));
425
+ console.log(chalk.red(''));
426
426
  failed++;
427
427
  }
428
428
  } catch (error) {
429
- console.log(chalk.red(`❌ ${error.message}`));
429
+ console.log(chalk.red(`${error.message}`));
430
430
  failed++;
431
431
  }
432
432
  }
433
433
 
434
- console.log(chalk.bold.green(`\n📊 Results: ${applied} fixed, ${failed} failed\n`));
434
+ console.log(chalk.bold.green(`\nResults: ${applied} fixed, ${failed} failed\n`));
435
435
 
436
436
  return {
437
437
  applied,
@@ -458,7 +458,7 @@ async function diagnoseCommand(options = {}) {
458
458
  if (fixableCount > 0 && !options.fix) {
459
459
  console.log(
460
460
  chalk.yellow(
461
- `💡 ${fixableCount} issue${fixableCount > 1 ? 's' : ''} can be fixed automatically`
461
+ `${fixableCount} issue${fixableCount > 1 ? 's' : ''} can be fixed automatically`
462
462
  )
463
463
  );
464
464
  console.log(chalk.yellow(' Run: caws diagnose --fix to apply fixes\n'));
@@ -466,14 +466,14 @@ async function diagnoseCommand(options = {}) {
466
466
  const fixResults = await applyAutoFixes(results);
467
467
 
468
468
  if (fixResults.applied > 0) {
469
- console.log(chalk.green('Auto-fixes applied successfully'));
470
- console.log(chalk.blue('💡 Run: caws validate to verify fixes\n'));
469
+ console.log(chalk.green('Auto-fixes applied successfully'));
470
+ console.log(chalk.blue('Run: caws validate to verify fixes\n'));
471
471
  }
472
472
 
473
473
  if (fixResults.skipped > 0) {
474
474
  console.log(
475
475
  chalk.yellow(
476
- `⚠️ ${fixResults.skipped} issue${fixResults.skipped > 1 ? 's' : ''} require manual intervention\n`
476
+ `${fixResults.skipped} issue${fixResults.skipped > 1 ? 's' : ''} require manual intervention\n`
477
477
  )
478
478
  );
479
479
  }
@@ -483,17 +483,17 @@ async function diagnoseCommand(options = {}) {
483
483
  const issueCount = results.filter((r) => !r.passed && !r.skipped).length;
484
484
 
485
485
  if (issueCount === 0) {
486
- console.log(chalk.blue('📚 Next steps:'));
487
- console.log(chalk.blue(' Run: caws status --visual to view project health'));
488
- console.log(chalk.blue(' Run: caws validate to check working spec'));
489
- console.log(chalk.blue(' Optional: Create .caws/policy.yaml for custom budgets'));
486
+ console.log(chalk.blue('Next steps:'));
487
+ console.log(chalk.blue(' - Run: caws status --visual to view project health'));
488
+ console.log(chalk.blue(' - Run: caws validate to check working spec'));
489
+ console.log(chalk.blue(' - Optional: Create .caws/policy.yaml for custom budgets'));
490
490
  console.log(
491
- chalk.blue(' Start implementing: caws iterate --current-state "Ready to begin"')
491
+ chalk.blue(' - Start implementing: caws iterate --current-state "Ready to begin"')
492
492
  );
493
493
  }
494
494
  } catch (error) {
495
- console.error(chalk.red('\n❌ Error running diagnosis:'), error.message);
496
- console.error(chalk.yellow('\n💡 Try: caws status for basic health check'));
495
+ console.error(chalk.red('\nError running diagnosis:'), error.message);
496
+ console.error(chalk.yellow('\nTry: caws status for basic health check'));
497
497
  process.exit(1);
498
498
  }
499
499
  }
@@ -21,11 +21,11 @@ const { initializeGlobalSetup } = require('../config');
21
21
  */
22
22
  async function evaluateCommand(specFile = '.caws/working-spec.yaml', options = {}) {
23
23
  try {
24
- console.log('🔍 Detecting CAWS setup...');
24
+ console.log('Detecting CAWS setup...');
25
25
  const setup = initializeGlobalSetup();
26
26
 
27
27
  if (setup.hasWorkingSpec) {
28
- console.log(`✅ Detected ${setup.setupType} CAWS setup`);
28
+ console.log(`Detected ${setup.setupType} CAWS setup`);
29
29
  console.log(` Capabilities: ${setup.capabilities.join(', ')}`);
30
30
  }
31
31
 
@@ -33,16 +33,16 @@ async function evaluateCommand(specFile = '.caws/working-spec.yaml', options = {
33
33
  const specPath = path.isAbsolute(specFile) ? specFile : path.join(process.cwd(), specFile);
34
34
 
35
35
  if (!fs.existsSync(specPath)) {
36
- console.error(chalk.red(`\n❌ Working spec not found: ${specFile}`));
37
- console.error(chalk.yellow('💡 Run: caws init to create a working spec'));
36
+ console.error(chalk.red(`\nWorking spec not found: ${specFile}`));
37
+ console.error(chalk.yellow('Run: caws init to create a working spec'));
38
38
  process.exit(1);
39
39
  }
40
40
 
41
41
  const specContent = fs.readFileSync(specPath, 'utf8');
42
42
  const spec = yaml.load(specContent);
43
43
 
44
- console.log(chalk.blue('\n📊 Evaluating CAWS Quality Standards\n'));
45
- console.log(''.repeat(60));
44
+ console.log(chalk.blue('\nEvaluating CAWS Quality Standards\n'));
45
+ console.log('-'.repeat(60));
46
46
 
47
47
  // Evaluation results
48
48
  const results = {
@@ -181,9 +181,9 @@ async function evaluateCommand(specFile = '.caws/working-spec.yaml', options = {
181
181
  }
182
182
 
183
183
  // Display results
184
- console.log('\n📋 Quality Checks:\n');
184
+ console.log('\nQuality Checks:\n');
185
185
  results.checks.forEach((check) => {
186
- const icon = check.status === 'pass' ? '' : check.status === 'partial' ? '⚠️' : '';
186
+ const icon = check.status === 'pass' ? '' : check.status === 'partial' ? '' : '';
187
187
  const detail = check.detail ? ` (${check.detail})` : '';
188
188
  console.log(
189
189
  `${icon} ${check.name}: ${check.points}/${results.maxScore / results.checks.length}${detail}`
@@ -203,33 +203,33 @@ async function evaluateCommand(specFile = '.caws/working-spec.yaml', options = {
203
203
  ? 'D'
204
204
  : 'F';
205
205
 
206
- console.log('\n' + ''.repeat(60));
206
+ console.log('\n' + '-'.repeat(60));
207
207
  console.log(
208
208
  chalk.bold(
209
- `\n📊 Overall Score: ${results.score}/${results.maxScore} (${percentage}%) - Grade: ${grade}\n`
209
+ `\nOverall Score: ${results.score}/${results.maxScore} (${percentage}%) - Grade: ${grade}\n`
210
210
  )
211
211
  );
212
212
 
213
213
  // Display warnings
214
214
  if (results.warnings.length > 0) {
215
- console.log(chalk.yellow('⚠️ Warnings:\n'));
215
+ console.log(chalk.yellow('Warnings:\n'));
216
216
  results.warnings.forEach((warning) => {
217
- console.log(chalk.yellow(` ${warning}`));
217
+ console.log(chalk.yellow(` - ${warning}`));
218
218
  });
219
219
  console.log();
220
220
  }
221
221
 
222
222
  // Display recommendations
223
223
  if (results.recommendations.length > 0) {
224
- console.log(chalk.blue('💡 Recommendations:\n'));
224
+ console.log(chalk.blue('Recommendations:\n'));
225
225
  results.recommendations.forEach((rec) => {
226
- console.log(chalk.blue(` ${rec}`));
226
+ console.log(chalk.blue(` - ${rec}`));
227
227
  });
228
228
  console.log();
229
229
  }
230
230
 
231
231
  // Risk tier specific guidance
232
- console.log(chalk.bold(`\n🎯 Risk Tier ${spec.risk_tier} Requirements:\n`));
232
+ console.log(chalk.bold(`\nRisk Tier ${spec.risk_tier} Requirements:\n`));
233
233
 
234
234
  const tierRequirements = {
235
235
  1: {
@@ -258,7 +258,7 @@ async function evaluateCommand(specFile = '.caws/working-spec.yaml', options = {
258
258
  console.log(` Contract Tests: ${req.contracts}`);
259
259
  console.log(` Code Review: ${req.review}`);
260
260
 
261
- console.log(chalk.blue('\n📚 Next Steps:\n'));
261
+ console.log(chalk.blue('\nNext Steps:\n'));
262
262
  console.log(' 1. Address warnings and recommendations above');
263
263
  console.log(' 2. Implement acceptance criteria with tests');
264
264
  console.log(' 3. Run: caws validate to check spec validity');
@@ -268,16 +268,16 @@ async function evaluateCommand(specFile = '.caws/working-spec.yaml', options = {
268
268
  // Exit with appropriate code
269
269
  if (percentage < 70) {
270
270
  console.log(
271
- chalk.red('\n⚠️ Quality score below 70% - improvements needed before proceeding\n')
271
+ chalk.red('\nQuality score below 70% - improvements needed before proceeding\n')
272
272
  );
273
273
  process.exit(1);
274
274
  } else if (percentage < 90) {
275
- console.log(chalk.yellow('\n⚠️ Quality score acceptable but improvements recommended\n'));
275
+ console.log(chalk.yellow('\nQuality score acceptable but improvements recommended\n'));
276
276
  } else {
277
- console.log(chalk.green('\n✅ Excellent quality score - ready to proceed!\n'));
277
+ console.log(chalk.green('\nExcellent quality score - ready to proceed!\n'));
278
278
  }
279
279
  } catch (error) {
280
- console.error(chalk.red(`\n❌ Evaluation failed: ${error.message}`));
280
+ console.error(chalk.red(`\nEvaluation failed: ${error.message}`));
281
281
  if (options.verbose) {
282
282
  console.error(error.stack);
283
283
  }