specweave 1.0.22 → 1.0.24
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 +95 -378
- package/dist/src/cli/commands/init.d.ts.map +1 -1
- package/dist/src/cli/commands/init.js +8 -26
- package/dist/src/cli/commands/init.js.map +1 -1
- package/dist/src/core/living-docs/cross-project-sync.d.ts +2 -0
- package/dist/src/core/living-docs/cross-project-sync.d.ts.map +1 -1
- package/dist/src/core/living-docs/cross-project-sync.js +14 -4
- package/dist/src/core/living-docs/cross-project-sync.js.map +1 -1
- package/dist/src/core/living-docs/living-docs-sync.d.ts.map +1 -1
- package/dist/src/core/living-docs/living-docs-sync.js +6 -2
- package/dist/src/core/living-docs/living-docs-sync.js.map +1 -1
- package/package.json +3 -3
- package/plugins/specweave/hooks/docs-changed.sh.backup +79 -0
- package/plugins/specweave/hooks/human-input-required.sh.backup +75 -0
- package/plugins/specweave/hooks/post-first-increment.sh.backup +61 -0
- package/plugins/specweave/hooks/post-increment-change.sh.backup +98 -0
- package/plugins/specweave/hooks/post-increment-completion.sh.backup +231 -0
- package/plugins/specweave/hooks/post-increment-planning.sh.backup +1048 -0
- package/plugins/specweave/hooks/post-increment-status-change.sh.backup +147 -0
- package/plugins/specweave/hooks/post-spec-update.sh.backup +158 -0
- package/plugins/specweave/hooks/post-user-story-complete.sh.backup +179 -0
- package/plugins/specweave/hooks/pre-command-deduplication.sh.backup +83 -0
- package/plugins/specweave/hooks/pre-implementation.sh.backup +67 -0
- package/plugins/specweave/hooks/pre-task-completion.sh.backup +194 -0
- package/plugins/specweave/hooks/pre-tool-use.sh.backup +133 -0
- package/plugins/specweave/hooks/user-prompt-submit.sh.backup +386 -0
- package/plugins/specweave-ado/hooks/post-living-docs-update.sh.backup +353 -0
- package/plugins/specweave-ado/hooks/post-task-completion.sh.backup +172 -0
- package/plugins/specweave-ado/lib/enhanced-ado-sync.js +170 -0
- package/plugins/specweave-github/hooks/.specweave/logs/hooks-debug.log +1262 -0
- package/plugins/specweave-github/hooks/post-task-completion.sh.backup +258 -0
- package/plugins/specweave-github/lib/enhanced-github-sync.js +220 -0
- package/plugins/specweave-jira/hooks/post-task-completion.sh.backup +172 -0
- package/plugins/specweave-jira/lib/enhanced-jira-sync.js +134 -0
- package/plugins/specweave-release/hooks/.specweave/logs/dora-tracking.log +1254 -0
- package/plugins/specweave-release/hooks/post-task-completion.sh.backup +110 -0
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# SpecWeave Pre-Task-Completion Hook
|
|
4
|
+
# CRITICAL QUALITY GATE: Validates AC tests before allowing task completion
|
|
5
|
+
#
|
|
6
|
+
# Runs automatically BEFORE any task is marked complete via TodoWrite
|
|
7
|
+
#
|
|
8
|
+
# WORKFLOW:
|
|
9
|
+
# =========
|
|
10
|
+
# 1. TodoWrite called with status="completed"
|
|
11
|
+
# 2. This hook fires (pre-completion validation)
|
|
12
|
+
# 3. Extract task ID from TodoWrite input
|
|
13
|
+
# 4. Find task in tasks.md
|
|
14
|
+
# 5. Run AC test validator
|
|
15
|
+
# 6. If tests PASS → Allow completion (continue: true)
|
|
16
|
+
# 7. If tests FAIL → Block completion (continue: false, show error)
|
|
17
|
+
#
|
|
18
|
+
# ENFORCEMENT:
|
|
19
|
+
# ============
|
|
20
|
+
# This is the ONLY way to mark tasks complete in SpecWeave.
|
|
21
|
+
# Manual edits to tasks.md are detected and flagged by pre-commit hooks.
|
|
22
|
+
|
|
23
|
+
set -e
|
|
24
|
+
|
|
25
|
+
# Find project root
|
|
26
|
+
find_project_root() {
|
|
27
|
+
local dir="$1"
|
|
28
|
+
while [ "$dir" != "/" ]; do
|
|
29
|
+
if [ -d "$dir/.specweave" ]; then
|
|
30
|
+
echo "$dir"
|
|
31
|
+
return 0
|
|
32
|
+
fi
|
|
33
|
+
dir="$(dirname "$dir")"
|
|
34
|
+
done
|
|
35
|
+
pwd
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
PROJECT_ROOT="$(find_project_root "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")"
|
|
39
|
+
cd "$PROJECT_ROOT" 2>/dev/null || true
|
|
40
|
+
|
|
41
|
+
# ============================================================================
|
|
42
|
+
# CONFIGURATION
|
|
43
|
+
# ============================================================================
|
|
44
|
+
|
|
45
|
+
LOGS_DIR=".specweave/logs"
|
|
46
|
+
DEBUG_LOG="$LOGS_DIR/hooks-debug.log"
|
|
47
|
+
|
|
48
|
+
mkdir -p "$LOGS_DIR" 2>/dev/null || true
|
|
49
|
+
|
|
50
|
+
echo "[$(date)] 🔒 Pre-task-completion hook fired" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
51
|
+
|
|
52
|
+
# ============================================================================
|
|
53
|
+
# CAPTURE INPUT
|
|
54
|
+
# ============================================================================
|
|
55
|
+
|
|
56
|
+
STDIN_DATA=$(mktemp)
|
|
57
|
+
cat > "$STDIN_DATA"
|
|
58
|
+
|
|
59
|
+
echo "[$(date)] Input JSON:" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
60
|
+
cat "$STDIN_DATA" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
61
|
+
|
|
62
|
+
# ============================================================================
|
|
63
|
+
# CHECK FOR TASK COMPLETION
|
|
64
|
+
# ============================================================================
|
|
65
|
+
|
|
66
|
+
# Only validate if a task is being marked complete
|
|
67
|
+
COMPLETING_TASK=false
|
|
68
|
+
|
|
69
|
+
if command -v jq >/dev/null 2>&1; then
|
|
70
|
+
# Check if any task is transitioning to "completed" status
|
|
71
|
+
COMPLETED_COUNT=$(jq -r '.tool_input.todos // [] | map(select(.status == "completed")) | length' "$STDIN_DATA" 2>/dev/null || echo "0")
|
|
72
|
+
|
|
73
|
+
if [ "$COMPLETED_COUNT" != "0" ]; then
|
|
74
|
+
COMPLETING_TASK=true
|
|
75
|
+
echo "[$(date)] ✓ Detected task completion (${COMPLETED_COUNT} tasks)" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
76
|
+
fi
|
|
77
|
+
fi
|
|
78
|
+
|
|
79
|
+
# If no tasks being completed, allow without validation
|
|
80
|
+
if [ "$COMPLETING_TASK" = "false" ]; then
|
|
81
|
+
echo "[$(date)] ⏭️ No tasks being completed, skipping validation" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
82
|
+
rm -f "$STDIN_DATA"
|
|
83
|
+
cat <<EOF
|
|
84
|
+
{
|
|
85
|
+
"continue": true
|
|
86
|
+
}
|
|
87
|
+
EOF
|
|
88
|
+
exit 0
|
|
89
|
+
fi
|
|
90
|
+
|
|
91
|
+
# ============================================================================
|
|
92
|
+
# DETECT CURRENT INCREMENT
|
|
93
|
+
# ============================================================================
|
|
94
|
+
|
|
95
|
+
CURRENT_INCREMENT=$(ls -td .specweave/increments/*/ 2>/dev/null | xargs -n1 basename | grep -v "_backlog" | grep -v "_archive" | grep -v "_working" | head -1)
|
|
96
|
+
|
|
97
|
+
if [ -z "$CURRENT_INCREMENT" ]; then
|
|
98
|
+
echo "[$(date)] ℹ️ No active increment found, skipping validation" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
99
|
+
rm -f "$STDIN_DATA"
|
|
100
|
+
cat <<EOF
|
|
101
|
+
{
|
|
102
|
+
"continue": true
|
|
103
|
+
}
|
|
104
|
+
EOF
|
|
105
|
+
exit 0
|
|
106
|
+
fi
|
|
107
|
+
|
|
108
|
+
TASKS_MD=".specweave/increments/$CURRENT_INCREMENT/tasks.md"
|
|
109
|
+
|
|
110
|
+
if [ ! -f "$TASKS_MD" ]; then
|
|
111
|
+
echo "[$(date)] ℹ️ tasks.md not found for $CURRENT_INCREMENT (increment may be in planning stage)" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
112
|
+
rm -f "$STDIN_DATA"
|
|
113
|
+
cat <<EOF
|
|
114
|
+
{
|
|
115
|
+
"continue": true
|
|
116
|
+
}
|
|
117
|
+
EOF
|
|
118
|
+
exit 0
|
|
119
|
+
fi
|
|
120
|
+
|
|
121
|
+
# ============================================================================
|
|
122
|
+
# RUN AC TEST VALIDATION
|
|
123
|
+
# ============================================================================
|
|
124
|
+
|
|
125
|
+
echo "[$(date)] 🧪 Running AC test validation for $CURRENT_INCREMENT" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
126
|
+
|
|
127
|
+
# Determine which validation script to use
|
|
128
|
+
VALIDATOR_SCRIPT=""
|
|
129
|
+
if [ -f "$PROJECT_ROOT/dist/src/core/ac-test-validator-cli.js" ]; then
|
|
130
|
+
VALIDATOR_SCRIPT="$PROJECT_ROOT/dist/src/core/ac-test-validator-cli.js"
|
|
131
|
+
elif [ -f "$PROJECT_ROOT/node_modules/specweave/dist/src/core/ac-test-validator-cli.js" ]; then
|
|
132
|
+
VALIDATOR_SCRIPT="$PROJECT_ROOT/node_modules/specweave/dist/src/core/ac-test-validator-cli.js"
|
|
133
|
+
elif [ -n "${CLAUDE_PLUGIN_ROOT}" ] && [ -f "${CLAUDE_PLUGIN_ROOT}/dist/src/core/ac-test-validator-cli.js" ]; then
|
|
134
|
+
VALIDATOR_SCRIPT="${CLAUDE_PLUGIN_ROOT}/dist/src/core/ac-test-validator-cli.js"
|
|
135
|
+
fi
|
|
136
|
+
|
|
137
|
+
if [ -z "$VALIDATOR_SCRIPT" ] || ! command -v node &> /dev/null; then
|
|
138
|
+
echo "[$(date)] ⚠️ AC test validator not found or Node.js missing" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
139
|
+
rm -f "$STDIN_DATA"
|
|
140
|
+
cat <<EOF
|
|
141
|
+
{
|
|
142
|
+
"continue": true,
|
|
143
|
+
"systemMessage": "⚠️ Warning: AC test validator not available. Task completion validation skipped. Install Node.js and rebuild SpecWeave to enable validation."
|
|
144
|
+
}
|
|
145
|
+
EOF
|
|
146
|
+
exit 0
|
|
147
|
+
fi
|
|
148
|
+
|
|
149
|
+
# Run validator (captures exit code)
|
|
150
|
+
VALIDATION_OUTPUT=$(mktemp)
|
|
151
|
+
VALIDATION_EXIT_CODE=0
|
|
152
|
+
|
|
153
|
+
(cd "$PROJECT_ROOT" && node "$VALIDATOR_SCRIPT" "$CURRENT_INCREMENT") > "$VALIDATION_OUTPUT" 2>&1 || VALIDATION_EXIT_CODE=$?
|
|
154
|
+
|
|
155
|
+
echo "[$(date)] Validator exit code: $VALIDATION_EXIT_CODE" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
156
|
+
cat "$VALIDATION_OUTPUT" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
157
|
+
|
|
158
|
+
rm -f "$STDIN_DATA"
|
|
159
|
+
|
|
160
|
+
# ============================================================================
|
|
161
|
+
# DECISION LOGIC
|
|
162
|
+
# ============================================================================
|
|
163
|
+
|
|
164
|
+
if [ "$VALIDATION_EXIT_CODE" = "0" ]; then
|
|
165
|
+
# Validation passed - allow completion
|
|
166
|
+
echo "[$(date)] ✅ AC test validation passed" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
167
|
+
|
|
168
|
+
VALIDATION_SUMMARY=$(cat "$VALIDATION_OUTPUT" | tail -5 | tr '\n' ' ')
|
|
169
|
+
|
|
170
|
+
rm -f "$VALIDATION_OUTPUT"
|
|
171
|
+
|
|
172
|
+
cat <<EOF
|
|
173
|
+
{
|
|
174
|
+
"continue": true,
|
|
175
|
+
"systemMessage": "✅ AC Test Validation Passed: All acceptance criteria have passing tests. Task completion allowed. ${VALIDATION_SUMMARY}"
|
|
176
|
+
}
|
|
177
|
+
EOF
|
|
178
|
+
else
|
|
179
|
+
# Validation failed - block completion
|
|
180
|
+
echo "[$(date)] ❌ AC test validation failed" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
181
|
+
|
|
182
|
+
VALIDATION_ERROR=$(cat "$VALIDATION_OUTPUT" | grep -A 10 "VALIDATION FAILED" | tr '\n' ' ' | cut -c 1-300)
|
|
183
|
+
|
|
184
|
+
rm -f "$VALIDATION_OUTPUT"
|
|
185
|
+
|
|
186
|
+
cat <<EOF
|
|
187
|
+
{
|
|
188
|
+
"continue": false,
|
|
189
|
+
"systemMessage": "❌ AC TEST VALIDATION FAILED: Cannot mark task as complete until all acceptance criteria have passing tests. ${VALIDATION_ERROR}
|
|
190
|
+
|
|
191
|
+
Fix the failing tests and try again. Run tests manually: npm test"
|
|
192
|
+
}
|
|
193
|
+
EOF
|
|
194
|
+
fi
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# SpecWeave Pre-Tool-Use Hook
|
|
4
|
+
# Runs BEFORE Claude calls any tool (PreToolUse event)
|
|
5
|
+
#
|
|
6
|
+
# PURPOSE: Detect when Claude asks questions via AskUserQuestion
|
|
7
|
+
# - Plays sound IMMEDIATELY when question is about to be asked
|
|
8
|
+
# - Complements post-task-completion hook (which only fires after TodoWrite)
|
|
9
|
+
# - Ensures user is always notified when Claude needs input
|
|
10
|
+
#
|
|
11
|
+
# SCOPE:
|
|
12
|
+
# - This hook fires for ALL tool calls (Read, Edit, Write, AskUserQuestion, etc.)
|
|
13
|
+
# - We filter for AskUserQuestion specifically to play sound
|
|
14
|
+
# - Non-blocking and fast (<10ms overhead)
|
|
15
|
+
|
|
16
|
+
set -e
|
|
17
|
+
|
|
18
|
+
# ============================================================================
|
|
19
|
+
# CONFIGURATION
|
|
20
|
+
# ============================================================================
|
|
21
|
+
|
|
22
|
+
# Find project root
|
|
23
|
+
find_project_root() {
|
|
24
|
+
local dir="$1"
|
|
25
|
+
while [ "$dir" != "/" ]; do
|
|
26
|
+
if [ -d "$dir/.specweave" ]; then
|
|
27
|
+
echo "$dir"
|
|
28
|
+
return 0
|
|
29
|
+
fi
|
|
30
|
+
dir="$(dirname "$dir")"
|
|
31
|
+
done
|
|
32
|
+
# Fallback
|
|
33
|
+
if [ -d "$(pwd)/.specweave" ]; then
|
|
34
|
+
pwd
|
|
35
|
+
else
|
|
36
|
+
echo "$(pwd)"
|
|
37
|
+
fi
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
PROJECT_ROOT="$(find_project_root "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")"
|
|
41
|
+
cd "$PROJECT_ROOT" 2>/dev/null || true
|
|
42
|
+
|
|
43
|
+
LOGS_DIR=".specweave/logs"
|
|
44
|
+
DEBUG_LOG="$LOGS_DIR/hooks-debug.log"
|
|
45
|
+
|
|
46
|
+
mkdir -p "$LOGS_DIR" 2>/dev/null || true
|
|
47
|
+
|
|
48
|
+
# ============================================================================
|
|
49
|
+
# CAPTURE INPUT (Tool Call Details)
|
|
50
|
+
# ============================================================================
|
|
51
|
+
|
|
52
|
+
STDIN_DATA=$(mktemp)
|
|
53
|
+
cat > "$STDIN_DATA"
|
|
54
|
+
|
|
55
|
+
# Log the tool call for debugging
|
|
56
|
+
echo "[$(date)] 🔧 PreToolUse hook fired" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
57
|
+
echo "[$(date)] Tool call JSON:" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
58
|
+
cat "$STDIN_DATA" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
59
|
+
echo "" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
60
|
+
|
|
61
|
+
# ============================================================================
|
|
62
|
+
# DETECT AskUserQuestion TOOL
|
|
63
|
+
# ============================================================================
|
|
64
|
+
|
|
65
|
+
TOOL_NAME=""
|
|
66
|
+
|
|
67
|
+
if command -v jq >/dev/null 2>&1; then
|
|
68
|
+
# Use jq if available (most reliable)
|
|
69
|
+
TOOL_NAME=$(jq -r '.tool_name // empty' "$STDIN_DATA" 2>/dev/null)
|
|
70
|
+
else
|
|
71
|
+
# Fallback: grep-based detection
|
|
72
|
+
if grep -q '"tool_name"' "$STDIN_DATA" 2>/dev/null; then
|
|
73
|
+
TOOL_NAME=$(grep -o '"tool_name":"[^"]*"' "$STDIN_DATA" | cut -d'"' -f4)
|
|
74
|
+
fi
|
|
75
|
+
fi
|
|
76
|
+
|
|
77
|
+
echo "[$(date)] Tool name: $TOOL_NAME" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
78
|
+
|
|
79
|
+
# ============================================================================
|
|
80
|
+
# PLAY SOUND IF AskUserQuestion
|
|
81
|
+
# ============================================================================
|
|
82
|
+
|
|
83
|
+
play_sound() {
|
|
84
|
+
case "$(uname -s)" in
|
|
85
|
+
Darwin)
|
|
86
|
+
# macOS: Use afplay with a distinctive sound for questions
|
|
87
|
+
afplay /System/Library/Sounds/Tink.aiff 2>/dev/null || true
|
|
88
|
+
;;
|
|
89
|
+
Linux)
|
|
90
|
+
# Linux: Use paplay or aplay
|
|
91
|
+
paplay /usr/share/sounds/freedesktop/stereo/dialog-question.oga 2>/dev/null || \
|
|
92
|
+
paplay /usr/share/sounds/freedesktop/stereo/message-new-instant.oga 2>/dev/null || \
|
|
93
|
+
aplay /usr/share/sounds/alsa/Front_Center.wav 2>/dev/null || true
|
|
94
|
+
;;
|
|
95
|
+
MINGW*|MSYS*|CYGWIN*)
|
|
96
|
+
# Windows: Use PowerShell
|
|
97
|
+
powershell -c "(New-Object Media.SoundPlayer 'C:\Windows\Media\Windows Notify.wav').PlaySync();" 2>/dev/null || true
|
|
98
|
+
;;
|
|
99
|
+
esac
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
if [ "$TOOL_NAME" = "AskUserQuestion" ]; then
|
|
103
|
+
echo "[$(date)] 🔔 QUESTION DETECTED! Playing notification sound" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
104
|
+
play_sound
|
|
105
|
+
|
|
106
|
+
# Log this event
|
|
107
|
+
echo "[$(date)] Claude is asking for user input via AskUserQuestion" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
108
|
+
fi
|
|
109
|
+
|
|
110
|
+
# ============================================================================
|
|
111
|
+
# CLEANUP
|
|
112
|
+
# ============================================================================
|
|
113
|
+
|
|
114
|
+
rm -f "$STDIN_DATA"
|
|
115
|
+
|
|
116
|
+
# ============================================================================
|
|
117
|
+
# OUTPUT TO CLAUDE (Always continue)
|
|
118
|
+
# ============================================================================
|
|
119
|
+
|
|
120
|
+
if [ "$TOOL_NAME" = "AskUserQuestion" ]; then
|
|
121
|
+
cat <<EOF
|
|
122
|
+
{
|
|
123
|
+
"continue": true,
|
|
124
|
+
"systemMessage": "🔔 Sound played - user notified of question request"
|
|
125
|
+
}
|
|
126
|
+
EOF
|
|
127
|
+
else
|
|
128
|
+
cat <<EOF
|
|
129
|
+
{
|
|
130
|
+
"continue": true
|
|
131
|
+
}
|
|
132
|
+
EOF
|
|
133
|
+
fi
|