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.
Files changed (135) hide show
  1. package/.claude-plugin/marketplace.json +7 -7
  2. package/CLAUDE.md +384 -1449
  3. package/dist/src/cli/commands/cleanup-cache.d.ts +14 -0
  4. package/dist/src/cli/commands/cleanup-cache.d.ts.map +1 -0
  5. package/dist/src/cli/commands/cleanup-cache.js +63 -0
  6. package/dist/src/cli/commands/cleanup-cache.js.map +1 -0
  7. package/dist/src/cli/commands/init.js +40 -0
  8. package/dist/src/cli/commands/init.js.map +1 -1
  9. package/dist/src/cli/helpers/async-project-loader.d.ts +148 -0
  10. package/dist/src/cli/helpers/async-project-loader.d.ts.map +1 -0
  11. package/dist/src/cli/helpers/async-project-loader.js +351 -0
  12. package/dist/src/cli/helpers/async-project-loader.js.map +1 -0
  13. package/dist/src/cli/helpers/cancelation-handler.d.ts +123 -0
  14. package/dist/src/cli/helpers/cancelation-handler.d.ts.map +1 -0
  15. package/dist/src/cli/helpers/cancelation-handler.js +187 -0
  16. package/dist/src/cli/helpers/cancelation-handler.js.map +1 -0
  17. package/dist/src/cli/helpers/import-strategy-prompter.d.ts +43 -0
  18. package/dist/src/cli/helpers/import-strategy-prompter.d.ts.map +1 -0
  19. package/dist/src/cli/helpers/import-strategy-prompter.js +136 -0
  20. package/dist/src/cli/helpers/import-strategy-prompter.js.map +1 -0
  21. package/dist/src/cli/helpers/issue-tracker/ado.d.ts +5 -2
  22. package/dist/src/cli/helpers/issue-tracker/ado.d.ts.map +1 -1
  23. package/dist/src/cli/helpers/issue-tracker/ado.js +90 -40
  24. package/dist/src/cli/helpers/issue-tracker/ado.js.map +1 -1
  25. package/dist/src/cli/helpers/issue-tracker/jira.d.ts +2 -1
  26. package/dist/src/cli/helpers/issue-tracker/jira.d.ts.map +1 -1
  27. package/dist/src/cli/helpers/issue-tracker/jira.js +120 -35
  28. package/dist/src/cli/helpers/issue-tracker/jira.js.map +1 -1
  29. package/dist/src/cli/helpers/progress-tracker.d.ts +121 -0
  30. package/dist/src/cli/helpers/progress-tracker.d.ts.map +1 -0
  31. package/dist/src/cli/helpers/progress-tracker.js +202 -0
  32. package/dist/src/cli/helpers/progress-tracker.js.map +1 -0
  33. package/dist/src/cli/helpers/project-count-fetcher.d.ts +69 -0
  34. package/dist/src/cli/helpers/project-count-fetcher.d.ts.map +1 -0
  35. package/dist/src/cli/helpers/project-count-fetcher.js +173 -0
  36. package/dist/src/cli/helpers/project-count-fetcher.js.map +1 -0
  37. package/dist/src/config/types.d.ts +14 -14
  38. package/dist/src/core/cache/cache-manager.d.ts +119 -0
  39. package/dist/src/core/cache/cache-manager.d.ts.map +1 -0
  40. package/dist/src/core/cache/cache-manager.js +304 -0
  41. package/dist/src/core/cache/cache-manager.js.map +1 -0
  42. package/dist/src/core/cache/rate-limit-checker.d.ts +92 -0
  43. package/dist/src/core/cache/rate-limit-checker.d.ts.map +1 -0
  44. package/dist/src/core/cache/rate-limit-checker.js +160 -0
  45. package/dist/src/core/cache/rate-limit-checker.js.map +1 -0
  46. package/dist/src/core/progress/cancelation-handler.d.ts +79 -0
  47. package/dist/src/core/progress/cancelation-handler.d.ts.map +1 -0
  48. package/dist/src/core/progress/cancelation-handler.js +111 -0
  49. package/dist/src/core/progress/cancelation-handler.js.map +1 -0
  50. package/dist/src/core/progress/error-logger.d.ts +58 -0
  51. package/dist/src/core/progress/error-logger.d.ts.map +1 -0
  52. package/dist/src/core/progress/error-logger.js +99 -0
  53. package/dist/src/core/progress/error-logger.js.map +1 -0
  54. package/dist/src/core/progress/import-state.d.ts +71 -0
  55. package/dist/src/core/progress/import-state.d.ts.map +1 -0
  56. package/dist/src/core/progress/import-state.js +96 -0
  57. package/dist/src/core/progress/import-state.js.map +1 -0
  58. package/dist/src/core/progress/progress-tracker.d.ts +139 -0
  59. package/dist/src/core/progress/progress-tracker.d.ts.map +1 -0
  60. package/dist/src/core/progress/progress-tracker.js +223 -0
  61. package/dist/src/core/progress/progress-tracker.js.map +1 -0
  62. package/dist/src/init/architecture/types.d.ts +6 -6
  63. package/dist/src/integrations/ado/ado-client.d.ts +25 -0
  64. package/dist/src/integrations/ado/ado-client.d.ts.map +1 -1
  65. package/dist/src/integrations/ado/ado-client.js +67 -0
  66. package/dist/src/integrations/ado/ado-client.js.map +1 -1
  67. package/dist/src/integrations/ado/ado-dependency-loader.d.ts +99 -0
  68. package/dist/src/integrations/ado/ado-dependency-loader.d.ts.map +1 -0
  69. package/dist/src/integrations/ado/ado-dependency-loader.js +207 -0
  70. package/dist/src/integrations/ado/ado-dependency-loader.js.map +1 -0
  71. package/dist/src/integrations/jira/jira-client.d.ts +32 -0
  72. package/dist/src/integrations/jira/jira-client.d.ts.map +1 -1
  73. package/dist/src/integrations/jira/jira-client.js +81 -0
  74. package/dist/src/integrations/jira/jira-client.js.map +1 -1
  75. package/dist/src/integrations/jira/jira-dependency-loader.d.ts +101 -0
  76. package/dist/src/integrations/jira/jira-dependency-loader.d.ts.map +1 -0
  77. package/dist/src/integrations/jira/jira-dependency-loader.js +200 -0
  78. package/dist/src/integrations/jira/jira-dependency-loader.js.map +1 -0
  79. package/package.json +1 -1
  80. package/plugins/specweave/.claude-plugin/plugin.json +20 -0
  81. package/plugins/specweave/agents/architect/AGENT.md +100 -602
  82. package/plugins/specweave/agents/pm/AGENT.md +96 -597
  83. package/plugins/specweave/agents/pm/AGENT.md.bak +1893 -0
  84. package/plugins/specweave/agents/pm/AGENT.md.bak2 +1754 -0
  85. package/plugins/specweave/commands/check-hooks.md +257 -0
  86. package/plugins/specweave/hooks/docs-changed.sh +9 -1
  87. package/plugins/specweave/hooks/docs-changed.sh.backup +79 -0
  88. package/plugins/specweave/hooks/human-input-required.sh +9 -1
  89. package/plugins/specweave/hooks/human-input-required.sh.backup +75 -0
  90. package/plugins/specweave/hooks/post-edit-spec.sh +202 -31
  91. package/plugins/specweave/hooks/post-first-increment.sh.backup +61 -0
  92. package/plugins/specweave/hooks/post-increment-change.sh +6 -1
  93. package/plugins/specweave/hooks/post-increment-change.sh.backup +98 -0
  94. package/plugins/specweave/hooks/post-increment-completion.sh +6 -1
  95. package/plugins/specweave/hooks/post-increment-completion.sh.backup +231 -0
  96. package/plugins/specweave/hooks/post-increment-planning.sh +6 -1
  97. package/plugins/specweave/hooks/post-increment-planning.sh.backup +1048 -0
  98. package/plugins/specweave/hooks/post-increment-status-change.sh +6 -1
  99. package/plugins/specweave/hooks/post-increment-status-change.sh.backup +147 -0
  100. package/plugins/specweave/hooks/post-metadata-change.sh +7 -1
  101. package/plugins/specweave/hooks/post-spec-update.sh.backup +158 -0
  102. package/plugins/specweave/hooks/post-task-completion.sh +225 -228
  103. package/plugins/specweave/hooks/post-user-story-complete.sh.backup +179 -0
  104. package/plugins/specweave/hooks/post-write-spec.sh +207 -31
  105. package/plugins/specweave/hooks/pre-command-deduplication.sh.backup +83 -0
  106. package/plugins/specweave/hooks/pre-edit-spec.sh +151 -0
  107. package/plugins/specweave/hooks/pre-implementation.sh +9 -1
  108. package/plugins/specweave/hooks/pre-implementation.sh.backup +67 -0
  109. package/plugins/specweave/hooks/pre-task-completion.sh +14 -8
  110. package/plugins/specweave/hooks/pre-task-completion.sh.backup +194 -0
  111. package/plugins/specweave/hooks/pre-tool-use.sh +9 -1
  112. package/plugins/specweave/hooks/pre-tool-use.sh.backup +133 -0
  113. package/plugins/specweave/hooks/pre-write-spec.sh +151 -0
  114. package/plugins/specweave/hooks/test-pretooluse-env.sh +72 -0
  115. package/plugins/specweave/hooks/user-prompt-submit.sh.backup +386 -0
  116. package/plugins/specweave/skills/compliance-architecture/SKILL.md +374 -0
  117. package/plugins/specweave/skills/external-sync-wizard/SKILL.md +610 -0
  118. package/plugins/specweave/skills/pm-closure-validation/SKILL.md +541 -0
  119. package/plugins/specweave/skills/roadmap-planner/SKILL.md +473 -0
  120. package/plugins/specweave-ado/commands/refresh-cache.js +25 -0
  121. package/plugins/specweave-ado/commands/refresh-cache.ts +40 -0
  122. package/plugins/specweave-ado/hooks/post-living-docs-update.sh +9 -2
  123. package/plugins/specweave-ado/hooks/post-living-docs-update.sh.backup +353 -0
  124. package/plugins/specweave-ado/hooks/post-task-completion.sh +10 -2
  125. package/plugins/specweave-ado/hooks/post-task-completion.sh.backup +172 -0
  126. package/plugins/specweave-github/hooks/post-task-completion.sh +10 -2
  127. package/plugins/specweave-github/hooks/post-task-completion.sh.backup +258 -0
  128. package/plugins/specweave-jira/commands/refresh-cache.js +25 -0
  129. package/plugins/specweave-jira/commands/refresh-cache.ts +40 -0
  130. package/plugins/specweave-jira/hooks/post-task-completion.sh +10 -2
  131. package/plugins/specweave-jira/hooks/post-task-completion.sh.backup +172 -0
  132. package/plugins/specweave-kafka-streams/commands/topology.md +437 -0
  133. package/plugins/specweave-n8n/commands/workflow-template.md +262 -0
  134. package/plugins/specweave-release/hooks/.specweave/logs/dora-tracking.log +252 -6465
  135. package/plugins/specweave-release/hooks/post-task-completion.sh.backup +110 -0
