@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.
- package/dist/budget-derivation.js +5 -4
- package/dist/commands/diagnose.js +26 -20
- package/dist/commands/init.js +72 -5
- package/dist/commands/specs.js +40 -1
- package/dist/commands/status.js +2 -2
- package/dist/commands/templates.js +10 -0
- package/dist/commands/tool.js +2 -3
- package/dist/commands/validate.js +12 -0
- package/dist/config/index.js +17 -8
- package/dist/generators/working-spec.js +42 -9
- package/dist/index.js +3 -1
- package/dist/scaffold/cursor-hooks.js +10 -2
- package/dist/scaffold/git-hooks.js +189 -32
- package/dist/scaffold/index.js +105 -17
- 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 +34 -6
- 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 +105 -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
|
@@ -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
|
|
|
@@ -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
|
-
|
|
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 "
|
|
372
|
-
echo "
|
|
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
|
package/dist/scaffold/index.js
CHANGED
|
@@ -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
|
|
221
|
+
// Try to find template directory using robust path resolution
|
|
196
222
|
const possiblePaths = [
|
|
197
|
-
// 1.
|
|
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
|
-
|
|
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
|
-
//
|
|
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
|
|
305
|
+
// Add CAWS tools to .caws/ directory (keeps all CAWS files together)
|
|
275
306
|
enhancements.push({
|
|
276
|
-
name: '
|
|
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,
|
|
634
|
+
// If source doesn't exist in template, check if it should be a file or directory
|
|
571
635
|
try {
|
|
572
|
-
|
|
573
|
-
|
|
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.
|
|
633
|
-
console.log('3. Run
|
|
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('
|
|
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
|
+
|