specweave 0.30.19 → 0.32.2

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 (242) hide show
  1. package/CLAUDE.md +176 -2
  2. package/README.md +22 -0
  3. package/bin/specweave.js +18 -1
  4. package/dist/src/cli/commands/cache.d.ts +17 -0
  5. package/dist/src/cli/commands/cache.d.ts.map +1 -0
  6. package/dist/src/cli/commands/cache.js +126 -0
  7. package/dist/src/cli/commands/cache.js.map +1 -0
  8. package/dist/src/cli/commands/init.js +1 -1
  9. package/dist/src/cli/commands/init.js.map +1 -1
  10. package/dist/src/cli/commands/plan/increment-detector.js +2 -2
  11. package/dist/src/cli/commands/plan/increment-detector.js.map +1 -1
  12. package/dist/src/cli/commands/sync-spec-commits.js +1 -1
  13. package/dist/src/cli/commands/sync-spec-commits.js.map +1 -1
  14. package/dist/src/cli/commands/sync-specs.js +2 -2
  15. package/dist/src/cli/commands/sync-specs.js.map +1 -1
  16. package/dist/src/cli/helpers/github/increment-profile-selector.js +1 -1
  17. package/dist/src/cli/helpers/github/increment-profile-selector.js.map +1 -1
  18. package/dist/src/cli/workers/living-docs-worker.js +66 -1
  19. package/dist/src/cli/workers/living-docs-worker.js.map +1 -1
  20. package/dist/src/config/types.d.ts +203 -1208
  21. package/dist/src/config/types.d.ts.map +1 -1
  22. package/dist/src/core/discrepancy/increment-generator.d.ts.map +1 -1
  23. package/dist/src/core/discrepancy/increment-generator.js +5 -2
  24. package/dist/src/core/discrepancy/increment-generator.js.map +1 -1
  25. package/dist/src/core/external-tools/external-items-counter.d.ts +62 -0
  26. package/dist/src/core/external-tools/external-items-counter.d.ts.map +1 -0
  27. package/dist/src/core/external-tools/external-items-counter.js +206 -0
  28. package/dist/src/core/external-tools/external-items-counter.js.map +1 -0
  29. package/dist/src/core/external-tools/external-items-display.d.ts +39 -0
  30. package/dist/src/core/external-tools/external-items-display.d.ts.map +1 -0
  31. package/dist/src/core/external-tools/external-items-display.js +185 -0
  32. package/dist/src/core/external-tools/external-items-display.js.map +1 -0
  33. package/dist/src/core/external-tools/index.d.ts +8 -0
  34. package/dist/src/core/external-tools/index.d.ts.map +1 -0
  35. package/dist/src/core/external-tools/index.js +8 -0
  36. package/dist/src/core/external-tools/index.js.map +1 -0
  37. package/dist/src/core/external-tools/providers/ado-items-adapter.d.ts +39 -0
  38. package/dist/src/core/external-tools/providers/ado-items-adapter.d.ts.map +1 -0
  39. package/dist/src/core/external-tools/providers/ado-items-adapter.js +188 -0
  40. package/dist/src/core/external-tools/providers/ado-items-adapter.js.map +1 -0
  41. package/dist/src/core/external-tools/providers/github-items-adapter.d.ts +38 -0
  42. package/dist/src/core/external-tools/providers/github-items-adapter.d.ts.map +1 -0
  43. package/dist/src/core/external-tools/providers/github-items-adapter.js +136 -0
  44. package/dist/src/core/external-tools/providers/github-items-adapter.js.map +1 -0
  45. package/dist/src/core/external-tools/providers/index.d.ts +7 -0
  46. package/dist/src/core/external-tools/providers/index.d.ts.map +1 -0
  47. package/dist/src/core/external-tools/providers/index.js +7 -0
  48. package/dist/src/core/external-tools/providers/index.js.map +1 -0
  49. package/dist/src/core/external-tools/providers/jira-items-adapter.d.ts +42 -0
  50. package/dist/src/core/external-tools/providers/jira-items-adapter.d.ts.map +1 -0
  51. package/dist/src/core/external-tools/providers/jira-items-adapter.js +153 -0
  52. package/dist/src/core/external-tools/providers/jira-items-adapter.js.map +1 -0
  53. package/dist/src/core/external-tools/types.d.ts +78 -0
  54. package/dist/src/core/external-tools/types.d.ts.map +1 -0
  55. package/dist/src/core/external-tools/types.js +19 -0
  56. package/dist/src/core/external-tools/types.js.map +1 -0
  57. package/dist/src/core/increment/duplicate-detector.js +2 -2
  58. package/dist/src/core/increment/duplicate-detector.js.map +1 -1
  59. package/dist/src/core/increment/increment-archiver.d.ts +24 -0
  60. package/dist/src/core/increment/increment-archiver.d.ts.map +1 -1
  61. package/dist/src/core/increment/increment-archiver.js +59 -2
  62. package/dist/src/core/increment/increment-archiver.js.map +1 -1
  63. package/dist/src/core/increment/increment-status.js +2 -2
  64. package/dist/src/core/increment/increment-status.js.map +1 -1
  65. package/dist/src/core/increment/increment-utils.d.ts +98 -37
  66. package/dist/src/core/increment/increment-utils.d.ts.map +1 -1
  67. package/dist/src/core/increment/increment-utils.js +119 -68
  68. package/dist/src/core/increment/increment-utils.js.map +1 -1
  69. package/dist/src/core/increment/metadata-validator.js +1 -1
  70. package/dist/src/core/increment/metadata-validator.js.map +1 -1
  71. package/dist/src/core/increment/status-change-sync-trigger.d.ts.map +1 -1
  72. package/dist/src/core/increment/status-change-sync-trigger.js +4 -0
  73. package/dist/src/core/increment/status-change-sync-trigger.js.map +1 -1
  74. package/dist/src/core/living-docs/feature-id-manager.js +1 -1
  75. package/dist/src/core/living-docs/feature-id-manager.js.map +1 -1
  76. package/dist/src/core/living-docs/hierarchy-mapper.js +3 -3
  77. package/dist/src/core/living-docs/hierarchy-mapper.js.map +1 -1
  78. package/dist/src/core/living-docs/intelligent-analyzer/architecture-generator.d.ts +18 -0
  79. package/dist/src/core/living-docs/intelligent-analyzer/architecture-generator.d.ts.map +1 -0
  80. package/dist/src/core/living-docs/intelligent-analyzer/architecture-generator.js +247 -0
  81. package/dist/src/core/living-docs/intelligent-analyzer/architecture-generator.js.map +1 -0
  82. package/dist/src/core/living-docs/intelligent-analyzer/deep-repo-analyzer.d.ts +15 -0
  83. package/dist/src/core/living-docs/intelligent-analyzer/deep-repo-analyzer.d.ts.map +1 -0
  84. package/dist/src/core/living-docs/intelligent-analyzer/deep-repo-analyzer.js +138 -0
  85. package/dist/src/core/living-docs/intelligent-analyzer/deep-repo-analyzer.js.map +1 -0
  86. package/dist/src/core/living-docs/intelligent-analyzer/file-sampler.d.ts +24 -0
  87. package/dist/src/core/living-docs/intelligent-analyzer/file-sampler.d.ts.map +1 -0
  88. package/dist/src/core/living-docs/intelligent-analyzer/file-sampler.js +198 -0
  89. package/dist/src/core/living-docs/intelligent-analyzer/file-sampler.js.map +1 -0
  90. package/dist/src/core/living-docs/intelligent-analyzer/inconsistency-detector.d.ts +17 -0
  91. package/dist/src/core/living-docs/intelligent-analyzer/inconsistency-detector.d.ts.map +1 -0
  92. package/dist/src/core/living-docs/intelligent-analyzer/inconsistency-detector.js +241 -0
  93. package/dist/src/core/living-docs/intelligent-analyzer/inconsistency-detector.js.map +1 -0
  94. package/dist/src/core/living-docs/intelligent-analyzer/index.d.ts +28 -0
  95. package/dist/src/core/living-docs/intelligent-analyzer/index.d.ts.map +1 -0
  96. package/dist/src/core/living-docs/intelligent-analyzer/index.js +197 -0
  97. package/dist/src/core/living-docs/intelligent-analyzer/index.js.map +1 -0
  98. package/dist/src/core/living-docs/intelligent-analyzer/organization-synthesizer.d.ts +18 -0
  99. package/dist/src/core/living-docs/intelligent-analyzer/organization-synthesizer.d.ts.map +1 -0
  100. package/dist/src/core/living-docs/intelligent-analyzer/organization-synthesizer.js +154 -0
  101. package/dist/src/core/living-docs/intelligent-analyzer/organization-synthesizer.js.map +1 -0
  102. package/dist/src/core/living-docs/intelligent-analyzer/strategy-generator.d.ts +42 -0
  103. package/dist/src/core/living-docs/intelligent-analyzer/strategy-generator.d.ts.map +1 -0
  104. package/dist/src/core/living-docs/intelligent-analyzer/strategy-generator.js +343 -0
  105. package/dist/src/core/living-docs/intelligent-analyzer/strategy-generator.js.map +1 -0
  106. package/dist/src/core/living-docs/intelligent-analyzer/types.d.ts +146 -0
  107. package/dist/src/core/living-docs/intelligent-analyzer/types.d.ts.map +1 -0
  108. package/dist/src/core/living-docs/intelligent-analyzer/types.js +7 -0
  109. package/dist/src/core/living-docs/intelligent-analyzer/types.js.map +1 -0
  110. package/dist/src/core/living-docs/living-docs-sync.d.ts +5 -0
  111. package/dist/src/core/living-docs/living-docs-sync.d.ts.map +1 -1
  112. package/dist/src/core/living-docs/living-docs-sync.js +36 -2
  113. package/dist/src/core/living-docs/living-docs-sync.js.map +1 -1
  114. package/dist/src/core/llm/providers/azure-openai-provider.d.ts.map +1 -1
  115. package/dist/src/core/llm/providers/azure-openai-provider.js +1 -0
  116. package/dist/src/core/llm/providers/azure-openai-provider.js.map +1 -1
  117. package/dist/src/core/llm/providers/bedrock-provider.d.ts.map +1 -1
  118. package/dist/src/core/llm/providers/bedrock-provider.js +2 -0
  119. package/dist/src/core/llm/providers/bedrock-provider.js.map +1 -1
  120. package/dist/src/core/llm/providers/openai-provider.d.ts.map +1 -1
  121. package/dist/src/core/llm/providers/openai-provider.js +1 -0
  122. package/dist/src/core/llm/providers/openai-provider.js.map +1 -1
  123. package/dist/src/core/llm/providers/vertex-ai-provider.d.ts.map +1 -1
  124. package/dist/src/core/llm/providers/vertex-ai-provider.js +1 -0
  125. package/dist/src/core/llm/providers/vertex-ai-provider.js.map +1 -1
  126. package/dist/src/core/sync/spec-increment-mapper.js +3 -3
  127. package/dist/src/core/sync/spec-increment-mapper.js.map +1 -1
  128. package/dist/src/importers/item-converter.d.ts +25 -0
  129. package/dist/src/importers/item-converter.d.ts.map +1 -1
  130. package/dist/src/importers/item-converter.js +135 -5
  131. package/dist/src/importers/item-converter.js.map +1 -1
  132. package/dist/src/init/architecture/types.d.ts +33 -140
  133. package/dist/src/init/architecture/types.d.ts.map +1 -1
  134. package/dist/src/init/compliance/types.d.ts +30 -27
  135. package/dist/src/init/compliance/types.d.ts.map +1 -1
  136. package/dist/src/init/repo/types.d.ts +11 -34
  137. package/dist/src/init/repo/types.d.ts.map +1 -1
  138. package/dist/src/init/research/src/config/types.d.ts +15 -82
  139. package/dist/src/init/research/src/config/types.d.ts.map +1 -1
  140. package/dist/src/init/research/types.d.ts +38 -93
  141. package/dist/src/init/research/types.d.ts.map +1 -1
  142. package/dist/src/init/team/types.d.ts +4 -42
  143. package/dist/src/init/team/types.d.ts.map +1 -1
  144. package/dist/src/types/dashboard-cache.d.ts +181 -0
  145. package/dist/src/types/dashboard-cache.d.ts.map +1 -0
  146. package/dist/src/types/dashboard-cache.js +65 -0
  147. package/dist/src/types/dashboard-cache.js.map +1 -0
  148. package/dist/src/utils/docs-validator.d.ts +131 -0
  149. package/dist/src/utils/docs-validator.d.ts.map +1 -0
  150. package/dist/src/utils/docs-validator.js +529 -0
  151. package/dist/src/utils/docs-validator.js.map +1 -0
  152. package/dist/src/utils/feature-id-collision.js +1 -1
  153. package/dist/src/utils/feature-id-collision.js.map +1 -1
  154. package/dist/src/utils/html-to-mdx.d.ts +1 -0
  155. package/dist/src/utils/html-to-mdx.d.ts.map +1 -1
  156. package/dist/src/utils/html-to-mdx.js +43 -5
  157. package/dist/src/utils/html-to-mdx.js.map +1 -1
  158. package/package.json +1 -5
  159. package/plugins/specweave/agents/pm/AGENT.md +10 -7
  160. package/plugins/specweave/commands/specweave-archive-features.md +5 -7
  161. package/plugins/specweave/commands/specweave-archive.md +2 -1
  162. package/plugins/specweave/commands/specweave-do.md +35 -1
  163. package/plugins/specweave/commands/specweave-done.md +96 -0
  164. package/plugins/specweave/commands/specweave-external.md +150 -0
  165. package/plugins/specweave/commands/specweave-import-external.md +45 -18
  166. package/plugins/specweave/commands/specweave-increment.md +331 -33
  167. package/plugins/specweave/commands/specweave-jobs.md +2 -2
  168. package/plugins/specweave/commands/specweave-progress.md +4 -4
  169. package/plugins/specweave/commands/specweave-restore-feature.md +5 -4
  170. package/plugins/specweave/commands/specweave-sync-docs.md +1 -1
  171. package/plugins/specweave/commands/specweave-sync-specs.md +216 -322
  172. package/plugins/specweave/commands/specweave-validate-features.md +13 -8
  173. package/plugins/specweave/hooks/docs-changed.sh.backup +79 -0
  174. package/plugins/specweave/hooks/hooks.json +33 -4
  175. package/plugins/specweave/hooks/human-input-required.sh.backup +75 -0
  176. package/plugins/specweave/hooks/lib/common-setup.sh +375 -0
  177. package/plugins/specweave/hooks/lib/crash-prevention.sh +336 -0
  178. package/plugins/specweave/hooks/post-first-increment.sh.backup +61 -0
  179. package/plugins/specweave/hooks/post-increment-change.sh.backup +98 -0
  180. package/plugins/specweave/hooks/post-increment-completion.sh.backup +231 -0
  181. package/plugins/specweave/hooks/post-increment-planning.sh.backup +1048 -0
  182. package/plugins/specweave/hooks/post-increment-status-change.sh.backup +147 -0
  183. package/plugins/specweave/hooks/post-spec-update.sh.backup +158 -0
  184. package/plugins/specweave/hooks/post-task-completion.sh +4 -23
  185. package/plugins/specweave/hooks/post-user-story-complete.sh.backup +179 -0
  186. package/plugins/specweave/hooks/pre-command-deduplication.sh +1 -6
  187. package/plugins/specweave/hooks/pre-command-deduplication.sh.backup +83 -0
  188. package/plugins/specweave/hooks/pre-implementation.sh.backup +67 -0
  189. package/plugins/specweave/hooks/pre-task-completion.sh +8 -37
  190. package/plugins/specweave/hooks/pre-task-completion.sh.backup +194 -0
  191. package/plugins/specweave/hooks/pre-tool-use.sh +2 -11
  192. package/plugins/specweave/hooks/pre-tool-use.sh.backup +133 -0
  193. package/plugins/specweave/hooks/universal/dispatcher.mjs +135 -42
  194. package/plugins/specweave/hooks/universal/fail-fast-wrapper.sh +183 -0
  195. package/plugins/specweave/hooks/universal/hook-wrapper.cmd +26 -26
  196. package/plugins/specweave/hooks/universal/session-start.cmd +16 -16
  197. package/plugins/specweave/hooks/universal/session-start.ps1 +16 -16
  198. package/plugins/specweave/hooks/user-prompt-submit.sh +140 -38
  199. package/plugins/specweave/hooks/user-prompt-submit.sh.backup +386 -0
  200. package/plugins/specweave/hooks/v2/dispatchers/post-tool-use.sh +12 -0
  201. package/plugins/specweave/hooks/v2/dispatchers/session-start.sh +89 -0
  202. package/plugins/specweave/hooks/v2/guards/bash-file-guard.sh +211 -0
  203. package/plugins/specweave/hooks/v2/guards/bash-file-guard.test.sh +163 -0
  204. package/plugins/specweave/hooks/v2/guards/completion-guard.sh +26 -28
  205. package/plugins/specweave/hooks/v2/guards/features-folder-guard.sh +50 -0
  206. package/plugins/specweave/lib/vendor/core/increment/duplicate-detector.js +2 -2
  207. package/plugins/specweave/lib/vendor/core/increment/duplicate-detector.js.map +1 -1
  208. package/plugins/specweave/scripts/README.md +166 -0
  209. package/plugins/specweave/scripts/cleanup-state.sh +142 -0
  210. package/plugins/specweave/scripts/force-kill.sh +142 -0
  211. package/plugins/specweave/scripts/jobs.js +171 -0
  212. package/plugins/specweave/scripts/progress.js +170 -0
  213. package/plugins/specweave/scripts/read-costs.sh +132 -0
  214. package/plugins/specweave/scripts/read-jobs.sh +324 -0
  215. package/plugins/specweave/scripts/read-progress.sh +185 -0
  216. package/plugins/specweave/scripts/read-status.sh +146 -0
  217. package/plugins/specweave/scripts/read-workflow.sh +173 -0
  218. package/plugins/specweave/scripts/rebuild-dashboard-cache.sh +327 -0
  219. package/plugins/specweave/scripts/session-watchdog.sh +192 -0
  220. package/plugins/specweave/scripts/status.js +154 -0
  221. package/plugins/specweave/scripts/update-dashboard-cache.sh +281 -0
  222. package/plugins/specweave/skills/increment-planner/SKILL.md +333 -24
  223. package/plugins/specweave/skills/increment-planner/templates/spec-multi-project.md +17 -9
  224. package/plugins/specweave/skills/increment-planner/templates/spec-single-project.md +6 -2
  225. package/plugins/specweave/skills/instant-status/SKILL.md +70 -0
  226. package/plugins/specweave-ado/hooks/post-living-docs-update.sh.backup +353 -0
  227. package/plugins/specweave-ado/hooks/post-task-completion.sh.backup +172 -0
  228. package/plugins/specweave-ado/lib/enhanced-ado-sync.js +170 -0
  229. package/plugins/specweave-docs/commands/build.md +32 -4
  230. package/plugins/specweave-docs/commands/preview.md +43 -1
  231. package/plugins/specweave-docs/commands/validate.md +250 -0
  232. package/plugins/specweave-github/hooks/.specweave/logs/hooks-debug.log +1262 -626
  233. package/plugins/specweave-github/hooks/post-task-completion.sh.backup +258 -0
  234. package/plugins/specweave-github/lib/enhanced-github-sync.js +220 -0
  235. package/plugins/specweave-jira/hooks/post-task-completion.sh.backup +172 -0
  236. package/plugins/specweave-jira/lib/enhanced-jira-sync.js +134 -0
  237. package/plugins/specweave-release/hooks/.specweave/logs/dora-tracking.log +1254 -939
  238. package/plugins/specweave-release/hooks/post-task-completion.sh.backup +110 -0
  239. package/plugins/specweave/hooks/post-edit-spec.sh +0 -265
  240. package/plugins/specweave/hooks/post-write-spec.sh +0 -267
  241. package/plugins/specweave/hooks/pre-edit-spec.sh +0 -151
  242. package/plugins/specweave/hooks/pre-write-spec.sh +0 -151
