specweave 1.0.550 → 1.0.552

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 (166) hide show
  1. package/CLAUDE.md +1 -1
  2. package/bin/specweave.js +23 -1
  3. package/dist/src/cli/commands/hook.d.ts +15 -0
  4. package/dist/src/cli/commands/hook.d.ts.map +1 -0
  5. package/dist/src/cli/commands/hook.js +61 -0
  6. package/dist/src/cli/commands/hook.js.map +1 -0
  7. package/dist/src/cli/commands/init.d.ts.map +1 -1
  8. package/dist/src/cli/commands/init.js +5 -0
  9. package/dist/src/cli/commands/init.js.map +1 -1
  10. package/dist/src/cli/commands/refresh-plugins.d.ts.map +1 -1
  11. package/dist/src/cli/commands/refresh-plugins.js +11 -1
  12. package/dist/src/cli/commands/refresh-plugins.js.map +1 -1
  13. package/dist/src/cli/commands/sync-setup.d.ts.map +1 -1
  14. package/dist/src/cli/commands/sync-setup.js +7 -3
  15. package/dist/src/cli/commands/sync-setup.js.map +1 -1
  16. package/dist/src/cli/helpers/issue-tracker/project-mapping-wizard.d.ts +9 -0
  17. package/dist/src/cli/helpers/issue-tracker/project-mapping-wizard.d.ts.map +1 -1
  18. package/dist/src/cli/helpers/issue-tracker/project-mapping-wizard.js +9 -3
  19. package/dist/src/cli/helpers/issue-tracker/project-mapping-wizard.js.map +1 -1
  20. package/dist/src/config/types.d.ts +2 -2
  21. package/dist/src/core/config/types.d.ts +18 -2
  22. package/dist/src/core/config/types.d.ts.map +1 -1
  23. package/dist/src/core/config/types.js.map +1 -1
  24. package/dist/src/core/hooks/handlers/hook-router.d.ts +19 -0
  25. package/dist/src/core/hooks/handlers/hook-router.d.ts.map +1 -0
  26. package/dist/src/core/hooks/handlers/hook-router.js +75 -0
  27. package/dist/src/core/hooks/handlers/hook-router.js.map +1 -0
  28. package/dist/src/core/hooks/handlers/index.d.ts +10 -0
  29. package/dist/src/core/hooks/handlers/index.d.ts.map +1 -0
  30. package/dist/src/core/hooks/handlers/index.js +9 -0
  31. package/dist/src/core/hooks/handlers/index.js.map +1 -0
  32. package/dist/src/core/hooks/handlers/post-tool-use-analytics.d.ts +11 -0
  33. package/dist/src/core/hooks/handlers/post-tool-use-analytics.d.ts.map +1 -0
  34. package/dist/src/core/hooks/handlers/post-tool-use-analytics.js +73 -0
  35. package/dist/src/core/hooks/handlers/post-tool-use-analytics.js.map +1 -0
  36. package/dist/src/core/hooks/handlers/post-tool-use.d.ts +11 -0
  37. package/dist/src/core/hooks/handlers/post-tool-use.d.ts.map +1 -0
  38. package/dist/src/core/hooks/handlers/post-tool-use.js +76 -0
  39. package/dist/src/core/hooks/handlers/post-tool-use.js.map +1 -0
  40. package/dist/src/core/hooks/handlers/pre-compact.d.ts +11 -0
  41. package/dist/src/core/hooks/handlers/pre-compact.d.ts.map +1 -0
  42. package/dist/src/core/hooks/handlers/pre-compact.js +77 -0
  43. package/dist/src/core/hooks/handlers/pre-compact.js.map +1 -0
  44. package/dist/src/core/hooks/handlers/pre-tool-use.d.ts +11 -0
  45. package/dist/src/core/hooks/handlers/pre-tool-use.d.ts.map +1 -0
  46. package/dist/src/core/hooks/handlers/pre-tool-use.js +318 -0
  47. package/dist/src/core/hooks/handlers/pre-tool-use.js.map +1 -0
  48. package/dist/src/core/hooks/handlers/session-start.d.ts +9 -0
  49. package/dist/src/core/hooks/handlers/session-start.d.ts.map +1 -0
  50. package/dist/src/core/hooks/handlers/session-start.js +111 -0
  51. package/dist/src/core/hooks/handlers/session-start.js.map +1 -0
  52. package/dist/src/core/hooks/handlers/stop-auto.d.ts +16 -0
  53. package/dist/src/core/hooks/handlers/stop-auto.d.ts.map +1 -0
  54. package/dist/src/core/hooks/handlers/stop-auto.js +122 -0
  55. package/dist/src/core/hooks/handlers/stop-auto.js.map +1 -0
  56. package/dist/src/core/hooks/handlers/stop-reflect.d.ts +14 -0
  57. package/dist/src/core/hooks/handlers/stop-reflect.d.ts.map +1 -0
  58. package/dist/src/core/hooks/handlers/stop-reflect.js +43 -0
  59. package/dist/src/core/hooks/handlers/stop-reflect.js.map +1 -0
  60. package/dist/src/core/hooks/handlers/stop-sync.d.ts +15 -0
  61. package/dist/src/core/hooks/handlers/stop-sync.d.ts.map +1 -0
  62. package/dist/src/core/hooks/handlers/stop-sync.js +68 -0
  63. package/dist/src/core/hooks/handlers/stop-sync.js.map +1 -0
  64. package/dist/src/core/hooks/handlers/types.d.ts +63 -0
  65. package/dist/src/core/hooks/handlers/types.d.ts.map +1 -0
  66. package/dist/src/core/hooks/handlers/types.js +27 -0
  67. package/dist/src/core/hooks/handlers/types.js.map +1 -0
  68. package/dist/src/core/hooks/handlers/user-prompt-submit.d.ts +14 -0
  69. package/dist/src/core/hooks/handlers/user-prompt-submit.d.ts.map +1 -0
  70. package/dist/src/core/hooks/handlers/user-prompt-submit.js +173 -0
  71. package/dist/src/core/hooks/handlers/user-prompt-submit.js.map +1 -0
  72. package/dist/src/core/hooks/handlers/utils.d.ts +25 -0
  73. package/dist/src/core/hooks/handlers/utils.d.ts.map +1 -0
  74. package/dist/src/core/hooks/handlers/utils.js +64 -0
  75. package/dist/src/core/hooks/handlers/utils.js.map +1 -0
  76. package/dist/src/core/increment/completion-validator.d.ts.map +1 -1
  77. package/dist/src/core/increment/completion-validator.js +32 -0
  78. package/dist/src/core/increment/completion-validator.js.map +1 -1
  79. package/dist/src/init/research/types.d.ts +1 -1
  80. package/dist/src/sync/sync-target-resolver.js.map +1 -1
  81. package/dist/src/utils/lock-manager.d.ts.map +1 -1
  82. package/dist/src/utils/lock-manager.js +5 -0
  83. package/dist/src/utils/lock-manager.js.map +1 -1
  84. package/dist/src/utils/plugin-copier.d.ts +10 -0
  85. package/dist/src/utils/plugin-copier.d.ts.map +1 -1
  86. package/dist/src/utils/plugin-copier.js +63 -35
  87. package/dist/src/utils/plugin-copier.js.map +1 -1
  88. package/package.json +1 -1
  89. package/plugins/specweave/agents/sw-closer.md +3 -2
  90. package/plugins/specweave/hooks/hooks.json +10 -10
  91. package/plugins/specweave/skills/code-reviewer/SKILL.md +180 -16
  92. package/plugins/specweave/skills/code-reviewer/agents/reviewer-comments.md +83 -0
  93. package/plugins/specweave/skills/code-reviewer/agents/reviewer-silent-failures.md +19 -0
  94. package/plugins/specweave/skills/code-reviewer/agents/reviewer-spec-compliance.md +19 -0
  95. package/plugins/specweave/skills/code-reviewer/agents/reviewer-tests.md +101 -0
  96. package/plugins/specweave/skills/code-reviewer/agents/reviewer-types.md +20 -0
  97. package/plugins/specweave/skills/done/SKILL.md +56 -21
  98. package/plugins/specweave/skills/grill/SKILL.md +1 -1
  99. package/plugins/specweave/skills/team-lead/agents/reviewer-logic.md +19 -0
  100. package/plugins/specweave/skills/team-lead/agents/reviewer-performance.md +20 -0
  101. package/plugins/specweave/skills/team-lead/agents/reviewer-security.md +20 -0
  102. package/src/templates/CLAUDE.md.template +7 -4
  103. package/plugins/specweave/hooks/README.md +0 -493
  104. package/plugins/specweave/hooks/_archive/stop-auto-v4-legacy.sh +0 -1319
  105. package/plugins/specweave/hooks/lib/common-setup.sh +0 -144
  106. package/plugins/specweave/hooks/lib/hook-errors.sh +0 -414
  107. package/plugins/specweave/hooks/lib/migrate-increment-work.sh +0 -245
  108. package/plugins/specweave/hooks/lib/resolve-package.sh +0 -146
  109. package/plugins/specweave/hooks/lib/scheduler-startup.sh +0 -135
  110. package/plugins/specweave/hooks/lib/score-increment.sh +0 -87
  111. package/plugins/specweave/hooks/lib/sync-spec-content.sh +0 -193
  112. package/plugins/specweave/hooks/lib/update-active-increment.sh +0 -95
  113. package/plugins/specweave/hooks/lib/update-status-line.sh +0 -233
  114. package/plugins/specweave/hooks/lib/validate-spec-status.sh +0 -171
  115. package/plugins/specweave/hooks/llm-judge-validator.sh +0 -219
  116. package/plugins/specweave/hooks/log-decision.sh +0 -168
  117. package/plugins/specweave/hooks/pre-compact.sh +0 -64
  118. package/plugins/specweave/hooks/startup-health-check.sh +0 -64
  119. package/plugins/specweave/hooks/stop-auto-v5.sh +0 -276
  120. package/plugins/specweave/hooks/stop-reflect.sh +0 -336
  121. package/plugins/specweave/hooks/stop-sync.sh +0 -283
  122. package/plugins/specweave/hooks/tests/test-auto-context-integration.sh +0 -126
  123. package/plugins/specweave/hooks/tests/test-stop-auto-enriched.sh +0 -128
  124. package/plugins/specweave/hooks/universal/dispatcher.mjs +0 -336
  125. package/plugins/specweave/hooks/universal/fail-fast-wrapper.sh +0 -325
  126. package/plugins/specweave/hooks/universal/hook-wrapper.cmd +0 -26
  127. package/plugins/specweave/hooks/universal/hook-wrapper.sh +0 -69
  128. package/plugins/specweave/hooks/universal/run-hook.sh +0 -20
  129. package/plugins/specweave/hooks/universal/session-start.cmd +0 -16
  130. package/plugins/specweave/hooks/universal/session-start.ps1 +0 -16
  131. package/plugins/specweave/hooks/user-prompt-submit.sh +0 -2550
  132. package/plugins/specweave/hooks/v2/detectors/lifecycle-detector.sh +0 -87
  133. package/plugins/specweave/hooks/v2/detectors/us-completion-detector.sh +0 -186
  134. package/plugins/specweave/hooks/v2/dispatchers/post-tool-use-analytics.sh +0 -83
  135. package/plugins/specweave/hooks/v2/dispatchers/post-tool-use.sh +0 -447
  136. package/plugins/specweave/hooks/v2/dispatchers/pre-tool-use.sh +0 -104
  137. package/plugins/specweave/hooks/v2/dispatchers/session-start.sh +0 -270
  138. package/plugins/specweave/hooks/v2/guards/completion-guard.sh +0 -14
  139. package/plugins/specweave/hooks/v2/guards/increment-duplicate-guard.sh +0 -14
  140. package/plugins/specweave/hooks/v2/guards/increment-existence-guard.sh +0 -240
  141. package/plugins/specweave/hooks/v2/guards/interview-enforcement-guard.sh +0 -171
  142. package/plugins/specweave/hooks/v2/guards/metadata-json-guard.sh +0 -14
  143. package/plugins/specweave/hooks/v2/guards/skill-chain-enforcement-guard.sh +0 -222
  144. package/plugins/specweave/hooks/v2/guards/spec-template-enforcement-guard.sh +0 -21
  145. package/plugins/specweave/hooks/v2/guards/spec-validation-guard.sh +0 -14
  146. package/plugins/specweave/hooks/v2/guards/status-completion-guard.sh +0 -84
  147. package/plugins/specweave/hooks/v2/guards/task-ac-sync-guard.sh +0 -475
  148. package/plugins/specweave/hooks/v2/guards/tdd-enforcement-guard.sh +0 -268
  149. package/plugins/specweave/hooks/v2/handlers/ac-sync-dispatcher.sh +0 -332
  150. package/plugins/specweave/hooks/v2/handlers/ac-validation-handler.sh +0 -50
  151. package/plugins/specweave/hooks/v2/handlers/github-sync-handler.sh +0 -347
  152. package/plugins/specweave/hooks/v2/handlers/living-docs-handler.sh +0 -83
  153. package/plugins/specweave/hooks/v2/handlers/living-specs-handler.sh +0 -268
  154. package/plugins/specweave/hooks/v2/handlers/project-bridge-handler.sh +0 -104
  155. package/plugins/specweave/hooks/v2/handlers/status-line-handler.sh +0 -165
  156. package/plugins/specweave/hooks/v2/handlers/status-update.sh +0 -61
  157. package/plugins/specweave/hooks/v2/handlers/universal-auto-create-dispatcher.sh +0 -270
  158. package/plugins/specweave/hooks/v2/integrations/ado-post-living-docs-update.sh +0 -367
  159. package/plugins/specweave/hooks/v2/integrations/ado-post-task.sh +0 -179
  160. package/plugins/specweave/hooks/v2/integrations/github-auto-create-handler.sh +0 -553
  161. package/plugins/specweave/hooks/v2/integrations/github-post-task.sh +0 -345
  162. package/plugins/specweave/hooks/v2/integrations/jira-post-task.sh +0 -180
  163. package/plugins/specweave/hooks/v2/lib/check-provider-enabled.sh +0 -52
  164. package/plugins/specweave/hooks/v2/queue/enqueue.sh +0 -81
  165. package/plugins/specweave/hooks/v2/session-end.sh +0 -139
  166. package/plugins/specweave/hooks/validate-skill-activations.sh +0 -227
