gsd-pi 2.65.0 → 2.66.0-dev.e159299

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 (462) hide show
  1. package/dist/mcp-server.js +6 -2
  2. package/dist/resources/extensions/browser-tools/capture.js +20 -1
  3. package/dist/resources/extensions/browser-tools/tests/capture-sharp-optional.test.cjs +93 -0
  4. package/dist/resources/extensions/gsd/auto/finalize-timeout.js +2 -0
  5. package/dist/resources/extensions/gsd/auto/loop.js +2 -2
  6. package/dist/resources/extensions/gsd/auto/phases.js +48 -5
  7. package/dist/resources/extensions/gsd/auto/run-unit.js +13 -2
  8. package/dist/resources/extensions/gsd/auto/session.js +4 -0
  9. package/dist/resources/extensions/gsd/auto/types.js +2 -0
  10. package/dist/resources/extensions/gsd/auto-dashboard.js +2 -1
  11. package/dist/resources/extensions/gsd/auto-dispatch.js +99 -9
  12. package/dist/resources/extensions/gsd/auto-model-selection.js +7 -5
  13. package/dist/resources/extensions/gsd/auto-post-unit.js +17 -6
  14. package/dist/resources/extensions/gsd/auto-prompts.js +24 -0
  15. package/dist/resources/extensions/gsd/auto-recovery.js +40 -22
  16. package/dist/resources/extensions/gsd/auto-start.js +175 -12
  17. package/dist/resources/extensions/gsd/auto-tool-tracking.js +10 -0
  18. package/dist/resources/extensions/gsd/auto-worktree.js +29 -7
  19. package/dist/resources/extensions/gsd/auto.js +21 -15
  20. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +17 -4
  21. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +10 -0
  22. package/dist/resources/extensions/gsd/bootstrap/query-tools.js +6 -4
  23. package/dist/resources/extensions/gsd/bootstrap/register-extension.js +5 -1
  24. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +11 -3
  25. package/dist/resources/extensions/gsd/bootstrap/system-context.js +3 -1
  26. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +31 -1
  27. package/dist/resources/extensions/gsd/commands/context.js +8 -1
  28. package/dist/resources/extensions/gsd/commands/handlers/core.js +23 -2
  29. package/dist/resources/extensions/gsd/commands-extensions.js +1 -1
  30. package/dist/resources/extensions/gsd/config-overlay.js +312 -0
  31. package/dist/resources/extensions/gsd/db-writer.js +13 -3
  32. package/dist/resources/extensions/gsd/detection.js +1 -1
  33. package/dist/resources/extensions/gsd/dispatch-guard.js +2 -1
  34. package/dist/resources/extensions/gsd/docs/preferences-reference.md +1 -0
  35. package/dist/resources/extensions/gsd/doctor.js +2 -1
  36. package/dist/resources/extensions/gsd/files.js +17 -0
  37. package/dist/resources/extensions/gsd/gitignore.js +1 -0
  38. package/dist/resources/extensions/gsd/gsd-db.js +47 -4
  39. package/dist/resources/extensions/gsd/guided-flow.js +220 -29
  40. package/dist/resources/extensions/gsd/index.js +1 -1
  41. package/dist/resources/extensions/gsd/json-persistence.js +5 -2
  42. package/dist/resources/extensions/gsd/md-importer.js +14 -7
  43. package/dist/resources/extensions/gsd/notification-overlay.js +1 -1
  44. package/dist/resources/extensions/gsd/notification-widget.js +2 -1
  45. package/dist/resources/extensions/gsd/parallel-monitor-overlay.js +1 -1
  46. package/dist/resources/extensions/gsd/parallel-orchestrator.js +17 -11
  47. package/dist/resources/extensions/gsd/pre-execution-checks.js +26 -5
  48. package/dist/resources/extensions/gsd/preferences-types.js +3 -0
  49. package/dist/resources/extensions/gsd/preferences-validation.js +45 -1
  50. package/dist/resources/extensions/gsd/preferences.js +9 -2
  51. package/dist/resources/extensions/gsd/preparation.js +1092 -0
  52. package/dist/resources/extensions/gsd/prompt-validation.js +67 -0
  53. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +3 -3
  54. package/dist/resources/extensions/gsd/prompts/complete-slice.md +1 -1
  55. package/dist/resources/extensions/gsd/prompts/discuss-prepared.md +424 -0
  56. package/dist/resources/extensions/gsd/prompts/discuss.md +2 -0
  57. package/dist/resources/extensions/gsd/prompts/guided-discuss-milestone.md +6 -1
  58. package/dist/resources/extensions/gsd/prompts/guided-discuss-slice.md +5 -4
  59. package/dist/resources/extensions/gsd/prompts/parallel-research-slices.md +23 -0
  60. package/dist/resources/extensions/gsd/prompts/queue.md +2 -0
  61. package/dist/resources/extensions/gsd/prompts/rethink.md +2 -1
  62. package/dist/resources/extensions/gsd/prompts/system.md +2 -2
  63. package/dist/resources/extensions/gsd/prompts/validate-milestone.md +56 -23
  64. package/dist/resources/extensions/gsd/quick.js +19 -15
  65. package/dist/resources/extensions/gsd/reactive-graph.js +12 -0
  66. package/dist/resources/extensions/gsd/roadmap-slices.js +24 -5
  67. package/dist/resources/extensions/gsd/safety/content-validator.js +3 -3
  68. package/dist/resources/extensions/gsd/session-lock.js +23 -1
  69. package/dist/resources/extensions/gsd/state.js +115 -28
  70. package/dist/resources/extensions/gsd/templates/context-enhanced.md +138 -0
  71. package/dist/resources/extensions/gsd/tools/complete-milestone.js +15 -3
  72. package/dist/resources/extensions/gsd/tools/complete-slice.js +27 -6
  73. package/dist/resources/extensions/gsd/tools/complete-task.js +31 -7
  74. package/dist/resources/extensions/gsd/tools/plan-milestone.js +7 -5
  75. package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +5 -2
  76. package/dist/resources/extensions/gsd/tools/reopen-milestone.js +119 -0
  77. package/dist/resources/extensions/gsd/tools/reopen-slice.js +30 -0
  78. package/dist/resources/extensions/gsd/tools/reopen-task.js +18 -0
  79. package/dist/resources/extensions/gsd/triage-resolution.js +33 -16
  80. package/dist/resources/extensions/gsd/undo.js +3 -2
  81. package/dist/resources/extensions/gsd/workflow-events.js +1 -0
  82. package/dist/resources/extensions/gsd/workflow-logger.js +1 -1
  83. package/dist/resources/extensions/gsd/workflow-projections.js +7 -9
  84. package/dist/resources/extensions/gsd/workflow-reconcile.js +100 -9
  85. package/dist/resources/extensions/gsd/workflow-templates.js +11 -2
  86. package/dist/resources/extensions/gsd/worktree-manager.js +5 -2
  87. package/dist/resources/extensions/gsd/worktree.js +9 -0
  88. package/dist/resources/extensions/shared/interview-ui.js +1 -1
  89. package/dist/resources/extensions/subagent/agents.js +19 -5
  90. package/dist/web/standalone/.next/BUILD_ID +1 -1
  91. package/dist/web/standalone/.next/app-path-routes-manifest.json +17 -17
  92. package/dist/web/standalone/.next/build-manifest.json +4 -4
  93. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  94. package/dist/web/standalone/.next/react-loadable-manifest.json +1 -1
  95. package/dist/web/standalone/.next/required-server-files.json +3 -3
  96. package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
  97. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  98. package/dist/web/standalone/.next/server/app/_global-error.html +2 -2
  99. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  100. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  101. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  102. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  103. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  104. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  105. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  106. package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
  107. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  108. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  109. package/dist/web/standalone/.next/server/app/_not-found.rsc +3 -3
  110. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
  111. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  112. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +3 -3
  113. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  114. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  115. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  116. package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
  117. package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
  118. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
  119. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
  120. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
  121. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
  122. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
  123. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
  124. package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
  125. package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
  126. package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
  127. package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
  128. package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
  129. package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
  130. package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
  131. package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
  132. package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
  133. package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
  134. package/dist/web/standalone/.next/server/app/api/experimental/route.js +2 -2
  135. package/dist/web/standalone/.next/server/app/api/experimental/route_client-reference-manifest.js +1 -1
  136. package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
  137. package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
  138. package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
  139. package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
  140. package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
  141. package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
  142. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  143. package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  144. package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
  145. package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
  146. package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
  147. package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
  148. package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
  149. package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
  150. package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
  151. package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
  152. package/dist/web/standalone/.next/server/app/api/live-state/route.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/notifications/route.js +2 -2
  155. package/dist/web/standalone/.next/server/app/api/notifications/route_client-reference-manifest.js +1 -1
  156. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  157. package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
  158. package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
  159. package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
  160. package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
  161. package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  162. package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
  163. package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
  164. package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +2 -2
  165. package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
  166. package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
  167. package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
  168. package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
  169. package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
  170. package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
  171. package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
  172. package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
  173. package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
  174. package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
  175. package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
  176. package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
  177. package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
  178. package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
  179. package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
  180. package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
  181. package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
  182. package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
  183. package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
  184. package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +2 -2
  185. package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
  186. package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
  187. package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
  188. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +2 -2
  189. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
  190. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +4 -4
  191. package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
  192. package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
  193. package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
  194. package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
  195. package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
  196. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  197. package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  198. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  199. package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
  200. package/dist/web/standalone/.next/server/app/index.html +1 -1
  201. package/dist/web/standalone/.next/server/app/index.rsc +4 -4
  202. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  203. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +4 -4
  204. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  205. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +3 -3
  206. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  207. package/dist/web/standalone/.next/server/app/page.js +2 -2
  208. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  209. package/dist/web/standalone/.next/server/app-paths-manifest.json +17 -17
  210. package/dist/web/standalone/.next/server/chunks/6897.js +1 -1
  211. package/dist/web/standalone/.next/server/chunks/7471.js +3 -3
  212. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  213. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  214. package/dist/web/standalone/.next/server/middleware.js +2 -2
  215. package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
  216. package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
  217. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  218. package/dist/web/standalone/.next/server/pages/500.html +2 -2
  219. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  220. package/dist/web/standalone/.next/static/chunks/6502.8874bcae249c02e1.js +9 -0
  221. package/dist/web/standalone/.next/static/chunks/app/_not-found/{page-2f24283c162b6ab3.js → page-f2a7482d42a5614b.js} +1 -1
  222. package/dist/web/standalone/.next/static/chunks/app/{layout-9ecfd95f343793f0.js → layout-a16c7a7ecdf0c2cf.js} +1 -1
  223. package/dist/web/standalone/.next/static/chunks/app/page-0c485498795110d6.js +1 -0
  224. package/dist/web/standalone/.next/static/chunks/main-app-fdab67f7802d7832.js +1 -0
  225. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +1 -0
  226. package/dist/web/standalone/.next/static/chunks/{webpack-a1c1e452c6b32d04.js → webpack-9fed74684e1c5bb1.js} +1 -1
  227. package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
  228. package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
  229. package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
  230. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api.target.mk +14 -14
  231. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_except.target.mk +14 -14
  232. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_maybe.target.mk +14 -14
  233. package/dist/web/standalone/server.js +1 -1
  234. package/package.json +1 -1
  235. package/packages/pi-coding-agent/dist/core/retry-handler.d.ts.map +1 -1
  236. package/packages/pi-coding-agent/dist/core/retry-handler.js +30 -19
  237. package/packages/pi-coding-agent/dist/core/retry-handler.js.map +1 -1
  238. package/packages/pi-coding-agent/dist/core/retry-handler.test.js +51 -0
  239. package/packages/pi-coding-agent/dist/core/retry-handler.test.js.map +1 -1
  240. package/packages/pi-coding-agent/dist/core/sdk.js +9 -9
  241. package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
  242. package/packages/pi-coding-agent/dist/modes/interactive/components/provider-manager.d.ts +2 -1
  243. package/packages/pi-coding-agent/dist/modes/interactive/components/provider-manager.d.ts.map +1 -1
  244. package/packages/pi-coding-agent/dist/modes/interactive/components/provider-manager.js +10 -1
  245. package/packages/pi-coding-agent/dist/modes/interactive/components/provider-manager.js.map +1 -1
  246. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts +1 -0
  247. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  248. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +20 -5
  249. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
  250. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js +15 -1
  251. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js.map +1 -1
  252. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js +18 -0
  253. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js.map +1 -1
  254. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  255. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +4 -0
  256. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  257. package/packages/pi-coding-agent/package.json +1 -1
  258. package/packages/pi-coding-agent/src/core/retry-handler.test.ts +80 -0
  259. package/packages/pi-coding-agent/src/core/retry-handler.ts +37 -25
  260. package/packages/pi-coding-agent/src/core/sdk.ts +9 -9
  261. package/packages/pi-coding-agent/src/modes/interactive/components/provider-manager.ts +10 -0
  262. package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +20 -4
  263. package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.test.ts +27 -0
  264. package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.ts +16 -1
  265. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +5 -0
  266. package/packages/pi-tui/dist/components/image.d.ts +2 -0
  267. package/packages/pi-tui/dist/components/image.d.ts.map +1 -1
  268. package/packages/pi-tui/dist/components/image.js +4 -0
  269. package/packages/pi-tui/dist/components/image.js.map +1 -1
  270. package/packages/pi-tui/dist/components/image.test.d.ts +6 -0
  271. package/packages/pi-tui/dist/components/image.test.d.ts.map +1 -0
  272. package/packages/pi-tui/dist/components/image.test.js +32 -0
  273. package/packages/pi-tui/dist/components/image.test.js.map +1 -0
  274. package/packages/pi-tui/dist/tui.d.ts.map +1 -1
  275. package/packages/pi-tui/dist/tui.js +3 -1
  276. package/packages/pi-tui/dist/tui.js.map +1 -1
  277. package/packages/pi-tui/src/components/image.test.ts +36 -0
  278. package/packages/pi-tui/src/components/image.ts +5 -0
  279. package/packages/pi-tui/src/tui.ts +3 -1
  280. package/pkg/package.json +1 -1
  281. package/src/resources/extensions/browser-tools/capture.ts +19 -1
  282. package/src/resources/extensions/browser-tools/tests/capture-sharp-optional.test.cjs +93 -0
  283. package/src/resources/extensions/gsd/auto/finalize-timeout.ts +3 -0
  284. package/src/resources/extensions/gsd/auto/loop.ts +2 -2
  285. package/src/resources/extensions/gsd/auto/phases.ts +68 -3
  286. package/src/resources/extensions/gsd/auto/run-unit.ts +12 -2
  287. package/src/resources/extensions/gsd/auto/session.ts +4 -0
  288. package/src/resources/extensions/gsd/auto/types.ts +5 -0
  289. package/src/resources/extensions/gsd/auto-dashboard.ts +2 -1
  290. package/src/resources/extensions/gsd/auto-dispatch.ts +110 -9
  291. package/src/resources/extensions/gsd/auto-model-selection.ts +7 -5
  292. package/src/resources/extensions/gsd/auto-post-unit.ts +16 -6
  293. package/src/resources/extensions/gsd/auto-prompts.ts +31 -0
  294. package/src/resources/extensions/gsd/auto-recovery.ts +29 -23
  295. package/src/resources/extensions/gsd/auto-start.ts +188 -10
  296. package/src/resources/extensions/gsd/auto-tool-tracking.ts +10 -0
  297. package/src/resources/extensions/gsd/auto-worktree.ts +28 -7
  298. package/src/resources/extensions/gsd/auto.ts +19 -8
  299. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +16 -4
  300. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +10 -0
  301. package/src/resources/extensions/gsd/bootstrap/query-tools.ts +5 -4
  302. package/src/resources/extensions/gsd/bootstrap/register-extension.ts +4 -1
  303. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +11 -3
  304. package/src/resources/extensions/gsd/bootstrap/system-context.ts +3 -1
  305. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +36 -1
  306. package/src/resources/extensions/gsd/commands/context.ts +7 -1
  307. package/src/resources/extensions/gsd/commands/handlers/core.ts +26 -2
  308. package/src/resources/extensions/gsd/commands-extensions.ts +1 -1
  309. package/src/resources/extensions/gsd/config-overlay.ts +331 -0
  310. package/src/resources/extensions/gsd/db-writer.ts +11 -3
  311. package/src/resources/extensions/gsd/detection.ts +1 -1
  312. package/src/resources/extensions/gsd/dispatch-guard.ts +2 -1
  313. package/src/resources/extensions/gsd/docs/preferences-reference.md +1 -0
  314. package/src/resources/extensions/gsd/doctor.ts +2 -1
  315. package/src/resources/extensions/gsd/files.ts +19 -0
  316. package/src/resources/extensions/gsd/gitignore.ts +1 -0
  317. package/src/resources/extensions/gsd/gsd-db.ts +46 -4
  318. package/src/resources/extensions/gsd/guided-flow.ts +254 -30
  319. package/src/resources/extensions/gsd/index.ts +1 -0
  320. package/src/resources/extensions/gsd/json-persistence.ts +6 -3
  321. package/src/resources/extensions/gsd/md-importer.ts +13 -6
  322. package/src/resources/extensions/gsd/notification-overlay.ts +1 -1
  323. package/src/resources/extensions/gsd/notification-widget.ts +2 -1
  324. package/src/resources/extensions/gsd/parallel-monitor-overlay.ts +1 -1
  325. package/src/resources/extensions/gsd/parallel-orchestrator.ts +19 -11
  326. package/src/resources/extensions/gsd/pre-execution-checks.ts +32 -7
  327. package/src/resources/extensions/gsd/preferences-types.ts +25 -0
  328. package/src/resources/extensions/gsd/preferences-validation.ts +45 -1
  329. package/src/resources/extensions/gsd/preferences.ts +9 -2
  330. package/src/resources/extensions/gsd/preparation.ts +1419 -0
  331. package/src/resources/extensions/gsd/prompt-validation.ts +88 -0
  332. package/src/resources/extensions/gsd/prompts/complete-milestone.md +3 -3
  333. package/src/resources/extensions/gsd/prompts/complete-slice.md +1 -1
  334. package/src/resources/extensions/gsd/prompts/discuss-prepared.md +424 -0
  335. package/src/resources/extensions/gsd/prompts/discuss.md +2 -0
  336. package/src/resources/extensions/gsd/prompts/guided-discuss-milestone.md +6 -1
  337. package/src/resources/extensions/gsd/prompts/guided-discuss-slice.md +5 -4
  338. package/src/resources/extensions/gsd/prompts/parallel-research-slices.md +23 -0
  339. package/src/resources/extensions/gsd/prompts/queue.md +2 -0
  340. package/src/resources/extensions/gsd/prompts/rethink.md +2 -1
  341. package/src/resources/extensions/gsd/prompts/system.md +2 -2
  342. package/src/resources/extensions/gsd/prompts/validate-milestone.md +56 -23
  343. package/src/resources/extensions/gsd/quick.ts +20 -15
  344. package/src/resources/extensions/gsd/reactive-graph.ts +18 -0
  345. package/src/resources/extensions/gsd/roadmap-slices.ts +21 -5
  346. package/src/resources/extensions/gsd/safety/content-validator.ts +3 -3
  347. package/src/resources/extensions/gsd/session-lock.ts +17 -1
  348. package/src/resources/extensions/gsd/state.ts +115 -26
  349. package/src/resources/extensions/gsd/templates/context-enhanced.md +138 -0
  350. package/src/resources/extensions/gsd/tests/adversarial-review-fixes.test.ts +223 -0
  351. package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +33 -2
  352. package/src/resources/extensions/gsd/tests/auto-remediate-slice-status.test.ts +56 -0
  353. package/src/resources/extensions/gsd/tests/clear-stale-autostart.test.ts +41 -0
  354. package/src/resources/extensions/gsd/tests/complete-slice-verification-gate.test.ts +72 -0
  355. package/src/resources/extensions/gsd/tests/complete-task-normalize-lists.test.ts +54 -0
  356. package/src/resources/extensions/gsd/tests/defer-milestone-stamp.test.ts +30 -0
  357. package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +4 -3
  358. package/src/resources/extensions/gsd/tests/discuss-incremental-persistence.test.ts +36 -0
  359. package/src/resources/extensions/gsd/tests/discuss-slice-structured-questions.test.ts +46 -0
  360. package/src/resources/extensions/gsd/tests/dispatch-guard-closed-status.test.ts +33 -0
  361. package/src/resources/extensions/gsd/tests/dispatcher-stuck-planning.test.ts +37 -0
  362. package/src/resources/extensions/gsd/tests/error-success-mask.test.ts +37 -0
  363. package/src/resources/extensions/gsd/tests/finalize-timeout-guard.test.ts +125 -0
  364. package/src/resources/extensions/gsd/tests/find-missing-summaries-closed.test.ts +48 -0
  365. package/src/resources/extensions/gsd/tests/format-shortcut.test.ts +69 -0
  366. package/src/resources/extensions/gsd/tests/frontmatter-parse-noise.test.ts +42 -0
  367. package/src/resources/extensions/gsd/tests/gitignore-bg-shell.test.ts +38 -0
  368. package/src/resources/extensions/gsd/tests/guided-flow-state-rebuild.test.ts +103 -0
  369. package/src/resources/extensions/gsd/tests/import-done-milestones.test.ts +42 -0
  370. package/src/resources/extensions/gsd/tests/integration/auto-recovery.test.ts +11 -9
  371. package/src/resources/extensions/gsd/tests/integration/state-machine-edge-cases.test.ts +4 -2
  372. package/src/resources/extensions/gsd/tests/integration/state-machine-live-validation.test.ts +28 -30
  373. package/src/resources/extensions/gsd/tests/integration/test-isolation.ts +53 -0
  374. package/src/resources/extensions/gsd/tests/integration-prepared-discussion.test.ts +525 -0
  375. package/src/resources/extensions/gsd/tests/isolation-none-branch-guard.test.ts +62 -0
  376. package/src/resources/extensions/gsd/tests/journal-integration.test.ts +11 -10
  377. package/src/resources/extensions/gsd/tests/needs-remediation-revalidation.test.ts +48 -0
  378. package/src/resources/extensions/gsd/tests/note-captures-executed.test.ts +46 -0
  379. package/src/resources/extensions/gsd/tests/orphaned-worktree-audit.test.ts +189 -0
  380. package/src/resources/extensions/gsd/tests/parallel-research-dispatch.test.ts +77 -0
  381. package/src/resources/extensions/gsd/tests/phantom-ghost-detection.test.ts +55 -0
  382. package/src/resources/extensions/gsd/tests/phantom-milestone-default-queued.test.ts +39 -0
  383. package/src/resources/extensions/gsd/tests/pre-exec-backtick-strip.test.ts +68 -0
  384. package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +284 -20
  385. package/src/resources/extensions/gsd/tests/pre-execution-fail-closed.test.ts +2 -2
  386. package/src/resources/extensions/gsd/tests/pre-execution-pause-wiring.test.ts +2 -2
  387. package/src/resources/extensions/gsd/tests/preparation.test.ts +1211 -0
  388. package/src/resources/extensions/gsd/tests/project-root-cwd-crash.test.ts +53 -0
  389. package/src/resources/extensions/gsd/tests/projection-no-plan-overwrite.test.ts +83 -0
  390. package/src/resources/extensions/gsd/tests/prompt-builder.test.ts +669 -0
  391. package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +7 -4
  392. package/src/resources/extensions/gsd/tests/prompt-step-ordering.test.ts +85 -0
  393. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +2 -1
  394. package/src/resources/extensions/gsd/tests/query-tools-db-open.test.ts +47 -0
  395. package/src/resources/extensions/gsd/tests/queued-discuss-fast-path.test.ts +107 -0
  396. package/src/resources/extensions/gsd/tests/reactive-graph.test.ts +45 -0
  397. package/src/resources/extensions/gsd/tests/restore-tools-after-discuss.test.ts +63 -0
  398. package/src/resources/extensions/gsd/tests/rogue-file-detection.test.ts +4 -5
  399. package/src/resources/extensions/gsd/tests/run-uat-replay-cap.test.ts +51 -0
  400. package/src/resources/extensions/gsd/tests/show-config-command.test.ts +56 -0
  401. package/src/resources/extensions/gsd/tests/skip-slice-state-rebuild.test.ts +31 -0
  402. package/src/resources/extensions/gsd/tests/skipped-validation-completion.test.ts +39 -0
  403. package/src/resources/extensions/gsd/tests/slice-sequence-insert.test.ts +51 -0
  404. package/src/resources/extensions/gsd/tests/smart-entry-complete.test.ts +1 -1
  405. package/src/resources/extensions/gsd/tests/stale-lockfile-recovery.test.ts +36 -0
  406. package/src/resources/extensions/gsd/tests/stale-queued-milestone.test.ts +147 -0
  407. package/src/resources/extensions/gsd/tests/stale-worktree-cwd.test.ts +13 -0
  408. package/src/resources/extensions/gsd/tests/stash-pop-gsd-conflict.test.ts +21 -0
  409. package/src/resources/extensions/gsd/tests/stash-queued-context-files.test.ts +21 -0
  410. package/src/resources/extensions/gsd/tests/state-machine-full-walkthrough.test.ts +6 -7
  411. package/src/resources/extensions/gsd/tests/status-db-open.test.ts +47 -0
  412. package/src/resources/extensions/gsd/tests/stuck-detection-coverage.test.ts +1 -0
  413. package/src/resources/extensions/gsd/tests/subagent-agent-discovery.test.ts +47 -0
  414. package/src/resources/extensions/gsd/tests/symlink-extension-discovery.test.ts +125 -0
  415. package/src/resources/extensions/gsd/tests/sync-worktree-skip-current.test.ts +65 -0
  416. package/src/resources/extensions/gsd/tests/tool-invocation-error-loop-break.test.ts +29 -1
  417. package/src/resources/extensions/gsd/tests/triage-resolution.test.ts +2 -1
  418. package/src/resources/extensions/gsd/tests/validate-milestone.test.ts +3 -4
  419. package/src/resources/extensions/gsd/tests/verification-operational-gate.test.ts +15 -0
  420. package/src/resources/extensions/gsd/tests/verify-artifact-tightened.test.ts +89 -0
  421. package/src/resources/extensions/gsd/tests/wave1-critical-regressions.test.ts +49 -0
  422. package/src/resources/extensions/gsd/tests/wave2-events-regressions.test.ts +48 -0
  423. package/src/resources/extensions/gsd/tests/wave3-session-regressions.test.ts +47 -0
  424. package/src/resources/extensions/gsd/tests/wave4-write-safety-regressions.test.ts +70 -0
  425. package/src/resources/extensions/gsd/tests/wave5-consistency-regressions.test.ts +165 -0
  426. package/src/resources/extensions/gsd/tests/worker-model-override.test.ts +48 -0
  427. package/src/resources/extensions/gsd/tests/workflow-logger-audit.test.ts +6 -3
  428. package/src/resources/extensions/gsd/tests/worktree-expected-warnings.test.ts +38 -0
  429. package/src/resources/extensions/gsd/tests/worktree-integration.test.ts +16 -0
  430. package/src/resources/extensions/gsd/tests/worktree-main-branch.test.ts +20 -0
  431. package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +16 -17
  432. package/src/resources/extensions/gsd/tests/worktree-sync-tasks.test.ts +13 -9
  433. package/src/resources/extensions/gsd/tests/worktree.test.ts +26 -9
  434. package/src/resources/extensions/gsd/tests/write-gate.test.ts +127 -2
  435. package/src/resources/extensions/gsd/tests/zero-slice-roadmap-guided.test.ts +19 -0
  436. package/src/resources/extensions/gsd/tools/complete-milestone.ts +13 -3
  437. package/src/resources/extensions/gsd/tools/complete-slice.ts +26 -6
  438. package/src/resources/extensions/gsd/tools/complete-task.ts +29 -7
  439. package/src/resources/extensions/gsd/tools/plan-milestone.ts +11 -9
  440. package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +5 -2
  441. package/src/resources/extensions/gsd/tools/reopen-milestone.ts +152 -0
  442. package/src/resources/extensions/gsd/tools/reopen-slice.ts +27 -0
  443. package/src/resources/extensions/gsd/tools/reopen-task.ts +17 -0
  444. package/src/resources/extensions/gsd/triage-resolution.ts +37 -17
  445. package/src/resources/extensions/gsd/types.ts +4 -0
  446. package/src/resources/extensions/gsd/undo.ts +3 -2
  447. package/src/resources/extensions/gsd/workflow-events.ts +5 -3
  448. package/src/resources/extensions/gsd/workflow-logger.ts +1 -1
  449. package/src/resources/extensions/gsd/workflow-projections.ts +7 -8
  450. package/src/resources/extensions/gsd/workflow-reconcile.ts +109 -8
  451. package/src/resources/extensions/gsd/workflow-templates.ts +11 -2
  452. package/src/resources/extensions/gsd/worktree-manager.ts +4 -2
  453. package/src/resources/extensions/gsd/worktree.ts +10 -0
  454. package/src/resources/extensions/shared/interview-ui.ts +1 -1
  455. package/src/resources/extensions/shared/tests/interview-notes-loop.test.ts +8 -10
  456. package/src/resources/extensions/subagent/agents.ts +30 -6
  457. package/dist/web/standalone/.next/static/chunks/6502.7593d7797a4b3999.js +0 -9
  458. package/dist/web/standalone/.next/static/chunks/app/page-62be3b5fa91e4c8f.js +0 -1
  459. package/dist/web/standalone/.next/static/chunks/main-app-d3d4c336195465f9.js +0 -1
  460. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ab5a8926e07ec673.js +0 -1
  461. /package/dist/web/standalone/.next/static/{MRM3OSYIAa4HMDqVGQ9nt → h8aBiLMFjb__ogynY08cm}/_buildManifest.js +0 -0
  462. /package/dist/web/standalone/.next/static/{MRM3OSYIAa4HMDqVGQ9nt → h8aBiLMFjb__ogynY08cm}/_ssgManifest.js +0 -0
