@paths.design/caws-cli 7.0.2 → 7.0.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.
- package/dist/budget-derivation.js +5 -4
- package/dist/commands/diagnose.js +24 -19
- package/dist/commands/init.js +51 -4
- package/dist/commands/specs.js +40 -1
- package/dist/commands/status.js +2 -2
- package/dist/commands/tool.js +2 -3
- package/dist/config/index.js +17 -8
- package/dist/generators/working-spec.js +19 -6
- package/dist/scaffold/git-hooks.js +127 -29
- package/dist/scaffold/index.js +53 -7
- package/dist/templates/.caws/tools/README.md +20 -0
- package/dist/templates/.cursor/README.md +311 -0
- package/dist/templates/.cursor/hooks/audit.sh +55 -0
- package/dist/templates/.cursor/hooks/block-dangerous.sh +83 -0
- package/dist/templates/.cursor/hooks/caws-quality-check.sh +52 -0
- package/dist/templates/.cursor/hooks/caws-scope-guard.sh +130 -0
- package/dist/templates/.cursor/hooks/caws-tool-validation.sh +121 -0
- package/dist/templates/.cursor/hooks/format.sh +38 -0
- package/dist/templates/.cursor/hooks/naming-check.sh +64 -0
- package/dist/templates/.cursor/hooks/scan-secrets.sh +46 -0
- package/dist/templates/.cursor/hooks/scope-guard.sh +52 -0
- package/dist/templates/.cursor/hooks/validate-spec.sh +83 -0
- package/dist/templates/.cursor/hooks.json +59 -0
- package/dist/templates/.cursor/rules/00-claims-verification.mdc +144 -0
- package/dist/templates/.cursor/rules/01-working-style.mdc +50 -0
- package/dist/templates/.cursor/rules/02-quality-gates.mdc +370 -0
- package/dist/templates/.cursor/rules/03-naming-and-refactor.mdc +33 -0
- package/dist/templates/.cursor/rules/04-logging-language-style.mdc +23 -0
- package/dist/templates/.cursor/rules/05-safe-defaults-guards.mdc +23 -0
- package/dist/templates/.cursor/rules/06-typescript-conventions.mdc +36 -0
- package/dist/templates/.cursor/rules/07-process-ops.mdc +20 -0
- package/dist/templates/.cursor/rules/08-solid-and-architecture.mdc +16 -0
- package/dist/templates/.cursor/rules/09-docstrings.mdc +89 -0
- package/dist/templates/.cursor/rules/10-documentation-quality-standards.mdc +390 -0
- package/dist/templates/.cursor/rules/11-scope-management-waivers.mdc +385 -0
- package/dist/templates/.cursor/rules/12-implementation-completeness.mdc +516 -0
- package/dist/templates/.cursor/rules/13-language-agnostic-standards.mdc +588 -0
- package/dist/templates/.cursor/rules/README.md +148 -0
- package/dist/templates/.github/copilot/instructions.md +311 -0
- package/dist/templates/.idea/runConfigurations/CAWS_Evaluate.xml +5 -0
- package/dist/templates/.idea/runConfigurations/CAWS_Validate.xml +5 -0
- package/dist/templates/.vscode/launch.json +56 -0
- package/dist/templates/.vscode/settings.json +93 -0
- package/dist/templates/.windsurf/workflows/caws-guided-development.md +92 -0
- package/dist/templates/COMMIT_CONVENTIONS.md +86 -0
- package/dist/templates/OIDC_SETUP.md +300 -0
- package/dist/templates/agents.md +1047 -0
- package/dist/templates/codemod/README.md +1 -0
- package/dist/templates/codemod/test.js +93 -0
- package/dist/templates/docs/README.md +150 -0
- package/dist/templates/scripts/quality-gates/check-god-objects.js +146 -0
- package/dist/templates/scripts/quality-gates/run-quality-gates.js +50 -0
- package/dist/templates/scripts/v3/analysis/todo_analyzer.py +1997 -0
- package/dist/tool-loader.js +6 -1
- package/dist/tool-validator.js +8 -2
- package/dist/utils/detection.js +4 -3
- package/dist/utils/git-lock.js +118 -0
- package/dist/utils/gitignore-updater.js +148 -0
- package/dist/utils/quality-gates.js +47 -7
- package/dist/utils/spec-resolver.js +23 -3
- package/dist/utils/yaml-validation.js +155 -0
- package/dist/validation/spec-validation.js +81 -2
- package/package.json +2 -2
- package/templates/.caws/schemas/waivers.schema.json +30 -0
- package/templates/.caws/schemas/working-spec.schema.json +133 -0
- package/templates/.caws/templates/working-spec.template.yml +74 -0
- package/templates/.caws/tools/README.md +20 -0
- package/templates/.caws/tools/scope-guard.js +208 -0
- package/templates/.caws/tools-allow.json +331 -0
- package/templates/.caws/waivers.yml +19 -0
- package/templates/.cursor/hooks/scope-guard.sh +2 -2
- package/templates/.cursor/hooks/validate-spec.sh +42 -7
- package/templates/apps/tools/caws/COMPLETION_REPORT.md +0 -331
- package/templates/apps/tools/caws/MIGRATION_SUMMARY.md +0 -360
- package/templates/apps/tools/caws/README.md +0 -463
- package/templates/apps/tools/caws/TEST_STATUS.md +0 -365
- package/templates/apps/tools/caws/attest.js +0 -357
- package/templates/apps/tools/caws/ci-optimizer.js +0 -642
- package/templates/apps/tools/caws/config.ts +0 -245
- package/templates/apps/tools/caws/cross-functional.js +0 -876
- package/templates/apps/tools/caws/dashboard.js +0 -1112
- package/templates/apps/tools/caws/flake-detector.ts +0 -362
- package/templates/apps/tools/caws/gates.js +0 -198
- package/templates/apps/tools/caws/gates.ts +0 -271
- package/templates/apps/tools/caws/language-adapters.ts +0 -381
- package/templates/apps/tools/caws/language-support.d.ts +0 -367
- package/templates/apps/tools/caws/language-support.d.ts.map +0 -1
- package/templates/apps/tools/caws/language-support.js +0 -585
- package/templates/apps/tools/caws/legacy-assessment.ts +0 -408
- package/templates/apps/tools/caws/legacy-assessor.js +0 -764
- package/templates/apps/tools/caws/mutant-analyzer.js +0 -734
- package/templates/apps/tools/caws/perf-budgets.ts +0 -349
- package/templates/apps/tools/caws/prompt-lint.js.backup +0 -274
- package/templates/apps/tools/caws/property-testing.js +0 -707
- package/templates/apps/tools/caws/provenance.d.ts +0 -14
- package/templates/apps/tools/caws/provenance.d.ts.map +0 -1
- package/templates/apps/tools/caws/provenance.js +0 -132
- package/templates/apps/tools/caws/provenance.js.backup +0 -73
- package/templates/apps/tools/caws/provenance.ts +0 -211
- package/templates/apps/tools/caws/security-provenance.ts +0 -483
- package/templates/apps/tools/caws/shared/base-tool.ts +0 -281
- package/templates/apps/tools/caws/shared/config-manager.ts +0 -366
- package/templates/apps/tools/caws/shared/gate-checker.ts +0 -849
- package/templates/apps/tools/caws/shared/types.ts +0 -444
- package/templates/apps/tools/caws/shared/validator.ts +0 -305
- package/templates/apps/tools/caws/shared/waivers-manager.ts +0 -174
- package/templates/apps/tools/caws/spec-test-mapper.ts +0 -391
- package/templates/apps/tools/caws/test-quality.js +0 -578
- package/templates/apps/tools/caws/validate.js +0 -76
- package/templates/apps/tools/caws/validate.ts +0 -228
- package/templates/apps/tools/caws/waivers.js +0 -344
- /package/{templates/apps/tools/caws → dist/templates/.caws}/schemas/waivers.schema.json +0 -0
- /package/{templates/apps/tools/caws → dist/templates/.caws}/schemas/working-spec.schema.json +0 -0
- /package/{templates/apps/tools/caws → dist/templates/.caws}/templates/working-spec.template.yml +0 -0
- /package/{templates/apps/tools/caws → dist/templates/.caws/tools}/scope-guard.js +0 -0
- /package/{templates/apps/tools/caws → dist/templates/.caws}/tools-allow.json +0 -0
- /package/{templates/apps/tools/caws → dist/templates/.caws}/waivers.yml +0 -0
|
@@ -196,10 +196,11 @@ async function deriveBudget(spec, projectRoot = process.cwd(), options = {}) {
|
|
|
196
196
|
' This may be a path resolution or caching issue\n'
|
|
197
197
|
);
|
|
198
198
|
} else {
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
199
|
+
// Policy.yaml is optional - defaults work fine, so don't warn unnecessarily
|
|
200
|
+
// Only show info message if user explicitly wants to see it
|
|
201
|
+
if (options.showPolicyInfo !== false) {
|
|
202
|
+
// Silent by default - policy.yaml is optional
|
|
203
|
+
}
|
|
203
204
|
}
|
|
204
205
|
}
|
|
205
206
|
|
|
@@ -240,41 +240,44 @@ async function checkTestFiles() {
|
|
|
240
240
|
* @returns {Promise<Object>} Check result
|
|
241
241
|
*/
|
|
242
242
|
async function checkCAWSTools() {
|
|
243
|
-
|
|
243
|
+
// Check new location first, then legacy location for backward compatibility
|
|
244
|
+
const toolsPath = '.caws/tools';
|
|
245
|
+
const legacyToolsPath = 'apps/tools/caws';
|
|
244
246
|
|
|
245
|
-
if (!(await fs.pathExists(toolsPath))) {
|
|
247
|
+
if (!(await fs.pathExists(toolsPath)) && !(await fs.pathExists(legacyToolsPath))) {
|
|
246
248
|
return {
|
|
247
|
-
passed:
|
|
248
|
-
severity: '
|
|
249
|
-
message: 'CAWS tools directory not found',
|
|
250
|
-
fix: '
|
|
249
|
+
passed: true,
|
|
250
|
+
severity: 'info',
|
|
251
|
+
message: 'CAWS tools directory not found (optional - use CLI commands instead)',
|
|
252
|
+
fix: 'Core functionality available via: caws validate, caws quality-gates, caws provenance',
|
|
251
253
|
autoFixable: false,
|
|
252
254
|
};
|
|
253
255
|
}
|
|
254
256
|
|
|
255
|
-
//
|
|
256
|
-
const
|
|
257
|
-
|
|
257
|
+
// Tools directory exists - check for specialized tools (not core CLI duplicates)
|
|
258
|
+
const specializedTools = ['flake-detector.ts', 'spec-test-mapper.ts', 'perf-budgets.ts'];
|
|
259
|
+
const foundTools = [];
|
|
258
260
|
|
|
259
|
-
for (const tool of
|
|
260
|
-
if (
|
|
261
|
-
|
|
261
|
+
for (const tool of specializedTools) {
|
|
262
|
+
if (await fs.pathExists(path.join(toolsPath, tool))) {
|
|
263
|
+
foundTools.push(tool);
|
|
262
264
|
}
|
|
263
265
|
}
|
|
264
266
|
|
|
265
|
-
if (
|
|
267
|
+
if (foundTools.length === 0) {
|
|
266
268
|
return {
|
|
267
|
-
passed:
|
|
268
|
-
severity: '
|
|
269
|
-
message:
|
|
270
|
-
fix: '
|
|
269
|
+
passed: true,
|
|
270
|
+
severity: 'info',
|
|
271
|
+
message: 'No specialized tools found (optional - use CLI commands for core functionality)',
|
|
272
|
+
fix: 'Core functionality available via: caws validate, caws quality-gates, caws provenance',
|
|
271
273
|
autoFixable: false,
|
|
272
274
|
};
|
|
273
275
|
}
|
|
274
276
|
|
|
275
277
|
return {
|
|
276
278
|
passed: true,
|
|
277
|
-
message:
|
|
279
|
+
message: `Found ${foundTools.length} specialized tool(s): ${foundTools.join(', ')}`,
|
|
280
|
+
note: 'Core functionality (validate, quality-gates, provenance) available via CLI commands',
|
|
278
281
|
};
|
|
279
282
|
}
|
|
280
283
|
|
|
@@ -484,7 +487,9 @@ async function diagnoseCommand(options = {}) {
|
|
|
484
487
|
console.log(chalk.blue(' • Run: caws status --visual to view project health'));
|
|
485
488
|
console.log(chalk.blue(' • Run: caws validate to check working spec'));
|
|
486
489
|
console.log(chalk.blue(' • Optional: Create .caws/policy.yaml for custom budgets'));
|
|
487
|
-
console.log(
|
|
490
|
+
console.log(
|
|
491
|
+
chalk.blue(' • Start implementing: caws iterate --current-state "Ready to begin"')
|
|
492
|
+
);
|
|
488
493
|
}
|
|
489
494
|
} catch (error) {
|
|
490
495
|
console.error(chalk.red('\n❌ Error running diagnosis:'), error.message);
|
package/dist/commands/init.js
CHANGED
|
@@ -17,6 +17,7 @@ const { generateWorkingSpec } = require('../generators/working-spec');
|
|
|
17
17
|
const { finalizeProject } = require('../utils/finalization');
|
|
18
18
|
const { scaffoldCursorHooks } = require('../scaffold/cursor-hooks');
|
|
19
19
|
const { scaffoldIDEIntegrations } = require('../scaffold/index');
|
|
20
|
+
const { updateGitignore } = require('../utils/gitignore-updater');
|
|
20
21
|
|
|
21
22
|
/**
|
|
22
23
|
* Initialize a new project with CAWS
|
|
@@ -361,6 +362,18 @@ async function initProject(projectName, options) {
|
|
|
361
362
|
await fs.writeFile(path.join('.caws', 'working-spec.yaml'), specContent);
|
|
362
363
|
console.log(chalk.green('✅ Created .caws/working-spec.yaml'));
|
|
363
364
|
|
|
365
|
+
// Optionally create policy.yaml (optional - defaults work fine)
|
|
366
|
+
const policyPath = path.join('.caws', 'policy.yaml');
|
|
367
|
+
if (!fs.existsSync(policyPath)) {
|
|
368
|
+
const { PolicyManager } = require('../policy/PolicyManager');
|
|
369
|
+
const policyManager = new PolicyManager();
|
|
370
|
+
const defaultPolicy = policyManager.getDefaultPolicy();
|
|
371
|
+
const yaml = require('js-yaml');
|
|
372
|
+
const policyContent = yaml.dump(defaultPolicy, { indent: 2 });
|
|
373
|
+
await fs.writeFile(policyPath, policyContent);
|
|
374
|
+
console.log(chalk.green('✅ Created .caws/policy.yaml (optional - defaults work fine)'));
|
|
375
|
+
}
|
|
376
|
+
|
|
364
377
|
// Generate additional files if requested
|
|
365
378
|
if (answers.generateExamples) {
|
|
366
379
|
console.log(chalk.blue('📝 Generating example files...'));
|
|
@@ -409,6 +422,17 @@ Happy coding! 🎯
|
|
|
409
422
|
console.log(chalk.blue('🎨 Setting up IDE integrations...'));
|
|
410
423
|
await scaffoldIDEIntegrations(process.cwd(), { force: false });
|
|
411
424
|
|
|
425
|
+
// Update .gitignore to exclude CAWS local runtime files
|
|
426
|
+
console.log(chalk.blue('📝 Updating .gitignore...'));
|
|
427
|
+
const gitignoreUpdated = await updateGitignore(process.cwd());
|
|
428
|
+
if (gitignoreUpdated) {
|
|
429
|
+
console.log(chalk.green('✅ Updated .gitignore to exclude CAWS local runtime files'));
|
|
430
|
+
console.log(
|
|
431
|
+
chalk.gray(' Tracked: Specs, policy, waivers, provenance, plans (shared with team)')
|
|
432
|
+
);
|
|
433
|
+
console.log(chalk.gray(' Ignored: Agent runtime, temp files, logs (local-only)'));
|
|
434
|
+
}
|
|
435
|
+
|
|
412
436
|
// Finalize project
|
|
413
437
|
await finalizeProject(projectName, options, answers);
|
|
414
438
|
} else {
|
|
@@ -456,7 +480,7 @@ Happy coding! 🎯
|
|
|
456
480
|
experimentalSandbox: '',
|
|
457
481
|
aiConfidence: 0.8,
|
|
458
482
|
uncertaintyAreas: '',
|
|
459
|
-
complexityFactors: ''
|
|
483
|
+
complexityFactors: '',
|
|
460
484
|
};
|
|
461
485
|
|
|
462
486
|
const specContent = generateWorkingSpec(defaultAnswers);
|
|
@@ -464,6 +488,18 @@ Happy coding! 🎯
|
|
|
464
488
|
await fs.writeFile(path.join('.caws', 'working-spec.yaml'), specContent);
|
|
465
489
|
console.log(chalk.green('✅ Created .caws/working-spec.yaml'));
|
|
466
490
|
|
|
491
|
+
// Optionally create policy.yaml (optional - defaults work fine)
|
|
492
|
+
const policyPath = path.join('.caws', 'policy.yaml');
|
|
493
|
+
if (!fs.existsSync(policyPath)) {
|
|
494
|
+
const { PolicyManager } = require('../policy/PolicyManager');
|
|
495
|
+
const policyManager = new PolicyManager();
|
|
496
|
+
const defaultPolicy = policyManager.getDefaultPolicy();
|
|
497
|
+
const yaml = require('js-yaml');
|
|
498
|
+
const policyContent = yaml.dump(defaultPolicy, { indent: 2 });
|
|
499
|
+
await fs.writeFile(policyPath, policyContent);
|
|
500
|
+
console.log(chalk.green('✅ Created .caws/policy.yaml (optional - defaults work fine)'));
|
|
501
|
+
}
|
|
502
|
+
|
|
467
503
|
// Setup Cursor hooks by default in non-interactive mode
|
|
468
504
|
console.log(chalk.blue('🎯 Setting up Cursor hooks...'));
|
|
469
505
|
await scaffoldCursorHooks(process.cwd());
|
|
@@ -472,6 +508,17 @@ Happy coding! 🎯
|
|
|
472
508
|
console.log(chalk.blue('🎨 Setting up IDE integrations...'));
|
|
473
509
|
await scaffoldIDEIntegrations(process.cwd(), { force: false });
|
|
474
510
|
|
|
511
|
+
// Update .gitignore to exclude CAWS local runtime files
|
|
512
|
+
console.log(chalk.blue('📝 Updating .gitignore...'));
|
|
513
|
+
const gitignoreUpdated = await updateGitignore(process.cwd());
|
|
514
|
+
if (gitignoreUpdated) {
|
|
515
|
+
console.log(chalk.green('✅ Updated .gitignore to exclude CAWS local runtime files'));
|
|
516
|
+
console.log(
|
|
517
|
+
chalk.gray(' Tracked: Specs, policy, waivers, provenance, plans (shared with team)')
|
|
518
|
+
);
|
|
519
|
+
console.log(chalk.gray(' Ignored: Agent runtime, temp files, logs (local-only)'));
|
|
520
|
+
}
|
|
521
|
+
|
|
475
522
|
// Finalize project
|
|
476
523
|
await finalizeProject(projectName, options, defaultAnswers);
|
|
477
524
|
}
|
|
@@ -481,7 +528,7 @@ Happy coding! 🎯
|
|
|
481
528
|
console.log(chalk.blue('\nNext steps:'));
|
|
482
529
|
console.log('1. Review .caws/working-spec.yaml');
|
|
483
530
|
console.log('2. Customize the specification for your needs');
|
|
484
|
-
|
|
531
|
+
|
|
485
532
|
// Show contract requirements if Tier 1 or 2
|
|
486
533
|
// Use answers if available (interactive mode), otherwise default to 2
|
|
487
534
|
const riskTier = answers?.riskTier || 2;
|
|
@@ -495,7 +542,7 @@ Happy coding! 🎯
|
|
|
495
542
|
console.log(chalk.gray(' description: "Project-level CAWS configuration"'));
|
|
496
543
|
console.log(' Or use "chore" mode for maintenance work (mode: chore)');
|
|
497
544
|
}
|
|
498
|
-
|
|
545
|
+
|
|
499
546
|
console.log('\n📋 Recommended Setup Workflow:');
|
|
500
547
|
console.log(' 1. Review .caws/working-spec.yaml');
|
|
501
548
|
console.log(' 2. Run: caws scaffold (adds tools and templates)');
|
|
@@ -511,7 +558,7 @@ Happy coding! 🎯
|
|
|
511
558
|
if (error.stack) {
|
|
512
559
|
console.error(chalk.gray(error.stack));
|
|
513
560
|
}
|
|
514
|
-
|
|
561
|
+
|
|
515
562
|
// Cleanup on error (only for new directory creation)
|
|
516
563
|
if (projectName && projectName !== '.' && fs.existsSync(projectName)) {
|
|
517
564
|
try {
|
package/dist/commands/specs.js
CHANGED
|
@@ -202,7 +202,46 @@ async function createSpec(id, options = {}) {
|
|
|
202
202
|
const filePath = path.join(SPECS_DIR, fileName);
|
|
203
203
|
|
|
204
204
|
// Write spec file
|
|
205
|
-
|
|
205
|
+
const yamlContent = yaml.dump(specContent, { indent: 2 });
|
|
206
|
+
await fs.writeFile(filePath, yamlContent);
|
|
207
|
+
|
|
208
|
+
// Validate written file (YAML syntax and structure)
|
|
209
|
+
try {
|
|
210
|
+
const writtenContent = await fs.readFile(filePath, 'utf8');
|
|
211
|
+
const parsed = yaml.load(writtenContent);
|
|
212
|
+
|
|
213
|
+
// Validate YAML syntax was preserved
|
|
214
|
+
if (!parsed || typeof parsed !== 'object') {
|
|
215
|
+
await fs.remove(filePath);
|
|
216
|
+
throw new Error('Failed to parse written spec file - invalid YAML structure');
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// Validate spec structure using CAWS validation
|
|
220
|
+
const { validateWorkingSpec } = require('../validation/spec-validation');
|
|
221
|
+
const validation = validateWorkingSpec(parsed);
|
|
222
|
+
|
|
223
|
+
if (!validation.valid) {
|
|
224
|
+
await fs.remove(filePath);
|
|
225
|
+
const errorMessages = validation.errors
|
|
226
|
+
.map((e) => `${e.instancePath}: ${e.message}`)
|
|
227
|
+
.join('; ');
|
|
228
|
+
throw new Error(`Spec validation failed: ${errorMessages}`);
|
|
229
|
+
}
|
|
230
|
+
} catch (error) {
|
|
231
|
+
// Clean up invalid file if it exists
|
|
232
|
+
if (await fs.pathExists(filePath)) {
|
|
233
|
+
await fs.remove(filePath);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// Re-throw with helpful message
|
|
237
|
+
if (error.message.includes('YAMLException') || error.message.includes('yaml')) {
|
|
238
|
+
throw new Error(
|
|
239
|
+
`Failed to create valid spec: YAML syntax error. ${error.message}\n` +
|
|
240
|
+
'💡 Consider using the interactive mode: caws specs create <id> --interactive'
|
|
241
|
+
);
|
|
242
|
+
}
|
|
243
|
+
throw error;
|
|
244
|
+
}
|
|
206
245
|
|
|
207
246
|
// Update registry
|
|
208
247
|
const registry = await loadSpecsRegistry();
|
package/dist/commands/status.js
CHANGED
|
@@ -182,10 +182,10 @@ async function loadWaiverStatus() {
|
|
|
182
182
|
*/
|
|
183
183
|
async function checkQualityGates() {
|
|
184
184
|
// For now, return a placeholder
|
|
185
|
-
//
|
|
185
|
+
// Quality gates are available via CLI or MCP
|
|
186
186
|
return {
|
|
187
187
|
checked: false,
|
|
188
|
-
message: 'Run:
|
|
188
|
+
message: 'Run: caws quality-gates or use MCP tool caws_quality_gates_run for full gate status',
|
|
189
189
|
};
|
|
190
190
|
}
|
|
191
191
|
|
package/dist/commands/tool.js
CHANGED
|
@@ -23,9 +23,8 @@ async function initializeToolSystem() {
|
|
|
23
23
|
if (toolLoader) return toolLoader;
|
|
24
24
|
|
|
25
25
|
try {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
});
|
|
26
|
+
// ToolLoader now checks .caws/tools first, then falls back to legacy location
|
|
27
|
+
toolLoader = new ToolLoader();
|
|
29
28
|
|
|
30
29
|
toolValidator = new ToolValidator();
|
|
31
30
|
|
package/dist/config/index.js
CHANGED
|
@@ -49,15 +49,19 @@ function initializeGlobalSetup() {
|
|
|
49
49
|
function loadProvenanceTools() {
|
|
50
50
|
if (provenanceTools) return provenanceTools; // Already loaded
|
|
51
51
|
|
|
52
|
-
//
|
|
52
|
+
// Provenance tools are now handled by CLI command (caws provenance)
|
|
53
|
+
// Legacy tool loading removed - use CLI instead
|
|
54
|
+
// Try multiple possible locations for provenance tools (legacy support)
|
|
53
55
|
const possiblePaths = [
|
|
54
|
-
// 1.
|
|
55
|
-
path.join(
|
|
56
|
-
// 2.
|
|
56
|
+
// 1. New location (if someone manually adds it)
|
|
57
|
+
path.join(process.cwd(), '.caws/tools/provenance.js'),
|
|
58
|
+
// 2. Legacy location (for backward compatibility)
|
|
57
59
|
path.join(process.cwd(), 'apps/tools/caws/provenance.js'),
|
|
58
|
-
// 3.
|
|
60
|
+
// 3. Bundled templates in CLI package (legacy)
|
|
61
|
+
path.join(__dirname, '../../templates/.caws/tools/provenance.js'),
|
|
62
|
+
// 4. Template package in monorepo (legacy)
|
|
59
63
|
path.join(__dirname, '../../../caws-template/apps/tools/caws/provenance.js'),
|
|
60
|
-
//
|
|
64
|
+
// 5. Detected setup template directory
|
|
61
65
|
null, // Will be set from setup if available
|
|
62
66
|
];
|
|
63
67
|
|
|
@@ -65,7 +69,7 @@ function loadProvenanceTools() {
|
|
|
65
69
|
try {
|
|
66
70
|
const setup = cawsSetup || initializeGlobalSetup();
|
|
67
71
|
if (setup?.hasTemplateDir && setup?.templateDir) {
|
|
68
|
-
possiblePaths[
|
|
72
|
+
possiblePaths[4] = path.join(setup.templateDir, '.caws/tools/provenance.js');
|
|
69
73
|
}
|
|
70
74
|
} catch (setupError) {
|
|
71
75
|
// Continue without detected setup
|
|
@@ -97,8 +101,13 @@ function initializeLanguageSupport() {
|
|
|
97
101
|
if (languageSupport) return languageSupport;
|
|
98
102
|
|
|
99
103
|
try {
|
|
100
|
-
//
|
|
104
|
+
// Language support tools removed - use CLI instead
|
|
105
|
+
// Try multiple possible locations for language support (legacy support)
|
|
101
106
|
const possiblePaths = [
|
|
107
|
+
// New location (if someone manually adds it)
|
|
108
|
+
path.join(process.cwd(), '.caws/tools/language-support.js'),
|
|
109
|
+
// Legacy locations
|
|
110
|
+
path.join(process.cwd(), 'apps/tools/caws/language-support.js'),
|
|
102
111
|
path.join(__dirname, '../../../caws-template/apps/tools/caws/language-support.js'),
|
|
103
112
|
path.join(__dirname, '../../../../caws-template/apps/tools/caws/language-support.js'),
|
|
104
113
|
path.join(process.cwd(), 'packages/caws-template/apps/tools/caws/language-support.js'),
|
|
@@ -42,16 +42,28 @@ function generateWorkingSpec(answers) {
|
|
|
42
42
|
.split(',')
|
|
43
43
|
.map((s) => s.trim())
|
|
44
44
|
.filter((s) => s),
|
|
45
|
-
out: (answers.scopeOut || 'node_modules/, dist/')
|
|
45
|
+
out: (answers.scopeOut || 'node_modules/, dist/, build/')
|
|
46
46
|
.split(',')
|
|
47
47
|
.map((s) => s.trim())
|
|
48
|
-
.filter((s) => s)
|
|
48
|
+
.filter((s) => s)
|
|
49
|
+
// Remove glob patterns - scope.out should only contain directory paths
|
|
50
|
+
.filter((s) => !s.includes('*') && !s.includes('?'))
|
|
51
|
+
// Ensure paths end with / for directories or are explicit file paths
|
|
52
|
+
.map((s) => {
|
|
53
|
+
// If it's a directory pattern without trailing slash, add it
|
|
54
|
+
if (!s.includes('.') && !s.endsWith('/')) {
|
|
55
|
+
return s + '/';
|
|
56
|
+
}
|
|
57
|
+
return s;
|
|
58
|
+
}),
|
|
49
59
|
},
|
|
50
60
|
invariants: (answers.projectInvariants || 'System maintains data consistency')
|
|
51
61
|
.split('\n')
|
|
52
62
|
.map((i) => i.trim())
|
|
53
63
|
.filter((i) => i),
|
|
54
|
-
acceptance: (
|
|
64
|
+
acceptance: (
|
|
65
|
+
answers.acceptanceCriteria || 'Given current state, when action occurs, then expected result'
|
|
66
|
+
)
|
|
55
67
|
.split('\n')
|
|
56
68
|
.filter((a) => a.trim())
|
|
57
69
|
.map((criteria, index) => {
|
|
@@ -107,7 +119,7 @@ function generateWorkingSpec(answers) {
|
|
|
107
119
|
},
|
|
108
120
|
];
|
|
109
121
|
}
|
|
110
|
-
|
|
122
|
+
|
|
111
123
|
// For Tier 1 & 2, provide minimal project_setup contract if none specified
|
|
112
124
|
const riskTier = answers.riskTier || 2;
|
|
113
125
|
if (riskTier === 1 || riskTier === 2) {
|
|
@@ -115,11 +127,12 @@ function generateWorkingSpec(answers) {
|
|
|
115
127
|
{
|
|
116
128
|
type: 'project_setup',
|
|
117
129
|
path: '.caws/working-spec.yaml',
|
|
118
|
-
description:
|
|
130
|
+
description:
|
|
131
|
+
'Project-level CAWS configuration. Feature-specific contracts will be added as features are developed.',
|
|
119
132
|
},
|
|
120
133
|
];
|
|
121
134
|
}
|
|
122
|
-
|
|
135
|
+
|
|
123
136
|
// Tier 3 doesn't require contracts
|
|
124
137
|
return [];
|
|
125
138
|
})(),
|
|
@@ -138,6 +138,100 @@ if [ ! -d ".caws" ]; then
|
|
|
138
138
|
exit 0
|
|
139
139
|
fi
|
|
140
140
|
|
|
141
|
+
# Check for git locks before proceeding
|
|
142
|
+
if [ -f ".git/index.lock" ]; then
|
|
143
|
+
LOCK_AGE=$(($(date +%s) - $(stat -f %m .git/index.lock 2>/dev/null || stat -c %Y .git/index.lock 2>/dev/null || echo 0)))
|
|
144
|
+
LOCK_AGE_MINUTES=$((LOCK_AGE / 60))
|
|
145
|
+
|
|
146
|
+
if [ $LOCK_AGE_MINUTES -gt 5 ]; then
|
|
147
|
+
echo "⚠️ Stale git lock detected (${LOCK_AGE_MINUTES} minutes old)"
|
|
148
|
+
echo "💡 This may indicate a crashed git process"
|
|
149
|
+
echo "💡 Remove stale lock: rm .git/index.lock"
|
|
150
|
+
echo "⚠️ Warning: Check for running git/editor processes before removing"
|
|
151
|
+
exit 1
|
|
152
|
+
else
|
|
153
|
+
echo "⚠️ Git lock detected (${LOCK_AGE_MINUTES} minutes old)"
|
|
154
|
+
echo "💡 Another git process may be running"
|
|
155
|
+
echo "💡 Wait for the other process to complete, or check for running processes"
|
|
156
|
+
exit 1
|
|
157
|
+
fi
|
|
158
|
+
fi
|
|
159
|
+
|
|
160
|
+
# Validate YAML syntax for all CAWS spec files
|
|
161
|
+
echo "🔍 Validating YAML syntax for CAWS spec files..."
|
|
162
|
+
YAML_VALIDATION_FAILED=false
|
|
163
|
+
|
|
164
|
+
# Find all staged .yaml/.yml files in .caws directory
|
|
165
|
+
STAGED_YAML_FILES=$(git diff --cached --name-only --diff-filter=ACM | grep -E '\.caws/.*\.(yaml|yml)$' || true)
|
|
166
|
+
|
|
167
|
+
if [ -n "$STAGED_YAML_FILES" ]; then
|
|
168
|
+
# Use Node.js to validate YAML if available
|
|
169
|
+
if command -v node >/dev/null 2>&1; then
|
|
170
|
+
# Try to use CAWS CLI for validation
|
|
171
|
+
if command -v caws >/dev/null 2>&1; then
|
|
172
|
+
for file in $STAGED_YAML_FILES; do
|
|
173
|
+
if [ -f "$file" ]; then
|
|
174
|
+
# Use Node.js to validate YAML syntax
|
|
175
|
+
if ! node -e "
|
|
176
|
+
const yaml = require('js-yaml');
|
|
177
|
+
const fs = require('fs');
|
|
178
|
+
try {
|
|
179
|
+
const content = fs.readFileSync('$file', 'utf8');
|
|
180
|
+
yaml.load(content);
|
|
181
|
+
process.exit(0);
|
|
182
|
+
} catch (error) {
|
|
183
|
+
console.error('❌ Invalid YAML in $file');
|
|
184
|
+
console.error(' Error:', error.message);
|
|
185
|
+
if (error.mark) {
|
|
186
|
+
console.error(' Line:', error.mark.line + 1, 'Column:', error.mark.column + 1);
|
|
187
|
+
if (error.mark.snippet) console.error(' ' + error.mark.snippet);
|
|
188
|
+
}
|
|
189
|
+
process.exit(1);
|
|
190
|
+
}
|
|
191
|
+
" 2>&1; then
|
|
192
|
+
YAML_VALIDATION_FAILED=true
|
|
193
|
+
fi
|
|
194
|
+
fi
|
|
195
|
+
done
|
|
196
|
+
else
|
|
197
|
+
# Fallback: use node directly with js-yaml
|
|
198
|
+
for file in $STAGED_YAML_FILES; do
|
|
199
|
+
if [ -f "$file" ]; then
|
|
200
|
+
if ! node -e "
|
|
201
|
+
const yaml = require('js-yaml');
|
|
202
|
+
const fs = require('fs');
|
|
203
|
+
try {
|
|
204
|
+
const content = fs.readFileSync('$file', 'utf8');
|
|
205
|
+
yaml.load(content);
|
|
206
|
+
process.exit(0);
|
|
207
|
+
} catch (error) {
|
|
208
|
+
console.error('❌ Invalid YAML in $file');
|
|
209
|
+
console.error(' Error:', error.message);
|
|
210
|
+
if (error.mark) {
|
|
211
|
+
console.error(' Line:', error.mark.line + 1, 'Column:', error.mark.column + 1);
|
|
212
|
+
if (error.mark.snippet) console.error(' ' + error.mark.snippet);
|
|
213
|
+
}
|
|
214
|
+
process.exit(1);
|
|
215
|
+
}
|
|
216
|
+
" 2>&1; then
|
|
217
|
+
YAML_VALIDATION_FAILED=true
|
|
218
|
+
fi
|
|
219
|
+
fi
|
|
220
|
+
done
|
|
221
|
+
fi
|
|
222
|
+
else
|
|
223
|
+
echo "⚠️ Node.js not available - skipping YAML validation"
|
|
224
|
+
echo "💡 Install Node.js to enable YAML syntax validation"
|
|
225
|
+
fi
|
|
226
|
+
fi
|
|
227
|
+
|
|
228
|
+
if [ "$YAML_VALIDATION_FAILED" = true ]; then
|
|
229
|
+
echo "❌ YAML syntax validation failed - commit blocked"
|
|
230
|
+
echo "💡 Fix YAML syntax errors above before committing"
|
|
231
|
+
echo "💡 Consider using 'caws specs create <id>' instead of manual creation"
|
|
232
|
+
exit 1
|
|
233
|
+
fi
|
|
234
|
+
|
|
141
235
|
# Fallback chain for quality gates:
|
|
142
236
|
# 1. Try Node.js script (if exists)
|
|
143
237
|
# 2. Try CAWS CLI
|
|
@@ -231,38 +325,41 @@ fi
|
|
|
231
325
|
# Run hidden TODO analysis on staged files only (if available)
|
|
232
326
|
if [ "$QUALITY_GATES_RAN" = true ]; then
|
|
233
327
|
echo "🔍 Checking for hidden TODOs in staged files..."
|
|
234
|
-
|
|
328
|
+
|
|
329
|
+
# Find TODO analyzer .mjs file (preferred - no Python dependency)
|
|
330
|
+
TODO_ANALYZER=""
|
|
331
|
+
|
|
332
|
+
# Try quality gates package TODO analyzer (published package)
|
|
235
333
|
if [ -f "node_modules/@paths.design/quality-gates/todo-analyzer.mjs" ]; then
|
|
236
|
-
|
|
237
|
-
if node node_modules/@paths.design/quality-gates/todo-analyzer.mjs --staged-only --ci-mode --min-confidence 0.8 >/dev/null 2>&1; then
|
|
238
|
-
echo "✅ No critical hidden TODOs found in staged files"
|
|
239
|
-
else
|
|
240
|
-
echo "❌ Critical hidden TODOs detected in staged files - commit blocked"
|
|
241
|
-
echo "💡 Fix stub implementations and placeholder code before committing"
|
|
242
|
-
echo "📖 See docs/PLACEHOLDER-DETECTION-GUIDE.md for classification"
|
|
243
|
-
echo ""
|
|
244
|
-
echo "🔍 Running detailed analysis on staged files..."
|
|
245
|
-
node node_modules/@paths.design/quality-gates/todo-analyzer.mjs --staged-only --min-confidence 0.8
|
|
246
|
-
exit 1
|
|
247
|
-
fi
|
|
248
|
-
fi
|
|
334
|
+
TODO_ANALYZER="node_modules/@paths.design/quality-gates/todo-analyzer.mjs"
|
|
249
335
|
# Try quality gates package TODO analyzer (monorepo/local copy)
|
|
250
336
|
elif [ -f "node_modules/@caws/quality-gates/todo-analyzer.mjs" ]; then
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
337
|
+
TODO_ANALYZER="node_modules/@caws/quality-gates/todo-analyzer.mjs"
|
|
338
|
+
# Try monorepo structure (development)
|
|
339
|
+
elif [ -f "packages/quality-gates/todo-analyzer.mjs" ]; then
|
|
340
|
+
TODO_ANALYZER="packages/quality-gates/todo-analyzer.mjs"
|
|
341
|
+
# Try local copy in scripts directory (if scaffolded)
|
|
342
|
+
elif [ -f "scripts/todo-analyzer.mjs" ]; then
|
|
343
|
+
TODO_ANALYZER="scripts/todo-analyzer.mjs"
|
|
344
|
+
fi
|
|
345
|
+
|
|
346
|
+
# Run TODO analyzer if found
|
|
347
|
+
if [ -n "$TODO_ANALYZER" ] && command -v node >/dev/null 2>&1; then
|
|
348
|
+
if node "$TODO_ANALYZER" --staged-only --ci-mode --min-confidence 0.8 >/dev/null 2>&1; then
|
|
349
|
+
echo "✅ No critical hidden TODOs found in staged files"
|
|
350
|
+
else
|
|
351
|
+
echo "❌ Critical hidden TODOs detected in staged files - commit blocked"
|
|
352
|
+
echo "💡 Fix stub implementations and placeholder code before committing"
|
|
353
|
+
echo "📖 See docs/PLACEHOLDER-DETECTION-GUIDE.md for classification"
|
|
354
|
+
echo ""
|
|
355
|
+
echo "🔍 Running detailed analysis on staged files..."
|
|
356
|
+
node "$TODO_ANALYZER" --staged-only --min-confidence 0.8
|
|
357
|
+
exit 1
|
|
263
358
|
fi
|
|
264
|
-
# Fallback to legacy Python analyzer
|
|
359
|
+
# Fallback to legacy Python analyzer (deprecated - will be removed)
|
|
265
360
|
elif command -v python3 >/dev/null 2>&1 && [ -f "scripts/v3/analysis/todo_analyzer.py" ]; then
|
|
361
|
+
echo "⚠️ Using legacy Python TODO analyzer (deprecated)"
|
|
362
|
+
echo "💡 Install @paths.design/quality-gates for Node.js version: npm install --save-dev @paths.design/quality-gates"
|
|
266
363
|
if python3 scripts/v3/analysis/todo_analyzer.py --staged-only --ci-mode --min-confidence 0.8 >/dev/null 2>&1; then
|
|
267
364
|
echo "✅ No critical hidden TODOs found in staged files"
|
|
268
365
|
else
|
|
@@ -274,8 +371,9 @@ if [ "$QUALITY_GATES_RAN" = true ]; then
|
|
|
274
371
|
python3 scripts/v3/analysis/todo_analyzer.py --staged-only --min-confidence 0.8
|
|
275
372
|
exit 1
|
|
276
373
|
fi
|
|
277
|
-
|
|
278
|
-
echo "⚠️
|
|
374
|
+
else
|
|
375
|
+
echo "⚠️ TODO analyzer not available - skipping hidden TODO check"
|
|
376
|
+
echo "💡 Install @paths.design/quality-gates for TODO analysis: npm install --save-dev @paths.design/quality-gates"
|
|
279
377
|
fi
|
|
280
378
|
fi
|
|
281
379
|
|