gsd-pi 2.58.0-dev.778d6ac → 2.58.0-dev.d63175c

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 (628) hide show
  1. package/README.md +1 -1
  2. package/dist/cli.js +35 -49
  3. package/dist/headless-ui.d.ts +0 -17
  4. package/dist/headless-ui.js +3 -97
  5. package/dist/headless.js +6 -67
  6. package/dist/help-text.js +0 -1
  7. package/dist/onboarding.js +0 -44
  8. package/dist/resource-loader.js +1 -16
  9. package/dist/resources/agents/researcher.md +1 -1
  10. package/dist/resources/extensions/ask-user-questions.js +3 -16
  11. package/dist/resources/extensions/async-jobs/extension-manifest.json +1 -1
  12. package/dist/resources/extensions/bg-shell/extension-manifest.json +1 -1
  13. package/dist/resources/extensions/browser-tools/extension-manifest.json +1 -1
  14. package/dist/resources/extensions/claude-code-cli/partial-builder.js +6 -14
  15. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +36 -59
  16. package/dist/resources/extensions/context7/extension-manifest.json +1 -1
  17. package/dist/resources/extensions/get-secrets-from-user.js +5 -8
  18. package/dist/resources/extensions/google-search/extension-manifest.json +1 -1
  19. package/dist/resources/extensions/google-search/index.js +1 -2
  20. package/dist/resources/extensions/gsd/auto/phases.js +21 -25
  21. package/dist/resources/extensions/gsd/auto-artifact-paths.js +2 -2
  22. package/dist/resources/extensions/gsd/auto-dashboard.js +20 -37
  23. package/dist/resources/extensions/gsd/auto-dispatch.js +2 -17
  24. package/dist/resources/extensions/gsd/auto-model-selection.js +3 -26
  25. package/dist/resources/extensions/gsd/auto-post-unit.js +4 -16
  26. package/dist/resources/extensions/gsd/auto-prompts.js +1 -1
  27. package/dist/resources/extensions/gsd/auto-recovery.js +5 -13
  28. package/dist/resources/extensions/gsd/auto-start.js +22 -35
  29. package/dist/resources/extensions/gsd/auto-worktree.js +12 -196
  30. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +0 -32
  31. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +8 -80
  32. package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +1 -32
  33. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +18 -33
  34. package/dist/resources/extensions/gsd/bootstrap/system-context.js +11 -44
  35. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +0 -67
  36. package/dist/resources/extensions/gsd/captures.js +4 -56
  37. package/dist/resources/extensions/gsd/db-writer.js +8 -116
  38. package/dist/resources/extensions/gsd/doctor-git-checks.js +0 -28
  39. package/dist/resources/extensions/gsd/doctor-providers.js +1 -2
  40. package/dist/resources/extensions/gsd/doctor-runtime-checks.js +4 -5
  41. package/dist/resources/extensions/gsd/doctor.js +1 -3
  42. package/dist/resources/extensions/gsd/error-classifier.js +10 -13
  43. package/dist/resources/extensions/gsd/extension-manifest.json +1 -16
  44. package/dist/resources/extensions/gsd/forensics.js +20 -123
  45. package/dist/resources/extensions/gsd/git-service.js +1 -23
  46. package/dist/resources/extensions/gsd/gitignore.js +0 -33
  47. package/dist/resources/extensions/gsd/gsd-db.js +9 -36
  48. package/dist/resources/extensions/gsd/guided-flow.js +44 -106
  49. package/dist/resources/extensions/gsd/health-widget-core.js +0 -31
  50. package/dist/resources/extensions/gsd/health-widget.js +0 -17
  51. package/dist/resources/extensions/gsd/index.js +1 -1
  52. package/dist/resources/extensions/gsd/memory-extractor.js +0 -7
  53. package/dist/resources/extensions/gsd/migrate-external.js +1 -8
  54. package/dist/resources/extensions/gsd/model-cost-table.js +0 -18
  55. package/dist/resources/extensions/gsd/model-router.js +1 -35
  56. package/dist/resources/extensions/gsd/native-git-bridge.js +0 -17
  57. package/dist/resources/extensions/gsd/notifications.js +1 -16
  58. package/dist/resources/extensions/gsd/parallel-eligibility.js +2 -13
  59. package/dist/resources/extensions/gsd/parallel-merge.js +5 -78
  60. package/dist/resources/extensions/gsd/parsers-legacy.js +3 -20
  61. package/dist/resources/extensions/gsd/paths.js +0 -43
  62. package/dist/resources/extensions/gsd/preferences-models.js +1 -14
  63. package/dist/resources/extensions/gsd/preferences-types.js +1 -2
  64. package/dist/resources/extensions/gsd/preferences.js +16 -13
  65. package/dist/resources/extensions/gsd/prompt-loader.js +1 -4
  66. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
  67. package/dist/resources/extensions/gsd/prompts/complete-slice.md +2 -4
  68. package/dist/resources/extensions/gsd/prompts/discuss-headless.md +1 -1
  69. package/dist/resources/extensions/gsd/prompts/discuss.md +1 -1
  70. package/dist/resources/extensions/gsd/prompts/execute-task.md +1 -3
  71. package/dist/resources/extensions/gsd/prompts/forensics.md +2 -2
  72. package/dist/resources/extensions/gsd/prompts/guided-discuss-milestone.md +1 -1
  73. package/dist/resources/extensions/gsd/prompts/guided-discuss-slice.md +1 -1
  74. package/dist/resources/extensions/gsd/prompts/plan-slice.md +0 -2
  75. package/dist/resources/extensions/gsd/prompts/rethink.md +1 -1
  76. package/dist/resources/extensions/gsd/prompts/triage-captures.md +0 -1
  77. package/dist/resources/extensions/gsd/repo-identity.js +11 -205
  78. package/dist/resources/extensions/gsd/rethink.js +0 -5
  79. package/dist/resources/extensions/gsd/roadmap-slices.js +4 -5
  80. package/dist/resources/extensions/gsd/state.js +27 -85
  81. package/dist/resources/extensions/gsd/tests/dist-redirect.mjs +1 -20
  82. package/dist/resources/extensions/gsd/tools/complete-task.js +71 -34
  83. package/dist/resources/extensions/gsd/tools/plan-milestone.js +2 -12
  84. package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +1 -29
  85. package/dist/resources/extensions/gsd/tools/validate-milestone.js +3 -14
  86. package/dist/resources/extensions/gsd/triage-resolution.js +7 -22
  87. package/dist/resources/extensions/gsd/undo.js +2 -2
  88. package/dist/resources/extensions/gsd/unit-ownership.js +33 -164
  89. package/dist/resources/extensions/gsd/verdict-parser.js +8 -20
  90. package/dist/resources/extensions/gsd/workflow-manifest.js +5 -24
  91. package/dist/resources/extensions/gsd/workflow-projections.js +63 -95
  92. package/dist/resources/extensions/gsd/workflow-reconcile.js +5 -35
  93. package/dist/resources/extensions/gsd/workspace-index.js +0 -24
  94. package/dist/resources/extensions/gsd/worktree-manager.js +1 -105
  95. package/dist/resources/extensions/gsd/worktree-resolver.js +3 -20
  96. package/dist/resources/extensions/mcp-client/index.js +7 -11
  97. package/dist/resources/extensions/search-the-web/extension-manifest.json +1 -1
  98. package/dist/resources/extensions/shared/interview-ui.js +1 -11
  99. package/dist/resources/skills/create-gsd-extension/SKILL.md +3 -5
  100. package/dist/resources/skills/create-gsd-extension/references/key-rules-gotchas.md +4 -5
  101. package/dist/resources/skills/create-gsd-extension/workflows/add-capability.md +2 -2
  102. package/dist/resources/skills/create-gsd-extension/workflows/create-extension.md +4 -4
  103. package/dist/resources/skills/create-gsd-extension/workflows/debug-extension.md +3 -5
  104. package/dist/web/standalone/.next/BUILD_ID +1 -1
  105. package/dist/web/standalone/.next/app-path-routes-manifest.json +17 -17
  106. package/dist/web/standalone/.next/build-manifest.json +3 -3
  107. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  108. package/dist/web/standalone/.next/react-loadable-manifest.json +1 -1
  109. package/dist/web/standalone/.next/required-server-files.json +1 -1
  110. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  111. package/dist/web/standalone/.next/server/app/_global-error.html +2 -2
  112. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  113. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  114. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  115. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  116. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  117. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  118. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  119. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  120. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  121. package/dist/web/standalone/.next/server/app/_not-found.rsc +2 -2
  122. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
  123. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  124. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +2 -2
  125. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  126. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  127. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  128. package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
  129. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
  130. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
  131. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
  132. package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
  133. package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
  134. package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
  135. package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
  136. package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
  137. package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
  138. package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
  139. package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
  140. package/dist/web/standalone/.next/server/app/api/experimental/route_client-reference-manifest.js +1 -1
  141. package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
  142. package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
  143. package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
  144. package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
  145. package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
  146. package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  147. package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
  148. package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
  149. package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
  150. package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
  151. package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
  152. package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
  153. package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
  154. package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
  155. package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
  156. package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  157. package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
  158. package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
  159. package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
  160. package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
  161. package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
  162. package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
  163. package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
  164. package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
  165. package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
  166. package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
  167. package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
  168. package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
  169. package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
  170. package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
  171. package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
  172. package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
  173. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
  174. package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
  175. package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
  176. package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
  177. package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
  178. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  179. package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  180. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  181. package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
  182. package/dist/web/standalone/.next/server/app/index.html +1 -1
  183. package/dist/web/standalone/.next/server/app/index.rsc +2 -2
  184. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  185. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +2 -2
  186. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  187. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +2 -2
  188. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  189. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  190. package/dist/web/standalone/.next/server/app-paths-manifest.json +17 -17
  191. package/dist/web/standalone/.next/server/chunks/2229.js +2 -2
  192. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  193. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  194. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  195. package/dist/web/standalone/.next/server/pages/500.html +2 -2
  196. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  197. package/dist/web/standalone/.next/static/chunks/6502.8b732f67a11b11b4.js +9 -0
  198. package/dist/web/standalone/.next/static/chunks/{webpack-a1c1e452c6b32d04.js → webpack-61d3afac6d0f0ce7.js} +1 -1
  199. package/dist/web/standalone/.next/static/css/a58ef8a151aa0493.css +1 -0
  200. package/dist/web/standalone/server.js +1 -1
  201. package/dist/web-mode.js +1 -2
  202. package/package.json +2 -2
  203. package/packages/native/dist/ast/index.js +5 -9
  204. package/packages/native/dist/ast/types.js +1 -2
  205. package/packages/native/dist/clipboard/index.js +7 -12
  206. package/packages/native/dist/clipboard/types.js +1 -2
  207. package/packages/native/dist/diff/index.js +7 -12
  208. package/packages/native/dist/diff/types.js +1 -2
  209. package/packages/native/dist/fd/index.js +3 -6
  210. package/packages/native/dist/fd/types.js +1 -2
  211. package/packages/native/dist/glob/index.js +5 -9
  212. package/packages/native/dist/glob/types.js +1 -2
  213. package/packages/native/dist/grep/index.js +5 -9
  214. package/packages/native/dist/grep/types.js +1 -2
  215. package/packages/native/dist/gsd-parser/index.js +11 -18
  216. package/packages/native/dist/gsd-parser/types.js +1 -2
  217. package/packages/native/dist/highlight/index.js +7 -12
  218. package/packages/native/dist/highlight/types.js +1 -2
  219. package/packages/native/dist/html/index.js +3 -6
  220. package/packages/native/dist/html/types.js +1 -2
  221. package/packages/native/dist/image/index.js +5 -10
  222. package/packages/native/dist/image/types.js +4 -7
  223. package/packages/native/dist/index.js +17 -70
  224. package/packages/native/dist/json-parse/index.js +8 -13
  225. package/packages/native/dist/native.js +10 -47
  226. package/packages/native/dist/ps/index.js +9 -15
  227. package/packages/native/dist/ps/types.js +1 -2
  228. package/packages/native/dist/stream-process/index.js +7 -12
  229. package/packages/native/dist/text/index.js +14 -24
  230. package/packages/native/dist/text/types.js +2 -5
  231. package/packages/native/dist/truncate/index.js +7 -12
  232. package/packages/native/dist/ttsr/index.js +7 -12
  233. package/packages/native/dist/ttsr/types.js +1 -2
  234. package/packages/native/dist/xxhash/index.js +5 -9
  235. package/packages/native/package.json +19 -19
  236. package/packages/native/src/native.ts +8 -9
  237. package/packages/pi-agent-core/dist/agent-loop.js +2 -3
  238. package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
  239. package/packages/pi-agent-core/dist/proxy.d.ts +1 -1
  240. package/packages/pi-agent-core/dist/proxy.d.ts.map +1 -1
  241. package/packages/pi-agent-core/dist/proxy.js.map +1 -1
  242. package/packages/pi-agent-core/src/agent-loop.ts +2 -3
  243. package/packages/pi-agent-core/src/proxy.ts +1 -1
  244. package/packages/pi-ai/dist/env-api-keys.js +0 -1
  245. package/packages/pi-ai/dist/env-api-keys.js.map +1 -1
  246. package/packages/pi-ai/dist/index.d.ts +0 -1
  247. package/packages/pi-ai/dist/index.d.ts.map +1 -1
  248. package/packages/pi-ai/dist/index.js +0 -1
  249. package/packages/pi-ai/dist/index.js.map +1 -1
  250. package/packages/pi-ai/dist/providers/anthropic-shared.d.ts.map +1 -1
  251. package/packages/pi-ai/dist/providers/anthropic-shared.js +2 -19
  252. package/packages/pi-ai/dist/providers/anthropic-shared.js.map +1 -1
  253. package/packages/pi-ai/dist/types.d.ts +3 -3
  254. package/packages/pi-ai/dist/types.d.ts.map +1 -1
  255. package/packages/pi-ai/dist/types.js.map +1 -1
  256. package/packages/pi-ai/dist/utils/json-parse.d.ts +0 -3
  257. package/packages/pi-ai/dist/utils/json-parse.d.ts.map +1 -1
  258. package/packages/pi-ai/dist/utils/json-parse.js +1 -24
  259. package/packages/pi-ai/dist/utils/json-parse.js.map +1 -1
  260. package/packages/pi-ai/src/env-api-keys.ts +0 -1
  261. package/packages/pi-ai/src/index.ts +0 -1
  262. package/packages/pi-ai/src/providers/anthropic-shared.ts +2 -17
  263. package/packages/pi-ai/src/types.ts +2 -3
  264. package/packages/pi-ai/src/utils/json-parse.ts +1 -28
  265. package/packages/pi-coding-agent/dist/core/agent-session.d.ts +0 -4
  266. package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
  267. package/packages/pi-coding-agent/dist/core/agent-session.js +0 -31
  268. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  269. package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts +1 -17
  270. package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts.map +1 -1
  271. package/packages/pi-coding-agent/dist/core/compaction/compaction.js +2 -62
  272. package/packages/pi-coding-agent/dist/core/compaction/compaction.js.map +1 -1
  273. package/packages/pi-coding-agent/dist/core/exec.d.ts.map +1 -1
  274. package/packages/pi-coding-agent/dist/core/exec.js +1 -3
  275. package/packages/pi-coding-agent/dist/core/exec.js.map +1 -1
  276. package/packages/pi-coding-agent/dist/core/extensions/index.d.ts +0 -4
  277. package/packages/pi-coding-agent/dist/core/extensions/index.d.ts.map +1 -1
  278. package/packages/pi-coding-agent/dist/core/extensions/index.js +0 -2
  279. package/packages/pi-coding-agent/dist/core/extensions/index.js.map +1 -1
  280. package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts +0 -5
  281. package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
  282. package/packages/pi-coding-agent/dist/core/extensions/loader.js +0 -5
  283. package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
  284. package/packages/pi-coding-agent/dist/core/index.d.ts +1 -1
  285. package/packages/pi-coding-agent/dist/core/index.d.ts.map +1 -1
  286. package/packages/pi-coding-agent/dist/core/index.js +1 -1
  287. package/packages/pi-coding-agent/dist/core/index.js.map +1 -1
  288. package/packages/pi-coding-agent/dist/core/lsp/index.d.ts.map +1 -1
  289. package/packages/pi-coding-agent/dist/core/lsp/index.js +0 -3
  290. package/packages/pi-coding-agent/dist/core/lsp/index.js.map +1 -1
  291. package/packages/pi-coding-agent/dist/core/lsp/lspmux.d.ts.map +1 -1
  292. package/packages/pi-coding-agent/dist/core/lsp/lspmux.js +0 -3
  293. package/packages/pi-coding-agent/dist/core/lsp/lspmux.js.map +1 -1
  294. package/packages/pi-coding-agent/dist/core/messages.d.ts.map +1 -1
  295. package/packages/pi-coding-agent/dist/core/messages.js +2 -31
  296. package/packages/pi-coding-agent/dist/core/messages.js.map +1 -1
  297. package/packages/pi-coding-agent/dist/core/model-resolver.d.ts.map +1 -1
  298. package/packages/pi-coding-agent/dist/core/model-resolver.js +0 -1
  299. package/packages/pi-coding-agent/dist/core/model-resolver.js.map +1 -1
  300. package/packages/pi-coding-agent/dist/core/resource-loader.d.ts +0 -10
  301. package/packages/pi-coding-agent/dist/core/resource-loader.d.ts.map +1 -1
  302. package/packages/pi-coding-agent/dist/core/resource-loader.js +1 -12
  303. package/packages/pi-coding-agent/dist/core/resource-loader.js.map +1 -1
  304. package/packages/pi-coding-agent/dist/core/retry-handler.d.ts +0 -6
  305. package/packages/pi-coding-agent/dist/core/retry-handler.d.ts.map +1 -1
  306. package/packages/pi-coding-agent/dist/core/retry-handler.js +1 -48
  307. package/packages/pi-coding-agent/dist/core/retry-handler.js.map +1 -1
  308. package/packages/pi-coding-agent/dist/core/tools/hashline-read.d.ts.map +1 -1
  309. package/packages/pi-coding-agent/dist/core/tools/hashline-read.js +3 -10
  310. package/packages/pi-coding-agent/dist/core/tools/hashline-read.js.map +1 -1
  311. package/packages/pi-coding-agent/dist/core/tools/read.d.ts.map +1 -1
  312. package/packages/pi-coding-agent/dist/core/tools/read.js +4 -13
  313. package/packages/pi-coding-agent/dist/core/tools/read.js.map +1 -1
  314. package/packages/pi-coding-agent/dist/index.d.ts +2 -2
  315. package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
  316. package/packages/pi-coding-agent/dist/index.js +1 -1
  317. package/packages/pi-coding-agent/dist/index.js.map +1 -1
  318. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  319. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +0 -4
  320. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  321. package/packages/pi-coding-agent/dist/modes/rpc/remote-terminal.d.ts +0 -1
  322. package/packages/pi-coding-agent/dist/modes/rpc/remote-terminal.d.ts.map +1 -1
  323. package/packages/pi-coding-agent/dist/modes/rpc/remote-terminal.js +0 -5
  324. package/packages/pi-coding-agent/dist/modes/rpc/remote-terminal.js.map +1 -1
  325. package/packages/pi-coding-agent/src/core/agent-session.ts +1 -38
  326. package/packages/pi-coding-agent/src/core/compaction/compaction.ts +1 -94
  327. package/packages/pi-coding-agent/src/core/exec.ts +1 -3
  328. package/packages/pi-coding-agent/src/core/extensions/index.ts +0 -4
  329. package/packages/pi-coding-agent/src/core/extensions/loader.ts +0 -5
  330. package/packages/pi-coding-agent/src/core/index.ts +0 -6
  331. package/packages/pi-coding-agent/src/core/lsp/index.ts +0 -3
  332. package/packages/pi-coding-agent/src/core/lsp/lspmux.ts +0 -3
  333. package/packages/pi-coding-agent/src/core/messages.ts +2 -29
  334. package/packages/pi-coding-agent/src/core/model-resolver.ts +0 -1
  335. package/packages/pi-coding-agent/src/core/resource-loader.ts +1 -20
  336. package/packages/pi-coding-agent/src/core/retry-handler.ts +1 -52
  337. package/packages/pi-coding-agent/src/core/tools/hashline-read.ts +3 -11
  338. package/packages/pi-coding-agent/src/core/tools/read.ts +4 -14
  339. package/packages/pi-coding-agent/src/index.ts +0 -6
  340. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +0 -7
  341. package/packages/pi-coding-agent/src/modes/rpc/remote-terminal.ts +0 -6
  342. package/packages/pi-tui/dist/terminal.d.ts +0 -2
  343. package/packages/pi-tui/dist/terminal.d.ts.map +1 -1
  344. package/packages/pi-tui/dist/terminal.js +0 -9
  345. package/packages/pi-tui/dist/terminal.js.map +1 -1
  346. package/packages/pi-tui/dist/tui.d.ts.map +1 -1
  347. package/packages/pi-tui/dist/tui.js +0 -9
  348. package/packages/pi-tui/dist/tui.js.map +1 -1
  349. package/packages/pi-tui/src/terminal.ts +0 -14
  350. package/packages/pi-tui/src/tui.ts +0 -8
  351. package/scripts/ensure-workspace-builds.cjs +14 -45
  352. package/src/resources/agents/researcher.md +1 -1
  353. package/src/resources/extensions/ask-user-questions.ts +3 -21
  354. package/src/resources/extensions/async-jobs/extension-manifest.json +1 -1
  355. package/src/resources/extensions/bg-shell/extension-manifest.json +1 -1
  356. package/src/resources/extensions/browser-tools/extension-manifest.json +1 -1
  357. package/src/resources/extensions/claude-code-cli/partial-builder.ts +6 -13
  358. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +35 -63
  359. package/src/resources/extensions/claude-code-cli/tests/partial-builder.test.ts +0 -28
  360. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +1 -108
  361. package/src/resources/extensions/context7/extension-manifest.json +1 -1
  362. package/src/resources/extensions/get-secrets-from-user.ts +5 -8
  363. package/src/resources/extensions/google-search/extension-manifest.json +1 -1
  364. package/src/resources/extensions/google-search/index.ts +1 -2
  365. package/src/resources/extensions/gsd/auto/loop-deps.ts +0 -1
  366. package/src/resources/extensions/gsd/auto/phases.ts +34 -43
  367. package/src/resources/extensions/gsd/auto-artifact-paths.ts +2 -2
  368. package/src/resources/extensions/gsd/auto-dashboard.ts +19 -37
  369. package/src/resources/extensions/gsd/auto-dispatch.ts +2 -18
  370. package/src/resources/extensions/gsd/auto-model-selection.ts +5 -26
  371. package/src/resources/extensions/gsd/auto-post-unit.ts +4 -18
  372. package/src/resources/extensions/gsd/auto-prompts.ts +1 -1
  373. package/src/resources/extensions/gsd/auto-recovery.ts +5 -12
  374. package/src/resources/extensions/gsd/auto-start.ts +26 -35
  375. package/src/resources/extensions/gsd/auto-worktree.ts +9 -190
  376. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +0 -31
  377. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +8 -85
  378. package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +1 -38
  379. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +19 -31
  380. package/src/resources/extensions/gsd/bootstrap/system-context.ts +11 -50
  381. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +0 -75
  382. package/src/resources/extensions/gsd/captures.ts +3 -63
  383. package/src/resources/extensions/gsd/db-writer.ts +7 -140
  384. package/src/resources/extensions/gsd/doctor-git-checks.ts +0 -26
  385. package/src/resources/extensions/gsd/doctor-providers.ts +1 -2
  386. package/src/resources/extensions/gsd/doctor-runtime-checks.ts +4 -5
  387. package/src/resources/extensions/gsd/doctor.ts +1 -3
  388. package/src/resources/extensions/gsd/error-classifier.ts +11 -14
  389. package/src/resources/extensions/gsd/extension-manifest.json +1 -16
  390. package/src/resources/extensions/gsd/forensics.ts +20 -144
  391. package/src/resources/extensions/gsd/git-service.ts +3 -26
  392. package/src/resources/extensions/gsd/gitignore.ts +0 -33
  393. package/src/resources/extensions/gsd/gsd-db.ts +7 -43
  394. package/src/resources/extensions/gsd/guided-flow.ts +45 -114
  395. package/src/resources/extensions/gsd/health-widget-core.ts +0 -34
  396. package/src/resources/extensions/gsd/health-widget.ts +0 -17
  397. package/src/resources/extensions/gsd/index.ts +0 -1
  398. package/src/resources/extensions/gsd/memory-extractor.ts +0 -8
  399. package/src/resources/extensions/gsd/migrate-external.ts +1 -9
  400. package/src/resources/extensions/gsd/model-cost-table.ts +0 -19
  401. package/src/resources/extensions/gsd/model-router.ts +1 -35
  402. package/src/resources/extensions/gsd/native-git-bridge.ts +0 -17
  403. package/src/resources/extensions/gsd/notifications.ts +0 -16
  404. package/src/resources/extensions/gsd/parallel-eligibility.ts +2 -15
  405. package/src/resources/extensions/gsd/parallel-merge.ts +4 -87
  406. package/src/resources/extensions/gsd/parsers-legacy.ts +3 -22
  407. package/src/resources/extensions/gsd/paths.ts +0 -42
  408. package/src/resources/extensions/gsd/preferences-models.ts +1 -14
  409. package/src/resources/extensions/gsd/preferences-types.ts +1 -2
  410. package/src/resources/extensions/gsd/preferences.ts +15 -13
  411. package/src/resources/extensions/gsd/prompt-loader.ts +1 -4
  412. package/src/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
  413. package/src/resources/extensions/gsd/prompts/complete-slice.md +2 -4
  414. package/src/resources/extensions/gsd/prompts/discuss-headless.md +1 -1
  415. package/src/resources/extensions/gsd/prompts/discuss.md +1 -1
  416. package/src/resources/extensions/gsd/prompts/execute-task.md +1 -3
  417. package/src/resources/extensions/gsd/prompts/forensics.md +2 -2
  418. package/src/resources/extensions/gsd/prompts/guided-discuss-milestone.md +1 -1
  419. package/src/resources/extensions/gsd/prompts/guided-discuss-slice.md +1 -1
  420. package/src/resources/extensions/gsd/prompts/plan-slice.md +0 -2
  421. package/src/resources/extensions/gsd/prompts/rethink.md +1 -1
  422. package/src/resources/extensions/gsd/prompts/triage-captures.md +0 -1
  423. package/src/resources/extensions/gsd/repo-identity.ts +11 -186
  424. package/src/resources/extensions/gsd/rethink.ts +0 -6
  425. package/src/resources/extensions/gsd/roadmap-slices.ts +4 -5
  426. package/src/resources/extensions/gsd/state.ts +32 -84
  427. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +0 -29
  428. package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +1 -71
  429. package/src/resources/extensions/gsd/tests/captures.test.ts +0 -103
  430. package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +0 -27
  431. package/src/resources/extensions/gsd/tests/complete-slice.test.ts +0 -21
  432. package/src/resources/extensions/gsd/tests/db-writer.test.ts +12 -7
  433. package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +5 -78
  434. package/src/resources/extensions/gsd/tests/derive-state.test.ts +0 -29
  435. package/src/resources/extensions/gsd/tests/discuss-queued-milestones.test.ts +0 -40
  436. package/src/resources/extensions/gsd/tests/dist-redirect.mjs +1 -20
  437. package/src/resources/extensions/gsd/tests/doctor-providers.test.ts +0 -117
  438. package/src/resources/extensions/gsd/tests/empty-db-reconciliation.test.ts +79 -0
  439. package/src/resources/extensions/gsd/tests/forensics-dedup.test.ts +0 -31
  440. package/src/resources/extensions/gsd/tests/gsd-tools.test.ts +12 -125
  441. package/src/resources/extensions/gsd/tests/health-widget.test.ts +0 -67
  442. package/src/resources/extensions/gsd/tests/integration/auto-recovery.test.ts +1 -111
  443. package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +0 -101
  444. package/src/resources/extensions/gsd/tests/integration/auto-worktree.test.ts +0 -59
  445. package/src/resources/extensions/gsd/tests/integration/parallel-merge.test.ts +0 -110
  446. package/src/resources/extensions/gsd/tests/integration/run-uat.test.ts +1 -1
  447. package/src/resources/extensions/gsd/tests/memory-extractor.test.ts +2 -85
  448. package/src/resources/extensions/gsd/tests/model-cost-table.test.ts +0 -34
  449. package/src/resources/extensions/gsd/tests/model-router.test.ts +3 -68
  450. package/src/resources/extensions/gsd/tests/model-unittype-mapping.test.ts +0 -28
  451. package/src/resources/extensions/gsd/tests/notifications.test.ts +0 -45
  452. package/src/resources/extensions/gsd/tests/plan-milestone.test.ts +1 -33
  453. package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +0 -29
  454. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +0 -38
  455. package/src/resources/extensions/gsd/tests/reassess-handler.test.ts +0 -117
  456. package/src/resources/extensions/gsd/tests/roadmap-slices.test.ts +0 -97
  457. package/src/resources/extensions/gsd/tests/secure-env-collect.test.ts +0 -134
  458. package/src/resources/extensions/gsd/tests/tool-naming.test.ts +1 -2
  459. package/src/resources/extensions/gsd/tests/triage-resolution.test.ts +0 -8
  460. package/src/resources/extensions/gsd/tests/unit-ownership.test.ts +17 -100
  461. package/src/resources/extensions/gsd/tests/validate-milestone-write-order.test.ts +1 -4
  462. package/src/resources/extensions/gsd/tests/workflow-logger.test.ts +0 -48
  463. package/src/resources/extensions/gsd/tests/workflow-manifest.test.ts +0 -92
  464. package/src/resources/extensions/gsd/tests/workflow-projections.test.ts +2 -4
  465. package/src/resources/extensions/gsd/tests/worktree-resolver.test.ts +1 -48
  466. package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +5 -29
  467. package/src/resources/extensions/gsd/tools/complete-task.ts +74 -36
  468. package/src/resources/extensions/gsd/tools/plan-milestone.ts +1 -13
  469. package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +0 -36
  470. package/src/resources/extensions/gsd/tools/validate-milestone.ts +2 -20
  471. package/src/resources/extensions/gsd/triage-resolution.ts +6 -23
  472. package/src/resources/extensions/gsd/types.ts +2 -4
  473. package/src/resources/extensions/gsd/undo.ts +2 -2
  474. package/src/resources/extensions/gsd/unit-ownership.ts +35 -206
  475. package/src/resources/extensions/gsd/verdict-parser.ts +6 -21
  476. package/src/resources/extensions/gsd/workflow-logger.ts +1 -3
  477. package/src/resources/extensions/gsd/workflow-manifest.ts +5 -22
  478. package/src/resources/extensions/gsd/workflow-projections.ts +64 -97
  479. package/src/resources/extensions/gsd/workflow-reconcile.ts +10 -39
  480. package/src/resources/extensions/gsd/workspace-index.ts +0 -30
  481. package/src/resources/extensions/gsd/worktree-manager.ts +1 -120
  482. package/src/resources/extensions/gsd/worktree-resolver.ts +3 -22
  483. package/src/resources/extensions/mcp-client/index.ts +7 -13
  484. package/src/resources/extensions/search-the-web/extension-manifest.json +1 -1
  485. package/src/resources/extensions/shared/interview-ui.ts +1 -12
  486. package/src/resources/skills/create-gsd-extension/SKILL.md +3 -5
  487. package/src/resources/skills/create-gsd-extension/references/key-rules-gotchas.md +4 -5
  488. package/src/resources/skills/create-gsd-extension/workflows/add-capability.md +2 -2
  489. package/src/resources/skills/create-gsd-extension/workflows/create-extension.md +4 -4
  490. package/src/resources/skills/create-gsd-extension/workflows/debug-extension.md +3 -5
  491. package/dist/resources/extensions/gsd/milestone-validation-gates.js +0 -45
  492. package/dist/resources/extensions/ollama/index.js +0 -112
  493. package/dist/resources/extensions/ollama/model-capabilities.js +0 -115
  494. package/dist/resources/extensions/ollama/ollama-client.js +0 -168
  495. package/dist/resources/extensions/ollama/ollama-commands.js +0 -194
  496. package/dist/resources/extensions/ollama/ollama-discovery.js +0 -69
  497. package/dist/resources/extensions/ollama/ollama-tool.js +0 -184
  498. package/dist/resources/extensions/ollama/types.js +0 -2
  499. package/dist/startup-model-validation.d.ts +0 -39
  500. package/dist/startup-model-validation.js +0 -50
  501. package/dist/web/standalone/.next/static/chunks/6502.7593d7797a4b3999.js +0 -9
  502. package/dist/web/standalone/.next/static/css/f6e8833d46e738d8.css +0 -1
  503. package/packages/native/src/__tests__/module-compat.test.mjs +0 -91
  504. package/packages/pi-agent-core/src/agent-loop.test.ts +0 -45
  505. package/packages/pi-ai/dist/providers/anthropic-shared.test.d.ts +0 -2
  506. package/packages/pi-ai/dist/providers/anthropic-shared.test.d.ts.map +0 -1
  507. package/packages/pi-ai/dist/providers/anthropic-shared.test.js +0 -25
  508. package/packages/pi-ai/dist/providers/anthropic-shared.test.js.map +0 -1
  509. package/packages/pi-ai/dist/utils/repair-tool-json.d.ts +0 -37
  510. package/packages/pi-ai/dist/utils/repair-tool-json.d.ts.map +0 -1
  511. package/packages/pi-ai/dist/utils/repair-tool-json.js +0 -75
  512. package/packages/pi-ai/dist/utils/repair-tool-json.js.map +0 -1
  513. package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.d.ts +0 -2
  514. package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.d.ts.map +0 -1
  515. package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.js +0 -73
  516. package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.js.map +0 -1
  517. package/packages/pi-ai/src/providers/anthropic-shared.test.ts +0 -29
  518. package/packages/pi-ai/src/utils/repair-tool-json.ts +0 -88
  519. package/packages/pi-ai/src/utils/tests/repair-tool-json.test.ts +0 -102
  520. package/packages/pi-coding-agent/dist/core/compaction/compaction.test.d.ts +0 -6
  521. package/packages/pi-coding-agent/dist/core/compaction/compaction.test.d.ts.map +0 -1
  522. package/packages/pi-coding-agent/dist/core/compaction/compaction.test.js +0 -176
  523. package/packages/pi-coding-agent/dist/core/compaction/compaction.test.js.map +0 -1
  524. package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.d.ts +0 -28
  525. package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.d.ts.map +0 -1
  526. package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.js +0 -37
  527. package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.js.map +0 -1
  528. package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.test.d.ts +0 -2
  529. package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.test.d.ts.map +0 -1
  530. package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.test.js +0 -63
  531. package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.test.js.map +0 -1
  532. package/packages/pi-coding-agent/dist/core/extensions/extension-sort.d.ts +0 -19
  533. package/packages/pi-coding-agent/dist/core/extensions/extension-sort.d.ts.map +0 -1
  534. package/packages/pi-coding-agent/dist/core/extensions/extension-sort.js +0 -115
  535. package/packages/pi-coding-agent/dist/core/extensions/extension-sort.js.map +0 -1
  536. package/packages/pi-coding-agent/dist/core/extensions/extension-sort.test.d.ts +0 -2
  537. package/packages/pi-coding-agent/dist/core/extensions/extension-sort.test.d.ts.map +0 -1
  538. package/packages/pi-coding-agent/dist/core/extensions/extension-sort.test.js +0 -109
  539. package/packages/pi-coding-agent/dist/core/extensions/extension-sort.test.js.map +0 -1
  540. package/packages/pi-coding-agent/dist/core/image-overflow-recovery.d.ts +0 -44
  541. package/packages/pi-coding-agent/dist/core/image-overflow-recovery.d.ts.map +0 -1
  542. package/packages/pi-coding-agent/dist/core/image-overflow-recovery.js +0 -97
  543. package/packages/pi-coding-agent/dist/core/image-overflow-recovery.js.map +0 -1
  544. package/packages/pi-coding-agent/dist/core/image-overflow-recovery.test.d.ts +0 -2
  545. package/packages/pi-coding-agent/dist/core/image-overflow-recovery.test.d.ts.map +0 -1
  546. package/packages/pi-coding-agent/dist/core/image-overflow-recovery.test.js +0 -181
  547. package/packages/pi-coding-agent/dist/core/image-overflow-recovery.test.js.map +0 -1
  548. package/packages/pi-coding-agent/dist/core/messages.test.d.ts +0 -9
  549. package/packages/pi-coding-agent/dist/core/messages.test.d.ts.map +0 -1
  550. package/packages/pi-coding-agent/dist/core/messages.test.js +0 -86
  551. package/packages/pi-coding-agent/dist/core/messages.test.js.map +0 -1
  552. package/packages/pi-coding-agent/dist/core/retry-handler.test.d.ts +0 -9
  553. package/packages/pi-coding-agent/dist/core/retry-handler.test.d.ts.map +0 -1
  554. package/packages/pi-coding-agent/dist/core/retry-handler.test.js +0 -193
  555. package/packages/pi-coding-agent/dist/core/retry-handler.test.js.map +0 -1
  556. package/packages/pi-coding-agent/dist/core/tools/spawn-shell-windows.test.d.ts +0 -16
  557. package/packages/pi-coding-agent/dist/core/tools/spawn-shell-windows.test.d.ts.map +0 -1
  558. package/packages/pi-coding-agent/dist/core/tools/spawn-shell-windows.test.js +0 -80
  559. package/packages/pi-coding-agent/dist/core/tools/spawn-shell-windows.test.js.map +0 -1
  560. package/packages/pi-coding-agent/src/core/compaction/compaction.test.ts +0 -236
  561. package/packages/pi-coding-agent/src/core/extensions/extension-manifest.test.ts +0 -77
  562. package/packages/pi-coding-agent/src/core/extensions/extension-manifest.ts +0 -62
  563. package/packages/pi-coding-agent/src/core/extensions/extension-sort.test.ts +0 -134
  564. package/packages/pi-coding-agent/src/core/extensions/extension-sort.ts +0 -137
  565. package/packages/pi-coding-agent/src/core/image-overflow-recovery.test.ts +0 -228
  566. package/packages/pi-coding-agent/src/core/image-overflow-recovery.ts +0 -118
  567. package/packages/pi-coding-agent/src/core/messages.test.ts +0 -114
  568. package/packages/pi-coding-agent/src/core/retry-handler.test.ts +0 -255
  569. package/packages/pi-coding-agent/src/core/tools/spawn-shell-windows.test.ts +0 -92
  570. package/src/resources/extensions/gsd/milestone-validation-gates.ts +0 -56
  571. package/src/resources/extensions/gsd/tests/auto-mode-interactive-guard.test.ts +0 -71
  572. package/src/resources/extensions/gsd/tests/cli-provider-rate-limit.test.ts +0 -47
  573. package/src/resources/extensions/gsd/tests/completion-hierarchy-guards.test.ts +0 -192
  574. package/src/resources/extensions/gsd/tests/db-path-worktree-symlink.test.ts +0 -131
  575. package/src/resources/extensions/gsd/tests/discord-invite-links.test.ts +0 -47
  576. package/src/resources/extensions/gsd/tests/discuss-empty-db-fallback.test.ts +0 -127
  577. package/src/resources/extensions/gsd/tests/dynamic-routing-default.test.ts +0 -20
  578. package/src/resources/extensions/gsd/tests/empty-content-abort-loop.test.ts +0 -74
  579. package/src/resources/extensions/gsd/tests/event-replay-idempotency.test.ts +0 -140
  580. package/src/resources/extensions/gsd/tests/forensics-context-persist.test.ts +0 -129
  581. package/src/resources/extensions/gsd/tests/forensics-db-completion.test.ts +0 -96
  582. package/src/resources/extensions/gsd/tests/gsdroot-worktree-detection.test.ts +0 -164
  583. package/src/resources/extensions/gsd/tests/guided-flow-dynamic-routing.test.ts +0 -135
  584. package/src/resources/extensions/gsd/tests/guided-flow-session-isolation.test.ts +0 -97
  585. package/src/resources/extensions/gsd/tests/hook-key-parsing.test.ts +0 -107
  586. package/src/resources/extensions/gsd/tests/integration/doctor-false-positives.test.ts +0 -243
  587. package/src/resources/extensions/gsd/tests/integration/gitignore-staging-2570.test.ts +0 -150
  588. package/src/resources/extensions/gsd/tests/integration/state-machine-live-validation.test.ts +0 -959
  589. package/src/resources/extensions/gsd/tests/migrate-external-worktree.test.ts +0 -105
  590. package/src/resources/extensions/gsd/tests/milestone-status-authoritative.test.ts +0 -116
  591. package/src/resources/extensions/gsd/tests/parallel-commit-scope.test.ts +0 -159
  592. package/src/resources/extensions/gsd/tests/parallel-eligibility-ghost.test.ts +0 -150
  593. package/src/resources/extensions/gsd/tests/plan-milestone-title.test.ts +0 -70
  594. package/src/resources/extensions/gsd/tests/project-relocation-recovery.test.ts +0 -297
  595. package/src/resources/extensions/gsd/tests/prompt-loader-replacement.test.ts +0 -178
  596. package/src/resources/extensions/gsd/tests/prompt-tool-names.test.ts +0 -69
  597. package/src/resources/extensions/gsd/tests/queue-execution-guard.test.ts +0 -157
  598. package/src/resources/extensions/gsd/tests/quick-turn-end-cleanup.test.ts +0 -90
  599. package/src/resources/extensions/gsd/tests/reconciliation-edge-cases.test.ts +0 -162
  600. package/src/resources/extensions/gsd/tests/slice-disk-reconcile.test.ts +0 -233
  601. package/src/resources/extensions/gsd/tests/stash-queued-context-files.test.ts +0 -305
  602. package/src/resources/extensions/gsd/tests/state-corruption-2945.test.ts +0 -405
  603. package/src/resources/extensions/gsd/tests/state-derivation-parity.test.ts +0 -257
  604. package/src/resources/extensions/gsd/tests/state-machine-full-walkthrough.test.ts +0 -1628
  605. package/src/resources/extensions/gsd/tests/stop-auto-race-null-unit.test.ts +0 -106
  606. package/src/resources/extensions/gsd/tests/stuck-detection-coverage.test.ts +0 -174
  607. package/src/resources/extensions/gsd/tests/summary-render-parity.test.ts +0 -221
  608. package/src/resources/extensions/gsd/tests/uat-stuck-loop-orphaned-worktree.test.ts +0 -289
  609. package/src/resources/extensions/gsd/tests/vacuum-recovery.test.ts +0 -154
  610. package/src/resources/extensions/gsd/tests/verdict-parser.test.ts +0 -156
  611. package/src/resources/extensions/gsd/tests/verification-operational-gate.test.ts +0 -82
  612. package/src/resources/extensions/gsd/tests/worktree-db-respawn-truncation.test.ts +0 -140
  613. package/src/resources/extensions/gsd/tests/worktree-nested-git-safety.test.ts +0 -101
  614. package/src/resources/extensions/gsd/tests/zombie-gsd-state.test.ts +0 -95
  615. package/src/resources/extensions/mcp-client/tests/server-name-spaces.test.ts +0 -55
  616. package/src/resources/extensions/ollama/index.ts +0 -130
  617. package/src/resources/extensions/ollama/model-capabilities.ts +0 -145
  618. package/src/resources/extensions/ollama/ollama-client.ts +0 -196
  619. package/src/resources/extensions/ollama/ollama-commands.ts +0 -248
  620. package/src/resources/extensions/ollama/ollama-discovery.ts +0 -106
  621. package/src/resources/extensions/ollama/ollama-tool.ts +0 -218
  622. package/src/resources/extensions/ollama/tests/model-capabilities.test.ts +0 -162
  623. package/src/resources/extensions/ollama/tests/ollama-client.test.ts +0 -38
  624. package/src/resources/extensions/ollama/tests/ollama-discovery.test.ts +0 -28
  625. package/src/resources/extensions/ollama/types.ts +0 -130
  626. package/src/resources/extensions/shared/tests/ask-user-freetext.test.ts +0 -156
  627. /package/dist/web/standalone/.next/static/{R0D4xaIPl5kg93edN7Oo0 → 5DLsjFHdSB6_a1EDQVjr7}/_buildManifest.js +0 -0
  628. /package/dist/web/standalone/.next/static/{R0D4xaIPl5kg93edN7Oo0 → 5DLsjFHdSB6_a1EDQVjr7}/_ssgManifest.js +0 -0
