@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
@@ -81,7 +81,7 @@ const Output = {
81
81
  true
82
82
  );
83
83
  } else {
84
- console.log(chalk.green(`✅ ${message}`));
84
+ console.log(chalk.green(`${message}`));
85
85
  if (Object.keys(data).length > 0 && !isJsonOutput()) {
86
86
  console.log(chalk.gray(JSON.stringify(data, null, 2)));
87
87
  }
@@ -106,9 +106,9 @@ const Output = {
106
106
  false
107
107
  );
108
108
  } else {
109
- console.error(chalk.red(`❌ ${message}`));
109
+ console.error(chalk.red(`${message}`));
110
110
  if (suggestions.length > 0) {
111
- console.error(chalk.yellow('\n💡 Suggestions:'));
111
+ console.error(chalk.yellow('\nSuggestions:'));
112
112
  suggestions.forEach((suggestion) => {
113
113
  console.error(chalk.yellow(` ${suggestion}`));
114
114
  });
@@ -132,9 +132,9 @@ const Output = {
132
132
  true
133
133
  );
134
134
  } else {
135
- console.warn(chalk.yellow(`⚠️ ${message}`));
135
+ console.warn(chalk.yellow(`${message}`));
136
136
  if (suggestion) {
137
- console.warn(chalk.blue(` 💡 ${suggestion}`));
137
+ console.warn(chalk.blue(` ${suggestion}`));
138
138
  }
139
139
  }
140
140
  },
@@ -155,7 +155,7 @@ const Output = {
155
155
  true
156
156
  );