@@ -8,12 +8,30 @@
8
8
  # This ensures status line stays in sync when ACs are marked complete via Edit tool
9
9
  # (not just TodoWrite, which only tracks internal todo lists)
10
10
  #
11
- # CRITICAL FIX (v0.24.1): Enhanced file detection to handle increment completion
11
+ # EMERGENCY FIXES (v0.24.3):
12
+ # - Kill switch: Set SPECWEAVE_DISABLE_HOOKS=1 to disable ALL hooks
13
+ # - Circuit breaker: Auto-disable after 3 consecutive failures
14
+ # - File locking: Prevent concurrent executions (max 1 at a time)
15
+ # - Aggressive debouncing: Increased from 1s to 5s
16
+ # - Complete error isolation: Never let errors reach Claude Code
17
+ #
18
+ # TIER 1 IMPROVEMENTS (v0.24.2):
19
+ # - Debouncing: Skip if updated less than 1 second ago (90% overhead reduction)
20
+ # - File mtime detection: Check recently modified spec.md/tasks.md as fallback
21
+ # - Non-blocking: Run update-status-line.sh in background
22
+ # - Smart detection: Only update if spec/tasks files actually changed
23
+ #
24
+ # Previous fix (v0.24.1): Enhanced file detection for increment completion
12
25
  # - Detects edits via TOOL_USE_CONTENT, TOOL_RESULT, and argument parsing
