gsd-pi 2.64.0-dev.f8aad9b → 2.65.0-dev.16e10d7

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 (473) hide show
  1. package/dist/headless.js +3 -1
  2. package/dist/mcp-server.js +6 -2
  3. package/dist/resources/extensions/bg-shell/bg-shell-lifecycle.js +22 -7
  4. package/dist/resources/extensions/bg-shell/process-manager.js +6 -1
  5. package/dist/resources/extensions/browser-tools/capture.js +20 -1
  6. package/dist/resources/extensions/browser-tools/tests/capture-sharp-optional.test.cjs +93 -0
  7. package/dist/resources/extensions/gsd/auto/run-unit.js +13 -2
  8. package/dist/resources/extensions/gsd/auto-dispatch.js +94 -8
  9. package/dist/resources/extensions/gsd/auto-model-selection.js +7 -5
  10. package/dist/resources/extensions/gsd/auto-post-unit.js +115 -7
  11. package/dist/resources/extensions/gsd/auto-prompts.js +24 -0
  12. package/dist/resources/extensions/gsd/auto-recovery.js +12 -8
  13. package/dist/resources/extensions/gsd/auto-start.js +35 -1
  14. package/dist/resources/extensions/gsd/auto-tool-tracking.js +10 -0
  15. package/dist/resources/extensions/gsd/auto-verification.js +138 -1
  16. package/dist/resources/extensions/gsd/auto-worktree.js +29 -7
  17. package/dist/resources/extensions/gsd/auto.js +2 -2
  18. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +17 -4
  19. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +34 -13
  20. package/dist/resources/extensions/gsd/bootstrap/notify-interceptor.js +28 -0
  21. package/dist/resources/extensions/gsd/bootstrap/query-tools.js +6 -4
  22. package/dist/resources/extensions/gsd/bootstrap/register-extension.js +5 -1
  23. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +12 -1
  24. package/dist/resources/extensions/gsd/bootstrap/register-shortcuts.js +16 -0
  25. package/dist/resources/extensions/gsd/bootstrap/system-context.js +20 -0
  26. package/dist/resources/extensions/gsd/commands/catalog.js +7 -1
  27. package/dist/resources/extensions/gsd/commands/context.js +8 -1
  28. package/dist/resources/extensions/gsd/commands/handlers/core.js +21 -0
  29. package/dist/resources/extensions/gsd/commands/handlers/notifications-handler.js +104 -0
  30. package/dist/resources/extensions/gsd/commands/handlers/ops.js +5 -0
  31. package/dist/resources/extensions/gsd/commands-extensions.js +1 -1
  32. package/dist/resources/extensions/gsd/config-overlay.js +312 -0
  33. package/dist/resources/extensions/gsd/detection.js +1 -1
  34. package/dist/resources/extensions/gsd/dispatch-guard.js +2 -1
  35. package/dist/resources/extensions/gsd/docs/preferences-reference.md +1 -0
  36. package/dist/resources/extensions/gsd/doctor.js +2 -1
  37. package/dist/resources/extensions/gsd/gitignore.js +1 -0
  38. package/dist/resources/extensions/gsd/gsd-db.js +11 -2
  39. package/dist/resources/extensions/gsd/guided-flow.js +220 -29
  40. package/dist/resources/extensions/gsd/md-importer.js +14 -7
  41. package/dist/resources/extensions/gsd/notification-overlay.js +256 -0
  42. package/dist/resources/extensions/gsd/notification-store.js +273 -0
  43. package/dist/resources/extensions/gsd/notification-widget.js +56 -0
  44. package/dist/resources/extensions/gsd/parallel-orchestrator.js +17 -11
  45. package/dist/resources/extensions/gsd/post-execution-checks.js +407 -0
  46. package/dist/resources/extensions/gsd/pre-execution-checks.js +471 -0
  47. package/dist/resources/extensions/gsd/preferences-types.js +7 -0
  48. package/dist/resources/extensions/gsd/preferences-validation.js +78 -1
  49. package/dist/resources/extensions/gsd/preferences.js +13 -2
  50. package/dist/resources/extensions/gsd/preparation.js +1092 -0
  51. package/dist/resources/extensions/gsd/prompt-validation.js +67 -0
  52. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +3 -3
  53. package/dist/resources/extensions/gsd/prompts/complete-slice.md +1 -1
  54. package/dist/resources/extensions/gsd/prompts/discuss-prepared.md +424 -0
  55. package/dist/resources/extensions/gsd/prompts/guided-discuss-milestone.md +4 -1
  56. package/dist/resources/extensions/gsd/prompts/guided-discuss-slice.md +5 -4
  57. package/dist/resources/extensions/gsd/prompts/parallel-research-slices.md +23 -0
  58. package/dist/resources/extensions/gsd/prompts/rethink.md +2 -1
  59. package/dist/resources/extensions/gsd/prompts/validate-milestone.md +56 -23
  60. package/dist/resources/extensions/gsd/quick.js +19 -15
  61. package/dist/resources/extensions/gsd/reactive-graph.js +12 -0
  62. package/dist/resources/extensions/gsd/roadmap-slices.js +24 -5
  63. package/dist/resources/extensions/gsd/safety/content-validator.js +3 -3
  64. package/dist/resources/extensions/gsd/session-lock.js +23 -1
  65. package/dist/resources/extensions/gsd/state.js +100 -12
  66. package/dist/resources/extensions/gsd/templates/context-enhanced.md +138 -0
  67. package/dist/resources/extensions/gsd/tools/complete-slice.js +12 -3
  68. package/dist/resources/extensions/gsd/tools/complete-task.js +16 -4
  69. package/dist/resources/extensions/gsd/tools/plan-milestone.js +7 -5
  70. package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +5 -2
  71. package/dist/resources/extensions/gsd/tools/reopen-milestone.js +119 -0
  72. package/dist/resources/extensions/gsd/tools/reopen-slice.js +30 -0
  73. package/dist/resources/extensions/gsd/tools/reopen-task.js +18 -0
  74. package/dist/resources/extensions/gsd/triage-resolution.js +25 -9
  75. package/dist/resources/extensions/gsd/verification-evidence.js +18 -0
  76. package/dist/resources/extensions/gsd/workflow-logger.js +8 -0
  77. package/dist/resources/extensions/gsd/workflow-projections.js +4 -7
  78. package/dist/resources/extensions/gsd/workflow-reconcile.js +2 -4
  79. package/dist/resources/extensions/gsd/workflow-templates.js +11 -2
  80. package/dist/resources/extensions/gsd/worktree-manager.js +5 -2
  81. package/dist/resources/extensions/gsd/worktree.js +9 -0
  82. package/dist/resources/extensions/shared/interview-ui.js +1 -1
  83. package/dist/web/standalone/.next/BUILD_ID +1 -1
  84. package/dist/web/standalone/.next/app-path-routes-manifest.json +18 -17
  85. package/dist/web/standalone/.next/build-manifest.json +3 -3
  86. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  87. package/dist/web/standalone/.next/react-loadable-manifest.json +1 -1
  88. package/dist/web/standalone/.next/routes-manifest.json +6 -0
  89. package/dist/web/standalone/.next/server/app/_global-error.html +2 -2
  90. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  91. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  92. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  93. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  94. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  95. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  96. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  97. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  98. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  99. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  100. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  101. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  102. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  103. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  104. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  105. package/dist/web/standalone/.next/server/app/api/notifications/route.js +3 -0
  106. package/dist/web/standalone/.next/server/app/api/notifications/route.js.nft.json +1 -0
  107. package/dist/web/standalone/.next/server/app/api/notifications/route_client-reference-manifest.js +1 -0
  108. package/dist/web/standalone/.next/server/app/index.html +1 -1
  109. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  110. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  111. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  112. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  113. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  114. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  115. package/dist/web/standalone/.next/server/app-paths-manifest.json +18 -17
  116. package/dist/web/standalone/.next/server/functions-config-manifest.json +1 -0
  117. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  118. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  119. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  120. package/dist/web/standalone/.next/server/pages/500.html +2 -2
  121. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  122. package/dist/web/standalone/.next/static/Z3TgDP0c7kG9j8CVQVGcl/_buildManifest.js +1 -0
  123. package/dist/web/standalone/.next/static/chunks/6502.8874bcae249c02e1.js +9 -0
  124. package/dist/web/standalone/.next/static/chunks/app/_global-error/page-8805a20e15762c3c.js +1 -0
  125. package/dist/web/standalone/.next/static/chunks/app/api/boot/route-8805a20e15762c3c.js +1 -0
  126. package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/input/route-8805a20e15762c3c.js +1 -0
  127. package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/resize/route-8805a20e15762c3c.js +1 -0
  128. package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/stream/route-8805a20e15762c3c.js +1 -0
  129. package/dist/web/standalone/.next/static/chunks/app/api/browse-directories/route-8805a20e15762c3c.js +1 -0
  130. package/dist/web/standalone/.next/static/chunks/app/api/captures/route-8805a20e15762c3c.js +1 -0
  131. package/dist/web/standalone/.next/static/chunks/app/api/cleanup/route-8805a20e15762c3c.js +1 -0
  132. package/dist/web/standalone/.next/static/chunks/app/api/dev-mode/route-8805a20e15762c3c.js +1 -0
  133. package/dist/web/standalone/.next/static/chunks/app/api/doctor/route-8805a20e15762c3c.js +1 -0
  134. package/dist/web/standalone/.next/static/chunks/app/api/experimental/route-8805a20e15762c3c.js +1 -0
  135. package/dist/web/standalone/.next/static/chunks/app/api/export-data/route-8805a20e15762c3c.js +1 -0
  136. package/dist/web/standalone/.next/static/chunks/app/api/files/route-8805a20e15762c3c.js +1 -0
  137. package/dist/web/standalone/.next/static/chunks/app/api/forensics/route-8805a20e15762c3c.js +1 -0
  138. package/dist/web/standalone/.next/static/chunks/app/api/git/route-8805a20e15762c3c.js +1 -0
  139. package/dist/web/standalone/.next/static/chunks/app/api/history/route-8805a20e15762c3c.js +1 -0
  140. package/dist/web/standalone/.next/static/chunks/app/api/hooks/route-8805a20e15762c3c.js +1 -0
  141. package/dist/web/standalone/.next/static/chunks/app/api/inspect/route-8805a20e15762c3c.js +1 -0
  142. package/dist/web/standalone/.next/static/chunks/app/api/knowledge/route-8805a20e15762c3c.js +1 -0
  143. package/dist/web/standalone/.next/static/chunks/app/api/live-state/route-8805a20e15762c3c.js +1 -0
  144. package/dist/web/standalone/.next/static/chunks/app/api/notifications/route-8805a20e15762c3c.js +1 -0
  145. package/dist/web/standalone/.next/static/chunks/app/api/onboarding/route-8805a20e15762c3c.js +1 -0
  146. package/dist/web/standalone/.next/static/chunks/app/api/preferences/route-8805a20e15762c3c.js +1 -0
  147. package/dist/web/standalone/.next/static/chunks/app/api/projects/route-8805a20e15762c3c.js +1 -0
  148. package/dist/web/standalone/.next/static/chunks/app/api/recovery/route-8805a20e15762c3c.js +1 -0
  149. package/dist/web/standalone/.next/static/chunks/app/api/remote-questions/route-8805a20e15762c3c.js +1 -0
  150. package/dist/web/standalone/.next/static/chunks/app/api/session/browser/route-8805a20e15762c3c.js +1 -0
  151. package/dist/web/standalone/.next/static/chunks/app/api/session/command/route-8805a20e15762c3c.js +1 -0
  152. package/dist/web/standalone/.next/static/chunks/app/api/session/events/route-8805a20e15762c3c.js +1 -0
  153. package/dist/web/standalone/.next/static/chunks/app/api/session/manage/route-8805a20e15762c3c.js +1 -0
  154. package/dist/web/standalone/.next/static/chunks/app/api/settings-data/route-8805a20e15762c3c.js +1 -0
  155. package/dist/web/standalone/.next/static/chunks/app/api/shutdown/route-8805a20e15762c3c.js +1 -0
  156. package/dist/web/standalone/.next/static/chunks/app/api/skill-health/route-8805a20e15762c3c.js +1 -0
  157. package/dist/web/standalone/.next/static/chunks/app/api/steer/route-8805a20e15762c3c.js +1 -0
  158. package/dist/web/standalone/.next/static/chunks/app/api/switch-root/route-8805a20e15762c3c.js +1 -0
  159. package/dist/web/standalone/.next/static/chunks/app/api/terminal/input/route-8805a20e15762c3c.js +1 -0
  160. package/dist/web/standalone/.next/static/chunks/app/api/terminal/resize/route-8805a20e15762c3c.js +1 -0
  161. package/dist/web/standalone/.next/static/chunks/app/api/terminal/sessions/route-8805a20e15762c3c.js +1 -0
  162. package/dist/web/standalone/.next/static/chunks/app/api/terminal/stream/route-8805a20e15762c3c.js +1 -0
  163. package/dist/web/standalone/.next/static/chunks/app/api/terminal/upload/route-8805a20e15762c3c.js +1 -0
  164. package/dist/web/standalone/.next/static/chunks/app/api/undo/route-8805a20e15762c3c.js +1 -0
  165. package/dist/web/standalone/.next/static/chunks/app/api/update/route-8805a20e15762c3c.js +1 -0
  166. package/dist/web/standalone/.next/static/chunks/app/api/visualizer/route-8805a20e15762c3c.js +1 -0
  167. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/app-error-8805a20e15762c3c.js +1 -0
  168. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/forbidden-8805a20e15762c3c.js +1 -0
  169. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/not-found-8805a20e15762c3c.js +1 -0
  170. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/unauthorized-8805a20e15762c3c.js +1 -0
  171. package/dist/web/standalone/.next/static/chunks/{webpack-a1c1e452c6b32d04.js → webpack-9fed74684e1c5bb1.js} +1 -1
  172. package/package.json +1 -1
  173. package/packages/pi-agent-core/dist/agent-loop.js +26 -9
  174. package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
  175. package/packages/pi-agent-core/src/agent-loop.test.ts +100 -4
  176. package/packages/pi-agent-core/src/agent-loop.ts +43 -12
  177. package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.d.ts +2 -0
  178. package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.d.ts.map +1 -0
  179. package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.js +38 -0
  180. package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.js.map +1 -0
  181. package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
  182. package/packages/pi-coding-agent/dist/core/agent-session.js +11 -0
  183. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  184. package/packages/pi-coding-agent/dist/core/resource-loader-cache-reset.test.d.ts +2 -0
  185. package/packages/pi-coding-agent/dist/core/resource-loader-cache-reset.test.d.ts.map +1 -0
  186. package/packages/pi-coding-agent/dist/core/resource-loader-cache-reset.test.js +24 -0
  187. package/packages/pi-coding-agent/dist/core/resource-loader-cache-reset.test.js.map +1 -0
  188. package/packages/pi-coding-agent/dist/core/resource-loader.d.ts.map +1 -1
  189. package/packages/pi-coding-agent/dist/core/resource-loader.js +4 -1
  190. package/packages/pi-coding-agent/dist/core/resource-loader.js.map +1 -1
  191. package/packages/pi-coding-agent/dist/core/retry-handler.d.ts.map +1 -1
  192. package/packages/pi-coding-agent/dist/core/retry-handler.js +30 -19
  193. package/packages/pi-coding-agent/dist/core/retry-handler.js.map +1 -1
  194. package/packages/pi-coding-agent/dist/core/retry-handler.test.js +51 -0
  195. package/packages/pi-coding-agent/dist/core/retry-handler.test.js.map +1 -1
  196. package/packages/pi-coding-agent/dist/core/sdk.js +9 -9
  197. package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
  198. package/packages/pi-coding-agent/dist/modes/interactive/components/provider-manager.d.ts +2 -1
  199. package/packages/pi-coding-agent/dist/modes/interactive/components/provider-manager.d.ts.map +1 -1
  200. package/packages/pi-coding-agent/dist/modes/interactive/components/provider-manager.js +10 -1
  201. package/packages/pi-coding-agent/dist/modes/interactive/components/provider-manager.js.map +1 -1
  202. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts +2 -0
  203. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  204. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +28 -5
  205. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
  206. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js +15 -1
  207. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js.map +1 -1
  208. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js +18 -0
  209. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js.map +1 -1
  210. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +6 -0
  211. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  212. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +40 -0
  213. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  214. package/packages/pi-coding-agent/package.json +1 -1
  215. package/packages/pi-coding-agent/src/core/agent-session-tool-refresh.test.ts +64 -0
  216. package/packages/pi-coding-agent/src/core/agent-session.ts +10 -0
  217. package/packages/pi-coding-agent/src/core/resource-loader-cache-reset.test.ts +42 -0
  218. package/packages/pi-coding-agent/src/core/resource-loader.ts +5 -1
  219. package/packages/pi-coding-agent/src/core/retry-handler.test.ts +80 -0
  220. package/packages/pi-coding-agent/src/core/retry-handler.ts +37 -25
  221. package/packages/pi-coding-agent/src/core/sdk.ts +9 -9
  222. package/packages/pi-coding-agent/src/modes/interactive/components/provider-manager.ts +10 -0
  223. package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +29 -4
  224. package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.test.ts +27 -0
  225. package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.ts +16 -1
  226. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +38 -0
  227. package/packages/pi-tui/dist/__tests__/overlay-layout.test.d.ts +2 -0
  228. package/packages/pi-tui/dist/__tests__/overlay-layout.test.d.ts.map +1 -0
  229. package/packages/pi-tui/dist/__tests__/overlay-layout.test.js +66 -0
  230. package/packages/pi-tui/dist/__tests__/overlay-layout.test.js.map +1 -0
  231. package/packages/pi-tui/dist/components/image.d.ts +2 -0
  232. package/packages/pi-tui/dist/components/image.d.ts.map +1 -1
  233. package/packages/pi-tui/dist/components/image.js +4 -0
  234. package/packages/pi-tui/dist/components/image.js.map +1 -1
  235. package/packages/pi-tui/dist/components/image.test.d.ts +6 -0
  236. package/packages/pi-tui/dist/components/image.test.d.ts.map +1 -0
  237. package/packages/pi-tui/dist/components/image.test.js +32 -0
  238. package/packages/pi-tui/dist/components/image.test.js.map +1 -0
  239. package/packages/pi-tui/dist/components/loader.d.ts +4 -2
  240. package/packages/pi-tui/dist/components/loader.d.ts.map +1 -1
  241. package/packages/pi-tui/dist/components/loader.js +27 -9
  242. package/packages/pi-tui/dist/components/loader.js.map +1 -1
  243. package/packages/pi-tui/dist/components/text.d.ts.map +1 -1
  244. package/packages/pi-tui/dist/components/text.js +2 -0
  245. package/packages/pi-tui/dist/components/text.js.map +1 -1
  246. package/packages/pi-tui/dist/overlay-layout.d.ts.map +1 -1
  247. package/packages/pi-tui/dist/overlay-layout.js +12 -1
  248. package/packages/pi-tui/dist/overlay-layout.js.map +1 -1
  249. package/packages/pi-tui/dist/tui.d.ts +4 -0
  250. package/packages/pi-tui/dist/tui.d.ts.map +1 -1
  251. package/packages/pi-tui/dist/tui.js +35 -0
  252. package/packages/pi-tui/dist/tui.js.map +1 -1
  253. package/packages/pi-tui/src/__tests__/overlay-layout.test.ts +82 -0
  254. package/packages/pi-tui/src/components/image.test.ts +36 -0
  255. package/packages/pi-tui/src/components/image.ts +5 -0
  256. package/packages/pi-tui/src/components/loader.ts +27 -10
  257. package/packages/pi-tui/src/components/text.ts +1 -0
  258. package/packages/pi-tui/src/overlay-layout.ts +13 -1
  259. package/packages/pi-tui/src/tui.ts +34 -0
  260. package/pkg/package.json +1 -1
  261. package/src/resources/extensions/bg-shell/bg-shell-lifecycle.ts +19 -7
  262. package/src/resources/extensions/bg-shell/process-manager.ts +8 -2
  263. package/src/resources/extensions/browser-tools/capture.ts +19 -1
  264. package/src/resources/extensions/browser-tools/tests/capture-sharp-optional.test.cjs +93 -0
  265. package/src/resources/extensions/gsd/auto/run-unit.ts +12 -2
  266. package/src/resources/extensions/gsd/auto-dispatch.ts +105 -8
  267. package/src/resources/extensions/gsd/auto-model-selection.ts +7 -5
  268. package/src/resources/extensions/gsd/auto-post-unit.ts +138 -6
  269. package/src/resources/extensions/gsd/auto-prompts.ts +31 -0
  270. package/src/resources/extensions/gsd/auto-recovery.ts +10 -8
  271. package/src/resources/extensions/gsd/auto-start.ts +38 -0
  272. package/src/resources/extensions/gsd/auto-tool-tracking.ts +10 -0
  273. package/src/resources/extensions/gsd/auto-verification.ts +190 -2
  274. package/src/resources/extensions/gsd/auto-worktree.ts +28 -7
  275. package/src/resources/extensions/gsd/auto.ts +2 -1
  276. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +16 -4
  277. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +35 -13
  278. package/src/resources/extensions/gsd/bootstrap/notify-interceptor.ts +34 -0
  279. package/src/resources/extensions/gsd/bootstrap/query-tools.ts +5 -4
  280. package/src/resources/extensions/gsd/bootstrap/register-extension.ts +4 -1
  281. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +12 -1
  282. package/src/resources/extensions/gsd/bootstrap/register-shortcuts.ts +20 -0
  283. package/src/resources/extensions/gsd/bootstrap/system-context.ts +28 -0
  284. package/src/resources/extensions/gsd/commands/catalog.ts +7 -1
  285. package/src/resources/extensions/gsd/commands/context.ts +7 -1
  286. package/src/resources/extensions/gsd/commands/handlers/core.ts +24 -0
  287. package/src/resources/extensions/gsd/commands/handlers/notifications-handler.ts +140 -0
  288. package/src/resources/extensions/gsd/commands/handlers/ops.ts +5 -0
  289. package/src/resources/extensions/gsd/commands-extensions.ts +1 -1
  290. package/src/resources/extensions/gsd/config-overlay.ts +331 -0
  291. package/src/resources/extensions/gsd/detection.ts +1 -1
  292. package/src/resources/extensions/gsd/dispatch-guard.ts +2 -1
  293. package/src/resources/extensions/gsd/docs/preferences-reference.md +1 -0
  294. package/src/resources/extensions/gsd/doctor.ts +2 -1
  295. package/src/resources/extensions/gsd/gitignore.ts +1 -0
  296. package/src/resources/extensions/gsd/gsd-db.ts +13 -2
  297. package/src/resources/extensions/gsd/guided-flow.ts +254 -30
  298. package/src/resources/extensions/gsd/md-importer.ts +13 -6
  299. package/src/resources/extensions/gsd/notification-overlay.ts +295 -0
  300. package/src/resources/extensions/gsd/notification-store.ts +293 -0
  301. package/src/resources/extensions/gsd/notification-widget.ts +68 -0
  302. package/src/resources/extensions/gsd/parallel-orchestrator.ts +19 -11
  303. package/src/resources/extensions/gsd/post-execution-checks.ts +539 -0
  304. package/src/resources/extensions/gsd/pre-execution-checks.ts +581 -0
  305. package/src/resources/extensions/gsd/preferences-types.ts +53 -0
  306. package/src/resources/extensions/gsd/preferences-validation.ts +78 -1
  307. package/src/resources/extensions/gsd/preferences.ts +13 -2
  308. package/src/resources/extensions/gsd/preparation.ts +1419 -0
  309. package/src/resources/extensions/gsd/prompt-validation.ts +88 -0
  310. package/src/resources/extensions/gsd/prompts/complete-milestone.md +3 -3
  311. package/src/resources/extensions/gsd/prompts/complete-slice.md +1 -1
  312. package/src/resources/extensions/gsd/prompts/discuss-prepared.md +424 -0
  313. package/src/resources/extensions/gsd/prompts/guided-discuss-milestone.md +4 -1
  314. package/src/resources/extensions/gsd/prompts/guided-discuss-slice.md +5 -4
  315. package/src/resources/extensions/gsd/prompts/parallel-research-slices.md +23 -0
  316. package/src/resources/extensions/gsd/prompts/rethink.md +2 -1
  317. package/src/resources/extensions/gsd/prompts/validate-milestone.md +56 -23
  318. package/src/resources/extensions/gsd/quick.ts +20 -15
  319. package/src/resources/extensions/gsd/reactive-graph.ts +18 -0
  320. package/src/resources/extensions/gsd/roadmap-slices.ts +21 -5
  321. package/src/resources/extensions/gsd/safety/content-validator.ts +3 -3
  322. package/src/resources/extensions/gsd/session-lock.ts +17 -1
  323. package/src/resources/extensions/gsd/state.ts +101 -11
  324. package/src/resources/extensions/gsd/templates/context-enhanced.md +138 -0
  325. package/src/resources/extensions/gsd/tests/adversarial-review-fixes.test.ts +223 -0
  326. package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +33 -2
  327. package/src/resources/extensions/gsd/tests/auto-remediate-slice-status.test.ts +56 -0
  328. package/src/resources/extensions/gsd/tests/clear-stale-autostart.test.ts +41 -0
  329. package/src/resources/extensions/gsd/tests/complete-slice-string-coercion.test.ts +36 -0
  330. package/src/resources/extensions/gsd/tests/complete-slice-verification-gate.test.ts +72 -0
  331. package/src/resources/extensions/gsd/tests/complete-task-normalize-lists.test.ts +54 -0
  332. package/src/resources/extensions/gsd/tests/defer-milestone-stamp.test.ts +30 -0
  333. package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +4 -3
  334. package/src/resources/extensions/gsd/tests/discuss-incremental-persistence.test.ts +36 -0
  335. package/src/resources/extensions/gsd/tests/discuss-slice-structured-questions.test.ts +46 -0
  336. package/src/resources/extensions/gsd/tests/discuss-tool-scope-leak.test.ts +76 -0
  337. package/src/resources/extensions/gsd/tests/dispatch-guard-closed-status.test.ts +33 -0
  338. package/src/resources/extensions/gsd/tests/dispatcher-stuck-planning.test.ts +37 -0
  339. package/src/resources/extensions/gsd/tests/enhanced-verification-integration.test.ts +526 -0
  340. package/src/resources/extensions/gsd/tests/error-success-mask.test.ts +37 -0
  341. package/src/resources/extensions/gsd/tests/find-missing-summaries-closed.test.ts +48 -0
  342. package/src/resources/extensions/gsd/tests/frontmatter-parse-noise.test.ts +42 -0
  343. package/src/resources/extensions/gsd/tests/gitignore-bg-shell.test.ts +38 -0
  344. package/src/resources/extensions/gsd/tests/guided-flow-state-rebuild.test.ts +103 -0
  345. package/src/resources/extensions/gsd/tests/import-done-milestones.test.ts +42 -0
  346. package/src/resources/extensions/gsd/tests/integration/auto-recovery.test.ts +5 -3
  347. package/src/resources/extensions/gsd/tests/integration/state-machine-edge-cases.test.ts +4 -2
  348. package/src/resources/extensions/gsd/tests/integration/state-machine-live-validation.test.ts +28 -30
  349. package/src/resources/extensions/gsd/tests/integration/test-isolation.ts +53 -0
  350. package/src/resources/extensions/gsd/tests/integration-prepared-discussion.test.ts +525 -0
  351. package/src/resources/extensions/gsd/tests/isolation-none-branch-guard.test.ts +62 -0
  352. package/src/resources/extensions/gsd/tests/needs-remediation-revalidation.test.ts +48 -0
  353. package/src/resources/extensions/gsd/tests/note-captures-executed.test.ts +46 -0
  354. package/src/resources/extensions/gsd/tests/notification-overlay.test.ts +73 -0
  355. package/src/resources/extensions/gsd/tests/notification-store.test.ts +282 -0
  356. package/src/resources/extensions/gsd/tests/parallel-research-dispatch.test.ts +77 -0
  357. package/src/resources/extensions/gsd/tests/phantom-ghost-detection.test.ts +55 -0
  358. package/src/resources/extensions/gsd/tests/phantom-milestone-default-queued.test.ts +39 -0
  359. package/src/resources/extensions/gsd/tests/post-exec-retry-bypass.test.ts +312 -0
  360. package/src/resources/extensions/gsd/tests/post-execution-checks.test.ts +813 -0
  361. package/src/resources/extensions/gsd/tests/pre-exec-backtick-strip.test.ts +68 -0
  362. package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +1197 -0
  363. package/src/resources/extensions/gsd/tests/pre-execution-fail-closed.test.ts +266 -0
  364. package/src/resources/extensions/gsd/tests/pre-execution-pause-wiring.test.ts +457 -0
  365. package/src/resources/extensions/gsd/tests/preparation.test.ts +1211 -0
  366. package/src/resources/extensions/gsd/tests/project-root-cwd-crash.test.ts +53 -0
  367. package/src/resources/extensions/gsd/tests/projection-no-plan-overwrite.test.ts +83 -0
  368. package/src/resources/extensions/gsd/tests/prompt-builder.test.ts +669 -0
  369. package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +7 -4
  370. package/src/resources/extensions/gsd/tests/prompt-step-ordering.test.ts +85 -0
  371. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +2 -1
  372. package/src/resources/extensions/gsd/tests/query-tools-db-open.test.ts +47 -0
  373. package/src/resources/extensions/gsd/tests/queued-discuss-fast-path.test.ts +107 -0
  374. package/src/resources/extensions/gsd/tests/reactive-graph.test.ts +45 -0
  375. package/src/resources/extensions/gsd/tests/restore-tools-after-discuss.test.ts +63 -0
  376. package/src/resources/extensions/gsd/tests/rogue-file-detection.test.ts +4 -5
  377. package/src/resources/extensions/gsd/tests/run-uat-replay-cap.test.ts +51 -0
  378. package/src/resources/extensions/gsd/tests/show-config-command.test.ts +56 -0
  379. package/src/resources/extensions/gsd/tests/skip-slice-state-rebuild.test.ts +31 -0
  380. package/src/resources/extensions/gsd/tests/skipped-validation-completion.test.ts +39 -0
  381. package/src/resources/extensions/gsd/tests/slice-sequence-insert.test.ts +51 -0
  382. package/src/resources/extensions/gsd/tests/smart-entry-complete.test.ts +1 -1
  383. package/src/resources/extensions/gsd/tests/stale-lockfile-recovery.test.ts +36 -0
  384. package/src/resources/extensions/gsd/tests/stale-queued-milestone.test.ts +147 -0
  385. package/src/resources/extensions/gsd/tests/stale-worktree-cwd.test.ts +13 -0
  386. package/src/resources/extensions/gsd/tests/stash-pop-gsd-conflict.test.ts +21 -0
  387. package/src/resources/extensions/gsd/tests/stash-queued-context-files.test.ts +21 -0
  388. package/src/resources/extensions/gsd/tests/state-machine-full-walkthrough.test.ts +6 -7
  389. package/src/resources/extensions/gsd/tests/status-db-open.test.ts +47 -0
  390. package/src/resources/extensions/gsd/tests/stuck-detection-coverage.test.ts +1 -0
  391. package/src/resources/extensions/gsd/tests/symlink-extension-discovery.test.ts +125 -0
  392. package/src/resources/extensions/gsd/tests/sync-worktree-skip-current.test.ts +65 -0
  393. package/src/resources/extensions/gsd/tests/tool-invocation-error-loop-break.test.ts +29 -1
  394. package/src/resources/extensions/gsd/tests/triage-resolution.test.ts +2 -1
  395. package/src/resources/extensions/gsd/tests/unstructured-continue-context-injection.test.ts +163 -0
  396. package/src/resources/extensions/gsd/tests/validate-milestone.test.ts +3 -4
  397. package/src/resources/extensions/gsd/tests/verification-operational-gate.test.ts +15 -0
  398. package/src/resources/extensions/gsd/tests/verify-artifact-tightened.test.ts +89 -0
  399. package/src/resources/extensions/gsd/tests/worker-model-override.test.ts +48 -0
  400. package/src/resources/extensions/gsd/tests/worktree-expected-warnings.test.ts +38 -0
  401. package/src/resources/extensions/gsd/tests/worktree-integration.test.ts +16 -0
  402. package/src/resources/extensions/gsd/tests/worktree-main-branch.test.ts +20 -0
  403. package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +16 -17
  404. package/src/resources/extensions/gsd/tests/worktree-sync-tasks.test.ts +13 -9
  405. package/src/resources/extensions/gsd/tests/worktree.test.ts +26 -9
  406. package/src/resources/extensions/gsd/tests/zero-slice-roadmap-guided.test.ts +19 -0
  407. package/src/resources/extensions/gsd/tools/complete-slice.ts +13 -3
  408. package/src/resources/extensions/gsd/tools/complete-task.ts +16 -4
  409. package/src/resources/extensions/gsd/tools/plan-milestone.ts +11 -9
  410. package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +5 -2
  411. package/src/resources/extensions/gsd/tools/reopen-milestone.ts +152 -0
  412. package/src/resources/extensions/gsd/tools/reopen-slice.ts +27 -0
  413. package/src/resources/extensions/gsd/tools/reopen-task.ts +17 -0
  414. package/src/resources/extensions/gsd/triage-resolution.ts +29 -10
  415. package/src/resources/extensions/gsd/types.ts +4 -0
  416. package/src/resources/extensions/gsd/verification-evidence.ts +68 -0
  417. package/src/resources/extensions/gsd/workflow-logger.ts +13 -0
  418. package/src/resources/extensions/gsd/workflow-projections.ts +4 -6
  419. package/src/resources/extensions/gsd/workflow-reconcile.ts +2 -3
  420. package/src/resources/extensions/gsd/workflow-templates.ts +11 -2
  421. package/src/resources/extensions/gsd/worktree-manager.ts +4 -2
  422. package/src/resources/extensions/gsd/worktree.ts +10 -0
  423. package/src/resources/extensions/shared/interview-ui.ts +1 -1
  424. package/src/resources/extensions/shared/tests/interview-notes-loop.test.ts +8 -10
  425. package/dist/web/standalone/.next/static/F1mOwzgCW9R8N3Pt1Et87/_buildManifest.js +0 -1
  426. package/dist/web/standalone/.next/static/chunks/6502.7593d7797a4b3999.js +0 -9
  427. package/dist/web/standalone/.next/static/chunks/app/_global-error/page-c4cc189e7b117ea2.js +0 -1
  428. package/dist/web/standalone/.next/static/chunks/app/api/boot/route-c4cc189e7b117ea2.js +0 -1
  429. package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/input/route-c4cc189e7b117ea2.js +0 -1
  430. package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/resize/route-c4cc189e7b117ea2.js +0 -1
  431. package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/stream/route-c4cc189e7b117ea2.js +0 -1
  432. package/dist/web/standalone/.next/static/chunks/app/api/browse-directories/route-c4cc189e7b117ea2.js +0 -1
  433. package/dist/web/standalone/.next/static/chunks/app/api/captures/route-c4cc189e7b117ea2.js +0 -1
  434. package/dist/web/standalone/.next/static/chunks/app/api/cleanup/route-c4cc189e7b117ea2.js +0 -1
  435. package/dist/web/standalone/.next/static/chunks/app/api/dev-mode/route-c4cc189e7b117ea2.js +0 -1
  436. package/dist/web/standalone/.next/static/chunks/app/api/doctor/route-c4cc189e7b117ea2.js +0 -1
  437. package/dist/web/standalone/.next/static/chunks/app/api/experimental/route-c4cc189e7b117ea2.js +0 -1
  438. package/dist/web/standalone/.next/static/chunks/app/api/export-data/route-c4cc189e7b117ea2.js +0 -1
  439. package/dist/web/standalone/.next/static/chunks/app/api/files/route-c4cc189e7b117ea2.js +0 -1
  440. package/dist/web/standalone/.next/static/chunks/app/api/forensics/route-c4cc189e7b117ea2.js +0 -1
  441. package/dist/web/standalone/.next/static/chunks/app/api/git/route-c4cc189e7b117ea2.js +0 -1
  442. package/dist/web/standalone/.next/static/chunks/app/api/history/route-c4cc189e7b117ea2.js +0 -1
  443. package/dist/web/standalone/.next/static/chunks/app/api/hooks/route-c4cc189e7b117ea2.js +0 -1
  444. package/dist/web/standalone/.next/static/chunks/app/api/inspect/route-c4cc189e7b117ea2.js +0 -1
  445. package/dist/web/standalone/.next/static/chunks/app/api/knowledge/route-c4cc189e7b117ea2.js +0 -1
  446. package/dist/web/standalone/.next/static/chunks/app/api/live-state/route-c4cc189e7b117ea2.js +0 -1
  447. package/dist/web/standalone/.next/static/chunks/app/api/onboarding/route-c4cc189e7b117ea2.js +0 -1
  448. package/dist/web/standalone/.next/static/chunks/app/api/preferences/route-c4cc189e7b117ea2.js +0 -1
  449. package/dist/web/standalone/.next/static/chunks/app/api/projects/route-c4cc189e7b117ea2.js +0 -1
  450. package/dist/web/standalone/.next/static/chunks/app/api/recovery/route-c4cc189e7b117ea2.js +0 -1
  451. package/dist/web/standalone/.next/static/chunks/app/api/remote-questions/route-c4cc189e7b117ea2.js +0 -1
  452. package/dist/web/standalone/.next/static/chunks/app/api/session/browser/route-c4cc189e7b117ea2.js +0 -1
  453. package/dist/web/standalone/.next/static/chunks/app/api/session/command/route-c4cc189e7b117ea2.js +0 -1
  454. package/dist/web/standalone/.next/static/chunks/app/api/session/events/route-c4cc189e7b117ea2.js +0 -1
  455. package/dist/web/standalone/.next/static/chunks/app/api/session/manage/route-c4cc189e7b117ea2.js +0 -1
  456. package/dist/web/standalone/.next/static/chunks/app/api/settings-data/route-c4cc189e7b117ea2.js +0 -1
  457. package/dist/web/standalone/.next/static/chunks/app/api/shutdown/route-c4cc189e7b117ea2.js +0 -1
  458. package/dist/web/standalone/.next/static/chunks/app/api/skill-health/route-c4cc189e7b117ea2.js +0 -1
  459. package/dist/web/standalone/.next/static/chunks/app/api/steer/route-c4cc189e7b117ea2.js +0 -1
  460. package/dist/web/standalone/.next/static/chunks/app/api/switch-root/route-c4cc189e7b117ea2.js +0 -1
  461. package/dist/web/standalone/.next/static/chunks/app/api/terminal/input/route-c4cc189e7b117ea2.js +0 -1
  462. package/dist/web/standalone/.next/static/chunks/app/api/terminal/resize/route-c4cc189e7b117ea2.js +0 -1
  463. package/dist/web/standalone/.next/static/chunks/app/api/terminal/sessions/route-c4cc189e7b117ea2.js +0 -1
  464. package/dist/web/standalone/.next/static/chunks/app/api/terminal/stream/route-c4cc189e7b117ea2.js +0 -1
  465. package/dist/web/standalone/.next/static/chunks/app/api/terminal/upload/route-c4cc189e7b117ea2.js +0 -1
  466. package/dist/web/standalone/.next/static/chunks/app/api/undo/route-c4cc189e7b117ea2.js +0 -1
  467. package/dist/web/standalone/.next/static/chunks/app/api/update/route-c4cc189e7b117ea2.js +0 -1
  468. package/dist/web/standalone/.next/static/chunks/app/api/visualizer/route-c4cc189e7b117ea2.js +0 -1
  469. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/app-error-c4cc189e7b117ea2.js +0 -1
  470. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/forbidden-c4cc189e7b117ea2.js +0 -1
  471. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/not-found-c4cc189e7b117ea2.js +0 -1
  472. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/unauthorized-c4cc189e7b117ea2.js +0 -1
  473. /package/dist/web/standalone/.next/static/{F1mOwzgCW9R8N3Pt1Et87 → Z3TgDP0c7kG9j8CVQVGcl}/_ssgManifest.js +0 -0
