@paths.design/caws-cli 7.0.3 → 8.0.1

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 (59) hide show
  1. package/dist/budget-derivation.d.ts.map +1 -1
  2. package/dist/commands/diagnose.d.ts.map +1 -1
  3. package/dist/commands/init.d.ts.map +1 -1
  4. package/dist/commands/provenance.d.ts +1 -1
  5. package/dist/commands/provenance.d.ts.map +1 -1
  6. package/dist/commands/quality-gates.d.ts +0 -46
  7. package/dist/commands/quality-gates.d.ts.map +1 -1
  8. package/dist/commands/quality-gates.js +226 -11
  9. package/dist/commands/specs.d.ts.map +1 -1
  10. package/dist/commands/specs.js +108 -13
  11. package/dist/commands/status.d.ts.map +1 -1
  12. package/dist/commands/templates.d.ts.map +1 -1
  13. package/dist/commands/tool.d.ts +1 -1
  14. package/dist/commands/tool.d.ts.map +1 -1
  15. package/dist/commands/tool.js +0 -1
  16. package/dist/commands/validate.d.ts.map +1 -1
  17. package/dist/commands/waivers.d.ts +1 -1
  18. package/dist/commands/waivers.d.ts.map +1 -1
  19. package/dist/config/index.d.ts.map +1 -1
  20. package/dist/generators/working-spec.d.ts.map +1 -1
  21. package/dist/index.js +10 -0
  22. package/dist/policy/PolicyManager.d.ts.map +1 -1
  23. package/dist/scaffold/cursor-hooks.d.ts.map +1 -1
  24. package/dist/scaffold/git-hooks.d.ts +18 -0
  25. package/dist/scaffold/git-hooks.d.ts.map +1 -1
  26. package/dist/scaffold/git-hooks.js +159 -58
  27. package/dist/scaffold/index.d.ts +1 -6
  28. package/dist/scaffold/index.d.ts.map +1 -1
  29. package/dist/scaffold/index.js +1 -1
  30. package/dist/templates/.caws/tools/README.md +1 -0
  31. package/dist/tool-loader.d.ts.map +1 -1
  32. package/dist/tool-validator.d.ts.map +1 -1
  33. package/dist/utils/async-utils.d.ts +73 -0
  34. package/dist/utils/async-utils.d.ts.map +1 -0
  35. package/dist/utils/command-wrapper.d.ts +66 -0
  36. package/dist/utils/command-wrapper.d.ts.map +1 -0
  37. package/dist/utils/detection.d.ts +7 -0
  38. package/dist/utils/detection.d.ts.map +1 -1
  39. package/dist/utils/git-lock.d.ts +13 -0
  40. package/dist/utils/git-lock.d.ts.map +1 -0
  41. package/dist/utils/git-lock.js +1 -0
  42. package/dist/utils/gitignore-updater.d.ts +39 -0
  43. package/dist/utils/gitignore-updater.d.ts.map +1 -0
  44. package/dist/utils/project-analysis.d.ts +20 -0
  45. package/dist/utils/project-analysis.d.ts.map +1 -1
  46. package/dist/utils/project-analysis.js +176 -16
  47. package/dist/utils/promise-utils.d.ts +30 -0
  48. package/dist/utils/promise-utils.d.ts.map +1 -0
  49. package/dist/utils/quality-gates.d.ts.map +1 -1
  50. package/dist/utils/quality-gates.js +7 -6
  51. package/dist/utils/spec-resolver.d.ts +1 -9
  52. package/dist/utils/spec-resolver.d.ts.map +1 -1
  53. package/dist/utils/spec-resolver.js +4 -0
  54. package/dist/utils/yaml-validation.d.ts +32 -0
  55. package/dist/utils/yaml-validation.d.ts.map +1 -0
  56. package/dist/utils/yaml-validation.js +1 -0
  57. package/dist/validation/spec-validation.d.ts.map +1 -1
  58. package/package.json +1 -1
  59. package/templates/.caws/tools/README.md +1 -0
package/dist/index.js CHANGED
@@ -142,6 +142,8 @@ program
142
142
  ''
143
143
  )
144
144
  .option('--fix', 'Attempt automatic fixes (experimental)', false)
145
+ .option('--context <context>', 'Execution context: commit (staged files), push (all tracked files), or ci (all tracked files)', 'commit')
146
+ .option('--all-files', 'Check all tracked files (equivalent to --context=ci)', false)
145
147
  .option('--help', 'Show detailed help and usage examples', false)
