specweave 0.32.0 β†’ 0.32.3

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 (347) hide show
  1. package/CLAUDE.md +215 -2
  2. package/README.md +22 -0
  3. package/bin/specweave.js +52 -1
  4. package/dist/plugins/specweave-ado/lib/ado-duplicate-detector.d.ts +100 -0
  5. package/dist/plugins/specweave-ado/lib/ado-duplicate-detector.d.ts.map +1 -0
  6. package/dist/plugins/specweave-ado/lib/ado-duplicate-detector.js +291 -0
  7. package/dist/plugins/specweave-ado/lib/ado-duplicate-detector.js.map +1 -0
  8. package/dist/plugins/specweave-jira/lib/jira-duplicate-detector.d.ts +103 -0
  9. package/dist/plugins/specweave-jira/lib/jira-duplicate-detector.d.ts.map +1 -0
  10. package/dist/plugins/specweave-jira/lib/jira-duplicate-detector.js +310 -0
  11. package/dist/plugins/specweave-jira/lib/jira-duplicate-detector.js.map +1 -0
  12. package/dist/plugins/specweave-jira/lib/jira-permission-gate.d.ts +126 -0
  13. package/dist/plugins/specweave-jira/lib/jira-permission-gate.d.ts.map +1 -0
  14. package/dist/plugins/specweave-jira/lib/jira-permission-gate.js +207 -0
  15. package/dist/plugins/specweave-jira/lib/jira-permission-gate.js.map +1 -0
  16. package/dist/src/adapters/codex/README.md +1 -1
  17. package/dist/src/adapters/codex/adapter.js +1 -1
  18. package/dist/src/cli/commands/archive.d.ts +2 -0
  19. package/dist/src/cli/commands/archive.d.ts.map +1 -1
  20. package/dist/src/cli/commands/archive.js +33 -0
  21. package/dist/src/cli/commands/archive.js.map +1 -1
  22. package/dist/src/cli/commands/cache.d.ts +17 -0
  23. package/dist/src/cli/commands/cache.d.ts.map +1 -0
  24. package/dist/src/cli/commands/cache.js +126 -0
  25. package/dist/src/cli/commands/cache.js.map +1 -0
  26. package/dist/src/cli/commands/context.d.ts +92 -0
  27. package/dist/src/cli/commands/context.d.ts.map +1 -0
  28. package/dist/src/cli/commands/context.js +205 -0
  29. package/dist/src/cli/commands/context.js.map +1 -0
  30. package/dist/src/cli/commands/init.d.ts.map +1 -1
  31. package/dist/src/cli/commands/init.js +112 -70
  32. package/dist/src/cli/commands/init.js.map +1 -1
  33. package/dist/src/cli/commands/plan/increment-detector.js +2 -2
  34. package/dist/src/cli/commands/plan/increment-detector.js.map +1 -1
  35. package/dist/src/cli/commands/sync-spec-commits.js +1 -1
  36. package/dist/src/cli/commands/sync-spec-commits.js.map +1 -1
  37. package/dist/src/cli/commands/sync-specs.js +2 -2
  38. package/dist/src/cli/commands/sync-specs.js.map +1 -1
  39. package/dist/src/cli/helpers/github/increment-profile-selector.js +1 -1
  40. package/dist/src/cli/helpers/github/increment-profile-selector.js.map +1 -1
  41. package/dist/src/cli/helpers/init/external-import.d.ts +3 -0
  42. package/dist/src/cli/helpers/init/external-import.d.ts.map +1 -1
  43. package/dist/src/cli/helpers/init/external-import.js +17 -4
  44. package/dist/src/cli/helpers/init/external-import.js.map +1 -1
  45. package/dist/src/cli/helpers/init/index.d.ts +1 -0
  46. package/dist/src/cli/helpers/init/index.d.ts.map +1 -1
  47. package/dist/src/cli/helpers/init/index.js +2 -0
  48. package/dist/src/cli/helpers/init/index.js.map +1 -1
  49. package/dist/src/cli/helpers/init/jira-ado-auto-detect.d.ts +70 -0
  50. package/dist/src/cli/helpers/init/jira-ado-auto-detect.d.ts.map +1 -1
  51. package/dist/src/cli/helpers/init/jira-ado-auto-detect.js +214 -4
  52. package/dist/src/cli/helpers/init/jira-ado-auto-detect.js.map +1 -1
  53. package/dist/src/cli/helpers/init/living-docs-preflight.d.ts +4 -0
  54. package/dist/src/cli/helpers/init/living-docs-preflight.d.ts.map +1 -1
  55. package/dist/src/cli/helpers/init/living-docs-preflight.js +34 -3
  56. package/dist/src/cli/helpers/init/living-docs-preflight.js.map +1 -1
  57. package/dist/src/cli/helpers/init/testing-config.d.ts +3 -0
  58. package/dist/src/cli/helpers/init/testing-config.d.ts.map +1 -1
  59. package/dist/src/cli/helpers/init/testing-config.js +9 -2
  60. package/dist/src/cli/helpers/init/testing-config.js.map +1 -1
  61. package/dist/src/cli/helpers/init/translation-config.d.ts +3 -0
  62. package/dist/src/cli/helpers/init/translation-config.d.ts.map +1 -1
  63. package/dist/src/cli/helpers/init/translation-config.js +21 -4
  64. package/dist/src/cli/helpers/init/translation-config.js.map +1 -1
  65. package/dist/src/cli/helpers/init/wizard-navigation.d.ts +45 -0
  66. package/dist/src/cli/helpers/init/wizard-navigation.d.ts.map +1 -0
  67. package/dist/src/cli/helpers/init/wizard-navigation.js +97 -0
  68. package/dist/src/cli/helpers/init/wizard-navigation.js.map +1 -0
  69. package/dist/src/cli/workers/living-docs-worker.js +66 -1
  70. package/dist/src/cli/workers/living-docs-worker.js.map +1 -1
  71. package/dist/src/config/types.d.ts +203 -1208
  72. package/dist/src/config/types.d.ts.map +1 -1
  73. package/dist/src/core/discrepancy/increment-generator.d.ts.map +1 -1
  74. package/dist/src/core/discrepancy/increment-generator.js +5 -2
  75. package/dist/src/core/discrepancy/increment-generator.js.map +1 -1
  76. package/dist/src/core/increment/duplicate-detector.js +2 -2
  77. package/dist/src/core/increment/duplicate-detector.js.map +1 -1
  78. package/dist/src/core/increment/increment-archiver.d.ts +49 -4
  79. package/dist/src/core/increment/increment-archiver.d.ts.map +1 -1
  80. package/dist/src/core/increment/increment-archiver.js +123 -22
  81. package/dist/src/core/increment/increment-archiver.js.map +1 -1
  82. package/dist/src/core/increment/increment-status.js +2 -2
  83. package/dist/src/core/increment/increment-status.js.map +1 -1
  84. package/dist/src/core/increment/increment-utils.d.ts +150 -0
  85. package/dist/src/core/increment/increment-utils.d.ts.map +1 -1
  86. package/dist/src/core/increment/increment-utils.js +216 -4
  87. package/dist/src/core/increment/increment-utils.js.map +1 -1
  88. package/dist/src/core/increment/metadata-validator.js +1 -1
  89. package/dist/src/core/increment/metadata-validator.js.map +1 -1
  90. package/dist/src/core/living-docs/feature-archiver.d.ts +4 -0
  91. package/dist/src/core/living-docs/feature-archiver.d.ts.map +1 -1
  92. package/dist/src/core/living-docs/feature-archiver.js +32 -10
  93. package/dist/src/core/living-docs/feature-archiver.js.map +1 -1
  94. package/dist/src/core/living-docs/feature-id-manager.d.ts.map +1 -1
  95. package/dist/src/core/living-docs/feature-id-manager.js +8 -4
  96. package/dist/src/core/living-docs/feature-id-manager.js.map +1 -1
  97. package/dist/src/core/living-docs/governance/ecosystem-detector.d.ts +38 -0
  98. package/dist/src/core/living-docs/governance/ecosystem-detector.d.ts.map +1 -0
  99. package/dist/src/core/living-docs/governance/ecosystem-detector.js +325 -0
  100. package/dist/src/core/living-docs/governance/ecosystem-detector.js.map +1 -0
  101. package/dist/src/core/living-docs/governance/frontend-standards-parser.d.ts +74 -0
  102. package/dist/src/core/living-docs/governance/frontend-standards-parser.d.ts.map +1 -0
  103. package/dist/src/core/living-docs/governance/frontend-standards-parser.js +366 -0
  104. package/dist/src/core/living-docs/governance/frontend-standards-parser.js.map +1 -0
  105. package/dist/src/core/living-docs/governance/go-standards-parser.d.ts +64 -0
  106. package/dist/src/core/living-docs/governance/go-standards-parser.d.ts.map +1 -0
  107. package/dist/src/core/living-docs/governance/go-standards-parser.js +229 -0
  108. package/dist/src/core/living-docs/governance/go-standards-parser.js.map +1 -0
  109. package/dist/src/core/living-docs/governance/index.d.ts +50 -0
  110. package/dist/src/core/living-docs/governance/index.d.ts.map +1 -0
  111. package/dist/src/core/living-docs/governance/index.js +56 -0
  112. package/dist/src/core/living-docs/governance/index.js.map +1 -0
  113. package/dist/src/core/living-docs/governance/java-standards-parser.d.ts +89 -0
  114. package/dist/src/core/living-docs/governance/java-standards-parser.d.ts.map +1 -0
  115. package/dist/src/core/living-docs/governance/java-standards-parser.js +356 -0
  116. package/dist/src/core/living-docs/governance/java-standards-parser.js.map +1 -0
  117. package/dist/src/core/living-docs/governance/python-standards-parser.d.ts +83 -0
  118. package/dist/src/core/living-docs/governance/python-standards-parser.d.ts.map +1 -0
  119. package/dist/src/core/living-docs/governance/python-standards-parser.js +347 -0
  120. package/dist/src/core/living-docs/governance/python-standards-parser.js.map +1 -0
  121. package/dist/src/core/living-docs/governance/standards-generator.d.ts +38 -0
  122. package/dist/src/core/living-docs/governance/standards-generator.d.ts.map +1 -0
  123. package/dist/src/core/living-docs/governance/standards-generator.js +476 -0
  124. package/dist/src/core/living-docs/governance/standards-generator.js.map +1 -0
  125. package/dist/src/core/living-docs/hierarchy-mapper.js +3 -3
  126. package/dist/src/core/living-docs/hierarchy-mapper.js.map +1 -1
  127. package/dist/src/core/living-docs/intelligent-analyzer/architecture-generator.d.ts +18 -0
  128. package/dist/src/core/living-docs/intelligent-analyzer/architecture-generator.d.ts.map +1 -0
  129. package/dist/src/core/living-docs/intelligent-analyzer/architecture-generator.js +299 -0
  130. package/dist/src/core/living-docs/intelligent-analyzer/architecture-generator.js.map +1 -0
  131. package/dist/src/core/living-docs/intelligent-analyzer/deep-repo-analyzer.d.ts +15 -0
  132. package/dist/src/core/living-docs/intelligent-analyzer/deep-repo-analyzer.d.ts.map +1 -0
  133. package/dist/src/core/living-docs/intelligent-analyzer/deep-repo-analyzer.js +138 -0
  134. package/dist/src/core/living-docs/intelligent-analyzer/deep-repo-analyzer.js.map +1 -0
  135. package/dist/src/core/living-docs/intelligent-analyzer/file-sampler.d.ts +24 -0
  136. package/dist/src/core/living-docs/intelligent-analyzer/file-sampler.d.ts.map +1 -0
  137. package/dist/src/core/living-docs/intelligent-analyzer/file-sampler.js +198 -0
  138. package/dist/src/core/living-docs/intelligent-analyzer/file-sampler.js.map +1 -0
  139. package/dist/src/core/living-docs/intelligent-analyzer/inconsistency-detector.d.ts +17 -0
  140. package/dist/src/core/living-docs/intelligent-analyzer/inconsistency-detector.d.ts.map +1 -0
  141. package/dist/src/core/living-docs/intelligent-analyzer/inconsistency-detector.js +241 -0
  142. package/dist/src/core/living-docs/intelligent-analyzer/inconsistency-detector.js.map +1 -0
  143. package/dist/src/core/living-docs/intelligent-analyzer/index.d.ts +28 -0
  144. package/dist/src/core/living-docs/intelligent-analyzer/index.d.ts.map +1 -0
  145. package/dist/src/core/living-docs/intelligent-analyzer/index.js +197 -0
  146. package/dist/src/core/living-docs/intelligent-analyzer/index.js.map +1 -0
  147. package/dist/src/core/living-docs/intelligent-analyzer/organization-synthesizer.d.ts +22 -0
  148. package/dist/src/core/living-docs/intelligent-analyzer/organization-synthesizer.d.ts.map +1 -0
  149. package/dist/src/core/living-docs/intelligent-analyzer/organization-synthesizer.js +482 -0
  150. package/dist/src/core/living-docs/intelligent-analyzer/organization-synthesizer.js.map +1 -0
  151. package/dist/src/core/living-docs/intelligent-analyzer/strategy-generator.d.ts +42 -0
  152. package/dist/src/core/living-docs/intelligent-analyzer/strategy-generator.d.ts.map +1 -0
  153. package/dist/src/core/living-docs/intelligent-analyzer/strategy-generator.js +343 -0
  154. package/dist/src/core/living-docs/intelligent-analyzer/strategy-generator.js.map +1 -0
  155. package/dist/src/core/living-docs/intelligent-analyzer/types.d.ts +190 -0
  156. package/dist/src/core/living-docs/intelligent-analyzer/types.d.ts.map +1 -0
  157. package/dist/src/core/living-docs/intelligent-analyzer/types.js +7 -0
  158. package/dist/src/core/living-docs/intelligent-analyzer/types.js.map +1 -0
  159. package/dist/src/core/living-docs/living-docs-sync.d.ts +11 -3
  160. package/dist/src/core/living-docs/living-docs-sync.d.ts.map +1 -1
  161. package/dist/src/core/living-docs/living-docs-sync.js +53 -10
  162. package/dist/src/core/living-docs/living-docs-sync.js.map +1 -1
  163. package/dist/src/core/living-docs/module-analyzer.d.ts +22 -0
  164. package/dist/src/core/living-docs/module-analyzer.d.ts.map +1 -1
  165. package/dist/src/core/living-docs/module-analyzer.js +123 -19
  166. package/dist/src/core/living-docs/module-analyzer.js.map +1 -1
  167. package/dist/src/core/llm/provider-factory.js +2 -2
  168. package/dist/src/core/llm/provider-factory.js.map +1 -1
  169. package/dist/src/core/llm/providers/anthropic-provider.js +1 -1
  170. package/dist/src/core/llm/providers/bedrock-provider.d.ts.map +1 -1
  171. package/dist/src/core/llm/providers/bedrock-provider.js +8 -4
  172. package/dist/src/core/llm/providers/bedrock-provider.js.map +1 -1
  173. package/dist/src/core/sync/spec-increment-mapper.js +3 -3
  174. package/dist/src/core/sync/spec-increment-mapper.js.map +1 -1
  175. package/dist/src/importers/item-converter.d.ts +25 -0
  176. package/dist/src/importers/item-converter.d.ts.map +1 -1
  177. package/dist/src/importers/item-converter.js +135 -5
  178. package/dist/src/importers/item-converter.js.map +1 -1
  179. package/dist/src/importers/jira-importer.d.ts +14 -0
  180. package/dist/src/importers/jira-importer.d.ts.map +1 -1
  181. package/dist/src/importers/jira-importer.js +75 -0
  182. package/dist/src/importers/jira-importer.js.map +1 -1
  183. package/dist/src/init/architecture/types.d.ts +33 -140
  184. package/dist/src/init/architecture/types.d.ts.map +1 -1
  185. package/dist/src/init/compliance/types.d.ts +30 -27
  186. package/dist/src/init/compliance/types.d.ts.map +1 -1
  187. package/dist/src/init/repo/types.d.ts +11 -34
  188. package/dist/src/init/repo/types.d.ts.map +1 -1
  189. package/dist/src/init/research/src/config/types.d.ts +15 -82
  190. package/dist/src/init/research/src/config/types.d.ts.map +1 -1
  191. package/dist/src/init/research/types.d.ts +38 -93
  192. package/dist/src/init/research/types.d.ts.map +1 -1
  193. package/dist/src/init/team/types.d.ts +4 -42
  194. package/dist/src/init/team/types.d.ts.map +1 -1
  195. package/dist/src/integrations/jira/jira-token-provider.d.ts +93 -0
  196. package/dist/src/integrations/jira/jira-token-provider.d.ts.map +1 -0
  197. package/dist/src/integrations/jira/jira-token-provider.js +160 -0
  198. package/dist/src/integrations/jira/jira-token-provider.js.map +1 -0
  199. package/dist/src/sync/ado-reconciler.d.ts +92 -0
  200. package/dist/src/sync/ado-reconciler.d.ts.map +1 -0
  201. package/dist/src/sync/ado-reconciler.js +335 -0
  202. package/dist/src/sync/ado-reconciler.js.map +1 -0
  203. package/dist/src/sync/jira-reconciler.d.ts +106 -0
  204. package/dist/src/sync/jira-reconciler.d.ts.map +1 -0
  205. package/dist/src/sync/jira-reconciler.js +405 -0
  206. package/dist/src/sync/jira-reconciler.js.map +1 -0
  207. package/dist/src/types/dashboard-cache.d.ts +181 -0
  208. package/dist/src/types/dashboard-cache.d.ts.map +1 -0
  209. package/dist/src/types/dashboard-cache.js +65 -0
  210. package/dist/src/types/dashboard-cache.js.map +1 -0
  211. package/dist/src/types/model-selection.d.ts +6 -4
  212. package/dist/src/types/model-selection.d.ts.map +1 -1
  213. package/dist/src/types/model-selection.js +3 -1
  214. package/dist/src/types/model-selection.js.map +1 -1
  215. package/dist/src/utils/docs-validator.d.ts +131 -0
  216. package/dist/src/utils/docs-validator.d.ts.map +1 -0
  217. package/dist/src/utils/docs-validator.js +529 -0
  218. package/dist/src/utils/docs-validator.js.map +1 -0
  219. package/dist/src/utils/external-tool-drift-detector.d.ts +1 -1
  220. package/dist/src/utils/external-tool-drift-detector.d.ts.map +1 -1
  221. package/dist/src/utils/external-tool-drift-detector.js +5 -4
  222. package/dist/src/utils/external-tool-drift-detector.js.map +1 -1
  223. package/dist/src/utils/feature-id-collision.js +1 -1
  224. package/dist/src/utils/feature-id-collision.js.map +1 -1
  225. package/dist/src/utils/feature-id-derivation.d.ts +8 -3
  226. package/dist/src/utils/feature-id-derivation.d.ts.map +1 -1
  227. package/dist/src/utils/feature-id-derivation.js +14 -6
  228. package/dist/src/utils/feature-id-derivation.js.map +1 -1
  229. package/dist/src/utils/html-to-mdx.d.ts +1 -0
  230. package/dist/src/utils/html-to-mdx.d.ts.map +1 -1
  231. package/dist/src/utils/html-to-mdx.js +43 -5
  232. package/dist/src/utils/html-to-mdx.js.map +1 -1
  233. package/dist/src/utils/model-selection.d.ts +3 -4
  234. package/dist/src/utils/model-selection.d.ts.map +1 -1
  235. package/dist/src/utils/model-selection.js +3 -4
  236. package/dist/src/utils/model-selection.js.map +1 -1
  237. package/package.json +1 -1
  238. package/plugins/specweave/agents/code-standards-detective/AGENT.md +48 -0
  239. package/plugins/specweave/agents/pm/AGENT.md +10 -7
  240. package/plugins/specweave/commands/specweave-archive-features.md +5 -7
  241. package/plugins/specweave/commands/specweave-archive.md +2 -1
  242. package/plugins/specweave/commands/specweave-costs.md +4 -4
  243. package/plugins/specweave/commands/specweave-do.md +44 -10
  244. package/plugins/specweave/commands/specweave-done.md +109 -0
  245. package/plugins/specweave/commands/specweave-import-external.md +45 -18
  246. package/plugins/specweave/commands/specweave-increment.md +331 -33
  247. package/plugins/specweave/commands/specweave-jobs.md +2 -2
  248. package/plugins/specweave/commands/specweave-progress.md +4 -4
  249. package/plugins/specweave/commands/specweave-restore-feature.md +5 -4
  250. package/plugins/specweave/commands/specweave-sync-docs.md +1 -1
  251. package/plugins/specweave/commands/specweave-sync-specs.md +216 -322
  252. package/plugins/specweave/commands/specweave-validate-features.md +13 -8
  253. package/plugins/specweave/commands/specweave-validate.md +27 -1
  254. package/plugins/specweave/hooks/docs-changed.sh.backup +79 -0
  255. package/plugins/specweave/hooks/hooks.json +43 -4
  256. package/plugins/specweave/hooks/human-input-required.sh.backup +75 -0
  257. package/plugins/specweave/hooks/lib/common-setup.sh +375 -0
  258. package/plugins/specweave/hooks/lib/crash-prevention.sh +336 -0
  259. package/plugins/specweave/hooks/post-first-increment.sh.backup +61 -0
  260. package/plugins/specweave/hooks/post-increment-change.sh.backup +98 -0
  261. package/plugins/specweave/hooks/post-increment-completion.sh.backup +231 -0
  262. package/plugins/specweave/hooks/post-increment-planning.sh.backup +1048 -0
  263. package/plugins/specweave/hooks/post-increment-status-change.sh.backup +147 -0
  264. package/plugins/specweave/hooks/post-spec-update.sh.backup +158 -0
  265. package/plugins/specweave/hooks/post-task-completion.sh +4 -23
  266. package/plugins/specweave/hooks/post-user-story-complete.sh.backup +179 -0
  267. package/plugins/specweave/hooks/pre-command-deduplication.sh +1 -6
  268. package/plugins/specweave/hooks/pre-command-deduplication.sh.backup +83 -0
  269. package/plugins/specweave/hooks/pre-implementation.sh.backup +67 -0
  270. package/plugins/specweave/hooks/pre-task-completion.sh +8 -37
  271. package/plugins/specweave/hooks/pre-task-completion.sh.backup +194 -0
  272. package/plugins/specweave/hooks/pre-tool-use.sh +2 -11
  273. package/plugins/specweave/hooks/pre-tool-use.sh.backup +133 -0
  274. package/plugins/specweave/hooks/spec-project-validator.sh +80 -25
  275. package/plugins/specweave/hooks/universal/dispatcher.mjs +135 -42
  276. package/plugins/specweave/hooks/universal/fail-fast-wrapper.sh +183 -0
  277. package/plugins/specweave/hooks/user-prompt-submit.sh +140 -38
  278. package/plugins/specweave/hooks/user-prompt-submit.sh.backup +386 -0
  279. package/plugins/specweave/hooks/v2/dispatchers/post-tool-use.sh +12 -0
  280. package/plugins/specweave/hooks/v2/dispatchers/session-start.sh +89 -0
  281. package/plugins/specweave/hooks/v2/guards/bash-file-guard.sh +211 -0
  282. package/plugins/specweave/hooks/v2/guards/bash-file-guard.test.sh +163 -0
  283. package/plugins/specweave/hooks/v2/guards/completion-guard.sh +26 -28
  284. package/plugins/specweave/hooks/v2/guards/features-folder-guard.sh +50 -0
  285. package/plugins/specweave/hooks/v2/guards/increment-duplicate-guard.sh +135 -0
  286. package/plugins/specweave/lib/vendor/core/increment/duplicate-detector.js +2 -2
  287. package/plugins/specweave/lib/vendor/core/increment/duplicate-detector.js.map +1 -1
  288. package/plugins/specweave/scripts/README.md +166 -0
  289. package/plugins/specweave/scripts/cleanup-state.sh +142 -0
  290. package/plugins/specweave/scripts/force-kill.sh +142 -0
  291. package/plugins/specweave/scripts/jobs.js +171 -0
  292. package/plugins/specweave/scripts/progress.js +170 -0
  293. package/plugins/specweave/scripts/read-costs.sh +132 -0
  294. package/plugins/specweave/scripts/read-jobs.sh +324 -0
  295. package/plugins/specweave/scripts/read-progress.sh +185 -0
  296. package/plugins/specweave/scripts/read-status.sh +146 -0
  297. package/plugins/specweave/scripts/read-workflow.sh +173 -0
  298. package/plugins/specweave/scripts/rebuild-dashboard-cache.sh +327 -0
  299. package/plugins/specweave/scripts/session-watchdog.sh +192 -0
  300. package/plugins/specweave/scripts/status.js +154 -0
  301. package/plugins/specweave/scripts/update-dashboard-cache.sh +281 -0
  302. package/plugins/specweave/skills/code-standards-analyzer/SKILL.md +58 -6
  303. package/plugins/specweave/skills/increment-planner/SKILL.md +388 -48
  304. package/plugins/specweave/skills/increment-planner/templates/spec-multi-project.md +17 -7
  305. package/plugins/specweave/skills/increment-planner/templates/spec-single-project.md +6 -1
  306. package/plugins/specweave/skills/increment-planner/templates/tasks-multi-project.md +1 -1
  307. package/plugins/specweave/skills/increment-planner/templates/tasks-single-project.md +1 -1
  308. package/plugins/specweave/skills/instant-status/SKILL.md +70 -0
  309. package/plugins/specweave-ado/commands/cleanup-duplicates.md +212 -0
  310. package/plugins/specweave-ado/commands/reconcile.md +120 -0
  311. package/plugins/specweave-ado/hooks/post-living-docs-update.sh.backup +353 -0
  312. package/plugins/specweave-ado/hooks/post-task-completion.sh.backup +172 -0
  313. package/plugins/specweave-ado/lib/ado-duplicate-detector.js +279 -0
  314. package/plugins/specweave-ado/lib/ado-duplicate-detector.ts +407 -0
  315. package/plugins/specweave-ado/lib/enhanced-ado-sync.js +170 -0
  316. package/plugins/specweave-docs/commands/build.md +32 -4
  317. package/plugins/specweave-docs/commands/preview.md +43 -1
  318. package/plugins/specweave-docs/commands/validate.md +250 -0
  319. package/plugins/specweave-github/agents/github-manager/AGENT.md +2 -2
  320. package/plugins/specweave-github/hooks/.specweave/logs/hooks-debug.log +1262 -0
  321. package/plugins/specweave-github/hooks/post-task-completion.sh.backup +258 -0
  322. package/plugins/specweave-github/lib/enhanced-github-sync.js +220 -0
  323. package/plugins/specweave-infrastructure/skills/hetzner-provisioner/README.md +1 -1
  324. package/plugins/specweave-jira/agents/jira-manager/AGENT.md +1 -1
  325. package/plugins/specweave-jira/agents/jira-multi-project-mapper/AGENT.md +530 -0
  326. package/plugins/specweave-jira/agents/jira-sync-judge/AGENT.md +438 -0
  327. package/plugins/specweave-jira/commands/cleanup-duplicates.md +219 -0
  328. package/plugins/specweave-jira/commands/close.md +297 -0
  329. package/plugins/specweave-jira/commands/create.md +198 -0
  330. package/plugins/specweave-jira/commands/reconcile.md +123 -0
  331. package/plugins/specweave-jira/commands/status.md +215 -0
  332. package/plugins/specweave-jira/hooks/post-task-completion.sh.backup +172 -0
  333. package/plugins/specweave-jira/lib/enhanced-jira-sync.js +134 -0
  334. package/plugins/specweave-jira/lib/jira-duplicate-detector.js +296 -0
  335. package/plugins/specweave-jira/lib/jira-duplicate-detector.ts +434 -0
  336. package/plugins/specweave-jira/lib/jira-permission-gate.js +160 -0
  337. package/plugins/specweave-jira/lib/jira-permission-gate.ts +276 -0
  338. package/plugins/specweave-jira/lib/jira-profile-resolver.js +222 -0
  339. package/plugins/specweave-jira/lib/jira-profile-resolver.ts +427 -0
  340. package/plugins/specweave-jira/reference/jira-specweave-mapping.md +16 -11
  341. package/plugins/specweave-release/commands/specweave-release-npm.md +140 -14
  342. package/plugins/specweave-release/hooks/.specweave/logs/dora-tracking.log +1254 -0
  343. package/plugins/specweave-release/hooks/post-task-completion.sh.backup +110 -0
  344. package/plugins/specweave/hooks/post-edit-spec.sh +0 -265
  345. package/plugins/specweave/hooks/post-write-spec.sh +0 -267
  346. package/plugins/specweave/hooks/pre-edit-spec.sh +0 -151
  347. package/plugins/specweave/hooks/pre-write-spec.sh +0 -151
