@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.
Files changed (117) hide show
  1. package/dist/budget-derivation.js +5 -4
  2. package/dist/commands/diagnose.js +24 -19
  3. package/dist/commands/init.js +51 -4
  4. package/dist/commands/specs.js +40 -1
  5. package/dist/commands/status.js +2 -2
  6. package/dist/commands/tool.js +2 -3
  7. package/dist/config/index.js +17 -8
  8. package/dist/generators/working-spec.js +19 -6
  9. package/dist/scaffold/git-hooks.js +127 -29
  10. package/dist/scaffold/index.js +53 -7
  11. package/dist/templates/.caws/tools/README.md +20 -0
  12. package/dist/templates/.cursor/README.md +311 -0
  13. package/dist/templates/.cursor/hooks/audit.sh +55 -0
  14. package/dist/templates/.cursor/hooks/block-dangerous.sh +83 -0
  15. package/dist/templates/.cursor/hooks/caws-quality-check.sh +52 -0
  16. package/dist/templates/.cursor/hooks/caws-scope-guard.sh +130 -0
  17. package/dist/templates/.cursor/hooks/caws-tool-validation.sh +121 -0
  18. package/dist/templates/.cursor/hooks/format.sh +38 -0
  19. package/dist/templates/.cursor/hooks/naming-check.sh +64 -0
  20. package/dist/templates/.cursor/hooks/scan-secrets.sh +46 -0
  21. package/dist/templates/.cursor/hooks/scope-guard.sh +52 -0
  22. package/dist/templates/.cursor/hooks/validate-spec.sh +83 -0
  23. package/dist/templates/.cursor/hooks.json +59 -0
  24. package/dist/templates/.cursor/rules/00-claims-verification.mdc +144 -0
  25. package/dist/templates/.cursor/rules/01-working-style.mdc +50 -0
  26. package/dist/templates/.cursor/rules/02-quality-gates.mdc +370 -0
  27. package/dist/templates/.cursor/rules/03-naming-and-refactor.mdc +33 -0
  28. package/dist/templates/.cursor/rules/04-logging-language-style.mdc +23 -0
  29. package/dist/templates/.cursor/rules/05-safe-defaults-guards.mdc +23 -0
  30. package/dist/templates/.cursor/rules/06-typescript-conventions.mdc +36 -0
  31. package/dist/templates/.cursor/rules/07-process-ops.mdc +20 -0
  32. package/dist/templates/.cursor/rules/08-solid-and-architecture.mdc +16 -0
  33. package/dist/templates/.cursor/rules/09-docstrings.mdc +89 -0
  34. package/dist/templates/.cursor/rules/10-documentation-quality-standards.mdc +390 -0
  35. package/dist/templates/.cursor/rules/11-scope-management-waivers.mdc +385 -0
  36. package/dist/templates/.cursor/rules/12-implementation-completeness.mdc +516 -0
  37. package/dist/templates/.cursor/rules/13-language-agnostic-standards.mdc +588 -0
  38. package/dist/templates/.cursor/rules/README.md +148 -0
  39. package/dist/templates/.github/copilot/instructions.md +311 -0
  40. package/dist/templates/.idea/runConfigurations/CAWS_Evaluate.xml +5 -0
  41. package/dist/templates/.idea/runConfigurations/CAWS_Validate.xml +5 -0
  42. package/dist/templates/.vscode/launch.json +56 -0
  43. package/dist/templates/.vscode/settings.json +93 -0
  44. package/dist/templates/.windsurf/workflows/caws-guided-development.md +92 -0
  45. package/dist/templates/COMMIT_CONVENTIONS.md +86 -0
  46. package/dist/templates/OIDC_SETUP.md +300 -0
  47. package/dist/templates/agents.md +1047 -0
  48. package/dist/templates/codemod/README.md +1 -0
  49. package/dist/templates/codemod/test.js +93 -0
  50. package/dist/templates/docs/README.md +150 -0
  51. package/dist/templates/scripts/quality-gates/check-god-objects.js +146 -0
  52. package/dist/templates/scripts/quality-gates/run-quality-gates.js +50 -0
  53. package/dist/templates/scripts/v3/analysis/todo_analyzer.py +1997 -0
  54. package/dist/tool-loader.js +6 -1
  55. package/dist/tool-validator.js +8 -2
  56. package/dist/utils/detection.js +4 -3
  57. package/dist/utils/git-lock.js +118 -0
  58. package/dist/utils/gitignore-updater.js +148 -0
  59. package/dist/utils/quality-gates.js +47 -7
  60. package/dist/utils/spec-resolver.js +23 -3
  61. package/dist/utils/yaml-validation.js +155 -0
  62. package/dist/validation/spec-validation.js +81 -2
  63. package/package.json +2 -2
  64. package/templates/.caws/schemas/waivers.schema.json +30 -0
  65. package/templates/.caws/schemas/working-spec.schema.json +133 -0
  66. package/templates/.caws/templates/working-spec.template.yml +74 -0
  67. package/templates/.caws/tools/README.md +20 -0
  68. package/templates/.caws/tools/scope-guard.js +208 -0
  69. package/templates/.caws/tools-allow.json +331 -0
  70. package/templates/.caws/waivers.yml +19 -0
  71. package/templates/.cursor/hooks/scope-guard.sh +2 -2
  72. package/templates/.cursor/hooks/validate-spec.sh +42 -7
  73. package/templates/apps/tools/caws/COMPLETION_REPORT.md +0 -331
  74. package/templates/apps/tools/caws/MIGRATION_SUMMARY.md +0 -360
  75. package/templates/apps/tools/caws/README.md +0 -463
  76. package/templates/apps/tools/caws/TEST_STATUS.md +0 -365
  77. package/templates/apps/tools/caws/attest.js +0 -357
  78. package/templates/apps/tools/caws/ci-optimizer.js +0 -642
  79. package/templates/apps/tools/caws/config.ts +0 -245
  80. package/templates/apps/tools/caws/cross-functional.js +0 -876
  81. package/templates/apps/tools/caws/dashboard.js +0 -1112
  82. package/templates/apps/tools/caws/flake-detector.ts +0 -362
  83. package/templates/apps/tools/caws/gates.js +0 -198
  84. package/templates/apps/tools/caws/gates.ts +0 -271
  85. package/templates/apps/tools/caws/language-adapters.ts +0 -381
  86. package/templates/apps/tools/caws/language-support.d.ts +0 -367
  87. package/templates/apps/tools/caws/language-support.d.ts.map +0 -1
  88. package/templates/apps/tools/caws/language-support.js +0 -585
  89. package/templates/apps/tools/caws/legacy-assessment.ts +0 -408
  90. package/templates/apps/tools/caws/legacy-assessor.js +0 -764
  91. package/templates/apps/tools/caws/mutant-analyzer.js +0 -734
  92. package/templates/apps/tools/caws/perf-budgets.ts +0 -349
  93. package/templates/apps/tools/caws/prompt-lint.js.backup +0 -274
  94. package/templates/apps/tools/caws/property-testing.js +0 -707
  95. package/templates/apps/tools/caws/provenance.d.ts +0 -14
  96. package/templates/apps/tools/caws/provenance.d.ts.map +0 -1
  97. package/templates/apps/tools/caws/provenance.js +0 -132
  98. package/templates/apps/tools/caws/provenance.js.backup +0 -73
  99. package/templates/apps/tools/caws/provenance.ts +0 -211
  100. package/templates/apps/tools/caws/security-provenance.ts +0 -483
  101. package/templates/apps/tools/caws/shared/base-tool.ts +0 -281
  102. package/templates/apps/tools/caws/shared/config-manager.ts +0 -366
  103. package/templates/apps/tools/caws/shared/gate-checker.ts +0 -849
  104. package/templates/apps/tools/caws/shared/types.ts +0 -444
  105. package/templates/apps/tools/caws/shared/validator.ts +0 -305
  106. package/templates/apps/tools/caws/shared/waivers-manager.ts +0 -174
  107. package/templates/apps/tools/caws/spec-test-mapper.ts +0 -391
  108. package/templates/apps/tools/caws/test-quality.js +0 -578
  109. package/templates/apps/tools/caws/validate.js +0 -76
  110. package/templates/apps/tools/caws/validate.ts +0 -228
  111. package/templates/apps/tools/caws/waivers.js +0 -344
  112. /package/{templates/apps/tools/caws → dist/templates/.caws}/schemas/waivers.schema.json +0 -0
  113. /package/{templates/apps/tools/caws → dist/templates/.caws}/schemas/working-spec.schema.json +0 -0
  114. /package/{templates/apps/tools/caws → dist/templates/.caws}/templates/working-spec.template.yml +0 -0
  115. /package/{templates/apps/tools/caws → dist/templates/.caws/tools}/scope-guard.js +0 -0
  116. /package/{templates/apps/tools/caws → dist/templates/.caws}/tools-allow.json +0 -0
  117. /package/{templates/apps/tools/caws → dist/templates/.caws}/waivers.yml +0 -0