@@ -0,0 +1,138 @@
1
+ # {{milestoneId}}: {{milestoneTitle}}
2
+
3
+ **Gathered:** {{date}}
4
+ **Status:** Ready for planning
5
+
6
+ ## Project Description
7
+
8
+ {{description}}
9
+
10
+ ## Why This Milestone
11
+
12
+ {{whatProblemThisSolves_AND_whyNow}}
13
+
14
+ ## Codebase Brief
15
+
16
+ ### Technology Stack
17
+
18
+ {{techStack}}
19
+
20
+ ### Key Modules
21
+
22
+ {{keyModules}}
23
+
24
+ ### Patterns in Use
25
+
26
+ {{patternsInUse}}
27
+
28
+ ## User-Visible Outcome
29
+
30
+ ### When this milestone is complete, the user can:
31
+
32
+ - {{literalUserActionInRealEnvironment}}
33
+ - {{literalUserActionInRealEnvironment}}
34
+
35
+ ### Entry point / environment
36
+
37
+ - Entry point: {{CLI command / URL / bot / extension / service / workflow}}
38
+ - Environment: {{local dev / browser / mobile / launchd / CI / production-like}}
39
+ - Live dependencies involved: {{telegram / database / webhook / rpc subprocess / none}}
40
+
41
+ ## Completion Class
42
+
43
+ - Contract complete means: {{what can be proven by tests / fixtures / artifacts}}
44
+ - Integration complete means: {{what must work across real subsystems}}
45
+ - Operational complete means: {{what must work under real lifecycle conditions, or none}}
46
+
47
+ ## Architectural Decisions
48
+
49
+ ### {{decisionTitle}}
50
+
51
+ **Decision:** {{decisionStatement}}
52
+
53
+ **Rationale:** {{rationale}}
54
+
55
+ **Evidence:** {{evidence}}
56
+
57
+ **Alternatives Considered:**
58
+ - {{alternative1}} — {{whyNotChosen1}}
59
+ - {{alternative2}} — {{whyNotChosen2}}
60
+
61
+ ---
62
+
63
+ > Add additional decisions as separate `### Decision Title` blocks following the same structure above.
64
+
65
+ ## Interface Contracts
66
+
67
+ {{interfaceContracts}}
68
+
69
+ > Document API boundaries, function signatures, data shapes, or protocol agreements that must be honored. Leave blank or remove if not applicable to this milestone.
70
+
71
+ ## Error Handling Strategy
72
+
73
+ {{errorHandlingStrategy}}
74
+
75
+ > Describe the approach for handling failures, edge cases, and error propagation. Include retry policies, fallback behaviors, and user-facing error messages where relevant.
76
+
77
+ ## Final Integrated Acceptance
78
+
79
+ To call this milestone complete, we must prove:
80
+
81
+ - {{one real end-to-end scenario}}
82
+ - {{one real end-to-end scenario}}
83
+ - {{what cannot be simulated if this milestone is to be considered truly done}}
84
+
85
+ ## Testing Requirements
86
+
87
+ {{testingRequirements}}
88
+
89
+ > Specify test types (unit, integration, e2e), coverage expectations, and any specific test scenarios that must pass.
90
+
91
+ ## Acceptance Criteria
92
+
93
+ {{acceptanceCriteria}}
94
+
95
+ > Per-slice acceptance criteria gathered during discussion. Each slice should have clear, testable criteria.
96
+
97
+ ## Risks and Unknowns
98
+
99
+ - {{riskOrUnknown}} — {{whyItMatters}}
100
+
101
+ ## Existing Codebase / Prior Art
102
+
103
+ - `{{fileOrModule}}` — {{howItRelates}}
104
+ - `{{fileOrModule}}` — {{howItRelates}}
105
+
106
+ > See `.gsd/DECISIONS.md` for all architectural and pattern decisions — it is an append-only register; read it during planning, append to it during execution.
107
+
108
+ ## Relevant Requirements
109
+
110
+ - {{requirementId}} — {{howThisMilestoneAdvancesIt}}
111
+
112
+ ## Scope
113
+
114
+ ### In Scope
115
+
116
+ - {{inScopeItem}}
117
+
118
+ ### Out of Scope / Non-Goals
119
+
120
+ - {{outOfScopeItem}}
121
+
122
+ ## Technical Constraints
123
+
124
+ - {{constraint}}
125
+
126
+ ## Integration Points
127
+
128
+ - {{systemOrService}} — {{howThisMilestoneInteractsWithIt}}
129
+
130
+ ## Ecosystem Notes
131
+
132
+ {{ecosystemNotes}}
133
+
134
+ > Research findings, best practices, known issues, and relevant external documentation discovered during preparation.
135
+
136
+ ## Open Questions
137
+
138
+ - {{question}} — {{currentThinking}}
@@ -0,0 +1,223 @@
1
+ /**
2
+ * Tests for adversarial review fixes from PR #3602.
3
+ *
4
+ * These tests verify the fixes for:
5
+ * 1. Cross-session state leak in lastPreparationResult (HIGH)
6
+ * 2. Invalid regex anchor \z in prompt-validation.ts (HIGH)
7
+ * 3. Consecutive error counter in agent-loop.ts (MEDIUM) — UPSTREAM CODE, NOT MODIFIED
8
+ */
9
+
10
+ import { describe, test, beforeEach, afterEach } from "node:test";
11
+ import assert from "node:assert/strict";
12
+ import { mkdirSync, writeFileSync, rmSync } from "node:fs";
13
+ import { join } from "node:path";
14
+ import { tmpdir } from "node:os";
15
+
16
+ import { getLastPreparationResult, clearPreparationResult } from "../guided-flow.ts";
17
+ import { validateEnhancedContext } from "../prompt-validation.ts";
18
+
19
+ // ─── Test Helpers ───────────────────────────────────────────────────────────────
20
+
21
+ function makeTempDir(prefix: string): string {
22
+ const dir = join(
23
+ tmpdir(),
24
+ `gsd-adversarial-test-${prefix}-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
25
+ );
26
+ mkdirSync(dir, { recursive: true });
27
+ return dir;
28
+ }
29
+
30
+ function cleanup(dir: string): void {
31
+ try {
32
+ rmSync(dir, { recursive: true, force: true });
33
+ } catch {
34
+ // best-effort
35
+ }
36
+ }
37
+
38
+ // ─── Fix 1: Cross-session state leak in lastPreparationResult ────────────────────
39
+
40
+ describe("Fix #1 — Cross-session state leak (lastPreparationResult)", () => {
41
+ beforeEach(() => {
42
+ clearPreparationResult();
43
+ });
44
+
45
+ afterEach(() => {
46
+ clearPreparationResult();
47
+ });
48
+
49
+ test("clearPreparationResult sets lastPreparationResult to null", () => {
50
+ // First, verify the getter returns null after clear
51
+ clearPreparationResult();
52
+ const result = getLastPreparationResult();
53
+ assert.equal(result, null, "lastPreparationResult should be null after clear");
54
+ });
55
+
56
+ test("getLastPreparationResult returns null initially", () => {
57
+ clearPreparationResult();
58
+ const result = getLastPreparationResult();
59
+ assert.equal(result, null, "should return null when no preparation has run");
60
+ });
61
+
62
+ // Note: The actual test that prepareAndBuildDiscussPrompt clears the result
63
+ // on entry requires mocking ExtensionCommandContext which is complex.
64
+ // The fix is verified by code inspection and integration tests.
65
+ // The key behavior is:
66
+ // 1. lastPreparationResult = null at the start of prepareAndBuildDiscussPrompt
67
+ // 2. If preparation throws, lastPreparationResult stays null
68
+ // 3. If discuss_preparation is false, lastPreparationResult stays null
69
+ });
70
+
71
+ // ─── Fix 2: Invalid regex anchor \z in prompt-validation.ts ──────────────────────
72
+
73
+ describe("Fix #2 — Invalid regex anchor (prompt-validation.ts)", () => {
74
+ test("validates content with Architectural Decisions at end of file", () => {
75
+ // This was the bug: \z is PCRE/Ruby, not JS. JS treated it as literal 'z'.
76
+ // The section extraction would fail when Architectural Decisions was the
77
+ // last section (no subsequent ## heading).
78
+ const contentWithDecisionsAtEnd = `
79
+ # M001: Test Milestone
80
+
81
+ ## Why This Milestone
82
+
83
+ This is why.
84
+
85
+ ## Acceptance Criteria
86
+
87
+ - Criterion 1
88
+
89
+ ## Architectural Decisions
90
+
91
+ ### Decision 1
92
+
93
+ **Decision:** Use TypeScript
94
+ **Rationale:** Type safety
95
+ `;
96
+
97
+ const result = validateEnhancedContext(contentWithDecisionsAtEnd);
98
+ assert.equal(result.valid, true, "should validate content with decisions at end");
99
+ assert.equal(result.missing.length, 0, "should have no missing sections");
100
+ });
101
+
102
+ test("validates content with Architectural Decisions followed by another section", () => {
103
+ const contentWithDecisionsInMiddle = `
104
+ # M001: Test Milestone
105
+
106
+ ## Why This Milestone
107
+
108
+ This is why.
109
+
110
+ ## Architectural Decisions
111
+
112
+ ### Decision 1
113
+
114
+ **Decision:** Use TypeScript
115
+
116
+ ## Acceptance Criteria
117
+
118
+ - Criterion 1
119
+ `;
120
+
121
+ const result = validateEnhancedContext(contentWithDecisionsInMiddle);
122
+ assert.equal(result.valid, true, "should validate content with decisions in middle");
123
+ });
124
+
125
+ test("detects missing decision entry when section is empty", () => {
126
+ const contentEmptyDecisions = `
127
+ # M001: Test Milestone
128
+
129
+ ## Why This Milestone
130
+
131
+ This is why.
132
+
133
+ ## Architectural Decisions
134
+
135
+ (No decisions yet)
136
+
137
+ ## Acceptance Criteria
138
+
139
+ - Criterion 1
140
+ `;
141
+
142
+ const result = validateEnhancedContext(contentEmptyDecisions);
143
+ assert.equal(result.valid, false, "should fail when decisions section has no entries");
144
+ assert.ok(
145
+ result.missing.some((m) => m.includes("decision entry")),
146
+ "should report missing decision entry",
147
+ );
148
+ });
149
+
150
+ test("accepts inline **Decision format", () => {
151
+ const contentInlineDecision = `
152
+ ## Why This Milestone
153
+
154
+ Test
155
+
156
+ ## Architectural Decisions
157
+
158
+ **Decision:** Use React
159
+
160
+ ## Acceptance Criteria
161
+
162
+ - Criterion 1
163
+ `;
164
+
165
+ const result = validateEnhancedContext(contentInlineDecision);
166
+ assert.equal(result.valid, true, "should accept **Decision format");
167
+ });
168
+
169
+ test("accepts ### subsection format", () => {
170
+ const contentSubsectionDecision = `
171
+ ## Why This Milestone
172
+
173
+ Test
174
+
175
+ ## Architectural Decisions
176
+
177
+ ### Database Choice
178
+
179
+ We chose SQLite.
180
+
181
+ ## Acceptance Criteria
182
+
183
+ - Criterion 1
184
+ `;
185
+
186
+ const result = validateEnhancedContext(contentSubsectionDecision);
187
+ assert.equal(result.valid, true, "should accept ### subsection format");
188
+ });
189
+
190
+ test("handles edge case: Architectural Decisions heading without space before content", () => {
191
+ const contentNoSpace = `## Why This Milestone
192
+ Test
193
+ ## Architectural Decisions
194
+ ### Decision 1
195
+ Content here
196
+ ## Acceptance Criteria
197
+ - Done`;
198
+
199
+ const result = validateEnhancedContext(contentNoSpace);
200
+ assert.equal(result.valid, true, "should handle content without extra spacing");
201
+ });
202
+ });
203
+
204
+ // ─── Fix 3: Consecutive error counter (agent-loop.ts) ────────────────────────────
205
+
206
+ describe("Fix #3 — Consecutive error counter (UPSTREAM)", () => {
207
+ test("NOTE: agent-loop.ts is upstream code that was not modified", () => {
208
+ // This finding from the adversarial review relates to upstream behavior
209
+ // in packages/pi-agent-core/src/agent-loop.ts.
210
+ //
211
+ // The consecutiveAllToolErrorTurns counter logic was added in PR #3301
212
+ // and refined in PR #3618 by upstream contributors. These PRs fix
213
+ // issues with:
214
+ // - Schema overload detection counting bash exit codes as failures
215
+ // - The counter not resetting properly on successful turns
216
+ //
217
+ // Since this is upstream code (part of pi-agent-core, not gsd extension),
218
+ // we do not modify it here. The fix should be coordinated with upstream.
219
+ //
220
+ // See: packages/pi-agent-core/src/agent-loop.ts lines 191, 298-325
221
+ assert.ok(true, "Documented as upstream behavior — no changes made");
222
+ });
223
+ });
@@ -1,8 +1,11 @@
1
1
  import test from "node:test";
2
2
  import assert from "node:assert/strict";
3
- import { mkdtempSync, mkdirSync, rmSync, writeFileSync } from "node:fs";
4
- import { join } from "node:path";
3
+ import { mkdtempSync, mkdirSync, rmSync, writeFileSync, readFileSync } from "node:fs";
4
+ import { dirname, join } from "node:path";
5
5
  import { tmpdir } from "node:os";
6
+ import { fileURLToPath } from "node:url";
7
+
8
+ const __dirname = dirname(fileURLToPath(import.meta.url));
6
9
 
7
10
  import { resolvePreferredModelConfig, resolveModelId } from "../auto-model-selection.js";
8
11
 
@@ -196,6 +199,34 @@ test("resolveModelId: bare ID with claude-code as only provider still resolves",
196
199
  assert.equal(result.provider, "claude-code");
197
200
  });
198
201
 
202
+ // ─── selectAndApplyModel verbose-gating tests ──────────────────────────
203
+
204
+ test("model change notify in selectAndApplyModel is gated behind verbose flag", () => {
205
+ // The Model [phase] [tier] notification should only fire when verbose=true.
206
+ // The dashboard header already shows the active model, so the notification
207
+ // is redundant noise during auto-mode (#3719).
208
+ const gsdDir = join(__dirname, "..");
209
+ const src = readFileSync(join(gsdDir, "auto-model-selection.ts"), "utf-8");
210
+
211
+ // Find the block where setModel succeeds (appliedModel = model) and
212
+ // verify notify is inside an `if (verbose)` guard.
213
+ const setModelBlock = src.match(
214
+ /const ok = await pi\.setModel\(model[\s\S]*?appliedModel = model;([\s\S]*?)break;/,
215
+ );
216
+ assert.ok(setModelBlock, "should find the setModel success block");
217
+
218
+ const blockBody = setModelBlock![1];
219
+ // The notify call must be inside an if (verbose) block
220
+ assert.ok(
221
+ blockBody.includes("if (verbose)"),
222
+ "Model change ctx.ui.notify must be gated behind if (verbose) to avoid auto-mode notification noise",
223
+ );
224
+ assert.ok(
225
+ blockBody.includes("ctx.ui.notify"),
226
+ "notify call should still exist (just verbose-gated)",
227
+ );
228
+ });
229
+
199
230
  test("resolveModelId: anthropic wins over claude-code regardless of list order", () => {
200
231
  const availableModels = [
201
232
  { id: "claude-sonnet-4-6", provider: "claude-code" },
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Regression test for #3673 — auto-remediate stale slice DB status
3
+ *
4
+ * When complete-slice fails after writing SUMMARY.md but before calling
5
+ * updateSliceStatus(), the DB stays stale and the post-unit check
6
+ * previously reported this as a "rogue" artifact, causing infinite
7
+ * re-dispatch. The fix calls updateSliceStatus() to sync the DB.
8
+ *
9
+ * This structural test verifies updateSliceStatus is imported and called
10
+ * in the complete-slice branch of auto-post-unit.ts.
11
+ */
12
+
13
+ import { describe, test } from 'node:test';
14
+ import assert from 'node:assert/strict';
15
+ import { readFileSync } from 'node:fs';
16
+ import { fileURLToPath } from 'node:url';
17
+ import { dirname, join } from 'node:path';
18
+
19
+ const __filename = fileURLToPath(import.meta.url);
20
+ const __dirname = dirname(__filename);
21
+
22
+ const source = readFileSync(join(__dirname, '..', 'auto-post-unit.ts'), 'utf-8');
23
+
24
+ describe('auto-remediate stale slice status (#3673)', () => {
25
+ test('updateSliceStatus is imported from gsd-db', () => {
26
+ assert.match(source, /import\s*\{[^}]*updateSliceStatus[^}]*\}\s*from\s*["']\.\/gsd-db/,
27
+ 'updateSliceStatus should be imported from gsd-db');
28
+ });
29
+
30
+ test('updateSliceStatus is called with "complete" status', () => {
31
+ assert.match(source, /updateSliceStatus\(mid,\s*sid,\s*["']complete["']/,
32
+ 'updateSliceStatus should be called with "complete" status');
33
+ });
34
+
35
+ test('remediation is wrapped in try-catch for fallback to rogue detection', () => {
36
+ // The updateSliceStatus call should be in a try block with a catch
37
+ // that falls back to rogues.push
38
+ const updateIdx = source.indexOf('updateSliceStatus(mid, sid');
39
+ assert.ok(updateIdx > 0, 'updateSliceStatus call should exist');
40
+
41
+ // Find surrounding try-catch
42
+ const before = source.slice(Math.max(0, updateIdx - 200), updateIdx);
43
+ assert.match(before, /try\s*\{/,
44
+ 'updateSliceStatus should be inside a try block');
45
+
46
+ const after = source.slice(updateIdx, updateIdx + 300);
47
+ assert.match(after, /catch/,
48
+ 'try block should have a catch for fallback');
49
+ });
50
+
51
+ test('rogue detection still exists as fallback', () => {
52
+ // rogues.push should appear in the catch block
53
+ assert.match(source, /rogues\.push\(\{.*path:\s*summaryPath/,
54
+ 'rogues.push fallback should still exist');
55
+ });
56
+ });
@@ -0,0 +1,41 @@
1
+ /**
2
+ * clear-stale-autostart.test.ts — #3667
3
+ *
4
+ * Verify that guided-flow.ts adds a createdAt timestamp to pending auto-start
5
+ * entries and implements a staleness check (30s age guard) so that /clear
6
+ * interrupted discussions don't permanently block future /gsd invocations.
7
+ */
8
+
9
+ import { describe, test } from "node:test";
10
+ import assert from "node:assert/strict";
11
+ import { readFileSync } from "node:fs";
12
+ import { join, dirname } from "node:path";
13
+ import { fileURLToPath } from "node:url";
14
+
15
+ const __dirname = dirname(fileURLToPath(import.meta.url));
16
+ const sourceFile = join(__dirname, "..", "guided-flow.ts");
17
+
18
+ describe("clear stale pending auto-start (#3667)", () => {
19
+ const source = readFileSync(sourceFile, "utf-8");
20
+
21
+ test("PendingAutoStartEntry interface includes createdAt field", () => {
22
+ assert.match(source, /createdAt:\s*number/);
23
+ });
24
+
25
+ test("setPendingAutoStart defaults createdAt to Date.now()", () => {
26
+ assert.match(source, /createdAt:\s*Date\.now\(\)/);
27
+ });
28
+
29
+ test("staleness check uses 30_000ms threshold", () => {
30
+ assert.match(source, /30[_]?000/);
31
+ });
32
+
33
+ test("stale entry detection checks manifest and context files", () => {
34
+ assert.match(source, /DISCUSSION-MANIFEST\.json/);
35
+ assert.match(source, /CONTEXT\.md/);
36
+ });
37
+
38
+ test("stale entries are deleted from the map", () => {
39
+ assert.match(source, /pendingAutoStartMap\.delete\(basePath\)/);
40
+ });
41
+ });
@@ -0,0 +1,72 @@
1
+ /**
2
+ * Regression test for #3580 — complete-slice verification gate
3
+ *
4
+ * Without the gate, a prompt regression could silently advance a blocked
5
+ * or failed slice to "complete" status. The fix adds a BLOCKED_SIGNALS
6
+ * regex that rejects completion when verification/UAT content clearly
7
+ * indicates blocked or failed state.
8
+ */
9
+
10
+ import { describe, it } from 'node:test'
11
+ import assert from 'node:assert/strict'
12
+ import { readFileSync } from 'node:fs'
13
+ import { resolve } from 'node:path'
14
+
15
+ const src = readFileSync(
16
+ resolve(process.cwd(), 'src', 'resources', 'extensions', 'gsd', 'tools', 'complete-slice.ts'),
17
+ 'utf-8',
18
+ )
19
+
20
+ describe('complete-slice verification gate (#3580)', () => {
21
+ it('BLOCKED_SIGNALS regex is defined', () => {
22
+ assert.ok(
23
+ src.includes('BLOCKED_SIGNALS'),
24
+ 'BLOCKED_SIGNALS constant must be defined in complete-slice.ts',
25
+ )
26
+ })
27
+
28
+ it('BLOCKED_SIGNALS is a regex that tests verification content', () => {
29
+ // Extract the BLOCKED_SIGNALS definition line
30
+ const idx = src.indexOf('BLOCKED_SIGNALS')
31
+ assert.ok(idx !== -1)
32
+ const lineEnd = src.indexOf(';', idx)
33
+ const definition = src.slice(idx, lineEnd)
34
+
35
+ // Must be a regex (starts with /)
36
+ assert.ok(
37
+ definition.includes('= /'),
38
+ 'BLOCKED_SIGNALS must be assigned a regex literal',
39
+ )
40
+
41
+ // Must match key blocked/failed signals
42
+ assert.ok(definition.includes('blocked'), 'regex must match "blocked" signals')
43
+ assert.ok(definition.includes('failed'), 'regex must match "failed" signals')
44
+ })
45
+
46
+ it('gate checks params.verification and params.uatContent', () => {
47
+ // Find usage of BLOCKED_SIGNALS.test
48
+ const testCalls = src.match(/BLOCKED_SIGNALS\.test\([^)]+\)/g)
49
+ assert.ok(testCalls, 'BLOCKED_SIGNALS.test() must be called')
50
+ assert.ok(testCalls.length >= 2, 'must check at least verification and uatContent')
51
+
52
+ const joined = testCalls.join(' ')
53
+ assert.ok(joined.includes('verification'), 'must test params.verification')
54
+ assert.ok(joined.includes('uatContent'), 'must test params.uatContent')
55
+ })
56
+
57
+ it('gate returns an error message when blocked signals detected', () => {
58
+ // Find the return statement after BLOCKED_SIGNALS check
59
+ const gateIdx = src.indexOf('BLOCKED_SIGNALS.test(')
60
+ assert.ok(gateIdx !== -1)
61
+
62
+ const afterGate = src.slice(gateIdx, gateIdx + 500)
63
+ assert.ok(
64
+ afterGate.includes('return { error:'),
65
+ 'blocked signal detection must return an error',
66
+ )
67
+ assert.ok(
68
+ afterGate.includes('do not complete'),
69
+ 'error message must explain why completion is rejected',
70
+ )
71
+ })
72
+ })
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Regression test for #3692 — normalizeListParam in complete-task
3
+ *
4
+ * Agents sometimes pass keyFiles/keyDecisions as comma-separated strings
5
+ * instead of arrays. normalizeListParam coerces both forms to string[].
6
+ *
7
+ * Also verifies roadmap-slices.ts detects dependency column from header.
8
+ */
9
+
10
+ import { describe, test } from 'node:test';
11
+ import assert from 'node:assert/strict';
12
+ import { readFileSync } from 'node:fs';
13
+ import { fileURLToPath } from 'node:url';
14
+ import { dirname, join } from 'node:path';
15
+
16
+ const __filename = fileURLToPath(import.meta.url);
17
+ const __dirname = dirname(__filename);
18
+
19
+ const completeTaskSrc = readFileSync(
20
+ join(__dirname, '..', 'tools', 'complete-task.ts'),
21
+ 'utf-8',
22
+ );
23
+ const roadmapSlicesSrc = readFileSync(
24
+ join(__dirname, '..', 'roadmap-slices.ts'),
25
+ 'utf-8',
26
+ );
27
+
28
+ describe('complete-task normalizeListParam (#3692)', () => {
29
+ test('normalizeListParam function is defined', () => {
30
+ assert.match(completeTaskSrc, /function normalizeListParam\(/,
31
+ 'normalizeListParam function should be defined in complete-task.ts');
32
+ });
33
+
34
+ test('normalizeListParam is applied to keyFiles', () => {
35
+ assert.match(completeTaskSrc, /normalizeListParam\(params\.keyFiles\)/,
36
+ 'normalizeListParam should be applied to keyFiles');
37
+ });
38
+
39
+ test('normalizeListParam is applied to keyDecisions', () => {
40
+ assert.match(completeTaskSrc, /normalizeListParam\(params\.keyDecisions\)/,
41
+ 'normalizeListParam should be applied to keyDecisions');
42
+ });
43
+ });
44
+
45
+ describe('roadmap-slices depColumnIndex detection (#3692)', () => {
46
+ test('depColumnIndex is detected from header row', () => {
47
+ assert.match(roadmapSlicesSrc, /depColumnIndex/,
48
+ 'depColumnIndex variable should exist in roadmap-slices.ts');
49
+ assert.match(roadmapSlicesSrc, /headerCells/,
50
+ 'headerCells should be parsed from the header row');
51
+ assert.match(roadmapSlicesSrc, /depends|deps|depend/i,
52
+ 'header detection should match depends/deps/depend');
53
+ });
54
+ });
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Regression test for #3542: defer and milestone captures must be stamped
3
+ * as executed after triage resolution, regardless of directory state.
4
+ */
5
+ import { test } from "node:test";
6
+ import assert from "node:assert/strict";
7
+ import { mkdtempSync, mkdirSync, writeFileSync, readFileSync, rmSync } from "node:fs";
8
+ import { join } from "node:path";
9
+ import { tmpdir } from "node:os";
10
+ import { executeTriageResolutions } from "../triage-resolution.ts";
11
+ import { appendCapture, markCaptureResolved, loadAllCaptures } from "../captures.ts";
12
+
13
+ test("defer captures without milestone ID are stamped as executed (#3542)", async () => {
14
+ const base = mkdtempSync(join(tmpdir(), "gsd-stamp-"));
15
+ mkdirSync(join(base, ".gsd", "milestones", "M001"), { recursive: true });
16
+ try {
17
+ appendCapture(base, "Improve error messages");
18
+ const captures = loadAllCaptures(base);
19
+ const id = captures[0].id;
20
+ markCaptureResolved(base, id, "defer", "Deferred to a future UX-polish milestone", "Not urgent");
21
+
22
+ executeTriageResolutions(base, "M001", "S01");
23
+
24
+ const after = loadAllCaptures(base);
25
+ const cap = after.find(c => c.id === id);
26
+ assert.ok(cap?.executed, "Defer capture should be stamped as executed");
27
+ } finally {
28
+ rmSync(base, { recursive: true, force: true });
29
+ }
30
+ });
@@ -1098,16 +1098,17 @@ describe('derive-state-db', async () => {
1098
1098
  // M001: complete milestone with summary
1099
1099
  writeFile(base, 'milestones/M001/M001-SUMMARY.md', '# M001 Summary\n\nDone.');
1100
1100
 
1101
- // M002: queued milestone — directory exists, no content files, but has DB row
1101
+ // M002: queued milestone — directory exists with CONTEXT file and DB row
1102
1102
  mkdirSync(join(base, '.gsd', 'milestones', 'M002', 'slices'), { recursive: true });
1103
+ writeFile(base, 'milestones/M002/M002-CONTEXT.md', '# M002 Context\n\nPlanned milestone.');
1103
1104
 
1104
1105
  // DB has both M001 complete and M002 queued
1105
1106
  openDatabase(':memory:');
1106
1107
  insertMilestone({ id: 'M001', title: 'First', status: 'complete' });
1107
1108
  insertMilestone({ id: 'M002', title: 'Second', status: 'queued' });
1108
1109
 
1109
- // isGhostMilestone should NOT treat M002 as ghost when DB row exists
1110
- assert.ok(!isGhostMilestone(base, 'M002'), 'ghost-dbrow: M002 with DB row is NOT a ghost');
1110
+ // isGhostMilestone should NOT treat M002 as ghost when DB row + content files exist
1111
+ assert.ok(!isGhostMilestone(base, 'M002'), 'ghost-dbrow: M002 with DB row and content is NOT a ghost');
1111
1112
 
1112
1113
  invalidateStateCache();
1113
1114
  const dbState = await deriveStateFromDb(base);