146
148
  .action(async (options) => {
147
149
  // Handle --help flag
@@ -161,6 +163,8 @@ OPTIONS:
161
163
  --json Output machine-readable JSON to stdout
162
164
  --gates=<gates> Run only specific gates (comma-separated)
163
165
  --fix Attempt automatic fixes (experimental)
166
+ --context=<ctx> Execution context: commit (staged files), push (all tracked), ci (all tracked)
167
+ --all-files Check all tracked files (shortcut for --context=ci)
164
168
  --help Show this help message
165
169
 
166
170
  VALID GATES:
@@ -182,6 +186,12 @@ EXAMPLES:
182
186
  # CI mode with JSON output
183
187
  caws quality-gates --ci --json
184
188
 
189
+ # Check all files in repository (not just staged)
190
+ caws quality-gates --all-files
191
+
192
+ # Use specific context
193
+ caws quality-gates --context=ci
194
+
185
195
  # Show detailed help
186
196
  caws quality-gates --help
187
197
 
@@ -1 +1 @@
1
- {"version":3,"file":"PolicyManager.d.ts","sourceRoot":"","sources":["../../src/policy/PolicyManager.js"],"names":[],"mappings":"AAWA;;;;;;;;GAQG;AACH;IACE,0BAIC;IAHC,mBAAkD;IAClD,cAA0C;IAC1C,2BAA4B;IAG9B;;;;;;;;OAQG;IACH,wBANW,MAAM,YAEd;QAAyB,QAAQ,EAAzB,OAAO;QACS,QAAQ,EAAxB,MAAM;KACd,GAAU,OAAO,KAAQ,CAuE3B;IAED;;;;;;OAMG;IACH,qBAJW,MAAM,eACN,MAAM,GACJ,OAAO,CAAC,MAAO,IAAI,CAAC,CAchC;IAED;;;;;OAKG;IACH,4BAFa,OAAO,CA2BnB;IAED;;;;;;;OAOG;IACH,uCAJW,MAAM,EAAE,eACR,MAAM,GACJ,OAAO,KAAQ,CA2B3B;IAED;;;;;OAKG;IACH,kCA8BC;IAED;;;;;;OAMG;IACH,wBAoDC;IAED;;;;OAIG;IACH,yBAFW,MAAM,QAQhB;IAED;;;;;OAKG;IACH,4BAHW,MAAM,OAmBhB;IAED;;;;;OAKG;IACH,0BAHW,MAAM,GACJ,OAAO,KAAQ,CAK3B;IAED;;;;OAIG;IACH,qBAFa,MAAM,EAAE,CAIpB;IAED;;;;OAIG;IACH,qBA2BC;CACF;AAGD,iDAAiD;AAOnC,iFAA+E;AAC/E,2DAA6D;AACzD,8DAAiE"}
1
+ {"version":3,"file":"PolicyManager.d.ts","sourceRoot":"","sources":["../../src/policy/PolicyManager.js"],"names":[],"mappings":"AAWA;;;;;;;;GAQG;AACH;IACE,0BAIC;IAHC,mBAAkD;IAClD,cAA0C;IAC1C,2BAA4B;IAG9B;;;;;;;;OAQG;IACH,wBANW,MAAM,YAEd;QAAyB,QAAQ,EAAzB,OAAO;QACS,QAAQ,EAAxB,MAAM;KACd,GAAU,OAAO,KAAQ,CAuG3B;IAED;;;;;;OAMG;IACH,qBAJW,MAAM,eACN,MAAM,GACJ,OAAO,CAAC,MAAO,IAAI,CAAC,CAchC;IAED;;;;;OAKG;IACH,4BAFa,OAAO,CA2BnB;IAED;;;;;;;OAOG;IACH,uCAJW,MAAM,EAAE,eACR,MAAM,GACJ,OAAO,KAAQ,CA2B3B;IAED;;;;;OAKG;IACH,kCA8BC;IAED;;;;;;OAMG;IACH,wBAoDC;IAED;;;;OAIG;IACH,yBAFW,MAAM,QAQhB;IAED;;;;;OAKG;IACH,4BAHW,MAAM,OAmBhB;IAED;;;;;OAKG;IACH,0BAHW,MAAM,GACJ,OAAO,KAAQ,CAK3B;IAED;;;;OAIG;IACH,qBAFa,MAAM,EAAE,CAIpB;IAED;;;;OAIG;IACH,qBA2BC;CACF;AAGD,iDAAiD;AAOnC,iFAA+E;AAC/E,2DAA6D;AACzD,8DAAiE"}
@@ -1 +1 @@
1
- {"version":3,"file":"cursor-hooks.d.ts","sourceRoot":"","sources":["../../src/scaffold/cursor-hooks.js"],"names":[],"mappings":"AAaA;;;;GAIG;AACH,gDAHW,MAAM,WACN,MAAM,EAAE,iBAqJlB"}
1
+ {"version":3,"file":"cursor-hooks.d.ts","sourceRoot":"","sources":["../../src/scaffold/cursor-hooks.js"],"names":[],"mappings":"AAaA;;;;GAIG;AACH,gDAHW,MAAM,WACN,MAAM,EAAE,iBA6JlB"}
@@ -17,4 +17,22 @@ export function removeGitHooks(projectDir: string): Promise<void>;
17
17
  * @param {string} projectDir - Project directory path
18
18
  */
19
19
  export function checkGitHooksStatus(projectDir: string): Promise<void>;
20
+ /**
21
+ * Generate pre-push hook content
22
+ * Blocks --no-verify to enforce quality gates before pushing
23
+ */
24
+ export function generatePrePushHook(): string;
25
+ /**
26
+ * Generate pre-commit hook content with staged file quality gates
27
+ * Implements fallback chain: Node script → CLI → Python scripts → Skip gracefully
28
+ */
29
+ export function generatePreCommitHook(options: any): string;
30
+ /**
31
+ * Generate post-commit hook content
32
+ */
33
+ export function generatePostCommitHook(): string;
34
+ /**
35
+ * Generate commit-msg hook content
36
+ */
37
+ export function generateCommitMsgHook(): string;
20
38
  //# sourceMappingURL=git-hooks.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"git-hooks.d.ts","sourceRoot":"","sources":["../../src/scaffold/git-hooks.js"],"names":[],"mappings":"AASA;;;;GAIG;AACH,6CAHW,MAAM;;;GAwGhB;AAwND;;;GAGG;AACH,2CAFW,MAAM,iBAkChB;AAED;;;GAGG;AACH,gDAFW,MAAM,iBAgDhB"}
1
+ {"version":3,"file":"git-hooks.d.ts","sourceRoot":"","sources":["../../src/scaffold/git-hooks.js"],"names":[],"mappings":"AAUA;;;;GAIG;AACH,6CAHW,MAAM;;;GAwGhB;AA4kBD;;;GAGG;AACH,2CAFW,MAAM,iBAkChB;AAED;;;GAGG;AACH,gDAFW,MAAM,iBAgDhB;AA9VD;;;GAGG;AACH,8CAqNC;AA7hBD;;;GAGG;AACH,4DAsRC;AAED;;GAEG;AACH,iDAmCC;AA6ND;;GAEG;AACH,gDAsCC"}
@@ -6,6 +6,7 @@
6
6
 
7
7
  const fs = require('fs-extra');
8
8
  const path = require('path');
9
+ const { getTodoAnalyzerSuggestion } = require('../utils/project-analysis');
9
10
 
10
11
  /**
11
12
  * Scaffold git hooks for CAWS provenance tracking
@@ -39,7 +40,7 @@ async function scaffoldGitHooks(projectDir, options = {}) {
39
40
  name: 'pre-commit',
40
41
  description: 'Pre-commit validation and quality checks',
41
42
  enabled: validation || qualityGates,
42
- content: generatePreCommitHook({ validation, qualityGates }),
43
+ content: generatePreCommitHook({ validation, qualityGates, projectDir }),
43
44
  },
44
45
  {
45
46
  name: 'post-commit',
@@ -120,7 +121,10 @@ async function scaffoldGitHooks(projectDir, options = {}) {
120
121
  * Implements fallback chain: Node script → CLI → Python scripts → Skip gracefully
121
122
  */
122
123
  function generatePreCommitHook(options) {
123
- const { qualityGates = true, stagedOnly = true } = options;
124
+ const { qualityGates = true, stagedOnly = true, projectDir = process.cwd() } = options;
125
+
126
+ // Get language-agnostic suggestions based on runtime availability
127
+ const todoSuggestion = getTodoAnalyzerSuggestion(projectDir);
124
128
 
125
129
  return `#!/bin/bash
126
130
  # CAWS Pre-commit Hook
@@ -144,13 +148,13 @@ if [ -f ".git/index.lock" ]; then
144
148
  LOCK_AGE_MINUTES=$((LOCK_AGE / 60))
145
149
 
146
150
  if [ $LOCK_AGE_MINUTES -gt 5 ]; then
147
- echo "⚠️ Stale git lock detected (${LOCK_AGE_MINUTES} minutes old)"
151
+ echo "⚠️ Stale git lock detected (\${LOCK_AGE_MINUTES} minutes old)"
148
152
  echo "💡 This may indicate a crashed git process"
149
153
  echo "💡 Remove stale lock: rm .git/index.lock"
150
154
  echo "⚠️ Warning: Check for running git/editor processes before removing"
151
155
  exit 1
152
156
  else
153
- echo "⚠️ Git lock detected (${LOCK_AGE_MINUTES} minutes old)"
157
+ echo "⚠️ Git lock detected (\${LOCK_AGE_MINUTES} minutes old)"
154
158
  echo "💡 Another git process may be running"
155
159
  echo "💡 Wait for the other process to complete, or check for running processes"
156
160
  exit 1
@@ -162,7 +166,7 @@ echo "🔍 Validating YAML syntax for CAWS spec files..."
162
166
  YAML_VALIDATION_FAILED=false
163
167
 
164
168
  # 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)
169
+ STAGED_YAML_FILES=$(git diff --cached --name-only --diff-filter=ACM | grep -E '\\.caws/.*\\.(yaml|yml)$' || true)
166
170
 
167
171
  if [ -n "$STAGED_YAML_FILES" ]; then
168
172
  # Use Node.js to validate YAML if available
@@ -326,42 +330,49 @@ fi
326
330
  if [ "$QUALITY_GATES_RAN" = true ]; then
327
331
  echo "🔍 Checking for hidden TODOs in staged files..."
328
332
 
329
- # Find TODO analyzer .mjs file (preferred - no Python dependency)
330
- TODO_ANALYZER=""
333
+ TODO_CHECK_RAN=false
331
334
 
332
- # Try quality gates package TODO analyzer (published package)
333
- if [ -f "node_modules/@paths.design/quality-gates/todo-analyzer.mjs" ]; then
334
- TODO_ANALYZER="node_modules/@paths.design/quality-gates/todo-analyzer.mjs"
335
- # Try quality gates package TODO analyzer (monorepo/local copy)
336
- elif [ -f "node_modules/@caws/quality-gates/todo-analyzer.mjs" ]; then
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"
335
+ # Option 1: Find TODO analyzer .mjs file (if installed locally)
336
+ if [ "$TODO_CHECK_RAN" = false ]; then
337
+ TODO_ANALYZER=""
338
+
339
+ # Try quality gates package TODO analyzer (published package)
340
+ if [ -f "node_modules/@paths.design/quality-gates/todo-analyzer.mjs" ]; then
341
+ TODO_ANALYZER="node_modules/@paths.design/quality-gates/todo-analyzer.mjs"
342
+ # Try quality gates package TODO analyzer (monorepo/local copy)
343
+ elif [ -f "node_modules/@caws/quality-gates/todo-analyzer.mjs" ]; then
344
+ TODO_ANALYZER="node_modules/@caws/quality-gates/todo-analyzer.mjs"
345
+ # Try monorepo structure (development)
346
+ elif [ -f "packages/quality-gates/todo-analyzer.mjs" ]; then
347
+ TODO_ANALYZER="packages/quality-gates/todo-analyzer.mjs"
348
+ # Try local copy in scripts directory (if scaffolded)
349
+ elif [ -f "scripts/todo-analyzer.mjs" ]; then
350
+ TODO_ANALYZER="scripts/todo-analyzer.mjs"
351
+ fi
352
+
353
+ # Run TODO analyzer if found
354
+ if [ -n "$TODO_ANALYZER" ] && command -v node >/dev/null 2>&1; then
355
+ if node "$TODO_ANALYZER" --staged-only --ci-mode --min-confidence 0.8 >/dev/null 2>&1; then
356
+ echo "✅ No critical hidden TODOs found in staged files"
357
+ TODO_CHECK_RAN=true
358
+ else
359
+ echo "❌ Critical hidden TODOs detected in staged files - commit blocked"
360
+ echo "💡 Fix stub implementations and placeholder code before committing"
361
+ echo "📖 See docs/PLACEHOLDER-DETECTION-GUIDE.md for classification"
362
+ echo ""
363
+ echo "🔍 Running detailed analysis on staged files..."
364
+ node "$TODO_ANALYZER" --staged-only --min-confidence 0.8
365
+ exit 1
366
+ fi
367
+ fi
344
368
  fi
345
369
 
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
358
- fi
359
- # Fallback to legacy Python analyzer (deprecated - will be removed)
360
- elif command -v python3 >/dev/null 2>&1 && [ -f "scripts/v3/analysis/todo_analyzer.py" ]; then
370
+ # Option 2: Fallback to legacy Python analyzer (deprecated - will be removed)
371
+ if [ "$TODO_CHECK_RAN" = false ] && command -v python3 >/dev/null 2>&1 && [ -f "scripts/v3/analysis/todo_analyzer.py" ]; then
361
372
  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"
363
373
  if python3 scripts/v3/analysis/todo_analyzer.py --staged-only --ci-mode --min-confidence 0.8 >/dev/null 2>&1; then
364
374
  echo "✅ No critical hidden TODOs found in staged files"
375
+ TODO_CHECK_RAN=true
365
376
  else
366
377
  echo "❌ Critical hidden TODOs detected in staged files - commit blocked"
367
378
  echo "💡 Fix stub implementations and placeholder code before committing"
@@ -371,9 +382,16 @@ if [ "$QUALITY_GATES_RAN" = true ]; then
371
382
  python3 scripts/v3/analysis/todo_analyzer.py --staged-only --min-confidence 0.8
372
383
  exit 1
373
384
  fi
374
- else
385
+ fi
386
+
387
+ # Option 3: No analyzer available - show language-aware suggestions
388
+ if [ "$TODO_CHECK_RAN" = false ]; then
375
389
  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"
390
+ echo "💡 Available options for TODO analysis:"
391
+ ${todoSuggestion
392
+ .split('\n')
393
+ .map((line) => ` echo "${line.replace(/"/g, '\\"')}"`)
394
+ .join('\n')}
377
395
  fi