@@ -1,219 +0,0 @@
1
- #!/bin/bash
2
- # llm-judge-validator.sh - LLM Judge Quality Assessment
3
- #
4
- # Uses Claude to assess work quality before allowing auto session completion
5
- # Returns exit code 0 if quality approved, 1 if rejected
6
- #
7
- # Usage: llm-judge-validator.sh <INCREMENT_ID> <TRANSCRIPT_PATH>
8
-
9
- set -e
10
-
11
- INCREMENT_ID="$1"
12
- TRANSCRIPT_PATH="$2"
13
-
14
- if [ -z "$INCREMENT_ID" ] || [ -z "$TRANSCRIPT_PATH" ]; then
15
- echo "Usage: llm-judge-validator.sh <INCREMENT_ID> <TRANSCRIPT_PATH>" >&2
16
- exit 1
17
- fi
18
-
19
- PROJECT_ROOT="${PROJECT_ROOT:-$(pwd)}"
20
- INCREMENT_DIR="$PROJECT_ROOT/.specweave/increments/$INCREMENT_ID"
21
-
22
- if [ ! -d "$INCREMENT_DIR" ]; then
23
- echo "❌ Increment directory not found: $INCREMENT_DIR" >&2
24
- exit 1
25
- fi
26
-
27
- # ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
28
- # GATHER CONTEXT FOR JUDGE
29
- # ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
30
-
31
- SPEC_FILE="$INCREMENT_DIR/spec.md"
32
- TASKS_FILE="$INCREMENT_DIR/tasks.md"
33
-
34
- if [ ! -f "$SPEC_FILE" ]; then
35
- echo "❌ spec.md not found" >&2
36
- exit 1
37
- fi
38
-
39
- if [ ! -f "$TASKS_FILE" ]; then
40
- echo "❌ tasks.md not found" >&2
41
- exit 1
42
- fi
43
-
44
- # Extract acceptance criteria from spec.md
45
- ACS=$(grep -E "^- \[.\] \*\*AC-" "$SPEC_FILE" 2>/dev/null || echo "")
46
- TOTAL_ACS=$(echo "$ACS" | wc -l | tr -d ' ')
47
- COMPLETED_ACS=$(echo "$ACS" | grep -c "^- \[x\]" || echo "0")
48
-
49
- # Extract tasks status
50
- TASKS=$(grep -E "^### T-[0-9]+" "$TASKS_FILE" 2>/dev/null || echo "")
51
- TOTAL_TASKS=$(echo "$TASKS" | wc -l | tr -d ' ')
52
-
53
- TASK_STATUS=$(grep -E "\*\*Status\*\*:" "$TASKS_FILE" 2>/dev/null || echo "")
54
- COMPLETED_TASKS=$(echo "$TASK_STATUS" | grep -c "\[x\] completed" || echo "0")
55
-
56
- # Get recent changes from git
57
- RECENT_CHANGES=$(git diff HEAD~5..HEAD --stat 2>/dev/null | head -20 || echo "No git history available")
58
-
59
- # Get test results from transcript
60
- TEST_RESULTS=$(tail -500 "$TRANSCRIPT_PATH" 2>/dev/null | grep -E "(PASS|FAIL|passed|failed|✓|✗)" | tail -20 || echo "No test results in transcript")
61
-
62
- # ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
63
- # BUILD JUDGE PROMPT
64
- # ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
65
-
66
- JUDGE_PROMPT=$(cat <<EOF
67
- You are a strict quality judge assessing whether work on increment $INCREMENT_ID is COMPLETE and PRODUCTION-READY.
68
-
69
- # Context
70
-
71
- ## Acceptance Criteria Status
72
- - Total ACs: $TOTAL_ACS
73
- - Completed ACs: $COMPLETED_ACS
74
-
75
- ## Tasks Status
76
- - Total Tasks: $TOTAL_TASKS
77
- - Completed Tasks: $COMPLETED_TASKS
78
-
79
- ## Recent Changes
80
- \`\`\`
81
- $RECENT_CHANGES
82
- \`\`\`
83
-
84
- ## Test Results
85
- \`\`\`
86
- $TEST_RESULTS
87
- \`\`\`
88
-
89
- ## Specification
90
- $(head -100 "$SPEC_FILE")
91
-
92
- ## Task Details
93
- $(head -100 "$TASKS_FILE")
94
-
95
- # Your Role
96
-
97
- You are the FINAL quality gate. Your job is to determine if this work is:
98
- 1. **COMPLETE**: All acceptance criteria satisfied
99
- 2. **TESTED**: Appropriate test coverage (unit + integration/E2E where needed)
100
- 3. **PRODUCTION-READY**: No obvious bugs, security issues, or incomplete implementations
101
-
102
- # Evaluation Criteria
103
-
104
- ✅ **APPROVE** if:
105
- - All ACs marked [x] AND actually implemented
106
- - Tests exist AND pass for critical paths
107
- - Code quality is production-ready
108
- - No half-finished implementations
109
- - Security best practices followed
110
-
111
- ❌ **REJECT** if:
112
- - ACs marked [x] but not actually implemented (self-deception)
113
- - Missing tests for critical functionality
114
- - Obvious bugs or security vulnerabilities
115
- - Incomplete error handling
116
- - Poor code quality (will cause maintenance issues)
117
-
118
- # Output Format
119
-
120
- Respond with JSON ONLY:
121
-
122
- \`\`\`json
123
- {
124
- "decision": "approve" | "reject",
125
- "confidence": 0.0-1.0,
126
- "reasoning": "Brief explanation (2-3 sentences)",
127
- "concerns": ["concern 1", "concern 2"],
128
- "recommendations": ["recommendation 1"]
129
- }
130
- \`\`\`
131
-
132
- **Be strict.** False approvals lead to production bugs. When in doubt, REJECT with clear guidance.
133
- EOF
134
- )
135
-
136
- # ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
137
- # CALL CLAUDE API FOR JUDGMENT
138
- # ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
139
-
140
- echo "🤖 Requesting LLM Judge assessment..." >&2
141
-
142
- # Check if API key exists
143
- if [ -z "$ANTHROPIC_API_KEY" ]; then
144
- echo "⚠️ ANTHROPIC_API_KEY not set - skipping LLM judge (assuming approval)" >&2
145
- exit 0
146
- fi
147
-
148
- # Create temporary file for request
149
- TMP_REQUEST=$(mktemp)
150
- cat > "$TMP_REQUEST" <<EOF
151
- {
152
- "model": "claude-sonnet-4-20250514",
153
- "max_tokens": 1024,
154
- "messages": [
155
- {
156
- "role": "user",
157
- "content": $(echo "$JUDGE_PROMPT" | jq -Rs .)
158
- }
159
- ]
160
- }
161
- EOF
162
-
163
- # Call Claude API
164
- RESPONSE=$(curl -s -X POST https://api.anthropic.com/v1/messages \
165
- -H "Content-Type: application/json" \
166
- -H "X-API-Key: $ANTHROPIC_API_KEY" \
167
- -H "anthropic-version: 2023-06-01" \
168
- -d @"$TMP_REQUEST")
169
-
170
- rm -f "$TMP_REQUEST"
171
-
172
- # Extract text content
173
- JUDGE_OUTPUT=$(echo "$RESPONSE" | jq -r '.content[0].text // ""')
174
-
175
- if [ -z "$JUDGE_OUTPUT" ]; then
176
- echo "❌ Failed to get judge response" >&2
177
- echo "API Response: $RESPONSE" >&2
178
- exit 1
179
- fi
180
-
181
- # Parse JSON from output (extract JSON block)
182
- JUDGE_JSON=$(echo "$JUDGE_OUTPUT" | grep -A 100 '```json' | grep -B 100 '```' | grep -v '```' | jq -c '.')
183
-
184
- if [ -z "$JUDGE_JSON" ] || [ "$JUDGE_JSON" = "null" ]; then
185
- echo "⚠️ Could not parse judge JSON - raw output:" >&2
186
- echo "$JUDGE_OUTPUT" >&2
187
- exit 1
188
- fi
189
-
190
- # Extract decision
191
- DECISION=$(echo "$JUDGE_JSON" | jq -r '.decision')
192
- CONFIDENCE=$(echo "$JUDGE_JSON" | jq -r '.confidence')
193
- REASONING=$(echo "$JUDGE_JSON" | jq -r '.reasoning')
194
- CONCERNS=$(echo "$JUDGE_JSON" | jq -r '.concerns | join(", ")')
195
-
196
- echo "" >&2
197
- echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" >&2
198
- echo "🤖 LLM JUDGE ASSESSMENT" >&2
199
- echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" >&2
200
- echo "" >&2
201
- echo "Decision: $DECISION (confidence: $CONFIDENCE)" >&2
202
- echo "Reasoning: $REASONING" >&2
203
-
204
- if [ "$DECISION" = "reject" ]; then
205
- echo "" >&2
206
- echo "❌ CONCERNS:" >&2
207
- echo "$CONCERNS" >&2
208
- echo "" >&2
209
- echo "The LLM judge has REJECTED this work as not production-ready." >&2
210
- echo "Address the concerns above and try again." >&2
211
- echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" >&2
212
- exit 1
213
- fi
214
-
215
- echo "" >&2
216
- echo "✅ LLM judge APPROVED - work is production-ready" >&2
217
- echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" >&2
218
-
219
- exit 0
@@ -1,168 +0,0 @@
1
- #!/bin/bash
2
- # log-decision.sh - Structured Decision Logging Utility
3
- #
4
- # Shared utility for all SpecWeave hooks to log decisions in structured JSON format.
5
- # Inspired by Claude Code 2.1.27's "Added tool call failures and denials to debug logs"
6
- #
7
- # Usage:
8
- # source log-decision.sh
9
- # log_decision "hook_name" "decision" "reason_code" "reason" "context_json" duration_ms
10
- #
11
- # Output:
12
- # - Appends JSON entry to .specweave/logs/decisions.jsonl
13
- # - Debug output to stderr when SPECWEAVE_DEBUG_HOOKS=1
14
- #
15
- # Schema:
16
- # {
17
- # "timestamp": "ISO8601",
18
- # "hook": "stop-auto|stop-reflect|user-prompt-submit",
19
- # "decision": "approve|block",
20
- # "reason": "Human-readable reason",
21
- # "reasonCode": "machine_parseable_enum",
22
- # "durationMs": 123,
23
- # "context": { ... hook-specific context ... }
24
- # }
25
-
26
- # Max log size before rotation (10MB)
27
- _LOG_MAX_SIZE=10485760
28
-
29
- # Debug logging to stderr (only when SPECWEAVE_DEBUG_HOOKS=1)
30
- _log_debug() {
31
- if [ "${SPECWEAVE_DEBUG_HOOKS:-0}" = "1" ]; then
32
- local color_reset="\033[0m"
33
- local color_cyan="\033[36m"
34
- local color_green="\033[32m"
35
- local color_red="\033[31m"
36
- local color_yellow="\033[33m"
37
-
38
- local level="$1"
39
- shift
40
- local message="$*"
41
-
42
- local color="$color_cyan"
43
- case "$level" in
44
- "DECISION") color="$color_green" ;;
45
- "BLOCK") color="$color_red" ;;
46
- "WARN") color="$color_yellow" ;;
47
- esac
48
-
49
- echo -e "${color}[$level]${color_reset} $message" >&2
50
- fi
51
- }
52
-
53
- # Rotate log file if it exceeds max size
54
- _rotate_log_if_needed() {
55
- local log_file="$1"
56
-
57
- if [ ! -f "$log_file" ]; then
58
- return 0
59
- fi
60
-
61
- local file_size
62
- # Cross-platform file size (macOS vs Linux)
63
- if [[ "$OSTYPE" == "darwin"* ]]; then
64
- file_size=$(stat -f%z "$log_file" 2>/dev/null || echo "0")
65
- else
66
- file_size=$(stat -c%s "$log_file" 2>/dev/null || echo "0")
67
- fi
68
-
69
- if [ "$file_size" -gt "$_LOG_MAX_SIZE" ]; then
70
- _log_debug "WARN" "Log rotation triggered (${file_size} > ${_LOG_MAX_SIZE})"
71
-
72
- # Keep last ~5MB by taking last N lines
73
- # Estimate: average 500 bytes per line, so 5MB = ~10000 lines
74
- local temp_file="${log_file}.tmp"
75
- tail -n 10000 "$log_file" > "$temp_file" 2>/dev/null
76
- mv "$temp_file" "$log_file" 2>/dev/null
77
-
78
- _log_debug "INFO" "Log rotated, kept last 10000 entries"
79
- fi
80
- }
81
-
82
- # Main logging function
83
- # Arguments:
84
- # $1: hook_name - Name of the hook (stop-auto, stop-reflect, etc.)
85
- # $2: decision - Decision made (approve, block)
86
- # $3: reason_code - Machine-parseable reason code (session_inactive, work_remaining, etc.)
87
- # $4: reason - Human-readable reason message
88
- # $5: context_json - JSON string with hook-specific context (default: "{}")
89
- # $6: duration_ms - Execution time in milliseconds (default: 0)
90
- log_decision() {
91
- local hook_name="$1"
92
- local decision="$2"
93
- local reason_code="$3"
94
- local reason="$4"
95
- local context_json="${5:-"{}"}"
96
- local duration_ms="${6:-0}"
97
-
98
- # Compute paths based on current PROJECT_ROOT
99
- local project_root="${PROJECT_ROOT:-$(pwd)}"
100
- local log_dir="$project_root/.specweave/logs"
101
- local log_file="$log_dir/decisions.jsonl"
102
-
103
- # Validate required arguments
104
- if [ -z "$hook_name" ] || [ -z "$decision" ] || [ -z "$reason_code" ]; then
105
- _log_debug "WARN" "log_decision called with missing arguments"
106
- return 1
107
- fi
108
-
109
- # Guard: only create dirs in initialized SpecWeave projects (prevents .specweave pollution)
110
- if [ ! -d "$project_root/.specweave/increments" ] && [ ! -f "$project_root/.specweave/config.json" ]; then
111
- _log_debug "WARN" "Not a SpecWeave project, skipping decision log"
112
- return 0
113
- fi
114
-
115
- # Ensure logs directory exists
116
- if [ ! -d "$log_dir" ]; then
117
- mkdir -p "$log_dir" 2>/dev/null
118
- _log_debug "INFO" "Created logs directory: $log_dir"
119
- fi
120
-
121
- # Check for log rotation
122
- _rotate_log_if_needed "$log_file"
123
-
124
- # Generate ISO 8601 timestamp
125
- local timestamp
126
- timestamp=$(date -u +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || date +%Y-%m-%dT%H:%M:%SZ)
127
-
128
- # Escape special characters in reason for JSON
129
- local escaped_reason
130
- escaped_reason=$(printf '%s' "$reason" | sed 's/\\/\\\\/g; s/"/\\"/g; s/ /\\t/g' | tr '\n' ' ')
131
-
132
- # Build JSON entry using jq
133
- local json_entry
134
- json_entry=$(jq -n -c \
135
- --arg timestamp "$timestamp" \
136
- --arg hook "$hook_name" \
137
- --arg decision "$decision" \
138
- --arg reason "$escaped_reason" \
139
- --arg reasonCode "$reason_code" \
140
- --argjson durationMs "$duration_ms" \
141
- --argjson context "$context_json" \
142
- '{
143
- timestamp: $timestamp,
144
- hook: $hook,
145
- decision: $decision,
146
- reason: $reason,
147
- reasonCode: $reasonCode,
148
- durationMs: $durationMs,
149
- context: $context
150
- }' 2>/dev/null)
151
-
152
- # Fallback if jq fails
153
- if [ -z "$json_entry" ]; then
154
- json_entry="{\"timestamp\":\"$timestamp\",\"hook\":\"$hook_name\",\"decision\":\"$decision\",\"reason\":\"$escaped_reason\",\"reasonCode\":\"$reason_code\",\"durationMs\":$duration_ms,\"context\":$context_json}"
155
- fi
156
-
157
- # Append to log file
158
- printf '%s\n' "$json_entry" >> "$log_file" 2>/dev/null
159
-
160
- # Debug output
161
- if [ "$decision" = "block" ]; then
162
- _log_debug "BLOCK" "$hook_name: $reason_code - $reason"
163
- else
164
- _log_debug "DECISION" "$hook_name: $decision ($reason_code)"
165
- fi
166
-
167
- return 0
168
- }
@@ -1,64 +0,0 @@
1
- #!/bin/bash
2
- # pre-compact.sh - Context pressure signal handler (v1.0.262)
3
- #
4
- # Fires when Claude Code approaches context limits (before compaction).
5
- # Writes pressure state for UserPromptSubmit hook to read and reduce budget.
6
- #
7
- # Escalation: 1st → "elevated", 2nd → "critical", 3+ → "emergency"
8
- set +e
9
-
10
- [[ "${SPECWEAVE_DISABLE_HOOKS:-0}" == "1" ]] && echo '{"continue":true}' && exit 0
11
-
12
- # Find project root
13
- PROJECT_ROOT="$PWD"
14
- while [[ "$PROJECT_ROOT" != "/" ]] && [[ ! -f "$PROJECT_ROOT/.specweave/config.json" ]]; do
15
- PROJECT_ROOT=$(dirname "$PROJECT_ROOT")
16
- done
17
- [[ ! -f "$PROJECT_ROOT/.specweave/config.json" ]] && echo '{"continue":true}' && exit 0
18
-
19
- STATE_DIR="$PROJECT_ROOT/.specweave/state"
20
- PRESSURE_FILE="$STATE_DIR/context-pressure.json"
21
- mkdir -p "$STATE_DIR" 2>/dev/null
22
-
23
- # Read previous compaction count for escalation
24
- PREV_COUNT=0
25
- if [[ -f "$PRESSURE_FILE" ]] && command -v jq >/dev/null 2>&1; then
26
- PREV_COUNT=$(jq -r '.compactionCount // 0' "$PRESSURE_FILE" 2>/dev/null || echo "0")
27
- fi
28
- NEW_COUNT=$((PREV_COUNT + 1))
29
-
30
- # Determine level: 1 = elevated, 2 = critical, 3+ = emergency
31
- LEVEL="elevated"
32
- [[ "$NEW_COUNT" -ge 2 ]] && LEVEL="critical"
33
- [[ "$NEW_COUNT" -ge 3 ]] && LEVEL="emergency"
34
-
35
- cat > "$PRESSURE_FILE" <<EOF
36
- {"level":"$LEVEL","compactionCount":$NEW_COUNT,"lastCompaction":"$(date -Iseconds)"}
37
- EOF
38
-
39
- # Write prompt-health-alert.json with remediation advice (v1.0.268)
40
- ADVICE=""
41
- case "$LEVEL" in
42
- elevated)
43
- ADVICE="Context budget reduced to compact. Session is running long."
44
- ;;
45
- critical)
46
- ADVICE="Context budget at minimal. Consider starting a new session or setting contextBudget.level to off."
47
- ;;
48
- emergency)
49
- ADVICE="Context budget stripped to off (3+ compactions). Strongly recommend starting a new session."
50
- ;;
51
- esac
52
-
53
- ALERT_FILE="$STATE_DIR/prompt-health-alert.json"
54
- cat > "$ALERT_FILE" <<EOF
55
- {"level":"$LEVEL","compactionCount":$NEW_COUNT,"advice":"$ADVICE","timestamp":"$(date -Iseconds)"}
56
- EOF
57
-
58
- # Log compaction event for dashboard activity stream
59
- _LOG_DIR="$PROJECT_ROOT/.specweave/logs"
60
- mkdir -p "$_LOG_DIR" 2>/dev/null
61
- echo "[$(date -Iseconds)] COMPACTION #$NEW_COUNT | level=$LEVEL | $ADVICE" >> "$_LOG_DIR/prompt-health.log" 2>/dev/null
62
-
63
- echo '{"continue":true}'
64
- exit 0
@@ -1,64 +0,0 @@
1
- #!/bin/bash
2
-
3
- # ╔══════════════════════════════════════════════════════════════════════════╗
4
- # ║ SpecWeave Startup Health Check ║
5
- # ║ Runs on Claude Code startup to detect and auto-fix plugin issues ║
6
- # ║ This hook runs BEFORE plugin loading, catching issues early ║
7
- # ╚══════════════════════════════════════════════════════════════════════════╝
8
-
9
- # Detect project root via walk-up
10
- _DIR="$PWD"
11
- _LIMIT=0
12
- while [ "$_DIR" != "/" ] && [ ! -f "$_DIR/.specweave/config.json" ] && [ $_LIMIT -lt 50 ]; do
13
- _DIR=$(dirname "$_DIR")
14
- _LIMIT=$((_LIMIT + 1))
15
- done
16
- if [ ! -f "$_DIR/.specweave/config.json" ]; then
17
- exit 0
18
- fi
19
- PROJECT_ROOT="$_DIR"
20
-
21
- HEALTH_LOG="$HOME/.claude/plugins/.health-check.log"
22
-
23
- # Function to log with timestamp
24
- log() {
25
- echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> "$HEALTH_LOG"
26
- }
27
-
28
- # Rotate log if too large (>100KB)
29
- if [ -f "$HEALTH_LOG" ] && [ $(stat -f%z "$HEALTH_LOG" 2>/dev/null || stat -c%s "$HEALTH_LOG" 2>/dev/null) -gt 102400 ]; then
30
- mv "$HEALTH_LOG" "${HEALTH_LOG}.old"
31
- fi
32
-
33
- log "=== Health check started ==="
34
-
35
- # ============================================================================
36
- # SESSION CLEANUP: ALWAYS clear auto-mode.json (CRITICAL for session-scoped auto)
37
- # Auto mode MUST be session-scoped - each new Claude Code session starts FRESH.
38
- # The file is per-project but MUST only affect the session that created it.
39
- # ============================================================================
40
-
41
- AUTO_MODE_FILE="$PROJECT_ROOT/.specweave/state/auto-mode.json"
42
- STATE_DIR="$PROJECT_ROOT/.specweave/state"
43
-
44
- # ALWAYS clear auto-mode.json on session start
45
- # This ensures auto mode is truly session-scoped:
46
- # - Session A runs /sw:auto → creates auto-mode.json
47
- # - Session A closes → file remains but is now orphaned
48
- # - Session B starts → SessionStart hook clears the file
49
- # - Session B is NOT in auto mode (correct behavior)
50
- if [ -f "$AUTO_MODE_FILE" ]; then
51
- log "SESSION START: Clearing previous auto-mode.json (session-scoped cleanup)"
52
- rm -f "$AUTO_MODE_FILE" 2>/dev/null
53
- rm -f "$STATE_DIR/.stop-auto-dedup" 2>/dev/null
54
- rm -f "$STATE_DIR/.stop-auto-dedup-prev" 2>/dev/null
55
- rm -f "$STATE_DIR/.stop-auto-turns" 2>/dev/null
56
- log "Cleared all auto-mode session files - new session starts fresh"
57
- fi
58
-
59
- # v1.0.344 (0394): Removed marketplace directory checks (Checks 1-4).
60
- # Plugins are now installed on-demand via `npx vskill install --repo` in user-prompt-submit.sh.
61
- # No local marketplace directory at ~/.claude/plugins/marketplaces/specweave is required.
62
-
63
- log "OK: Health check passed (session cleanup complete)"
64
- exit 0