@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.
- package/dist/budget-derivation.js +10 -10
- package/dist/commands/archive.js +22 -22
- package/dist/commands/burnup.js +7 -7
- package/dist/commands/diagnose.js +25 -25
- package/dist/commands/evaluate.js +20 -20
- package/dist/commands/init.js +71 -72
- package/dist/commands/iterate.js +21 -21
- package/dist/commands/mode.js +11 -11
- package/dist/commands/plan.js +5 -5
- package/dist/commands/provenance.js +86 -86
- package/dist/commands/quality-gates.js +3 -3
- package/dist/commands/quality-monitor.js +17 -17
- package/dist/commands/session.js +312 -0
- package/dist/commands/specs.js +44 -44
- package/dist/commands/status.js +43 -43
- package/dist/commands/templates.js +14 -14
- package/dist/commands/tool.js +1 -1
- package/dist/commands/troubleshoot.js +11 -11
- package/dist/commands/tutorial.js +119 -119
- package/dist/commands/validate.js +6 -6
- package/dist/commands/waivers.js +93 -60
- package/dist/commands/workflow.js +17 -17
- package/dist/commands/worktree.js +13 -13
- package/dist/config/index.js +5 -5
- package/dist/config/modes.js +7 -7
- package/dist/constants/spec-types.js +5 -5
- package/dist/error-handler.js +4 -4
- package/dist/generators/jest-config-generator.js +3 -3
- package/dist/generators/working-spec.js +4 -4
- package/dist/index.js +79 -27
- package/dist/minimal-cli.js +9 -9
- package/dist/policy/PolicyManager.js +1 -1
- package/dist/scaffold/claude-hooks.js +7 -7
- package/dist/scaffold/cursor-hooks.js +8 -8
- package/dist/scaffold/git-hooks.js +152 -152
- package/dist/scaffold/index.js +48 -48
- package/dist/session/session-manager.js +548 -0
- package/dist/test-analysis.js +20 -20
- package/dist/utils/command-wrapper.js +8 -8
- package/dist/utils/detection.js +7 -7
- package/dist/utils/finalization.js +21 -21
- package/dist/utils/git-lock.js +3 -3
- package/dist/utils/gitignore-updater.js +1 -1
- package/dist/utils/project-analysis.js +7 -7
- package/dist/utils/quality-gates-utils.js +35 -35
- package/dist/utils/spec-resolver.js +8 -8
- package/dist/utils/typescript-detector.js +5 -5
- package/dist/utils/yaml-validation.js +1 -1
- package/dist/validation/spec-validation.js +4 -4
- package/dist/worktree/worktree-manager.js +11 -5
- package/package.json +1 -1
package/dist/commands/init.js
CHANGED
|
@@ -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(
|
|
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(
|
|
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('
|
|
54
|
-
console.error(chalk.blue('
|
|
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(
|
|
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('
|
|
71
|
-
console.error(chalk.blue('
|
|
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('
|
|
78
|
-
console.error(chalk.blue('
|
|
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('
|
|
85
|
-
console.error(chalk.blue('
|
|
86
|
-
console.error(chalk.blue('
|
|
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(
|
|
99
|
-
console.error(chalk.blue('
|
|
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('
|
|
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('
|
|
114
|
+
console.warn(chalk.yellow('Current directory contains project files'));
|
|
115
115
|
console.warn(
|
|
116
|
-
chalk.blue('
|
|
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(
|
|
136
|
+
console.log(chalk.green(`Created project directory: ${projectName}`));
|
|
137
137
|
} else {
|
|
138
|
-
console.log(chalk.green(
|
|
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('
|
|
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('
|
|
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('
|
|
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: '
|
|
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: '
|
|
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('
|
|
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('
|
|
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('
|
|
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('
|
|
251
|
+
console.log(chalk.blue('Updating .gitignore...'));
|
|
252
252
|
await updateGitignore(process.cwd());
|
|
253
253
|
|
|
254
254
|
// Success
|
|
255
|
-
console.log(chalk.green('\
|
|
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('
|
|
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(
|
|
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: '
|
|
298
|
+
message: 'What type of project is this?',
|
|
299
299
|
choices: [
|
|
300
300
|
{
|
|
301
|
-
name: '
|
|
301
|
+
name: 'VS Code Extension (webview, commands, integrations)',
|
|
302
302
|
value: 'extension',
|
|
303
303
|
short: 'VS Code Extension',
|
|
304
304
|
},
|
|
305
305
|
{
|
|
306
|
-
name: '
|
|
306
|
+
name: 'Library/Package (reusable components, utilities)',
|
|
307
307
|
value: 'library',
|
|
308
308
|
short: 'Library',
|
|
309
309
|
},
|
|
310
310
|
{
|
|
311
|
-
name: '
|
|
311
|
+
name: 'Web Application (frontend/backend, full-stack)',
|
|
312
312
|
value: 'application',
|
|
313
313
|
short: 'Web Application',
|
|
314
314
|
},
|
|
315
315
|
{
|
|
316
|
-
name: '
|
|
316
|
+
name: 'CLI Tool (command-line interface, scripts)',
|
|
317
317
|
value: 'cli',
|
|
318
318
|
short: 'CLI Tool',
|
|
319
319
|
},
|
|
320
320
|
{
|
|
321
|
-
name: '
|
|
321
|
+
name: 'Mobile App (iOS/Android, React Native, etc.)',
|
|
322
322
|
value: 'mobile',
|
|
323
323
|
short: 'Mobile App',
|
|
324
324
|
},
|
|
325
325
|
{
|
|
326
|
-
name: '
|
|
326
|
+
name: 'Infrastructure (DevOps, deployment, cloud)',
|
|
327
327
|
value: 'infrastructure',
|
|
328
328
|
short: 'Infrastructure',
|
|
329
329
|
},
|
|
330
330
|
{
|
|
331
|
-
name: '
|
|
331
|
+
name: 'Data/Analytics (ETL, ML, dashboards)',
|
|
332
332
|
value: 'data',
|
|
333
333
|
short: 'Data/Analytics',
|
|
334
334
|
},
|
|
335
335
|
{
|
|
336
|
-
name: '
|
|
336
|
+
name: 'Game Development (Unity, Godot, custom engine)',
|
|
337
337
|
value: 'game',
|
|
338
338
|
short: 'Game',
|
|
339
339
|
},
|
|
340
340
|
{
|
|
341
|
-
name: '
|
|
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: '
|
|
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: '
|
|
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: '
|
|
381
|
+
message: 'What risk tier does this project fall into?',
|
|
382
382
|
choices: [
|
|
383
383
|
{
|
|
384
|
-
name: '
|
|
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: '
|
|
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: '
|
|
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: '
|
|
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: '
|
|
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('\
|
|
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('
|
|
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('
|
|
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('
|
|
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('
|
|
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('
|
|
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('
|
|
565
|
+
console.log(chalk.blue('Updating .gitignore...'));
|
|
567
566
|
const gitignoreUpdated = await updateGitignore(process.cwd());
|
|
568
567
|
if (gitignoreUpdated) {
|
|
569
|
-
console.log(chalk.green('
|
|
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('
|
|
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('
|
|
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('
|
|
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('
|
|
656
|
+
console.log(chalk.blue('Updating .gitignore...'));
|
|
658
657
|
const gitignoreUpdated = await updateGitignore(process.cwd());
|
|
659
658
|
if (gitignoreUpdated) {
|
|
660
|
-
console.log(chalk.green('
|
|
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('\
|
|
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('\
|
|
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('\
|
|
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('\
|
|
700
|
+
console.log('\nQuick start: caws scaffold && caws validate && caws diagnose');
|
|
702
701
|
} catch (error) {
|
|
703
|
-
console.error(chalk.red('
|
|
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('
|
|
711
|
+
console.log(chalk.green('Cleanup completed'));
|
|
713
712
|
} catch (cleanupError) {
|
|
714
713
|
console.warn(
|
|
715
|
-
chalk.yellow('
|
|
714
|
+
chalk.yellow('Could not clean up:'),
|
|
716
715
|
cleanupError?.message || cleanupError
|
|
717
716
|
);
|
|
718
717
|
}
|
package/dist/commands/iterate.js
CHANGED
|
@@ -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('
|
|
35
|
+
console.log('Detecting CAWS setup...');
|
|
36
36
|
const setup = initializeGlobalSetup();
|
|
37
37
|
|
|
38
38
|
if (setup.hasWorkingSpec) {
|
|
39
|
-
console.log(
|
|
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('\
|
|
48
|
-
console.log('
|
|
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('
|
|
57
|
+
console.log(chalk.blue('Current Phase:\n'));
|
|
58
58
|
console.log(` ${guidance.phase}\n`);
|
|
59
59
|
|
|
60
|
-
console.log(chalk.blue('
|
|
60
|
+
console.log(chalk.blue('Completed Steps:\n'));
|
|
61
61
|
guidance.completed.forEach((step) => {
|
|
62
|
-
console.log(chalk.green(`
|
|
62
|
+
console.log(chalk.green(` [done] ${step}`));
|
|
63
63
|
});
|
|
64
64
|
|
|
65
|
-
console.log(chalk.blue('\
|
|
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('\
|
|
71
|
+
console.log(chalk.red('\nBlockers:\n'));
|
|
72
72
|
guidance.blockers.forEach((blocker) => {
|
|
73
|
-
console.log(chalk.red(`
|
|
73
|
+
console.log(chalk.red(` ${blocker}`));
|
|
74
74
|
});
|
|
75
75
|
}
|
|
76
76
|
|
|
77
|
-
console.log(chalk.blue('\
|
|
77
|
+
console.log(chalk.blue('\nRecommendations:\n'));
|
|
78
78
|
guidance.recommendations.forEach((rec) => {
|
|
79
|
-
console.log(chalk.blue(`
|
|
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('\
|
|
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('\
|
|
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('\
|
|
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(`\
|
|
192
|
+
console.error(chalk.red(`\nIteration guidance failed: ${error.message}`));
|
|
193
193
|
if (options.verbose) {
|
|
194
194
|
console.error(error.stack);
|
|
195
195
|
}
|
package/dist/commands/mode.js
CHANGED
|
@@ -23,8 +23,8 @@ const {
|
|
|
23
23
|
function displayCurrentMode(currentMode) {
|
|
24
24
|
const tier = getTier(currentMode);
|
|
25
25
|
|
|
26
|
-
console.log(chalk.bold.cyan('\
|
|
27
|
-
console.log(chalk.cyan('
|
|
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
|
|
60
|
-
console.log(chalk.cyan('
|
|
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(`
|
|
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(`
|
|
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('\
|
|
115
|
-
console.log(chalk.cyan('
|
|
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
|
-
|
|
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('\
|
|
214
|
-
console.log(chalk.cyan('
|
|
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}`
|