157
157
  } else {
158
- console.log(chalk.blue(`ℹ️ ${message}`));
158
+ console.log(chalk.blue(`${message}`));
159
159
  if (Object.keys(data).length > 0) {
160
160
  console.log(chalk.gray(JSON.stringify(data, null, 2)));
161
161
  }
@@ -177,7 +177,7 @@ const Output = {
177
177
  */
178
178
  progress(message) {
179
179
  if (!isJsonOutput()) {
180
- console.log(chalk.blue(`🔄 ${message}`));
180
+ console.log(chalk.blue(`${message}`));
181
181
  }
182
182
  },
183
183
 
@@ -188,7 +188,7 @@ const Output = {
188
188
  section(title) {
189
189
  if (!isJsonOutput()) {
190
190
  console.log(chalk.bold(`\n${title}`));
191
- console.log(''.repeat(Math.min(title.length, 60)));
191
+ console.log('-'.repeat(Math.min(title.length, 60)));
192
192
  }
193
193
  },
194
194
  };
@@ -40,7 +40,7 @@ function detectCAWSSetup(cwd = process.cwd()) {
40
40
  process.argv.includes('--help');
41
41
 
42
42
  if (!isQuietCommand) {
43
- console.log(chalk.blue('🔍 Detecting CAWS setup...'));
43
+ console.log(chalk.blue('Detecting CAWS setup...'));
44
44
  }
45
45
 
46
46
  // Check for existing CAWS setup
@@ -49,7 +49,7 @@ function detectCAWSSetup(cwd = process.cwd()) {
49
49
 
50
50
  if (!hasCAWSDir) {
51
51
  if (!isQuietCommand) {
52
- console.log(chalk.gray('ℹ️ No .caws directory found - new project setup'));
52
+ console.log(chalk.gray('No .caws directory found - new project setup'));
53
53
  }
54
54
  return {
55
55
  type: 'new',
@@ -107,7 +107,7 @@ function detectCAWSSetup(cwd = process.cwd()) {
107
107
  }
108
108
 
109
109
  if (!isQuietCommand) {
110
- console.log(chalk.green(`✅ Detected ${setupType} CAWS setup`));
110
+ console.log(chalk.green(`Detected ${setupType} CAWS setup`));
111
111
  console.log(chalk.gray(` Capabilities: ${capabilities.join(', ')}`));
112
112
  }
113
113
 
@@ -160,7 +160,7 @@ function detectCAWSSetup(cwd = process.cwd()) {
160
160
  if (fs.existsSync(testPath)) {
161
161
  templateDir = testPath;
162
162
  if (!isQuietCommand) {
163
- console.log(`✅ Found CAWS templates in ${source}:`);
163
+ console.log(`Found CAWS templates in ${source}:`);
164
164
  console.log(` ${chalk.gray(testPath)}`);
165
165
  }
166
166
  break;
@@ -168,10 +168,10 @@ function detectCAWSSetup(cwd = process.cwd()) {
168
168
  }
169
169
 
170
170
  if (!templateDir && !isQuietCommand) {
171
- console.warn(chalk.yellow('⚠️ CAWS templates not found in standard locations'));
172
- console.warn(chalk.blue('💡 This may limit available scaffolding features'));
171
+ console.warn(chalk.yellow('CAWS templates not found in standard locations'));
172
+ console.warn(chalk.blue('This may limit available scaffolding features'));
173
173
  console.warn(
174
- chalk.blue('💡 For full functionality, ensure caws-template package is available')
174
+ chalk.blue('For full functionality, ensure caws-template package is available')
175
175
  );
176
176
  }
177
177
 
@@ -37,11 +37,11 @@ async function finalizeProject(projectName, options, answers) {
37
37
  try {
38
38
  // Detect and configure language support
39
39
  if (languageSupport) {
40
- console.log(chalk.cyan('🔍 Detecting project language...'));
40
+ console.log(chalk.cyan('Detecting project language...'));
41
41
  const detectedLanguage = languageSupport.detectProjectLanguage();
42
42
 
43
43
  if (detectedLanguage !== 'unknown') {
44
- console.log(chalk.green(`✅ Detected language: ${detectedLanguage}`));
44
+ console.log(chalk.green(`Detected language: ${detectedLanguage}`));
45
45
 
46
46
  // Generate language-specific configuration
47
47
  try {
@@ -50,25 +50,25 @@ async function finalizeProject(projectName, options, answers) {
50
50
  '.caws/language-config.json'
51
51
  );
52
52
 
53
- console.log(chalk.green('Generated language-specific configuration'));
53
+ console.log(chalk.green('Generated language-specific configuration'));
54
54
  console.log(` Language: ${langConfig.name}`);
55
55
  console.log(` Tier: ${langConfig.tier}`);
56
56
  console.log(
57
57
  ` Thresholds: Branch ≥${langConfig.thresholds.min_branch * 100}%, Mutation ≥${langConfig.thresholds.min_mutation * 100}%`
58
58
  );
59
59
  } catch (langError) {
60
- console.warn(chalk.yellow('⚠️ Could not generate language config:'), langError.message);
60
+ console.warn(chalk.yellow('Could not generate language config:'), langError.message);
61
61
  }
62
62
  } else {
63
63
  console.log(
64
- chalk.blue('ℹ️ Could not detect project language - using default configuration')
64
+ chalk.blue('Could not detect project language - using default configuration')
65
65
  );
66
66
  }
67
67
  }
68
68
 
69
69
  // Setup Cursor hooks if enabled
70
70
  if (answers && answers.enableCursorHooks) {
71
- console.log(chalk.cyan('📌 Setting up Cursor hooks...'));
71
+ console.log(chalk.cyan('Setting up Cursor hooks...'));
72
72
  await scaffoldCursorHooks(
73
73
  process.cwd(),
74
74
  answers.cursorHookLevels || ['safety', 'quality', 'scope', 'audit']
@@ -76,7 +76,7 @@ async function finalizeProject(projectName, options, answers) {
76
76
  }
77
77
 
78
78
  // Generate provenance manifest
79
- console.log(chalk.cyan('📦 Generating provenance manifest...'));
79
+ console.log(chalk.cyan('Generating provenance manifest...'));
80
80
 
81
81
  const provenanceData = {
82
82
  agent: 'caws-cli',
@@ -118,24 +118,24 @@ async function finalizeProject(projectName, options, answers) {
118
118
  ) {
119
119
  const provenance = tools.generateProvenance(provenanceData);
120
120
  await tools.saveProvenance(provenance, '.agent/provenance.json');
121
- console.log(chalk.green('Provenance manifest generated'));
121
+ console.log(chalk.green('Provenance manifest generated'));
122
122
  } else {
123
123
  console.log(
124
- chalk.yellow('⚠️ Provenance tools not available - skipping manifest generation')
124
+ chalk.yellow('Provenance tools not available - skipping manifest generation')
125
125
  );
126
126
  }
127
127
 
128
128
  // Initialize git repository
129
129
  if (options.git) {
130
130
  try {
131
- console.log(chalk.cyan('🔧 Initializing git repository...'));
131
+ console.log(chalk.cyan('Initializing git repository...'));
132
132
 
133
133
  // Check if git is available
134
134
  try {
135
135
  require('child_process').execSync('git --version', { stdio: 'ignore' });
136
136
  } catch (error) {
137
- console.warn(chalk.yellow('⚠️ Git not found. Skipping git initialization.'));
138
- console.warn(chalk.blue('💡 Install git to enable automatic repository setup.'));
137
+ console.warn(chalk.yellow('Git not found. Skipping git initialization.'));
138
+ console.warn(chalk.blue('Install git to enable automatic repository setup.'));
139
139
  return;
140
140
  }
141
141
 
@@ -151,7 +151,7 @@ async function finalizeProject(projectName, options, answers) {
151
151
  require('child_process').execSync(`git config user.email "${authorEmail}"`, {
152
152
  stdio: 'inherit',
153
153
  });
154
- console.log(chalk.green(`✅ Git configured: ${authorName} <${authorEmail}>`));
154
+ console.log(chalk.green(`Git configured: ${authorName} <${authorEmail}>`));
155
155
  }
156
156
 
157
157
  require('child_process').execSync('git init', { stdio: 'inherit' });
@@ -159,7 +159,7 @@ async function finalizeProject(projectName, options, answers) {
159
159
  require('child_process').execSync('git commit -m "Initial CAWS project setup"', {
160
160
  stdio: 'inherit',
161
161
  });
162
- console.log(chalk.green('Git repository initialized'));
162
+ console.log(chalk.green('Git repository initialized'));
163
163
 
164
164
  // Update provenance with commit hash
165
165
  const commitHash = require('child_process')
@@ -173,19 +173,19 @@ async function finalizeProject(projectName, options, answers) {
173
173
  .digest('hex');
174
174
  await fs.writeFile('.agent/provenance.json', JSON.stringify(currentProvenance, null, 2));
175
175
 
176
- console.log(chalk.green('Provenance updated with commit hash'));
176
+ console.log(chalk.green('Provenance updated with commit hash'));
177
177
  } catch (error) {
178
178
  console.warn(
179
- chalk.yellow('⚠️ Failed to initialize git repository:'),
179
+ chalk.yellow('Failed to initialize git repository:'),
180
180
  error?.message || String(error)
181
181
  );
182
- console.warn(chalk.blue('💡 You can initialize git manually later with:'));
182
+ console.warn(chalk.blue('You can initialize git manually later with:'));
183
183
  console.warn(" git init && git add . && git commit -m 'Initial CAWS project setup'");
184
184
  }
185
185
  }
186
186
  } catch (error) {
187
187
  console.error(
188
- chalk.red('Error during project finalization:'),
188
+ chalk.red('Error during project finalization:'),
189
189
  error?.message || String(error)
190
190
  );
191
191
  }
@@ -199,15 +199,15 @@ function continueToSuccess() {
199
199
  process.cwd() ===
200
200
  path.resolve(process.argv[3] === '.' ? process.cwd() : process.argv[3] || 'caws-project');
201
201
 
202
- console.log(chalk.green('\n🎉 CAWS project initialized successfully!'));
202
+ console.log(chalk.green('\nCAWS project initialized successfully!'));
203
203
 
204
204
  if (isCurrentDir) {
205
205
  console.log(
206
- `📁 ${chalk.cyan('Initialized in current directory')}: ${path.resolve(process.cwd())}`
206
+ `${chalk.cyan('Initialized in current directory')}: ${path.resolve(process.cwd())}`
207
207
  );
208
208
  console.log(chalk.gray(' (CAWS files added to your existing project)'));
209
209
  } else {
210
- console.log(`📁 ${chalk.cyan('Project location')}: ${path.resolve(process.cwd())}`);
210
+ console.log(`${chalk.cyan('Project location')}: ${path.resolve(process.cwd())}`);
211
211
  console.log(chalk.gray(' (New subdirectory created with CAWS structure)'));
212
212
  }
213
213
 
@@ -84,7 +84,7 @@ function formatGitLockError(lockStatus) {
84
84
  return null;
85
85
  }
86
86
 
87
- let message = '⚠️ Git lock detected\n';
87
+ let message = 'Git lock detected\n';
88
88
  message += ` ${lockStatus.message}\n`;
89
89
 
90
90
  if (lockStatus.lockFiles.length > 0) {
@@ -99,12 +99,12 @@ function formatGitLockError(lockStatus) {
99
99
  }
100
100
 
101
101
  if (lockStatus.suggestion) {
102
- message += `\n 💡 ${lockStatus.suggestion}\n`;
102
+ message += `\n ${lockStatus.suggestion}\n`;
103
103
  }
104
104
 
105
105
  if (lockStatus.stale) {
106
106
  message +=
107
- '\n ⚠️ Warning: Removing stale locks may cause data loss if another process is actually running.\n';
107
+ '\n Warning: Removing stale locks may cause data loss if another process is actually running.\n';
108
108
  message += ' Check for running git/editor processes before removing locks.\n';
109
109
  }
110
110
 
@@ -124,7 +124,7 @@ async function updateGitignore(projectRoot, options = {}) {
124
124
 
125
125
  return true;
126
126
  } catch (error) {
127
- console.warn(chalk.yellow(`⚠️ Could not update .gitignore: ${error.message}`));
127
+ console.warn(chalk.yellow(`Could not update .gitignore: ${error.message}`));
128
128
  return false;
129
129
  }
130
130
  }
@@ -333,27 +333,27 @@ function getTodoAnalyzerSuggestion(cwd = process.cwd()) {
333
333
  if (hasNpx) {
334
334
  // npx available - works for any language, no installation needed
335
335
  suggestions.push(
336
- ' Use npx (no installation required): npx --yes @paths.design/quality-gates'
336
+ ' - Use npx (no installation required): npx --yes @paths.design/quality-gates'
337
337
  );
338
- suggestions.push(' Install package: npm install --save-dev @paths.design/quality-gates');
338
+ suggestions.push(' - Install package: npm install --save-dev @paths.design/quality-gates');
339
339
  } else if (hasNodeJs) {
340
340
  // Node.js available but npx not found (unusual)
341
- suggestions.push(' Install package: npm install --save-dev @paths.design/quality-gates');
341
+ suggestions.push(' - Install package: npm install --save-dev @paths.design/quality-gates');
342
342
  suggestions.push(
343
- ' Install npx: npm install -g npx (then use: npx --yes @paths.design/quality-gates)'
343
+ ' - Install npx: npm install -g npx (then use: npx --yes @paths.design/quality-gates)'
344
344
  );
345
345
  } else {
346
346
  // Node.js not available - suggest installation
347
347
  suggestions.push(
348
- ' Install Node.js: https://nodejs.org/ (then use: npx --yes @paths.design/quality-gates)'
348
+ ' - Install Node.js: https://nodejs.org/ (then use: npx --yes @paths.design/quality-gates)'
349
349
  );
350
- suggestions.push(' Use CAWS MCP server: caws quality-gates (via MCP)');
350
+ suggestions.push(' - Use CAWS MCP server: caws quality-gates (via MCP)');
351
351
  }
352
352
 
353
353
  // Check for project-specific scripts (language-agnostic - if they exist, suggest them)
354
354
  const pythonScript = path.join(cwd, 'scripts', 'v3', 'analysis', 'todo_analyzer.py');
355
355
  if (fs.existsSync(pythonScript)) {
356
- suggestions.push(` Use project script: python3 ${pythonScript}`);
356
+ suggestions.push(` - Use project script: python3 ${pythonScript}`);
357
357
  }
358
358
 
359
359
  return suggestions.join('\n');
@@ -117,7 +117,7 @@ function getStagedFiles() {
117
117
 
118
118
  return stagedFiles;
119
119
  } catch (error) {
120
- console.warn(`⚠️ Could not get staged files: ${error.message}`);
120
+ console.warn(`Could not get staged files: ${error.message}`);
121
121
  return [];
122
122
  }
123
123
  }
@@ -144,7 +144,7 @@ function checkGodObjects(stagedFiles, language = 'rust') {
144
144
  return { violations: [], warnings: [], total: 0 };
145
145
  }
146
146
 
147
- console.log(`📁 Found ${files.length} staged ${language} files to check`);
147
+ console.log(`Found ${files.length} staged ${language} files to check`);
148
148
 
149
149
  const violations = [];
150
150
  const warnings = [];
@@ -173,7 +173,7 @@ function checkGodObjects(stagedFiles, language = 'rust') {
173
173
  });
174
174
  }
175
175
  } catch (error) {
176
- console.warn(`⚠️ Could not analyze ${file}: ${error.message}`);
176
+ console.warn(`Could not analyze ${file}: ${error.message}`);
177
177
  }
178
178
  }
179
179
 
@@ -194,7 +194,7 @@ function checkHiddenTodos(stagedFiles) {
194
194
  return { todos: [], blocking: 0, total: 0 };
195
195
  }
196
196
 
197
- console.log(`📁 Found ${supportedFiles.length} staged files to analyze for TODOs`);
197
+ console.log(`Found ${supportedFiles.length} staged files to analyze for TODOs`);
198
198
 
199
199
  try {
200
200
  // Find TODO analyzer .mjs file (preferred - no Python dependency)
@@ -229,17 +229,17 @@ function checkHiddenTodos(stagedFiles) {
229
229
  }
230
230
 
231
231
  if (!analyzerPath) {
232
- console.warn('⚠️ TODO analyzer not found - skipping TODO analysis');
232
+ console.warn('TODO analyzer not found - skipping TODO analysis');
233
233
  const suggestion = getTodoAnalyzerSuggestion(process.cwd());
234
- console.warn('💡 Available options for TODO analysis:');
234
+ console.warn('Available options for TODO analysis:');
235
235
  console.warn(suggestion);
236
236
  return { todos: [], blocking: 0, total: 0 };
237
237
  }
238
238
 
239
239
  if (usePython) {
240
- console.warn('⚠️ Using legacy Python TODO analyzer (deprecated)');
240
+ console.warn('Using legacy Python TODO analyzer (deprecated)');
241
241
  const suggestion = getTodoAnalyzerSuggestion(process.cwd());
242
- console.warn('💡 Consider upgrading to Node.js version:');
242
+ console.warn('Consider upgrading to Node.js version:');
243
243
  console.warn(suggestion);
244
244
  }
245
245
 
@@ -262,7 +262,7 @@ function checkHiddenTodos(stagedFiles) {
262
262
  details: result,
263
263
  };
264
264
  } catch (error) {
265
- console.warn(`⚠️ Could not run TODO analysis: ${error.message}`);
265
+ console.warn(`Could not run TODO analysis: ${error.message}`);
266
266
  return { todos: [], blocking: 0, total: 0 };
267
267
  }
268
268
  }
@@ -275,18 +275,18 @@ function checkHiddenTodos(stagedFiles) {
275
275
  function runQualityGates(options = {}) {
276
276
  const { languages = ['rust'], checkTodos = true, checkGodObjects = true, ci = false } = options;
277
277
 
278
- console.log(`🚦 Running Quality Gates${ci ? ' (CI Mode)' : ' - Crisis Response Mode'}`);
278
+ console.log(`Running Quality Gates${ci ? ' (CI Mode)' : ' - Crisis Response Mode'}`);
279
279
  console.log('==================================================');
280
280
 
281
281
  // Get staged files
282
282
  const stagedFiles = getStagedFiles();
283
283
 
284
284
  if (stagedFiles.length === 0) {
285
- console.log('No staged files to analyze');
285
+ console.log('No staged files to analyze');
286
286
  return { passed: true, violations: [], warnings: [] };
287
287
  }
288
288
 
289
- console.log(`📁 Analyzing ${stagedFiles.length} staged files`);
289
+ console.log(`Analyzing ${stagedFiles.length} staged files`);
290
290
 
291
291
  const results = {
292
292
  passed: true,
@@ -296,37 +296,37 @@ function runQualityGates(options = {}) {
296
296
  };
297
297
 
298
298
  // Check naming conventions
299
- console.log('\n🔤 Checking naming conventions...');
300
- console.log(' Naming conventions check passed');
299
+ console.log('\nChecking naming conventions...');
300
+ console.log(' Naming conventions check passed');
301
301
 
302
302
  // Check code freeze compliance
303
- console.log('\n🚫 Checking code freeze compliance...');
304
- console.log(' Code freeze compliance check passed');
303
+ console.log('\nChecking code freeze compliance...');
304
+ console.log(' Code freeze compliance check passed');
305
305
 
306
306
  // Check duplication
307
- console.log('\n📋 Checking duplication...');
308
- console.log(' No duplication regression detected');
307
+ console.log('\nChecking duplication...');
308
+ console.log(' No duplication regression detected');
309
309
 
310
310
  // Check god objects for each language
311
311
  if (checkGodObjects) {
312
312
  for (const language of languages) {
313
- console.log(`\n🏗️ Checking god objects (${language})...`);
313
+ console.log(`\nChecking god objects (${language})...`);
314
314
  const godObjectResults = checkGodObjects(stagedFiles, language);
315
315
 
316
316
  results.violations.push(...godObjectResults.violations);
317
317
  results.warnings.push(...godObjectResults.warnings);
318
318
 
319
319
  if (godObjectResults.violations.length > 0) {
320
- console.log(' God object violations detected:');
320
+ console.log(' God object violations detected:');
321
321
  godObjectResults.violations.forEach((violation) => {
322
322
  console.log(` ${violation.file}: ${violation.message}`);
323
323
  });
324
324
  } else {
325
- console.log(' No blocking god object violations');
325
+ console.log(' No blocking god object violations');
326
326
  }
327
327
 
328
328
  if (godObjectResults.warnings.length > 0) {
329
- console.log(' ⚠️ God object warnings:');
329
+ console.log(' God object warnings:');
330
330
  godObjectResults.warnings.forEach((warning) => {
331
331
  console.log(` ${warning.file}: ${warning.message}`);
332
332
  });
@@ -336,22 +336,22 @@ function runQualityGates(options = {}) {
336
336
 
337
337
  // Check hidden TODOs
338
338
  if (checkTodos) {
339
- console.log('\n🔍 Checking hidden TODOs...');
339
+ console.log('\nChecking hidden TODOs...');
340
340
  const todoResults = checkHiddenTodos(stagedFiles);
341
341
  results.todos = todoResults.total;
342
342
 
343
343
  if (todoResults.total > 0) {
344
- console.log(` Found ${todoResults.total} hidden TODOs in staged files`);
345
- console.log(' 💡 Fix stub implementations and placeholder code before committing');
346
- console.log(' 📖 See docs/PLACEHOLDER-DETECTION-GUIDE.md for classification');
344
+ console.log(` Found ${todoResults.total} hidden TODOs in staged files`);
345
+ console.log(' Fix stub implementations and placeholder code before committing');
346
+ console.log(' See docs/PLACEHOLDER-DETECTION-GUIDE.md for classification');
347
347
  } else {
348
- console.log(' No critical hidden TODOs found in staged files');
348
+ console.log(' No critical hidden TODOs found in staged files');
349
349
  }
350
350
  }
351
351
 
352
352
  // Summary
353
353
  console.log('\n==================================================');
354
- console.log('📊 QUALITY GATES RESULTS');
354
+ console.log('QUALITY GATES RESULTS');
355
355
  console.log('==================================================');
356
356
 
357
357
  const totalViolations = results.violations.length;
@@ -359,7 +359,7 @@ function runQualityGates(options = {}) {
359
359
  const totalTodos = results.todos;
360
360
 
361
361
  if (totalViolations > 0) {
362
- console.log(`\n❌ CRITICAL VIOLATIONS (${totalViolations}):`);
362
+ console.log(`\nCRITICAL VIOLATIONS (${totalViolations}):`);
363
363
  results.violations.forEach((violation) => {
364
364
  console.log(` ${violation.file}: ${violation.message}`);
365
365
  });
@@ -367,25 +367,25 @@ function runQualityGates(options = {}) {
367
367
  }
368
368
 
369
369
  if (totalWarnings > 0) {
370
- console.log(`\n⚠️ WARNINGS (${totalWarnings}):`);
370
+ console.log(`\nWARNINGS (${totalWarnings}):`);
371
371
  results.warnings.forEach((warning) => {
372
372
  console.log(` ${warning.file}: ${warning.message}`);
373
373
  });
374
374
  }
375
375
 
376
376
  if (totalTodos > 0) {
377
- console.log(`\n🔍 HIDDEN TODOS (${totalTodos}):`);
377
+ console.log(`\nHIDDEN TODOS (${totalTodos}):`);
378
378
  console.log(` Found ${totalTodos} hidden TODOs in staged files`);
379
379
  results.passed = false;
380
380
  }
381
381
 
382
382
  // Final result
383
383
  if (results.passed) {
384
- console.log('\n✅ ALL QUALITY GATES PASSED');
385
- console.log('🎉 Commit allowed - quality maintained!');
384
+ console.log('\nALL QUALITY GATES PASSED');
385
+ console.log('Commit allowed - quality maintained!');
386
386
  } else {
387
- console.log('\n❌ QUALITY GATES FAILED');
388
- console.log('🚫 Commit blocked - fix violations above');
387
+ console.log('\nQUALITY GATES FAILED');
388
+ console.log('Commit blocked - fix violations above');
389
389
  }
390
390
 
391
391
  return results;
@@ -62,7 +62,7 @@ async function resolveSpec(options = {}) {
62
62
  const content = await fs.readFile(featurePath, 'utf8');
63
63
  const spec = yaml.load(content);
64
64
 
65
- console.log(chalk.green(`✅ Using feature-specific spec: ${specId}`));
65
+ console.log(chalk.green(`Using feature-specific spec: ${specId}`));
66
66
 
67
67
  return {
68
68
  path: featurePath,
@@ -90,7 +90,7 @@ async function resolveSpec(options = {}) {
90
90
  const content = await fs.readFile(singleSpecPath, 'utf8');
91
91
  const spec = yaml.load(content);
92
92
 
93
- console.log(chalk.blue(`📋 Auto-detected single spec: ${singleSpecId}`));
93
+ console.log(chalk.blue(`Auto-detected single spec: ${singleSpecId}`));
94
94
 
95
95
  return {
96
96
  path: singleSpecPath,
@@ -100,7 +100,7 @@ async function resolveSpec(options = {}) {
100
100
  }
101
101
  } else if (specIds.length > 1) {
102
102
  // Multiple specs - require explicit selection with enhanced guidance
103
- console.error(chalk.red('Multiple specs detected. Please specify which one:'));
103
+ console.error(chalk.red('Multiple specs detected. Please specify which one:'));
104
104
 
105
105
  // Show specs with details
106
106
  const specsInfo = [];
@@ -169,7 +169,7 @@ async function resolveSpec(options = {}) {
169
169
  return aTypePriority - bTypePriority;
170
170
  });
171
171
 
172
- console.log(chalk.green('\n💡 Quick suggestion:'));
172
+ console.log(chalk.green('\nQuick suggestion:'));
173
173
  console.log(chalk.gray(` Try: caws <command> --spec-id ${sortedSpecs[0]}`));
174
174
 
175
175
  // Interactive mode suggestion
@@ -187,7 +187,7 @@ async function resolveSpec(options = {}) {
187
187
  const spec = yaml.load(content);
188
188
 
189
189
  if (warnLegacy) {
190
- console.log(chalk.yellow('⚠️ Using legacy working-spec.yaml'));
190
+ console.log(chalk.yellow('Using legacy working-spec.yaml'));
191
191
  console.log(chalk.gray(' For multi-agent workflows, use feature-specific specs:'));
192
192
  console.log(chalk.blue(' caws specs create <feature-id>'));
193
193
  console.log('');
@@ -298,7 +298,7 @@ async function interactiveSpecSelection(specIds) {
298
298
  return new Promise((resolve, reject) => {
299
299
  const readline = require('readline');
300
300
 
301
- console.log(chalk.blue('\n📋 Interactive Spec Selection'));
301
+ console.log(chalk.blue('\nInteractive Spec Selection'));
302
302
  console.log(chalk.gray('Select which spec to use:\n'));
303
303
 
304
304
  specIds.forEach((id, index) => {
@@ -381,7 +381,7 @@ async function checkScopeConflicts(specIds) {
381
381
  ? ` Line ${yamlError.mark.line + 1}, Column ${yamlError.mark.column + 1}\n`
382
382
  : '') +
383
383
  (yamlError.mark?.snippet ? ` ${yamlError.mark.snippet}\n` : '') +
384
- `💡 Fix YAML syntax errors or use 'caws specs create <id>' for proper structure`
384
+ `Fix YAML syntax errors or use 'caws specs create <id>' for proper structure`
385
385
  );
386
386
  }
387
387
 
@@ -498,7 +498,7 @@ async function suggestMigration() {
498
498
  const status = await checkMultiSpecStatus();
499
499
 
500
500
  if (status.needsMigration) {
501
- console.log(chalk.yellow('\n⚠️ Migration Recommended: Single-Spec → Multi-Spec'));
501
+ console.log(chalk.yellow('\nMigration Recommended: Single-Spec → Multi-Spec'));
502
502
  console.log(chalk.gray(' Your project uses the legacy working-spec.yaml'));
503
503
  console.log(chalk.gray(' For multi-agent workflows, migrate to feature-specific specs:\n'));
504
504
  console.log(chalk.blue(' 1. caws specs create <feature-id>'));
@@ -337,17 +337,17 @@ function displayTypeScriptDetection(detection) {
337
337
  return;
338
338
  }
339
339
 
340
- console.log(chalk.cyan('\n📦 TypeScript Project Detected'));
341
- console.log(chalk.gray(` tsconfig.json: ${detection.hasTsConfig ? '' : ''}`));
342
- console.log(chalk.gray(` typescript dependency: ${detection.hasTypeScriptDep ? '' : ''}`));
340
+ console.log(chalk.cyan('\nTypeScript Project Detected'));
341
+ console.log(chalk.gray(` tsconfig.json: ${detection.hasTsConfig ? '' : ''}`));
342
+ console.log(chalk.gray(` typescript dependency: ${detection.hasTypeScriptDep ? '' : ''}`));
343
343
 
344
344
  if (detection.testFramework.framework !== 'none') {
345
345
  console.log(chalk.gray(` Test framework: ${detection.testFramework.framework}`));
346
- console.log(chalk.gray(` Configured: ${detection.testFramework.isConfigured ? '' : ''}`));
346
+ console.log(chalk.gray(` Configured: ${detection.testFramework.isConfigured ? '' : ''}`));
347
347
  }
348
348
 
349
349
  if (detection.recommendations.length > 0) {
350
- console.log(chalk.yellow('\n💡 Recommendations:'));
350
+ console.log(chalk.yellow('\nRecommendations:'));
351
351
  detection.recommendations.forEach((rec) => {
352
352
  console.log(chalk.yellow(` ${rec}`));
353
353
  });
@@ -127,7 +127,7 @@ function validateAllCawsYamlFiles(projectRoot) {
127
127
  */
128
128
  function formatYamlError(error, filePath) {
129
129
  const relativePath = path.relative(process.cwd(), filePath);
130
- let message = `❌ Invalid YAML in ${relativePath}\n`;
130
+ let message = `Invalid YAML in ${relativePath}\n`;
131
131
  message += ` Error: ${error.error}\n`;
132
132
 
133
133
  if (error.line !== null) {
@@ -608,7 +608,7 @@ function validateWorkingSpecWithSuggestions(spec, options = {}) {
608
608
 
609
609
  if (autoFix && fixes.length > 0) {
610
610
  if (dryRun) {
611
- console.log('🔍 Auto-fix preview (dry-run mode):');
611
+ console.log('Auto-fix preview (dry-run mode):');
612
612
  for (const fix of fixes) {
613
613
  console.log(` [WOULD FIX] ${fix.field}`);
614
614
  console.log(` Description: ${fix.description}`);
@@ -619,7 +619,7 @@ function validateWorkingSpecWithSuggestions(spec, options = {}) {
619
619
  console.log('');
620
620
  }
621
621
  } else {
622
- console.log('🔧 Applying auto-fixes...');
622
+ console.log('Applying auto-fixes...');
623
623
  for (const fix of fixes) {
624
624
  try {
625
625
  const pathParts = fix.field.split('.');
@@ -630,10 +630,10 @@ function validateWorkingSpecWithSuggestions(spec, options = {}) {
630
630
  }
631
631
  current[pathParts[pathParts.length - 1]] = fix.value;
632
632
  appliedFixes.push(fix);
633
- console.log(` Fixed ${fix.field}`);
633
+ console.log(` Fixed ${fix.field}`);
634
634
  console.log(` ${fix.description}`);
635
635
  } catch (error) {
636
- console.warn(` ⚠️ Failed to apply fix for ${fix.field}: ${error.message}`);
636
+ console.warn(` Failed to apply fix for ${fix.field}: ${error.message}`);
637
637
  }
638
638
  }
639
639
  }