378
396
  fi
379
397
 
@@ -444,8 +462,8 @@ for arg in "$@"; do
444
462
  echo "💡 To fix issues locally:"
445
463
  echo " 1. Run: caws validate"
446
464
  echo " 2. Fix reported issues"
447
- echo " 3. Commit fixes: git commit --no-verify (allowed)"
448
- echo " 4. Push again: git push (no --no-verify)"
465
+ echo " 3. Commit fixes: git commit --no-verify \\(allowed\\)"
466
+ echo " 4. Push again: git push \\(no --no-verify\\)"
449
467
  exit 1
450
468
  fi
451
469
  done
@@ -508,13 +526,13 @@ if command -v caws >/dev/null 2>&1; then
508
526
  echo " No active waivers found"
509
527
  echo ""
510
528
  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 \\"
529
+ echo " caws waivers create \\\\"
530
+ echo " --title='Initial CAWS setup' \\\\"
531
+ echo " --reason=infrastructure_limitation \\\\"
532
+ echo " --gates=contracts \\\\"
533
+ echo " --expires-at='2024-12-31T23:59:59Z' \\\\"
534
+ echo " --approved-by='@your-team' \\\\"
535
+ echo " --impact-level=low \\\\"
518
536
  echo " --mitigation-plan='Contracts will be added as features are developed'"