@@ -0,0 +1,336 @@
1
+ #!/bin/bash
2
+ # crash-prevention.sh - Unified Crash Prevention Runtime
3
+ #
4
+ # Consolidates ALL crash prevention patterns from 9 crash categories:
5
+ # 1. Bash heredoc hangs (infinite wait for EOF)
6
+ # 2. Context explosion (>280KB total)
7
+ # 3. Hook recursion loops
8
+ # 4. Process storms (bulk operations)
9
+ # 5. Agent chunking violations
10
+ # 6. Direct completion bypass
11
+ # 7. Hook registration duplicates
12
+ # 8. Context compaction deadlock
13
+ # 9. MCP connection drops
14
+ #
15
+ # This is the SINGLE SOURCE OF TRUTH for crash prevention.
16
+ # Consolidated from ADRs: 0060, 0068, 0073, 0127, 0128, 0130, 0133, 0157, 0189
17
+ #
18
+ # v0.33.0 - Initial consolidation
19
+
20
+ set +e
21
+
22
+ # ============================================================================
23
+ # CRASH CATEGORY 1: BASH HEREDOC DETECTION
24
+ # ============================================================================
25
+
26
+ # Patterns that cause INFINITE HANGS (shell waits forever for EOF)
27
+ detect_bash_hang_pattern() {
28
+ local command="$1"
29
+
30
+ # Heredoc patterns (MOST DANGEROUS)
31
+ if echo "$command" | grep -qE "<<-?[[:space:]]*['\"]?[A-Za-z_]+" 2>/dev/null; then
32
+ echo "heredoc"
33
+ return 0
34
+ fi
35
+
36
+ # Cat stdin redirect (waits forever)
37
+ if echo "$command" | grep -qE "^[[:space:]]*cat[[:space:]]+>[[:space:]]*[^>]" 2>/dev/null; then
38
+ echo "cat-stdin"
39
+ return 0
40
+ fi
41
+
42
+ # DD command with output file
43
+ if echo "$command" | grep -qE "^[[:space:]]*dd[[:space:]].*of=" 2>/dev/null; then
44
+ echo "dd-stdin"
45
+ return 0
46
+ fi
47
+
48
+ # Echo/printf to file (truncation risk)
49
+ if echo "$command" | grep -qE "^[[:space:]]*(echo|printf)[[:space:]]" 2>/dev/null; then
50
+ if echo "$command" | grep -qE '>[[:space:]]*[^>]' 2>/dev/null; then
51
+ if ! echo "$command" | grep -qE '>>' 2>/dev/null; then
52
+ echo "echo-redirect"
53
+ return 0
54
+ fi
55
+ fi
56
+ fi
57
+
58
+ return 1
59
+ }
60
+
61
+ # ============================================================================
62
+ # CRASH CATEGORY 2: CONTEXT BUDGET ESTIMATION
63
+ # ============================================================================
64
+
65
+ # Rough token estimation (1 token ≈ 4 chars)
66
+ estimate_tokens() {
67
+ local file="$1"
68
+ if [[ -f "$file" ]]; then
69
+ local chars
70
+ chars=$(wc -c < "$file" 2>/dev/null || echo "0")
71
+ echo $((chars / 4))
72
+ else
73
+ echo "0"
74
+ fi
75
+ }
76
+
77
+ # Check if context is in danger zone
78
+ check_context_budget() {
79
+ local project_root="$1"
80
+ local active_increment="$2"
81
+
82
+ local total_tokens=0
83
+ local warning_threshold=150000 # ~150K tokens
84
+ local danger_threshold=200000 # ~200K tokens
85
+
86
+ # Estimate increment context
87
+ if [[ -n "$active_increment" ]] && [[ -d "$project_root/.specweave/increments/$active_increment" ]]; then
88
+ local inc_dir="$project_root/.specweave/increments/$active_increment"
89
+
90
+ local spec_tokens=$(estimate_tokens "$inc_dir/spec.md")
91
+ local plan_tokens=$(estimate_tokens "$inc_dir/plan.md")
92
+ local tasks_tokens=$(estimate_tokens "$inc_dir/tasks.md")
93
+
94
+ total_tokens=$((spec_tokens + plan_tokens + tasks_tokens))
95
+ fi
96
+
97
+ # Return status
98
+ if [[ $total_tokens -gt $danger_threshold ]]; then
99
+ echo "DANGER:$total_tokens"
100
+ return 2
101
+ elif [[ $total_tokens -gt $warning_threshold ]]; then
102
+ echo "WARNING:$total_tokens"
103
+ return 1
104
+ else
105
+ echo "OK:$total_tokens"
106
+ return 0
107
+ fi
108
+ }
109
+
110
+ # Count tasks in active increment
111
+ count_increment_tasks() {
112
+ local project_root="$1"
113
+ local active_increment="$2"
114
+
115
+ local tasks_file="$project_root/.specweave/increments/$active_increment/tasks.md"
116
+ if [[ -f "$tasks_file" ]]; then
117
+ grep -c "^### T-" "$tasks_file" 2>/dev/null || echo "0"
118
+ else
119
+ echo "0"
120
+ fi
121
+ }
122
+
123
+ # ============================================================================
124
+ # CRASH CATEGORY 3: PROCESS STORM DETECTION
125
+ # ============================================================================
126
+
127
+ # Count running hook processes
128
+ count_hook_processes() {
129
+ ps aux 2>/dev/null | grep -c "specweave.*hook" || echo "0"
130
+ }
131
+
132
+ # Detect if we're in a process storm
133
+ detect_process_storm() {
134
+ local threshold="${1:-20}"
135
+ local count
136
+ count=$(count_hook_processes)
137
+
138
+ if [[ "$count" -gt "$threshold" ]]; then
139
+ echo "STORM:$count"
140
+ return 1
141
+ fi
142
+ echo "OK:$count"
143
+ return 0
144
+ }
145
+
146
+ # ============================================================================
147
+ # CRASH CATEGORY 4: ZOMBIE PROCESS DETECTION
148
+ # ============================================================================
149
+
150
+ # Find and kill zombie heredoc processes
151
+ kill_zombie_heredocs() {
152
+ # Kill any cat processes waiting for EOF
153
+ pkill -f "cat.*EOF" 2>/dev/null || true
154
+ pkill -f "cat.*<<" 2>/dev/null || true
155
+
156
+ # Kill stale bash processes related to specweave hooks
157
+ local stale_pids
158
+ stale_pids=$(ps aux 2>/dev/null | grep -E "bash.*specweave.*hook" | grep -v grep | awk '{print $2}' | head -10)
159
+
160
+ for pid in $stale_pids; do
161
+ # Check if process is older than 30 seconds
162
+ local elapsed
163
+ elapsed=$(ps -o etimes= -p "$pid" 2>/dev/null | tr -d ' ')
164
+ if [[ -n "$elapsed" ]] && [[ "$elapsed" -gt 30 ]]; then
165
+ kill -9 "$pid" 2>/dev/null || true
166
+ fi
167
+ done
168
+ }
169
+
170
+ # ============================================================================
171
+ # CRASH CATEGORY 5: LOCK FILE CLEANUP
172
+ # ============================================================================
173
+
174
+ # Clean stale lock files (older than 60s)
175
+ clean_stale_locks() {
176
+ local project_root="$1"
177
+ local state_dir="$project_root/.specweave/state"
178
+
179
+ [[ ! -d "$state_dir" ]] && return
180
+
181
+ find "$state_dir" -name "*.lock" -type d -mmin +1 2>/dev/null | while read -r lock; do
182
+ rmdir "$lock" 2>/dev/null || true
183
+ done
184
+
185
+ # Also clean stale guard files
186
+ find "$state_dir" -name ".hook-*-guard" -type f -mmin +1 2>/dev/null | while read -r guard; do
187
+ rm -f "$guard" 2>/dev/null
188
+ done
189
+ }
190
+
191
+ # ============================================================================
192
+ # CRASH CATEGORY 6: SESSION HEALTH CHECK
193
+ # ============================================================================
194
+
195
+ # Comprehensive health check
196
+ check_session_health() {
197
+ local project_root="$1"
198
+ local issues=()
199
+
200
+ # Check 1: Process storm
201
+ local storm_status
202
+ storm_status=$(detect_process_storm 15)
203
+ if [[ "$storm_status" == STORM* ]]; then
204
+ issues+=("Process storm detected: $storm_status")
205
+ fi
206
+
207
+ # Check 2: Stale locks
208
+ local stale_locks
209
+ stale_locks=$(find "$project_root/.specweave/state" -name "*.lock" -type d -mmin +1 2>/dev/null | wc -l | tr -d ' ')
210
+ if [[ "$stale_locks" -gt 0 ]]; then
211
+ issues+=("Stale locks: $stale_locks")
212
+ fi
213
+
214
+ # Check 3: Circuit breaker status
215
+ local cb_file="$project_root/.specweave/state/.hook-circuit-breaker"
216
+ if [[ -f "$cb_file" ]]; then
217
+ local failures
218
+ failures=$(cat "$cb_file" 2>/dev/null || echo "0")
219
+ if [[ "$failures" -ge 3 ]]; then
220
+ issues+=("Circuit breaker OPEN: $failures failures")
221
+ fi
222
+ fi
223
+
224
+ # Check 4: Active increment task count
225
+ local active_inc
226
+ active_inc=$(find "$project_root/.specweave/increments" -maxdepth 1 -type d -name "[0-9]*" 2>/dev/null | head -1 | xargs basename 2>/dev/null)
227
+ if [[ -n "$active_inc" ]]; then
228
+ local task_count
229
+ task_count=$(count_increment_tasks "$project_root" "$active_inc")
230
+ if [[ "$task_count" -gt 8 ]]; then
231
+ issues+=("Task count exceeds limit: $task_count/8 in $active_inc")
232
+ fi
233
+ fi
234
+
235
+ # Report
236
+ if [[ ${#issues[@]} -eq 0 ]]; then
237
+ echo "HEALTHY"
238
+ return 0
239
+ else
240
+ echo "ISSUES:"
241
+ printf '%s\n' "${issues[@]}"
242
+ return 1
243
+ fi
244
+ }
245
+
246
+ # ============================================================================
247
+ # CRASH CATEGORY 7: EMERGENCY CLEANUP
248
+ # ============================================================================
249
+
250
+ # Nuclear option: clean ALL state
251
+ emergency_cleanup() {
252
+ local project_root="$1"
253
+
254
+ echo "=== EMERGENCY CLEANUP ==="
255
+
256
+ # 1. Kill zombie processes
257
+ echo "1. Killing zombie processes..."
258
+ kill_zombie_heredocs
259
+ pkill -9 -f "bash.*specweave" 2>/dev/null || true
260
+
261
+ # 2. Remove all locks
262
+ echo "2. Removing all locks..."
263
+ rm -rf "$project_root/.specweave/state/"*.lock 2>/dev/null
264
+ rm -f "$project_root/.specweave/state/.hook-"* 2>/dev/null
265
+ rm -f "$project_root/.specweave/state/.processor.lock" 2>/dev/null
266
+
267
+ # 3. Reset circuit breakers
268
+ echo "3. Resetting circuit breakers..."
269
+ rm -f "$project_root/.specweave/state/.hook-circuit-breaker"* 2>/dev/null
270
+
271
+ # 4. Clear dedup cache
272
+ echo "4. Clearing dedup cache..."
273
+ rm -rf "$project_root/.specweave/state/.dedup-cache" 2>/dev/null
274
+
275
+ # 5. Clear bulk operation counter
276
+ echo "5. Clearing bulk operation counter..."
277
+ rm -f "$project_root/.specweave/state/.bulk-op-counter" 2>/dev/null
278
+
279
+ echo "=== CLEANUP COMPLETE ==="
280
+ echo "Restart Claude Code to continue."
281
+ }
282
+
283
+ # ============================================================================
284
+ # RUNTIME GUARDS (for use in hooks)
285
+ # ============================================================================
286
+
287
+ # Pre-execution guard for any hook
288
+ guard_hook_execution() {
289
+ local hook_name="$1"
290
+ local project_root="$2"
291
+
292
+ # Check for process storm
293
+ local storm
294
+ storm=$(detect_process_storm 20)
295
+ if [[ "$storm" == STORM* ]]; then
296
+ echo "[GUARD] Blocking $hook_name: $storm" >&2
297
+ return 1
298
+ fi
299
+
300
+ return 0
301
+ }
302
+
303
+ # ============================================================================
304
+ # MAIN (when run directly)
305
+ # ============================================================================
306
+
307
+ if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
308
+ case "${1:-health}" in
309
+ health)
310
+ PROJECT_ROOT=$(find "$PWD" -maxdepth 3 -type d -name ".specweave" 2>/dev/null | head -1 | xargs dirname 2>/dev/null)
311
+ if [[ -n "$PROJECT_ROOT" ]]; then
312
+ check_session_health "$PROJECT_ROOT"
313
+ else
314
+ echo "Not in a SpecWeave project"
315
+ exit 1
316
+ fi
317
+ ;;
318
+ cleanup)
319
+ PROJECT_ROOT=$(find "$PWD" -maxdepth 3 -type d -name ".specweave" 2>/dev/null | head -1 | xargs dirname 2>/dev/null)
320
+ if [[ -n "$PROJECT_ROOT" ]]; then
321
+ emergency_cleanup "$PROJECT_ROOT"
322
+ else
323
+ echo "Not in a SpecWeave project"
324
+ exit 1
325
+ fi
326
+ ;;
327
+ kill-zombies)
328
+ kill_zombie_heredocs
329
+ echo "Zombie processes cleaned"
330
+ ;;
331
+ *)
332
+ echo "Usage: $0 {health|cleanup|kill-zombies}"
333
+ exit 1
334
+ ;;
335
+ esac
336
+ fi
@@ -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
@@ -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