@@ -0,0 +1,581 @@
1
+ /**
2
+ * Pre-Execution Checks — Validate task plans before execution begins.
3
+ *
4
+ * Runs these checks against a slice's task plan:
5
+ * 1. Package existence — npm view calls in parallel with timeout
6
+ * 2. File path consistency — verify files exist or are in prior expected_output
7
+ * 3. Task ordering — detect impossible ordering (task reads file created later)
8
+ * 4. Interface contracts — detect contradictory function signatures (warn only)
9
+ *
10
+ * Design principles:
11
+ * - Pure functions taking (tasks: TaskRow[], basePath: string) for testability
12
+ * - Network failures warn, don't fail (R012 conservative design)
13
+ * - Total execution <2s target (R013)
14
+ * - No AST parsers — interface parsing is heuristic (regex on code blocks)
15
+ */
16
+
17
+ import { existsSync } from "node:fs";
18
+ import { spawn } from "node:child_process";
19
+ import { resolve } from "node:path";
20
+ import type { TaskRow } from "./gsd-db.ts";
21
+ import type { PreExecutionCheckJSON } from "./verification-evidence.ts";
22
+
23
+ // ─── Result Types ────────────────────────────────────────────────────────────
24
+
25
+ export interface PreExecutionResult {
26
+ /** Overall result: pass if no blocking failures, warn if non-blocking issues, fail if blocking issues */
27
+ status: "pass" | "warn" | "fail";
28
+ /** All check results */
29
+ checks: PreExecutionCheckJSON[];
30
+ /** Total duration in milliseconds */
31
+ durationMs: number;
32
+ }
33
+
34
+ // ─── Package Existence Check ─────────────────────────────────────────────────
35
+
36
+ /**
37
+ * Extract npm package names from task descriptions.
38
+ * Looks for:
39
+ * - `npm install <pkg>` patterns
40
+ * - Code blocks with `require('<pkg>')` or `import ... from '<pkg>'`
41
+ * - Explicit mentions like "uses lodash" or "package: axios"
42
+ */
43
+ export function extractPackageReferences(description: string): string[] {
44
+ const packages = new Set<string>();
45
+
46
+ // Common words that aren't package names but might appear after install
47
+ const stopwords = new Set([
48
+ "then", "and", "the", "to", "a", "an", "in", "for", "with", "from", "or",
49
+ "npm", "yarn", "pnpm", "i", // Don't capture the command itself
50
+ ]);
51
+
52
+ // npm install <pkg> patterns (handles npm i, npm add, yarn add, pnpm add)
53
+ // Use a global pattern to find all install commands, then parse following tokens
54
+ const installCmdPattern = /(?:npm\s+(?:install|i|add)|yarn\s+add|pnpm\s+add)\s+/g;
55
+ let cmdMatch: RegExpExecArray | null;
56
+
57
+ while ((cmdMatch = installCmdPattern.exec(description)) !== null) {
58
+ // Start after the install command
59
+ const afterCmd = description.slice(cmdMatch.index + cmdMatch[0].length);
60
+
61
+ // Match package-like tokens (alphanumeric, @, /, -, _) until we hit
62
+ // something that's not a package (non-token char after whitespace)
63
+ const tokenPattern = /^([@a-zA-Z][a-zA-Z0-9@/_-]*)(?:\s+|$)/;
64
+ let remaining = afterCmd;
65
+
66
+ while (remaining.length > 0) {
67
+ // Skip any flags like -D, --save-dev
68
+ const flagMatch = remaining.match(/^(-[a-zA-Z-]+)\s*/);
69
+ if (flagMatch) {
70
+ remaining = remaining.slice(flagMatch[0].length);
71
+ continue;
72
+ }
73
+
74
+ // Try to match a package name
75
+ const pkgMatch = remaining.match(tokenPattern);
76
+ if (pkgMatch) {
77
+ const token = pkgMatch[1];
78
+ // Skip stopwords - they indicate end of package list
79
+ if (stopwords.has(token.toLowerCase())) {
80
+ break;
81
+ }
82
+ packages.add(normalizePackageName(token));
83
+ remaining = remaining.slice(pkgMatch[0].length);
84
+ } else {
85
+ // Not a package name, stop parsing this install command
86
+ break;
87
+ }
88
+ }
89
+ }
90
+
91
+ // require('pkg') or import from 'pkg' in code blocks
92
+ const importPattern = /(?:require\s*\(\s*['"]|from\s+['"])([a-zA-Z0-9@/_-]+)['"\)]/g;
93
+ let importMatch: RegExpExecArray | null;
94
+ while ((importMatch = importPattern.exec(description)) !== null) {
95
+ // Skip relative imports and node builtins
96
+ const pkg = importMatch[1];
97
+ if (!pkg.startsWith(".") && !pkg.startsWith("node:")) {
98
+ packages.add(normalizePackageName(pkg));
99
+ }
100
+ }
101
+
102
+ return Array.from(packages);
103
+ }
104
+
105
+ /**
106
+ * Normalize package name to registry-checkable form.
107
+ * Handles scoped packages (@org/pkg) and subpaths (pkg/subpath → pkg).
108
+ */
109
+ function normalizePackageName(raw: string): string {
110
+ // Scoped package: @org/pkg or @org/pkg/subpath
111
+ if (raw.startsWith("@")) {
112
+ const parts = raw.split("/");
113
+ return parts.length >= 2 ? `${parts[0]}/${parts[1]}` : raw;
114
+ }
115
+ // Regular package: pkg or pkg/subpath
116
+ return raw.split("/")[0];
117
+ }
118
+
119
+ /**
120
+ * Check if a package exists on npm registry.
121
+ * Returns null on success, error message on failure.
122
+ * Times out after timeoutMs (default 5000ms).
123
+ */
124
+ async function checkPackageOnNpm(
125
+ packageName: string,
126
+ timeoutMs = 5000
127
+ ): Promise<{ exists: boolean; error?: string }> {
128
+ return new Promise((resolve) => {
129
+ const child = spawn("npm", ["view", packageName, "name"], {
130
+ stdio: ["ignore", "pipe", "pipe"],
131
+ timeout: timeoutMs,
132
+ });
133
+
134
+ let stdout = "";
135
+ let stderr = "";
136
+
137
+ child.stdout.on("data", (data: Buffer) => {
138
+ stdout += data.toString();
139
+ });
140
+ child.stderr.on("data", (data: Buffer) => {
141
+ stderr += data.toString();
142
+ });
143
+
144
+ const timer = setTimeout(() => {
145
+ child.kill("SIGTERM");
146
+ resolve({ exists: false, error: `Timeout after ${timeoutMs}ms` });
147
+ }, timeoutMs);
148
+
149
+ child.on("close", (code) => {
150
+ clearTimeout(timer);
151
+ if (code === 0 && stdout.trim()) {
152
+ resolve({ exists: true });
153
+ } else if (stderr.includes("404") || stderr.includes("not found")) {
154
+ resolve({ exists: false, error: `Package not found: ${packageName}` });
155
+ } else if (code !== 0) {
156
+ // Network error or other issue — warn, don't fail
157
+ resolve({ exists: true, error: `npm view failed (code ${code}): ${stderr.slice(0, 100)}` });
158
+ } else {
159
+ resolve({ exists: true });
160
+ }
161
+ });
162
+
163
+ child.on("error", (err) => {
164
+ clearTimeout(timer);
165
+ resolve({ exists: true, error: `npm spawn error: ${err.message}` });
166
+ });
167
+ });
168
+ }
169
+
170
+ /**
171
+ * Check all package references in tasks for existence on npm.
172
+ * Runs checks in parallel with a 5s timeout per package.
173
+ * Network failures warn but don't fail (R012 conservative design).
174
+ */
175
+ export async function checkPackageExistence(
176
+ tasks: TaskRow[],
177
+ _basePath: string
178
+ ): Promise<PreExecutionCheckJSON[]> {
179
+ const results: PreExecutionCheckJSON[] = [];
180
+ const packagesToCheck = new Set<string>();
181
+
182
+ // Collect all package references from task descriptions
183
+ for (const task of tasks) {
184
+ const packages = extractPackageReferences(task.description);
185
+ for (const pkg of packages) {
186
+ packagesToCheck.add(pkg);
187
+ }
188
+ }
189
+
190
+ if (packagesToCheck.size === 0) {
191
+ return results;
192
+ }
193
+
194
+ // Check packages in parallel
195
+ const checkPromises = Array.from(packagesToCheck).map(async (pkg) => {
196
+ const result = await checkPackageOnNpm(pkg);
197
+ return { pkg, result };
198
+ });
199
+
200
+ const checkResults = await Promise.all(checkPromises);
201
+
202
+ for (const { pkg, result } of checkResults) {
203
+ if (!result.exists && !result.error?.includes("Timeout") && !result.error?.includes("spawn error")) {
204
+ // Package genuinely doesn't exist — blocking failure
205
+ results.push({
206
+ category: "package",
207
+ target: pkg,
208
+ passed: false,
209
+ message: result.error || `Package '${pkg}' not found on npm`,
210
+ blocking: true,
211
+ });
212
+ } else if (result.error) {
213
+ // Network issue or timeout — warn but don't block
214
+ results.push({
215
+ category: "package",
216
+ target: pkg,
217
+ passed: true,
218
+ message: `Warning: ${result.error}`,
219
+ blocking: false,
220
+ });
221
+ }
222
+ // Silent success for existing packages — no need to report
223
+ }
224
+
225
+ return results;
226
+ }
227
+
228
+ // ─── File Path Consistency Check ─────────────────────────────────────────────
229
+
230
+ /**
231
+ * Normalize a file path for consistent comparison.
232
+ * - Strips leading ./
233
+ * - Normalizes path separators to forward slashes
234
+ * - Resolves redundant segments (e.g., foo/../bar → bar)
235
+ *
236
+ * This ensures that "./src/a.ts", "src/a.ts", and "src//a.ts" all compare equal.
237
+ */
238
+ export function normalizeFilePath(filePath: string): string {
239
+ if (!filePath) return filePath;
240
+
241
+ // Strip backtick wrapping from LLM-generated paths (#3649)
242
+ let normalized = filePath.replace(/`/g, "");
243
+
244
+ // Normalize path separators to forward slashes
245
+ normalized = normalized.replace(/\\/g, "/");
246
+
247
+ // Remove leading ./
248
+ while (normalized.startsWith("./")) {
249
+ normalized = normalized.slice(2);
250
+ }
251
+
252
+ // Remove duplicate slashes
253
+ normalized = normalized.replace(/\/+/g, "/");
254
+
255
+ // Remove trailing slash unless it's the root
256
+ if (normalized.length > 1 && normalized.endsWith("/")) {
257
+ normalized = normalized.slice(0, -1);
258
+ }
259
+
260
+ return normalized;
261
+ }
262
+
263
+ /**
264
+ * Build a set of files that will be created by tasks up to (but not including) taskIndex.
265
+ * All paths are normalized for consistent comparison.
266
+ */
267
+ function getExpectedOutputsUpTo(tasks: TaskRow[], taskIndex: number): Set<string> {
268
+ const outputs = new Set<string>();
269
+ for (let i = 0; i < taskIndex; i++) {
270
+ for (const file of tasks[i].expected_output) {
271
+ outputs.add(normalizeFilePath(file));
272
+ }
273
+ }
274
+ return outputs;
275
+ }
276
+
277
+ /**
278
+ * Check that all files referenced in task.inputs either:
279
+ * 1. Exist on disk, OR
280
+ * 2. Are in a prior task's expected_output
281
+ *
282
+ * task.files ("files likely touched") is excluded — it intentionally includes
283
+ * files the task will create, so they don't need to pre-exist (#3626).
284
+ *
285
+ * All paths are normalized before comparison to ensure ./src/a.ts matches src/a.ts.
286
+ */
287
+ export function checkFilePathConsistency(
288
+ tasks: TaskRow[],
289
+ basePath: string
290
+ ): PreExecutionCheckJSON[] {
291
+ const results: PreExecutionCheckJSON[] = [];
292
+
293
+ for (let i = 0; i < tasks.length; i++) {
294
+ const task = tasks[i];
295
+ const priorOutputs = getExpectedOutputsUpTo(tasks, i);
296
+ const filesToCheck = [...task.inputs];
297
+
298
+ for (const file of filesToCheck) {
299
+ // Skip empty strings
300
+ if (!file.trim()) continue;
301
+
302
+ // Normalize path for consistent comparison
303
+ const normalizedFile = normalizeFilePath(file);
304
+
305
+ // Check if file exists on disk
306
+ const absolutePath = resolve(basePath, normalizedFile);
307
+ const existsOnDisk = existsSync(absolutePath);
308
+
309
+ // Check if file is in prior expected outputs (priorOutputs already normalized)
310
+ const inPriorOutputs = priorOutputs.has(normalizedFile);
311
+
312
+ if (!existsOnDisk && !inPriorOutputs) {
313
+ results.push({
314
+ category: "file",
315
+ target: file,
316
+ passed: false,
317
+ message: `Task ${task.id} references '${file}' which doesn't exist and isn't created by prior tasks`,
318
+ blocking: true,
319
+ });
320
+ }
321
+ }
322
+ }
323
+
324
+ return results;
325
+ }
326
+
327
+ // ─── Task Ordering Check ─────────────────────────────────────────────────────
328
+
329
+ /**
330
+ * Detect impossible task ordering: task N reads a file that task N+M creates.
331
+ * This is a fatal error — the plan has an impossible dependency.
332
+ *
333
+ * All paths are normalized before comparison to ensure ./src/a.ts matches src/a.ts.
334
+ */
335
+ export function checkTaskOrdering(
336
+ tasks: TaskRow[],
337
+ _basePath: string
338
+ ): PreExecutionCheckJSON[] {
339
+ const results: PreExecutionCheckJSON[] = [];
340
+
341
+ // Build map: normalized file → task index that creates it
342
+ const fileCreators = new Map<string, { taskId: string; index: number; originalPath: string }>();
343
+ for (let i = 0; i < tasks.length; i++) {
344
+ const task = tasks[i];
345
+ for (const file of task.expected_output) {
346
+ const normalizedFile = normalizeFilePath(file);
347
+ if (!fileCreators.has(normalizedFile)) {
348
+ fileCreators.set(normalizedFile, { taskId: task.id, index: i, originalPath: file });
349
+ }
350
+ }
351
+ }
352
+
353
+ // Check each task's inputs against file creators.
354
+ // Only check task.inputs — task.files ("files likely touched") intentionally
355
+ // includes files the task will create, so they don't indicate read-before-create (#3677).
356
+ for (let i = 0; i < tasks.length; i++) {
357
+ const task = tasks[i];
358
+ const filesToCheck = [...task.inputs];
359
+
360
+ for (const file of filesToCheck) {
361
+ const normalizedFile = normalizeFilePath(file);
362
+ const creator = fileCreators.get(normalizedFile);
363
+ if (creator && creator.index > i) {
364
+ // Task reads file that is created later — impossible ordering
365
+ results.push({
366
+ category: "file",
367
+ target: file,
368
+ passed: false,
369
+ message: `Task ${task.id} reads '${file}' but it's created by task ${creator.taskId} (sequence violation)`,
370
+ blocking: true,
371
+ });
372
+ }
373
+ }
374
+ }
375
+
376
+ return results;
377
+ }
378
+
379
+ // ─── Interface Contract Check ────────────────────────────────────────────────
380
+
381
+ interface FunctionSignature {
382
+ name: string;
383
+ params: string;
384
+ returnType: string;
385
+ taskId: string;
386
+ raw: string;
387
+ }
388
+
389
+ /**
390
+ * Extract function signatures from code blocks in task description.
391
+ * Uses heuristic regex — not an AST parser.
392
+ */
393
+ function extractFunctionSignatures(description: string, taskId: string): FunctionSignature[] {
394
+ const signatures: FunctionSignature[] = [];
395
+
396
+ // Match code blocks (```...```)
397
+ const codeBlockPattern = /```(?:typescript|ts|javascript|js)?\n([\s\S]*?)```/g;
398
+ let blockMatch: RegExpExecArray | null;
399
+
400
+ while ((blockMatch = codeBlockPattern.exec(description)) !== null) {
401
+ const codeBlock = blockMatch[1];
402
+
403
+ // Match function declarations and exports
404
+ // Patterns:
405
+ // function name(params): ReturnType
406
+ // export function name(params): ReturnType
407
+ // export async function name(params): Promise<ReturnType>
408
+ // const name = (params): ReturnType =>
409
+ // export const name = (params): ReturnType =>
410
+ const funcPattern = /(?:export\s+)?(?:async\s+)?(?:function\s+|const\s+)(\w+)(?:\s*=\s*)?\s*\(([^)]*)\)(?:\s*:\s*([^{=>\n]+))?/g;
411
+ let funcMatch: RegExpExecArray | null;
412
+
413
+ while ((funcMatch = funcPattern.exec(codeBlock)) !== null) {
414
+ const [raw, name, params, returnType] = funcMatch;
415
+ signatures.push({
416
+ name,
417
+ params: normalizeParams(params),
418
+ returnType: normalizeType(returnType || "void"),
419
+ taskId,
420
+ raw: raw.trim(),
421
+ });
422
+ }
423
+
424
+ // Match interface method signatures
425
+ // Pattern: methodName(params): ReturnType;
426
+ const methodPattern = /^\s*(\w+)\s*\(([^)]*)\)\s*:\s*([^;]+);/gm;
427
+ let methodMatch: RegExpExecArray | null;
428
+
429
+ while ((methodMatch = methodPattern.exec(codeBlock)) !== null) {
430
+ const [raw, name, params, returnType] = methodMatch;
431
+ signatures.push({
432
+ name,
433
+ params: normalizeParams(params),
434
+ returnType: normalizeType(returnType),
435
+ taskId,
436
+ raw: raw.trim(),
437
+ });
438
+ }
439
+ }
440
+
441
+ return signatures;
442
+ }
443
+
444
+ /**
445
+ * Normalize parameter list for comparison.
446
+ * Removes whitespace, comments, and default values.
447
+ */
448
+ function normalizeParams(params: string): string {
449
+ return params
450
+ .replace(/\/\*[\s\S]*?\*\//g, "") // Remove block comments
451
+ .replace(/\/\/[^\n]*/g, "") // Remove line comments
452
+ .replace(/\s*=\s*[^,)]+/g, "") // Remove default values
453
+ .replace(/\s+/g, " ") // Normalize whitespace
454
+ .trim();
455
+ }
456
+
457
+ /**
458
+ * Normalize type for comparison.
459
+ */
460
+ function normalizeType(type: string): string {
461
+ return type
462
+ .replace(/\s+/g, " ")
463
+ .trim();
464
+ }
465
+
466
+ /**
467
+ * Check for contradictory function signatures across tasks.
468
+ * Same function name with different signatures is a warning (not blocking).
469
+ */
470
+ export function checkInterfaceContracts(
471
+ tasks: TaskRow[],
472
+ _basePath: string
473
+ ): PreExecutionCheckJSON[] {
474
+ const results: PreExecutionCheckJSON[] = [];
475
+
476
+ // Collect all signatures
477
+ const allSignatures: FunctionSignature[] = [];
478
+ for (const task of tasks) {
479
+ const sigs = extractFunctionSignatures(task.description, task.id);
480
+ allSignatures.push(...sigs);
481
+ }
482
+
483
+ // Group by function name
484
+ const byName = new Map<string, FunctionSignature[]>();
485
+ for (const sig of allSignatures) {
486
+ const existing = byName.get(sig.name) || [];
487
+ existing.push(sig);
488
+ byName.set(sig.name, existing);
489
+ }
490
+
491
+ // Check for contradictions
492
+ for (const [name, sigs] of byName) {
493
+ if (sigs.length < 2) continue;
494
+
495
+ // Compare signatures
496
+ const first = sigs[0];
497
+ for (let i = 1; i < sigs.length; i++) {
498
+ const current = sigs[i];
499
+
500
+ // Check parameter mismatch
501
+ if (first.params !== current.params) {
502
+ results.push({
503
+ category: "schema",
504
+ target: name,
505
+ passed: true, // Warning only, not blocking
506
+ message: `Function '${name}' has different parameters: '${first.params}' (${first.taskId}) vs '${current.params}' (${current.taskId})`,
507
+ blocking: false,
508
+ });
509
+ }
510
+
511
+ // Check return type mismatch
512
+ if (first.returnType !== current.returnType) {
513
+ results.push({
514
+ category: "schema",
515
+ target: name,
516
+ passed: true, // Warning only, not blocking
517
+ message: `Function '${name}' has different return types: '${first.returnType}' (${first.taskId}) vs '${current.returnType}' (${current.taskId})`,
518
+ blocking: false,
519
+ });
520
+ }
521
+ }
522
+ }
523
+
524
+ return results;
525
+ }
526
+
527
+ // ─── Main Entry Point ────────────────────────────────────────────────────────
528
+
529
+ /**
530
+ * Run all pre-execution checks against a slice's task plan.
531
+ *
532
+ * @param tasks - Array of TaskRow from the slice
533
+ * @param basePath - Base path for resolving file references
534
+ * @returns PreExecutionResult with status, checks, and duration
535
+ */
536
+ export async function runPreExecutionChecks(
537
+ tasks: TaskRow[],
538
+ basePath: string
539
+ ): Promise<PreExecutionResult> {
540
+ const startTime = Date.now();
541
+ const allChecks: PreExecutionCheckJSON[] = [];
542
+
543
+ // Run sync checks first
544
+ const fileChecks = checkFilePathConsistency(tasks, basePath);
545
+ const orderingChecks = checkTaskOrdering(tasks, basePath);
546
+ const contractChecks = checkInterfaceContracts(tasks, basePath);
547
+
548
+ allChecks.push(...fileChecks, ...orderingChecks, ...contractChecks);
549
+
550
+ // Run async package checks
551
+ const packageChecks = await checkPackageExistence(tasks, basePath);
552
+ allChecks.push(...packageChecks);
553
+
554
+ const durationMs = Date.now() - startTime;
555
+
556
+ // Determine overall status
557
+ const hasBlockingFailure = allChecks.some((c) => !c.passed && c.blocking);
558
+ const hasNonBlockingFailure = allChecks.some((c) => !c.passed && !c.blocking);
559
+ // Interface contract checks pass but still report warnings via message
560
+ const hasInterfaceWarning = allChecks.some(
561
+ (c) => c.category === "schema" && c.message && !c.message.startsWith("Warning:")
562
+ );
563
+ const hasNetworkWarning = allChecks.some(
564
+ (c) => c.passed && c.message?.startsWith("Warning:")
565
+ );
566
+
567
+ let status: "pass" | "warn" | "fail";
568
+ if (hasBlockingFailure) {
569
+ status = "fail";
570
+ } else if (hasNonBlockingFailure || hasInterfaceWarning || hasNetworkWarning) {
571
+ status = "warn";
572
+ } else {
573
+ status = "pass";
574
+ }
575
+
576
+ return {
577
+ status,
578
+ checks: allChecks,
579
+ durationMs,
580
+ };
581
+ }
@@ -106,6 +106,13 @@ export const KNOWN_PREFERENCE_KEYS = new Set<string>([
106
106
  "codebase",
107
107
  "slice_parallel",
108
108
  "safety_harness",
109
+ "enhanced_verification",
110
+ "enhanced_verification_pre",
111
+ "enhanced_verification_post",
112
+ "enhanced_verification_strict",
113
+ "discuss_preparation",
114
+ "discuss_web_research",
115
+ "discuss_depth",
109
116
  ]);