519
537
  fi
520
538
 
@@ -523,43 +541,121 @@ if command -v caws >/dev/null 2>&1; then
523
541
  echo "Next Steps:"
524
542
  echo " 1. Review errors above"
525
543
  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)"
544
+ echo " 3. Run: caws validate \\(to verify fixes\\)"
545
+ echo " 4. Commit fixes: git commit --no-verify \\(allowed\\)"
528
546
  echo " 5. Push again: git push"
529
547
  echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
530
548
  exit 1
531
549
  fi
532
550
  fi
533
551
 
534
- # Run security checks
552
+ # Run full pre-push checks (full test suite required before push)
553
+ # Note: Pre-commit uses filtered tests for speed, but push requires full suite
554
+ echo ""
555
+ echo "⚡ Running full pre-push checks (full test suite required)..."
556
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
557
+
558
+ QUICK_CHECKS_FAILED=false
559
+
560
+ # 1. Linting (fast)
561
+ if [ -f "package.json" ]; then
562
+ if command -v npm >/dev/null 2>&1; then
563
+ if grep -q '"lint"' package.json; then
564
+ echo "🔍 Running linting..."
565
+ if npm run lint >/dev/null 2>&1; then
566
+ echo "✅ Linting passed"
567
+ else
568
+ echo "❌ Linting failed"
569
+ echo "💡 Fix lint errors: npm run lint"
570
+ QUICK_CHECKS_FAILED=true
571
+ fi
572
+ fi
573
+ fi
574
+ fi
575
+
576
+ # 2. Type checking (fast for TypeScript/JavaScript)
577
+ if [ -f "package.json" ]; then
578
+ if command -v npm >/dev/null 2>&1; then
579
+ if grep -q '"typecheck"' package.json; then
580
+ echo "🔍 Running type checking..."
581
+ if npm run typecheck >/dev/null 2>&1; then
582
+ echo "✅ Type checking passed"
583
+ else
584
+ echo "❌ Type checking failed"
585
+ echo "💡 Fix type errors: npm run typecheck"
586
+ QUICK_CHECKS_FAILED=true
587
+ fi
588
+ fi
589
+ fi
590
+ fi
591
+
592
+ # 3. Run FULL test suite (required for push) - no filtering
593
+ # Pre-commit uses filtered tests for speed, but push requires full suite
594
+ if [ -f "package.json" ]; then
595
+ if command -v npm >/dev/null 2>&1 && grep -q '"test"' package.json; then
596
+ echo "🧪 Running FULL test suite (required for push)..."
597
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
598
+ if npm test 2>&1 | tee /tmp/pre-push-test-full.log; then
599
+ echo "✅ Full test suite passed"
600
+ rm -f /tmp/pre-push-test-full.log
601
+ else
602
+ FULL_TEST_EXIT_CODE=\${PIPESTATUS[0]}
603
+ echo "❌ Full test suite failed (exit code: \${FULL_TEST_EXIT_CODE})"
604
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
605
+ echo "Test output (last 100 lines):"
606
+ tail -100 /tmp/pre-push-test-full.log 2>/dev/null || echo "No test output captured"
607
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
608
+ echo "💡 Fix test failures before pushing: npm test"
609
+ rm -f /tmp/pre-push-test-full.log
610
+ QUICK_CHECKS_FAILED=true
611
+ fi
612
+ fi
613
+ fi
614
+
615
+ # 4. Security checks (non-blocking warnings)
616
+ echo ""
535
617
  echo "🔒 Running security checks..."
