specweave 1.0.550 → 1.0.552

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (166) hide show
  1. package/CLAUDE.md +1 -1
  2. package/bin/specweave.js +23 -1
  3. package/dist/src/cli/commands/hook.d.ts +15 -0
  4. package/dist/src/cli/commands/hook.d.ts.map +1 -0
  5. package/dist/src/cli/commands/hook.js +61 -0
  6. package/dist/src/cli/commands/hook.js.map +1 -0
  7. package/dist/src/cli/commands/init.d.ts.map +1 -1
  8. package/dist/src/cli/commands/init.js +5 -0
  9. package/dist/src/cli/commands/init.js.map +1 -1
  10. package/dist/src/cli/commands/refresh-plugins.d.ts.map +1 -1
  11. package/dist/src/cli/commands/refresh-plugins.js +11 -1
  12. package/dist/src/cli/commands/refresh-plugins.js.map +1 -1
  13. package/dist/src/cli/commands/sync-setup.d.ts.map +1 -1
  14. package/dist/src/cli/commands/sync-setup.js +7 -3
  15. package/dist/src/cli/commands/sync-setup.js.map +1 -1
  16. package/dist/src/cli/helpers/issue-tracker/project-mapping-wizard.d.ts +9 -0
  17. package/dist/src/cli/helpers/issue-tracker/project-mapping-wizard.d.ts.map +1 -1
  18. package/dist/src/cli/helpers/issue-tracker/project-mapping-wizard.js +9 -3
  19. package/dist/src/cli/helpers/issue-tracker/project-mapping-wizard.js.map +1 -1
  20. package/dist/src/config/types.d.ts +2 -2
  21. package/dist/src/core/config/types.d.ts +18 -2
  22. package/dist/src/core/config/types.d.ts.map +1 -1
  23. package/dist/src/core/config/types.js.map +1 -1
  24. package/dist/src/core/hooks/handlers/hook-router.d.ts +19 -0
  25. package/dist/src/core/hooks/handlers/hook-router.d.ts.map +1 -0
  26. package/dist/src/core/hooks/handlers/hook-router.js +75 -0
  27. package/dist/src/core/hooks/handlers/hook-router.js.map +1 -0
  28. package/dist/src/core/hooks/handlers/index.d.ts +10 -0
  29. package/dist/src/core/hooks/handlers/index.d.ts.map +1 -0
  30. package/dist/src/core/hooks/handlers/index.js +9 -0
  31. package/dist/src/core/hooks/handlers/index.js.map +1 -0
  32. package/dist/src/core/hooks/handlers/post-tool-use-analytics.d.ts +11 -0
  33. package/dist/src/core/hooks/handlers/post-tool-use-analytics.d.ts.map +1 -0
  34. package/dist/src/core/hooks/handlers/post-tool-use-analytics.js +73 -0
  35. package/dist/src/core/hooks/handlers/post-tool-use-analytics.js.map +1 -0
  36. package/dist/src/core/hooks/handlers/post-tool-use.d.ts +11 -0
  37. package/dist/src/core/hooks/handlers/post-tool-use.d.ts.map +1 -0
  38. package/dist/src/core/hooks/handlers/post-tool-use.js +76 -0
  39. package/dist/src/core/hooks/handlers/post-tool-use.js.map +1 -0
  40. package/dist/src/core/hooks/handlers/pre-compact.d.ts +11 -0
  41. package/dist/src/core/hooks/handlers/pre-compact.d.ts.map +1 -0
  42. package/dist/src/core/hooks/handlers/pre-compact.js +77 -0
  43. package/dist/src/core/hooks/handlers/pre-compact.js.map +1 -0
  44. package/dist/src/core/hooks/handlers/pre-tool-use.d.ts +11 -0
  45. package/dist/src/core/hooks/handlers/pre-tool-use.d.ts.map +1 -0
  46. package/dist/src/core/hooks/handlers/pre-tool-use.js +318 -0
  47. package/dist/src/core/hooks/handlers/pre-tool-use.js.map +1 -0
  48. package/dist/src/core/hooks/handlers/session-start.d.ts +9 -0
  49. package/dist/src/core/hooks/handlers/session-start.d.ts.map +1 -0
  50. package/dist/src/core/hooks/handlers/session-start.js +111 -0
  51. package/dist/src/core/hooks/handlers/session-start.js.map +1 -0
  52. package/dist/src/core/hooks/handlers/stop-auto.d.ts +16 -0
  53. package/dist/src/core/hooks/handlers/stop-auto.d.ts.map +1 -0
  54. package/dist/src/core/hooks/handlers/stop-auto.js +122 -0
  55. package/dist/src/core/hooks/handlers/stop-auto.js.map +1 -0
  56. package/dist/src/core/hooks/handlers/stop-reflect.d.ts +14 -0
  57. package/dist/src/core/hooks/handlers/stop-reflect.d.ts.map +1 -0
  58. package/dist/src/core/hooks/handlers/stop-reflect.js +43 -0
  59. package/dist/src/core/hooks/handlers/stop-reflect.js.map +1 -0
  60. package/dist/src/core/hooks/handlers/stop-sync.d.ts +15 -0
  61. package/dist/src/core/hooks/handlers/stop-sync.d.ts.map +1 -0
  62. package/dist/src/core/hooks/handlers/stop-sync.js +68 -0
  63. package/dist/src/core/hooks/handlers/stop-sync.js.map +1 -0
  64. package/dist/src/core/hooks/handlers/types.d.ts +63 -0
  65. package/dist/src/core/hooks/handlers/types.d.ts.map +1 -0
  66. package/dist/src/core/hooks/handlers/types.js +27 -0
  67. package/dist/src/core/hooks/handlers/types.js.map +1 -0
  68. package/dist/src/core/hooks/handlers/user-prompt-submit.d.ts +14 -0
  69. package/dist/src/core/hooks/handlers/user-prompt-submit.d.ts.map +1 -0
  70. package/dist/src/core/hooks/handlers/user-prompt-submit.js +173 -0
  71. package/dist/src/core/hooks/handlers/user-prompt-submit.js.map +1 -0
  72. package/dist/src/core/hooks/handlers/utils.d.ts +25 -0
  73. package/dist/src/core/hooks/handlers/utils.d.ts.map +1 -0
  74. package/dist/src/core/hooks/handlers/utils.js +64 -0
  75. package/dist/src/core/hooks/handlers/utils.js.map +1 -0
  76. package/dist/src/core/increment/completion-validator.d.ts.map +1 -1
  77. package/dist/src/core/increment/completion-validator.js +32 -0
  78. package/dist/src/core/increment/completion-validator.js.map +1 -1
  79. package/dist/src/init/research/types.d.ts +1 -1
  80. package/dist/src/sync/sync-target-resolver.js.map +1 -1
  81. package/dist/src/utils/lock-manager.d.ts.map +1 -1
  82. package/dist/src/utils/lock-manager.js +5 -0
  83. package/dist/src/utils/lock-manager.js.map +1 -1
  84. package/dist/src/utils/plugin-copier.d.ts +10 -0
  85. package/dist/src/utils/plugin-copier.d.ts.map +1 -1
  86. package/dist/src/utils/plugin-copier.js +63 -35
  87. package/dist/src/utils/plugin-copier.js.map +1 -1
  88. package/package.json +1 -1
  89. package/plugins/specweave/agents/sw-closer.md +3 -2
  90. package/plugins/specweave/hooks/hooks.json +10 -10
  91. package/plugins/specweave/skills/code-reviewer/SKILL.md +180 -16
  92. package/plugins/specweave/skills/code-reviewer/agents/reviewer-comments.md +83 -0
  93. package/plugins/specweave/skills/code-reviewer/agents/reviewer-silent-failures.md +19 -0
  94. package/plugins/specweave/skills/code-reviewer/agents/reviewer-spec-compliance.md +19 -0
  95. package/plugins/specweave/skills/code-reviewer/agents/reviewer-tests.md +101 -0
  96. package/plugins/specweave/skills/code-reviewer/agents/reviewer-types.md +20 -0
  97. package/plugins/specweave/skills/done/SKILL.md +56 -21
  98. package/plugins/specweave/skills/grill/SKILL.md +1 -1
  99. package/plugins/specweave/skills/team-lead/agents/reviewer-logic.md +19 -0
  100. package/plugins/specweave/skills/team-lead/agents/reviewer-performance.md +20 -0
  101. package/plugins/specweave/skills/team-lead/agents/reviewer-security.md +20 -0
  102. package/src/templates/CLAUDE.md.template +7 -4
  103. package/plugins/specweave/hooks/README.md +0 -493
  104. package/plugins/specweave/hooks/_archive/stop-auto-v4-legacy.sh +0 -1319
  105. package/plugins/specweave/hooks/lib/common-setup.sh +0 -144
  106. package/plugins/specweave/hooks/lib/hook-errors.sh +0 -414
  107. package/plugins/specweave/hooks/lib/migrate-increment-work.sh +0 -245
  108. package/plugins/specweave/hooks/lib/resolve-package.sh +0 -146
  109. package/plugins/specweave/hooks/lib/scheduler-startup.sh +0 -135
  110. package/plugins/specweave/hooks/lib/score-increment.sh +0 -87
  111. package/plugins/specweave/hooks/lib/sync-spec-content.sh +0 -193
  112. package/plugins/specweave/hooks/lib/update-active-increment.sh +0 -95
  113. package/plugins/specweave/hooks/lib/update-status-line.sh +0 -233
  114. package/plugins/specweave/hooks/lib/validate-spec-status.sh +0 -171
  115. package/plugins/specweave/hooks/llm-judge-validator.sh +0 -219
  116. package/plugins/specweave/hooks/log-decision.sh +0 -168
  117. package/plugins/specweave/hooks/pre-compact.sh +0 -64
  118. package/plugins/specweave/hooks/startup-health-check.sh +0 -64
  119. package/plugins/specweave/hooks/stop-auto-v5.sh +0 -276
  120. package/plugins/specweave/hooks/stop-reflect.sh +0 -336
  121. package/plugins/specweave/hooks/stop-sync.sh +0 -283
  122. package/plugins/specweave/hooks/tests/test-auto-context-integration.sh +0 -126
  123. package/plugins/specweave/hooks/tests/test-stop-auto-enriched.sh +0 -128
  124. package/plugins/specweave/hooks/universal/dispatcher.mjs +0 -336
  125. package/plugins/specweave/hooks/universal/fail-fast-wrapper.sh +0 -325
  126. package/plugins/specweave/hooks/universal/hook-wrapper.cmd +0 -26
  127. package/plugins/specweave/hooks/universal/hook-wrapper.sh +0 -69
  128. package/plugins/specweave/hooks/universal/run-hook.sh +0 -20
  129. package/plugins/specweave/hooks/universal/session-start.cmd +0 -16
  130. package/plugins/specweave/hooks/universal/session-start.ps1 +0 -16
  131. package/plugins/specweave/hooks/user-prompt-submit.sh +0 -2550
  132. package/plugins/specweave/hooks/v2/detectors/lifecycle-detector.sh +0 -87
  133. package/plugins/specweave/hooks/v2/detectors/us-completion-detector.sh +0 -186
  134. package/plugins/specweave/hooks/v2/dispatchers/post-tool-use-analytics.sh +0 -83
  135. package/plugins/specweave/hooks/v2/dispatchers/post-tool-use.sh +0 -447
  136. package/plugins/specweave/hooks/v2/dispatchers/pre-tool-use.sh +0 -104
  137. package/plugins/specweave/hooks/v2/dispatchers/session-start.sh +0 -270
  138. package/plugins/specweave/hooks/v2/guards/completion-guard.sh +0 -14
  139. package/plugins/specweave/hooks/v2/guards/increment-duplicate-guard.sh +0 -14
  140. package/plugins/specweave/hooks/v2/guards/increment-existence-guard.sh +0 -240
  141. package/plugins/specweave/hooks/v2/guards/interview-enforcement-guard.sh +0 -171
  142. package/plugins/specweave/hooks/v2/guards/metadata-json-guard.sh +0 -14
  143. package/plugins/specweave/hooks/v2/guards/skill-chain-enforcement-guard.sh +0 -222
  144. package/plugins/specweave/hooks/v2/guards/spec-template-enforcement-guard.sh +0 -21
  145. package/plugins/specweave/hooks/v2/guards/spec-validation-guard.sh +0 -14
  146. package/plugins/specweave/hooks/v2/guards/status-completion-guard.sh +0 -84
  147. package/plugins/specweave/hooks/v2/guards/task-ac-sync-guard.sh +0 -475
  148. package/plugins/specweave/hooks/v2/guards/tdd-enforcement-guard.sh +0 -268
  149. package/plugins/specweave/hooks/v2/handlers/ac-sync-dispatcher.sh +0 -332
  150. package/plugins/specweave/hooks/v2/handlers/ac-validation-handler.sh +0 -50
  151. package/plugins/specweave/hooks/v2/handlers/github-sync-handler.sh +0 -347
  152. package/plugins/specweave/hooks/v2/handlers/living-docs-handler.sh +0 -83
  153. package/plugins/specweave/hooks/v2/handlers/living-specs-handler.sh +0 -268
  154. package/plugins/specweave/hooks/v2/handlers/project-bridge-handler.sh +0 -104
  155. package/plugins/specweave/hooks/v2/handlers/status-line-handler.sh +0 -165
  156. package/plugins/specweave/hooks/v2/handlers/status-update.sh +0 -61
  157. package/plugins/specweave/hooks/v2/handlers/universal-auto-create-dispatcher.sh +0 -270
  158. package/plugins/specweave/hooks/v2/integrations/ado-post-living-docs-update.sh +0 -367
  159. package/plugins/specweave/hooks/v2/integrations/ado-post-task.sh +0 -179
  160. package/plugins/specweave/hooks/v2/integrations/github-auto-create-handler.sh +0 -553
  161. package/plugins/specweave/hooks/v2/integrations/github-post-task.sh +0 -345
  162. package/plugins/specweave/hooks/v2/integrations/jira-post-task.sh +0 -180
  163. package/plugins/specweave/hooks/v2/lib/check-provider-enabled.sh +0 -52
  164. package/plugins/specweave/hooks/v2/queue/enqueue.sh +0 -81
  165. package/plugins/specweave/hooks/v2/session-end.sh +0 -139
  166. package/plugins/specweave/hooks/validate-skill-activations.sh +0 -227
