@paths.design/caws-cli 7.0.1 → 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.
Files changed (121) hide show
  1. package/dist/budget-derivation.js +5 -4
  2. package/dist/commands/diagnose.js +26 -20
  3. package/dist/commands/init.js +72 -5
  4. package/dist/commands/specs.js +40 -1
  5. package/dist/commands/status.js +2 -2
  6. package/dist/commands/templates.js +10 -0
  7. package/dist/commands/tool.js +2 -3
  8. package/dist/commands/validate.js +12 -0
  9. package/dist/config/index.js +17 -8
  10. package/dist/generators/working-spec.js +42 -9
  11. package/dist/index.js +3 -1
  12. package/dist/scaffold/cursor-hooks.js +10 -2
  13. package/dist/scaffold/git-hooks.js +189 -32
  14. package/dist/scaffold/index.js +105 -17
  15. package/dist/templates/.caws/tools/README.md +20 -0
  16. package/dist/templates/.cursor/README.md +311 -0
  17. package/dist/templates/.cursor/hooks/audit.sh +55 -0
  18. package/dist/templates/.cursor/hooks/block-dangerous.sh +83 -0
  19. package/dist/templates/.cursor/hooks/caws-quality-check.sh +52 -0
  20. package/dist/templates/.cursor/hooks/caws-scope-guard.sh +130 -0
  21. package/dist/templates/.cursor/hooks/caws-tool-validation.sh +121 -0
  22. package/dist/templates/.cursor/hooks/format.sh +38 -0
  23. package/dist/templates/.cursor/hooks/naming-check.sh +64 -0
  24. package/dist/templates/.cursor/hooks/scan-secrets.sh +46 -0
  25. package/dist/templates/.cursor/hooks/scope-guard.sh +52 -0
  26. package/dist/templates/.cursor/hooks/validate-spec.sh +83 -0
  27. package/dist/templates/.cursor/hooks.json +59 -0
  28. package/dist/templates/.cursor/rules/00-claims-verification.mdc +144 -0
  29. package/dist/templates/.cursor/rules/01-working-style.mdc +50 -0
  30. package/dist/templates/.cursor/rules/02-quality-gates.mdc +370 -0
  31. package/dist/templates/.cursor/rules/03-naming-and-refactor.mdc +33 -0
  32. package/dist/templates/.cursor/rules/04-logging-language-style.mdc +23 -0
  33. package/dist/templates/.cursor/rules/05-safe-defaults-guards.mdc +23 -0
  34. package/dist/templates/.cursor/rules/06-typescript-conventions.mdc +36 -0
  35. package/dist/templates/.cursor/rules/07-process-ops.mdc +20 -0
  36. package/dist/templates/.cursor/rules/08-solid-and-architecture.mdc +16 -0
  37. package/dist/templates/.cursor/rules/09-docstrings.mdc +89 -0
  38. package/dist/templates/.cursor/rules/10-documentation-quality-standards.mdc +390 -0
  39. package/dist/templates/.cursor/rules/11-scope-management-waivers.mdc +385 -0
  40. package/dist/templates/.cursor/rules/12-implementation-completeness.mdc +516 -0
  41. package/dist/templates/.cursor/rules/13-language-agnostic-standards.mdc +588 -0
  42. package/dist/templates/.cursor/rules/README.md +148 -0
  43. package/dist/templates/.github/copilot/instructions.md +311 -0
  44. package/dist/templates/.idea/runConfigurations/CAWS_Evaluate.xml +5 -0
  45. package/dist/templates/.idea/runConfigurations/CAWS_Validate.xml +5 -0
  46. package/dist/templates/.vscode/launch.json +56 -0
  47. package/dist/templates/.vscode/settings.json +93 -0
  48. package/dist/templates/.windsurf/workflows/caws-guided-development.md +92 -0
  49. package/dist/templates/COMMIT_CONVENTIONS.md +86 -0
  50. package/dist/templates/OIDC_SETUP.md +300 -0
  51. package/dist/templates/agents.md +1047 -0
  52. package/dist/templates/codemod/README.md +1 -0
  53. package/dist/templates/codemod/test.js +93 -0
  54. package/dist/templates/docs/README.md +150 -0
  55. package/dist/templates/scripts/quality-gates/check-god-objects.js +146 -0
  56. package/dist/templates/scripts/quality-gates/run-quality-gates.js +50 -0
  57. package/dist/templates/scripts/v3/analysis/todo_analyzer.py +1997 -0
  58. package/dist/tool-loader.js +6 -1
  59. package/dist/tool-validator.js +8 -2
  60. package/dist/utils/detection.js +34 -6
  61. package/dist/utils/git-lock.js +118 -0
  62. package/dist/utils/gitignore-updater.js +148 -0
  63. package/dist/utils/quality-gates.js +47 -7
  64. package/dist/utils/spec-resolver.js +23 -3
  65. package/dist/utils/yaml-validation.js +155 -0
  66. package/dist/validation/spec-validation.js +105 -2
  67. package/package.json +2 -2
  68. package/templates/.caws/schemas/waivers.schema.json +30 -0
  69. package/templates/.caws/schemas/working-spec.schema.json +133 -0
  70. package/templates/.caws/templates/working-spec.template.yml +74 -0
  71. package/templates/.caws/tools/README.md +20 -0
  72. package/templates/.caws/tools/scope-guard.js +208 -0
  73. package/templates/.caws/tools-allow.json +331 -0
  74. package/templates/.caws/waivers.yml +19 -0
  75. package/templates/.cursor/hooks/scope-guard.sh +2 -2
  76. package/templates/.cursor/hooks/validate-spec.sh +42 -7
  77. package/templates/apps/tools/caws/COMPLETION_REPORT.md +0 -331
  78. package/templates/apps/tools/caws/MIGRATION_SUMMARY.md +0 -360
  79. package/templates/apps/tools/caws/README.md +0 -463
  80. package/templates/apps/tools/caws/TEST_STATUS.md +0 -365
  81. package/templates/apps/tools/caws/attest.js +0 -357
  82. package/templates/apps/tools/caws/ci-optimizer.js +0 -642
  83. package/templates/apps/tools/caws/config.ts +0 -245
  84. package/templates/apps/tools/caws/cross-functional.js +0 -876
  85. package/templates/apps/tools/caws/dashboard.js +0 -1112
  86. package/templates/apps/tools/caws/flake-detector.ts +0 -362
  87. package/templates/apps/tools/caws/gates.js +0 -198
  88. package/templates/apps/tools/caws/gates.ts +0 -271
  89. package/templates/apps/tools/caws/language-adapters.ts +0 -381
  90. package/templates/apps/tools/caws/language-support.d.ts +0 -367
  91. package/templates/apps/tools/caws/language-support.d.ts.map +0 -1
  92. package/templates/apps/tools/caws/language-support.js +0 -585
  93. package/templates/apps/tools/caws/legacy-assessment.ts +0 -408
  94. package/templates/apps/tools/caws/legacy-assessor.js +0 -764
  95. package/templates/apps/tools/caws/mutant-analyzer.js +0 -734
  96. package/templates/apps/tools/caws/perf-budgets.ts +0 -349
  97. package/templates/apps/tools/caws/prompt-lint.js.backup +0 -274
  98. package/templates/apps/tools/caws/property-testing.js +0 -707
  99. package/templates/apps/tools/caws/provenance.d.ts +0 -14
  100. package/templates/apps/tools/caws/provenance.d.ts.map +0 -1
  101. package/templates/apps/tools/caws/provenance.js +0 -132
  102. package/templates/apps/tools/caws/provenance.js.backup +0 -73
  103. package/templates/apps/tools/caws/provenance.ts +0 -211
  104. package/templates/apps/tools/caws/security-provenance.ts +0 -483
  105. package/templates/apps/tools/caws/shared/base-tool.ts +0 -281
  106. package/templates/apps/tools/caws/shared/config-manager.ts +0 -366
  107. package/templates/apps/tools/caws/shared/gate-checker.ts +0 -849
  108. package/templates/apps/tools/caws/shared/types.ts +0 -444
  109. package/templates/apps/tools/caws/shared/validator.ts +0 -305
  110. package/templates/apps/tools/caws/shared/waivers-manager.ts +0 -174
  111. package/templates/apps/tools/caws/spec-test-mapper.ts +0 -391
  112. package/templates/apps/tools/caws/test-quality.js +0 -578
  113. package/templates/apps/tools/caws/validate.js +0 -76
  114. package/templates/apps/tools/caws/validate.ts +0 -228
  115. package/templates/apps/tools/caws/waivers.js +0 -344
  116. /package/{templates/apps/tools/caws → dist/templates/.caws}/schemas/waivers.schema.json +0 -0
  117. /package/{templates/apps/tools/caws → dist/templates/.caws}/schemas/working-spec.schema.json +0 -0
  118. /package/{templates/apps/tools/caws → dist/templates/.caws}/templates/working-spec.template.yml +0 -0
  119. /package/{templates/apps/tools/caws → dist/templates/.caws/tools}/scope-guard.js +0 -0
  120. /package/{templates/apps/tools/caws → dist/templates/.caws}/tools-allow.json +0 -0
  121. /package/{templates/apps/tools/caws → dist/templates/.caws}/waivers.yml +0 -0