@@ -0,0 +1,327 @@
1
+ #!/usr/bin/env bash
2
+ # rebuild-dashboard-cache.sh - Full rebuild of dashboard cache
3
+ #
4
+ # Usage: bash rebuild-dashboard-cache.sh [--quiet]
5
+ #
6
+ # Scans all increments in .specweave/increments/ and builds complete cache.
7
+ # Uses atomic write pattern (temp file + rename) to prevent corruption.
8
+ #
9
+ # Output: .specweave/state/dashboard.json
10
+ #
11
+ # Compatible with bash 3.x (macOS default)
12
+
13
+ set -e
14
+
15
+ QUIET="${1:-}"
16
+ log() {
17
+ [[ "$QUIET" == "--quiet" ]] || echo "$@"
18
+ }
19
+
20
+ # Find project root
21
+ PROJECT_ROOT="$PWD"
22
+ while [[ "$PROJECT_ROOT" != "/" ]] && [[ ! -d "$PROJECT_ROOT/.specweave" ]]; do
23
+ PROJECT_ROOT=$(dirname "$PROJECT_ROOT")
24
+ done
25
+
26
+ if [[ ! -d "$PROJECT_ROOT/.specweave" ]]; then
27
+ echo "❌ No .specweave directory found"
28
+ exit 1
29
+ fi
30
+
31
+ INCREMENTS_DIR="$PROJECT_ROOT/.specweave/increments"
32
+ STATE_DIR="$PROJECT_ROOT/.specweave/state"
33
+ CACHE_FILE="$STATE_DIR/dashboard.json"
34
+ TEMP_FILE="$STATE_DIR/.dashboard.json.tmp.$$"
35
+ ARCHIVE_DIR="$INCREMENTS_DIR/_archive"
36
+
37
+ # Ensure state directory exists
38
+ mkdir -p "$STATE_DIR"
39
+
40
+ # Check if jq is available
41
+ if ! command -v jq >/dev/null 2>&1; then
42
+ echo "❌ jq is required for cache operations. Install with: brew install jq"
43
+ exit 1
44
+ fi
45
+
46
+ log "πŸ”„ Rebuilding dashboard cache..."
47
+
48
+ # Initialize counters using simple variables (bash 3.x compatible)
49
+ status_backlog=0
50
+ status_planned=0
51
+ status_active=0
52
+ status_paused=0
53
+ status_ready_for_review=0
54
+ status_completed=0
55
+ status_abandoned=0
56
+
57
+ type_feature=0
58
+ type_hotfix=0
59
+ type_bug=0
60
+ type_refactor=0
61
+ type_experiment=0
62
+ type_change_request=0
63
+
64
+ priority_P0=0
65
+ priority_P1=0
66
+ priority_P2=0
67
+ priority_P3=0
68
+
69
+ archived_count=0
70
+ total_count=0
71
+
72
+ # Start building JSON
73
+ increments_json="{}"
74
+ mtimes_json="{}"
75
+
76
+ # Process each increment directory
77
+ for increment_dir in "$INCREMENTS_DIR"/[0-9]*/; do
78
+ [[ -d "$increment_dir" ]] || continue
79
+
80
+ increment_id=$(basename "$increment_dir")
81
+ metadata_file="$increment_dir/metadata.json"
82
+ tasks_file="$increment_dir/tasks.md"
83
+ spec_file="$increment_dir/spec.md"
84
+
85
+ # Skip if no metadata
86
+ [[ -f "$metadata_file" ]] || continue
87
+
88
+ total_count=$((total_count + 1))
89
+
90
+ # Read metadata
91
+ status=$(jq -r '.status // "backlog"' "$metadata_file" 2>/dev/null)
92
+ type=$(jq -r '.type // "feature"' "$metadata_file" 2>/dev/null)
93
+ priority=$(jq -r '.priority // "P1"' "$metadata_file" 2>/dev/null)
94
+ title=$(jq -r '.title // ""' "$metadata_file" 2>/dev/null)
95
+ project=$(jq -r '.project // ""' "$metadata_file" 2>/dev/null)
96
+ created_at=$(jq -r '.createdAt // ""' "$metadata_file" 2>/dev/null)
97
+
98
+ # Read user stories
99
+ user_stories=$(jq -c '.userStories // []' "$metadata_file" 2>/dev/null || echo "[]")
100
+
101
+ # Count tasks
102
+ total_tasks=0
103
+ completed_tasks=0
104
+ if [[ -f "$tasks_file" ]]; then
105
+ # Count ### T- headers for total
106
+ total_tasks=$(grep -c "^### T-" "$tasks_file" 2>/dev/null) || total_tasks=0
107
+ # Count [x] for completed
108
+ completed_tasks=$(grep "^\*\*Status\*\*:.*\[x\]" "$tasks_file" 2>/dev/null | wc -l | tr -d ' ') || completed_tasks=0
109
+ # Ensure numeric
110
+ total_tasks="${total_tasks:-0}"
111
+ completed_tasks="${completed_tasks:-0}"
112
+ fi
113
+
114
+ # Fallback to metadata task counts if available
115
+ if [[ "$total_tasks" -eq 0 ]]; then
116
+ total_tasks=$(jq -r '.tasks.total // 0' "$metadata_file" 2>/dev/null) || total_tasks=0
117
+ completed_tasks=$(jq -r '.tasks.completed // 0' "$metadata_file" 2>/dev/null) || completed_tasks=0
118
+ total_tasks="${total_tasks:-0}"
119
+ completed_tasks="${completed_tasks:-0}"
120
+ fi
121
+
122
+ # Count ACs from spec.md
123
+ total_acs=0
124
+ completed_acs=0
125
+ if [[ -f "$spec_file" ]]; then
126
+ # Count all AC checkboxes
127
+ total_acs=$(grep -c "\- \[.\] \*\*AC-" "$spec_file" 2>/dev/null) || total_acs=0
128
+ completed_acs=$(grep -c "\- \[x\] \*\*AC-" "$spec_file" 2>/dev/null) || completed_acs=0
129
+ total_acs="${total_acs:-0}"
130
+ completed_acs="${completed_acs:-0}"
131
+ fi
132
+
133
+ # Fallback to metadata AC counts
134
+ if [[ "$total_acs" -eq 0 ]]; then
135
+ total_acs=$(jq -r '.acceptanceCriteria.total // 0' "$metadata_file" 2>/dev/null) || total_acs=0
136
+ completed_acs=$(jq -r '.acceptanceCriteria.satisfied // 0' "$metadata_file" 2>/dev/null) || completed_acs=0
137
+ total_acs="${total_acs:-0}"
138
+ completed_acs="${completed_acs:-0}"
139
+ fi
140
+
141
+ # Get last activity from file mtime
142
+ last_activity=""
143
+ if [[ "$(uname)" == "Darwin" ]]; then
144
+ last_activity=$(stat -f "%Sm" -t "%Y-%m-%dT%H:%M:%SZ" "$metadata_file" 2>/dev/null || echo "")
145
+ else
146
+ last_activity=$(stat -c "%y" "$metadata_file" 2>/dev/null | sed 's/ /T/' | cut -d. -f1)Z || echo ""
147
+ fi
148
+
149
+ # Build increment JSON
150
+ increment_json=$(jq -n \
151
+ --arg status "$status" \
152
+ --arg type "$type" \
153
+ --arg priority "$priority" \
154
+ --arg title "$title" \
155
+ --arg project "$project" \
156
+ --argjson total_tasks "$total_tasks" \
157
+ --argjson completed_tasks "$completed_tasks" \
158
+ --argjson total_acs "$total_acs" \
159
+ --argjson completed_acs "$completed_acs" \
160
+ --arg created_at "$created_at" \
161
+ --arg last_activity "$last_activity" \
162
+ --argjson user_stories "$user_stories" \
163
+ '{
164
+ status: $status,
165
+ type: $type,
166
+ priority: $priority,
167
+ title: $title,
168
+ project: $project,
169
+ tasks: { total: $total_tasks, completed: $completed_tasks },
170
+ acs: { total: $total_acs, completed: $completed_acs },
171
+ createdAt: $created_at,
172
+ lastActivity: $last_activity,
173
+ userStories: $user_stories
174
+ }')
175
+
176
+ # Add to increments object
177
+ increments_json=$(echo "$increments_json" | jq --arg id "$increment_id" --argjson inc "$increment_json" '.[$id] = $inc')
178
+
179
+ # Collect mtimes for stale detection
180
+ meta_mtime=0
181
+ tasks_mtime=0
182
+ spec_mtime=0
183
+ if [[ "$(uname)" == "Darwin" ]]; then
184
+ [[ -f "$metadata_file" ]] && meta_mtime=$(stat -f "%m" "$metadata_file" 2>/dev/null || echo "0")
185
+ [[ -f "$tasks_file" ]] && tasks_mtime=$(stat -f "%m" "$tasks_file" 2>/dev/null || echo "0")
186
+ [[ -f "$spec_file" ]] && spec_mtime=$(stat -f "%m" "$spec_file" 2>/dev/null || echo "0")
187
+ else
188
+ [[ -f "$metadata_file" ]] && meta_mtime=$(stat -c "%Y" "$metadata_file" 2>/dev/null || echo "0")
189
+ [[ -f "$tasks_file" ]] && tasks_mtime=$(stat -c "%Y" "$tasks_file" 2>/dev/null || echo "0")
190
+ [[ -f "$spec_file" ]] && spec_mtime=$(stat -c "%Y" "$spec_file" 2>/dev/null || echo "0")
191
+ fi
192
+
193
+ mtimes_json=$(echo "$mtimes_json" | jq --arg id "$increment_id" \
194
+ --argjson meta "$meta_mtime" \
195
+ --argjson tasks "$tasks_mtime" \
196
+ --argjson spec "$spec_mtime" \
197
+ '.[$id] = { metadata: $meta, tasks: $tasks, spec: $spec }')
198
+
199
+ # Update status counters (bash 3.x compatible)
200
+ case "$status" in
201
+ backlog) status_backlog=$((status_backlog + 1)) ;;
202
+ planned) status_planned=$((status_planned + 1)) ;;
203
+ active) status_active=$((status_active + 1)) ;;
204
+ paused) status_paused=$((status_paused + 1)) ;;
205
+ ready_for_review) status_ready_for_review=$((status_ready_for_review + 1)) ;;
206
+ completed) status_completed=$((status_completed + 1)) ;;
207
+ abandoned) status_abandoned=$((status_abandoned + 1)) ;;
208
+ *) status_backlog=$((status_backlog + 1)) ;;
209
+ esac
210
+
211
+ # Update type counters
212
+ case "$type" in
213
+ feature) type_feature=$((type_feature + 1)) ;;
214
+ hotfix) type_hotfix=$((type_hotfix + 1)) ;;
215
+ bug) type_bug=$((type_bug + 1)) ;;
216
+ refactor) type_refactor=$((type_refactor + 1)) ;;
217
+ experiment) type_experiment=$((type_experiment + 1)) ;;
218
+ change-request) type_change_request=$((type_change_request + 1)) ;;
219
+ *) type_feature=$((type_feature + 1)) ;;
220
+ esac
221
+
222
+ # Update priority counters
223
+ case "$priority" in
224
+ P0) priority_P0=$((priority_P0 + 1)) ;;
225
+ P1) priority_P1=$((priority_P1 + 1)) ;;
226
+ P2) priority_P2=$((priority_P2 + 1)) ;;
227
+ P3) priority_P3=$((priority_P3 + 1)) ;;
228
+ *) priority_P1=$((priority_P1 + 1)) ;;
229
+ esac
230
+ done
231
+
232
+ # Count archived increments
233
+ if [[ -d "$ARCHIVE_DIR" ]]; then
234
+ archived_count=$(find "$ARCHIVE_DIR" -maxdepth 1 -type d -name "[0-9]*" 2>/dev/null | wc -l | tr -d ' ')
235
+ fi
236
+
237
+ # Build jobs section (read from existing jobs file if present)
238
+ jobs_json='{"running":[],"paused":[],"failed":[],"completedCount":0}'
239
+ JOBS_FILE="$STATE_DIR/background-jobs.json"
240
+ if [[ -f "$JOBS_FILE" ]]; then
241
+ running=$(jq -c '[.[] | select(.status == "running")]' "$JOBS_FILE" 2>/dev/null || echo "[]")
242
+ paused=$(jq -c '[.[] | select(.status == "paused")]' "$JOBS_FILE" 2>/dev/null || echo "[]")
243
+ failed=$(jq -c '[.[] | select(.status == "failed")]' "$JOBS_FILE" 2>/dev/null || echo "[]")
244
+ completed_count=$(jq '[.[] | select(.status == "completed")] | length' "$JOBS_FILE" 2>/dev/null || echo "0")
245
+ jobs_json=$(jq -n \
246
+ --argjson running "$running" \
247
+ --argjson paused "$paused" \
248
+ --argjson failed "$failed" \
249
+ --argjson completed_count "$completed_count" \
250
+ '{running: $running, paused: $paused, failed: $failed, completedCount: $completed_count}')
251
+ fi
252
+
253
+ # Build costs section (placeholder - populated by cost tracking hooks)
254
+ costs_json='{"totalTokens":0,"totalCost":0,"totalSavings":0,"byIncrement":{}}'
255
+ COSTS_FILE="$STATE_DIR/costs.json"
256
+ if [[ -f "$COSTS_FILE" ]]; then
257
+ costs_json=$(cat "$COSTS_FILE" 2>/dev/null || echo "$costs_json")
258
+ fi
259
+
260
+ # Build complete cache
261
+ cache_json=$(jq -n \
262
+ --argjson version 1 \
263
+ --arg updated_at "$(date -u +"%Y-%m-%dT%H:%M:%SZ")" \
264
+ --argjson increments "$increments_json" \
265
+ --argjson total "$total_count" \
266
+ --argjson active "$status_active" \
267
+ --argjson paused "$status_paused" \
268
+ --argjson backlog "$status_backlog" \
269
+ --argjson planned "$status_planned" \
270
+ --argjson ready_for_review "$status_ready_for_review" \
271
+ --argjson completed "$status_completed" \
272
+ --argjson abandoned "$status_abandoned" \
273
+ --argjson archived "$archived_count" \
274
+ --argjson feature "$type_feature" \
275
+ --argjson hotfix "$type_hotfix" \
276
+ --argjson bug "$type_bug" \
277
+ --argjson refactor "$type_refactor" \
278
+ --argjson experiment "$type_experiment" \
279
+ --argjson change_request "$type_change_request" \
280
+ --argjson p0 "$priority_P0" \
281
+ --argjson p1 "$priority_P1" \
282
+ --argjson p2 "$priority_P2" \
283
+ --argjson p3 "$priority_P3" \
284
+ --argjson jobs "$jobs_json" \
285
+ --argjson costs "$costs_json" \
286
+ --argjson mtimes "$mtimes_json" \
287
+ '{
288
+ version: $version,
289
+ updatedAt: $updated_at,
290
+ increments: $increments,
291
+ summary: {
292
+ total: $total,
293
+ active: $active,
294
+ paused: $paused,
295
+ backlog: $backlog,
296
+ planned: $planned,
297
+ ready_for_review: $ready_for_review,
298
+ completed: $completed,
299
+ abandoned: $abandoned,
300
+ archived: $archived,
301
+ byType: {
302
+ feature: $feature,
303
+ hotfix: $hotfix,
304
+ bug: $bug,
305
+ refactor: $refactor,
306
+ experiment: $experiment,
307
+ "change-request": $change_request
308
+ },
309
+ byPriority: {
310
+ P0: $p0,
311
+ P1: $p1,
312
+ P2: $p2,
313
+ P3: $p3
314
+ }
315
+ },
316
+ jobs: $jobs,
317
+ costs: $costs,
318
+ mtimes: $mtimes
319
+ }')
320
+
321
+ # Atomic write: write to temp file, then rename
322
+ echo "$cache_json" > "$TEMP_FILE"
323
+ mv "$TEMP_FILE" "$CACHE_FILE"
324
+
325
+ log "βœ… Dashboard cache rebuilt"
326
+ log " πŸ“Š $total_count increments | $status_active active | $status_completed completed"
327
+ log " πŸ“ Cache: $CACHE_FILE"
@@ -0,0 +1,192 @@
1
+ #!/usr/bin/env bash
2
+ # SpecWeave Session Watchdog
3
+ # Monitors Claude Code sessions and alerts when stuck
4
+ # Usage: bash session-watchdog.sh [--daemon] [--interval=60]
5
+
6
+ set -euo pipefail
7
+
8
+ # Configuration
9
+ STUCK_THRESHOLD_SECONDS="${STUCK_THRESHOLD:-300}" # 5 minutes
10
+ CHECK_INTERVAL="${CHECK_INTERVAL:-60}" # 1 minute
11
+ SPECWEAVE_ROOT="${SPECWEAVE_ROOT:-.specweave}"
12
+ SIGNAL_FILE="${SPECWEAVE_ROOT}/state/.session-stuck"
13
+ HEARTBEAT_FILE="${SPECWEAVE_ROOT}/state/.heartbeat"
14
+ DAEMON_MODE=false
15
+
16
+ # Colors
17
+ RED='\033[0;31m'
18
+ YELLOW='\033[1;33m'
19
+ GREEN='\033[0;32m'
20
+ NC='\033[0m'
21
+
22
+ # Parse arguments
23
+ for arg in "$@"; do
24
+ case $arg in
25
+ --daemon)
26
+ DAEMON_MODE=true
27
+ ;;
28
+ --interval=*)
29
+ CHECK_INTERVAL="${arg#*=}"
30
+ ;;
31
+ --threshold=*)
32
+ STUCK_THRESHOLD_SECONDS="${arg#*=}"
33
+ ;;
34
+ esac
35
+ done
36
+
37
+ log() {
38
+ echo -e "[$(date '+%H:%M:%S')] $1"
39
+ }
40
+
41
+ send_notification() {
42
+ local title="$1"
43
+ local message="$2"
44
+
45
+ # macOS notification
46
+ if command -v osascript &> /dev/null; then
47
+ osascript -e "display notification \"$message\" with title \"$title\" sound name \"Basso\""
48
+ fi
49
+
50
+ # Linux notification (if available)
51
+ if command -v notify-send &> /dev/null; then
52
+ notify-send "$title" "$message" --urgency=critical
53
+ fi
54
+ }
55
+
56
+ get_file_age_seconds() {
57
+ local file="$1"
58
+ if [[ ! -f "$file" ]]; then
59
+ echo "999999"
60
+ return
61
+ fi
62
+
63
+ local now
64
+ local mtime
65
+ now=$(date +%s)
66
+
67
+ if [[ "$(uname)" == "Darwin" ]]; then
68
+ mtime=$(stat -f %m "$file")
69
+ else
70
+ mtime=$(stat -c %Y "$file")
71
+ fi
72
+
73
+ echo $((now - mtime))
74
+ }
75
+
76
+ check_lock_file() {
77
+ local lock_file="${SPECWEAVE_ROOT}/state/.processor.lock"
78
+ if [[ -f "$lock_file" ]]; then
79
+ local age
80
+ age=$(get_file_age_seconds "$lock_file")
81
+ if [[ "$age" -gt "$STUCK_THRESHOLD_SECONDS" ]]; then
82
+ log "${RED}⚠️ STUCK DETECTED: Lock file held for ${age}s (threshold: ${STUCK_THRESHOLD_SECONDS}s)${NC}"
83
+ return 1
84
+ fi
85
+ fi
86
+ return 0
87
+ }
88
+
89
+ check_heartbeat() {
90
+ if [[ -f "$HEARTBEAT_FILE" ]]; then
91
+ local age
92
+ age=$(get_file_age_seconds "$HEARTBEAT_FILE")
93
+ if [[ "$age" -gt "$STUCK_THRESHOLD_SECONDS" ]]; then
94
+ log "${RED}⚠️ STUCK DETECTED: No heartbeat for ${age}s${NC}"
95
+ return 1
96
+ fi
97
+ fi
98
+ return 0
99
+ }
100
+
101
+ check_mcp_drops() {
102
+ local debug_log="$HOME/.claude/debug/latest"
103
+ if [[ -f "$debug_log" ]]; then
104
+ local drops
105
+ drops=$(grep -c "WS-IDE connection dropped" "$debug_log" 2>/dev/null | head -1 || echo "0")
106
+ drops="${drops//[^0-9]/}"
107
+ drops="${drops:-0}"
108
+ if [[ "$drops" -gt 3 ]]; then
109
+ log "${YELLOW}⚠️ MCP instability: $drops connection drops detected${NC}"
110
+ return 1
111
+ fi
112
+ fi
113
+ return 0
114
+ }
115
+
116
+ check_zombie_processes() {
117
+ local zombies
118
+ zombies=$(pgrep -f "cat.*EOF" 2>/dev/null | wc -l | tr -d ' ')
119
+ if [[ "$zombies" -gt 0 ]]; then
120
+ log "${RED}⚠️ STUCK DETECTED: $zombies zombie heredoc processes${NC}"
121
+ return 1
122
+ fi
123
+ return 0
124
+ }
125
+
126
+ check_session_health() {
127
+ local stuck=false
128
+ local reasons=()
129
+
130
+ if ! check_lock_file; then
131
+ stuck=true
132
+ reasons+=("Lock file stale")
133
+ fi
134
+
135
+ if ! check_heartbeat; then
136
+ stuck=true
137
+ reasons+=("No heartbeat")
138
+ fi
139
+
140
+ if ! check_mcp_drops; then
141
+ reasons+=("MCP unstable")
142
+ fi
143
+
144
+ if ! check_zombie_processes; then
145
+ stuck=true
146
+ reasons+=("Zombie processes")
147
+ fi
148
+
149
+ if [[ "$stuck" == "true" ]]; then
150
+ local reason_str
151
+ reason_str=$(IFS=", "; echo "${reasons[*]}")
152
+
153
+ # Create signal file
154
+ echo "stuck_at=$(date -u +%Y-%m-%dT%H:%M:%SZ)" > "$SIGNAL_FILE"
155
+ echo "reasons=$reason_str" >> "$SIGNAL_FILE"
156
+
157
+ send_notification "🚨 Claude Code Stuck" "$reason_str - Run cleanup-state.sh"
158
+
159
+ log "${RED}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
160
+ log "${RED}SESSION STUCK DETECTED${NC}"
161
+ log "${RED}Reasons: $reason_str${NC}"
162
+ log ""
163
+ log "Recovery steps:"
164
+ log " 1. Press Ctrl+C multiple times in Claude Code terminal"
165
+ log " 2. Run: bash plugins/specweave/scripts/cleanup-state.sh"
166
+ log " 3. If VS Code, restart Extension Host (Cmd+Shift+P)"
167
+ log " 4. Restart Claude Code"
168
+ log "${RED}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
169
+
170
+ return 1
171
+ else
172
+ # Remove signal file if exists
173
+ rm -f "$SIGNAL_FILE"
174
+ log "${GREEN}βœ“ Session healthy${NC}"
175
+ return 0
176
+ fi
177
+ }
178
+
179
+ # Main execution
180
+ if [[ "$DAEMON_MODE" == "true" ]]; then
181
+ log "Starting session watchdog daemon (interval: ${CHECK_INTERVAL}s, threshold: ${STUCK_THRESHOLD_SECONDS}s)"
182
+ log "Press Ctrl+C to stop"
183
+
184
+ while true; do
185
+ check_session_health || true
186
+ sleep "$CHECK_INTERVAL"
187
+ done
188
+ else
189
+ log "Running single health check..."
190
+ check_session_health
191
+ exit $?
192
+ fi
@@ -0,0 +1,154 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Instant Increment Status Overview
4
+ *
5
+ * Executed by UserPromptSubmit hook for /specweave:status
6
+ * Bypasses LLM entirely - output shown directly to user
7
+ *
8
+ * Usage: node status.js [--help]
9
+ */
10
+
11
+ import fs from 'fs';
12
+ import path from 'path';
13
+
14
+ // Handle --help
15
+ if (process.argv.includes('--help') || process.argv.includes('-h')) {
16
+ console.log(`
17
+ SpecWeave Instant Status
18
+
19
+ USAGE
20
+ node plugins/specweave/scripts/status.js [options]
21
+ specweave status [options]
22
+
23
+ OPTIONS
24
+ --help, -h Show this help message
25
+
26
+ DESCRIPTION
27
+ Shows increment status overview grouped by status (active, paused, completed, etc.).
28
+ This script bypasses LLM processing for instant results (<100ms).
29
+
30
+ EXECUTION PATHS
31
+ 1. Claude Code: /specweave:status (hook intercepts, <100ms)
32
+ 2. Any LLM: Skill instructs to run this script (~2s)
33
+ 3. Terminal: specweave status (~500ms)
34
+
35
+ EXAMPLES
36
+ node plugins/specweave/scripts/status.js
37
+ specweave status
38
+ specweave status --verbose
39
+ `);
40
+ process.exit(0);
41
+ }
42
+
43
+ const cwd = process.cwd();
44
+ const incrementsDir = path.join(cwd, '.specweave/increments');
45
+ const archiveDir = path.join(incrementsDir, '_archive');
46
+
47
+ // Check if increments directory exists
48
+ if (!fs.existsSync(incrementsDir)) {
49
+ console.log('No SpecWeave project found (missing .specweave/increments/)');
50
+ process.exit(0);
51
+ }
52
+
53
+ // Find increments
54
+ const entries = fs.readdirSync(incrementsDir, { withFileTypes: true });
55
+ const incrementFolders = entries
56
+ .filter(e => e.isDirectory() && !e.name.startsWith('_') && /^\d{4}/.test(e.name))
57
+ .map(e => e.name);
58
+
59
+ // Count archived
60
+ let archivedCount = 0;
61
+ if (fs.existsSync(archiveDir)) {
62
+ const archived = fs.readdirSync(archiveDir, { withFileTypes: true });
63
+ archivedCount = archived.filter(e => e.isDirectory() && /^\d{4}/.test(e.name)).length;
64
+ }
65
+
66
+ // Parse increment status
67
+ function getStatus(folder) {
68
+ const metaPath = path.join(incrementsDir, folder, 'metadata.json');
69
+ if (fs.existsSync(metaPath)) {
70
+ try {
71
+ const meta = JSON.parse(fs.readFileSync(metaPath, 'utf-8'));
72
+ return meta.status || 'unknown';
73
+ } catch {}
74
+ }
75
+ return 'unknown';
76
+ }
77
+
78
+ // Group by status
79
+ const byStatus = {};
80
+ for (const folder of incrementFolders) {
81
+ const status = getStatus(folder);
82
+ if (!byStatus[status]) byStatus[status] = [];
83
+ byStatus[status].push(folder);
84
+ }
85
+
86
+ // Display
87
+ console.log('\nπŸ“‹ SpecWeave Status Overview\n');
88
+
89
+ const statusOrder = ['active', 'planning', 'in-progress', 'ready_for_review', 'paused', 'backlog', 'completed', 'abandoned'];
90
+ const statusIcons = {
91
+ 'active': 'πŸ”„',
92
+ 'planning': 'πŸ“',
93
+ 'in-progress': 'βš™οΈ',
94
+ 'ready_for_review': 'πŸ‘€',
95
+ 'paused': '⏸️',
96
+ 'backlog': 'πŸ“‹',
97
+ 'completed': 'βœ…',
98
+ 'abandoned': '❌'
99
+ };
100
+
101
+ let hasOutput = false;
102
+
103
+ for (const status of statusOrder) {
104
+ const items = byStatus[status];
105
+ if (items && items.length > 0) {
106
+ hasOutput = true;
107
+ const icon = statusIcons[status] || 'β€’';
108
+ console.log(`${icon} ${status.replace('_', ' ')} (${items.length}):`);
109
+
110
+ // Show first 5, summarize rest
111
+ const toShow = items.slice(0, 5);
112
+ for (const item of toShow) {
113
+ console.log(` ${item}`);
114
+ }
115
+ if (items.length > 5) {
116
+ console.log(` ... and ${items.length - 5} more`);
117
+ }
118
+ console.log('');
119
+ }
120
+ }
121
+
122
+ // Handle unknown statuses
123
+ for (const status of Object.keys(byStatus)) {
124
+ if (!statusOrder.includes(status)) {
125
+ const items = byStatus[status];
126
+ if (items.length > 0) {
127
+ hasOutput = true;
128
+ console.log(`? ${status} (${items.length}):`);
129
+ for (const item of items.slice(0, 3)) {
130
+ console.log(` ${item}`);
131
+ }
132
+ console.log('');
133
+ }
134
+ }
135
+ }
136
+
137
+ if (!hasOutput) {
138
+ console.log('No increments found.');
139
+ }
140
+
141
+ // Summary line
142
+ const total = incrementFolders.length;
143
+ const activeCount = (byStatus['active']?.length || 0) +
144
+ (byStatus['planning']?.length || 0) +
145
+ (byStatus['in-progress']?.length || 0);
146
+ const completedCount = byStatus['completed']?.length || 0;
147
+
148
+ console.log('─'.repeat(40));
149
+ console.log(`Total: ${total} increment(s) | Active: ${activeCount} | Completed: ${completedCount} | Archived: ${archivedCount}`);
150
+ console.log('');
151
+ console.log('πŸ’‘ Commands:');
152
+ console.log(' /specweave:progress Show task progress');
153
+ console.log(' /specweave:do Execute current tasks');
154
+ console.log(' /specweave:done <id> Close increment');