@paths.design/caws-cli 3.1.0 → 3.2.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/README.md +295 -150
- package/dist/budget-derivation.d.ts +35 -0
- package/dist/budget-derivation.d.ts.map +1 -0
- package/dist/budget-derivation.js +204 -0
- package/dist/cicd-optimizer.d.ts +142 -0
- package/dist/cicd-optimizer.d.ts.map +1 -0
- package/dist/cicd-optimizer.js +504 -0
- package/dist/commands/burnup.d.ts +6 -0
- package/dist/commands/burnup.d.ts.map +1 -0
- package/dist/commands/burnup.js +90 -0
- package/dist/commands/init.d.ts +5 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +514 -0
- package/dist/commands/provenance.d.ts +32 -0
- package/dist/commands/provenance.d.ts.map +1 -0
- package/dist/commands/provenance.js +979 -0
- package/dist/commands/tool.d.ts +13 -0
- package/dist/commands/tool.d.ts.map +1 -0
- package/dist/commands/tool.js +138 -0
- package/dist/commands/validate.d.ts +7 -0
- package/dist/commands/validate.d.ts.map +1 -0
- package/dist/commands/validate.js +80 -0
- package/dist/config/index.d.ts +29 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +132 -0
- package/dist/error-handler.d.ts +50 -0
- package/dist/error-handler.d.ts.map +1 -0
- package/dist/error-handler.js +253 -0
- package/dist/generators/working-spec.d.ts +13 -0
- package/dist/generators/working-spec.d.ts.map +1 -0
- package/dist/generators/working-spec.js +204 -0
- package/dist/index.d.ts +3 -12
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +193 -2983
- package/dist/scaffold/cursor-hooks.d.ts +7 -0
- package/dist/scaffold/cursor-hooks.d.ts.map +1 -0
- package/dist/scaffold/cursor-hooks.js +152 -0
- package/dist/scaffold/git-hooks.d.ts +20 -0
- package/dist/scaffold/git-hooks.d.ts.map +1 -0
- package/dist/scaffold/git-hooks.js +417 -0
- package/dist/scaffold/index.d.ts +20 -0
- package/dist/scaffold/index.d.ts.map +1 -0
- package/dist/scaffold/index.js +486 -0
- package/dist/test-analysis.d.ts +182 -0
- package/dist/test-analysis.d.ts.map +1 -0
- package/dist/test-analysis.js +580 -0
- package/dist/tool-interface.d.ts +236 -0
- package/dist/tool-interface.d.ts.map +1 -0
- package/dist/tool-interface.js +314 -0
- package/dist/tool-loader.d.ts +77 -0
- package/dist/tool-loader.d.ts.map +1 -0
- package/dist/tool-loader.js +298 -0
- package/dist/tool-validator.d.ts +72 -0
- package/dist/tool-validator.d.ts.map +1 -0
- package/dist/tool-validator.js +387 -0
- package/dist/utils/detection.d.ts +7 -0
- package/dist/utils/detection.d.ts.map +1 -0
- package/dist/utils/detection.js +174 -0
- package/dist/utils/finalization.d.ts +17 -0
- package/dist/utils/finalization.d.ts.map +1 -0
- package/dist/utils/finalization.js +229 -0
- package/dist/utils/project-analysis.d.ts +14 -0
- package/dist/utils/project-analysis.d.ts.map +1 -0
- package/dist/utils/project-analysis.js +105 -0
- package/dist/validation/spec-validation.d.ts +29 -0
- package/dist/validation/spec-validation.d.ts.map +1 -0
- package/dist/validation/spec-validation.js +376 -0
- package/dist/waivers-manager.d.ts +167 -0
- package/dist/waivers-manager.d.ts.map +1 -0
- package/dist/waivers-manager.js +549 -0
- package/package.json +10 -12
- package/templates/.cursor/README.md +311 -0
- package/templates/.cursor/hooks/audit.sh +55 -0
- package/templates/.cursor/hooks/block-dangerous.sh +77 -0
- package/templates/.cursor/hooks/caws-quality-check.sh +52 -0
- package/templates/.cursor/hooks/caws-scope-guard.sh +74 -0
- package/templates/.cursor/hooks/caws-tool-validation.sh +121 -0
- package/templates/.cursor/hooks/format.sh +38 -0
- package/templates/.cursor/hooks/naming-check.sh +64 -0
- package/templates/.cursor/hooks/scan-secrets.sh +46 -0
- package/templates/.cursor/hooks/scope-guard.sh +52 -0
- package/templates/.cursor/hooks/validate-spec.sh +38 -0
- package/templates/.cursor/hooks.json +59 -0
- package/templates/.github/copilot/instructions.md +311 -0
- package/templates/.idea/runConfigurations/CAWS_Evaluate.xml +5 -0
- package/templates/.idea/runConfigurations/CAWS_Validate.xml +5 -0
- package/templates/.vscode/launch.json +56 -0
- package/templates/.vscode/settings.json +93 -0
- package/templates/.windsurf/workflows/caws-guided-development.md +92 -0
- package/templates/apps/tools/caws/README.md +1 -1
- package/templates/apps/tools/caws/schemas/working-spec.schema.json +21 -3
- package/templates/codemod/test.js +93 -1
- package/templates/apps/tools/caws/prompt-lint.js.backup +0 -274
- package/templates/apps/tools/caws/provenance.js.backup +0 -73
|
@@ -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,77 @@
|
|
|
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
|
+
HARD_BLOCKS=(
|
|
20
|
+
"rm -rf /"
|
|
21
|
+
"rm -rf /*"
|
|
22
|
+
"rm -rf ~"
|
|
23
|
+
"rm -rf $HOME"
|
|
24
|
+
"> /dev/sda"
|
|
25
|
+
"dd if="
|
|
26
|
+
"mkfs"
|
|
27
|
+
"format c:"
|
|
28
|
+
"del /f /s /q"
|
|
29
|
+
"DROP DATABASE"
|
|
30
|
+
"TRUNCATE TABLE"
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
for blocked in "${HARD_BLOCKS[@]}"; do
|
|
34
|
+
if [[ "$COMMAND" == *"$blocked"* ]]; then
|
|
35
|
+
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
|
|
36
|
+
exit 0
|
|
37
|
+
fi
|
|
38
|
+
done
|
|
39
|
+
|
|
40
|
+
# Ask permission for risky operations
|
|
41
|
+
ASK_PERMISSION=(
|
|
42
|
+
"rm -rf"
|
|
43
|
+
"git push --force"
|
|
44
|
+
"git reset --hard"
|
|
45
|
+
"npm publish"
|
|
46
|
+
"docker rmi"
|
|
47
|
+
"docker system prune"
|
|
48
|
+
"kubectl delete"
|
|
49
|
+
"terraform destroy"
|
|
50
|
+
"DROP TABLE"
|
|
51
|
+
"DELETE FROM"
|
|
52
|
+
"UPDATE.*SET"
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
for risky in "${ASK_PERMISSION[@]}"; do
|
|
56
|
+
if echo "$COMMAND" | grep -qiE "$risky"; then
|
|
57
|
+
echo '{"permission":"ask","userMessage":"⚠️ Risky operation: '"$COMMAND"'. Approve to continue.","agentMessage":"This is a potentially destructive operation. User approval required."}' 2>/dev/null
|
|
58
|
+
exit 0
|
|
59
|
+
fi
|
|
60
|
+
done
|
|
61
|
+
|
|
62
|
+
# Block git operations that skip hooks
|
|
63
|
+
if echo "$COMMAND" | grep -qE "(--no-verify|--no-gpg-sign)"; then
|
|
64
|
+
echo '{"permission":"ask","userMessage":"⚠️ This command skips git hooks. Approve to continue.","agentMessage":"Skipping hooks bypasses quality gates. Use with caution."}' 2>/dev/null
|
|
65
|
+
exit 0
|
|
66
|
+
fi
|
|
67
|
+
|
|
68
|
+
# Block force push to main/master
|
|
69
|
+
if echo "$COMMAND" | grep -qE "git push.*(--force|-f).*\s+(origin\s+)?(main|master)"; then
|
|
70
|
+
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
|
|
71
|
+
exit 0
|
|
72
|
+
fi
|
|
73
|
+
|
|
74
|
+
# Allow by default
|
|
75
|
+
echo '{"permission":"allow"}' 2>/dev/null
|
|
76
|
+
exit 0
|
|
77
|
+
|
|
@@ -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
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# CAWS Scope Guard Hook
|
|
3
|
+
# Prevents agents from accessing files outside CAWS-defined scope
|
|
4
|
+
# @author @darianrosebrook
|
|
5
|
+
|
|
6
|
+
set -e
|
|
7
|
+
|
|
8
|
+
# Read input from Cursor
|
|
9
|
+
INPUT=$(cat)
|
|
10
|
+
ACTION=$(echo "$INPUT" | jq -r '.action // ""')
|
|
11
|
+
FILE_PATH=$(echo "$INPUT" | jq -r '.file_path // ""')
|
|
12
|
+
|
|
13
|
+
# Check if CAWS is available and we have a working spec
|
|
14
|
+
if command -v caws &> /dev/null && [[ -f ".caws/working-spec.yaml" ]]; then
|
|
15
|
+
|
|
16
|
+
# For file access actions, check scope
|
|
17
|
+
if [[ "$ACTION" == "read_file" ]] || [[ "$ACTION" == "edit_file" ]] || [[ -n "$FILE_PATH" ]]; then
|
|
18
|
+
|
|
19
|
+
# Get scope information from CAWS spec
|
|
20
|
+
SCOPE_CHECK=$(caws validate .caws/working-spec.yaml --scope-check "$FILE_PATH" 2>/dev/null || echo "unknown")
|
|
21
|
+
|
|
22
|
+
if [[ "$SCOPE_CHECK" == "out_of_scope" ]]; then
|
|
23
|
+
echo '{
|
|
24
|
+
"userMessage": "🚫 File access blocked by CAWS scope guard",
|
|
25
|
+
"agentMessage": "Cannot access '"$FILE_PATH"' - outside CAWS defined scope",
|
|
26
|
+
"block": true,
|
|
27
|
+
"suggestions": [
|
|
28
|
+
"Check CAWS working spec scope definition",
|
|
29
|
+
"Update scope in .caws/working-spec.yaml if needed",
|
|
30
|
+
"Create waiver for scope violation: caws waivers create --reason=scope_violation"
|
|
31
|
+
]
|
|
32
|
+
}'
|
|
33
|
+
exit 1
|
|
34
|
+
elif [[ "$SCOPE_CHECK" == "scope_warning" ]]; then
|
|
35
|
+
echo '{
|
|
36
|
+
"userMessage": "⚠️ File access outside primary scope",
|
|
37
|
+
"agentMessage": "File '"$FILE_PATH"' is outside primary scope but allowed",
|
|
38
|
+
"suggestions": [
|
|
39
|
+
"Consider if this file should be in primary scope",
|
|
40
|
+
"Update .caws/working-spec.yaml scope if needed"
|
|
41
|
+
]
|
|
42
|
+
}'
|
|
43
|
+
fi
|
|
44
|
+
fi
|
|
45
|
+
|
|
46
|
+
# For prompt submissions, check working spec compliance
|
|
47
|
+
if [[ "$ACTION" == "submit_prompt" ]]; then
|
|
48
|
+
PROMPT_CONTENT=$(echo "$INPUT" | jq -r '.prompt // ""')
|
|
49
|
+
|
|
50
|
+
# Check if prompt mentions files outside scope
|
|
51
|
+
if [[ -n "$PROMPT_CONTENT" ]]; then
|
|
52
|
+
MENTIONED_FILES=$(echo "$PROMPT_CONTENT" | grep -oE '\b[a-zA-Z0-9_/.-]+\.(js|ts|jsx|tsx|py|go|rs|java|yaml|json|md)\b' | sort | uniq || true)
|
|
53
|
+
|
|
54
|
+
OUT_OF_SCOPE=""
|
|
55
|
+
for file in $MENTIONED_FILES; do
|
|
56
|
+
if [[ -f "$file" ]] && ! caws validate .caws/working-spec.yaml --scope-check "$file" 2>/dev/null | grep -q "in_scope"; then
|
|
57
|
+
OUT_OF_SCOPE="$OUT_OF_SCOPE $file"
|
|
58
|
+
fi
|
|
59
|
+
done
|
|
60
|
+
|
|
61
|
+
if [[ -n "$OUT_OF_SCOPE" ]]; then
|
|
62
|
+
echo '{
|
|
63
|
+
"userMessage": "⚠️ Prompt references files outside CAWS scope",
|
|
64
|
+
"agentMessage": "Prompt mentions out-of-scope files: '"$OUT_OF_SCOPE"'",
|
|
65
|
+
"suggestions": [
|
|
66
|
+
"Focus on files within CAWS defined scope",
|
|
67
|
+
"Update working spec scope if additional files needed",
|
|
68
|
+
"Remove out-of-scope file references from prompt"
|
|
69
|
+
]
|
|
70
|
+
}'
|
|
71
|
+
fi
|
|
72
|
+
fi
|
|
73
|
+
fi
|
|
74
|
+
fi
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# CAWS Tool Validation Hook
|
|
3
|
+
# Validates MCP tool calls against CAWS security policies
|
|
4
|
+
# @author @darianrosebrook
|
|
5
|
+
|
|
6
|
+
set -e
|
|
7
|
+
|
|
8
|
+
# Read input from Cursor
|
|
9
|
+
INPUT=$(cat)
|
|
10
|
+
TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name // ""')
|
|
11
|
+
TOOL_ARGS=$(echo "$INPUT" | jq -r '.arguments // "{}"')
|
|
12
|
+
|
|
13
|
+
# Only validate CAWS-related tools
|
|
14
|
+
if [[ "$TOOL_NAME" =~ ^caws_ ]]; then
|
|
15
|
+
|
|
16
|
+
echo "🔍 Validating CAWS tool call: $TOOL_NAME" >&2
|
|
17
|
+
|
|
18
|
+
# Check if CAWS CLI is available
|
|
19
|
+
if ! command -v caws &> /dev/null; then
|
|
20
|
+
echo '{
|
|
21
|
+
"userMessage": "❌ CAWS CLI not available",
|
|
22
|
+
"agentMessage": "Cannot execute CAWS tools - CLI not installed",
|
|
23
|
+
"block": true,
|
|
24
|
+
"suggestions": [
|
|
25
|
+
"Install CAWS CLI: npm install -g @caws/cli",
|
|
26
|
+
"Check PATH includes CAWS CLI"
|
|
27
|
+
]
|
|
28
|
+
}'
|
|
29
|
+
exit 1
|
|
30
|
+
fi
|
|
31
|
+
|
|
32
|
+
# Check if we're in a CAWS project
|
|
33
|
+
if [[ ! -f ".caws/working-spec.yaml" ]]; then
|
|
34
|
+
echo '{
|
|
35
|
+
"userMessage": "⚠️ Not in a CAWS project",
|
|
36
|
+
"agentMessage": "CAWS tools require .caws/working-spec.yaml",
|
|
37
|
+
"suggestions": [
|
|
38
|
+
"Initialize CAWS project: caws init",
|
|
39
|
+
"Create working spec: caws scaffold"
|
|
40
|
+
]
|
|
41
|
+
}'
|
|
42
|
+
fi
|
|
43
|
+
|
|
44
|
+
# Validate tool-specific arguments
|
|
45
|
+
case "$TOOL_NAME" in
|
|
46
|
+
"caws_waiver_create")
|
|
47
|
+
# Check waiver creation permissions
|
|
48
|
+
IMPACT_LEVEL=$(echo "$TOOL_ARGS" | jq -r '.impactLevel // "low"')
|
|
49
|
+
|
|
50
|
+
if [[ "$IMPACT_LEVEL" == "critical" ]]; then
|
|
51
|
+
echo '{
|
|
52
|
+
"userMessage": "🚨 Critical waiver requires approval",
|
|
53
|
+
"agentMessage": "Critical impact waivers need human approval",
|
|
54
|
+
"block": false,
|
|
55
|
+
"warnings": [
|
|
56
|
+
"Critical waivers require code owner review",
|
|
57
|
+
"Waiver will be flagged for manual approval"
|
|
58
|
+
]
|
|
59
|
+
}'
|
|
60
|
+
fi
|
|
61
|
+
|
|
62
|
+
# Check expiration time
|
|
63
|
+
EXPIRES_AT=$(echo "$TOOL_ARGS" | jq -r '.expiresAt // ""')
|
|
64
|
+
if [[ -n "$EXPIRES_AT" ]]; then
|
|
65
|
+
EXPIRE_TIME=$(date -j -f "%Y-%m-%dT%H:%M:%S%Z" "$EXPIRES_AT" +%s 2>/dev/null || echo "")
|
|
66
|
+
CURRENT_TIME=$(date +%s)
|
|
67
|
+
DAYS_DIFF=$(( (EXPIRE_TIME - CURRENT_TIME) / 86400 ))
|
|
68
|
+
|
|
69
|
+
if [[ $DAYS_DIFF -gt 90 ]]; then
|
|
70
|
+
echo '{
|
|
71
|
+
"userMessage": "⚠️ Waiver expiration too far in future",
|
|
72
|
+
"agentMessage": "Waivers cannot exceed 90 days expiration",
|
|
73
|
+
"suggestions": [
|
|
74
|
+
"Reduce expiration time to within 90 days",
|
|
75
|
+
"Consider shorter waiver periods for better security"
|
|
76
|
+
]
|
|
77
|
+
}'
|
|
78
|
+
fi
|
|
79
|
+
fi
|
|
80
|
+
;;
|
|
81
|
+
|
|
82
|
+
"caws_evaluate"|"caws_iterate")
|
|
83
|
+
# These are generally safe to run
|
|
84
|
+
echo '{"userMessage": "✅ CAWS quality tool validated", "agentMessage": "Tool execution approved"}'
|
|
85
|
+
;;
|
|
86
|
+
|
|
87
|
+
*)
|
|
88
|
+
# Unknown CAWS tool - allow but warn
|
|
89
|
+
echo '{
|
|
90
|
+
"userMessage": "⚠️ Unknown CAWS tool",
|
|
91
|
+
"agentMessage": "Tool '"'"$TOOL_NAME"'"' not recognized - proceeding with caution",
|
|
92
|
+
"suggestions": [
|
|
93
|
+
"Verify tool name and arguments",
|
|
94
|
+
"Check CAWS CLI documentation"
|
|
95
|
+
]
|
|
96
|
+
}'
|
|
97
|
+
;;
|
|
98
|
+
esac
|
|
99
|
+
|
|
100
|
+
elif [[ "$TOOL_NAME" =~ (exec|shell|run|terminal) ]]; then
|
|
101
|
+
# Generic shell execution - check for dangerous commands
|
|
102
|
+
COMMAND=$(echo "$TOOL_ARGS" | jq -r '.command // .cmd // ""')
|
|
103
|
+
|
|
104
|
+
DANGEROUS_COMMANDS=("rm -rf" "rm -rf /" "format" "mkfs" "dd" "fdisk" ">" "sudo" "chmod 777")
|
|
105
|
+
|
|
106
|
+
for dangerous in "${DANGEROUS_COMMANDS[@]}"; do
|
|
107
|
+
if [[ "$COMMAND" =~ $dangerous ]]; then
|
|
108
|
+
echo '{
|
|
109
|
+
"userMessage": "🚫 Dangerous command blocked",
|
|
110
|
+
"agentMessage": "Command contains dangerous operations: '"'"$dangerous"'"'",
|
|
111
|
+
"block": true,
|
|
112
|
+
"suggestions": [
|
|
113
|
+
"Avoid destructive operations",
|
|
114
|
+
"Use safer alternatives",
|
|
115
|
+
"Get explicit approval for dangerous commands"
|
|
116
|
+
]
|
|
117
|
+
}'
|
|
118
|
+
exit 1
|
|
119
|
+
fi
|
|
120
|
+
done
|
|
121
|
+
fi
|