@@ -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
- # Try quality gates package TODO analyzer first (published package)
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
- if command -v node >/dev/null 2>&1; then
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
- if command -v node >/dev/null 2>&1; then
252
- if node node_modules/@caws/quality-gates/todo-analyzer.mjs --staged-only --ci-mode --min-confidence 0.8 >/dev/null 2>&1; then
253
- echo "✅ No critical hidden TODOs found in staged files"
254
- else
255
- echo "❌ Critical hidden TODOs detected in staged files - commit blocked"
256
- echo "💡 Fix stub implementations and placeholder code before committing"
257
- echo "📖 See docs/PLACEHOLDER-DETECTION-GUIDE.md for classification"
258
- echo ""
259
- echo "🔍 Running detailed analysis on staged files..."
260
- node node_modules/@caws/quality-gates/todo-analyzer.mjs --staged-only --min-confidence 0.8
261
- exit 1
262
- fi
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
- elif command -v python3 >/dev/null 2>&1; then
278
- echo "⚠️ Python3 found but TODO analyzer not available - skipping"
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
 
@@ -364,12 +462,71 @@ fi
364
462
  # Run full validation suite
365
463
  if command -v caws >/dev/null 2>&1; then
366
464
  echo "📋 Running comprehensive CAWS validation..."
367
- if caws validate --quiet; then
465
+
466
+ # Run validation and capture output
467
+ VALIDATION_OUTPUT=$(caws validate 2>&1)
468
+ VALIDATION_EXIT=$?
469
+
470
+ if [ $VALIDATION_EXIT -eq 0 ]; then
368
471
  echo "✅ CAWS validation passed"