536
618
  if [ -f "package.json" ]; then
537
- # Check for vulnerabilities
538
619
  if command -v npm >/dev/null 2>&1; then
539
620
  echo "🔍 Checking for vulnerabilities..."
540
621
  if npm audit --audit-level moderate >/dev/null 2>&1; then
541
622
  echo "✅ Security audit passed"
542
623
  else
543
- echo "⚠️ Security vulnerabilities found"
624
+ echo "⚠️ Security vulnerabilities found (non-blocking)"
544
625
  echo "💡 Review with: npm audit"
545
- # Don't fail on warnings, just warn
546
626
  fi
547
627
  fi
548
628
  elif [ -f "requirements.txt" ] || [ -f "pyproject.toml" ]; then
549
- # Python project security checks
550
629
  if command -v pip-audit >/dev/null 2>&1; then
551
630
  echo "🔍 Checking Python vulnerabilities..."
552
- pip-audit --desc 2>/dev/null || echo "⚠️ Install pip-audit for vulnerability checks: pip install pip-audit"
631
+ pip-audit --desc 2>/dev/null || echo "⚠️ Install pip-audit: pip install pip-audit"
553
632
  fi
554
633
  elif [ -f "Cargo.toml" ]; then
555
- # Rust project security checks
556
634
  if command -v cargo-audit >/dev/null 2>&1; then
557
635
  echo "🔍 Checking Rust vulnerabilities..."
558
- cargo audit 2>/dev/null || echo "⚠️ Install cargo-audit for vulnerability checks: cargo install cargo-audit"
636
+ cargo audit 2>/dev/null || echo "⚠️ Install cargo-audit: cargo install cargo-audit"
559
637
  fi
560
638
  fi
561
639
 
