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.
- package/CLAUDE.md +1 -1
- package/bin/specweave.js +23 -1
- package/dist/src/cli/commands/hook.d.ts +15 -0
- package/dist/src/cli/commands/hook.d.ts.map +1 -0
- package/dist/src/cli/commands/hook.js +61 -0
- package/dist/src/cli/commands/hook.js.map +1 -0
- package/dist/src/cli/commands/init.d.ts.map +1 -1
- package/dist/src/cli/commands/init.js +5 -0
- package/dist/src/cli/commands/init.js.map +1 -1
- package/dist/src/cli/commands/refresh-plugins.d.ts.map +1 -1
- package/dist/src/cli/commands/refresh-plugins.js +11 -1
- package/dist/src/cli/commands/refresh-plugins.js.map +1 -1
- package/dist/src/cli/commands/sync-setup.d.ts.map +1 -1
- package/dist/src/cli/commands/sync-setup.js +7 -3
- package/dist/src/cli/commands/sync-setup.js.map +1 -1
- package/dist/src/cli/helpers/issue-tracker/project-mapping-wizard.d.ts +9 -0
- package/dist/src/cli/helpers/issue-tracker/project-mapping-wizard.d.ts.map +1 -1
- package/dist/src/cli/helpers/issue-tracker/project-mapping-wizard.js +9 -3
- package/dist/src/cli/helpers/issue-tracker/project-mapping-wizard.js.map +1 -1
- package/dist/src/config/types.d.ts +2 -2
- package/dist/src/core/config/types.d.ts +18 -2
- package/dist/src/core/config/types.d.ts.map +1 -1
- package/dist/src/core/config/types.js.map +1 -1
- package/dist/src/core/hooks/handlers/hook-router.d.ts +19 -0
- package/dist/src/core/hooks/handlers/hook-router.d.ts.map +1 -0
- package/dist/src/core/hooks/handlers/hook-router.js +75 -0
- package/dist/src/core/hooks/handlers/hook-router.js.map +1 -0
- package/dist/src/core/hooks/handlers/index.d.ts +10 -0
- package/dist/src/core/hooks/handlers/index.d.ts.map +1 -0
- package/dist/src/core/hooks/handlers/index.js +9 -0
- package/dist/src/core/hooks/handlers/index.js.map +1 -0
- package/dist/src/core/hooks/handlers/post-tool-use-analytics.d.ts +11 -0
- package/dist/src/core/hooks/handlers/post-tool-use-analytics.d.ts.map +1 -0
- package/dist/src/core/hooks/handlers/post-tool-use-analytics.js +73 -0
- package/dist/src/core/hooks/handlers/post-tool-use-analytics.js.map +1 -0
- package/dist/src/core/hooks/handlers/post-tool-use.d.ts +11 -0
- package/dist/src/core/hooks/handlers/post-tool-use.d.ts.map +1 -0
- package/dist/src/core/hooks/handlers/post-tool-use.js +76 -0
- package/dist/src/core/hooks/handlers/post-tool-use.js.map +1 -0
- package/dist/src/core/hooks/handlers/pre-compact.d.ts +11 -0
- package/dist/src/core/hooks/handlers/pre-compact.d.ts.map +1 -0
- package/dist/src/core/hooks/handlers/pre-compact.js +77 -0
- package/dist/src/core/hooks/handlers/pre-compact.js.map +1 -0
- package/dist/src/core/hooks/handlers/pre-tool-use.d.ts +11 -0
- package/dist/src/core/hooks/handlers/pre-tool-use.d.ts.map +1 -0
- package/dist/src/core/hooks/handlers/pre-tool-use.js +318 -0
- package/dist/src/core/hooks/handlers/pre-tool-use.js.map +1 -0
- package/dist/src/core/hooks/handlers/session-start.d.ts +9 -0
- package/dist/src/core/hooks/handlers/session-start.d.ts.map +1 -0
- package/dist/src/core/hooks/handlers/session-start.js +111 -0
- package/dist/src/core/hooks/handlers/session-start.js.map +1 -0
- package/dist/src/core/hooks/handlers/stop-auto.d.ts +16 -0
- package/dist/src/core/hooks/handlers/stop-auto.d.ts.map +1 -0
- package/dist/src/core/hooks/handlers/stop-auto.js +122 -0
- package/dist/src/core/hooks/handlers/stop-auto.js.map +1 -0
- package/dist/src/core/hooks/handlers/stop-reflect.d.ts +14 -0
- package/dist/src/core/hooks/handlers/stop-reflect.d.ts.map +1 -0
- package/dist/src/core/hooks/handlers/stop-reflect.js +43 -0
- package/dist/src/core/hooks/handlers/stop-reflect.js.map +1 -0
- package/dist/src/core/hooks/handlers/stop-sync.d.ts +15 -0
- package/dist/src/core/hooks/handlers/stop-sync.d.ts.map +1 -0
- package/dist/src/core/hooks/handlers/stop-sync.js +68 -0
- package/dist/src/core/hooks/handlers/stop-sync.js.map +1 -0
- package/dist/src/core/hooks/handlers/types.d.ts +63 -0
- package/dist/src/core/hooks/handlers/types.d.ts.map +1 -0
- package/dist/src/core/hooks/handlers/types.js +27 -0
- package/dist/src/core/hooks/handlers/types.js.map +1 -0
- package/dist/src/core/hooks/handlers/user-prompt-submit.d.ts +14 -0
- package/dist/src/core/hooks/handlers/user-prompt-submit.d.ts.map +1 -0
- package/dist/src/core/hooks/handlers/user-prompt-submit.js +173 -0
- package/dist/src/core/hooks/handlers/user-prompt-submit.js.map +1 -0
- package/dist/src/core/hooks/handlers/utils.d.ts +25 -0
- package/dist/src/core/hooks/handlers/utils.d.ts.map +1 -0
- package/dist/src/core/hooks/handlers/utils.js +64 -0
- package/dist/src/core/hooks/handlers/utils.js.map +1 -0
- package/dist/src/core/increment/completion-validator.d.ts.map +1 -1
- package/dist/src/core/increment/completion-validator.js +32 -0
- package/dist/src/core/increment/completion-validator.js.map +1 -1
- package/dist/src/init/research/types.d.ts +1 -1
- package/dist/src/sync/sync-target-resolver.js.map +1 -1
- package/dist/src/utils/lock-manager.d.ts.map +1 -1
- package/dist/src/utils/lock-manager.js +5 -0
- package/dist/src/utils/lock-manager.js.map +1 -1
- package/dist/src/utils/plugin-copier.d.ts +10 -0
- package/dist/src/utils/plugin-copier.d.ts.map +1 -1
- package/dist/src/utils/plugin-copier.js +63 -35
- package/dist/src/utils/plugin-copier.js.map +1 -1
- package/package.json +1 -1
- package/plugins/specweave/agents/sw-closer.md +3 -2
- package/plugins/specweave/hooks/hooks.json +10 -10
- package/plugins/specweave/skills/code-reviewer/SKILL.md +180 -16
- package/plugins/specweave/skills/code-reviewer/agents/reviewer-comments.md +83 -0
- package/plugins/specweave/skills/code-reviewer/agents/reviewer-silent-failures.md +19 -0
- package/plugins/specweave/skills/code-reviewer/agents/reviewer-spec-compliance.md +19 -0
- package/plugins/specweave/skills/code-reviewer/agents/reviewer-tests.md +101 -0
- package/plugins/specweave/skills/code-reviewer/agents/reviewer-types.md +20 -0
- package/plugins/specweave/skills/done/SKILL.md +56 -21
- package/plugins/specweave/skills/grill/SKILL.md +1 -1
- package/plugins/specweave/skills/team-lead/agents/reviewer-logic.md +19 -0
- package/plugins/specweave/skills/team-lead/agents/reviewer-performance.md +20 -0
- package/plugins/specweave/skills/team-lead/agents/reviewer-security.md +20 -0
- package/src/templates/CLAUDE.md.template +7 -4
- package/plugins/specweave/hooks/README.md +0 -493
- package/plugins/specweave/hooks/_archive/stop-auto-v4-legacy.sh +0 -1319
- package/plugins/specweave/hooks/lib/common-setup.sh +0 -144
- package/plugins/specweave/hooks/lib/hook-errors.sh +0 -414
- package/plugins/specweave/hooks/lib/migrate-increment-work.sh +0 -245
- package/plugins/specweave/hooks/lib/resolve-package.sh +0 -146
- package/plugins/specweave/hooks/lib/scheduler-startup.sh +0 -135
- package/plugins/specweave/hooks/lib/score-increment.sh +0 -87
- package/plugins/specweave/hooks/lib/sync-spec-content.sh +0 -193
- package/plugins/specweave/hooks/lib/update-active-increment.sh +0 -95
- package/plugins/specweave/hooks/lib/update-status-line.sh +0 -233
- package/plugins/specweave/hooks/lib/validate-spec-status.sh +0 -171
- package/plugins/specweave/hooks/llm-judge-validator.sh +0 -219
- package/plugins/specweave/hooks/log-decision.sh +0 -168
- package/plugins/specweave/hooks/pre-compact.sh +0 -64
- package/plugins/specweave/hooks/startup-health-check.sh +0 -64
- package/plugins/specweave/hooks/stop-auto-v5.sh +0 -276
- package/plugins/specweave/hooks/stop-reflect.sh +0 -336
- package/plugins/specweave/hooks/stop-sync.sh +0 -283
- package/plugins/specweave/hooks/tests/test-auto-context-integration.sh +0 -126
- package/plugins/specweave/hooks/tests/test-stop-auto-enriched.sh +0 -128
- package/plugins/specweave/hooks/universal/dispatcher.mjs +0 -336
- package/plugins/specweave/hooks/universal/fail-fast-wrapper.sh +0 -325
- package/plugins/specweave/hooks/universal/hook-wrapper.cmd +0 -26
- package/plugins/specweave/hooks/universal/hook-wrapper.sh +0 -69
- package/plugins/specweave/hooks/universal/run-hook.sh +0 -20
- package/plugins/specweave/hooks/universal/session-start.cmd +0 -16
- package/plugins/specweave/hooks/universal/session-start.ps1 +0 -16
- package/plugins/specweave/hooks/user-prompt-submit.sh +0 -2550
- package/plugins/specweave/hooks/v2/detectors/lifecycle-detector.sh +0 -87
- package/plugins/specweave/hooks/v2/detectors/us-completion-detector.sh +0 -186
- package/plugins/specweave/hooks/v2/dispatchers/post-tool-use-analytics.sh +0 -83
- package/plugins/specweave/hooks/v2/dispatchers/post-tool-use.sh +0 -447
- package/plugins/specweave/hooks/v2/dispatchers/pre-tool-use.sh +0 -104
- package/plugins/specweave/hooks/v2/dispatchers/session-start.sh +0 -270
- package/plugins/specweave/hooks/v2/guards/completion-guard.sh +0 -14
- package/plugins/specweave/hooks/v2/guards/increment-duplicate-guard.sh +0 -14
- package/plugins/specweave/hooks/v2/guards/increment-existence-guard.sh +0 -240
- package/plugins/specweave/hooks/v2/guards/interview-enforcement-guard.sh +0 -171
- package/plugins/specweave/hooks/v2/guards/metadata-json-guard.sh +0 -14
- package/plugins/specweave/hooks/v2/guards/skill-chain-enforcement-guard.sh +0 -222
- package/plugins/specweave/hooks/v2/guards/spec-template-enforcement-guard.sh +0 -21
- package/plugins/specweave/hooks/v2/guards/spec-validation-guard.sh +0 -14
- package/plugins/specweave/hooks/v2/guards/status-completion-guard.sh +0 -84
- package/plugins/specweave/hooks/v2/guards/task-ac-sync-guard.sh +0 -475
- package/plugins/specweave/hooks/v2/guards/tdd-enforcement-guard.sh +0 -268
- package/plugins/specweave/hooks/v2/handlers/ac-sync-dispatcher.sh +0 -332
- package/plugins/specweave/hooks/v2/handlers/ac-validation-handler.sh +0 -50
- package/plugins/specweave/hooks/v2/handlers/github-sync-handler.sh +0 -347
- package/plugins/specweave/hooks/v2/handlers/living-docs-handler.sh +0 -83
- package/plugins/specweave/hooks/v2/handlers/living-specs-handler.sh +0 -268
- package/plugins/specweave/hooks/v2/handlers/project-bridge-handler.sh +0 -104
- package/plugins/specweave/hooks/v2/handlers/status-line-handler.sh +0 -165
- package/plugins/specweave/hooks/v2/handlers/status-update.sh +0 -61
- package/plugins/specweave/hooks/v2/handlers/universal-auto-create-dispatcher.sh +0 -270
- package/plugins/specweave/hooks/v2/integrations/ado-post-living-docs-update.sh +0 -367
- package/plugins/specweave/hooks/v2/integrations/ado-post-task.sh +0 -179
- package/plugins/specweave/hooks/v2/integrations/github-auto-create-handler.sh +0 -553
- package/plugins/specweave/hooks/v2/integrations/github-post-task.sh +0 -345
- package/plugins/specweave/hooks/v2/integrations/jira-post-task.sh +0 -180
- package/plugins/specweave/hooks/v2/lib/check-provider-enabled.sh +0 -52
- package/plugins/specweave/hooks/v2/queue/enqueue.sh +0 -81
- package/plugins/specweave/hooks/v2/session-end.sh +0 -139
- 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
|