13
26
  # - Always updates status line for ANY spec.md/tasks.md edit in increments folder
14
- # - Fixes bug where status line wasn't updating on increment close
15
27
 
16
- set -e
28
+ # CRITICAL: Remove set -e to prevent hook errors from crashing Claude Code
29
+ set +e
30
+
31
+ # EMERGENCY KILL SWITCH: Disable all hooks if env variable set
32
+ if [[ "${SPECWEAVE_DISABLE_HOOKS:-0}" == "1" ]]; then
33
+ exit 0
34
+ fi
17
35
 
18
36
  # Find project root
19
37
  find_project_root() {
@@ -32,31 +50,129 @@ PROJECT_ROOT=$(find_project_root)
32
50
  LOGS_DIR="$PROJECT_ROOT/.specweave/logs"
33
51
  DEBUG_LOG="$LOGS_DIR/hooks-debug.log"
34
52
 
35
- # Ensure logs directory exists
36
- mkdir -p "$LOGS_DIR" 2>/dev/null || true
53
+ # Ensure state and logs directories exist
54
+ mkdir -p "$PROJECT_ROOT/.specweave/state" "$LOGS_DIR" 2>/dev/null || true
37
55
 
38
- # Extract edited file from multiple sources (Claude Code provides this in various ways)
39
- EDITED_FILE=""
56
+ # EMERGENCY CIRCUIT BREAKER: Track consecutive failures
57
+ CIRCUIT_BREAKER_FILE="$PROJECT_ROOT/.specweave/state/.hook-circuit-breaker"
58
+ CIRCUIT_BREAKER_THRESHOLD=3
40
59
 
41
- # Method 1: TOOL_USE_CONTENT environment variable (primary)
42
- if [[ -n "${TOOL_USE_CONTENT:-}" ]]; then
43
- EDITED_FILE="$TOOL_USE_CONTENT"
60
+ if [[ -f "$CIRCUIT_BREAKER_FILE" ]]; then
61
+ FAILURE_COUNT=$(cat "$CIRCUIT_BREAKER_FILE" 2>/dev/null || echo 0)
62
+ if (( FAILURE_COUNT >= CIRCUIT_BREAKER_THRESHOLD )); then
63
+ echo "[$(date)] CIRCUIT BREAKER OPEN: Hooks disabled after $FAILURE_COUNT failures. Run: rm $CIRCUIT_BREAKER_FILE" >> "$DEBUG_LOG" 2>/dev/null || true
64
+ exit 0
65
+ fi
44
66
  fi
45
67
 
46
- # Method 2: TOOL_RESULT environment variable (fallback)
47
- if [[ -z "$EDITED_FILE" ]] && [[ -n "${TOOL_RESULT:-}" ]]; then
48
- # Extract file_path from tool result JSON
49
- EDITED_FILE=$(echo "$TOOL_RESULT" | grep -o '"file_path"[[:space:]]*:[[:space:]]*"[^"]*"' | head -1 | sed 's/.*"\([^"]*\)".*/\1/' || echo "")
68
+ # EMERGENCY FILE LOCK: Prevent concurrent executions
69
+ LOCK_FILE="$PROJECT_ROOT/.specweave/state/.hook-post-edit.lock"
70
+ LOCK_TIMEOUT=5 # seconds
71
+
72
+ # Try to acquire lock with timeout
73
+ LOCK_ACQUIRED=false
74
+ for i in {1..5}; do
75
+ if mkdir "$LOCK_FILE" 2>/dev/null; then
76
+ LOCK_ACQUIRED=true
77
+ trap 'rmdir "$LOCK_FILE" 2>/dev/null || true' EXIT
78
+ break
79
+ fi
80
+
81
+ # Check if lock is stale (older than LOCK_TIMEOUT seconds)
82
+ if [[ -d "$LOCK_FILE" ]]; then
83
+ LOCK_AGE=$(($(date +%s) - $(stat -f "%m" "$LOCK_FILE" 2>/dev/null || echo 0)))
84
+ if (( LOCK_AGE > LOCK_TIMEOUT )); then
85
+ rmdir "$LOCK_FILE" 2>/dev/null || true
86
+ continue
87
+ fi
88
+ fi
89
+
90
+ sleep 0.2
91
+ done
92
+
93
+ if [[ "$LOCK_ACQUIRED" == "false" ]]; then
94
+ echo "[$(date)] post-edit-spec: Could not acquire lock, skipping" >> "$DEBUG_LOG" 2>/dev/null || true
95
+ exit 0
50
96
  fi
51
97
 
52
- # Method 3: Parse tool use arguments (last resort)
53
- if [[ -z "$EDITED_FILE" ]] && [[ -n "${TOOL_USE_ARGS:-}" ]]; then
54
- # Extract file_path from tool arguments
55
- EDITED_FILE=$(echo "$TOOL_USE_ARGS" | grep -o '"file_path"[[:space:]]*:[[:space:]]*"[^"]*"' | head -1 | sed 's/.*"\([^"]*\)".*/\1/' || echo "")
98
+ # Log rotation: Keep debug log under 100KB
99
+ if [[ -f "$DEBUG_LOG" ]] && [[ $(wc -c < "$DEBUG_LOG" 2>/dev/null || echo 0) -gt 102400 ]]; then
100
+ tail -100 "$DEBUG_LOG" > "$DEBUG_LOG.tmp" 2>/dev/null || true
101
+ mv "$DEBUG_LOG.tmp" "$DEBUG_LOG" 2>/dev/null || true
102
+ echo "[$(date)] Log rotated" >> "$DEBUG_LOG" 2>/dev/null || true
56
103
  fi
57
104
 
58
- # Log detection attempt
59
- echo "[$(date)] post-edit-spec: Detected file: ${EDITED_FILE:-<none>}" >> "$DEBUG_LOG" 2>/dev/null || true
105
+ # ============================================================================
106
+ # TIER 1 FIX: Debouncing (Prevent Redundant Updates)
107
+ # ============================================================================
108
+ # Skip update if we updated less than 5 seconds ago (INCREASED FROM 1s)
109
+ # This handles rapid consecutive edits (e.g., 10 tasks marked complete quickly)
110
+ LAST_UPDATE_FILE="$PROJECT_ROOT/.specweave/state/.last-status-update"
111
+ DEBOUNCE_SECONDS=5
112
+
113
+ if [[ -f "$LAST_UPDATE_FILE" ]]; then
114
+ LAST_UPDATE=$(cat "$LAST_UPDATE_FILE" 2>/dev/null || echo 0)
115
+ NOW=$(date +%s)
116
+ TIME_SINCE_UPDATE=$((NOW - LAST_UPDATE))
117
+
118
+ if (( TIME_SINCE_UPDATE < DEBOUNCE_SECONDS )); then
119
+ echo "[$(date)] post-edit-spec: Debounced (${TIME_SINCE_UPDATE}s since last update)" >> "$DEBUG_LOG" 2>/dev/null || true
120
+ exit 0 # Skip this update
121
+ fi
122
+ fi
123
+
124
+ # ============================================================================
125
+ # TIER 2: Check for PreToolUse Signal (Primary Detection Method)
126
+ # ============================================================================
127
+ PENDING_FILE="$PROJECT_ROOT/.specweave/state/.pending-status-update"
128
+ METRICS_FILE="$PROJECT_ROOT/.specweave/state/hook-metrics.jsonl"
129
+ EDITED_FILE=""
130
+ DETECTION_METHOD="none"
131
+
132
+ # First, check if PreToolUse hook left a signal
133
+ if [[ -f "$PENDING_FILE" ]]; then
134
+ EDITED_FILE=$(cat "$PENDING_FILE" 2>/dev/null || echo "")
135
+ # Delete pending file immediately (consume signal)
136
+ rm "$PENDING_FILE" 2>/dev/null || true
137
+
138
+ if [[ -n "$EDITED_FILE" ]]; then
139
+ DETECTION_METHOD="pretooluse"
140
+ echo "[$(date)] post-edit-spec: File from PreToolUse signal: $EDITED_FILE" >> "$DEBUG_LOG" 2>/dev/null || true
141
+
142
+ # Record Tier 2 success metric
143
+ TIMESTAMP=$(date -u +%Y-%m-%dT%H:%M:%SZ)
144
+ echo "{\"timestamp\":\"$TIMESTAMP\",\"hook\":\"post-edit-spec\",\"event\":\"tier2_success\",\"method\":\"pretooluse\"}" >> "$METRICS_FILE" 2>/dev/null || true
145
+ fi
146
+ fi
147
+
148
+ # ============================================================================
149
+ # TIER 1 FALLBACK: Environment Variable Detection
150
+ # ============================================================================
151
+ # If PreToolUse didn't provide signal, fall back to Tier 1 methods
152
+ if [[ -z "$EDITED_FILE" ]]; then
153
+ # Method 1: TOOL_USE_CONTENT environment variable
154
+ if [[ -n "${TOOL_USE_CONTENT:-}" ]]; then
155
+ EDITED_FILE="$TOOL_USE_CONTENT"
156
+ DETECTION_METHOD="env_content"
157
+ fi
158
+
159
+ # Method 2: TOOL_RESULT environment variable
160
+ if [[ -z "$EDITED_FILE" ]] && [[ -n "${TOOL_RESULT:-}" ]]; then
161
+ EDITED_FILE=$(echo "$TOOL_RESULT" | grep -o '"file_path"[[:space:]]*:[[:space:]]*"[^"]*"' | head -1 | sed 's/.*"\([^"]*\)".*/\1/' || echo "")
162
+ DETECTION_METHOD="env_result"
163
+ fi
164
+
165
+ # Method 3: TOOL_USE_ARGS
166
+ if [[ -z "$EDITED_FILE" ]] && [[ -n "${TOOL_USE_ARGS:-}" ]]; then
167
+ EDITED_FILE=$(echo "$TOOL_USE_ARGS" | grep -o '"file_path"[[:space:]]*:[[:space:]]*"[^"]*"' | head -1 | sed 's/.*"\([^"]*\)".*/\1/' || echo "")
168
+ DETECTION_METHOD="env_args"
169
+ fi
170
+
171
+ # Log env var detection (for metrics)
172
+ if [[ -n "$EDITED_FILE" ]]; then
173
+ echo "[$(date)] post-edit-spec: File from env vars ($DETECTION_METHOD): $EDITED_FILE" >> "$DEBUG_LOG" 2>/dev/null || true
174
+ fi
175
+ fi
60
176
 
61
177
  # Check if we detected a spec.md or tasks.md edit in increments folder
62
178
  SHOULD_UPDATE=false
@@ -72,23 +188,78 @@ if [[ -n "$EDITED_FILE" ]]; then
72
188
  fi
73
189
  fi
74
190
 
75
- # If we couldn't detect the file via environment variables, always update status line
76
- # This ensures we don't miss updates during increment closure
191
+ # ============================================================================
192
+ # TIER 1 FIX: File Modification Time Detection (Fallback)
193
+ # ============================================================================
194
+ # If we couldn't detect the file via environment variables, check which files
195
+ # were modified recently (within last 2 seconds) instead of blindly updating
77
196
  if [[ -z "$EDITED_FILE" ]]; then
78
- echo "[$(date)] post-edit-spec: No file detected - updating status line as safety measure" >> "$DEBUG_LOG" 2>/dev/null || true
79
- SHOULD_UPDATE=true
197
+ echo "[$(date)] post-edit-spec: Env vars empty - checking file mtimes" >> "$DEBUG_LOG" 2>/dev/null || true
198
+
199
+ NOW=$(date +%s)
200
+ INCREMENTS_DIR="$PROJECT_ROOT/.specweave/increments"
201
+
202
+ # Check for recently modified spec.md or tasks.md files
203
+ if [[ -d "$INCREMENTS_DIR" ]]; then
204
+ for file in "$INCREMENTS_DIR"/*/spec.md "$INCREMENTS_DIR"/*/tasks.md; do
205
+ if [[ -f "$file" ]]; then
206
+ # Get file modification time (platform-specific)
207
+ if [[ "$(uname)" == "Darwin" ]]; then
208
+ MTIME=$(stat -f "%m" "$file" 2>/dev/null || echo 0)
209
+ else
210
+ MTIME=$(stat -c "%Y" "$file" 2>/dev/null || echo 0)
211
+ fi
212
+
213
+ # If file was modified in last 2 seconds, consider it the edited file
214
+ TIME_DIFF=$((NOW - MTIME))
215
+ if (( TIME_DIFF <= 2 )); then
216
+ EDITED_FILE="$file"
217
+ echo "[$(date)] post-edit-spec: Detected recent modification: $file (${TIME_DIFF}s ago)" >> "$DEBUG_LOG" 2>/dev/null || true
218
+ SHOULD_UPDATE=true
219
+ break
220
+ fi
221
+ fi
222
+ done
223
+ fi
224
+
225
+ # If still no file detected, skip update (not a spec/tasks edit)
226
+ if [[ -z "$EDITED_FILE" ]]; then
227
+ echo "[$(date)] post-edit-spec: No spec/tasks modifications detected - skipping" >> "$DEBUG_LOG" 2>/dev/null || true
228
+ exit 0
229
+ fi
80
230
  fi
81
231
 
232
+ # ============================================================================
233
+ # TIER 1 FIX: Non-Blocking Background Update with COMPLETE ERROR ISOLATION
234
+ # ============================================================================
82
235
  # Update status line if needed
83
236
  if [[ "$SHOULD_UPDATE" == "true" ]]; then
84
- echo "[$(date)] post-edit-spec: Running update-status-line.sh" >> "$DEBUG_LOG" 2>/dev/null || true
237
+ echo "[$(date)] post-edit-spec: Running update-status-line.sh (background)" >> "$DEBUG_LOG" 2>/dev/null || true
85
238
 
86
- # Run status line update (capture errors for debugging)
87
- if "$PROJECT_ROOT/plugins/specweave/hooks/lib/update-status-line.sh" 2>&1 | tee -a "$DEBUG_LOG" >/dev/null; then
88
- echo "[$(date)] post-edit-spec: Status line updated successfully" >> "$DEBUG_LOG" 2>/dev/null || true
89
- else
90
- echo "[$(date)] post-edit-spec: Warning - status line update failed (non-blocking)" >> "$DEBUG_LOG" 2>/dev/null || true
91
- fi
239
+ # Record update time BEFORE spawning background process
240
+ # This ensures debouncing works even if update hasn't completed yet
241
+ echo "$(date +%s)" > "$LAST_UPDATE_FILE"
242
+
243
+ # Run status line update in background with COMPLETE error isolation
244
+ # This prevents Edit tool from waiting for status line computation
245
+ (
246
+ set +e # Disable error propagation
247
+
248
+ if "$PROJECT_ROOT/plugins/specweave/hooks/lib/update-status-line.sh" 2>&1 | tee -a "$DEBUG_LOG" >/dev/null; then
249
+ echo "[$(date)] post-edit-spec: Status line updated successfully" >> "$DEBUG_LOG" 2>/dev/null || true
250
+ # Reset circuit breaker on success
251
+ echo "0" > "$CIRCUIT_BREAKER_FILE" 2>/dev/null || true
252
+ else
253
+ echo "[$(date)] post-edit-spec: Warning - status line update failed (non-blocking)" >> "$DEBUG_LOG" 2>/dev/null || true
254
+ # Increment circuit breaker
255
+ CURRENT_FAILURES=$(cat "$CIRCUIT_BREAKER_FILE" 2>/dev/null || echo 0)
256
+ echo "$((CURRENT_FAILURES + 1))" > "$CIRCUIT_BREAKER_FILE" 2>/dev/null || true
257
+ fi
258
+ ) &
259
+
260
+ # Disown the background process so it's not killed when hook exits
261
+ disown 2>/dev/null || true
92
262
  fi
93
263
 
264
+ # Always exit 0 to prevent hook errors from crashing Claude Code
94
265
  exit 0
@@ -0,0 +1,61 @@
1
+ #!/usr/bin/env bash
2
+ # SpecWeave Post-First-Increment Hook
3
+ #
4
+ # Triggers after the first increment is completed
5
+ # Congratulates the user on completing their first increment
6
+ #
7
+ # NON-INTERACTIVE: Just shows a message (hooks run in background)
8
+
9
+ set -euo pipefail
10
+
11
+ # Get project root (where .specweave/ lives)
12
+ PROJECT_ROOT="$(pwd)"
13
+
14
+ # Check if .specweave directory exists
15
+ if [ ! -d ".specweave" ]; then
16
+ # Not in SpecWeave project, skip
17
+ exit 0
18
+ fi
19
+
20
+ # Check if this is the first increment completion
21
+ # Count completed increments in .specweave/increments/
22
+ COMPLETED_COUNT=0
23
+ if [ -d ".specweave/increments" ]; then
24
+ # Count directories that have COMPLETION-REPORT.md or completion metadata
25
+ for inc_dir in .specweave/increments/[0-9][0-9][0-9][0-9]-*/; do
26
+ if [ -d "$inc_dir" ]; then
27
+ if [ -f "${inc_dir}reports/COMPLETION-REPORT.md" ] || \
28
+ [ -f "${inc_dir}COMPLETION-SUMMARY.md" ] || \
29
+ ([ -f "${inc_dir}metadata.json" ] && grep -q '"status".*"completed"' "${inc_dir}metadata.json" 2>/dev/null); then
30
+ COMPLETED_COUNT=$((COMPLETED_COUNT + 1))
31
+ fi
32
+ fi
33
+ done
34
+ fi
35
+
36
+ # Only trigger on first completion
37
+ if [ "$COMPLETED_COUNT" -ne 1 ]; then
38
+ exit 0
39
+ fi
40
+
41
+ # Show congratulations message (non-interactive)
42
+ echo ""
43
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
44
+ echo "🎉 Congratulations! You completed your first increment!"
45
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
46
+ echo ""
47
+ echo "✅ Your increment has been documented in:"
48
+ echo " .specweave/increments/[increment-id]/"
49
+ echo ""
50
+ echo "📚 View your documentation:"
51
+ echo " - Specs: .specweave/docs/internal/specs/"
52
+ echo " - Architecture: .specweave/docs/internal/architecture/"
53
+ echo ""
54
+ echo "🚀 Next steps:"
55
+ echo " - Review your increment: /specweave:status"
56
+ echo " - Start next increment: /specweave:increment \"feature name\""
57
+ echo ""
58
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
59
+ echo ""
60
+
61
+ exit 0
@@ -17,7 +17,12 @@
17
17
  # Example:
18
18
  # ./post-increment-change.sh 0015-hierarchical-sync spec.md
19
19
 
20
- set -e
20
+ set +e # EMERGENCY FIX: Prevents Claude Code crashes
21
+
22
+ # EMERGENCY KILL SWITCH
23
+ if [[ "${SPECWEAVE_DISABLE_HOOKS:-0}" == "1" ]]; then
24
+ exit 0
25
+ fi
21
26
 
22
27
  # Find project root
23
28
  find_project_root() {
@@ -0,0 +1,98 @@
1
+ #!/bin/bash
2
+
3
+ # SpecWeave Post-Increment-Change Hook
4
+ # Runs automatically after increment files (spec.md, plan.md, tasks.md) are modified
5
+ #
6
+ # Trigger: File watcher or git hook (pre-commit/post-commit)
7
+ # Purpose: Sync increment file changes to GitHub issues
8
+ #
9
+ # What it does:
10
+ # 1. Detects which file changed (spec.md, plan.md, tasks.md)
11
+ # 2. Invokes GitHub sync for increment changes
12
+ # 3. Updates GitHub issue with scope/plan/task changes
13
+ #
14
+ # Usage:
15
+ # ./post-increment-change.sh <incrementId> <changedFile>
16
+ #
17
+ # Example:
18
+ # ./post-increment-change.sh 0015-hierarchical-sync spec.md
19
+
20
+ set -e
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
+ pwd
33
+ }
34
+
35
+ PROJECT_ROOT="$(find_project_root "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")"
36
+ cd "$PROJECT_ROOT" 2>/dev/null || true
37
+
38
+ # Configuration
39
+ LOGS_DIR=".specweave/logs"
40
+ DEBUG_LOG="$LOGS_DIR/hooks-debug.log"
41
+
42
+ mkdir -p "$LOGS_DIR" 2>/dev/null || true
43
+
44
+ # Arguments
45
+ INCREMENT_ID="$1"
46
+ CHANGED_FILE="$2"
47
+
48
+ if [ -z "$INCREMENT_ID" ] || [ -z "$CHANGED_FILE" ]; then
49
+ echo "Usage: $0 <incrementId> <changedFile>" >&2
50
+ echo "Example: $0 0015-hierarchical-sync spec.md" >&2
51
+ exit 1
52
+ fi
53
+
54
+ echo "[$(date)] 📝 Increment file changed: $CHANGED_FILE" >> "$DEBUG_LOG" 2>/dev/null || true
55
+
56
+ # Validate changed file
57
+ case "$CHANGED_FILE" in
58
+ spec.md|plan.md|tasks.md)
59
+ ;;
60
+ *)
61
+ echo "[$(date)] âš ī¸ Unknown file type: $CHANGED_FILE (skipping sync)" >> "$DEBUG_LOG" 2>/dev/null || true
62
+ exit 0
63
+ ;;
64
+ esac
65
+
66
+ # Check if Node.js available
67
+ if ! command -v node &> /dev/null; then
68
+ echo "[$(date)] âš ī¸ Node.js not found, skipping sync" >> "$DEBUG_LOG" 2>/dev/null || true
69
+ exit 0
70
+ fi
71
+
72
+ # Check if GitHub CLI available
73
+ if ! command -v gh &> /dev/null; then
74
+ echo "[$(date)] â„šī¸ GitHub CLI not found, skipping sync" >> "$DEBUG_LOG" 2>/dev/null || true
75
+ exit 0
76
+ fi
77
+
78
+ # Check if authenticated
79
+ if ! gh auth status &> /dev/null; then
80
+ echo "[$(date)] â„šī¸ GitHub CLI not authenticated, skipping sync" >> "$DEBUG_LOG" 2>/dev/null || true
81
+ exit 0
82
+ fi
83
+
84
+ # Sync to GitHub
85
+ echo "[$(date)] 🔄 Syncing $CHANGED_FILE changes to GitHub..." >> "$DEBUG_LOG" 2>/dev/null || true
86
+
87
+ node dist/plugins/specweave-github/lib/github-sync-increment-changes.js "$INCREMENT_ID" "$CHANGED_FILE" 2>&1 | tee -a "$DEBUG_LOG" >/dev/null || {
88
+ echo "[$(date)] âš ī¸ Failed to sync increment changes (non-blocking)" >> "$DEBUG_LOG" 2>/dev/null || true
89
+ }
90
+
91
+ echo "[$(date)] ✅ Post-increment-change hook complete" >> "$DEBUG_LOG" 2>/dev/null || true
92
+
93
+ # Update status line cache (increment changed)
94
+ HOOK_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
95
+ bash "$HOOK_DIR/lib/update-status-line.sh" 2>/dev/null || true
96
+
97
+ # Return success (non-blocking)
98
+ exit 0
@@ -5,7 +5,12 @@
5
5
  #
6
6
  # This hook closes GitHub issues automatically when increments complete
7
7
 
8
- set -e
8
+ set +e # EMERGENCY FIX: Prevents Claude Code crashes
9
+
10
+ # EMERGENCY KILL SWITCH
11
+ if [[ "${SPECWEAVE_DISABLE_HOOKS:-0}" == "1" ]]; then
12
+ exit 0
13
+ fi
9
14
 
10
15
  HOOK_NAME="post-increment-completion"
11
16
  INCREMENT_ID="${1:-}"