369
472
  else
370
473
  echo "❌ CAWS validation failed"
371
- echo "💡 Fix issues locally, then push again"
372
- echo "💡 You can commit fixes with: git commit --no-verify"
474
+ echo ""
475
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
476
+ echo "Validation Errors:"
477
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
478
+ echo "$VALIDATION_OUTPUT" | grep -E "(❌|error|Error|Missing|required)" || echo "$VALIDATION_OUTPUT"
479
+ echo ""
480
+
481
+ # Check for contract-related errors
482
+ if echo "$VALIDATION_OUTPUT" | grep -qi "contract"; then
483
+ echo "💡 Contract Requirements:"
484
+ echo " • Tier 1 & 2 changes require at least one contract"
485
+ echo " • For infrastructure/setup work, use 'chore' mode or add a minimal contract:"
486
+ echo ""
487
+ echo " Example minimal contract (.caws/working-spec.yaml):"
488
+ echo " contracts:"
489
+ echo " - type: 'project_setup'"
490
+ echo " path: '.caws/working-spec.yaml'"
491
+ echo " description: 'Project-level CAWS configuration'"
492
+ echo ""
493
+ echo " Or change mode to 'chore' for maintenance work:"
494
+ echo " mode: chore"
495
+ echo ""
496
+ fi
497
+
498
+ # Check for active waivers
499
+ echo "🔍 Checking for active waivers..."
500
+ if command -v caws >/dev/null 2>&1 && caws waivers list --status=active --format=count 2>/dev/null | grep -q "[1-9]"; then
501
+ ACTIVE_WAIVERS=$(caws waivers list --status=active 2>/dev/null)
502
+ echo "⚠️ Active waivers found:"
503
+ echo "$ACTIVE_WAIVERS" | head -5
504
+ echo ""
505
+ echo "💡 Note: Waivers may not cover all validation failures"
506
+ echo " Review waiver coverage: caws waivers list --status=active"
507
+ else
508
+ echo " No active waivers found"
509
+ echo ""
510
+ echo "💡 If this is infrastructure/setup work, you can create a waiver:"
511
+ echo " caws waivers create \\"
512
+ echo " --title='Initial CAWS setup' \\"
513
+ echo " --reason=infrastructure_limitation \\"
514
+ echo " --gates=contracts \\"
515
+ echo " --expires-at='2024-12-31T23:59:59Z' \\"
516
+ echo " --approved-by='@your-team' \\"
517
+ echo " --impact-level=low \\"
518
+ echo " --mitigation-plan='Contracts will be added as features are developed'"
519
+ fi
520
+
521
+ echo ""
522
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
523
+ echo "Next Steps:"
524
+ echo " 1. Review errors above"
525
+ echo " 2. Fix issues in .caws/working-spec.yaml"
526
+ echo " 3. Run: caws validate (to verify fixes)"
527
+ echo " 4. Commit fixes: git commit --no-verify (allowed)"
528
+ echo " 5. Push again: git push"
529
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
373
530
  exit 1
