specweave 0.23.10 → 0.23.14
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-plugin/marketplace.json +7 -7
- package/CLAUDE.md +384 -1449
- package/dist/src/cli/commands/cleanup-cache.d.ts +14 -0
- package/dist/src/cli/commands/cleanup-cache.d.ts.map +1 -0
- package/dist/src/cli/commands/cleanup-cache.js +63 -0
- package/dist/src/cli/commands/cleanup-cache.js.map +1 -0
- package/dist/src/cli/commands/init.js +40 -0
- package/dist/src/cli/commands/init.js.map +1 -1
- package/dist/src/cli/helpers/async-project-loader.d.ts +148 -0
- package/dist/src/cli/helpers/async-project-loader.d.ts.map +1 -0
- package/dist/src/cli/helpers/async-project-loader.js +351 -0
- package/dist/src/cli/helpers/async-project-loader.js.map +1 -0
- package/dist/src/cli/helpers/cancelation-handler.d.ts +123 -0
- package/dist/src/cli/helpers/cancelation-handler.d.ts.map +1 -0
- package/dist/src/cli/helpers/cancelation-handler.js +187 -0
- package/dist/src/cli/helpers/cancelation-handler.js.map +1 -0
- package/dist/src/cli/helpers/import-strategy-prompter.d.ts +43 -0
- package/dist/src/cli/helpers/import-strategy-prompter.d.ts.map +1 -0
- package/dist/src/cli/helpers/import-strategy-prompter.js +136 -0
- package/dist/src/cli/helpers/import-strategy-prompter.js.map +1 -0
- package/dist/src/cli/helpers/issue-tracker/ado.d.ts +5 -2
- package/dist/src/cli/helpers/issue-tracker/ado.d.ts.map +1 -1
- package/dist/src/cli/helpers/issue-tracker/ado.js +90 -40
- package/dist/src/cli/helpers/issue-tracker/ado.js.map +1 -1
- package/dist/src/cli/helpers/issue-tracker/jira.d.ts +2 -1
- package/dist/src/cli/helpers/issue-tracker/jira.d.ts.map +1 -1
- package/dist/src/cli/helpers/issue-tracker/jira.js +120 -35
- package/dist/src/cli/helpers/issue-tracker/jira.js.map +1 -1
- package/dist/src/cli/helpers/progress-tracker.d.ts +121 -0
- package/dist/src/cli/helpers/progress-tracker.d.ts.map +1 -0
- package/dist/src/cli/helpers/progress-tracker.js +202 -0
- package/dist/src/cli/helpers/progress-tracker.js.map +1 -0
- package/dist/src/cli/helpers/project-count-fetcher.d.ts +69 -0
- package/dist/src/cli/helpers/project-count-fetcher.d.ts.map +1 -0
- package/dist/src/cli/helpers/project-count-fetcher.js +173 -0
- package/dist/src/cli/helpers/project-count-fetcher.js.map +1 -0
- package/dist/src/config/types.d.ts +14 -14
- package/dist/src/core/cache/cache-manager.d.ts +119 -0
- package/dist/src/core/cache/cache-manager.d.ts.map +1 -0
- package/dist/src/core/cache/cache-manager.js +304 -0
- package/dist/src/core/cache/cache-manager.js.map +1 -0
- package/dist/src/core/cache/rate-limit-checker.d.ts +92 -0
- package/dist/src/core/cache/rate-limit-checker.d.ts.map +1 -0
- package/dist/src/core/cache/rate-limit-checker.js +160 -0
- package/dist/src/core/cache/rate-limit-checker.js.map +1 -0
- package/dist/src/core/progress/cancelation-handler.d.ts +79 -0
- package/dist/src/core/progress/cancelation-handler.d.ts.map +1 -0
- package/dist/src/core/progress/cancelation-handler.js +111 -0
- package/dist/src/core/progress/cancelation-handler.js.map +1 -0
- package/dist/src/core/progress/error-logger.d.ts +58 -0
- package/dist/src/core/progress/error-logger.d.ts.map +1 -0
- package/dist/src/core/progress/error-logger.js +99 -0
- package/dist/src/core/progress/error-logger.js.map +1 -0
- package/dist/src/core/progress/import-state.d.ts +71 -0
- package/dist/src/core/progress/import-state.d.ts.map +1 -0
- package/dist/src/core/progress/import-state.js +96 -0
- package/dist/src/core/progress/import-state.js.map +1 -0
- package/dist/src/core/progress/progress-tracker.d.ts +139 -0
- package/dist/src/core/progress/progress-tracker.d.ts.map +1 -0
- package/dist/src/core/progress/progress-tracker.js +223 -0
- package/dist/src/core/progress/progress-tracker.js.map +1 -0
- package/dist/src/init/architecture/types.d.ts +6 -6
- package/dist/src/integrations/ado/ado-client.d.ts +25 -0
- package/dist/src/integrations/ado/ado-client.d.ts.map +1 -1
- package/dist/src/integrations/ado/ado-client.js +67 -0
- package/dist/src/integrations/ado/ado-client.js.map +1 -1
- package/dist/src/integrations/ado/ado-dependency-loader.d.ts +99 -0
- package/dist/src/integrations/ado/ado-dependency-loader.d.ts.map +1 -0
- package/dist/src/integrations/ado/ado-dependency-loader.js +207 -0
- package/dist/src/integrations/ado/ado-dependency-loader.js.map +1 -0
- package/dist/src/integrations/jira/jira-client.d.ts +32 -0
- package/dist/src/integrations/jira/jira-client.d.ts.map +1 -1
- package/dist/src/integrations/jira/jira-client.js +81 -0
- package/dist/src/integrations/jira/jira-client.js.map +1 -1
- package/dist/src/integrations/jira/jira-dependency-loader.d.ts +101 -0
- package/dist/src/integrations/jira/jira-dependency-loader.d.ts.map +1 -0
- package/dist/src/integrations/jira/jira-dependency-loader.js +200 -0
- package/dist/src/integrations/jira/jira-dependency-loader.js.map +1 -0
- package/package.json +1 -1
- package/plugins/specweave/.claude-plugin/plugin.json +20 -0
- package/plugins/specweave/agents/architect/AGENT.md +100 -602
- package/plugins/specweave/agents/pm/AGENT.md +96 -597
- package/plugins/specweave/agents/pm/AGENT.md.bak +1893 -0
- package/plugins/specweave/agents/pm/AGENT.md.bak2 +1754 -0
- package/plugins/specweave/commands/check-hooks.md +257 -0
- package/plugins/specweave/hooks/docs-changed.sh +9 -1
- package/plugins/specweave/hooks/docs-changed.sh.backup +79 -0
- package/plugins/specweave/hooks/human-input-required.sh +9 -1
- package/plugins/specweave/hooks/human-input-required.sh.backup +75 -0
- package/plugins/specweave/hooks/post-edit-spec.sh +202 -31
- package/plugins/specweave/hooks/post-first-increment.sh.backup +61 -0
- package/plugins/specweave/hooks/post-increment-change.sh +6 -1
- package/plugins/specweave/hooks/post-increment-change.sh.backup +98 -0
- package/plugins/specweave/hooks/post-increment-completion.sh +6 -1
- package/plugins/specweave/hooks/post-increment-completion.sh.backup +231 -0
- package/plugins/specweave/hooks/post-increment-planning.sh +6 -1
- package/plugins/specweave/hooks/post-increment-planning.sh.backup +1048 -0
- package/plugins/specweave/hooks/post-increment-status-change.sh +6 -1
- package/plugins/specweave/hooks/post-increment-status-change.sh.backup +147 -0
- package/plugins/specweave/hooks/post-metadata-change.sh +7 -1
- package/plugins/specweave/hooks/post-spec-update.sh.backup +158 -0
- package/plugins/specweave/hooks/post-task-completion.sh +225 -228
- package/plugins/specweave/hooks/post-user-story-complete.sh.backup +179 -0
- package/plugins/specweave/hooks/post-write-spec.sh +207 -31
- package/plugins/specweave/hooks/pre-command-deduplication.sh.backup +83 -0
- package/plugins/specweave/hooks/pre-edit-spec.sh +151 -0
- package/plugins/specweave/hooks/pre-implementation.sh +9 -1
- package/plugins/specweave/hooks/pre-implementation.sh.backup +67 -0
- package/plugins/specweave/hooks/pre-task-completion.sh +14 -8
- package/plugins/specweave/hooks/pre-task-completion.sh.backup +194 -0
- package/plugins/specweave/hooks/pre-tool-use.sh +9 -1
- package/plugins/specweave/hooks/pre-tool-use.sh.backup +133 -0
- package/plugins/specweave/hooks/pre-write-spec.sh +151 -0
- package/plugins/specweave/hooks/test-pretooluse-env.sh +72 -0
- package/plugins/specweave/hooks/user-prompt-submit.sh.backup +386 -0
- package/plugins/specweave/skills/compliance-architecture/SKILL.md +374 -0
- package/plugins/specweave/skills/external-sync-wizard/SKILL.md +610 -0
- package/plugins/specweave/skills/pm-closure-validation/SKILL.md +541 -0
- package/plugins/specweave/skills/roadmap-planner/SKILL.md +473 -0
- package/plugins/specweave-ado/commands/refresh-cache.js +25 -0
- package/plugins/specweave-ado/commands/refresh-cache.ts +40 -0
- package/plugins/specweave-ado/hooks/post-living-docs-update.sh +9 -2
- package/plugins/specweave-ado/hooks/post-living-docs-update.sh.backup +353 -0
- package/plugins/specweave-ado/hooks/post-task-completion.sh +10 -2
- package/plugins/specweave-ado/hooks/post-task-completion.sh.backup +172 -0
- package/plugins/specweave-github/hooks/post-task-completion.sh +10 -2
- package/plugins/specweave-github/hooks/post-task-completion.sh.backup +258 -0
- package/plugins/specweave-jira/commands/refresh-cache.js +25 -0
- package/plugins/specweave-jira/commands/refresh-cache.ts +40 -0
- package/plugins/specweave-jira/hooks/post-task-completion.sh +10 -2
- package/plugins/specweave-jira/hooks/post-task-completion.sh.backup +172 -0
- package/plugins/specweave-kafka-streams/commands/topology.md +437 -0
- package/plugins/specweave-n8n/commands/workflow-template.md +262 -0
- package/plugins/specweave-release/hooks/.specweave/logs/dora-tracking.log +252 -6465
- package/plugins/specweave-release/hooks/post-task-completion.sh.backup +110 -0
|
@@ -26,7 +26,20 @@
|
|
|
26
26
|
#
|
|
27
27
|
# DEBOUNCING: Prevents duplicate fires (Claude Code calls hooks twice)
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
# EMERGENCY FIXES (v0.24.3): CRITICAL SAFETY FIRST
|
|
30
|
+
# - Remove set -e completely to prevent any errors from propagating
|
|
31
|
+
# - Kill switch: SPECWEAVE_DISABLE_HOOKS=1 disables all hooks
|
|
32
|
+
# - Circuit breaker: Auto-disable after 3 consecutive failures
|
|
33
|
+
# - File locking: Only 1 instance can run at a time
|
|
34
|
+
# - Aggressive debouncing: 5 seconds (was 5s, keeping it)
|
|
35
|
+
# - Complete error isolation: ALL background work wrapped
|
|
36
|
+
|
|
37
|
+
set +e # NEVER use set -e in hooks - it causes crashes
|
|
38
|
+
|
|
39
|
+
# EMERGENCY KILL SWITCH FIRST (before anything else)
|
|
40
|
+
if [[ "${SPECWEAVE_DISABLE_HOOKS:-0}" == "1" ]]; then
|
|
41
|
+
exit 0
|
|
42
|
+
fi
|
|
30
43
|
|
|
31
44
|
# Find project root by searching upward for .specweave/ directory
|
|
32
45
|
# Works regardless of where hook is installed (source or .claude/hooks/)
|
|
@@ -50,16 +63,64 @@ find_project_root() {
|
|
|
50
63
|
PROJECT_ROOT="$(find_project_root "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")"
|
|
51
64
|
cd "$PROJECT_ROOT" 2>/dev/null || true
|
|
52
65
|
|
|
66
|
+
# ============================================================================
|
|
67
|
+
# EMERGENCY SAFETY CHECKS
|
|
68
|
+
# ============================================================================
|
|
69
|
+
|
|
70
|
+
# CIRCUIT BREAKER: Auto-disable after consecutive failures
|
|
71
|
+
CIRCUIT_BREAKER_FILE=".specweave/state/.hook-circuit-breaker"
|
|
72
|
+
CIRCUIT_BREAKER_THRESHOLD=3
|
|
73
|
+
|
|
74
|
+
mkdir -p ".specweave/state" 2>/dev/null || true
|
|
75
|
+
|
|
76
|
+
if [[ -f "$CIRCUIT_BREAKER_FILE" ]]; then
|
|
77
|
+
FAILURE_COUNT=$(cat "$CIRCUIT_BREAKER_FILE" 2>/dev/null || echo 0)
|
|
78
|
+
if (( FAILURE_COUNT >= CIRCUIT_BREAKER_THRESHOLD )); then
|
|
79
|
+
# Circuit breaker is OPEN - hooks are disabled
|
|
80
|
+
exit 0
|
|
81
|
+
fi
|
|
82
|
+
fi
|
|
83
|
+
|
|
84
|
+
# FILE LOCK: Only allow 1 post-task-completion hook at a time
|
|
85
|
+
LOCK_FILE=".specweave/state/.hook-post-task.lock"
|
|
86
|
+
LOCK_TIMEOUT=10 # seconds (longer than others because this does more work)
|
|
87
|
+
|
|
88
|
+
LOCK_ACQUIRED=false
|
|
89
|
+
for i in {1..10}; do
|
|
90
|
+
if mkdir "$LOCK_FILE" 2>/dev/null; then
|
|
91
|
+
LOCK_ACQUIRED=true
|
|
92
|
+
trap 'rmdir "$LOCK_FILE" 2>/dev/null || true' EXIT
|
|
93
|
+
break
|
|
94
|
+
fi
|
|
95
|
+
|
|
96
|
+
# Check for stale lock
|
|
97
|
+
if [[ -d "$LOCK_FILE" ]]; then
|
|
98
|
+
LOCK_AGE=$(($(date +%s) - $(stat -f "%m" "$LOCK_FILE" 2>/dev/null || echo 0)))
|
|
99
|
+
if (( LOCK_AGE > LOCK_TIMEOUT )); then
|
|
100
|
+
rmdir "$LOCK_FILE" 2>/dev/null || true
|
|
101
|
+
continue
|
|
102
|
+
fi
|
|
103
|
+
fi
|
|
104
|
+
|
|
105
|
+
sleep 0.2
|
|
106
|
+
done
|
|
107
|
+
|
|
108
|
+
if [[ "$LOCK_ACQUIRED" == "false" ]]; then
|
|
109
|
+
# Another instance is running, skip
|
|
110
|
+
exit 0
|
|
111
|
+
fi
|
|
112
|
+
|
|
53
113
|
# ============================================================================
|
|
54
114
|
# CONFIGURATION
|
|
55
115
|
# ============================================================================
|
|
56
116
|
|
|
57
117
|
# Debounce window to prevent duplicate hook fires
|
|
58
|
-
|
|
118
|
+
# AGGRESSIVE: 5 seconds to prevent rapid-fire executions
|
|
119
|
+
DEBOUNCE_SECONDS=5
|
|
59
120
|
|
|
60
121
|
# Inactivity threshold to detect session end
|
|
61
122
|
# If gap between TodoWrite calls > this value, assume session is ending
|
|
62
|
-
INACTIVITY_THRESHOLD=
|
|
123
|
+
INACTIVITY_THRESHOLD=120 # seconds (2 minutes - increased from 15s to reduce false positives)
|
|
63
124
|
|
|
64
125
|
# File paths
|
|
65
126
|
LOGS_DIR=".specweave/logs"
|
|
@@ -70,6 +131,13 @@ TASKS_LOG="$LOGS_DIR/tasks.log"
|
|
|
70
131
|
|
|
71
132
|
mkdir -p "$LOGS_DIR" 2>/dev/null || true
|
|
72
133
|
|
|
134
|
+
# Log rotation: Keep tasks.log under 100KB (keep last 200 lines)
|
|
135
|
+
if [[ -f "$TASKS_LOG" ]] && [[ $(wc -c < "$TASKS_LOG" 2>/dev/null || echo 0) -gt 102400 ]]; then
|
|
136
|
+
tail -200 "$TASKS_LOG" > "$TASKS_LOG.tmp" 2>/dev/null || true
|
|
137
|
+
mv "$TASKS_LOG.tmp" "$TASKS_LOG" 2>/dev/null || true
|
|
138
|
+
echo "[$(date)] Log rotated (was >100KB)" >> "$TASKS_LOG" 2>/dev/null || true
|
|
139
|
+
fi
|
|
140
|
+
|
|
73
141
|
# ============================================================================
|
|
74
142
|
# DEBOUNCING
|
|
75
143
|
# ============================================================================
|
|
@@ -173,287 +241,223 @@ else
|
|
|
173
241
|
fi
|
|
174
242
|
|
|
175
243
|
# ============================================================================
|
|
176
|
-
#
|
|
244
|
+
# CONSOLIDATED BACKGROUND WORK (ALL I/O OPERATIONS IN SINGLE PROCESS)
|
|
177
245
|
# ============================================================================
|
|
246
|
+
# EMERGENCY FIX: Instead of spawning 6+ separate Node.js processes, consolidate
|
|
247
|
+
# ALL background work into a single background job with complete error isolation
|
|
248
|
+
# This prevents process exhaustion that causes Claude Code crashes
|
|
178
249
|
|
|
179
|
-
|
|
180
|
-
#
|
|
181
|
-
CURRENT_INCREMENT=$(ls -t .specweave/increments/ 2>/dev/null | grep -v "_backlog" | grep -v "_archive" | grep -v "_working" | head -1)
|
|
250
|
+
(
|
|
251
|
+
set +e # Disable error propagation in background job
|
|
182
252
|
|
|
183
|
-
|
|
184
|
-
|
|
253
|
+
# Detect current increment ONCE
|
|
254
|
+
CURRENT_INCREMENT=$(ls -td .specweave/increments/*/ 2>/dev/null | xargs -n1 basename | grep -v "_backlog" | grep -v "_archive" | grep -v "_working" | head -1)
|
|
185
255
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
else
|
|
191
|
-
echo "[$(date)] ℹ️ No current increment or tasks.md found, skipping tasks.md update" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
256
|
+
if [[ -z "$CURRENT_INCREMENT" ]]; then
|
|
257
|
+
echo "[$(date)] No active increment, skipping all background work" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
258
|
+
echo "0" > "$CIRCUIT_BREAKER_FILE" 2>/dev/null || true # Reset on success
|
|
259
|
+
exit 0
|
|
192
260
|
fi
|
|
193
|
-
else
|
|
194
|
-
echo "[$(date)] ⚠️ Node.js not found, skipping tasks.md update" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
195
|
-
fi
|
|
196
261
|
|
|
197
|
-
|
|
198
|
-
# SYNC LIVING DOCS (NEW in v0.6.1)
|
|
199
|
-
# ============================================================================
|
|
262
|
+
echo "[$(date)] Starting consolidated background work for $CURRENT_INCREMENT" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
200
263
|
|
|
201
|
-
|
|
202
|
-
if
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
264
|
+
# Only proceed if Node.js is available
|
|
265
|
+
if ! command -v node &> /dev/null; then
|
|
266
|
+
echo "[$(date)] Node.js not found, skipping background work" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
267
|
+
echo "0" > "$CIRCUIT_BREAKER_FILE" 2>/dev/null || true
|
|
268
|
+
exit 0
|
|
269
|
+
fi
|
|
270
|
+
|
|
271
|
+
# Track if ANY operation succeeded (for circuit breaker)
|
|
272
|
+
ANY_SUCCESS=false
|
|
273
|
+
|
|
274
|
+
# ============================================================================
|
|
275
|
+
# 1. UPDATE TASKS.MD
|
|
276
|
+
# ============================================================================
|
|
277
|
+
if [ -f ".specweave/increments/$CURRENT_INCREMENT/tasks.md" ]; then
|
|
278
|
+
echo "[$(date)] 📝 Updating tasks.md" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
279
|
+
|
|
280
|
+
UPDATE_TASKS_SCRIPT=""
|
|
281
|
+
if [ -f "$PROJECT_ROOT/plugins/specweave/lib/hooks/update-tasks-md.js" ]; then
|
|
282
|
+
UPDATE_TASKS_SCRIPT="$PROJECT_ROOT/plugins/specweave/lib/hooks/update-tasks-md.js"
|
|
283
|
+
elif [ -f "$PROJECT_ROOT/dist/plugins/specweave/lib/hooks/update-tasks-md.js" ]; then
|
|
284
|
+
UPDATE_TASKS_SCRIPT="$PROJECT_ROOT/dist/plugins/specweave/lib/hooks/update-tasks-md.js"
|
|
285
|
+
elif [ -f "$PROJECT_ROOT/node_modules/specweave/dist/plugins/specweave/lib/hooks/update-tasks-md.js" ]; then
|
|
286
|
+
UPDATE_TASKS_SCRIPT="$PROJECT_ROOT/node_modules/specweave/dist/plugins/specweave/lib/hooks/update-tasks-md.js"
|
|
287
|
+
elif [ -n "${CLAUDE_PLUGIN_ROOT:-}" ] && [ -f "${CLAUDE_PLUGIN_ROOT}/lib/hooks/update-tasks-md.js" ]; then
|
|
288
|
+
UPDATE_TASKS_SCRIPT="${CLAUDE_PLUGIN_ROOT}/lib/hooks/update-tasks-md.js"
|
|
289
|
+
fi
|
|
290
|
+
|
|
291
|
+
if [ -n "$UPDATE_TASKS_SCRIPT" ]; then
|
|
292
|
+
if node "$UPDATE_TASKS_SCRIPT" "$CURRENT_INCREMENT" >> "$DEBUG_LOG" 2>&1; then
|
|
293
|
+
echo "[$(date)] ✅ tasks.md updated" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
294
|
+
ANY_SUCCESS=true
|
|
295
|
+
else
|
|
296
|
+
echo "[$(date)] ⚠️ tasks.md update failed (non-blocking)" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
297
|
+
fi
|
|
298
|
+
fi
|
|
299
|
+
fi
|
|
213
300
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
301
|
+
# ============================================================================
|
|
302
|
+
# 2. SYNC LIVING DOCS
|
|
303
|
+
# ============================================================================
|
|
304
|
+
# Skip if increment is archived
|
|
305
|
+
if [ ! -d ".specweave/increments/_archive/$CURRENT_INCREMENT" ]; then
|
|
306
|
+
echo "[$(date)] 📚 Syncing living docs" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
220
307
|
|
|
308
|
+
# Extract feature ID and project ID
|
|
221
309
|
FEATURE_ID=""
|
|
222
310
|
SPEC_MD_PATH=".specweave/increments/$CURRENT_INCREMENT/spec.md"
|
|
223
311
|
|
|
224
312
|
if [ -f "$SPEC_MD_PATH" ]; then
|
|
225
|
-
|
|
226
|
-
FEATURE_ID=$(awk '
|
|
227
|
-
BEGIN { in_frontmatter=0 }
|
|
228
|
-
/^---$/ {
|
|
229
|
-
if (in_frontmatter == 0) {
|
|
230
|
-
in_frontmatter=1; next
|
|
231
|
-
} else {
|
|
232
|
-
exit
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
in_frontmatter == 1 && /^epic:/ {
|
|
236
|
-
gsub(/^epic:[ \t]*/, "");
|
|
237
|
-
gsub(/["'\'']/, "");
|
|
238
|
-
print;
|
|
239
|
-
exit
|
|
240
|
-
}
|
|
241
|
-
' "$SPEC_MD_PATH" | tr -d '\r\n')
|
|
242
|
-
|
|
243
|
-
if [ -n "$FEATURE_ID" ]; then
|
|
244
|
-
echo "[$(date)] 📎 Extracted feature ID from spec.md: $FEATURE_ID" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
245
|
-
else
|
|
246
|
-
echo "[$(date)] ⚠️ No epic field found in spec.md frontmatter" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
247
|
-
echo "[$(date)] ℹ️ Sync will auto-generate feature ID from increment number" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
248
|
-
fi
|
|
249
|
-
else
|
|
250
|
-
echo "[$(date)] ⚠️ spec.md not found at $SPEC_MD_PATH" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
313
|
+
FEATURE_ID=$(awk 'BEGIN{in_fm=0}/^---$/{if(in_fm==0){in_fm=1;next}else{exit}}in_fm==1&&/^epic:/{gsub(/^epic:[ \t]*/,"");gsub(/["'\'']/,"");print;exit}' "$SPEC_MD_PATH" | tr -d '\r\n')
|
|
251
314
|
fi
|
|
252
315
|
|
|
253
|
-
# Extract project ID from config or metadata (defaults to "default")
|
|
254
316
|
PROJECT_ID="default"
|
|
255
|
-
if [ -f ".specweave/config.json" ]; then
|
|
256
|
-
|
|
257
|
-
if
|
|
258
|
-
ACTIVE_PROJECT
|
|
259
|
-
if [ -n "$ACTIVE_PROJECT" ] && [ "$ACTIVE_PROJECT" != "null" ]; then
|
|
260
|
-
PROJECT_ID="$ACTIVE_PROJECT"
|
|
261
|
-
fi
|
|
317
|
+
if [ -f ".specweave/config.json" ] && command -v jq >/dev/null 2>&1; then
|
|
318
|
+
ACTIVE_PROJECT=$(jq -r '.activeProject // "default"' ".specweave/config.json" 2>/dev/null || echo "default")
|
|
319
|
+
if [ -n "$ACTIVE_PROJECT" ] && [ "$ACTIVE_PROJECT" != "null" ]; then
|
|
320
|
+
PROJECT_ID="$ACTIVE_PROJECT"
|
|
262
321
|
fi
|
|
263
322
|
fi
|
|
264
|
-
echo "[$(date)] 📁 Project ID: $PROJECT_ID" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
265
323
|
|
|
266
|
-
#
|
|
324
|
+
# Find sync script
|
|
267
325
|
SYNC_SCRIPT=""
|
|
268
326
|
if [ -f "$PROJECT_ROOT/plugins/specweave/lib/hooks/sync-living-docs.js" ]; then
|
|
269
|
-
# Development: Use in-place compiled hooks (esbuild, not tsc)
|
|
270
327
|
SYNC_SCRIPT="$PROJECT_ROOT/plugins/specweave/lib/hooks/sync-living-docs.js"
|
|
271
|
-
echo "[$(date)] Using in-place compiled hook: $SYNC_SCRIPT" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
272
328
|
elif [ -f "$PROJECT_ROOT/dist/plugins/specweave/lib/hooks/sync-living-docs.js" ]; then
|
|
273
|
-
# Development: Use project's compiled files (has node_modules)
|
|
274
329
|
SYNC_SCRIPT="$PROJECT_ROOT/dist/plugins/specweave/lib/hooks/sync-living-docs.js"
|
|
275
|
-
echo "[$(date)] Using local dist: $SYNC_SCRIPT" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
276
330
|
elif [ -f "$PROJECT_ROOT/node_modules/specweave/dist/plugins/specweave/lib/hooks/sync-living-docs.js" ]; then
|
|
277
|
-
# Installed as dependency: Use node_modules version
|
|
278
331
|
SYNC_SCRIPT="$PROJECT_ROOT/node_modules/specweave/dist/plugins/specweave/lib/hooks/sync-living-docs.js"
|
|
279
|
-
echo "[$(date)] Using node_modules: $SYNC_SCRIPT" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
280
332
|
elif [ -n "${CLAUDE_PLUGIN_ROOT}" ] && [ -f "${CLAUDE_PLUGIN_ROOT}/lib/hooks/sync-living-docs.js" ]; then
|
|
281
|
-
# Fallback: Plugin marketplace (may fail if deps missing)
|
|
282
333
|
SYNC_SCRIPT="${CLAUDE_PLUGIN_ROOT}/lib/hooks/sync-living-docs.js"
|
|
283
|
-
echo "[$(date)] Using plugin marketplace: $SYNC_SCRIPT" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
284
334
|
fi
|
|
285
335
|
|
|
286
336
|
if [ -n "$SYNC_SCRIPT" ]; then
|
|
287
|
-
# Run living docs sync with feature ID (non-blocking, best-effort)
|
|
288
|
-
# Pass FEATURE_ID and PROJECT_ID as environment variables if available
|
|
289
337
|
if [ -n "$FEATURE_ID" ]; then
|
|
290
|
-
(cd "$PROJECT_ROOT" && FEATURE_ID="$FEATURE_ID" PROJECT_ID="$PROJECT_ID" node "$SYNC_SCRIPT" "$CURRENT_INCREMENT")
|
|
291
|
-
echo "[$(date)]
|
|
292
|
-
|
|
338
|
+
if (cd "$PROJECT_ROOT" && FEATURE_ID="$FEATURE_ID" PROJECT_ID="$PROJECT_ID" node "$SYNC_SCRIPT" "$CURRENT_INCREMENT") >> "$DEBUG_LOG" 2>&1; then
|
|
339
|
+
echo "[$(date)] ✅ Living docs synced" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
340
|
+
ANY_SUCCESS=true
|
|
341
|
+
else
|
|
342
|
+
echo "[$(date)] ⚠️ Living docs sync failed (non-blocking)" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
343
|
+
fi
|
|
293
344
|
else
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
345
|
+
if (cd "$PROJECT_ROOT" && PROJECT_ID="$PROJECT_ID" node "$SYNC_SCRIPT" "$CURRENT_INCREMENT") >> "$DEBUG_LOG" 2>&1; then
|
|
346
|
+
echo "[$(date)] ✅ Living docs synced" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
347
|
+
ANY_SUCCESS=true
|
|
348
|
+
else
|
|
349
|
+
echo "[$(date)] ⚠️ Living docs sync failed (non-blocking)" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
350
|
+
fi
|
|
298
351
|
fi
|
|
299
|
-
else
|
|
300
|
-
echo "[$(date)] ⚠️ sync-living-docs.js not found in any location" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
301
352
|
fi
|
|
302
|
-
fi # Close the archive check 'else' block
|
|
303
353
|
fi
|
|
304
|
-
fi
|
|
305
354
|
|
|
306
|
-
# ============================================================================
|
|
307
|
-
# UPDATE AC STATUS
|
|
308
|
-
# ============================================================================
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
UPDATE_AC_SCRIPT=""
|
|
320
|
-
|
|
321
|
-
# Development: Use in-place compiled hooks (esbuild, not tsc)
|
|
322
|
-
UPDATE_AC_SCRIPT="$PROJECT_ROOT/plugins/specweave/lib/hooks/update-ac-status.js"
|
|
323
|
-
echo "[$(date)] Using in-place compiled hook: $UPDATE_AC_SCRIPT" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
324
|
-
elif [ -f "$PROJECT_ROOT/dist/plugins/specweave/lib/hooks/update-ac-status.js" ]; then
|
|
325
|
-
# Development: Use project's compiled files (has node_modules)
|
|
326
|
-
UPDATE_AC_SCRIPT="$PROJECT_ROOT/dist/plugins/specweave/lib/hooks/update-ac-status.js"
|
|
327
|
-
echo "[$(date)] Using local dist: $UPDATE_AC_SCRIPT" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
328
|
-
elif [ -f "$PROJECT_ROOT/node_modules/specweave/dist/plugins/specweave/lib/hooks/update-ac-status.js" ]; then
|
|
329
|
-
# Installed as dependency: Use node_modules version
|
|
330
|
-
UPDATE_AC_SCRIPT="$PROJECT_ROOT/node_modules/specweave/dist/plugins/specweave/lib/hooks/update-ac-status.js"
|
|
331
|
-
echo "[$(date)] Using node_modules: $UPDATE_AC_SCRIPT" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
332
|
-
elif [ -n "${CLAUDE_PLUGIN_ROOT}" ] && [ -f "${CLAUDE_PLUGIN_ROOT}/lib/hooks/update-ac-status.js" ]; then
|
|
333
|
-
# Fallback: Plugin marketplace (may fail if deps missing)
|
|
334
|
-
UPDATE_AC_SCRIPT="${CLAUDE_PLUGIN_ROOT}/lib/hooks/update-ac-status.js"
|
|
335
|
-
echo "[$(date)] Using plugin marketplace: $UPDATE_AC_SCRIPT" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
336
|
-
fi
|
|
355
|
+
# ============================================================================
|
|
356
|
+
# 3. UPDATE AC STATUS
|
|
357
|
+
# ============================================================================
|
|
358
|
+
echo "[$(date)] ✓ Updating AC status" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
359
|
+
|
|
360
|
+
UPDATE_AC_SCRIPT=""
|
|
361
|
+
if [ -f "$PROJECT_ROOT/plugins/specweave/lib/hooks/update-ac-status.js" ]; then
|
|
362
|
+
UPDATE_AC_SCRIPT="$PROJECT_ROOT/plugins/specweave/lib/hooks/update-ac-status.js"
|
|
363
|
+
elif [ -f "$PROJECT_ROOT/dist/plugins/specweave/lib/hooks/update-ac-status.js" ]; then
|
|
364
|
+
UPDATE_AC_SCRIPT="$PROJECT_ROOT/dist/plugins/specweave/lib/hooks/update-ac-status.js"
|
|
365
|
+
elif [ -f "$PROJECT_ROOT/node_modules/specweave/dist/plugins/specweave/lib/hooks/update-ac-status.js" ]; then
|
|
366
|
+
UPDATE_AC_SCRIPT="$PROJECT_ROOT/node_modules/specweave/dist/plugins/specweave/lib/hooks/update-ac-status.js"
|
|
367
|
+
elif [ -n "${CLAUDE_PLUGIN_ROOT}" ] && [ -f "${CLAUDE_PLUGIN_ROOT}/lib/hooks/update-ac-status.js" ]; then
|
|
368
|
+
UPDATE_AC_SCRIPT="${CLAUDE_PLUGIN_ROOT}/lib/hooks/update-ac-status.js"
|
|
369
|
+
fi
|
|
337
370
|
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
}
|
|
371
|
+
if [ -n "$UPDATE_AC_SCRIPT" ]; then
|
|
372
|
+
if (cd "$PROJECT_ROOT" && node "$UPDATE_AC_SCRIPT" "$CURRENT_INCREMENT") >> "$DEBUG_LOG" 2>&1; then
|
|
373
|
+
echo "[$(date)] ✅ AC status updated" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
374
|
+
ANY_SUCCESS=true
|
|
343
375
|
else
|
|
344
|
-
echo "[$(date)] ⚠️
|
|
376
|
+
echo "[$(date)] ⚠️ AC status update failed (non-blocking)" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
345
377
|
fi
|
|
346
378
|
fi
|
|
347
|
-
fi
|
|
348
|
-
|
|
349
|
-
# ============================================================================
|
|
350
|
-
# TRANSLATE LIVING DOCS (NEW in v0.6.0 - i18n)
|
|
351
|
-
# ============================================================================
|
|
352
379
|
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
# Installed as dependency: Use node_modules version
|
|
369
|
-
TRANSLATE_SCRIPT="$PROJECT_ROOT/node_modules/specweave/dist/plugins/specweave/lib/hooks/translate-living-docs.js"
|
|
370
|
-
echo "[$(date)] Using node_modules: $TRANSLATE_SCRIPT" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
371
|
-
elif [ -n "${CLAUDE_PLUGIN_ROOT}" ] && [ -f "${CLAUDE_PLUGIN_ROOT}/lib/hooks/translate-living-docs.js" ]; then
|
|
372
|
-
# Fallback: Plugin marketplace (may fail if deps missing)
|
|
373
|
-
TRANSLATE_SCRIPT="${CLAUDE_PLUGIN_ROOT}/lib/hooks/translate-living-docs.js"
|
|
374
|
-
echo "[$(date)] Using plugin marketplace: $TRANSLATE_SCRIPT" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
375
|
-
fi
|
|
380
|
+
# ============================================================================
|
|
381
|
+
# 4. TRANSLATE LIVING DOCS (if needed)
|
|
382
|
+
# ============================================================================
|
|
383
|
+
echo "[$(date)] 🌐 Checking translation needs" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
384
|
+
|
|
385
|
+
TRANSLATE_SCRIPT=""
|
|
386
|
+
if [ -f "$PROJECT_ROOT/plugins/specweave/lib/hooks/translate-living-docs.js" ]; then
|
|
387
|
+
TRANSLATE_SCRIPT="$PROJECT_ROOT/plugins/specweave/lib/hooks/translate-living-docs.js"
|
|
388
|
+
elif [ -f "$PROJECT_ROOT/dist/plugins/specweave/lib/hooks/translate-living-docs.js" ]; then
|
|
389
|
+
TRANSLATE_SCRIPT="$PROJECT_ROOT/dist/plugins/specweave/lib/hooks/translate-living-docs.js"
|
|
390
|
+
elif [ -f "$PROJECT_ROOT/node_modules/specweave/dist/plugins/specweave/lib/hooks/translate-living-docs.js" ]; then
|
|
391
|
+
TRANSLATE_SCRIPT="$PROJECT_ROOT/node_modules/specweave/dist/plugins/specweave/lib/hooks/translate-living-docs.js"
|
|
392
|
+
elif [ -n "${CLAUDE_PLUGIN_ROOT}" ] && [ -f "${CLAUDE_PLUGIN_ROOT}/lib/hooks/translate-living-docs.js" ]; then
|
|
393
|
+
TRANSLATE_SCRIPT="${CLAUDE_PLUGIN_ROOT}/lib/hooks/translate-living-docs.js"
|
|
394
|
+
fi
|
|
376
395
|
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
}
|
|
382
|
-
else
|
|
383
|
-
echo "[$(date)] ⚠️ translate-living-docs.js not found in any location" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
396
|
+
if [ -n "$TRANSLATE_SCRIPT" ]; then
|
|
397
|
+
if (cd "$PROJECT_ROOT" && node "$TRANSLATE_SCRIPT" "$CURRENT_INCREMENT") >> "$DEBUG_LOG" 2>&1; then
|
|
398
|
+
echo "[$(date)] ✅ Translation checked" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
399
|
+
ANY_SUCCESS=true
|
|
384
400
|
fi
|
|
385
401
|
fi
|
|
386
|
-
fi
|
|
387
|
-
|
|
388
|
-
# ============================================================================
|
|
389
|
-
# EXTERNAL TRACKER SYNC (REMOVED in v0.13.0 - Moved to Plugin Hooks)
|
|
390
|
-
# ============================================================================
|
|
391
|
-
#
|
|
392
|
-
# External tool sync logic has been moved to respective plugin hooks:
|
|
393
|
-
# - GitHub sync: plugins/specweave-github/hooks/post-task-completion.sh
|
|
394
|
-
# - JIRA sync: plugins/specweave-jira/hooks/post-task-completion.sh
|
|
395
|
-
# - Azure DevOps sync: plugins/specweave-ado/hooks/post-task-completion.sh
|
|
396
|
-
#
|
|
397
|
-
# When multiple plugins are installed, Claude Code fires all hooks in parallel.
|
|
398
|
-
# This architecture provides:
|
|
399
|
-
# - Clean separation of concerns (core vs. external tools)
|
|
400
|
-
# - Optional plugins (GitHub sync only runs if specweave-github installed)
|
|
401
|
-
# - Independent testing and maintenance
|
|
402
|
-
# - No external tool dependencies in core plugin
|
|
403
|
-
#
|
|
404
|
-
# See: .specweave/increments/0018-strict-increment-discipline-enforcement/reports/HOOKS-ARCHITECTURE-ANALYSIS.md
|
|
405
|
-
|
|
406
|
-
echo "[$(date)] ℹ️ External tracker sync moved to plugin hooks (GitHub/JIRA/ADO)" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
407
402
|
|
|
408
|
-
# ============================================================================
|
|
409
|
-
# SELF-REFLECTION (
|
|
410
|
-
# ============================================================================
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
if [ -n "$CURRENT_INCREMENT" ] && [ "$ALL_COMPLETED" = "true" ]; then
|
|
414
|
-
echo "[$(date)] 🤔 Preparing self-reflection context for $CURRENT_INCREMENT" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
403
|
+
# ============================================================================
|
|
404
|
+
# 5. SELF-REFLECTION (only if all tasks complete)
|
|
405
|
+
# ============================================================================
|
|
406
|
+
if [ "$ALL_COMPLETED" = "true" ]; then
|
|
407
|
+
echo "[$(date)] 🤔 Preparing reflection" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
415
408
|
|
|
416
|
-
# Detect latest completed task
|
|
417
409
|
LATEST_TASK=$(grep "^## T-[0-9]" ".specweave/increments/$CURRENT_INCREMENT/tasks.md" 2>/dev/null | tail -1 | awk '{print $2}' | sed 's/://')
|
|
418
410
|
|
|
419
411
|
if [ -n "$LATEST_TASK" ]; then
|
|
420
|
-
# Determine which reflection script to use (project local or global)
|
|
421
412
|
REFLECTION_SCRIPT=""
|
|
422
413
|
if [ -f "$PROJECT_ROOT/plugins/specweave/lib/hooks/prepare-reflection-context.js" ]; then
|
|
423
|
-
# Development: Use in-place compiled hooks (esbuild, not tsc)
|
|
424
414
|
REFLECTION_SCRIPT="$PROJECT_ROOT/plugins/specweave/lib/hooks/prepare-reflection-context.js"
|
|
425
|
-
echo "[$(date)] Using in-place compiled hook: $REFLECTION_SCRIPT" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
426
415
|
elif [ -f "$PROJECT_ROOT/dist/plugins/specweave/lib/hooks/prepare-reflection-context.js" ]; then
|
|
427
|
-
# Development: Use project's compiled files (has node_modules)
|
|
428
416
|
REFLECTION_SCRIPT="$PROJECT_ROOT/dist/plugins/specweave/lib/hooks/prepare-reflection-context.js"
|
|
429
|
-
echo "[$(date)] Using local dist: $REFLECTION_SCRIPT" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
430
417
|
elif [ -f "$PROJECT_ROOT/node_modules/specweave/dist/plugins/specweave/lib/hooks/prepare-reflection-context.js" ]; then
|
|
431
|
-
# Installed as dependency: Use node_modules version
|
|
432
418
|
REFLECTION_SCRIPT="$PROJECT_ROOT/node_modules/specweave/dist/plugins/specweave/lib/hooks/prepare-reflection-context.js"
|
|
433
|
-
echo "[$(date)] Using node_modules: $REFLECTION_SCRIPT" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
434
419
|
elif [ -n "${CLAUDE_PLUGIN_ROOT}" ] && [ -f "${CLAUDE_PLUGIN_ROOT}/lib/hooks/prepare-reflection-context.js" ]; then
|
|
435
|
-
# Fallback: Plugin marketplace (may fail if deps missing)
|
|
436
420
|
REFLECTION_SCRIPT="${CLAUDE_PLUGIN_ROOT}/lib/hooks/prepare-reflection-context.js"
|
|
437
|
-
echo "[$(date)] Using plugin marketplace: $REFLECTION_SCRIPT" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
438
421
|
fi
|
|
439
422
|
|
|
440
423
|
if [ -n "$REFLECTION_SCRIPT" ]; then
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
else
|
|
446
|
-
echo "[$(date)] ⚠️ prepare-reflection-context.js not found in any location" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
424
|
+
if (cd "$PROJECT_ROOT" && node "$REFLECTION_SCRIPT" "$CURRENT_INCREMENT" "$LATEST_TASK") >> "$DEBUG_LOG" 2>&1; then
|
|
425
|
+
echo "[$(date)] ✅ Reflection prepared" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
426
|
+
ANY_SUCCESS=true
|
|
427
|
+
fi
|
|
447
428
|
fi
|
|
448
|
-
else
|
|
449
|
-
echo "[$(date)] ℹ️ No tasks found in tasks.md, skipping reflection" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
450
429
|
fi
|
|
430
|
+
fi
|
|
431
|
+
|
|
432
|
+
# ============================================================================
|
|
433
|
+
# 6. STATUS LINE UPDATE
|
|
434
|
+
# ============================================================================
|
|
435
|
+
echo "[$(date)] 📊 Updating status line" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
436
|
+
|
|
437
|
+
HOOK_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
438
|
+
if bash "$HOOK_DIR/lib/update-status-line.sh" >> "$DEBUG_LOG" 2>&1; then
|
|
439
|
+
echo "[$(date)] ✅ Status line updated" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
440
|
+
ANY_SUCCESS=true
|
|
451
441
|
else
|
|
452
|
-
echo "[$(date)]
|
|
442
|
+
echo "[$(date)] ⚠️ Status line update failed (non-blocking)" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
453
443
|
fi
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
444
|
+
|
|
445
|
+
# ============================================================================
|
|
446
|
+
# CIRCUIT BREAKER UPDATE
|
|
447
|
+
# ============================================================================
|
|
448
|
+
if [ "$ANY_SUCCESS" = "true" ]; then
|
|
449
|
+
echo "0" > "$CIRCUIT_BREAKER_FILE" 2>/dev/null || true
|
|
450
|
+
else
|
|
451
|
+
CURRENT_FAILURES=$(cat "$CIRCUIT_BREAKER_FILE" 2>/dev/null || echo 0)
|
|
452
|
+
echo "$((CURRENT_FAILURES + 1))" > "$CIRCUIT_BREAKER_FILE" 2>/dev/null || true
|
|
453
|
+
fi
|
|
454
|
+
|
|
455
|
+
echo "[$(date)] Consolidated background work completed (success=$ANY_SUCCESS)" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
456
|
+
|
|
457
|
+
) &
|
|
458
|
+
|
|
459
|
+
# Disown background process immediately
|
|
460
|
+
disown 2>/dev/null || true
|
|
457
461
|
|
|
458
462
|
# ============================================================================
|
|
459
463
|
# PLAY SOUND (only if session is truly ending)
|
|
@@ -474,16 +478,6 @@ play_sound() {
|
|
|
474
478
|
esac
|
|
475
479
|
}
|
|
476
480
|
|
|
477
|
-
# ============================================================================
|
|
478
|
-
# STATUS LINE UPDATE
|
|
479
|
-
# ============================================================================
|
|
480
|
-
# Update status line cache BEFORE playing sound (async, non-blocking)
|
|
481
|
-
# Cache will be read by status line renderer for fast display (<1ms)
|
|
482
|
-
|
|
483
|
-
echo "[$(date)] 📊 Updating status line cache" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
484
|
-
HOOK_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
485
|
-
bash "$HOOK_DIR/lib/update-status-line.sh" 2>/dev/null || true
|
|
486
|
-
|
|
487
481
|
if [ "$SESSION_ENDING" = "true" ]; then
|
|
488
482
|
echo "[$(date)] 🔔 Playing completion sound" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
489
483
|
play_sound
|
|
@@ -523,3 +517,6 @@ else
|
|
|
523
517
|
}
|
|
524
518
|
EOF
|
|
525
519
|
fi
|
|
520
|
+
|
|
521
|
+
# ALWAYS exit 0 - NEVER let hook errors crash Claude Code
|
|
522
|
+
exit 0
|