@paths.design/caws-cli 7.0.2 → 8.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/budget-derivation.js +5 -4
- package/dist/commands/diagnose.js +24 -19
- package/dist/commands/init.js +51 -4
- package/dist/commands/quality-gates.js +147 -9
- package/dist/commands/specs.js +148 -14
- package/dist/commands/status.js +2 -2
- package/dist/commands/tool.js +2 -4
- package/dist/config/index.js +17 -8
- package/dist/generators/working-spec.js +19 -6
- package/dist/scaffold/git-hooks.js +245 -46
- package/dist/scaffold/index.js +53 -7
- package/dist/templates/.caws/tools/README.md +21 -0
- package/dist/templates/.cursor/README.md +311 -0
- package/dist/templates/.cursor/hooks/audit.sh +55 -0
- package/dist/templates/.cursor/hooks/block-dangerous.sh +83 -0
- package/dist/templates/.cursor/hooks/caws-quality-check.sh +52 -0
- package/dist/templates/.cursor/hooks/caws-scope-guard.sh +130 -0
- package/dist/templates/.cursor/hooks/caws-tool-validation.sh +121 -0
- package/dist/templates/.cursor/hooks/format.sh +38 -0
- package/dist/templates/.cursor/hooks/naming-check.sh +64 -0
- package/dist/templates/.cursor/hooks/scan-secrets.sh +46 -0
- package/dist/templates/.cursor/hooks/scope-guard.sh +52 -0
- package/dist/templates/.cursor/hooks/validate-spec.sh +83 -0
- package/dist/templates/.cursor/hooks.json +59 -0
- package/dist/templates/.cursor/rules/00-claims-verification.mdc +144 -0
- package/dist/templates/.cursor/rules/01-working-style.mdc +50 -0
- package/dist/templates/.cursor/rules/02-quality-gates.mdc +370 -0
- package/dist/templates/.cursor/rules/03-naming-and-refactor.mdc +33 -0
- package/dist/templates/.cursor/rules/04-logging-language-style.mdc +23 -0
- package/dist/templates/.cursor/rules/05-safe-defaults-guards.mdc +23 -0
- package/dist/templates/.cursor/rules/06-typescript-conventions.mdc +36 -0
- package/dist/templates/.cursor/rules/07-process-ops.mdc +20 -0
- package/dist/templates/.cursor/rules/08-solid-and-architecture.mdc +16 -0
- package/dist/templates/.cursor/rules/09-docstrings.mdc +89 -0
- package/dist/templates/.cursor/rules/10-documentation-quality-standards.mdc +390 -0
- package/dist/templates/.cursor/rules/11-scope-management-waivers.mdc +385 -0
- package/dist/templates/.cursor/rules/12-implementation-completeness.mdc +516 -0
- package/dist/templates/.cursor/rules/13-language-agnostic-standards.mdc +588 -0
- package/dist/templates/.cursor/rules/README.md +148 -0
- package/dist/templates/.github/copilot/instructions.md +311 -0
- package/dist/templates/.idea/runConfigurations/CAWS_Evaluate.xml +5 -0
- package/dist/templates/.idea/runConfigurations/CAWS_Validate.xml +5 -0
- package/dist/templates/.vscode/launch.json +56 -0
- package/dist/templates/.vscode/settings.json +93 -0
- package/dist/templates/.windsurf/workflows/caws-guided-development.md +92 -0
- package/dist/templates/COMMIT_CONVENTIONS.md +86 -0
- package/dist/templates/OIDC_SETUP.md +300 -0
- package/dist/templates/agents.md +1047 -0
- package/dist/templates/codemod/README.md +1 -0
- package/dist/templates/codemod/test.js +93 -0
- package/dist/templates/docs/README.md +150 -0
- package/dist/templates/scripts/quality-gates/check-god-objects.js +146 -0
- package/dist/templates/scripts/quality-gates/run-quality-gates.js +50 -0
- package/dist/templates/scripts/v3/analysis/todo_analyzer.py +1997 -0
- package/dist/tool-loader.js +6 -1
- package/dist/tool-validator.js +8 -2
- package/dist/utils/detection.js +4 -3
- package/dist/utils/git-lock.js +119 -0
- package/dist/utils/gitignore-updater.js +148 -0
- package/dist/utils/project-analysis.js +176 -16
- package/dist/utils/quality-gates.js +48 -7
- package/dist/utils/spec-resolver.js +27 -3
- package/dist/utils/yaml-validation.js +156 -0
- package/dist/validation/spec-validation.js +81 -2
- package/package.json +2 -2
- package/templates/.caws/schemas/waivers.schema.json +30 -0
- package/templates/.caws/schemas/working-spec.schema.json +133 -0
- package/templates/.caws/templates/working-spec.template.yml +74 -0
- package/templates/.caws/tools/README.md +21 -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/dist/budget-derivation.d.ts +0 -74
- package/dist/budget-derivation.d.ts.map +0 -1
- package/dist/cicd-optimizer.d.ts +0 -142
- package/dist/cicd-optimizer.d.ts.map +0 -1
- package/dist/commands/archive.d.ts +0 -50
- package/dist/commands/archive.d.ts.map +0 -1
- package/dist/commands/burnup.d.ts +0 -6
- package/dist/commands/burnup.d.ts.map +0 -1
- package/dist/commands/diagnose.d.ts +0 -52
- package/dist/commands/diagnose.d.ts.map +0 -1
- package/dist/commands/evaluate.d.ts +0 -8
- package/dist/commands/evaluate.d.ts.map +0 -1
- package/dist/commands/init.d.ts +0 -5
- package/dist/commands/init.d.ts.map +0 -1
- package/dist/commands/iterate.d.ts +0 -8
- package/dist/commands/iterate.d.ts.map +0 -1
- package/dist/commands/mode.d.ts +0 -24
- package/dist/commands/mode.d.ts.map +0 -1
- package/dist/commands/plan.d.ts +0 -49
- package/dist/commands/plan.d.ts.map +0 -1
- package/dist/commands/provenance.d.ts +0 -32
- package/dist/commands/provenance.d.ts.map +0 -1
- package/dist/commands/quality-gates.d.ts +0 -52
- package/dist/commands/quality-gates.d.ts.map +0 -1
- package/dist/commands/quality-monitor.d.ts +0 -17
- package/dist/commands/quality-monitor.d.ts.map +0 -1
- package/dist/commands/specs.d.ts +0 -71
- package/dist/commands/specs.d.ts.map +0 -1
- package/dist/commands/status.d.ts +0 -44
- package/dist/commands/status.d.ts.map +0 -1
- package/dist/commands/templates.d.ts +0 -74
- package/dist/commands/templates.d.ts.map +0 -1
- package/dist/commands/tool.d.ts +0 -13
- package/dist/commands/tool.d.ts.map +0 -1
- package/dist/commands/troubleshoot.d.ts +0 -8
- package/dist/commands/troubleshoot.d.ts.map +0 -1
- package/dist/commands/tutorial.d.ts +0 -55
- package/dist/commands/tutorial.d.ts.map +0 -1
- package/dist/commands/validate.d.ts +0 -15
- package/dist/commands/validate.d.ts.map +0 -1
- package/dist/commands/waivers.d.ts +0 -8
- package/dist/commands/waivers.d.ts.map +0 -1
- package/dist/commands/workflow.d.ts +0 -85
- package/dist/commands/workflow.d.ts.map +0 -1
- package/dist/config/index.d.ts +0 -29
- package/dist/config/index.d.ts.map +0 -1
- package/dist/config/modes.d.ts +0 -225
- package/dist/config/modes.d.ts.map +0 -1
- package/dist/constants/spec-types.d.ts +0 -41
- package/dist/constants/spec-types.d.ts.map +0 -1
- package/dist/error-handler.d.ts +0 -164
- package/dist/error-handler.d.ts.map +0 -1
- package/dist/generators/jest-config.d.ts +0 -32
- package/dist/generators/jest-config.d.ts.map +0 -1
- package/dist/generators/working-spec.d.ts +0 -13
- package/dist/generators/working-spec.d.ts.map +0 -1
- package/dist/index-new.d.ts +0 -5
- package/dist/index-new.d.ts.map +0 -1
- package/dist/index-new.js +0 -317
- package/dist/index.d.ts +0 -5
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.backup +0 -4711
- package/dist/minimal-cli.d.ts +0 -3
- package/dist/minimal-cli.d.ts.map +0 -1
- package/dist/policy/PolicyManager.d.ts +0 -104
- package/dist/policy/PolicyManager.d.ts.map +0 -1
- package/dist/scaffold/cursor-hooks.d.ts +0 -7
- package/dist/scaffold/cursor-hooks.d.ts.map +0 -1
- package/dist/scaffold/git-hooks.d.ts +0 -20
- package/dist/scaffold/git-hooks.d.ts.map +0 -1
- package/dist/scaffold/index.d.ts +0 -20
- package/dist/scaffold/index.d.ts.map +0 -1
- package/dist/spec/SpecFileManager.d.ts +0 -146
- package/dist/spec/SpecFileManager.d.ts.map +0 -1
- package/dist/test-analysis.d.ts +0 -182
- package/dist/test-analysis.d.ts.map +0 -1
- package/dist/tool-interface.d.ts +0 -236
- package/dist/tool-interface.d.ts.map +0 -1
- package/dist/tool-loader.d.ts +0 -77
- package/dist/tool-loader.d.ts.map +0 -1
- package/dist/tool-validator.d.ts +0 -72
- package/dist/tool-validator.d.ts.map +0 -1
- package/dist/utils/detection.d.ts +0 -7
- package/dist/utils/detection.d.ts.map +0 -1
- package/dist/utils/finalization.d.ts +0 -17
- package/dist/utils/finalization.d.ts.map +0 -1
- package/dist/utils/project-analysis.d.ts +0 -14
- package/dist/utils/project-analysis.d.ts.map +0 -1
- package/dist/utils/quality-gates.d.ts +0 -49
- package/dist/utils/quality-gates.d.ts.map +0 -1
- package/dist/utils/spec-resolver.d.ts +0 -88
- package/dist/utils/spec-resolver.d.ts.map +0 -1
- package/dist/utils/typescript-detector.d.ts +0 -63
- package/dist/utils/typescript-detector.d.ts.map +0 -1
- package/dist/validation/spec-validation.d.ts +0 -43
- package/dist/validation/spec-validation.d.ts.map +0 -1
- package/dist/waivers-manager.d.ts +0 -167
- package/dist/waivers-manager.d.ts.map +0 -1
- 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
package/dist/config/index.js
CHANGED
|
@@ -49,15 +49,19 @@ function initializeGlobalSetup() {
|
|
|
49
49
|
function loadProvenanceTools() {
|
|
50
50
|
if (provenanceTools) return provenanceTools; // Already loaded
|
|
51
51
|
|
|
52
|
-
//
|
|
52
|
+
// Provenance tools are now handled by CLI command (caws provenance)
|
|
53
|
+
// Legacy tool loading removed - use CLI instead
|
|
54
|
+
// Try multiple possible locations for provenance tools (legacy support)
|
|
53
55
|
const possiblePaths = [
|
|
54
|
-
// 1.
|
|
55
|
-
path.join(
|
|
56
|
-
// 2.
|
|
56
|
+
// 1. New location (if someone manually adds it)
|
|
57
|
+
path.join(process.cwd(), '.caws/tools/provenance.js'),
|
|
58
|
+
// 2. Legacy location (for backward compatibility)
|
|
57
59
|
path.join(process.cwd(), 'apps/tools/caws/provenance.js'),
|
|
58
|
-
// 3.
|
|
60
|
+
// 3. Bundled templates in CLI package (legacy)
|
|
61
|
+
path.join(__dirname, '../../templates/.caws/tools/provenance.js'),
|
|
62
|
+
// 4. Template package in monorepo (legacy)
|
|
59
63
|
path.join(__dirname, '../../../caws-template/apps/tools/caws/provenance.js'),
|
|
60
|
-
//
|
|
64
|
+
// 5. Detected setup template directory
|
|
61
65
|
null, // Will be set from setup if available
|
|
62
66
|
];
|
|
63
67
|
|
|
@@ -65,7 +69,7 @@ function loadProvenanceTools() {
|
|
|
65
69
|
try {
|
|
66
70
|
const setup = cawsSetup || initializeGlobalSetup();
|
|
67
71
|
if (setup?.hasTemplateDir && setup?.templateDir) {
|
|
68
|
-
possiblePaths[
|
|
72
|
+
possiblePaths[4] = path.join(setup.templateDir, '.caws/tools/provenance.js');
|
|
69
73
|
}
|
|
70
74
|
} catch (setupError) {
|
|
71
75
|
// Continue without detected setup
|
|
@@ -97,8 +101,13 @@ function initializeLanguageSupport() {
|
|
|
97
101
|
if (languageSupport) return languageSupport;
|
|
98
102
|
|
|
99
103
|
try {
|
|
100
|
-
//
|
|
104
|
+
// Language support tools removed - use CLI instead
|
|
105
|
+
// Try multiple possible locations for language support (legacy support)
|
|
101
106
|
const possiblePaths = [
|
|
107
|
+
// New location (if someone manually adds it)
|
|
108
|
+
path.join(process.cwd(), '.caws/tools/language-support.js'),
|
|
109
|
+
// Legacy locations
|
|
110
|
+
path.join(process.cwd(), 'apps/tools/caws/language-support.js'),
|
|
102
111
|
path.join(__dirname, '../../../caws-template/apps/tools/caws/language-support.js'),
|
|
103
112
|
path.join(__dirname, '../../../../caws-template/apps/tools/caws/language-support.js'),
|
|
104
113
|
path.join(process.cwd(), 'packages/caws-template/apps/tools/caws/language-support.js'),
|
|
@@ -42,16 +42,28 @@ function generateWorkingSpec(answers) {
|
|
|
42
42
|
.split(',')
|
|
43
43
|
.map((s) => s.trim())
|
|
44
44
|
.filter((s) => s),
|
|
45
|
-
out: (answers.scopeOut || 'node_modules/, dist/')
|
|
45
|
+
out: (answers.scopeOut || 'node_modules/, dist/, build/')
|
|
46
46
|
.split(',')
|
|
47
47
|
.map((s) => s.trim())
|
|
48
|
-
.filter((s) => s)
|
|
48
|
+
.filter((s) => s)
|
|
49
|
+
// Remove glob patterns - scope.out should only contain directory paths
|
|
50
|
+
.filter((s) => !s.includes('*') && !s.includes('?'))
|
|
51
|
+
// Ensure paths end with / for directories or are explicit file paths
|
|
52
|
+
.map((s) => {
|
|
53
|
+
// If it's a directory pattern without trailing slash, add it
|
|
54
|
+
if (!s.includes('.') && !s.endsWith('/')) {
|
|
55
|
+
return s + '/';
|
|
56
|
+
}
|
|
57
|
+
return s;
|
|
58
|
+
}),
|
|
49
59
|
},
|
|
50
60
|
invariants: (answers.projectInvariants || 'System maintains data consistency')
|
|
51
61
|
.split('\n')
|
|
52
62
|
.map((i) => i.trim())
|
|
53
63
|
.filter((i) => i),
|
|
54
|
-
acceptance: (
|
|
64
|
+
acceptance: (
|
|
65
|
+
answers.acceptanceCriteria || 'Given current state, when action occurs, then expected result'
|
|
66
|
+
)
|
|
55
67
|
.split('\n')
|
|
56
68
|
.filter((a) => a.trim())
|
|
57
69
|
.map((criteria, index) => {
|
|
@@ -107,7 +119,7 @@ function generateWorkingSpec(answers) {
|
|
|
107
119
|
},
|
|
108
120
|
];
|
|
109
121
|
}
|
|
110
|
-
|
|
122
|
+
|
|
111
123
|
// For Tier 1 & 2, provide minimal project_setup contract if none specified
|
|
112
124
|
const riskTier = answers.riskTier || 2;
|
|
113
125
|
if (riskTier === 1 || riskTier === 2) {
|
|
@@ -115,11 +127,12 @@ function generateWorkingSpec(answers) {
|
|
|
115
127
|
{
|
|
116
128
|
type: 'project_setup',
|
|
117
129
|
path: '.caws/working-spec.yaml',
|
|
118
|
-
description:
|
|
130
|
+
description:
|
|
131
|
+
'Project-level CAWS configuration. Feature-specific contracts will be added as features are developed.',
|
|
119
132
|
},
|
|
120
133
|
];
|
|
121
134
|
}
|
|
122
|
-
|
|
135
|
+
|
|
123
136
|
// Tier 3 doesn't require contracts
|
|
124
137
|
return [];
|
|
125
138
|
})(),
|
|
@@ -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
|
|
@@ -138,6 +142,100 @@ if [ ! -d ".caws" ]; then
|
|
|
138
142
|
exit 0
|
|
139
143
|
fi
|
|
140
144
|
|
|
145
|
+
# Check for git locks before proceeding
|
|
146
|
+
if [ -f ".git/index.lock" ]; then
|
|
147
|
+
LOCK_AGE=$(($(date +%s) - $(stat -f %m .git/index.lock 2>/dev/null || stat -c %Y .git/index.lock 2>/dev/null || echo 0)))
|
|
148
|
+
LOCK_AGE_MINUTES=$((LOCK_AGE / 60))
|
|
149
|
+
|
|
150
|
+
if [ $LOCK_AGE_MINUTES -gt 5 ]; then
|
|
151
|
+
echo "⚠️ Stale git lock detected (\${LOCK_AGE_MINUTES} minutes old)"
|
|
152
|
+
echo "💡 This may indicate a crashed git process"
|
|
153
|
+
echo "💡 Remove stale lock: rm .git/index.lock"
|
|
154
|
+
echo "⚠️ Warning: Check for running git/editor processes before removing"
|
|
155
|
+
exit 1
|
|
156
|
+
else
|
|
157
|
+
echo "⚠️ Git lock detected (\${LOCK_AGE_MINUTES} minutes old)"
|
|
158
|
+
echo "💡 Another git process may be running"
|
|
159
|
+
echo "💡 Wait for the other process to complete, or check for running processes"
|
|
160
|
+
exit 1
|
|
161
|
+
fi
|
|
162
|
+
fi
|
|
163
|
+
|
|
164
|
+
# Validate YAML syntax for all CAWS spec files
|
|
165
|
+
echo "🔍 Validating YAML syntax for CAWS spec files..."
|
|
166
|
+
YAML_VALIDATION_FAILED=false
|
|
167
|
+
|
|
168
|
+
# Find all staged .yaml/.yml files in .caws directory
|
|
169
|
+
STAGED_YAML_FILES=$(git diff --cached --name-only --diff-filter=ACM | grep -E '\\.caws/.*\\.(yaml|yml)$' || true)
|
|
170
|
+
|
|
171
|
+
if [ -n "$STAGED_YAML_FILES" ]; then
|
|
172
|
+
# Use Node.js to validate YAML if available
|
|
173
|
+
if command -v node >/dev/null 2>&1; then
|
|
174
|
+
# Try to use CAWS CLI for validation
|
|
175
|
+
if command -v caws >/dev/null 2>&1; then
|
|
176
|
+
for file in $STAGED_YAML_FILES; do
|
|
177
|
+
if [ -f "$file" ]; then
|
|
178
|
+
# Use Node.js to validate YAML syntax
|
|
179
|
+
if ! node -e "
|
|
180
|
+
const yaml = require('js-yaml');
|
|
181
|
+
const fs = require('fs');
|
|
182
|
+
try {
|
|
183
|
+
const content = fs.readFileSync('$file', 'utf8');
|
|
184
|
+
yaml.load(content);
|
|
185
|
+
process.exit(0);
|
|
186
|
+
} catch (error) {
|
|
187
|
+
console.error('❌ Invalid YAML in $file');
|
|
188
|
+
console.error(' Error:', error.message);
|
|
189
|
+
if (error.mark) {
|
|
190
|
+
console.error(' Line:', error.mark.line + 1, 'Column:', error.mark.column + 1);
|
|
191
|
+
if (error.mark.snippet) console.error(' ' + error.mark.snippet);
|
|
192
|
+
}
|
|
193
|
+
process.exit(1);
|
|
194
|
+
}
|
|
195
|
+
" 2>&1; then
|
|
196
|
+
YAML_VALIDATION_FAILED=true
|
|
197
|
+
fi
|
|
198
|
+
fi
|
|
199
|
+
done
|
|
200
|
+
else
|
|
201
|
+
# Fallback: use node directly with js-yaml
|
|
202
|
+
for file in $STAGED_YAML_FILES; do
|
|
203
|
+
if [ -f "$file" ]; then
|
|
204
|
+
if ! node -e "
|
|
205
|
+
const yaml = require('js-yaml');
|
|
206
|
+
const fs = require('fs');
|
|
207
|
+
try {
|
|
208
|
+
const content = fs.readFileSync('$file', 'utf8');
|
|
209
|
+
yaml.load(content);
|
|
210
|
+
process.exit(0);
|
|
211
|
+
} catch (error) {
|
|
212
|
+
console.error('❌ Invalid YAML in $file');
|
|
213
|
+
console.error(' Error:', error.message);
|
|
214
|
+
if (error.mark) {
|
|
215
|
+
console.error(' Line:', error.mark.line + 1, 'Column:', error.mark.column + 1);
|
|
216
|
+
if (error.mark.snippet) console.error(' ' + error.mark.snippet);
|
|
217
|
+
}
|
|
218
|
+
process.exit(1);
|
|
219
|
+
}
|
|
220
|
+
" 2>&1; then
|
|
221
|
+
YAML_VALIDATION_FAILED=true
|
|
222
|
+
fi
|
|
223
|
+
fi
|
|
224
|
+
done
|
|
225
|
+
fi
|
|
226
|
+
else
|
|
227
|
+
echo "⚠️ Node.js not available - skipping YAML validation"
|
|
228
|
+
echo "💡 Install Node.js to enable YAML syntax validation"
|
|
229
|
+
fi
|
|
230
|
+
fi
|
|
231
|
+
|
|
232
|
+
if [ "$YAML_VALIDATION_FAILED" = true ]; then
|
|
233
|
+
echo "❌ YAML syntax validation failed - commit blocked"
|
|
234
|
+
echo "💡 Fix YAML syntax errors above before committing"
|
|
235
|
+
echo "💡 Consider using 'caws specs create <id>' instead of manual creation"
|
|
236
|
+
exit 1
|
|
237
|
+
fi
|
|
238
|
+
|
|
141
239
|
# Fallback chain for quality gates:
|
|
142
240
|
# 1. Try Node.js script (if exists)
|
|
143
241
|
# 2. Try CAWS CLI
|
|
@@ -231,40 +329,50 @@ fi
|
|
|
231
329
|
# Run hidden TODO analysis on staged files only (if available)
|
|
232
330
|
if [ "$QUALITY_GATES_RAN" = true ]; then
|
|
233
331
|
echo "🔍 Checking for hidden TODOs in staged files..."
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
332
|
+
|
|
333
|
+
TODO_CHECK_RAN=false
|
|
334
|
+
|
|
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"
|
|
248
351
|
fi
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
if command -v node >/dev/null 2>&1; then
|
|
252
|
-
if node
|
|
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
|
|
253
356
|
echo "✅ No critical hidden TODOs found in staged files"
|
|
357
|
+
TODO_CHECK_RAN=true
|
|
254
358
|
else
|
|
255
359
|
echo "❌ Critical hidden TODOs detected in staged files - commit blocked"
|
|
256
360
|
echo "💡 Fix stub implementations and placeholder code before committing"
|
|
257
361
|
echo "📖 See docs/PLACEHOLDER-DETECTION-GUIDE.md for classification"
|
|
258
362
|
echo ""
|
|
259
363
|
echo "🔍 Running detailed analysis on staged files..."
|
|
260
|
-
node
|
|
364
|
+
node "$TODO_ANALYZER" --staged-only --min-confidence 0.8
|
|
261
365
|
exit 1
|
|
262
366
|
fi
|
|
263
367
|
fi
|
|
264
|
-
|
|
265
|
-
|
|
368
|
+
fi
|
|
369
|
+
|
|
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
|
|
372
|
+
echo "⚠️ Using legacy Python TODO analyzer (deprecated)"
|
|
266
373
|
if python3 scripts/v3/analysis/todo_analyzer.py --staged-only --ci-mode --min-confidence 0.8 >/dev/null 2>&1; then
|
|
267
374
|
echo "✅ No critical hidden TODOs found in staged files"
|
|
375
|
+
TODO_CHECK_RAN=true
|
|
268
376
|
else
|
|
269
377
|
echo "❌ Critical hidden TODOs detected in staged files - commit blocked"
|
|
270
378
|
echo "💡 Fix stub implementations and placeholder code before committing"
|
|
@@ -274,8 +382,16 @@ if [ "$QUALITY_GATES_RAN" = true ]; then
|
|
|
274
382
|
python3 scripts/v3/analysis/todo_analyzer.py --staged-only --min-confidence 0.8
|
|
275
383
|
exit 1
|
|
276
384
|
fi
|
|
277
|
-
|
|
278
|
-
|
|
385
|
+
fi
|
|
386
|
+
|
|
387
|
+
# Option 3: No analyzer available - show language-aware suggestions
|
|
388
|
+
if [ "$TODO_CHECK_RAN" = false ]; then
|
|
389
|
+
echo "⚠️ TODO analyzer not available - skipping hidden TODO check"
|
|
390
|
+
echo "💡 Available options for TODO analysis:"
|
|
391
|
+
${todoSuggestion
|
|
392
|
+
.split('\n')
|
|
393
|
+
.map((line) => ` echo "${line.replace(/"/g, '\\"')}"`)
|
|
394
|
+
.join('\n')}
|
|
279
395
|
fi
|
|
280
396
|
fi
|
|
281
397
|
|
|
@@ -346,8 +462,8 @@ for arg in "$@"; do
|
|
|
346
462
|
echo "💡 To fix issues locally:"
|
|
347
463
|
echo " 1. Run: caws validate"
|
|
348
464
|
echo " 2. Fix reported issues"
|
|
349
|
-
echo " 3. Commit fixes: git commit --no-verify (allowed)"
|
|
350
|
-
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\\)"
|
|
351
467
|
exit 1
|
|
352
468
|
fi
|
|
353
469
|
done
|
|
@@ -410,13 +526,13 @@ if command -v caws >/dev/null 2>&1; then
|
|
|
410
526
|
echo " No active waivers found"
|
|
411
527
|
echo ""
|
|
412
528
|
echo "💡 If this is infrastructure/setup work, you can create a waiver:"
|
|
413
|
-
echo " caws waivers create
|
|
414
|
-
echo " --title='Initial CAWS setup'
|
|
415
|
-
echo " --reason=infrastructure_limitation
|
|
416
|
-
echo " --gates=contracts
|
|
417
|
-
echo " --expires-at='2024-12-31T23:59:59Z'
|
|
418
|
-
echo " --approved-by='@your-team'
|
|
419
|
-
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 \\\\"
|
|
420
536
|
echo " --mitigation-plan='Contracts will be added as features are developed'"
|
|
421
537
|
fi
|
|
422
538
|
|
|
@@ -425,43 +541,121 @@ if command -v caws >/dev/null 2>&1; then
|
|
|
425
541
|
echo "Next Steps:"
|
|
426
542
|
echo " 1. Review errors above"
|
|
427
543
|
echo " 2. Fix issues in .caws/working-spec.yaml"
|
|
428
|
-
echo " 3. Run: caws validate (to verify fixes)"
|
|
429
|
-
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\\)"
|
|
430
546
|
echo " 5. Push again: git push"
|
|
431
547
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
432
548
|
exit 1
|
|
433
549
|
fi
|
|
434
550
|
fi
|
|
435
551
|
|
|
436
|
-
# Run
|
|
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 ""
|
|
437
617
|
echo "🔒 Running security checks..."
|
|
438
618
|
if [ -f "package.json" ]; then
|
|
439
|
-
# Check for vulnerabilities
|
|
440
619
|
if command -v npm >/dev/null 2>&1; then
|
|
441
620
|
echo "🔍 Checking for vulnerabilities..."
|
|
442
621
|
if npm audit --audit-level moderate >/dev/null 2>&1; then
|
|
443
622
|
echo "✅ Security audit passed"
|
|
444
623
|
else
|
|
445
|
-
echo "⚠️ Security vulnerabilities found"
|
|
624
|
+
echo "⚠️ Security vulnerabilities found (non-blocking)"
|
|
446
625
|
echo "💡 Review with: npm audit"
|
|
447
|
-
# Don't fail on warnings, just warn
|
|
448
626
|
fi
|
|
449
627
|
fi
|
|
450
628
|
elif [ -f "requirements.txt" ] || [ -f "pyproject.toml" ]; then
|
|
451
|
-
# Python project security checks
|
|
452
629
|
if command -v pip-audit >/dev/null 2>&1; then
|
|
453
630
|
echo "🔍 Checking Python vulnerabilities..."
|
|
454
|
-
pip-audit --desc 2>/dev/null || echo "⚠️ Install pip-audit
|
|
631
|
+
pip-audit --desc 2>/dev/null || echo "⚠️ Install pip-audit: pip install pip-audit"
|
|
455
632
|
fi
|
|
456
633
|
elif [ -f "Cargo.toml" ]; then
|
|
457
|
-
# Rust project security checks
|
|
458
634
|
if command -v cargo-audit >/dev/null 2>&1; then
|
|
459
635
|
echo "🔍 Checking Rust vulnerabilities..."
|
|
460
|
-
cargo audit 2>/dev/null || echo "⚠️ Install cargo-audit
|
|
636
|
+
cargo audit 2>/dev/null || echo "⚠️ Install cargo-audit: cargo install cargo-audit"
|
|
461
637
|
fi
|
|
462
638
|
fi
|
|
463
639
|
|
|
464
|
-
|
|
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"
|
|
465
659
|
`;
|
|
466
660
|
}
|
|
467
661
|
|
|
@@ -485,7 +679,7 @@ fi
|
|
|
485
679
|
|
|
486
680
|
# Basic commit message validation
|
|
487
681
|
if [ \${#COMMIT_MSG} -lt 10 ]; then
|
|
488
|
-
echo "❌ Commit message too short (minimum 10 characters)"
|
|
682
|
+
echo "❌ Commit message too short \\(minimum 10 characters\\)"
|
|
489
683
|
echo "💡 Write descriptive commit messages"
|
|
490
684
|
exit 1
|
|
491
685
|
fi
|
|
@@ -602,4 +796,9 @@ module.exports = {
|
|
|
602
796
|
scaffoldGitHooks,
|
|
603
797
|
removeGitHooks,
|
|
604
798
|
checkGitHooksStatus,
|
|
799
|
+
// Export generator functions for testing
|
|
800
|
+
generatePrePushHook,
|
|
801
|
+
generatePreCommitHook,
|
|
802
|
+
generatePostCommitHook,
|
|
803
|
+
generateCommitMsgHook,
|
|
605
804
|
};
|
package/dist/scaffold/index.js
CHANGED
|
@@ -14,6 +14,7 @@ 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;
|
|
@@ -31,20 +32,20 @@ const CLI_VERSION = require('../../package.json').version;
|
|
|
31
32
|
function findTemplateDir() {
|
|
32
33
|
// Find package root using shared utility
|
|
33
34
|
const packageRoot = findPackageRoot(__dirname);
|
|
34
|
-
|
|
35
|
+
|
|
35
36
|
// Try templates relative to package root first (works in both dev and global install)
|
|
36
37
|
const possiblePaths = [
|
|
37
38
|
path.join(packageRoot, 'templates'),
|
|
38
39
|
path.resolve(__dirname, '../../templates'), // Dev fallback
|
|
39
40
|
path.resolve(__dirname, '../templates'), // Legacy fallback
|
|
40
41
|
];
|
|
41
|
-
|
|
42
|
+
|
|
42
43
|
for (const testPath of possiblePaths) {
|
|
43
44
|
if (fs.existsSync(testPath)) {
|
|
44
45
|
return testPath;
|
|
45
46
|
}
|
|
46
47
|
}
|
|
47
|
-
|
|
48
|
+
|
|
48
49
|
return null;
|
|
49
50
|
}
|
|
50
51
|
|
|
@@ -301,12 +302,32 @@ async function scaffoldProject(options) {
|
|
|
301
302
|
// Determine what enhancements to add based on setup type and options
|
|
302
303
|
const enhancements = [];
|
|
303
304
|
|
|
304
|
-
// Add CAWS tools directory
|
|
305
|
+
// Add CAWS tools to .caws/ directory (keeps all CAWS files together)
|
|
305
306
|
enhancements.push({
|
|
306
|
-
name: '
|
|
307
|
+
name: '.caws/tools',
|
|
307
308
|
description: 'CAWS tools directory',
|
|
308
309
|
required: true,
|
|
309
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
|
+
});
|
|
310
331
|
|
|
311
332
|
// Add codemods if requested or not minimal
|
|
312
333
|
if (options.withCodemods || (!options.minimal && !options.withCodemods)) {
|
|
@@ -457,6 +478,19 @@ async function scaffoldProject(options) {
|
|
|
457
478
|
console.log(
|
|
458
479
|
chalk.gray(' For now, quality gates will work via CAWS CLI or local scripts')
|
|
459
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
|
+
}
|
|
460
494
|
}
|
|
461
495
|
} else {
|
|
462
496
|
// No package.json - suggest global install or manual setup
|
|
@@ -601,12 +635,14 @@ async function scaffoldProject(options) {
|
|
|
601
635
|
try {
|
|
602
636
|
// Check if the enhancement name looks like a file (has extension)
|
|
603
637
|
const hasExtension = path.extname(enhancement.name).length > 0;
|
|
604
|
-
|
|
638
|
+
|
|
605
639
|
if (hasExtension) {
|
|
606
640
|
// Create an empty file for file-like enhancements
|
|
607
641
|
await fs.ensureDir(path.dirname(destPath));
|
|
608
642
|
await fs.writeFile(destPath, '');
|
|
609
|
-
console.log(
|
|
643
|
+
console.log(
|
|
644
|
+
chalk.yellow(`⚠️ Created empty ${enhancement.description} (template not found)`)
|
|
645
|
+
);
|
|
610
646
|
console.log(chalk.gray(` Template expected at: ${sourcePath}`));
|
|
611
647
|
} else {
|
|
612
648
|
// Create directory for directory-like enhancements
|
|
@@ -698,6 +734,16 @@ async function scaffoldProject(options) {
|
|
|
698
734
|
console.log(chalk.yellow('\n⚠️ Force mode was used - review changes carefully'));
|
|
699
735
|
}
|
|
700
736
|
|
|
737
|
+
// Update .gitignore to exclude CAWS local runtime files
|
|
738
|
+
const gitignoreUpdated = await updateGitignore(currentDir);
|
|
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
|
+
|
|
701
747
|
// Save provenance manifest if tools are available
|
|
702
748
|
const tools = loadProvenanceTools && loadProvenanceTools();
|
|
703
749
|
if (tools && typeof tools.saveProvenance === 'function') {
|
|
@@ -0,0 +1,21 @@
|
|
|
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
|
+
|
|
21
|
+
|