@@ -1,268 +0,0 @@
1
- #!/bin/bash
2
- # living-specs-handler.sh - Update living SPECS on lifecycle events
3
- # Events: increment.created, increment.done, increment.archived, increment.reopened
4
- #
5
- # This handler updates the specs/ folder structure when increment lifecycle changes.
6
- # It is called by the event processor, NOT directly by post-tool-use.
7
- #
8
- # IMPORTANT: This script must be fast (<100ms) and never crash Claude
9
- # v1.0.71 - Fixed: Use specweave package location, not PROJECT_ROOT/dist
10
- set +e
11
-
12
- [[ "${SPECWEAVE_DISABLE_HOOKS:-0}" == "1" ]] && exit 0
13
-
14
- EVENT="${1:-}"
15
- INC_ID="${2:-}"
16
-
17
- [[ -z "$EVENT" ]] && exit 0
18
- [[ -z "$INC_ID" ]] && exit 0
19
-
20
- # Find project root
21
- PROJECT_ROOT="$PWD"
22
- while [[ "$PROJECT_ROOT" != "/" ]] && [[ ! -f "$PROJECT_ROOT/.specweave/config.json" ]]; do
23
- PROJECT_ROOT=$(dirname "$PROJECT_ROOT")
24
- done
25
- [[ ! -f "$PROJECT_ROOT/.specweave/config.json" ]] && exit 0
26
-
27
- # Resolve specweave package location
28
- HANDLER_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
29
- source "$HANDLER_DIR/../../lib/resolve-package.sh" 2>/dev/null || true
30
-
31
- # Throttle: max once per 60 seconds per increment
32
- STATE_DIR="$PROJECT_ROOT/.specweave/state"
33
- THROTTLE_FILE="$STATE_DIR/.living-specs-$INC_ID"
34
- mkdir -p "$STATE_DIR" 2>/dev/null
35
-
36
- if [[ -f "$THROTTLE_FILE" ]]; then
37
- if [[ "$(uname)" == "Darwin" ]]; then
38
- AGE=$(($(date +%s) - $(stat -f %m "$THROTTLE_FILE" 2>/dev/null || echo 0)))
39
- else
40
- AGE=$(($(date +%s) - $(stat -c %Y "$THROTTLE_FILE" 2>/dev/null || echo 0)))
41
- fi
42
- [[ $AGE -lt 60 ]] && exit 0
43
- fi
44
- touch "$THROTTLE_FILE"
45
-
46
- # Find the sync script (check SPECWEAVE_PKG first, then fallbacks)
47
- SYNC_SCRIPT=""
48
- for path in \
49
- "${SPECWEAVE_PKG:-}/dist/plugins/specweave/lib/hooks/sync-living-docs.js" \
50
- "${SPECWEAVE_PKG:-}/plugins/specweave/lib/hooks/sync-living-docs.js" \
51
- "${CLAUDE_PLUGIN_ROOT:-}/lib/hooks/sync-living-docs.js" \
52
- "$PROJECT_ROOT/dist/plugins/specweave/lib/hooks/sync-living-docs.js" \
53
- "$PROJECT_ROOT/plugins/specweave/lib/hooks/sync-living-docs.js"; do
54
- [[ -f "$path" ]] && { SYNC_SCRIPT="$path"; break; }
55
- done
56
-
57
- # Log event (silent, async)
58
- LOG_FILE="$PROJECT_ROOT/.specweave/logs/hooks.log"
59
- mkdir -p "$(dirname "$LOG_FILE")" 2>/dev/null
60
- echo "[$(date '+%Y-%m-%d %H:%M:%S')] living-specs-handler: $EVENT $INC_ID" >> "$LOG_FILE" 2>/dev/null
61
-
62
- # Get increment paths
63
- INC_DIR="$PROJECT_ROOT/.specweave/increments/$INC_ID"
64
- ARCHIVE_DIR="$PROJECT_ROOT/.specweave/increments/_archive/$INC_ID"
65
- SPEC_FILE="$INC_DIR/spec.md"
66
- ARCHIVE_SPEC="$ARCHIVE_DIR/spec.md"
67
-
68
- # Extract feature ID from spec.md (fast grep)
69
- get_feature_id() {
70
- local spec="$1"
71
- [[ -f "$spec" ]] && grep -E "^(epic|feature_id):" "$spec" 2>/dev/null | head -1 | sed 's/.*:[[:space:]]*//' | tr -d '"'"'"
72
- }
73
-
74
- # Cross-platform timeout wrapper
75
- # Uses GNU timeout, gtimeout (macOS with coreutils), or fallback
76
- run_with_timeout() {
77
- local timeout_secs="$1"
78
- shift
79
- if command -v timeout >/dev/null 2>&1; then
80
- timeout "$timeout_secs" "$@" 2>/dev/null || true
81
- elif command -v gtimeout >/dev/null 2>&1; then
82
- gtimeout "$timeout_secs" "$@" 2>/dev/null || true
83
- else
84
- "$@" 2>/dev/null || true
85
- fi
86
- }
87
-
88
- case "$EVENT" in
89
- increment.created)
90
- # Create spec entry in living docs via Node.js script
91
- if [[ -n "$SYNC_SCRIPT" ]] && [[ -f "$SPEC_FILE" ]]; then
92
- FEATURE_ID=$(get_feature_id "$SPEC_FILE")
93
- cd "$PROJECT_ROOT" || exit 0
94
- if [[ -n "$FEATURE_ID" ]]; then
95
- FEATURE_ID="$FEATURE_ID" run_with_timeout 30 node "$SYNC_SCRIPT" "$INC_ID" >/dev/null 2>&1 &
96
- else
97
- run_with_timeout 30 node "$SYNC_SCRIPT" "$INC_ID" >/dev/null 2>&1 &
98
- fi
99
- fi
100
- ;;
101
-
102
- increment.done)
103
- # Update status to complete in living docs
104
- if [[ -n "$SYNC_SCRIPT" ]] && [[ -f "$SPEC_FILE" ]]; then
105
- FEATURE_ID=$(get_feature_id "$SPEC_FILE")
106
- cd "$PROJECT_ROOT" || exit 0
107
-
108
- # Mark as complete in FEATURE.md if it exists
109
- if [[ -n "$FEATURE_ID" ]]; then
110
- SPECS_DIR="$PROJECT_ROOT/.specweave/docs/internal/specs"
111
- # Find FEATURE.md for this feature
112
- FEATURE_FILE=$(find "$SPECS_DIR" -path "*/$FEATURE_ID/FEATURE.md" 2>/dev/null | head -1)
113
-
114
- if [[ -f "$FEATURE_FILE" ]]; then
115
- # Update status in FEATURE.md (in-progress -> complete)
116
- sed -i.bak 's/status: in-progress/status: complete/g' "$FEATURE_FILE" 2>/dev/null
117
- rm -f "${FEATURE_FILE}.bak" 2>/dev/null
118
-
119
- # Update increment row status
120
- sed -i.bak "s/\[$INC_ID\].*in-progress/[$INC_ID](..\/..\/..\/..\/increments\/$INC_ID\/spec.md) | complete/g" "$FEATURE_FILE" 2>/dev/null
121
- rm -f "${FEATURE_FILE}.bak" 2>/dev/null
122
- fi
123
-
124
- # Also run full sync for completeness
125
- FEATURE_ID="$FEATURE_ID" run_with_timeout 30 node "$SYNC_SCRIPT" "$INC_ID" >/dev/null 2>&1 &
126
- else
127
- run_with_timeout 30 node "$SYNC_SCRIPT" "$INC_ID" >/dev/null 2>&1 &
128
- fi
129
- fi
130
-
131
- # ========================================================================
132
- # CRITICAL FIX (v0.34.0): Close GitHub/JIRA/ADO issues on increment.done
133
- # ========================================================================
134
- # Root cause: sync-increment-closure.js was NEVER being called when
135
- # increments completed. The EDA architecture routes increment.done to
136
- # this handler, but only sync-living-docs.js was called (updates docs).
137
- #
138
- # sync-increment-closure.js contains the actual logic to:
139
- # - Close GitHub issues linked to User Stories
140
- # - Close JIRA/ADO issues (with proper gates)
141
- # - Post completion comments on external issues
142
- #
143
- # Without this, GitHub issues stayed OPEN forever after increment closure!
144
- # See: GitHub Issues #817-#822 (increment 0136) stayed open until manual fix
145
- CLOSURE_SCRIPT=""
146
- for path in \
147
- "${SPECWEAVE_PKG:-}/dist/plugins/specweave/lib/hooks/sync-increment-closure.js" \
148
- "${SPECWEAVE_PKG:-}/plugins/specweave/lib/hooks/sync-increment-closure.js" \
149
- "${CLAUDE_PLUGIN_ROOT:-}/lib/hooks/sync-increment-closure.js" \
150
- "$PROJECT_ROOT/dist/plugins/specweave/lib/hooks/sync-increment-closure.js" \
151
- "$PROJECT_ROOT/plugins/specweave/lib/hooks/sync-increment-closure.js"; do
152
- [[ -f "$path" ]] && { CLOSURE_SCRIPT="$path"; break; }
153
- done
154
-
155
- if [[ -n "$CLOSURE_SCRIPT" ]]; then
156
- cd "$PROJECT_ROOT" || exit 0
157
- echo "[$(date '+%Y-%m-%d %H:%M:%S')] Calling sync-increment-closure.js for $INC_ID" >> "$LOG_FILE" 2>/dev/null
158
- # Run closure sync in background (can take 10-30s for multiple issues)
159
- run_with_timeout 60 node "$CLOSURE_SCRIPT" "$INC_ID" >> "$LOG_FILE" 2>&1 &
160
- fi
161
-
162
- # ========================================================================
163
- # CODEBASE RESCAN (v1.0.47): Update living docs based on actual code
164
- # ========================================================================
165
- # When an increment closes, we MUST rescan the actual source code to ensure
166
- # living docs reflect implementation reality (code as source of truth).
167
- #
168
- # This launches a background job that:
169
- # 1. Scans files modified since increment started
170
- # 2. Extracts implementation details (exports, functions, classes)
171
- # 3. Updates living docs with actual code structure
172
- # 4. Generates implementation summary report
173
- #
174
- # The job runs asynchronously to not block increment closure.
175
- RESCAN_SCRIPT=""
176
- for path in \
177
- "${SPECWEAVE_PKG:-}/dist/plugins/specweave/lib/hooks/launch-codebase-rescan.js" \
178
- "${SPECWEAVE_PKG:-}/plugins/specweave/lib/hooks/launch-codebase-rescan.js" \
179
- "${CLAUDE_PLUGIN_ROOT:-}/lib/hooks/launch-codebase-rescan.js" \
180
- "$PROJECT_ROOT/dist/plugins/specweave/lib/hooks/launch-codebase-rescan.js" \
181
- "$PROJECT_ROOT/plugins/specweave/lib/hooks/launch-codebase-rescan.js"; do
182
- [[ -f "$path" ]] && { RESCAN_SCRIPT="$path"; break; }
183
- done
184
-
185
- if [[ -n "$RESCAN_SCRIPT" ]]; then
186
- cd "$PROJECT_ROOT" || exit 0
187
- FEATURE_ID=$(get_feature_id "$SPEC_FILE")
188
- echo "[$(date '+%Y-%m-%d %H:%M:%S')] Launching codebase rescan job for $INC_ID (feature: ${FEATURE_ID:-none})" >> "$LOG_FILE" 2>/dev/null
189
- # Run rescan in background - non-blocking, fire-and-forget
190
- if [[ -n "$FEATURE_ID" ]]; then
191
- run_with_timeout 10 node "$RESCAN_SCRIPT" "$INC_ID" "$FEATURE_ID" >> "$LOG_FILE" 2>&1 &
192
- else
193
- run_with_timeout 10 node "$RESCAN_SCRIPT" "$INC_ID" >> "$LOG_FILE" 2>&1 &
194
- fi
195
- else
196
- echo "[$(date '+%Y-%m-%d %H:%M:%S')] Codebase rescan script not found, skipping" >> "$LOG_FILE" 2>/dev/null
197
- fi
198
- ;;
199
-
200
- increment.archived)
201
- # Move spec entry to _archive section in living docs
202
- if [[ -f "$ARCHIVE_SPEC" ]]; then
203
- FEATURE_ID=$(get_feature_id "$ARCHIVE_SPEC")
204
-
205
- if [[ -n "$FEATURE_ID" ]]; then
206
- SPECS_DIR="$PROJECT_ROOT/.specweave/docs/internal/specs"
207
- ACTIVE_FEATURE=$(find "$SPECS_DIR" -path "*/$FEATURE_ID/FEATURE.md" -not -path "*/_archive/*" 2>/dev/null | head -1)
208
- ARCHIVE_SPECS="$SPECS_DIR/specweave/_archive"
209
-
210
- if [[ -f "$ACTIVE_FEATURE" ]]; then
211
- # Check if all increments for this feature are archived
212
- FEATURE_DIR=$(dirname "$ACTIVE_FEATURE")
213
- ACTIVE_INC_COUNT=$(ls -1 "$FEATURE_DIR"/*.md 2>/dev/null | grep -v FEATURE.md | grep -v README.md | wc -l | tr -d ' ')
214
-
215
- if [[ "$ACTIVE_INC_COUNT" -eq 0 ]]; then
216
- # Move entire feature folder to archive
217
- mkdir -p "$ARCHIVE_SPECS" 2>/dev/null
218
- mv "$FEATURE_DIR" "$ARCHIVE_SPECS/" 2>/dev/null
219
- else
220
- # Just update status in FEATURE.md
221
- sed -i.bak "s/\[$INC_ID\].*|.*$/[$INC_ID](..\/..\/..\/..\/increments\/_archive\/$INC_ID\/spec.md) | archived/g" "$ACTIVE_FEATURE" 2>/dev/null
222
- rm -f "${ACTIVE_FEATURE}.bak" 2>/dev/null
223
- fi
224
- fi
225
- fi
226
- fi
227
- ;;
228
-
229
- increment.reopened)
230
- # Restore from archive section in living docs
231
- if [[ -f "$SPEC_FILE" ]]; then
232
- FEATURE_ID=$(get_feature_id "$SPEC_FILE")
233
-
234
- if [[ -n "$FEATURE_ID" ]]; then
235
- SPECS_DIR="$PROJECT_ROOT/.specweave/docs/internal/specs"
236
- ARCHIVE_FEATURE="$SPECS_DIR/specweave/_archive/$FEATURE_ID"
237
- ACTIVE_SPECS="$SPECS_DIR/specweave"
238
-
239
- # Check if feature was archived, restore it
240
- if [[ -d "$ARCHIVE_FEATURE" ]]; then
241
- mv "$ARCHIVE_FEATURE" "$ACTIVE_SPECS/" 2>/dev/null
242
-
243
- # Update status back to in-progress
244
- FEATURE_FILE="$ACTIVE_SPECS/$FEATURE_ID/FEATURE.md"
245
- if [[ -f "$FEATURE_FILE" ]]; then
246
- sed -i.bak 's/status: archived/status: in-progress/g' "$FEATURE_FILE" 2>/dev/null
247
- sed -i.bak 's/status: complete/status: in-progress/g' "$FEATURE_FILE" 2>/dev/null
248
- rm -f "${FEATURE_FILE}.bak" 2>/dev/null
249
- fi
250
- else
251
- # Feature still exists, just update increment status
252
- FEATURE_FILE=$(find "$SPECS_DIR" -path "*/$FEATURE_ID/FEATURE.md" -not -path "*/_archive/*" 2>/dev/null | head -1)
253
- if [[ -f "$FEATURE_FILE" ]]; then
254
- sed -i.bak "s/\[$INC_ID\].*archived/[$INC_ID](..\/..\/..\/..\/increments\/$INC_ID\/spec.md) | in-progress/g" "$FEATURE_FILE" 2>/dev/null
255
- sed -i.bak "s/\[$INC_ID\].*complete/[$INC_ID](..\/..\/..\/..\/increments\/$INC_ID\/spec.md) | in-progress/g" "$FEATURE_FILE" 2>/dev/null
256
- rm -f "${FEATURE_FILE}.bak" 2>/dev/null
257
- fi
258
- fi
259
-
260
- # Run full sync to restore any missing content
261
- cd "$PROJECT_ROOT" || exit 0
262
- FEATURE_ID="$FEATURE_ID" run_with_timeout 30 node "$SYNC_SCRIPT" "$INC_ID" >/dev/null 2>&1 &
263
- fi
264
- fi
265
- ;;
266
- esac
267
-
268
- exit 0
@@ -1,104 +0,0 @@
1
- #!/bin/bash
2
- # project-bridge-handler.sh - Bridge increment events to project-level EDA
3
- #
4
- # This handler connects the increment-level EDA (hooks v2) to the
5
- # project-level EDA (ProjectRegistry + Adapters).
6
- #
7
- # Events bridged:
8
- # - increment.created -> May create project labels in GitHub
9
- # - increment.done -> Triggers project sync to all external tools
10
- # - increment.archived -> Updates project sync status
11
- # - increment.reopened -> Triggers project sync
12
- #
13
- # Architecture:
14
- # [Increment Event] -> [This Handler] -> [project-bridge.js] -> [ProjectService]
15
- # |
16
- # v
17
- # [ProjectEventBus]
18
- # |
19
- # +----------------+----------------+
20
- # v v v
21
- # [GitHub] [ADO] [JIRA]
22
- # Adapter Adapter Adapter
23
- #
24
- # IMPORTANT: Never crash Claude, always exit 0
25
- # v1.0.71 - Fixed: Use specweave package location, not PROJECT_ROOT/dist
26
- set +e
27
-
28
- [[ "${SPECWEAVE_DISABLE_HOOKS:-0}" == "1" ]] && exit 0
29
-
30
- EVENT_TYPE="${1:-}"
31
- EVENT_DATA="${2:-}"
32
-
33
- [[ -z "$EVENT_TYPE" ]] && exit 0
34
- [[ -z "$EVENT_DATA" ]] && exit 0
35
-
36
- # Find project root
37
- PROJECT_ROOT="$PWD"
38
- while [[ "$PROJECT_ROOT" != "/" ]] && [[ ! -f "$PROJECT_ROOT/.specweave/config.json" ]]; do
39
- PROJECT_ROOT=$(dirname "$PROJECT_ROOT")
40
- done
41
- [[ ! -f "$PROJECT_ROOT/.specweave/config.json" ]] && exit 0
42
-
43
- # Resolve specweave package location
44
- HANDLER_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
45
- source "$HANDLER_DIR/../../lib/resolve-package.sh" 2>/dev/null || true
46
-
47
- # Throttle: max once per 2 minutes per increment for project sync
48
- # (More aggressive throttle since this triggers external API calls)
49
- INC_ID="${EVENT_DATA%%:*}" # Extract increment ID from INC_ID:US_ID format
50
- STATE_DIR="$PROJECT_ROOT/.specweave/state"
51
- THROTTLE_FILE="$STATE_DIR/.project-bridge-$INC_ID"
52
- THROTTLE_WINDOW=120 # 2 minutes
53
- mkdir -p "$STATE_DIR" 2>/dev/null
54
-
55
- if [[ -f "$THROTTLE_FILE" ]]; then
56
- if [[ "$(uname)" == "Darwin" ]]; then
57
- AGE=$(($(date +%s) - $(stat -f %m "$THROTTLE_FILE" 2>/dev/null || echo 0)))
58
- else
59
- AGE=$(($(date +%s) - $(stat -c %Y "$THROTTLE_FILE" 2>/dev/null || echo 0)))
60
- fi
61
- [[ $AGE -lt $THROTTLE_WINDOW ]] && exit 0
62
- fi
63
- touch "$THROTTLE_FILE"
64
-
65
- # Log event
66
- LOG_FILE="$PROJECT_ROOT/.specweave/logs/hooks.log"
67
- mkdir -p "$(dirname "$LOG_FILE")" 2>/dev/null
68
- echo "[$(date '+%Y-%m-%d %H:%M:%S')] project-bridge-handler: $EVENT_TYPE $EVENT_DATA" >> "$LOG_FILE" 2>/dev/null
69
-
70
- # Find the bridge script (check SPECWEAVE_PKG first)
71
- BRIDGE_SCRIPT=""
72
- for path in \
73
- "${SPECWEAVE_PKG:-}/dist/plugins/specweave/lib/hooks/project-bridge.js" \
74
- "${SPECWEAVE_PKG:-}/plugins/specweave/lib/hooks/project-bridge.js" \
75
- "${CLAUDE_PLUGIN_ROOT:-}/lib/hooks/project-bridge.js" \
76
- "$PROJECT_ROOT/dist/plugins/specweave/lib/hooks/project-bridge.js" \
77
- "$PROJECT_ROOT/plugins/specweave/lib/hooks/project-bridge.js"; do
78
- [[ -f "$path" ]] && { BRIDGE_SCRIPT="$path"; break; }
79
- done
80
-
81
- # Cross-platform timeout wrapper
82
- # FIXED (v1.0.302): Don't suppress stderr from inner commands
83
- run_with_timeout() {
84
- local timeout_secs="$1"
85
- shift
86
- if command -v timeout >/dev/null 2>&1; then
87
- timeout "$timeout_secs" "$@" || true
88
- elif command -v gtimeout >/dev/null 2>&1; then
89
- gtimeout "$timeout_secs" "$@" || true
90
- else
91
- "$@" || true
92
- fi
93
- }
94
-
95
- # Run bridge script if available
96
- if [[ -n "$BRIDGE_SCRIPT" ]]; then
97
- cd "$PROJECT_ROOT" || exit 0
98
- # Run with 60s timeout (external API calls can be slow)
99
- run_with_timeout 60 node "$BRIDGE_SCRIPT" "$EVENT_TYPE" "$EVENT_DATA" >> "$LOG_FILE" 2>&1 &
100
- else
101
- echo "[$(date '+%Y-%m-%d %H:%M:%S')] project-bridge-handler: No bridge script found, skipping" >> "$LOG_FILE" 2>/dev/null
102
- fi
103
-
104
- exit 0
@@ -1,165 +0,0 @@
1
- #!/bin/bash
2
- # status-line-handler.sh - Event-driven status line updates
3
- # Events: user-story.completed, user-story.reopened, increment.done, increment.archived, increment.reopened
4
- #
5
- # This handler updates the status line ONLY when meaningful events occur:
6
- # - User story completed (all ACs + tasks done for that US)
7
- # - User story reopened (US tasks/ACs unchecked)
8
- # - Increment lifecycle changes (done, archived, reopened)
9
- #
10
- # It does NOT update on every task.md edit - that would cause:
11
- # - Race conditions (multiple rapid updates)
12
- # - Performance issues (too frequent writes)
13
- # - Status line flickering
14
- #
15
- # IMPORTANT: This script must be fast (<20ms) and never crash Claude
16
- set +e
17
-
18
- [[ "${SPECWEAVE_DISABLE_HOOKS:-0}" == "1" ]] && exit 0
19
-
20
- EVENT="${1:-}"
21
- EVENT_DATA="${2:-}"
22
-
23
- [[ -z "$EVENT" ]] && exit 0
24
- [[ -z "$EVENT_DATA" ]] && exit 0
25
-
26
- # Find project root
27
- PROJECT_ROOT="$PWD"
28
- while [[ "$PROJECT_ROOT" != "/" ]] && [[ ! -f "$PROJECT_ROOT/.specweave/config.json" ]]; do
29
- PROJECT_ROOT=$(dirname "$PROJECT_ROOT")
30
- done
31
- [[ ! -f "$PROJECT_ROOT/.specweave/config.json" ]] && exit 0
32
-
33
- STATE_DIR="$PROJECT_ROOT/.specweave/state"
34
- CACHE_FILE="$STATE_DIR/status-line.json"
35
- mkdir -p "$STATE_DIR" 2>/dev/null
36
-
37
- # Log event (silent, async)
38
- LOG_FILE="$PROJECT_ROOT/.specweave/logs/hooks.log"
39
- mkdir -p "$(dirname "$LOG_FILE")" 2>/dev/null
40
- echo "[$(date '+%Y-%m-%d %H:%M:%S')] status-line-handler: $EVENT $EVENT_DATA" >> "$LOG_FILE" 2>/dev/null
41
-
42
- # Parse event data
43
- # Format: INC_ID:US_ID (for user-story events) or just INC_ID (for lifecycle events)
44
- if [[ "$EVENT_DATA" == *":"* ]]; then
45
- INC_ID="${EVENT_DATA%%:*}"
46
- US_ID="${EVENT_DATA##*:}"
47
- else
48
- INC_ID="$EVENT_DATA"
49
- US_ID=""
50
- fi
51
-
52
- # Handle events
53
- case "$EVENT" in
54
- user-story.completed)
55
- # User story completed - update status line with US progress
56
- # This is the RIGHT time to update (not on every checkbox click)
57
- ;;
58
-
59
- user-story.reopened)
60
- # User story reopened - update status line
61
- ;;
62
-
63
- increment.done)
64
- # Increment completed - update status line to show completion
65
- ;;
66
-
67
- increment.archived)
68
- # Increment archived - clear from status line, find next active
69
- INC_ID="" # Force finding a new active increment
70
- ;;
71
-
72
- increment.reopened)
73
- # Increment reopened - show it as active again
74
- ;;
75
-
76
- *)
77
- # Unknown event - ignore
78
- exit 0
79
- ;;
80
- esac
81
-
82
- # Find active increment if not determined or was archived
83
- if [[ -z "$INC_ID" ]] || [[ "$EVENT" == "increment.archived" ]]; then
84
- INC_ID=""
85
- for meta in "$PROJECT_ROOT/.specweave/increments"/[0-9]*/metadata.json; do
86
- [[ -f "$meta" ]] || continue
87
- STATUS=$(grep -o '"status"[[:space:]]*:[[:space:]]*"[^"]*"' "$meta" | grep -o '"[^"]*"$' | tr -d '"')
88
- [[ "$STATUS" == "active" || "$STATUS" == "planning" ]] && {
89
- INC_ID=$(basename "$(dirname "$meta")")
90
- break
91
- }
92
- done
93
- fi
94
-
95
- # If no active increment, write null status
96
- if [[ -z "$INC_ID" ]]; then
97
- cat > "$CACHE_FILE" << 'EOF'
98
- {"current":null,"event":"increment.archived","ts":"__TS__"}
99
- EOF
100
- sed -i.bak "s/__TS__/$(date +%s)/" "$CACHE_FILE" 2>/dev/null
101
- rm -f "${CACHE_FILE}.bak" 2>/dev/null
102
- exit 0
103
- fi
104
-
105
- # Get increment paths
106
- TASKS_FILE="$PROJECT_ROOT/.specweave/increments/$INC_ID/tasks.md"
107
- SPEC_FILE="$PROJECT_ROOT/.specweave/increments/$INC_ID/spec.md"
108
- META_FILE="$PROJECT_ROOT/.specweave/increments/$INC_ID/metadata.json"
109
-
110
- # Check files exist
111
- [[ ! -f "$TASKS_FILE" ]] && exit 0
112
-
113
- # Count tasks (pure bash, fast)
114
- TOTAL=$(grep -c "^###\? T-" "$TASKS_FILE" 2>/dev/null || echo 0)
115
- DONE=$(grep -c "\[x\]" "$TASKS_FILE" 2>/dev/null || echo 0)
116
- PCT=0; [[ $TOTAL -gt 0 ]] && PCT=$((DONE * 100 / TOTAL))
117
-
118
- # Count user stories completed
119
- US_TOTAL=0
120
- US_DONE=0
121
- if [[ -f "$SPEC_FILE" ]]; then
122
- # Count user story headers (## US-XXX or similar)
123
- US_TOTAL=$(grep -c "^##.*US-" "$SPEC_FILE" 2>/dev/null || echo 0)
124
-
125
- # Count by checking if all ACs for each US are checked
126
- # This is a simplified count - the actual detection is done by us-completion-detector.sh
127
- US_STATE_FILE="$STATE_DIR/.us-completion-$INC_ID"
128
- if [[ -f "$US_STATE_FILE" ]]; then
129
- US_DONE=$(grep -c "=yes$" "$US_STATE_FILE" 2>/dev/null || echo 0)
130
- fi
131
- fi
132
-
133
- # Get increment status
134
- INC_STATUS="active"
135
- if [[ -f "$META_FILE" ]]; then
136
- INC_STATUS=$(grep -o '"status"[[:space:]]*:[[:space:]]*"[^"]*"' "$META_FILE" | grep -o '"[^"]*"$' | tr -d '"')
137
- fi
138
-
139
- # Build detailed status JSON with event info
140
- TMP_FILE="$CACHE_FILE.tmp.$$"
141
- cat > "$TMP_FILE" << EOF
142
- {
143
- "current": {
144
- "id": "$INC_ID",
145
- "completed": $DONE,
146
- "total": $TOTAL,
147
- "percentage": $PCT,
148
- "status": "$INC_STATUS",
149
- "userStories": {
150
- "completed": $US_DONE,
151
- "total": $US_TOTAL
152
- }
153
- },
154
- "lastEvent": {
155
- "type": "$EVENT",
156
- "data": "$EVENT_DATA"
157
- },
158
- "ts": "$(date +%s)"
159
- }
160
- EOF
161
-
162
- # Atomic write (mv is atomic on same filesystem)
163
- mv "$TMP_FILE" "$CACHE_FILE" 2>/dev/null
164
-
165
- exit 0
@@ -1,61 +0,0 @@
1
- #!/bin/bash
2
- # status-update.sh - Fast status line update (synchronous)
3
- # Goal: <20ms execution, pure bash, no external processes
4
- #
5
- # NOTE: This is the LEGACY handler. New EDA architecture uses
6
- # status-line-handler.sh which is EVENT-DRIVEN.
7
- #
8
- # IMPORTANT: Never crash Claude, always exit 0
9
- set +e
10
-
11
- [[ "${SPECWEAVE_DISABLE_HOOKS:-0}" == "1" ]] && exit 0
12
-
13
- INC_ID="${1:-}"
14
-
15
- # Find project root
16
- PROJECT_ROOT="$PWD"
17
- while [[ "$PROJECT_ROOT" != "/" ]] && [[ ! -f "$PROJECT_ROOT/.specweave/config.json" ]]; do
18
- PROJECT_ROOT=$(dirname "$PROJECT_ROOT")
19
- done
20
- [[ ! -f "$PROJECT_ROOT/.specweave/config.json" ]] && exit 0
21
-
22
- STATE_DIR="$PROJECT_ROOT/.specweave/state"
23
- CACHE_FILE="$STATE_DIR/status-line.json"
24
- mkdir -p "$STATE_DIR" 2>/dev/null
25
-
26
- # TTL check (10 seconds)
27
- if [[ -f "$CACHE_FILE" ]]; then
28
- if [[ "$(uname)" == "Darwin" ]]; then
29
- CACHE_AGE=$(($(date +%s) - $(stat -f %m "$CACHE_FILE" 2>/dev/null || echo 0)))
30
- else
31
- CACHE_AGE=$(($(date +%s) - $(stat -c %Y "$CACHE_FILE" 2>/dev/null || echo 0)))
32
- fi
33
- [[ $CACHE_AGE -lt 10 ]] && exit 0
34
- fi
35
-
36
- # Find active increment if not provided
37
- if [[ -z "$INC_ID" ]]; then
38
- for meta in "$PROJECT_ROOT/.specweave/increments"/[0-9]*/metadata.json; do
39
- [[ -f "$meta" ]] || continue
40
- STATUS=$(grep -o '"status"[[:space:]]*:[[:space:]]*"[^"]*"' "$meta" | grep -o '"[^"]*"$' | tr -d '"')
41
- [[ "$STATUS" == "active" || "$STATUS" == "planning" ]] && {
42
- INC_ID=$(basename "$(dirname "$meta")")
43
- break
44
- }
45
- done
46
- fi
47
- [[ -z "$INC_ID" ]] && { echo '{"current":null}' > "$CACHE_FILE"; exit 0; }
48
-
49
- TASKS_FILE="$PROJECT_ROOT/.specweave/increments/$INC_ID/tasks.md"
50
- [[ ! -f "$TASKS_FILE" ]] && exit 0
51
-
52
- # Count tasks (pure bash, fast)
53
- TOTAL=$(grep -c "^###\? T-" "$TASKS_FILE" 2>/dev/null || echo 0)
54
- DONE=$(grep -c "\[x\]" "$TASKS_FILE" 2>/dev/null || echo 0)
55
- PCT=0; [[ $TOTAL -gt 0 ]] && PCT=$((DONE * 100 / TOTAL))
56
-
57
- # Write cache (atomic)
58
- cat > "$CACHE_FILE" << EOF
59
- {"current":{"id":"$INC_ID","completed":$DONE,"total":$TOTAL,"percentage":$PCT},"ts":"$(date +%s)"}
60
- EOF
61
- exit 0