374
531
  fi
375
532
  fi
@@ -9,11 +9,12 @@ const path = require('path');
9
9
  const chalk = require('chalk');
10
10
 
11
11
  // Import detection utilities
12
- const { detectCAWSSetup } = require('../utils/detection');
12
+ const { detectCAWSSetup, findPackageRoot } = require('../utils/detection');
13
13
  const { detectsPublishing } = require('../utils/project-analysis');
14
14
 
15
15
  // Import git hooks scaffolding
16
16
  const { scaffoldGitHooks } = require('./git-hooks');
17
+ const { updateGitignore } = require('../utils/gitignore-updater');
17
18
 
18
19
  // CLI version from package.json
19
20
  const CLI_VERSION = require('../../package.json').version;
@@ -23,8 +24,33 @@ const CLI_VERSION = require('../../package.json').version;
23
24
  * @param {string} targetDir - Target directory for scaffolding
24
25
  * @param {Object} options - Scaffold options
25
26
  */
27
+ /**
28
+ * Find the template directory using robust path resolution
29
+ * Works in both development and global install scenarios
30
+ * @returns {string|null} Template directory path or null
31
+ */
32
+ function findTemplateDir() {
33
+ // Find package root using shared utility
34
+ const packageRoot = findPackageRoot(__dirname);
35
+
36
+ // Try templates relative to package root first (works in both dev and global install)
37
+ const possiblePaths = [
38
+ path.join(packageRoot, 'templates'),
39
+ path.resolve(__dirname, '../../templates'), // Dev fallback
40
+ path.resolve(__dirname, '../templates'), // Legacy fallback
41
+ ];
42
+
43
+ for (const testPath of possiblePaths) {
44
+ if (fs.existsSync(testPath)) {
45
+ return testPath;
46
+ }
47
+ }
48
+
49
+ return null;
50
+ }
51
+
26
52
  async function scaffoldIDEIntegrations(targetDir, options) {
27
- const templateDir = path.join(__dirname, '../../templates');
53
+ const templateDir = findTemplateDir() || path.join(__dirname, '../../templates');
28
54
 
29
55
  console.log(chalk.cyan('🎨 Setting up IDE integrations...'));
30
56
 
@@ -192,19 +218,24 @@ async function scaffoldProject(options) {
192
218
  setup.templateDir = cawsSetup.templateDir;
193
219
  setup.hasTemplateDir = true;
194
220
  } else if (!setup.templateDir) {
195
- // Try to find template directory using absolute paths that work in CI
221
+ // Try to find template directory using robust path resolution
196
222
  const possiblePaths = [
197
- // 1. Bundled templates in CLI package (for global installs) - CHECK THIS FIRST!
223
+ // 1. Use the helper function to find templates (works in dev and global install)
224
+ findTemplateDir(),
225
+ // 2. Bundled templates relative to package root
226
+ path.join(findPackageRoot(__dirname), 'templates'),
227
+ // 3. Legacy fallback paths
198
228
  path.join(__dirname, '../../templates'),
199
- // 2. CI paths
229
+ path.join(__dirname, '../templates'),
230
+ // 4. CI paths
200
231
  '/home/runner/work/coding-agent-working-standard/coding-agent-working-standard/packages/caws-template',
201
232
  '/workspace/packages/caws-template',
202
233
  '/caws/packages/caws-template',
203
- // 3. Monorepo relative paths
234
+ // 5. Monorepo relative paths
204
235
  path.resolve(process.cwd(), '../../../packages/caws-template'),
205
236
  path.resolve(process.cwd(), '../../packages/caws-template'),
206
237
  path.resolve(process.cwd(), '../packages/caws-template'),
207
- ];
238
+ ].filter(Boolean); // Remove null values
208
239
 
209
240
  for (const testPath of possiblePaths) {
210
241
  if (fs.existsSync(testPath)) {
@@ -271,12 +302,32 @@ async function scaffoldProject(options) {
271
302
  // Determine what enhancements to add based on setup type and options
272
303
  const enhancements = [];
273
304
 
274
- // Add CAWS tools directory structure (matches test expectations)
305
+ // Add CAWS tools to .caws/ directory (keeps all CAWS files together)
275
306
  enhancements.push({
276
- name: 'apps/tools/caws',
307
+ name: '.caws/tools',
277
308
  description: 'CAWS tools directory',
278
309
  required: true,
279
310
  });
311
+ enhancements.push({
312
+ name: '.caws/schemas',
313
+ description: 'CAWS JSON schemas',
314
+ required: true,
315
+ });
316
+ enhancements.push({
317
+ name: '.caws/templates',
318
+ description: 'CAWS templates',
319
+ required: true,
320
+ });
321
+ enhancements.push({
322
+ name: '.caws/waivers.yml',
323
+ description: 'CAWS waivers configuration',
324
+ required: false,
325
+ });
326
+ enhancements.push({
327
+ name: '.caws/tools-allow.json',
328
+ description: 'CAWS tools allowlist',
329
+ required: false,
330
+ });
280
331
 
281
332
  // Add codemods if requested or not minimal
282
333
  if (options.withCodemods || (!options.minimal && !options.withCodemods)) {
@@ -427,6 +478,19 @@ async function scaffoldProject(options) {
427
478
  console.log(
428
479
  chalk.gray(' For now, quality gates will work via CAWS CLI or local scripts')
429
480
  );
481
+
482
+ // Copy todo-analyzer.mjs locally as fallback if available
483
+ const qualityGatesPath = path.resolve(__dirname, '../../../quality-gates');
484
+ const todoAnalyzerSource = path.join(qualityGatesPath, 'todo-analyzer.mjs');
485
+ if (fs.existsSync(todoAnalyzerSource)) {
486
+ const scriptsDir = path.join(currentDir, 'scripts');
487
+ await fs.ensureDir(scriptsDir);
488
+ const todoAnalyzerDest = path.join(scriptsDir, 'todo-analyzer.mjs');
489
+ await fs.copy(todoAnalyzerSource, todoAnalyzerDest);
490
+ console.log(
491
+ chalk.green('✅ Copied todo-analyzer.mjs to scripts/ directory (local fallback)')
492
+ );
493
+ }
430
494
  }
431
495
  } else {
432
496
  // No package.json - suggest global install or manual setup
@@ -567,10 +631,24 @@ async function scaffoldProject(options) {
567
631
  console.warn(chalk.yellow(`⚠️ Failed to add ${enhancement.name}:`), copyError.message);
568
632
  }
569
633
  } else {
570
- // If source doesn't exist in template, create the directory structure
634
+ // If source doesn't exist in template, check if it should be a file or directory
571
635
  try {
572
- await fs.ensureDir(destPath);
573
- console.log(chalk.green(`✅ Created ${enhancement.description}`));
636
+ // Check if the enhancement name looks like a file (has extension)
637
+ const hasExtension = path.extname(enhancement.name).length > 0;
638
+
639
+ if (hasExtension) {
640
+ // Create an empty file for file-like enhancements
641
+ await fs.ensureDir(path.dirname(destPath));
642
+ await fs.writeFile(destPath, '');
643
+ console.log(
644
+ chalk.yellow(`⚠️ Created empty ${enhancement.description} (template not found)`)
645
+ );
646
+ console.log(chalk.gray(` Template expected at: ${sourcePath}`));
647
+ } else {
648
+ // Create directory for directory-like enhancements
649
+ await fs.ensureDir(destPath);
650
+ console.log(chalk.green(`✅ Created ${enhancement.description}`));
651
+ }
574
652
  addedCount++;
575
653
  addedFiles.push(enhancement.name);
576
654
  } catch (createError) {
@@ -629,19 +707,19 @@ async function scaffoldProject(options) {
629
707
  console.log('3. Push to trigger automated publishing');
630
708
  console.log('4. Your existing CAWS tools remain unchanged');
631
709
  } else {
632
- console.log('2. Customize your working spec in .caws/working-spec.yaml');
633
- console.log('3. Run validation: caws validate --suggestions');
710
+ console.log('2. Run: caws validate (verify setup)');
711
+ console.log('3. Run: caws diagnose (check project health)');
712
+ console.log('4. Customize .caws/working-spec.yaml for your project');
713
+ console.log('5. Optional: Create .caws/policy.yaml for tier-specific budgets');
634
714
  if (!qualityGatesAdded && !options.minimal) {
635
715
  console.log(
636
- chalk.gray('4. Note: Quality gates scripts skipped (git hooks use CAWS CLI by default)')
716
+ chalk.gray('6. Note: Quality gates scripts skipped (git hooks use CAWS CLI by default)')
637
717
  );
638
718
  console.log(
639
719
  chalk.gray(
640
720
  ' Add --with-quality-gates flag if you want local scripts without global CLI'
641
721
  )
642
722
  );
643
- } else {
644
- console.log('4. Your existing CAWS tools remain unchanged');
645
723
  }
646
724
  }
647
725
  }
@@ -656,6 +734,16 @@ async function scaffoldProject(options) {
656
734
  console.log(chalk.yellow('\n⚠️ Force mode was used - review changes carefully'));
657
735
  }
658
736
 
737
+ // Update .gitignore to exclude CAWS local runtime files
738
+ const gitignoreUpdated = await updateGitignore(targetDir);
739
+ if (gitignoreUpdated) {
740
+ console.log(chalk.green('\n✅ Updated .gitignore to exclude CAWS local runtime files'));
741
+ console.log(
742
+ chalk.gray(' Tracked: Specs, policy, waivers, provenance, plans (shared with team)')
743
+ );
744
+ console.log(chalk.gray(' Ignored: Agent runtime, temp files, logs (local-only)'));
745
+ }
746
+
659
747
  // Save provenance manifest if tools are available
660
748
  const tools = loadProvenanceTools && loadProvenanceTools();
661
749
  if (tools && typeof tools.saveProvenance === 'function') {
@@ -0,0 +1,20 @@
1
+ # CAWS Tools
2
+
3
+ This directory contains CAWS-specific tools that aren't available in the CLI.
4
+
5
+ ## scope-guard.js
6
+
7
+ Enforces that experimental code stays within designated sandbox areas. Used by Cursor hooks for scope validation.
8
+
9
+ ```bash
10
+ # Validate experimental code containment
11
+ node .caws/tools/scope-guard.js validate
12
+
13
+ # Check containment status
14
+ node .caws/tools/scope-guard.js check .caws/working-spec.yaml
15
+ ```
16
+
17
+ **Usage in Cursor Hooks:**
18
+
19
+ The `.cursor/hooks/scope-guard.sh` hook automatically uses this tool to validate file attachments against working spec scope boundaries.
20
+