@paths.design/caws-cli 7.0.2 → 7.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/budget-derivation.js +5 -4
- package/dist/commands/diagnose.js +24 -19
- package/dist/commands/init.js +51 -4
- package/dist/commands/specs.js +40 -1
- package/dist/commands/status.js +2 -2
- package/dist/commands/tool.js +2 -3
- package/dist/config/index.js +17 -8
- package/dist/generators/working-spec.js +19 -6
- package/dist/scaffold/git-hooks.js +127 -29
- package/dist/scaffold/index.js +53 -7
- package/dist/templates/.caws/tools/README.md +20 -0
- package/dist/templates/.cursor/README.md +311 -0
- package/dist/templates/.cursor/hooks/audit.sh +55 -0
- package/dist/templates/.cursor/hooks/block-dangerous.sh +83 -0
- package/dist/templates/.cursor/hooks/caws-quality-check.sh +52 -0
- package/dist/templates/.cursor/hooks/caws-scope-guard.sh +130 -0
- package/dist/templates/.cursor/hooks/caws-tool-validation.sh +121 -0
- package/dist/templates/.cursor/hooks/format.sh +38 -0
- package/dist/templates/.cursor/hooks/naming-check.sh +64 -0
- package/dist/templates/.cursor/hooks/scan-secrets.sh +46 -0
- package/dist/templates/.cursor/hooks/scope-guard.sh +52 -0
- package/dist/templates/.cursor/hooks/validate-spec.sh +83 -0
- package/dist/templates/.cursor/hooks.json +59 -0
- package/dist/templates/.cursor/rules/00-claims-verification.mdc +144 -0
- package/dist/templates/.cursor/rules/01-working-style.mdc +50 -0
- package/dist/templates/.cursor/rules/02-quality-gates.mdc +370 -0
- package/dist/templates/.cursor/rules/03-naming-and-refactor.mdc +33 -0
- package/dist/templates/.cursor/rules/04-logging-language-style.mdc +23 -0
- package/dist/templates/.cursor/rules/05-safe-defaults-guards.mdc +23 -0
- package/dist/templates/.cursor/rules/06-typescript-conventions.mdc +36 -0
- package/dist/templates/.cursor/rules/07-process-ops.mdc +20 -0
- package/dist/templates/.cursor/rules/08-solid-and-architecture.mdc +16 -0
- package/dist/templates/.cursor/rules/09-docstrings.mdc +89 -0
- package/dist/templates/.cursor/rules/10-documentation-quality-standards.mdc +390 -0
- package/dist/templates/.cursor/rules/11-scope-management-waivers.mdc +385 -0
- package/dist/templates/.cursor/rules/12-implementation-completeness.mdc +516 -0
- package/dist/templates/.cursor/rules/13-language-agnostic-standards.mdc +588 -0
- package/dist/templates/.cursor/rules/README.md +148 -0
- package/dist/templates/.github/copilot/instructions.md +311 -0
- package/dist/templates/.idea/runConfigurations/CAWS_Evaluate.xml +5 -0
- package/dist/templates/.idea/runConfigurations/CAWS_Validate.xml +5 -0
- package/dist/templates/.vscode/launch.json +56 -0
- package/dist/templates/.vscode/settings.json +93 -0
- package/dist/templates/.windsurf/workflows/caws-guided-development.md +92 -0
- package/dist/templates/COMMIT_CONVENTIONS.md +86 -0
- package/dist/templates/OIDC_SETUP.md +300 -0
- package/dist/templates/agents.md +1047 -0
- package/dist/templates/codemod/README.md +1 -0
- package/dist/templates/codemod/test.js +93 -0
- package/dist/templates/docs/README.md +150 -0
- package/dist/templates/scripts/quality-gates/check-god-objects.js +146 -0
- package/dist/templates/scripts/quality-gates/run-quality-gates.js +50 -0
- package/dist/templates/scripts/v3/analysis/todo_analyzer.py +1997 -0
- package/dist/tool-loader.js +6 -1
- package/dist/tool-validator.js +8 -2
- package/dist/utils/detection.js +4 -3
- package/dist/utils/git-lock.js +118 -0
- package/dist/utils/gitignore-updater.js +148 -0
- package/dist/utils/quality-gates.js +47 -7
- package/dist/utils/spec-resolver.js +23 -3
- package/dist/utils/yaml-validation.js +155 -0
- package/dist/validation/spec-validation.js +81 -2
- package/package.json +2 -2
- package/templates/.caws/schemas/waivers.schema.json +30 -0
- package/templates/.caws/schemas/working-spec.schema.json +133 -0
- package/templates/.caws/templates/working-spec.template.yml +74 -0
- package/templates/.caws/tools/README.md +20 -0
- package/templates/.caws/tools/scope-guard.js +208 -0
- package/templates/.caws/tools-allow.json +331 -0
- package/templates/.caws/waivers.yml +19 -0
- package/templates/.cursor/hooks/scope-guard.sh +2 -2
- package/templates/.cursor/hooks/validate-spec.sh +42 -7
- package/templates/apps/tools/caws/COMPLETION_REPORT.md +0 -331
- package/templates/apps/tools/caws/MIGRATION_SUMMARY.md +0 -360
- package/templates/apps/tools/caws/README.md +0 -463
- package/templates/apps/tools/caws/TEST_STATUS.md +0 -365
- package/templates/apps/tools/caws/attest.js +0 -357
- package/templates/apps/tools/caws/ci-optimizer.js +0 -642
- package/templates/apps/tools/caws/config.ts +0 -245
- package/templates/apps/tools/caws/cross-functional.js +0 -876
- package/templates/apps/tools/caws/dashboard.js +0 -1112
- package/templates/apps/tools/caws/flake-detector.ts +0 -362
- package/templates/apps/tools/caws/gates.js +0 -198
- package/templates/apps/tools/caws/gates.ts +0 -271
- package/templates/apps/tools/caws/language-adapters.ts +0 -381
- package/templates/apps/tools/caws/language-support.d.ts +0 -367
- package/templates/apps/tools/caws/language-support.d.ts.map +0 -1
- package/templates/apps/tools/caws/language-support.js +0 -585
- package/templates/apps/tools/caws/legacy-assessment.ts +0 -408
- package/templates/apps/tools/caws/legacy-assessor.js +0 -764
- package/templates/apps/tools/caws/mutant-analyzer.js +0 -734
- package/templates/apps/tools/caws/perf-budgets.ts +0 -349
- package/templates/apps/tools/caws/prompt-lint.js.backup +0 -274
- package/templates/apps/tools/caws/property-testing.js +0 -707
- package/templates/apps/tools/caws/provenance.d.ts +0 -14
- package/templates/apps/tools/caws/provenance.d.ts.map +0 -1
- package/templates/apps/tools/caws/provenance.js +0 -132
- package/templates/apps/tools/caws/provenance.js.backup +0 -73
- package/templates/apps/tools/caws/provenance.ts +0 -211
- package/templates/apps/tools/caws/security-provenance.ts +0 -483
- package/templates/apps/tools/caws/shared/base-tool.ts +0 -281
- package/templates/apps/tools/caws/shared/config-manager.ts +0 -366
- package/templates/apps/tools/caws/shared/gate-checker.ts +0 -849
- package/templates/apps/tools/caws/shared/types.ts +0 -444
- package/templates/apps/tools/caws/shared/validator.ts +0 -305
- package/templates/apps/tools/caws/shared/waivers-manager.ts +0 -174
- package/templates/apps/tools/caws/spec-test-mapper.ts +0 -391
- package/templates/apps/tools/caws/test-quality.js +0 -578
- package/templates/apps/tools/caws/validate.js +0 -76
- package/templates/apps/tools/caws/validate.ts +0 -228
- package/templates/apps/tools/caws/waivers.js +0 -344
- /package/{templates/apps/tools/caws → dist/templates/.caws}/schemas/waivers.schema.json +0 -0
- /package/{templates/apps/tools/caws → dist/templates/.caws}/schemas/working-spec.schema.json +0 -0
- /package/{templates/apps/tools/caws → dist/templates/.caws}/templates/working-spec.template.yml +0 -0
- /package/{templates/apps/tools/caws → dist/templates/.caws/tools}/scope-guard.js +0 -0
- /package/{templates/apps/tools/caws → dist/templates/.caws}/tools-allow.json +0 -0
- /package/{templates/apps/tools/caws → dist/templates/.caws}/waivers.yml +0 -0
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(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
|
+
|
|
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,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
|
+
|
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
# CAWS Cursor IDE Integration
|
|
2
|
+
|
|
3
|
+
This directory contains Cursor IDE hooks that provide real-time CAWS quality assurance integration during development.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
Cursor hooks enable seamless integration between CAWS and the Cursor IDE, providing:
|
|
8
|
+
|
|
9
|
+
- **Real-time quality validation** as you code
|
|
10
|
+
- **Automatic spec validation** when editing working specs
|
|
11
|
+
- **Scope enforcement** preventing out-of-scope file access
|
|
12
|
+
- **Tool validation** for safe MCP execution
|
|
13
|
+
- **Quality monitoring** after file edits
|
|
14
|
+
|
|
15
|
+
## Hook Configuration
|
|
16
|
+
|
|
17
|
+
The `hooks.json` file defines when each hook runs:
|
|
18
|
+
|
|
19
|
+
```json
|
|
20
|
+
{
|
|
21
|
+
"beforeShellExecution": ["block-dangerous.sh", "audit.sh"],
|
|
22
|
+
"beforeMCPExecution": ["audit.sh", "caws-tool-validation.sh"],
|
|
23
|
+
"beforeReadFile": ["scan-secrets.sh", "caws-scope-guard.sh"],
|
|
24
|
+
"afterFileEdit": ["format.sh", "naming-check.sh", "validate-spec.sh", "caws-quality-check.sh", "audit.sh"],
|
|
25
|
+
"beforeSubmitPrompt": ["caws-scope-guard.sh", "audit.sh"],
|
|
26
|
+
"stop": ["audit.sh"]
|
|
27
|
+
}
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Available Hooks
|
|
31
|
+
|
|
32
|
+
### CAWS-Specific Hooks
|
|
33
|
+
|
|
34
|
+
#### `caws-quality-check.sh`
|
|
35
|
+
- **Trigger**: `afterFileEdit`
|
|
36
|
+
- **Purpose**: Runs CAWS quality evaluation after code changes
|
|
37
|
+
- **Blocks**: No (provides warnings and suggestions)
|
|
38
|
+
- **Fallback**: Graceful degradation if CAWS CLI unavailable
|
|
39
|
+
|
|
40
|
+
#### `caws-scope-guard.sh`
|
|
41
|
+
- **Trigger**: `beforeReadFile`, `beforeSubmitPrompt`
|
|
42
|
+
- **Purpose**: Prevents access to files outside CAWS-defined scope
|
|
43
|
+
- **Blocks**: Yes (for out-of-scope file access)
|
|
44
|
+
- **Requires**: `.caws/working-spec.yaml`
|
|
45
|
+
|
|
46
|
+
#### `caws-tool-validation.sh`
|
|
47
|
+
- **Trigger**: `beforeMCPExecution`
|
|
48
|
+
- **Purpose**: Validates CAWS MCP tool calls for security
|
|
49
|
+
- **Blocks**: Yes (for dangerous operations or invalid waivers)
|
|
50
|
+
- **Validates**: Waiver creation, tool permissions, command safety
|
|
51
|
+
|
|
52
|
+
### General Security Hooks
|
|
53
|
+
|
|
54
|
+
#### `block-dangerous.sh`
|
|
55
|
+
- **Trigger**: `beforeShellExecution`
|
|
56
|
+
- **Purpose**: Prevents execution of dangerous shell commands
|
|
57
|
+
- **Blocks**: `rm -rf /`, `sudo`, destructive operations
|
|
58
|
+
|
|
59
|
+
#### `scan-secrets.sh`
|
|
60
|
+
- **Trigger**: `beforeReadFile`
|
|
61
|
+
- **Purpose**: Scans for potential secrets before file access
|
|
62
|
+
- **Blocks**: Files containing password/token patterns
|
|
63
|
+
|
|
64
|
+
### Code Quality Hooks
|
|
65
|
+
|
|
66
|
+
#### `format.sh`
|
|
67
|
+
- **Trigger**: `afterFileEdit`
|
|
68
|
+
- **Purpose**: Auto-formats code using Prettier/ESLint
|
|
69
|
+
- **Blocks**: No (formats in background)
|
|
70
|
+
|
|
71
|
+
#### `naming-check.sh`
|
|
72
|
+
- **Trigger**: `afterFileEdit`
|
|
73
|
+
- **Purpose**: Enforces CAWS naming conventions
|
|
74
|
+
- **Blocks**: No (provides warnings)
|
|
75
|
+
|
|
76
|
+
#### `validate-spec.sh`
|
|
77
|
+
- **Trigger**: `afterFileEdit`
|
|
78
|
+
- **Purpose**: Validates CAWS working specs in real-time
|
|
79
|
+
- **Blocks**: No (shows validation errors)
|
|
80
|
+
|
|
81
|
+
### Audit Hooks
|
|
82
|
+
|
|
83
|
+
#### `audit.sh`
|
|
84
|
+
- **Trigger**: Multiple events
|
|
85
|
+
- **Purpose**: Logs all hook executions for debugging
|
|
86
|
+
- **Blocks**: No (passive logging)
|
|
87
|
+
|
|
88
|
+
## Installation
|
|
89
|
+
|
|
90
|
+
### Automatic Setup
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
# CAWS init automatically sets up Cursor hooks
|
|
94
|
+
caws init my-project --interactive
|
|
95
|
+
|
|
96
|
+
# Or manually scaffold hooks
|
|
97
|
+
caws scaffold
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### Manual Setup
|
|
101
|
+
|
|
102
|
+
1. Copy `.cursor/` directory to your project root
|
|
103
|
+
2. Ensure hook scripts are executable: `chmod +x .cursor/hooks/*.sh`
|
|
104
|
+
3. Restart Cursor IDE
|
|
105
|
+
4. Verify hooks are active in Cursor settings
|
|
106
|
+
|
|
107
|
+
## Configuration
|
|
108
|
+
|
|
109
|
+
### Environment Variables
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
# Enable debug logging
|
|
113
|
+
export CURSOR_HOOKS_DEBUG=1
|
|
114
|
+
|
|
115
|
+
# CAWS CLI path override
|
|
116
|
+
export CAWS_CLI_PATH=/custom/path/to/caws
|
|
117
|
+
|
|
118
|
+
# Disable specific hooks
|
|
119
|
+
export CURSOR_DISABLE_HOOKS=audit.sh,format.sh
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### Hook Customization
|
|
123
|
+
|
|
124
|
+
Modify `hooks.json` to customize hook behavior:
|
|
125
|
+
|
|
126
|
+
```json
|
|
127
|
+
{
|
|
128
|
+
"afterFileEdit": [
|
|
129
|
+
{
|
|
130
|
+
"command": "./.cursor/hooks/caws-quality-check.sh",
|
|
131
|
+
"timeout": 5000,
|
|
132
|
+
"background": true
|
|
133
|
+
}
|
|
134
|
+
]
|
|
135
|
+
}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## Troubleshooting
|
|
139
|
+
|
|
140
|
+
### Hooks Not Running
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
# Check hook permissions
|
|
144
|
+
ls -la .cursor/hooks/
|
|
145
|
+
|
|
146
|
+
# Verify Cursor hooks are enabled
|
|
147
|
+
# Cursor Settings → Hooks → Enable hooks
|
|
148
|
+
|
|
149
|
+
# Check Cursor logs
|
|
150
|
+
# Help → Toggle Developer Tools → Console
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### CAWS CLI Not Found
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
# Install CAWS CLI
|
|
157
|
+
npm install -g @caws/cli
|
|
158
|
+
|
|
159
|
+
# Or use bundled version (VS Code extension)
|
|
160
|
+
code --install-extension caws.caws-vscode-extension
|
|
161
|
+
|
|
162
|
+
# Verify PATH
|
|
163
|
+
which caws
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
### False Positives
|
|
167
|
+
|
|
168
|
+
```bash
|
|
169
|
+
# Temporarily disable hooks
|
|
170
|
+
export CURSOR_DISABLE_HOOKS=caws-scope-guard.sh
|
|
171
|
+
|
|
172
|
+
# Or modify hook logic
|
|
173
|
+
vim .cursor/hooks/caws-scope-guard.sh
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### Performance Issues
|
|
177
|
+
|
|
178
|
+
```bash
|
|
179
|
+
# Run hooks in background
|
|
180
|
+
# Edit hooks.json to add "background": true
|
|
181
|
+
|
|
182
|
+
# Increase timeouts
|
|
183
|
+
# Edit hooks.json to add "timeout": 10000
|
|
184
|
+
|
|
185
|
+
# Disable slow hooks
|
|
186
|
+
export CURSOR_DISABLE_HOOKS=format.sh,naming-check.sh
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
## Development
|
|
190
|
+
|
|
191
|
+
### Creating New Hooks
|
|
192
|
+
|
|
193
|
+
1. **Create script** in `.cursor/hooks/`
|
|
194
|
+
2. **Make executable**: `chmod +x .cursor/hooks/your-hook.sh`
|
|
195
|
+
3. **Add to configuration** in `hooks.json`
|
|
196
|
+
4. **Test manually**: `echo '{}' | ./cursor/hooks/your-hook.sh`
|
|
197
|
+
|
|
198
|
+
### Hook Script Template
|
|
199
|
+
|
|
200
|
+
```bash
|
|
201
|
+
#!/bin/bash
|
|
202
|
+
# CAWS Hook: Description
|
|
203
|
+
# @author @darianrosebrook
|
|
204
|
+
|
|
205
|
+
set -e
|
|
206
|
+
|
|
207
|
+
# Read Cursor input
|
|
208
|
+
INPUT=$(cat)
|
|
209
|
+
DATA=$(echo "$INPUT" | jq -r '.data // ""')
|
|
210
|
+
|
|
211
|
+
# Your hook logic here
|
|
212
|
+
if [[ -n "$DATA" ]]; then
|
|
213
|
+
# Process data
|
|
214
|
+
echo '{"userMessage": "Hook executed", "agentMessage": "Details"}'
|
|
215
|
+
fi
|
|
216
|
+
|
|
217
|
+
exit 0
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
### Testing Hooks
|
|
221
|
+
|
|
222
|
+
```bash
|
|
223
|
+
# Test with sample input
|
|
224
|
+
echo '{"action": "edit_file", "file_path": "test.js"}' | ./cursor/hooks/caws-quality-check.sh
|
|
225
|
+
|
|
226
|
+
# Test error conditions
|
|
227
|
+
echo '{}' | ./cursor/hooks/caws-scope-guard.sh
|
|
228
|
+
|
|
229
|
+
# Debug with verbose output
|
|
230
|
+
export CURSOR_HOOKS_DEBUG=1
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
## Integration with CAWS Ecosystem
|
|
234
|
+
|
|
235
|
+
### Relationship to Other Tools
|
|
236
|
+
|
|
237
|
+
```
|
|
238
|
+
Cursor Hooks ←→ CAWS CLI ←→ VS Code Extension
|
|
239
|
+
↓ ↓ ↓
|
|
240
|
+
Real-time Command-line Rich IDE
|
|
241
|
+
Validation Interface Integration
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
### Complementary Tools
|
|
245
|
+
|
|
246
|
+
- **Git Hooks**: `.git/hooks/` for commit/push validation
|
|
247
|
+
- **VS Code Extension**: Rich UI for CAWS operations
|
|
248
|
+
- **MCP Server**: Agent tool integration
|
|
249
|
+
- **CAWS CLI**: Core functionality
|
|
250
|
+
|
|
251
|
+
### Data Flow
|
|
252
|
+
|
|
253
|
+
```
|
|
254
|
+
File Edit → Cursor Hook → CAWS CLI → Quality Check → User Feedback
|
|
255
|
+
↓
|
|
256
|
+
Audit Log → Provenance Tracking
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
## Security Considerations
|
|
260
|
+
|
|
261
|
+
### Safe Execution
|
|
262
|
+
|
|
263
|
+
- Hooks run in isolated processes
|
|
264
|
+
- No access to sensitive Cursor data
|
|
265
|
+
- Input validation on all hook data
|
|
266
|
+
- Timeout protection against hanging hooks
|
|
267
|
+
|
|
268
|
+
### Privacy Protection
|
|
269
|
+
|
|
270
|
+
- File contents not sent to external services
|
|
271
|
+
- Local CAWS CLI execution only
|
|
272
|
+
- No telemetry or data collection
|
|
273
|
+
- User-controlled hook execution
|
|
274
|
+
|
|
275
|
+
## Performance Optimization
|
|
276
|
+
|
|
277
|
+
### Hook Design Principles
|
|
278
|
+
|
|
279
|
+
1. **Fast Execution**: < 2 seconds for real-time feedback
|
|
280
|
+
2. **Background Processing**: Non-blocking operations
|
|
281
|
+
3. **Selective Running**: Only run relevant hooks
|
|
282
|
+
4. **Caching**: Avoid redundant operations
|
|
283
|
+
|
|
284
|
+
### Optimization Strategies
|
|
285
|
+
|
|
286
|
+
- **Debounced execution** for file edit hooks
|
|
287
|
+
- **Incremental validation** for large codebases
|
|
288
|
+
- **Parallel processing** for independent checks
|
|
289
|
+
- **Result caching** for repeated operations
|
|
290
|
+
|
|
291
|
+
## Contributing
|
|
292
|
+
|
|
293
|
+
### Hook Development Guidelines
|
|
294
|
+
|
|
295
|
+
- **Clear naming**: `caws-*` prefix for CAWS-specific hooks
|
|
296
|
+
- **Comprehensive logging**: Debug-friendly output
|
|
297
|
+
- **Error handling**: Graceful failure modes
|
|
298
|
+
- **Documentation**: Inline comments and README updates
|
|
299
|
+
- **Testing**: Manual and automated test coverage
|
|
300
|
+
|
|
301
|
+
### Pull Request Process
|
|
302
|
+
|
|
303
|
+
1. **Test locally** in Cursor IDE
|
|
304
|
+
2. **Update documentation** in this README
|
|
305
|
+
3. **Add configuration examples** if needed
|
|
306
|
+
4. **Consider performance impact** on large codebases
|
|
307
|
+
5. **Test with different project types** (CAWS/non-CAWS)
|
|
308
|
+
|
|
309
|
+
## License
|
|
310
|
+
|
|
311
|
+
MIT License - see main project LICENSE file.
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Cursor Hook: Audit Trail
|
|
3
|
+
#
|
|
4
|
+
# Purpose: Log all Cursor AI events for provenance tracking
|
|
5
|
+
# Event: All (beforeShellExecution, beforeMCPExecution, beforeReadFile,
|
|
6
|
+
# afterFileEdit, beforeSubmitPrompt, stop)
|
|
7
|
+
#
|
|
8
|
+
# @author @darianrosebrook
|
|
9
|
+
|
|
10
|
+
set -euo pipefail
|
|
11
|
+
|
|
12
|
+
# Read input from Cursor
|
|
13
|
+
INPUT=$(cat)
|
|
14
|
+
|
|
15
|
+
# Create log directory if it doesn't exist
|
|
16
|
+
LOG_DIR=".cursor/logs"
|
|
17
|
+
mkdir -p "$LOG_DIR"
|
|
18
|
+
|
|
19
|
+
# Log file with date rotation
|
|
20
|
+
LOG_FILE="$LOG_DIR/audit-$(date +%Y-%m-%d).log"
|
|
21
|
+
|
|
22
|
+
# Extract key information
|
|
23
|
+
TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
|
|
24
|
+
HOOK_EVENT=$(echo "$INPUT" | jq -r '.hook_event_name // "unknown"')
|
|
25
|
+
CONVERSATION_ID=$(echo "$INPUT" | jq -r '.conversation_id // "none"')
|
|
26
|
+
GENERATION_ID=$(echo "$INPUT" | jq -r '.generation_id // "none"')
|
|
27
|
+
|
|
28
|
+
# Create audit entry
|
|
29
|
+
AUDIT_ENTRY=$(cat <<EOF
|
|
30
|
+
{
|
|
31
|
+
"timestamp": "$TIMESTAMP",
|
|
32
|
+
"event": "$HOOK_EVENT",
|
|
33
|
+
"conversation_id": "$CONVERSATION_ID",
|
|
34
|
+
"generation_id": "$GENERATION_ID",
|
|
35
|
+
"details": $INPUT
|
|
36
|
+
}
|
|
37
|
+
EOF
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
# Append to audit log
|
|
41
|
+
echo "$AUDIT_ENTRY" >> "$LOG_FILE"
|
|
42
|
+
|
|
43
|
+
# Try to update CAWS provenance if available
|
|
44
|
+
if [ -f "apps/tools/caws/provenance.js" ]; then
|
|
45
|
+
node apps/tools/caws/provenance.js log-event \
|
|
46
|
+
--event="$HOOK_EVENT" \
|
|
47
|
+
--conversation="$CONVERSATION_ID" \
|
|
48
|
+
--generation="$GENERATION_ID" \
|
|
49
|
+
2>/dev/null || true
|
|
50
|
+
fi
|
|
51
|
+
|
|
52
|
+
# Always allow - this is observation only
|
|
53
|
+
echo '{"permission":"allow"}' 2>/dev/null || true
|
|
54
|
+
exit 0
|
|
55
|
+
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Cursor Hook: Dangerous Command Blocker
|
|
3
|
+
#
|
|
4
|
+
# Purpose: Block or ask permission for risky shell commands
|
|
5
|
+
# Event: beforeShellExecution
|
|
6
|
+
#
|
|
7
|
+
# @author @darianrosebrook
|
|
8
|
+
|
|
9
|
+
set -euo pipefail
|
|
10
|
+
|
|
11
|
+
# Read input from Cursor
|
|
12
|
+
INPUT=$(cat)
|
|
13
|
+
|
|
14
|
+
# Extract command and cwd
|
|
15
|
+
COMMAND=$(echo "$INPUT" | jq -r '.command // ""')
|
|
16
|
+
CWD=$(echo "$INPUT" | jq -r '.cwd // ""')
|
|
17
|
+
|
|
18
|
+
# Hard blocks - never allow these
|
|
19
|
+
# CRITICAL: These commands can cause catastrophic data loss
|
|
20
|
+
# git init, git reset --hard, and git push --force were added after an incident
|
|
21
|
+
# where an agent panicked at quality gates and wiped thousands of lines of work
|
|
22
|
+
HARD_BLOCKS=(
|
|
23
|
+
"rm -rf /"
|
|
24
|
+
"rm -rf /*"
|
|
25
|
+
"rm -rf ~"
|
|
26
|
+
"rm -rf $HOME"
|
|
27
|
+
"> /dev/sda"
|
|
28
|
+
"git init" # Can wipe entire git history and stashed changes
|
|
29
|
+
"git commit --amend --no-edit" # Can rewrite commit history destructively
|
|
30
|
+
"git reset --hard" # Can lose uncommitted work and stashed changes
|
|
31
|
+
"git push --force" # Can overwrite remote repository history
|
|
32
|
+
"dd if="
|
|
33
|
+
"mkfs"
|
|
34
|
+
"format c:"
|
|
35
|
+
"del /f /s /q"
|
|
36
|
+
"DROP DATABASE"
|
|
37
|
+
"TRUNCATE TABLE"
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
for blocked in "${HARD_BLOCKS[@]}"; do
|
|
41
|
+
if [[ "$COMMAND" == *"$blocked"* ]]; then
|
|
42
|
+
echo '{"permission":"deny","userMessage":"⚠️ BLOCKED: Dangerous command detected. This operation could cause data loss.","agentMessage":"This command is blocked for safety. If you need to perform this operation, run it manually."}' 2>/dev/null
|
|
43
|
+
exit 0
|
|
44
|
+
fi
|
|
45
|
+
done
|
|
46
|
+
|
|
47
|
+
# Ask permission for risky operations
|
|
48
|
+
# Note: git commands moved to HARD_BLOCKS after catastrophic data loss incident
|
|
49
|
+
ASK_PERMISSION=(
|
|
50
|
+
"rm -rf"
|
|
51
|
+
"npm publish"
|
|
52
|
+
"docker rmi"
|
|
53
|
+
"docker system prune"
|
|
54
|
+
"kubectl delete"
|
|
55
|
+
"terraform destroy"
|
|
56
|
+
"DROP TABLE"
|
|
57
|
+
"DELETE FROM"
|
|
58
|
+
"UPDATE.*SET"
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
for risky in "${ASK_PERMISSION[@]}"; do
|
|
62
|
+
if echo "$COMMAND" | grep -qiE "$risky"; then
|
|
63
|
+
echo '{"permission":"ask","userMessage":"⚠️ Risky operation: '"$COMMAND"'. Approve to continue.","agentMessage":"This is a potentially destructive operation. User approval required."}' 2>/dev/null
|
|
64
|
+
exit 0
|
|
65
|
+
fi
|
|
66
|
+
done
|
|
67
|
+
|
|
68
|
+
# Block git operations that skip hooks
|
|
69
|
+
if echo "$COMMAND" | grep -qE "(--no-verify|--no-gpg-sign)"; then
|
|
70
|
+
echo '{"permission":"ask","userMessage":"⚠️ This command skips git hooks. Approve to continue.","agentMessage":"Skipping hooks bypasses quality gates. Use with caution."}' 2>/dev/null
|
|
71
|
+
exit 0
|
|
72
|
+
fi
|
|
73
|
+
|
|
74
|
+
# Block force push to main/master
|
|
75
|
+
if echo "$COMMAND" | grep -qE "git push.*(--force|-f).*\s+(origin\s+)?(main|master)"; then
|
|
76
|
+
echo '{"permission":"deny","userMessage":"⚠️ BLOCKED: Force push to main/master is not allowed.","agentMessage":"Force pushing to main/master can cause data loss for other developers."}' 2>/dev/null
|
|
77
|
+
exit 0
|
|
78
|
+
fi
|
|
79
|
+
|
|
80
|
+
# Allow by default
|
|
81
|
+
echo '{"permission":"allow"}' 2>/dev/null
|
|
82
|
+
exit 0
|
|
83
|
+
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# CAWS Quality Check Hook
|
|
3
|
+
# Runs CAWS quality validation after file edits
|
|
4
|
+
# @author @darianrosebrook
|
|
5
|
+
|
|
6
|
+
set -e
|
|
7
|
+
|
|
8
|
+
# Read input from Cursor
|
|
9
|
+
INPUT=$(cat)
|
|
10
|
+
FILE_PATH=$(echo "$INPUT" | jq -r '.file_path // ""')
|
|
11
|
+
|
|
12
|
+
# Only run on source files
|
|
13
|
+
if [[ "$FILE_PATH" =~ \.(js|ts|jsx|tsx|py|go|rs|java)$ ]] && [[ ! "$FILE_PATH" =~ node_modules ]] && [[ ! "$FILE_PATH" =~ dist ]]; then
|
|
14
|
+
|
|
15
|
+
# Check if CAWS is available
|
|
16
|
+
if command -v caws &> /dev/null; then
|
|
17
|
+
|
|
18
|
+
# Check if we're in a CAWS project
|
|
19
|
+
if [[ -f ".caws/working-spec.yaml" ]]; then
|
|
20
|
+
|
|
21
|
+
echo "🔍 Running CAWS quality check..." >&2
|
|
22
|
+
|
|
23
|
+
# Run CAWS evaluation in quiet mode for fast feedback
|
|
24
|
+
if caws agent evaluate .caws/working-spec.yaml --quiet 2>/dev/null; then
|
|
25
|
+
echo '{"userMessage": "✅ CAWS quality check passed", "agentMessage": "Quality standards maintained"}'
|
|
26
|
+
else
|
|
27
|
+
# Get detailed feedback
|
|
28
|
+
EVALUATION=$(caws agent evaluate .caws/working-spec.yaml --json 2>/dev/null || echo '{"success": false, "error": "Evaluation failed"}')
|
|
29
|
+
|
|
30
|
+
# Parse the evaluation result
|
|
31
|
+
SUCCESS=$(echo "$EVALUATION" | jq -r '.success // false')
|
|
32
|
+
SCORE=$(echo "$EVALUATION" | jq -r '.evaluation.quality_score // 0')
|
|
33
|
+
|
|
34
|
+
if [[ "$SUCCESS" == "true" ]] && (( $(echo "$SCORE > 0.75" | bc -l) )); then
|
|
35
|
+
echo '{"userMessage": "✅ CAWS quality standards met", "agentMessage": "Code meets quality requirements"}'
|
|
36
|
+
else
|
|
37
|
+
FAILED_GATES=$(echo "$EVALUATION" | jq -r '.evaluation.criteria[] | select(.status == "failed") | .name' | tr '\n' ', ' | sed 's/, $//')
|
|
38
|
+
|
|
39
|
+
echo '{
|
|
40
|
+
"userMessage": "⚠️ CAWS quality issues detected. Run: caws agent evaluate",
|
|
41
|
+
"agentMessage": "Quality gates failed: '"$FAILED_GATES"'",
|
|
42
|
+
"suggestions": [
|
|
43
|
+
"Run caws agent evaluate for detailed feedback",
|
|
44
|
+
"Consider creating a waiver if justified: caws waivers create",
|
|
45
|
+
"Address failing quality gates before proceeding"
|
|
46
|
+
]
|
|
47
|
+
}'
|
|
48
|
+
fi
|
|
49
|
+
fi
|
|
50
|
+
fi
|
|
51
|
+
fi
|
|
52
|
+
fi
|