562
- echo "🎉 Pre-push checks completed!"
640
+ # Fail if any checks failed
641
+ if [ "$QUICK_CHECKS_FAILED" = true ]; then
642
+ echo ""
643
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
644
+ echo "❌ Pre-push checks failed"
645
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
646
+ echo "All checks (linting/type checking/full test suite) must pass before push."
647
+ echo ""
648
+ echo "💡 Fix failures before pushing:"
649
+ echo " - Linting: npm run lint"
650
+ echo " - Type checking: npm run typecheck"
651
+ echo " - Tests: npm test"
652
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
653
+ exit 1
654
+ fi
655
+
656
+ echo ""
657
+ echo "✅ Pre-push checks completed!"
658
+ echo "💡 All quality gates passed - ready to push"
563
659
  `;
564
660
  }
565
661
 
@@ -583,7 +679,7 @@ fi
583
679
 
584
680
  # Basic commit message validation
585
681
  if [ \${#COMMIT_MSG} -lt 10 ]; then
586
- echo "❌ Commit message too short (minimum 10 characters)"
682
+ echo "❌ Commit message too short \\(minimum 10 characters\\)"
587
683
  echo "💡 Write descriptive commit messages"
588
684
  exit 1
589
685
  fi
@@ -700,4 +796,9 @@ module.exports = {
700
796
  scaffoldGitHooks,
701
797
  removeGitHooks,
702
798
  checkGitHooksStatus,
799
+ // Export generator functions for testing
800
+ generatePrePushHook,
801
+ generatePreCommitHook,
802
+ generatePostCommitHook,
803
+ generateCommitMsgHook,
703
804
  };
@@ -3,12 +3,7 @@
3
3
  * @param {Object} options - Scaffold options
4
4
  */
5
5
  export function scaffoldProject(options: any): Promise<void>;
6
- /**
7
- * Scaffold IDE integrations for comprehensive CAWS development experience
8
- * @param {string} targetDir - Target directory for scaffolding
9
- * @param {Object} options - Scaffold options
10
- */
11
- export function scaffoldIDEIntegrations(targetDir: string, options: any): Promise<{
6
+ export function scaffoldIDEIntegrations(targetDir: any, options: any): Promise<{
12
7
  added: number;
13
8
  skipped: number;
14
9
  }>;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/scaffold/index.js"],"names":[],"mappings":"AAkKA;;;GAGG;AACH,6DA6VC;AAhfD;;;;GAIG;AACH,mDAHW,MAAM;;;GA8HhB;AAMD;;;GAGG;AACH,yDAGC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/scaffold/index.js"],"names":[],"mappings":"AA6LA;;;GAGG;AACH,6DA6jBC;AA3sBD;;;GA2HC;AAMD;;;GAGG;AACH,yDAGC"}
@@ -735,7 +735,7 @@ async function scaffoldProject(options) {
735
735
  }
736
736
 
737
737
  // Update .gitignore to exclude CAWS local runtime files
738
- const gitignoreUpdated = await updateGitignore(targetDir);
738
+ const gitignoreUpdated = await updateGitignore(currentDir);
739
739
  if (gitignoreUpdated) {
740
740
  console.log(chalk.green('\n✅ Updated .gitignore to exclude CAWS local runtime files'));
741
741
  console.log(
@@ -18,3 +18,4 @@ node .caws/tools/scope-guard.js check .caws/working-spec.yaml
18
18
 
19
19
  The `.cursor/hooks/scope-guard.sh` hook automatically uses this tool to validate file attachments against working spec scope boundaries.
20
20
 
21
+
@@ -1 +1 @@
1
- {"version":3,"file":"tool-loader.d.ts","sourceRoot":"","sources":["../src/tool-loader.js"],"names":[],"mappings":";;AAcA;;;GAGG;AACH;IACE,0BAaC;IAXC;;;;;MAMC;IAED,2BAA4B;IAC5B,0BAAgC;IAChC,qBAA0B;IAG5B;;;OAGG;IACH,iBAFa,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAkDlC;IAED;;;;OAIG;IACH,mBAHW,MAAM,GACJ,OAAO,KAAQ,CAmC3B;IAED;;;OAGG;IACH,gBAFa,OAAO,CAAC,GAAG,CAAC,MAAM,MAAS,CAAC,CAuBxC;IAED;;;;OAIG;IACH,gBAHW,MAAM,GACJ,MAAO,IAAI,CAIvB;IAED;;;OAGG;IACH,eAFa,GAAG,CAAC,MAAM,MAAS,CAI/B;IAED;;;;OAIG;IACH,mBAHW,MAAM,GACJ,OAAO,CAQnB;IAED;;;;OAIG;IACH,yBAgCC;IAED;;;;OAIG;IACH,8BAkBC;IAED;;;;;OAKG;IACH,8BAyBC;IAED;;;OAGG;IACH,gBAQC;CACF"}
1
+ {"version":3,"file":"tool-loader.d.ts","sourceRoot":"","sources":["../src/tool-loader.js"],"names":[],"mappings":";;AAcA;;;GAGG;AACH;IACE,0BAkBC;IAXC;;;;;MAMC;IAED,2BAA4B;IAC5B,0BAAgC;IAChC,qBAA0B;IAG5B;;;OAGG;IACH,iBAFa,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAkDlC;IAED;;;;OAIG;IACH,mBAHW,MAAM,GACJ,OAAO,KAAQ,CAmC3B;IAED;;;OAGG;IACH,gBAFa,OAAO,CAAC,GAAG,CAAC,MAAM,MAAS,CAAC,CAuBxC;IAED;;;;OAIG;IACH,gBAHW,MAAM,GACJ,MAAO,IAAI,CAIvB;IAED;;;OAGG;IACH,eAFa,GAAG,CAAC,MAAM,MAAS,CAI/B;IAED;;;;OAIG;IACH,mBAHW,MAAM,GACJ,OAAO,CAQnB;IAED;;;;OAIG;IACH,yBAgCC;IAED;;;;OAIG;IACH,8BAkBC;IAED;;;;;OAKG;IACH,8BAyBC;IAED;;;OAGG;IACH,gBAQC;CACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"tool-validator.d.ts","sourceRoot":"","sources":["../src/tool-validator.js"],"names":[],"mappings":";;AAYA;;GAEG;AACH;IACE,0BAWC;IAVC;;;;MAMC;IAED,eAAqB;IACrB,+BAAgC;IAGlC;;;OAGG;IACH,iBAFa,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAqBlC;IAED;;;;OAIG;IACH,yBAFa,OAAO,KAAQ,CAsF3B;IAED;;;;OAIG;IACH,0BAgCC;IAED;;;;OAIG;IACH,0BA8CC;IAED;;;;OAIG;IACH,iCAkBC;IAED;;;;OAIG;IACH,8BAqCC;IAED;;;;OAIG;IACH,8BA4BC;IAED;;;;OAIG;IACH,yBAHW,MAAM,GACJ,OAAO,CAmBnB;IAED;;OAEG;IACH,mBAEC;IAED;;;OAGG;IACH,gBAOC;CACF"}
1
+ {"version":3,"file":"tool-validator.d.ts","sourceRoot":"","sources":["../src/tool-validator.js"],"names":[],"mappings":";;AAYA;;GAEG;AACH;IACE,0BAiBC;IATC;;;;MAKC;IAED,eAAqB;IACrB,+BAAgC;IAGlC;;;OAGG;IACH,iBAFa,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAqBlC;IAED;;;;OAIG;IACH,yBAFa,OAAO,KAAQ,CAsF3B;IAED;;;;OAIG;IACH,0BAgCC;IAED;;;;OAIG;IACH,0BA8CC;IAED;;;;OAIG;IACH,iCAkBC;IAED;;;;OAIG;IACH,8BAqCC;IAED;;;;OAIG;IACH,8BA4BC;IAED;;;;OAIG;IACH,yBAHW,MAAM,GACJ,OAAO,CAmBnB;IAED;;OAEG;IACH,mBAEC;IAED;;;OAGG;IACH,gBAOC;CACF"}
@@ -0,0 +1,73 @@
1
+ /**
2
+ * @fileoverview Async Operation Utilities
3
+ * Provides consistent patterns for async operations, parallel execution, and resource cleanup
4
+ * @author @darianrosebrook
5
+ */
6
+ /**
7
+ * Execute multiple async operations in parallel
8
+ * @param {Array<Promise>} promises - Array of promises to execute
9
+ * @param {Object} options - Options
10
+ * @param {boolean} [options.failFast=true] - Stop on first error
11
+ * @returns {Promise<Array>} Array of results
12
+ */
13
+ export function parallel(promises: Array<Promise<any>>, options?: {
14
+ failFast?: boolean;
15
+ }): Promise<any[]>;
16
+ /**
17
+ * Execute async operations sequentially
18
+ * @param {Array<Function>} operations - Array of async functions to execute
19
+ * @param {Object} options - Options
20
+ * @param {boolean} [options.stopOnError=true] - Stop on first error
21
+ * @returns {Promise<Array>} Array of results
22
+ */
23
+ export function sequential(operations: Array<Function>, options?: {
24
+ stopOnError?: boolean;
25
+ }): Promise<any[]>;
26
+ /**
27
+ * Retry an async operation with exponential backoff
28
+ * @param {Function} operation - Async function to retry
29
+ * @param {Object} options - Retry options
30
+ * @param {number} [options.maxRetries=3] - Maximum number of retries
31
+ * @param {number} [options.initialDelay=1000] - Initial delay in ms
32
+ * @param {number} [options.maxDelay=10000] - Maximum delay in ms
33
+ * @param {Function} [options.shouldRetry] - Function to determine if error should be retried
34
+ * @returns {Promise<any>} Operation result
35
+ */
36
+ export function retry(operation: Function, options?: {
37
+ maxRetries?: number;
38
+ initialDelay?: number;
39
+ maxDelay?: number;
40
+ shouldRetry?: Function;
41
+ }): Promise<any>;
42
+ /**
43
+ * Execute operation with timeout
44
+ * @param {Promise} promise - Promise to execute
45
+ * @param {number} timeoutMs - Timeout in milliseconds
46
+ * @param {string} [errorMessage] - Custom error message
47
+ * @returns {Promise<any>} Operation result
48
+ */
49
+ export function withTimeout(promise: Promise<any>, timeoutMs: number, errorMessage?: string): Promise<any>;
50
+ /**
51
+ * Execute operation with resource cleanup
52
+ * @param {Function} operation - Async operation to execute
53
+ * @param {Function} cleanup - Cleanup function (called in finally)
54
+ * @returns {Promise<any>} Operation result
55
+ */
56
+ export function withCleanup(operation: Function, cleanup: Function): Promise<any>;
57
+ /**
58
+ * Execute multiple operations and collect all errors
59
+ * @param {Array<Function>} operations - Array of async functions
60
+ * @returns {Promise<{successes: Array, errors: Array}>} Results and errors
61
+ */
62
+ export function collectResults(operations: Array<Function>): Promise<{
63
+ successes: any[];
64
+ errors: any[];
65
+ }>;
66
+ /**
67
+ * Execute operation with cancellation support
68
+ * @param {Function} operation - Async operation to execute
69
+ * @param {AbortSignal} signal - Abort signal for cancellation
70
+ * @returns {Promise<any>} Operation result
71
+ */
72
+ export function withCancellation(operation: Function, signal: AbortSignal): Promise<any>;
73
+ //# sourceMappingURL=async-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"async-utils.d.ts","sourceRoot":"","sources":["../../src/utils/async-utils.js"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;;;GAMG;AACH,mCALW,KAAK,cAAS,YAEtB;IAA0B,QAAQ,GAA1B,OAAO;CACf,GAAU,OAAO,OAAO,CAmB1B;AAED;;;;;;GAMG;AACH,uCALW,KAAK,UAAU,YAEvB;IAA0B,WAAW,GAA7B,OAAO;CACf,GAAU,OAAO,OAAO,CAmB1B;AAED;;;;;;;;;GASG;AACH,qDANG;IAAyB,UAAU,GAA3B,MAAM;IACW,YAAY,GAA7B,MAAM;IACW,QAAQ,GAAzB,MAAM;IACa,WAAW;CACtC,GAAU,OAAO,CAAC,GAAG,CAAC,CA+BxB;AAED;;;;;;GAMG;AACH,8DAJW,MAAM,iBACN,MAAM,GACJ,OAAO,CAAC,GAAG,CAAC,CAWxB;AAED;;;;;GAKG;AACH,qEAFa,OAAO,CAAC,GAAG,CAAC,CAQxB;AAED;;;;GAIG;AACH,2CAHW,KAAK,UAAU,GACb,OAAO,CAAC;IAAC,SAAS,QAAQ;IAAC,MAAM,QAAO;CAAC,CAAC,CAmBtD;AAED;;;;;GAKG;AACH,8DAHW,WAAW,GACT,OAAO,CAAC,GAAG,CAAC,CAgBxB"}
@@ -0,0 +1,66 @@
1
+ /**
2
+ * Unified command wrapper that provides:
3
+ * - Consistent error handling
4
+ * - Standardized output formatting
5
+ * - Execution timing
6
+ * - JSON output support
7
+ *
8
+ * @param {Function} commandFn - Async command function to execute
9
+ * @param {Object} options - Command options
10
+ * @param {string} options.commandName - Name of the command (for error context)
11
+ * @param {boolean} [options.includeTiming=true] - Include execution timing
12
+ * @param {boolean} [options.exitOnError=true] - Exit process on error
13
+ * @param {Object} [options.context={}] - Additional context for error handling
14
+ * @returns {Promise<any>} Command result
15
+ */
16
+ export function commandWrapper(commandFn: Function, options?: {
17
+ commandName: string;
18
+ includeTiming?: boolean;
19
+ exitOnError?: boolean;
20
+ context?: any;
21
+ }): Promise<any>;
22
+ export namespace Output {
23
+ /**
24
+ * Output success message
25
+ * @param {string} message - Success message
26
+ * @param {Object} [data] - Additional data to output
27
+ */
28
+ function success(message: string, data?: any): void;
29
+ /**
30
+ * Output error message
31
+ * @param {string} message - Error message
32
+ * @param {string[]} [suggestions] - Recovery suggestions
33
+ */
34
+ function error(message: string, suggestions?: string[]): void;
35
+ /**
36
+ * Output warning message
37
+ * @param {string} message - Warning message
38
+ * @param {string} [suggestion] - Optional suggestion
39
+ */
40
+ function warning(message: string, suggestion?: string): void;
41
+ /**
42
+ * Output info message
43
+ * @param {string} message - Info message
44
+ * @param {Object} [data] - Additional data
45
+ */
46
+ function info(message: string, data?: any): void;
47
+ /**
48
+ * Output data in JSON format
49
+ * @param {Object} data - Data to output
50
+ * @param {boolean} [success=true] - Whether operation was successful
51
+ */
52
+ function json(data: any, success?: boolean): void;
53
+ /**
54
+ * Output progress message
55
+ * @param {string} message - Progress message
56
+ */
57
+ function progress(message: string): void;
58
+ /**
59
+ * Output section header
60
+ * @param {string} title - Section title
61
+ */
62
+ function section(title: string): void;
63
+ }
64
+ import { isJsonOutput } from "../error-handler";
65
+ export { isJsonOutput };
66
+ //# sourceMappingURL=command-wrapper.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"command-wrapper.d.ts","sourceRoot":"","sources":["../../src/utils/command-wrapper.js"],"names":[],"mappings":"AASA;;;;;;;;;;;;;;GAcG;AACH,8DANG;IAAwB,WAAW,EAA3B,MAAM;IACY,aAAa,GAA/B,OAAO;IACW,WAAW,GAA7B,OAAO;IACU,OAAO;CAChC,GAAU,OAAO,CAAC,GAAG,CAAC,CAuCxB;;IAMC;;;;OAIG;IACH,0BAHW,MAAM,oBAmBhB;IAED;;;;OAIG;IACH,wBAHW,MAAM,gBACN,MAAM,EAAE,QAuBlB;IAED;;;;OAIG;IACH,0BAHW,MAAM,eACN,MAAM,QAkBhB;IAED;;;;OAIG;IACH,uBAHW,MAAM,oBAmBhB;IAED;;;;OAIG;IACH,mCAFW,OAAO,QAIjB;IAED;;;OAGG;IACH,2BAFW,MAAM,QAMhB;IAED;;;OAGG;IACH,wBAFW,MAAM,QAOhB"}
@@ -4,4 +4,11 @@
4
4
  * @returns {Object} Setup information
5
5
  */
6
6
  export function detectCAWSSetup(cwd?: string): any;
7
+ /**
8
+ * Find the package root directory by looking for package.json
9
+ * Works in both development (src/) and production (dist/) scenarios
10
+ * @param {string} startDir - Directory to start searching from (defaults to __dirname)
11
+ * @returns {string} Package root directory path
12
+ */
13
+ export function findPackageRoot(startDir?: string): string;
7
14
  //# sourceMappingURL=detection.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"detection.d.ts","sourceRoot":"","sources":["../../src/utils/detection.js"],"names":[],"mappings":"AAUA;;;;GAIG;AACH,sCAHW,MAAM,OA6JhB"}
1
+ {"version":3,"file":"detection.d.ts","sourceRoot":"","sources":["../../src/utils/detection.js"],"names":[],"mappings":"AA6BA;;;;GAIG;AACH,sCAHW,MAAM,OAqKhB;AA1LD;;;;;GAKG;AACH,2CAHW,MAAM,GACJ,MAAM,CAalB"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Check for git lock files
3
+ * @param {string} projectRoot - Project root directory
4
+ * @returns {Object} Lock status information
5
+ */
6
+ export function checkGitLock(projectRoot: string): any;
7
+ /**
8
+ * Format git lock error message
9
+ * @param {Object} lockStatus - Lock status from checkGitLock
10
+ * @returns {string} Formatted error message
11
+ */
12
+ export function formatGitLockError(lockStatus: any): string;
13
+ //# sourceMappingURL=git-lock.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git-lock.d.ts","sourceRoot":"","sources":["../../src/utils/git-lock.js"],"names":[],"mappings":"AASA;;;;GAIG;AACH,0CAHW,MAAM,OA+DhB;AAED;;;;GAIG;AACH,qDAFa,MAAM,CAgClB"}
@@ -116,3 +116,4 @@ module.exports = {
116
116
  formatGitLockError,
117
117
  };
118
118
 
119
+