@@ -0,0 +1,130 @@
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
+ # AGENT GUARDRAILS - Prevent policy bypass attempts
17
+ if [[ "$ACTION" == "edit_file" ]] || [[ "$ACTION" == "create_file" ]]; then
18
+ if [[ "$FILE_PATH" == ".caws/policy.yaml" ]]; then
19
+ echo '{
20
+ "userMessage": "🚫 Policy file editing blocked by agent guardrails",
21
+ "agentMessage": "Agents cannot edit .caws/policy.yaml - requires human dual control",
22
+ "block": true,
23
+ "suggestions": [
24
+ "Policy changes must be approved by humans with Gatekeeper role",
25
+ "Create a separate PR for policy changes",
26
+ "For budget exceptions: caws waivers create --title=\"Budget exception\" --reason=architectural_refactor --gates=budget_limit",
27
+ "Contact @gatekeepers for policy modifications"
28
+ ]
29
+ }'
30
+ exit 1
31
+ fi
32
+
33
+ if [[ "$FILE_PATH" == "CODEOWNERS" ]]; then
34
+ echo '{
35
+ "userMessage": "🚫 CODEOWNERS editing blocked by agent guardrails",
36
+ "agentMessage": "Agents cannot modify CODEOWNERS - governance changes require approval",
37
+ "block": true,
38
+ "suggestions": [
39
+ "CODEOWNERS changes require governance review",
40
+ "Contact repository maintainers for ownership changes",
41
+ "For approval workflows: caws waivers create --reason=governance_change"
42
+ ]
43
+ }'
44
+ exit 1
45
+ fi
46
+
47
+ if [[ "$FILE_PATH" == ".caws/working-spec.yaml" ]]; then
48
+ # Check if trying to add change_budget
49
+ FILE_CONTENT=$(echo "$INPUT" | jq -r '.content // ""')
50
+ if echo "$FILE_CONTENT" | grep -q "change_budget"; then
51
+ echo '{
52
+ "userMessage": "🚫 Budget editing blocked by agent guardrails",
53
+ "agentMessage": "Agents cannot introduce change_budget fields - budgets are derived automatically",
54
+ "block": true,
55
+ "suggestions": [
56
+ "Check current budget status: caws burnup",
57
+ "For budget exceptions: caws waivers create --title=\"Scope expansion\" --reason=architectural_refactor --gates=budget_limit --expires-at=\"2025-12-31T23:59:59Z\"",
58
+ "Add waiver_ids to working spec instead: [\"WV-XXXX\"]",
59
+ "Validate waiver: caws validate .caws/working-spec.yaml"
60
+ ]
61
+ }'
62
+ exit 1
63
+ fi
64
+ fi
65
+ fi
66
+
67
+ # For file access actions, check scope
68
+ if [[ "$ACTION" == "read_file" ]] || [[ "$ACTION" == "edit_file" ]] || [[ -n "$FILE_PATH" ]]; then
69
+
70
+ # Get scope information from CAWS spec
71
+ SCOPE_CHECK=$(caws validate .caws/working-spec.yaml --scope-check "$FILE_PATH" 2>/dev/null || echo "unknown")
72
+
73
+ if [[ "$SCOPE_CHECK" == "out_of_scope" ]]; then
74
+ echo '{
75
+ "userMessage": "🚫 File access blocked by CAWS scope guard",
76
+ "agentMessage": "Cannot access '"$FILE_PATH"' - outside CAWS defined scope",
77
+ "block": true,
78
+ "suggestions": [
79
+ "Check current scope: caws validate .caws/working-spec.yaml",
80
+ "Update scope in working spec: edit .caws/working-spec.yaml scope.in array",
81
+ "For scope exceptions: caws waivers create --title=\"Scope expansion\" --reason=architectural_refactor --gates=scope_boundary --description=\"Need access to '"$FILE_PATH"' for implementation\"",
82
+ "Validate changes: caws validate .caws/working-spec.yaml"
83
+ ]
84
+ }'
85
+ exit 1
86
+ elif [[ "$SCOPE_CHECK" == "scope_warning" ]]; then
87
+ echo '{
88
+ "userMessage": "⚠️ File access outside primary scope",
89
+ "agentMessage": "File '"$FILE_PATH"' is outside primary scope but allowed",
90
+ "suggestions": [
91
+ "Check if needed in primary scope: edit .caws/working-spec.yaml scope.in",
92
+ "Consider scope implications: caws agent evaluate",
93
+ "Document scope decision in working spec invariants",
94
+ "Validate scope changes: caws validate .caws/working-spec.yaml"
95
+ ]
96
+ }'
97
+ fi
98
+ fi
99
+
100
+ # For prompt submissions, check working spec compliance
101
+ if [[ "$ACTION" == "submit_prompt" ]]; then
102
+ PROMPT_CONTENT=$(echo "$INPUT" | jq -r '.prompt // ""')
103
+
104
+ # Check if prompt mentions files outside scope
105
+ if [[ -n "$PROMPT_CONTENT" ]]; then
106
+ 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)
107
+
108
+ OUT_OF_SCOPE=""
109
+ for file in $MENTIONED_FILES; do
110
+ if [[ -f "$file" ]] && ! caws validate .caws/working-spec.yaml --scope-check "$file" 2>/dev/null | grep -q "in_scope"; then
111
+ OUT_OF_SCOPE="$OUT_OF_SCOPE $file"
112
+ fi
113
+ done
114
+
115
+ if [[ -n "$OUT_OF_SCOPE" ]]; then
116
+ echo '{
117
+ "userMessage": "⚠️ Prompt references files outside CAWS scope",
118
+ "agentMessage": "Prompt mentions out-of-scope files: '"$OUT_OF_SCOPE"'",
119
+ "suggestions": [
120
+ "Check current scope definition: caws validate .caws/working-spec.yaml",
121
+ "Update working spec scope: edit .caws/working-spec.yaml scope.in array",
122
+ "For scope exceptions: caws waivers create --title=\"Scope expansion\" --reason=architectural_refactor --gates=scope_boundary",
123
+ "Refocus prompt on in-scope files or request scope update approval",
124
+ "Validate scope changes: caws validate .caws/working-spec.yaml"
125
+ ]
126
+ }'
127
+ fi
128
+ fi
129
+ fi
130
+ 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
@@ -0,0 +1,38 @@
1
+ #!/bin/bash
2
+ # Cursor Hook: Auto-formatting
3
+ #
4
+ # Purpose: Run formatters after file edits
5
+ # Event: afterFileEdit
6
+ #
7
+ # @author @darianrosebrook
8
+
9
+ set -euo pipefail
10
+
11
+ # Read input from Cursor
12
+ INPUT=$(cat)
13
+
14
+ # Extract file path
15
+ FILE_PATH=$(echo "$INPUT" | jq -r '.file_path // ""')
16
+
17
+ # Only format source code files
18
+ if [[ "$FILE_PATH" =~ \.(js|ts|jsx|tsx|json|md|yml|yaml)$ ]]; then
19
+ # Try prettier if available
20
+ if command -v prettier &> /dev/null; then
21
+ prettier --write "$FILE_PATH" 2>/dev/null || true
22
+ elif [ -f "node_modules/.bin/prettier" ]; then
23
+ node_modules/.bin/prettier --write "$FILE_PATH" 2>/dev/null || true
24
+ fi
25
+
26
+ # Try eslint for JS/TS files
27
+ if [[ "$FILE_PATH" =~ \.(js|ts|jsx|tsx)$ ]]; then
28
+ if command -v eslint &> /dev/null; then
29
+ eslint --fix "$FILE_PATH" 2>/dev/null || true
30
+ elif [ -f "node_modules/.bin/eslint" ]; then
31
+ node_modules/.bin/eslint --fix "$FILE_PATH" 2>/dev/null || true
32
+ fi
33
+ fi
34
+ fi
35
+
36
+ # Always allow - formatting is non-blocking
37
+ exit 0
38
+
@@ -0,0 +1,64 @@
1
+ #!/bin/bash
2
+ # Cursor Hook: Naming Conventions
3
+ #
4
+ # Purpose: Enforce CAWS naming conventions (no enhanced-, -copy, etc.)
5
+ # Event: afterFileEdit
6
+ #
7
+ # @author @darianrosebrook
8
+
9
+ set -euo pipefail
10
+
11
+ # Read input from Cursor
12
+ INPUT=$(cat)
13
+
14
+ # Extract file path
15
+ FILE_PATH=$(echo "$INPUT" | jq -r '.file_path // ""')
16
+
17
+ # Get just the filename
18
+ FILENAME=$(basename "$FILE_PATH")
19
+
20
+ # Check for banned naming patterns
21
+ BANNED_PATTERNS=(
22
+ "enhanced-"
23
+ "-enhanced"
24
+ "unified-"
25
+ "-unified"
26
+ "better-"
27
+ "-better"
28
+ "new-"
29
+ "-new"
30
+ "next-"
31
+ "-next"
32
+ "final-"
33
+ "-final"
34
+ "-copy"
35
+ "copy-"
36
+ "-revamp"
37
+ "revamp-"
38
+ "-improved"
39
+ "improved-"
40
+ )
41
+
42
+ for pattern in "${BANNED_PATTERNS[@]}"; do
43
+ if [[ "$FILENAME" == *"$pattern"* ]]; then
44
+ # Extract the pattern for the message
45
+ echo '{"userMessage":"⚠️ Naming violation: File contains banned pattern '"'$pattern'"'. Use purpose-driven names instead.","agentMessage":"This file uses a generic naming pattern ('"$pattern"'). Please rename with a specific, purpose-driven name that describes what the file does."}' 2>/dev/null
46
+ exit 0
47
+ fi
48
+ done
49
+
50
+ # Check for duplicate module patterns (e.g., both processor.ts and enhanced-processor.ts)
51
+ if [[ "$FILENAME" =~ ^(enhanced|unified|better|new|next|final|improved)- ]]; then
52
+ BASE_NAME=$(echo "$FILENAME" | sed -E 's/^(enhanced|unified|better|new|next|final|improved)-//')
53
+ DIR_PATH=$(dirname "$FILE_PATH")
54
+
55
+ # Check if base file exists
56
+ if [ -f "$DIR_PATH/$BASE_NAME" ]; then
57
+ echo '{"userMessage":"⚠️ Duplicate module detected: Both '"$FILENAME"' and '"$BASE_NAME"' exist. Merge into canonical name.","agentMessage":"Found duplicate modules. Please merge '"$FILENAME"' into '"$BASE_NAME"' and remove the duplicate."}' 2>/dev/null
58
+ exit 0
59
+ fi
60
+ fi
61
+
62
+ # Allow by default
63
+ exit 0
64
+
@@ -0,0 +1,46 @@
1
+ #!/bin/bash
2
+ # Cursor Hook: Secret & PII Scanner
3
+ #
4
+ # Purpose: Prevent reading files with secrets or sensitive information
5
+ # Event: beforeReadFile
6
+ #
7
+ # @author @darianrosebrook
8
+
9
+ set -euo pipefail
10
+
11
+ # Read input from Cursor
12
+ INPUT=$(cat)
13
+
14
+ # Extract file path and content
15
+ FILE_PATH=$(echo "$INPUT" | jq -r '.file_path // ""')
16
+ CONTENT=$(echo "$INPUT" | jq -r '.content // ""')
17
+
18
+ # Block reading of environment files
19
+ if [[ "$FILE_PATH" =~ \.(env|env\.local|env\.development|env\.production|env\.test)$ ]]; then
20
+ echo '{"permission":"deny","userMessage":"⚠️ Blocked: Environment files contain secrets. Use placeholder values instead."}' 2>/dev/null
21
+ exit 0
22
+ fi
23
+
24
+ # Block reading of key files
25
+ if [[ "$FILE_PATH" =~ \.(pem|key|p12|pfx|cert|crt)$ ]]; then
26
+ echo '{"permission":"deny","userMessage":"⚠️ Blocked: Certificate/key files should not be read by AI."}' 2>/dev/null
27
+ exit 0
28
+ fi
29
+
30
+ # Scan content for common secret patterns
31
+ if echo "$CONTENT" | grep -qiE "(api[_-]?key|secret[_-]?key|password|private[_-]?key|access[_-]?token|bearer\s+[A-Za-z0-9_\-\.]+|AKIA[0-9A-Z]{16})"; then
32
+ # Don't block, but warn
33
+ echo '{"permission":"allow","userMessage":"⚠️ Warning: Potential secrets detected in file. Ensure they are not committed.","agentMessage":"This file may contain secrets. Use placeholder values or environment variables."}' 2>/dev/null
34
+ exit 0
35
+ fi
36
+
37
+ # Check for common PII patterns (SSN, credit card, etc.)
38
+ if echo "$CONTENT" | grep -qE "([0-9]{3}-[0-9]{2}-[0-9]{4}|[0-9]{4}[- ]?[0-9]{4}[- ]?[0-9]{4}[- ]?[0-9]{4})"; then
39
+ echo '{"permission":"allow","userMessage":"⚠️ Warning: Potential PII detected. Ensure compliance with data protection policies.","agentMessage":"This file may contain PII (SSN, credit card). Use anonymized test data."}' 2>/dev/null
40
+ exit 0
41
+ fi
42
+
43
+ # Allow by default
44
+ echo '{"permission":"allow"}' 2>/dev/null
45
+ exit 0
46
+
@@ -0,0 +1,52 @@
1
+ #!/bin/bash
2
+ # Cursor Hook: Scope Guard
3
+ #
4
+ # Purpose: Check if files being worked on are within working-spec scope
5
+ # Event: beforeSubmitPrompt
6
+ #
7
+ # @author @darianrosebrook
8
+
9
+ set -euo pipefail
10
+
11
+ # Read input from Cursor
12
+ INPUT=$(cat)
13
+
14
+ # Extract attachments
15
+ ATTACHMENTS=$(echo "$INPUT" | jq -r '.attachments // []')
16
+
17
+ # Only check if we have file attachments and a working spec
18
+ if [ ! -f ".caws/working-spec.yaml" ] && [ ! -f ".caws/working-spec.yml" ]; then
19
+ # No spec file, allow by default
20
+ echo '{"continue":true}' 2>/dev/null
21
+ exit 0
22
+ fi
23
+
24
+ # Check if scope-guard tool exists
25
+ if [ -f ".caws/tools/scope-guard.js" ]; then
26
+ # Extract file paths from attachments
27
+ FILE_PATHS=$(echo "$ATTACHMENTS" | jq -r '.[] | select(.type=="file") | .file_path' 2>/dev/null || echo "")
28
+
29
+ if [ -n "$FILE_PATHS" ]; then
30
+ # Check each file against scope
31
+ OUT_OF_SCOPE=()
32
+ while IFS= read -r file; do
33
+ if [ -n "$file" ]; then
34
+ if ! node .caws/tools/scope-guard.js check "$file" 2>/dev/null; then
35
+ OUT_OF_SCOPE+=("$file")
36
+ fi
37
+ fi
38
+ done <<< "$FILE_PATHS"
39
+
40
+ # If any files are out of scope, warn but don't block
41
+ if [ ${#OUT_OF_SCOPE[@]} -gt 0 ]; then
42
+ FILES_LIST=$(printf '%s\n' "${OUT_OF_SCOPE[@]}")
43
+ echo '{"continue":true,"userMessage":"⚠️ Warning: Some attached files may be outside working-spec scope:\n'"$FILES_LIST"'","agentMessage":"Some files are outside the defined scope in working-spec.yaml. Consider updating the scope or removing these files."}' 2>/dev/null
44
+ exit 0
45
+ fi
46
+ fi
47
+ fi
48
+
49
+ # Allow by default
50
+ echo '{"continue":true}' 2>/dev/null
51
+ exit 0
52
+
@@ -0,0 +1,83 @@
1
+ #!/bin/bash
2
+ # Cursor Hook: CAWS Spec Validation
3
+ #
4
+ # Purpose: Validate working-spec.yaml when it's edited
5
+ # Event: afterFileEdit
6
+ #
7
+ # @author @darianrosebrook
8
+
9
+ set -euo pipefail
10
+
11
+ # Read input from Cursor
12
+ INPUT=$(cat)
13
+
14
+ # Extract file path from input
15
+ FILE_PATH=$(echo "$INPUT" | jq -r '.file_path // ""')
16
+
17
+ # Validate if any CAWS YAML file was edited (.caws/**/*.yaml or .caws/**/*.yml)
18
+ if [[ "$FILE_PATH" == *".caws/"* ]] && ([[ "$FILE_PATH" == *.yaml ]] || [[ "$FILE_PATH" == *.yml ]]); then
19
+ echo "🔍 Validating CAWS spec file..." >&2
20
+
21
+ # First, validate YAML syntax
22
+ if command -v node >/dev/null 2>&1; then
23
+ # Check YAML syntax using Node.js
24
+ YAML_SYNTAX_VALID=$(node -e "
25
+ const yaml = require('js-yaml');
26
+ const fs = require('fs');
27
+ try {
28
+ const content = fs.readFileSync('$FILE_PATH', 'utf8');
29
+ yaml.load(content);
30
+ process.exit(0);
31
+ } catch (error) {
32
+ console.error('YAML syntax error:', error.message);
33
+ if (error.mark) {
34
+ console.error('Line:', error.mark.line + 1, 'Column:', error.mark.column + 1);
35
+ }
36
+ process.exit(1);
37
+ }
38
+ " 2>&1)
39
+
40
+ if [ $? -ne 0 ]; then
41
+ echo '{
42
+ "userMessage": "⚠️ YAML syntax error detected",
43
+ "agentMessage": "The spec file has invalid YAML syntax. Fix syntax errors before continuing.",
44
+ "suggestions": [
45
+ "Check indentation (YAML uses 2 spaces)",
46
+ "Ensure all array items use consistent format",
47
+ "Remove duplicate keys",
48
+ "Consider using '\''caws specs create <id>'\'' instead of manual creation"
49
+ ]
50
+ }' 2>/dev/null
51
+ exit 0
52
+ fi
53
+ fi
54
+
55
+ # Check if CAWS CLI is available for semantic validation
56
+ if command -v caws &> /dev/null; then
57
+ # Run CAWS validation with suggestions
58
+ if VALIDATION=$(caws validate "$FILE_PATH" --quiet 2>&1); then
59
+ echo '{"userMessage":"✅ CAWS spec validation passed","agentMessage":"Specification is valid and complete."}' 2>/dev/null
60
+ else
61
+ # Get suggestions for fixing the spec
62
+ SUGGESTIONS=$(caws validate "$FILE_PATH" --suggestions 2>/dev/null | head -5 | tr '\n' '; ' | sed 's/; $//' || echo "Run caws validate --suggestions for details")
63
+
64
+ echo '{
65
+ "userMessage": "⚠️ CAWS spec validation failed. Run: caws validate --suggestions",
66
+ "agentMessage": "The spec file has validation errors. Please review and fix before continuing.",
67
+ "suggestions": [
68
+ "Run caws validate --suggestions for detailed error messages",
69
+ "Check required fields: id, title, risk_tier, mode",
70
+ "Ensure acceptance criteria are properly defined",
71
+ "Verify scope boundaries are appropriate",
72
+ "Consider using '\''caws specs create <id>'\'' for proper structure"
73
+ ]
74
+ }' 2>/dev/null
75
+ fi
76
+ else
77
+ echo '{"userMessage":"⚠️ CAWS CLI not available for validation","agentMessage":"Install CAWS CLI for automatic spec validation: npm install -g @caws/cli"}' 2>/dev/null
78
+ fi
79
+ fi
80
+
81
+ # Allow the edit
82
+ exit 0
83
+
@@ -0,0 +1,59 @@
1
+ {
2
+ "version": 1,
3
+ "hooks": {
4
+ "beforeShellExecution": [
5
+ {
6
+ "command": "./.cursor/hooks/block-dangerous.sh"
7
+ },
8
+ {
9
+ "command": "./.cursor/hooks/audit.sh"
10
+ }
11
+ ],
12
+ "beforeMCPExecution": [
13
+ {
14
+ "command": "./.cursor/hooks/audit.sh"
15
+ },
16
+ {
17
+ "command": "./.cursor/hooks/caws-tool-validation.sh"
18
+ }
19
+ ],
20
+ "beforeReadFile": [
21
+ {
22
+ "command": "./.cursor/hooks/scan-secrets.sh"
23
+ },
24
+ {
25
+ "command": "./.cursor/hooks/caws-scope-guard.sh"
26
+ }
27
+ ],
28
+ "afterFileEdit": [
29
+ {
30
+ "command": "./.cursor/hooks/format.sh"
31
+ },
32
+ {
33
+ "command": "./.cursor/hooks/naming-check.sh"
34
+ },
35
+ {
36
+ "command": "./.cursor/hooks/validate-spec.sh"
37
+ },
38
+ {
39
+ "command": "./.cursor/hooks/caws-quality-check.sh"
40
+ },
41
+ {
42
+ "command": "./.cursor/hooks/audit.sh"
43
+ }
44
+ ],
45
+ "beforeSubmitPrompt": [
46
+ {
47
+ "command": "./.cursor/hooks/caws-scope-guard.sh"
48
+ },
49
+ {
50
+ "command": "./.cursor/hooks/audit.sh"
51
+ }
52
+ ],
53
+ "stop": [
54
+ {
55
+ "command": "./.cursor/hooks/audit.sh"
56
+ }
57
+ ]
58
+ }
59
+ }