@@ -1,959 +0,0 @@
1
- /**
2
- * state-machine-live-validation.test.ts — Live operational validation of the
3
- * GSD state machine with real handlers, real DB, and real filesystem.
4
- *
5
- * Exercises every phase transition, completion guard, edge case, and reopen
6
- * path end-to-end. This is NOT a unit test — it drives the actual tool handlers
7
- * against a real temp directory with a real SQLite database.
8
- *
9
- * Findings reference: #3161 (state machine validation report)
10
- */
11
-
12
- // GSD State Machine Live Validation (#3161)
13
-
14
- import { describe, test, beforeEach, afterEach } from "node:test";
15
- import assert from "node:assert/strict";
16
- import {
17
- mkdtempSync,
18
- mkdirSync,
19
- writeFileSync,
20
- readFileSync,
21
- rmSync,
22
- existsSync,
23
- } from "node:fs";
24
- import { tmpdir } from "node:os";
25
- import { join } from "node:path";
26
-
27
- // ── DB layer ──────────────────────────────────────────────────────────────
28
- import {
29
- openDatabase,
30
- closeDatabase,
31
- insertMilestone,
32
- insertSlice,
33
- insertTask,
34
- getTask,
35
- getSlice,
36
- getMilestone,
37
- getSliceTasks,
38
- getMilestoneSlices,
39
- updateTaskStatus,
40
- updateSliceStatus,
41
- updateMilestoneStatus,
42
- } from "../../gsd-db.ts";
43
-
44
- // ── Tool handlers ─────────────────────────────────────────────────────────
45
- import { handleCompleteTask } from "../../tools/complete-task.ts";
46
- import { handleCompleteSlice } from "../../tools/complete-slice.ts";
47
- import { handleCompleteMilestone } from "../../tools/complete-milestone.ts";
48
- import { handleReopenTask } from "../../tools/reopen-task.ts";
49
- import { handleReopenSlice } from "../../tools/reopen-slice.ts";
50
-
51
- // ── State derivation ──────────────────────────────────────────────────────
52
- import {
53
- deriveState,
54
- deriveStateFromDb,
55
- invalidateStateCache,
56
- isGhostMilestone,
57
- } from "../../state.ts";
58
-
59
- // ── Status guards ─────────────────────────────────────────────────────────
60
- import { isClosedStatus } from "../../status-guards.ts";
61
-
62
- // ── Events ────────────────────────────────────────────────────────────────
63
- import { readEvents } from "../../workflow-events.ts";
64
-
65
- // ── Cache invalidation ───────────────────────────────────────────────────
66
- import { invalidateAllCaches } from "../../cache.ts";
67
-
68
- // ═══════════════════════════════════════════════════════════════════════════
69
- // Fixture Helpers
70
- // ═══════════════════════════════════════════════════════════════════════════
71
-
72
- function makeTempDir(): string {
73
- return mkdtempSync(join(tmpdir(), "gsd-live-validation-"));
74
- }
75
-
76
- /**
77
- * Create a realistic .gsd/ fixture with:
78
- * - M001 milestone with ROADMAP, CONTEXT
79
- * - S01 slice with PLAN (2 tasks T01, T02)
80
- * - S02 slice with PLAN (1 task T01)
81
- * - Task PLAN stubs for each task
82
- * - REQUIREMENTS.md and DECISIONS.md
83
- */
84
- function createFullFixture(): string {
85
- const base = makeTempDir();
86
- const gsdDir = join(base, ".gsd");
87
- const m001Dir = join(gsdDir, "milestones", "M001");
88
- const s01Dir = join(m001Dir, "slices", "S01");
89
- const s01Tasks = join(s01Dir, "tasks");
90
- const s02Dir = join(m001Dir, "slices", "S02");
91
- const s02Tasks = join(s02Dir, "tasks");
92
-
93
- mkdirSync(s01Tasks, { recursive: true });
94
- mkdirSync(s02Tasks, { recursive: true });
95
-
96
- // CONTEXT.md — needed to get past needs-discussion
97
- writeFileSync(
98
- join(m001Dir, "M001-CONTEXT.md"),
99
- [
100
- "# M001: Live Validation Milestone",
101
- "",
102
- "## Purpose",
103
- "Validate the state machine end-to-end.",
104
- ].join("\n"),
105
- );
106
-
107
- // ROADMAP.md
108
- writeFileSync(
109
- join(m001Dir, "M001-ROADMAP.md"),
110
- [
111
- "# M001: Live Validation Milestone",
112
- "",
113
- "## Vision",
114
- "Prove state machine correctness.",
115
- "",
116
- "## Success Criteria",
117
- "- All operations succeed",
118
- "",
119
- "## Slices",
120
- "",
121
- "- [ ] **S01: First Feature** `risk:low` `depends:[]`",
122
- " - After this: First feature proven.",
123
- "",
124
- "- [ ] **S02: Second Feature** `risk:low` `depends:[]`",
125
- " - After this: Second feature proven.",
126
- "",
127
- "## Boundary Map",
128
- "",
129
- "| From | To | Produces | Consumes |",
130
- "|------|----|----------|----------|",
131
- "| S01 | terminal | feature-a | nothing |",
132
- "| S02 | terminal | feature-b | nothing |",
133
- ].join("\n"),
134
- );
135
-
136
- // S01 PLAN
137
- writeFileSync(
138
- join(s01Dir, "S01-PLAN.md"),
139
- [
140
- "# S01: First Feature",
141
- "",
142
- "**Goal:** Implement first feature.",
143
- "",
144
- "## Tasks",
145
- "",
146
- "- [ ] **T01: Implementation** `est:30m`",
147
- " - Do: Build it",
148
- " - Verify: Run tests",
149
- "",
150
- "- [ ] **T02: Testing** `est:30m`",
151
- " - Do: Write tests",
152
- " - Verify: Run tests",
153
- ].join("\n"),
154
- );
155
-
156
- // S01 task plan stubs
157
- writeFileSync(join(s01Tasks, "T01-PLAN.md"), "# T01 Plan\nImplement.\n");
158
- writeFileSync(join(s01Tasks, "T02-PLAN.md"), "# T02 Plan\nTest.\n");
159
-
160
- // S02 PLAN
161
- writeFileSync(
162
- join(s02Dir, "S02-PLAN.md"),
163
- [
164
- "# S02: Second Feature",
165
- "",
166
- "**Goal:** Implement second feature.",
167
- "",
168
- "## Tasks",
169
- "",
170
- "- [ ] **T01: Implementation** `est:30m`",
171
- " - Do: Build it",
172
- " - Verify: Run tests",
173
- ].join("\n"),
174
- );
175
-
176
- // S02 task plan stub
177
- writeFileSync(join(s02Tasks, "T01-PLAN.md"), "# T01 Plan\nBuild.\n");
178
-
179
- // REQUIREMENTS.md
180
- writeFileSync(
181
- join(gsdDir, "REQUIREMENTS.md"),
182
- [
183
- "# Requirements",
184
- "",
185
- "## Active",
186
- "",
187
- "| ID | Description | Owner |",
188
- "|----|-------------|-------|",
189
- "| R001 | Feature works | S01 |",
190
- ].join("\n"),
191
- );
192
-
193
- // DECISIONS.md
194
- writeFileSync(
195
- join(gsdDir, "DECISIONS.md"),
196
- [
197
- "# Decisions",
198
- "",
199
- "| ID | Decision | Choice | Rationale |",
200
- "|----|----------|--------|-----------|",
201
- ].join("\n"),
202
- );
203
-
204
- return base;
205
- }
206
-
207
- function makeTaskParams(
208
- taskId: string,
209
- sliceId: string,
210
- milestoneId: string,
211
- overrides?: Partial<Record<string, unknown>>,
212
- ): Record<string, unknown> {
213
- return {
214
- taskId,
215
- sliceId,
216
- milestoneId,
217
- oneLiner: `Completed ${taskId}`,
218
- narrative: `Implemented ${taskId} with full coverage.`,
219
- verification: "All tests pass.",
220
- keyFiles: ["src/feature.ts"],
221
- keyDecisions: [],
222
- deviations: "None.",
223
- knownIssues: "None.",
224
- blockerDiscovered: false,
225
- verificationEvidence: [
226
- { command: "npm test", exitCode: 0, verdict: "pass", durationMs: 1000 },
227
- ],
228
- ...overrides,
229
- };
230
- }
231
-
232
- function makeSliceParams(
233
- sliceId: string,
234
- milestoneId: string,
235
- ): Record<string, unknown> {
236
- return {
237
- sliceId,
238
- milestoneId,
239
- sliceTitle: `${sliceId} Feature`,
240
- oneLiner: `${sliceId} proven`,
241
- narrative: "All tasks completed.",
242
- verification: "Tests pass.",
243
- keyFiles: ["src/feature.ts"],
244
- keyDecisions: [],
245
- patternsEstablished: [],
246
- observabilitySurfaces: [],
247
- deviations: "None.",
248
- knownLimitations: "None.",
249
- followUps: "None.",
250
- requirementsAdvanced: [],
251
- requirementsValidated: [],
252
- requirementsSurfaced: [],
253
- requirementsInvalidated: [],
254
- filesModified: [{ path: "src/feature.ts", description: "Feature" }],
255
- uatContent: "Acceptance criteria met.",
256
- provides: ["feature"],
257
- requires: [],
258
- affects: [],
259
- drillDownPaths: [],
260
- };
261
- }
262
-
263
- function makeMilestoneParams(milestoneId: string): Record<string, unknown> {
264
- return {
265
- milestoneId,
266
- title: "Live Validation Milestone",
267
- oneLiner: "Milestone proven end-to-end",
268
- narrative: "All slices completed and verified.",
269
- successCriteriaResults: "All criteria met.",
270
- definitionOfDoneResults: "All items checked.",
271
- requirementOutcomes: "All requirements satisfied.",
272
- keyDecisions: ["Chose approach A"],
273
- keyFiles: ["src/feature.ts"],
274
- lessonsLearned: ["Integration testing is valuable"],
275
- followUps: "None.",
276
- deviations: "None.",
277
- verificationPassed: true,
278
- };
279
- }
280
-
281
- // ═══════════════════════════════════════════════════════════════════════════
282
- // Test Suite
283
- // ═══════════════════════════════════════════════════════════════════════════
284
-
285
- describe("state-machine-live-validation", () => {
286
- let base: string;
287
-
288
- afterEach(() => {
289
- closeDatabase();
290
- if (base) rmSync(base, { recursive: true, force: true });
291
- });
292
-
293
- // ─────────────────────────────────────────────────────────────────────────
294
- // PHASE 1: Full happy-path lifecycle
295
- // ─────────────────────────────────────────────────────────────────────────
296
-
297
- describe("happy path: full lifecycle M001 → complete", () => {
298
- test("step 1: empty project derives pre-planning", async () => {
299
- base = makeTempDir();
300
- mkdirSync(join(base, ".gsd", "milestones"), { recursive: true });
301
- const state = await deriveState(base);
302
- assert.equal(state.phase, "pre-planning");
303
- assert.equal(state.activeMilestone, null);
304
- });
305
-
306
- test("step 2: milestone with CONTEXT-DRAFT derives needs-discussion", async () => {
307
- base = makeTempDir();
308
- const mDir = join(base, ".gsd", "milestones", "M001");
309
- mkdirSync(mDir, { recursive: true });
310
- writeFileSync(join(mDir, "M001-CONTEXT-DRAFT.md"), "# Draft\nDraft context.\n");
311
- invalidateStateCache();
312
- const state = await deriveState(base);
313
- assert.equal(state.phase, "needs-discussion");
314
- assert.equal(state.activeMilestone?.id, "M001");
315
- });
316
-
317
- test("step 3: full fixture with ROADMAP+PLAN derives planning or executing", async () => {
318
- base = createFullFixture();
319
- openDatabase(join(base, ".gsd", "gsd.db"));
320
- invalidateStateCache();
321
- const state = await deriveState(base);
322
- // Without DB migration, filesystem path is used — should be planning or executing
323
- assert.ok(
324
- ["planning", "executing", "pre-planning"].includes(state.phase),
325
- `expected planning/executing/pre-planning, got: ${state.phase}`,
326
- );
327
- });
328
-
329
- test("step 4: complete T01 in S01 — handler succeeds, DB reflects completion", async () => {
330
- base = createFullFixture();
331
- openDatabase(join(base, ".gsd", "gsd.db"));
332
- // Seed DB with hierarchy
333
- insertMilestone({ id: "M001", title: "Live Validation", status: "active" });
334
- insertSlice({ id: "S01", milestoneId: "M001", title: "First Feature", status: "in_progress" });
335
- insertTask({ id: "T01", sliceId: "S01", milestoneId: "M001", title: "Implementation", status: "pending" });
336
- insertTask({ id: "T02", sliceId: "S01", milestoneId: "M001", title: "Testing", status: "pending" });
337
-
338
- const result = await handleCompleteTask(makeTaskParams("T01", "S01", "M001") as any, base);
339
- assert.ok(!("error" in result), `expected success, got: ${JSON.stringify(result)}`);
340
-
341
- // Verify DB state
342
- const task = getTask("M001", "S01", "T01");
343
- assert.ok(task, "T01 should exist in DB");
344
- assert.ok(isClosedStatus(task!.status), `T01 status should be closed, got: ${task!.status}`);
345
-
346
- // Verify SUMMARY.md written to disk
347
- const summaryPath = join(base, ".gsd", "milestones", "M001", "slices", "S01", "tasks", "T01-SUMMARY.md");
348
- assert.ok(existsSync(summaryPath), "T01-SUMMARY.md should exist on disk");
349
-
350
- // Verify event log entry
351
- const events = readEvents(join(base, ".gsd", "event-log.jsonl"));
352
- const taskEvent = events.find(e => e.cmd === "complete-task" && (e.params as any).taskId === "T01");
353
- assert.ok(taskEvent, "event log should contain complete-task for T01");
354
- });
355
-
356
- test("step 5: complete T02 in S01 — both tasks now done", async () => {
357
- base = createFullFixture();
358
- openDatabase(join(base, ".gsd", "gsd.db"));
359
- insertMilestone({ id: "M001", title: "Live Validation", status: "active" });
360
- insertSlice({ id: "S01", milestoneId: "M001", title: "First Feature", status: "in_progress" });
361
- insertTask({ id: "T01", sliceId: "S01", milestoneId: "M001", title: "Implementation", status: "complete" });
362
- insertTask({ id: "T02", sliceId: "S01", milestoneId: "M001", title: "Testing", status: "pending" });
363
-
364
- const result = await handleCompleteTask(makeTaskParams("T02", "S01", "M001") as any, base);
365
- assert.ok(!("error" in result), `expected success, got: ${JSON.stringify(result)}`);
366
-
367
- // Both tasks complete
368
- const tasks = getSliceTasks("M001", "S01");
369
- assert.equal(tasks.length, 2);
370
- assert.ok(tasks.every(t => isClosedStatus(t.status)), "all tasks should be closed");
371
- });
372
-
373
- test("step 6: complete slice S01 — all tasks done, slice closes", async () => {
374
- base = createFullFixture();
375
- openDatabase(join(base, ".gsd", "gsd.db"));
376
- insertMilestone({ id: "M001", title: "Live Validation", status: "active" });
377
- insertSlice({ id: "S01", milestoneId: "M001", title: "First Feature", status: "in_progress" });
378
- insertTask({ id: "T01", sliceId: "S01", milestoneId: "M001", title: "Impl", status: "complete" });
379
- insertTask({ id: "T02", sliceId: "S01", milestoneId: "M001", title: "Test", status: "complete" });
380
-
381
- const result = await handleCompleteSlice(makeSliceParams("S01", "M001") as any, base);
382
- assert.ok(!("error" in result), `expected success, got: ${JSON.stringify(result)}`);
383
-
384
- const slice = getSlice("M001", "S01");
385
- assert.ok(slice, "S01 should exist");
386
- assert.ok(isClosedStatus(slice!.status), `S01 should be closed, got: ${slice!.status}`);
387
-
388
- // SUMMARY.md on disk
389
- const summaryPath = join(base, ".gsd", "milestones", "M001", "slices", "S01", "S01-SUMMARY.md");
390
- assert.ok(existsSync(summaryPath), "S01-SUMMARY.md should exist");
391
- });
392
-
393
- test("step 7: complete S02 task + slice — both slices done", async () => {
394
- base = createFullFixture();
395
- openDatabase(join(base, ".gsd", "gsd.db"));
396
- insertMilestone({ id: "M001", title: "Live Validation", status: "active" });
397
- insertSlice({ id: "S01", milestoneId: "M001", title: "First", status: "complete" });
398
- insertSlice({ id: "S02", milestoneId: "M001", title: "Second", status: "in_progress" });
399
- insertTask({ id: "T01", sliceId: "S01", milestoneId: "M001", title: "Impl", status: "complete" });
400
- insertTask({ id: "T01", sliceId: "S02", milestoneId: "M001", title: "Impl", status: "pending" });
401
-
402
- // Complete task
403
- const taskResult = await handleCompleteTask(makeTaskParams("T01", "S02", "M001") as any, base);
404
- assert.ok(!("error" in taskResult), `task: ${JSON.stringify(taskResult)}`);
405
-
406
- // Complete slice
407
- const sliceResult = await handleCompleteSlice(makeSliceParams("S02", "M001") as any, base);
408
- assert.ok(!("error" in sliceResult), `slice: ${JSON.stringify(sliceResult)}`);
409
-
410
- // Both slices complete
411
- const slices = getMilestoneSlices("M001");
412
- assert.ok(slices.length >= 2, "should have 2+ slices");
413
- assert.ok(slices.every(s => isClosedStatus(s.status)), "all slices should be closed");
414
- });
415
-
416
- test("step 8: complete milestone M001 — full lifecycle done", async () => {
417
- base = createFullFixture();
418
- openDatabase(join(base, ".gsd", "gsd.db"));
419
- insertMilestone({ id: "M001", title: "Live Validation", status: "active" });
420
- insertSlice({ id: "S01", milestoneId: "M001", title: "First", status: "complete" });
421
- insertSlice({ id: "S02", milestoneId: "M001", title: "Second", status: "complete" });
422
- insertTask({ id: "T01", sliceId: "S01", milestoneId: "M001", title: "Impl", status: "complete" });
423
- insertTask({ id: "T02", sliceId: "S01", milestoneId: "M001", title: "Test", status: "complete" });
424
- insertTask({ id: "T01", sliceId: "S02", milestoneId: "M001", title: "Impl", status: "complete" });
425
-
426
- const result = await handleCompleteMilestone(makeMilestoneParams("M001") as any, base);
427
- assert.ok(!("error" in result), `expected success, got: ${JSON.stringify(result)}`);
428
-
429
- const milestone = getMilestone("M001");
430
- assert.ok(milestone, "M001 should exist");
431
- assert.ok(isClosedStatus(milestone!.status), `M001 should be closed, got: ${milestone!.status}`);
432
-
433
- // SUMMARY.md on disk
434
- const summaryPath = join(base, ".gsd", "milestones", "M001", "M001-SUMMARY.md");
435
- assert.ok(existsSync(summaryPath), "M001-SUMMARY.md should exist");
436
- });
437
- });
438
-
439
- // ─────────────────────────────────────────────────────────────────────────
440
- // PHASE 2: Completion guard edge cases
441
- // ─────────────────────────────────────────────────────────────────────────
442
-
443
- describe("completion guards — edge cases", () => {
444
- test("cannot complete task with empty taskId", async () => {
445
- base = createFullFixture();
446
- openDatabase(join(base, ".gsd", "gsd.db"));
447
- const result = await handleCompleteTask(makeTaskParams("", "S01", "M001") as any, base);
448
- assert.ok("error" in result);
449
- assert.match((result as any).error, /taskId is required/);
450
- });
451
-
452
- test("cannot complete task in closed milestone", async () => {
453
- base = createFullFixture();
454
- openDatabase(join(base, ".gsd", "gsd.db"));
455
- insertMilestone({ id: "M001", title: "Done", status: "complete" });
456
- insertSlice({ id: "S01", milestoneId: "M001" });
457
- insertTask({ id: "T01", sliceId: "S01", milestoneId: "M001", status: "pending" });
458
-
459
- const result = await handleCompleteTask(makeTaskParams("T01", "S01", "M001") as any, base);
460
- assert.ok("error" in result);
461
- assert.match((result as any).error, /closed milestone/);
462
- });
463
-
464
- test("cannot complete task in closed slice", async () => {
465
- base = createFullFixture();
466
- openDatabase(join(base, ".gsd", "gsd.db"));
467
- insertMilestone({ id: "M001", title: "Active", status: "active" });
468
- insertSlice({ id: "S01", milestoneId: "M001", status: "complete" });
469
- insertTask({ id: "T01", sliceId: "S01", milestoneId: "M001", status: "pending" });
470
-
471
- const result = await handleCompleteTask(makeTaskParams("T01", "S01", "M001") as any, base);
472
- assert.ok("error" in result);
473
- assert.match((result as any).error, /closed slice/);
474
- });
475
-
476
- test("double task completion returns error (H5-related)", async () => {
477
- base = createFullFixture();
478
- openDatabase(join(base, ".gsd", "gsd.db"));
479
- insertMilestone({ id: "M001", title: "Active", status: "active" });
480
- insertSlice({ id: "S01", milestoneId: "M001", status: "in_progress" });
481
- insertTask({ id: "T01", sliceId: "S01", milestoneId: "M001", status: "complete" });
482
-
483
- const result = await handleCompleteTask(makeTaskParams("T01", "S01", "M001") as any, base);
484
- assert.ok("error" in result);
485
- assert.match((result as any).error, /already complete/);
486
- });
487
-
488
- test("cannot complete slice with zero tasks — vacuous truth guard", async () => {
489
- base = createFullFixture();
490
- openDatabase(join(base, ".gsd", "gsd.db"));
491
- insertMilestone({ id: "M001", title: "Active", status: "active" });
492
- insertSlice({ id: "S01", milestoneId: "M001", status: "in_progress" });
493
- // No tasks inserted
494
-
495
- const result = await handleCompleteSlice(makeSliceParams("S01", "M001") as any, base);
496
- assert.ok("error" in result);
497
- assert.match((result as any).error, /no tasks found/);
498
- });
499
-
500
- test("cannot complete slice with incomplete tasks", async () => {
501
- base = createFullFixture();
502
- openDatabase(join(base, ".gsd", "gsd.db"));
503
- insertMilestone({ id: "M001", title: "Active", status: "active" });
504
- insertSlice({ id: "S01", milestoneId: "M001", status: "in_progress" });
505
- insertTask({ id: "T01", sliceId: "S01", milestoneId: "M001", status: "complete" });
506
- insertTask({ id: "T02", sliceId: "S01", milestoneId: "M001", status: "pending" });
507
-
508
- const result = await handleCompleteSlice(makeSliceParams("S01", "M001") as any, base);
509
- assert.ok("error" in result);
510
- assert.match((result as any).error, /incomplete tasks/);
511
- });
512
-
513
- test("double slice completion returns error", async () => {
514
- base = createFullFixture();
515
- openDatabase(join(base, ".gsd", "gsd.db"));
516
- insertMilestone({ id: "M001", title: "Active", status: "active" });
517
- insertSlice({ id: "S01", milestoneId: "M001", status: "complete" });
518
- insertTask({ id: "T01", sliceId: "S01", milestoneId: "M001", status: "complete" });
519
-
520
- const result = await handleCompleteSlice(makeSliceParams("S01", "M001") as any, base);
521
- assert.ok("error" in result);
522
- assert.match((result as any).error, /already complete/);
523
- });
524
-
525
- test("cannot complete milestone with zero slices", async () => {
526
- base = createFullFixture();
527
- openDatabase(join(base, ".gsd", "gsd.db"));
528
- insertMilestone({ id: "M001", title: "Active", status: "active" });
529
-
530
- const result = await handleCompleteMilestone(makeMilestoneParams("M001") as any, base);
531
- assert.ok("error" in result);
532
- assert.match((result as any).error, /no slices found/);
533
- });
534
-
535
- test("cannot complete milestone with incomplete slices", async () => {
536
- base = createFullFixture();
537
- openDatabase(join(base, ".gsd", "gsd.db"));
538
- insertMilestone({ id: "M001", title: "Active", status: "active" });
539
- insertSlice({ id: "S01", milestoneId: "M001", status: "complete" });
540
- insertSlice({ id: "S02", milestoneId: "M001", status: "in_progress" });
541
- insertTask({ id: "T01", sliceId: "S01", milestoneId: "M001", status: "complete" });
542
- insertTask({ id: "T01", sliceId: "S02", milestoneId: "M001", status: "pending" });
543
-
544
- const result = await handleCompleteMilestone(makeMilestoneParams("M001") as any, base);
545
- assert.ok("error" in result);
546
- assert.match((result as any).error, /incomplete slices/);
547
- });
548
-
549
- test("cannot complete milestone with incomplete tasks in complete slice (deep check)", async () => {
550
- base = createFullFixture();
551
- openDatabase(join(base, ".gsd", "gsd.db"));
552
- insertMilestone({ id: "M001", title: "Active", status: "active" });
553
- // Slice marked complete but task is still pending — simulates inconsistent state
554
- insertSlice({ id: "S01", milestoneId: "M001", status: "complete" });
555
- insertTask({ id: "T01", sliceId: "S01", milestoneId: "M001", status: "pending" });
556
-
557
- const result = await handleCompleteMilestone(makeMilestoneParams("M001") as any, base);
558
- assert.ok("error" in result);
559
- assert.match((result as any).error, /incomplete tasks/);
560
- });
561
-
562
- test("cannot complete milestone without verificationPassed=true", async () => {
563
- base = createFullFixture();
564
- openDatabase(join(base, ".gsd", "gsd.db"));
565
- insertMilestone({ id: "M001", title: "Active", status: "active" });
566
- insertSlice({ id: "S01", milestoneId: "M001", status: "complete" });
567
- insertTask({ id: "T01", sliceId: "S01", milestoneId: "M001", status: "complete" });
568
-
569
- const params = makeMilestoneParams("M001");
570
- params.verificationPassed = false;
571
- const result = await handleCompleteMilestone(params as any, base);
572
- assert.ok("error" in result);
573
- assert.match((result as any).error, /verification did not pass/);
574
- });
575
-
576
- test("double milestone completion returns error", async () => {
577
- base = createFullFixture();
578
- openDatabase(join(base, ".gsd", "gsd.db"));
579
- insertMilestone({ id: "M001", title: "Done", status: "complete" });
580
- insertSlice({ id: "S01", milestoneId: "M001", status: "complete" });
581
- insertTask({ id: "T01", sliceId: "S01", milestoneId: "M001", status: "complete" });
582
-
583
- const result = await handleCompleteMilestone(makeMilestoneParams("M001") as any, base);
584
- assert.ok("error" in result);
585
- assert.match((result as any).error, /already complete/);
586
- });
587
- });
588
-
589
- // ─────────────────────────────────────────────────────────────────────────
590
- // PHASE 3: Reopen operations
591
- // ─────────────────────────────────────────────────────────────────────────
592
-
593
- describe("reopen operations", () => {
594
- test("reopen task: resets completed task to pending", async () => {
595
- base = createFullFixture();
596
- openDatabase(join(base, ".gsd", "gsd.db"));
597
- insertMilestone({ id: "M001", title: "Active", status: "active" });
598
- insertSlice({ id: "S01", milestoneId: "M001", status: "in_progress" });
599
- insertTask({ id: "T01", sliceId: "S01", milestoneId: "M001", status: "complete" });
600
-
601
- const result = await handleReopenTask(
602
- { milestoneId: "M001", sliceId: "S01", taskId: "T01", reason: "Need to redo" },
603
- base,
604
- );
605
- assert.ok(!("error" in result), `expected success: ${JSON.stringify(result)}`);
606
-
607
- const task = getTask("M001", "S01", "T01");
608
- assert.equal(task!.status, "pending");
609
- });
610
-
611
- test("cannot reopen task that is not complete", async () => {
612
- base = createFullFixture();
613
- openDatabase(join(base, ".gsd", "gsd.db"));
614
- insertMilestone({ id: "M001", title: "Active", status: "active" });
615
- insertSlice({ id: "S01", milestoneId: "M001", status: "in_progress" });
616
- insertTask({ id: "T01", sliceId: "S01", milestoneId: "M001", status: "pending" });
617
-
618
- const result = await handleReopenTask(
619
- { milestoneId: "M001", sliceId: "S01", taskId: "T01" },
620
- base,
621
- );
622
- assert.ok("error" in result);
623
- assert.match((result as any).error, /not complete/);
624
- });
625
-
626
- test("cannot reopen task in closed slice — must reopen slice first", async () => {
627
- base = createFullFixture();
628
- openDatabase(join(base, ".gsd", "gsd.db"));
629
- insertMilestone({ id: "M001", title: "Active", status: "active" });
630
- insertSlice({ id: "S01", milestoneId: "M001", status: "complete" });
631
- insertTask({ id: "T01", sliceId: "S01", milestoneId: "M001", status: "complete" });
632
-
633
- const result = await handleReopenTask(
634
- { milestoneId: "M001", sliceId: "S01", taskId: "T01" },
635
- base,
636
- );
637
- assert.ok("error" in result);
638
- assert.match((result as any).error, /closed slice/);
639
- });
640
-
641
- test("cannot reopen task in closed milestone", async () => {
642
- base = createFullFixture();
643
- openDatabase(join(base, ".gsd", "gsd.db"));
644
- insertMilestone({ id: "M001", title: "Done", status: "complete" });
645
- insertSlice({ id: "S01", milestoneId: "M001", status: "complete" });
646
- insertTask({ id: "T01", sliceId: "S01", milestoneId: "M001", status: "complete" });
647
-
648
- const result = await handleReopenTask(
649
- { milestoneId: "M001", sliceId: "S01", taskId: "T01" },
650
- base,
651
- );
652
- assert.ok("error" in result);
653
- assert.match((result as any).error, /closed milestone/);
654
- });
655
-
656
- test("reopen slice: resets slice to in_progress and all tasks to pending", async () => {
657
- base = createFullFixture();
658
- openDatabase(join(base, ".gsd", "gsd.db"));
659
- insertMilestone({ id: "M001", title: "Active", status: "active" });
660
- insertSlice({ id: "S01", milestoneId: "M001", status: "complete" });
661
- insertTask({ id: "T01", sliceId: "S01", milestoneId: "M001", status: "complete" });
662
- insertTask({ id: "T02", sliceId: "S01", milestoneId: "M001", status: "complete" });
663
-
664
- const result = await handleReopenSlice(
665
- { milestoneId: "M001", sliceId: "S01", reason: "Need rework" },
666
- base,
667
- );
668
- assert.ok(!("error" in result), `expected success: ${JSON.stringify(result)}`);
669
- assert.equal((result as any).tasksReset, 2);
670
-
671
- // Verify slice state
672
- const slice = getSlice("M001", "S01");
673
- assert.equal(slice!.status, "in_progress");
674
-
675
- // Verify all tasks reset to pending
676
- const tasks = getSliceTasks("M001", "S01");
677
- assert.ok(tasks.every(t => t.status === "pending"), "all tasks should be pending after slice reopen");
678
- });
679
-
680
- test("cannot reopen slice in closed milestone", async () => {
681
- base = createFullFixture();
682
- openDatabase(join(base, ".gsd", "gsd.db"));
683
- insertMilestone({ id: "M001", title: "Done", status: "complete" });
684
- insertSlice({ id: "S01", milestoneId: "M001", status: "complete" });
685
-
686
- const result = await handleReopenSlice(
687
- { milestoneId: "M001", sliceId: "S01" },
688
- base,
689
- );
690
- assert.ok("error" in result);
691
- assert.match((result as any).error, /closed milestone/);
692
- });
693
-
694
- test("no reopen-milestone tool exists — milestone completion is irrevocable (H5)", async () => {
695
- // This test documents the H5 finding: there is no handleReopenMilestone function.
696
- // A completed milestone can only be undone via direct DB manipulation.
697
- base = createFullFixture();
698
- openDatabase(join(base, ".gsd", "gsd.db"));
699
- insertMilestone({ id: "M001", title: "Done", status: "complete" });
700
-
701
- const milestone = getMilestone("M001");
702
- assert.ok(isClosedStatus(milestone!.status), "milestone is closed");
703
-
704
- // The only escape is direct DB manipulation — no handler exists
705
- updateMilestoneStatus("M001", "active", null);
706
- const reopened = getMilestone("M001");
707
- assert.equal(reopened!.status, "active", "direct DB manipulation can reopen, but no tool exposes this");
708
- });
709
- });
710
-
711
- // ─────────────────────────────────────────────────────────────────────────
712
- // PHASE 4: Phantom parents and auto-creation (H6)
713
- // ─────────────────────────────────────────────────────────────────────────
714
-
715
- describe("phantom parent auto-creation (H6)", () => {
716
- test("completing task for non-existent milestone/slice auto-creates them", async () => {
717
- base = createFullFixture();
718
- openDatabase(join(base, ".gsd", "gsd.db"));
719
- // No milestone or slice pre-inserted — handler will auto-create
720
-
721
- const result = await handleCompleteTask(makeTaskParams("T01", "S99", "M099") as any, base);
722
- assert.ok(!("error" in result), `expected success: ${JSON.stringify(result)}`);
723
-
724
- // Phantom milestone created
725
- const milestone = getMilestone("M099");
726
- assert.ok(milestone, "phantom milestone M099 should exist");
727
- assert.equal(milestone!.title, "", "phantom milestone has empty title");
728
-
729
- // Phantom slice created
730
- const slice = getSlice("M099", "S99");
731
- assert.ok(slice, "phantom slice S99 should exist");
732
- });
733
-
734
- test("completing slice for non-existent milestone auto-creates it", async () => {
735
- base = createFullFixture();
736
- openDatabase(join(base, ".gsd", "gsd.db"));
737
- // Insert task to satisfy completion guard
738
- insertMilestone({ id: "M099" });
739
- insertSlice({ id: "S99", milestoneId: "M099" });
740
- insertTask({ id: "T01", sliceId: "S99", milestoneId: "M099", status: "complete" });
741
-
742
- const result = await handleCompleteSlice(makeSliceParams("S99", "M099") as any, base);
743
- assert.ok(!("error" in result), `expected success: ${JSON.stringify(result)}`);
744
- });
745
- });
746
-
747
- // ─────────────────────────────────────────────────────────────────────────
748
- // PHASE 5: State derivation consistency
749
- // ─────────────────────────────────────────────────────────────────────────
750
-
751
- describe("state derivation with live DB", () => {
752
- test("deriveStateFromDb reflects task completion immediately", async () => {
753
- base = createFullFixture();
754
- openDatabase(join(base, ".gsd", "gsd.db"));
755
- insertMilestone({ id: "M001", title: "Active", status: "active" });
756
- insertSlice({ id: "S01", milestoneId: "M001", title: "First", status: "in_progress" });
757
- insertTask({ id: "T01", sliceId: "S01", milestoneId: "M001", status: "pending" });
758
- insertTask({ id: "T02", sliceId: "S01", milestoneId: "M001", status: "pending" });
759
-
760
- invalidateStateCache();
761
- const stateBefore = await deriveStateFromDb(base);
762
- assert.equal(stateBefore.phase, "executing", `before: expected executing, got ${stateBefore.phase}`);
763
-
764
- // Complete T01
765
- updateTaskStatus("M001", "S01", "T01", "complete", new Date().toISOString());
766
- invalidateStateCache();
767
- const stateAfterT01 = await deriveStateFromDb(base);
768
- // Still executing — T02 is pending
769
- assert.equal(stateAfterT01.phase, "executing", `after T01: expected executing, got ${stateAfterT01.phase}`);
770
-
771
- // Complete T02
772
- updateTaskStatus("M001", "S01", "T02", "complete", new Date().toISOString());
773
- invalidateStateCache();
774
- const stateAfterT02 = await deriveStateFromDb(base);
775
- // All tasks done → summarizing
776
- assert.equal(stateAfterT02.phase, "summarizing", `after T02: expected summarizing, got ${stateAfterT02.phase}`);
777
- });
778
-
779
- test("deriveStateFromDb reflects slice completion → next slice or validating", async () => {
780
- base = createFullFixture();
781
- openDatabase(join(base, ".gsd", "gsd.db"));
782
- insertMilestone({ id: "M001", title: "Active", status: "active" });
783
- insertSlice({ id: "S01", milestoneId: "M001", title: "First", status: "complete" });
784
- insertSlice({ id: "S02", milestoneId: "M001", title: "Second", status: "in_progress" });
785
- insertTask({ id: "T01", sliceId: "S01", milestoneId: "M001", status: "complete" });
786
- insertTask({ id: "T01", sliceId: "S02", milestoneId: "M001", status: "pending" });
787
-
788
- invalidateStateCache();
789
- const state = await deriveStateFromDb(base);
790
- // S01 done, S02 has pending task → executing
791
- assert.equal(state.phase, "executing", `expected executing for S02, got ${state.phase}`);
792
- assert.equal(state.activeSlice?.id, "S02", "active slice should be S02");
793
- });
794
-
795
- test("deriveStateFromDb with all slices done → validating-milestone", async () => {
796
- base = createFullFixture();
797
- openDatabase(join(base, ".gsd", "gsd.db"));
798
- insertMilestone({ id: "M001", title: "Active", status: "active" });
799
- insertSlice({ id: "S01", milestoneId: "M001", title: "First", status: "complete" });
800
- insertSlice({ id: "S02", milestoneId: "M001", title: "Second", status: "complete" });
801
- insertTask({ id: "T01", sliceId: "S01", milestoneId: "M001", status: "complete" });
802
- insertTask({ id: "T01", sliceId: "S02", milestoneId: "M001", status: "complete" });
803
-
804
- invalidateStateCache();
805
- const state = await deriveStateFromDb(base);
806
- assert.equal(state.phase, "validating-milestone", `expected validating-milestone, got ${state.phase}`);
807
- });
808
-
809
- test("ghost milestone is skipped by deriveState", async () => {
810
- base = makeTempDir();
811
- const gsdDir = join(base, ".gsd", "milestones");
812
- // M001 is ghost — empty dir
813
- mkdirSync(join(gsdDir, "M001"), { recursive: true });
814
- // M002 has content
815
- mkdirSync(join(gsdDir, "M002"), { recursive: true });
816
- writeFileSync(join(gsdDir, "M002", "M002-CONTEXT-DRAFT.md"), "# Draft\nContent.\n");
817
-
818
- assert.ok(isGhostMilestone(base, "M001"), "M001 should be ghost");
819
- assert.ok(!isGhostMilestone(base, "M002"), "M002 should not be ghost");
820
-
821
- invalidateStateCache();
822
- const state = await deriveState(base);
823
- assert.equal(state.activeMilestone?.id, "M002", "should skip ghost M001 and use M002");
824
- });
825
- });
826
-
827
- // ─────────────────────────────────────────────────────────────────────────
828
- // PHASE 6: Event log integrity
829
- // ─────────────────────────────────────────────────────────────────────────
830
-
831
- describe("event log integrity across operations", () => {
832
- test("full operation sequence produces correct event log", async () => {
833
- base = createFullFixture();
834
- openDatabase(join(base, ".gsd", "gsd.db"));
835
- insertMilestone({ id: "M001", title: "Active", status: "active" });
836
- insertSlice({ id: "S01", milestoneId: "M001", title: "First", status: "in_progress" });
837
- insertTask({ id: "T01", sliceId: "S01", milestoneId: "M001", status: "pending" });
838
- insertTask({ id: "T02", sliceId: "S01", milestoneId: "M001", status: "pending" });
839
-
840
- // Complete T01
841
- await handleCompleteTask(makeTaskParams("T01", "S01", "M001") as any, base);
842
- // Complete T02
843
- await handleCompleteTask(makeTaskParams("T02", "S01", "M001") as any, base);
844
- // Complete S01
845
- await handleCompleteSlice(makeSliceParams("S01", "M001") as any, base);
846
-
847
- const events = readEvents(join(base, ".gsd", "event-log.jsonl"));
848
-
849
- // Should have 3 events: 2 task completions + 1 slice completion
850
- assert.ok(events.length >= 3, `expected ≥3 events, got ${events.length}`);
851
-
852
- const taskEvents = events.filter(e => e.cmd === "complete-task");
853
- assert.equal(taskEvents.length, 2, "2 task completion events");
854
-
855
- const sliceEvents = events.filter(e => e.cmd === "complete-slice");
856
- assert.equal(sliceEvents.length, 1, "1 slice completion event");
857
-
858
- // Events are ordered chronologically
859
- for (let i = 1; i < events.length; i++) {
860
- assert.ok(
861
- events[i]!.ts >= events[i - 1]!.ts,
862
- `events should be chronologically ordered: ${events[i - 1]!.ts} <= ${events[i]!.ts}`,
863
- );
864
- }
865
-
866
- // All events have hashes and session IDs
867
- for (const event of events) {
868
- assert.ok(event.hash, "event should have hash");
869
- assert.ok(event.session_id, "event should have session_id");
870
- }
871
- });
872
-
873
- test("reopen operations produce events", async () => {
874
- base = createFullFixture();
875
- openDatabase(join(base, ".gsd", "gsd.db"));
876
- insertMilestone({ id: "M001", title: "Active", status: "active" });
877
- insertSlice({ id: "S01", milestoneId: "M001", status: "in_progress" });
878
- insertTask({ id: "T01", sliceId: "S01", milestoneId: "M001", status: "complete" });
879
-
880
- await handleReopenTask(
881
- { milestoneId: "M001", sliceId: "S01", taskId: "T01", reason: "redo" },
882
- base,
883
- );
884
-
885
- const events = readEvents(join(base, ".gsd", "event-log.jsonl"));
886
- const reopenEvent = events.find(e => e.cmd === "reopen-task");
887
- assert.ok(reopenEvent, "should have reopen-task event");
888
- assert.equal((reopenEvent!.params as any).taskId, "T01");
889
- assert.equal((reopenEvent!.params as any).reason, "redo");
890
- });
891
- });
892
-
893
- // ─────────────────────────────────────────────────────────────────────────
894
- // PHASE 7: Reopen-then-redo cycle
895
- // ─────────────────────────────────────────────────────────────────────────
896
-
897
- describe("reopen-then-redo cycle", () => {
898
- test("complete → reopen → M12: stale SUMMARY causes immediate auto-reconcile", async () => {
899
- // Finding M12: reopen-task does NOT delete the SUMMARY.md from disk.
900
- // The reopen handler's own post-mutation hook calls renderAllProjections
901
- // which triggers deriveStateFromDb, which sees the stale SUMMARY.md and
902
- // auto-reconciles the task BACK to "complete" (#2514) within the same call.
903
- //
904
- // Result: the reopen is effectively a no-op when filesystem artifacts exist.
905
- base = createFullFixture();
906
- openDatabase(join(base, ".gsd", "gsd.db"));
907
- insertMilestone({ id: "M001", title: "Active", status: "active" });
908
- insertSlice({ id: "S01", milestoneId: "M001", title: "First", status: "in_progress" });
909
- insertTask({ id: "T01", sliceId: "S01", milestoneId: "M001", status: "pending" });
910
-
911
- // Complete — writes T01-SUMMARY.md to disk
912
- const r1 = await handleCompleteTask(makeTaskParams("T01", "S01", "M001") as any, base);
913
- assert.ok(!("error" in r1), `first complete: ${JSON.stringify(r1)}`);
914
-
915
- const summaryPath = join(base, ".gsd", "milestones", "M001", "slices", "S01", "tasks", "T01-SUMMARY.md");
916
- assert.ok(existsSync(summaryPath), "SUMMARY.md exists after completion");
917
-
918
- // Reopen — handler sets DB to "pending" in transaction, but post-mutation
919
- // hook triggers reconciler which immediately sets it back to "complete"
920
- const r2 = await handleReopenTask({ milestoneId: "M001", sliceId: "S01", taskId: "T01" }, base);
921
- assert.ok(!("error" in r2), `reopen handler succeeded: ${JSON.stringify(r2)}`);
922
-
923
- // M12: After reopen completes, DB shows "complete" not "pending" because
924
- // the reconciler auto-corrected it from the stale SUMMARY.md
925
- const task = getTask("M001", "S01", "T01");
926
- assert.equal(task!.status, "complete", "M12: reconciler overrides reopen — task is back to complete");
927
- assert.ok(existsSync(summaryPath), "M12: SUMMARY.md was never cleaned up");
928
- });
929
-
930
- test("complete slice → reopen → M12: reconciler overrides task reset via stale SUMMARY", async () => {
931
- // Same M12 pattern at the slice level: reopen-slice resets all tasks to
932
- // "pending" in DB, but task SUMMARY.md artifacts remain on disk. The
933
- // reopen handler's post-mutation hook triggers reconciler which sees the
934
- // stale artifacts and auto-corrects tasks back to "complete".
935
- base = createFullFixture();
936
- openDatabase(join(base, ".gsd", "gsd.db"));
937
- insertMilestone({ id: "M001", title: "Active", status: "active" });
938
- insertSlice({ id: "S01", milestoneId: "M001", title: "First", status: "in_progress" });
939
- insertTask({ id: "T01", sliceId: "S01", milestoneId: "M001", status: "pending" });
940
-
941
- // Complete task + slice
942
- await handleCompleteTask(makeTaskParams("T01", "S01", "M001") as any, base);
943
- await handleCompleteSlice(makeSliceParams("S01", "M001") as any, base);
944
- assert.ok(isClosedStatus(getSlice("M001", "S01")!.status));
945
-
946
- // Reopen slice — transaction resets slice to in_progress and task to pending,
947
- // but post-mutation hook triggers reconciler which sees stale SUMMARY.md
948
- await handleReopenSlice({ milestoneId: "M001", sliceId: "S01" }, base);
949
-
950
- // Slice status is correctly in_progress (no slice SUMMARY reconciliation)
951
- assert.equal(getSlice("M001", "S01")!.status, "in_progress");
952
-
953
- // M12: Task was reset to "pending" in the transaction, but reconciler
954
- // already corrected it back to "complete" from the stale SUMMARY.md
955
- const task = getTask("M001", "S01", "T01");
956
- assert.equal(task!.status, "complete", "M12: reconciler overrides reopen — task back to complete");
957
- });
958
- });
959
- });