110
117
 
111
118
  /** Canonical list of all dispatch unit types. */
@@ -304,6 +311,52 @@ export interface GSDPreferences {
304
311
  auto_rollback?: boolean;
305
312
  timeout_scale_cap?: number;
306
313
  };
314
+
315
+
316
+ // ─── Enhanced Verification ──────────────────────────────────────────────────
317
+ /**
318
+ * Enable enhanced verification (both pre-execution and post-execution checks).
319
+ * Default: true (opt-out, not opt-in). Set false to disable all enhanced verification.
320
+ */
321
+ enhanced_verification?: boolean;
322
+ /**
323
+ * Enable pre-execution checks (package existence, file references, etc.).
324
+ * Only applies when enhanced_verification is true.
325
+ * Default: true.
326
+ */
327
+ enhanced_verification_pre?: boolean;
328
+ /**
329
+ * Enable post-execution checks (runtime error detection, audit warnings, etc.).
330
+ * Only applies when enhanced_verification is true.
331
+ * Default: true.
332
+ */
333
+ enhanced_verification_post?: boolean;
334
+ /**
335
+ * Strict mode: treat any pre-execution check failure as blocking.
336
+ * Default: false (warnings only for non-critical failures).
337
+ */
338
+ enhanced_verification_strict?: boolean;
339
+ /**
340
+ * Enable the preparation phase before discussion sessions.
341
+ * Preparation analyzes the codebase, reviews prior context, and optionally researches the ecosystem.
342
+ * Default: true.
343
+ */
344
+ discuss_preparation?: boolean;
345
+ /**
346
+ * Enable web research during preparation phase.
347
+ * When enabled, searches for best practices and known issues for the detected tech stack.
348
+ * Requires a search API key (TAVILY_API_KEY or BRAVE_API_KEY).
349
+ * Default: true.
350
+ */
351
+ discuss_web_research?: boolean;
352
+ /**
353
+ * Depth of preparation analysis.
354
+ * - "quick": Minimal analysis, fastest (~10s)
355
+ * - "standard": Balanced analysis (~30s)
356
+ * - "thorough": Deep analysis with more file sampling (~60s)
357
+ * Default: "standard".
358
+ */
359
+ discuss_depth?: "quick" | "standard" | "thorough";
307
360
  }
308
361
 
309
362
  export interface LoadedGSDPreferences {