gsd-pi 2.63.0 → 2.64.0-dev.05b8a94

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 (612) hide show
  1. package/README.md +46 -134
  2. package/dist/cli.js +48 -6
  3. package/dist/headless-query.js +11 -1
  4. package/dist/headless.js +3 -1
  5. package/dist/help-text.js +4 -1
  6. package/dist/onboarding.js +15 -8
  7. package/dist/resource-loader.js +18 -3
  8. package/dist/resources/extensions/bg-shell/bg-shell-lifecycle.js +22 -7
  9. package/dist/resources/extensions/bg-shell/process-manager.js +6 -1
  10. package/dist/resources/extensions/cmux/index.js +21 -12
  11. package/dist/resources/extensions/gsd/auto/detect-stuck.js +27 -0
  12. package/dist/resources/extensions/gsd/auto/finalize-timeout.js +40 -0
  13. package/dist/resources/extensions/gsd/auto/loop.js +4 -0
  14. package/dist/resources/extensions/gsd/auto/phases.js +157 -22
  15. package/dist/resources/extensions/gsd/auto/session.js +12 -0
  16. package/dist/resources/extensions/gsd/auto-dashboard.js +14 -8
  17. package/dist/resources/extensions/gsd/auto-model-selection.js +32 -0
  18. package/dist/resources/extensions/gsd/auto-post-unit.js +222 -11
  19. package/dist/resources/extensions/gsd/auto-prompts.js +25 -0
  20. package/dist/resources/extensions/gsd/auto-recovery.js +15 -7
  21. package/dist/resources/extensions/gsd/auto-start.js +10 -21
  22. package/dist/resources/extensions/gsd/auto-timers.js +2 -1
  23. package/dist/resources/extensions/gsd/auto-tool-tracking.js +17 -0
  24. package/dist/resources/extensions/gsd/auto-verification.js +138 -1
  25. package/dist/resources/extensions/gsd/auto-worktree.js +13 -7
  26. package/dist/resources/extensions/gsd/auto.js +24 -2
  27. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +158 -75
  28. package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +13 -0
  29. package/dist/resources/extensions/gsd/bootstrap/notify-interceptor.js +28 -0
  30. package/dist/resources/extensions/gsd/bootstrap/query-tools.js +85 -0
  31. package/dist/resources/extensions/gsd/bootstrap/register-extension.js +3 -0
  32. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +40 -1
  33. package/dist/resources/extensions/gsd/bootstrap/register-shortcuts.js +15 -0
  34. package/dist/resources/extensions/gsd/bootstrap/sanitize-complete-milestone.js +54 -0
  35. package/dist/resources/extensions/gsd/bootstrap/system-context.js +50 -2
  36. package/dist/resources/extensions/gsd/commands/catalog.js +7 -1
  37. package/dist/resources/extensions/gsd/commands/handlers/core.js +1 -0
  38. package/dist/resources/extensions/gsd/commands/handlers/notifications-handler.js +103 -0
  39. package/dist/resources/extensions/gsd/commands/handlers/ops.js +5 -0
  40. package/dist/resources/extensions/gsd/commands-handlers.js +9 -4
  41. package/dist/resources/extensions/gsd/constants.js +42 -0
  42. package/dist/resources/extensions/gsd/db-writer.js +72 -4
  43. package/dist/resources/extensions/gsd/forensics.js +20 -4
  44. package/dist/resources/extensions/gsd/gsd-db.js +64 -17
  45. package/dist/resources/extensions/gsd/guided-flow.js +19 -0
  46. package/dist/resources/extensions/gsd/metrics.js +27 -1
  47. package/dist/resources/extensions/gsd/native-git-bridge.js +5 -3
  48. package/dist/resources/extensions/gsd/notification-overlay.js +224 -0
  49. package/dist/resources/extensions/gsd/notification-store.js +268 -0
  50. package/dist/resources/extensions/gsd/notification-widget.js +56 -0
  51. package/dist/resources/extensions/gsd/post-execution-checks.js +407 -0
  52. package/dist/resources/extensions/gsd/pre-execution-checks.js +464 -0
  53. package/dist/resources/extensions/gsd/preferences-types.js +6 -0
  54. package/dist/resources/extensions/gsd/preferences-validation.js +33 -0
  55. package/dist/resources/extensions/gsd/preferences.js +11 -2
  56. package/dist/resources/extensions/gsd/prompt-loader.js +7 -0
  57. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +2 -0
  58. package/dist/resources/extensions/gsd/prompts/complete-slice.md +2 -0
  59. package/dist/resources/extensions/gsd/prompts/doctor-heal.md +1 -0
  60. package/dist/resources/extensions/gsd/prompts/forensics.md +2 -0
  61. package/dist/resources/extensions/gsd/prompts/reassess-roadmap.md +2 -0
  62. package/dist/resources/extensions/gsd/prompts/system.md +4 -7
  63. package/dist/resources/extensions/gsd/prompts/validate-milestone.md +2 -0
  64. package/dist/resources/extensions/gsd/roadmap-mutations.js +1 -1
  65. package/dist/resources/extensions/gsd/roadmap-slices.js +9 -5
  66. package/dist/resources/extensions/gsd/safety/content-validator.js +73 -0
  67. package/dist/resources/extensions/gsd/safety/destructive-guard.js +34 -0
  68. package/dist/resources/extensions/gsd/safety/evidence-collector.js +109 -0
  69. package/dist/resources/extensions/gsd/safety/evidence-cross-ref.js +83 -0
  70. package/dist/resources/extensions/gsd/safety/file-change-validator.js +71 -0
  71. package/dist/resources/extensions/gsd/safety/git-checkpoint.js +91 -0
  72. package/dist/resources/extensions/gsd/safety/safety-harness.js +64 -0
  73. package/dist/resources/extensions/gsd/slice-parallel-conflict.js +67 -0
  74. package/dist/resources/extensions/gsd/slice-parallel-eligibility.js +51 -0
  75. package/dist/resources/extensions/gsd/slice-parallel-orchestrator.js +378 -0
  76. package/dist/resources/extensions/gsd/state.js +74 -14
  77. package/dist/resources/extensions/gsd/status-guards.js +11 -0
  78. package/dist/resources/extensions/gsd/tools/complete-milestone.js +17 -12
  79. package/dist/resources/extensions/gsd/tools/complete-slice.js +40 -26
  80. package/dist/resources/extensions/gsd/tools/complete-task.js +12 -12
  81. package/dist/resources/extensions/gsd/tools/plan-milestone.js +33 -25
  82. package/dist/resources/extensions/gsd/tools/plan-slice.js +5 -8
  83. package/dist/resources/extensions/gsd/verification-evidence.js +18 -0
  84. package/dist/resources/extensions/gsd/workflow-logger.js +8 -0
  85. package/dist/resources/extensions/gsd/workflow-projections.js +21 -5
  86. package/dist/resources/extensions/gsd/worktree-manager.js +82 -29
  87. package/dist/resources/extensions/gsd/worktree-resolver.js +4 -3
  88. package/dist/resources/extensions/mcp-client/auth.js +101 -0
  89. package/dist/resources/extensions/mcp-client/index.js +10 -1
  90. package/dist/resources/extensions/ollama/index.js +28 -22
  91. package/dist/resources/extensions/ollama/model-capabilities.js +37 -34
  92. package/dist/resources/extensions/ollama/ndjson-stream.js +54 -0
  93. package/dist/resources/extensions/ollama/ollama-chat-provider.js +380 -0
  94. package/dist/resources/extensions/ollama/ollama-client.js +23 -32
  95. package/dist/resources/extensions/ollama/ollama-discovery.js +2 -7
  96. package/dist/resources/extensions/ollama/ollama-tool.js +62 -0
  97. package/dist/resources/extensions/ollama/thinking-parser.js +104 -0
  98. package/dist/update-cmd.js +4 -2
  99. package/dist/web/standalone/.next/BUILD_ID +1 -1
  100. package/dist/web/standalone/.next/app-path-routes-manifest.json +20 -19
  101. package/dist/web/standalone/.next/build-manifest.json +3 -3
  102. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  103. package/dist/web/standalone/.next/required-server-files.json +4 -4
  104. package/dist/web/standalone/.next/routes-manifest.json +6 -0
  105. package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
  106. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  107. package/dist/web/standalone/.next/server/app/_global-error.html +2 -2
  108. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  109. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  110. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  111. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  112. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  113. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  114. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  115. package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
  116. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  117. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  118. package/dist/web/standalone/.next/server/app/_not-found.rsc +3 -3
  119. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
  120. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  121. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +3 -3
  122. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  123. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  124. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  125. package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
  126. package/dist/web/standalone/.next/server/app/api/boot/route.js.nft.json +1 -1
  127. package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
  128. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
  129. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js.nft.json +1 -1
  130. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
  131. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
  132. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js.nft.json +1 -1
  133. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
  134. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
  135. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js.nft.json +1 -1
  136. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
  137. package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
  138. package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
  139. package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
  140. package/dist/web/standalone/.next/server/app/api/captures/route.js.nft.json +1 -1
  141. package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
  142. package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
  143. package/dist/web/standalone/.next/server/app/api/cleanup/route.js.nft.json +1 -1
  144. package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
  145. package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
  146. package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
  147. package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
  148. package/dist/web/standalone/.next/server/app/api/doctor/route.js.nft.json +1 -1
  149. package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
  150. package/dist/web/standalone/.next/server/app/api/experimental/route.js +2 -2
  151. package/dist/web/standalone/.next/server/app/api/experimental/route_client-reference-manifest.js +1 -1
  152. package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
  153. package/dist/web/standalone/.next/server/app/api/export-data/route.js.nft.json +1 -1
  154. package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
  155. package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
  156. package/dist/web/standalone/.next/server/app/api/files/route.js.nft.json +1 -1
  157. package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
  158. package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
  159. package/dist/web/standalone/.next/server/app/api/forensics/route.js.nft.json +1 -1
  160. package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
  161. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  162. package/dist/web/standalone/.next/server/app/api/git/route.js.nft.json +1 -1
  163. package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  164. package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
  165. package/dist/web/standalone/.next/server/app/api/history/route.js.nft.json +1 -1
  166. package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
  167. package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
  168. package/dist/web/standalone/.next/server/app/api/hooks/route.js.nft.json +1 -1
  169. package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
  170. package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
  171. package/dist/web/standalone/.next/server/app/api/inspect/route.js.nft.json +1 -1
  172. package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
  173. package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
  174. package/dist/web/standalone/.next/server/app/api/knowledge/route.js.nft.json +1 -1
  175. package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
  176. package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
  177. package/dist/web/standalone/.next/server/app/api/live-state/route.js.nft.json +1 -1
  178. package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
  179. package/dist/web/standalone/.next/server/app/api/notifications/route.js +3 -0
  180. package/dist/web/standalone/.next/server/app/api/notifications/route.js.nft.json +1 -0
  181. package/dist/web/standalone/.next/server/app/api/notifications/route_client-reference-manifest.js +1 -0
  182. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  183. package/dist/web/standalone/.next/server/app/api/onboarding/route.js.nft.json +1 -1
  184. package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
  185. package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
  186. package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
  187. package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
  188. package/dist/web/standalone/.next/server/app/api/projects/route.js.nft.json +1 -1
  189. package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  190. package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
  191. package/dist/web/standalone/.next/server/app/api/recovery/route.js.nft.json +1 -1
  192. package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
  193. package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +2 -2
  194. package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
  195. package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
  196. package/dist/web/standalone/.next/server/app/api/session/browser/route.js.nft.json +1 -1
  197. package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
  198. package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
  199. package/dist/web/standalone/.next/server/app/api/session/command/route.js.nft.json +1 -1
  200. package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
  201. package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
  202. package/dist/web/standalone/.next/server/app/api/session/events/route.js.nft.json +1 -1
  203. package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
  204. package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
  205. package/dist/web/standalone/.next/server/app/api/session/manage/route.js.nft.json +1 -1
  206. package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
  207. package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
  208. package/dist/web/standalone/.next/server/app/api/settings-data/route.js.nft.json +1 -1
  209. package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
  210. package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
  211. package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
  212. package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
  213. package/dist/web/standalone/.next/server/app/api/skill-health/route.js.nft.json +1 -1
  214. package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
  215. package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
  216. package/dist/web/standalone/.next/server/app/api/steer/route.js.nft.json +1 -1
  217. package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
  218. package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
  219. package/dist/web/standalone/.next/server/app/api/switch-root/route.js.nft.json +1 -1
  220. package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
  221. package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +2 -2
  222. package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
  223. package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
  224. package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
  225. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +2 -2
  226. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js.nft.json +1 -1
  227. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
  228. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +4 -4
  229. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js.nft.json +1 -1
  230. package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
  231. package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
  232. package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
  233. package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
  234. package/dist/web/standalone/.next/server/app/api/undo/route.js.nft.json +1 -1
  235. package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
  236. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  237. package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  238. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  239. package/dist/web/standalone/.next/server/app/api/visualizer/route.js.nft.json +1 -1
  240. package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
  241. package/dist/web/standalone/.next/server/app/index.html +1 -1
  242. package/dist/web/standalone/.next/server/app/index.rsc +4 -4
  243. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  244. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +4 -4
  245. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  246. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +3 -3
  247. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  248. package/dist/web/standalone/.next/server/app/page.js +2 -2
  249. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  250. package/dist/web/standalone/.next/server/app-paths-manifest.json +20 -19
  251. package/dist/web/standalone/.next/server/chunks/6897.js +12 -0
  252. package/dist/web/standalone/.next/server/chunks/7471.js +3 -3
  253. package/dist/web/standalone/.next/server/functions-config-manifest.json +1 -0
  254. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  255. package/dist/web/standalone/.next/server/middleware.js +2 -2
  256. package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
  257. package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
  258. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  259. package/dist/web/standalone/.next/server/pages/500.html +2 -2
  260. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  261. package/dist/web/standalone/.next/static/Vbx2-SrSBOgta6576xj9m/_buildManifest.js +1 -0
  262. package/dist/web/standalone/.next/static/chunks/app/_global-error/page-8805a20e15762c3c.js +1 -0
  263. package/dist/web/standalone/.next/static/chunks/app/_not-found/{page-2f24283c162b6ab3.js → page-f2a7482d42a5614b.js} +1 -1
  264. package/dist/web/standalone/.next/static/chunks/app/api/boot/route-8805a20e15762c3c.js +1 -0
  265. package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/input/route-8805a20e15762c3c.js +1 -0
  266. package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/resize/route-8805a20e15762c3c.js +1 -0
  267. package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/stream/route-8805a20e15762c3c.js +1 -0
  268. package/dist/web/standalone/.next/static/chunks/app/api/browse-directories/route-8805a20e15762c3c.js +1 -0
  269. package/dist/web/standalone/.next/static/chunks/app/api/captures/route-8805a20e15762c3c.js +1 -0
  270. package/dist/web/standalone/.next/static/chunks/app/api/cleanup/route-8805a20e15762c3c.js +1 -0
  271. package/dist/web/standalone/.next/static/chunks/app/api/dev-mode/route-8805a20e15762c3c.js +1 -0
  272. package/dist/web/standalone/.next/static/chunks/app/api/doctor/route-8805a20e15762c3c.js +1 -0
  273. package/dist/web/standalone/.next/static/chunks/app/api/experimental/route-8805a20e15762c3c.js +1 -0
  274. package/dist/web/standalone/.next/static/chunks/app/api/export-data/route-8805a20e15762c3c.js +1 -0
  275. package/dist/web/standalone/.next/static/chunks/app/api/files/route-8805a20e15762c3c.js +1 -0
  276. package/dist/web/standalone/.next/static/chunks/app/api/forensics/route-8805a20e15762c3c.js +1 -0
  277. package/dist/web/standalone/.next/static/chunks/app/api/git/route-8805a20e15762c3c.js +1 -0
  278. package/dist/web/standalone/.next/static/chunks/app/api/history/route-8805a20e15762c3c.js +1 -0
  279. package/dist/web/standalone/.next/static/chunks/app/api/hooks/route-8805a20e15762c3c.js +1 -0
  280. package/dist/web/standalone/.next/static/chunks/app/api/inspect/route-8805a20e15762c3c.js +1 -0
  281. package/dist/web/standalone/.next/static/chunks/app/api/knowledge/route-8805a20e15762c3c.js +1 -0
  282. package/dist/web/standalone/.next/static/chunks/app/api/live-state/route-8805a20e15762c3c.js +1 -0
  283. package/dist/web/standalone/.next/static/chunks/app/api/notifications/route-8805a20e15762c3c.js +1 -0
  284. package/dist/web/standalone/.next/static/chunks/app/api/onboarding/route-8805a20e15762c3c.js +1 -0
  285. package/dist/web/standalone/.next/static/chunks/app/api/preferences/route-8805a20e15762c3c.js +1 -0
  286. package/dist/web/standalone/.next/static/chunks/app/api/projects/route-8805a20e15762c3c.js +1 -0
  287. package/dist/web/standalone/.next/static/chunks/app/api/recovery/route-8805a20e15762c3c.js +1 -0
  288. package/dist/web/standalone/.next/static/chunks/app/api/remote-questions/route-8805a20e15762c3c.js +1 -0
  289. package/dist/web/standalone/.next/static/chunks/app/api/session/browser/route-8805a20e15762c3c.js +1 -0
  290. package/dist/web/standalone/.next/static/chunks/app/api/session/command/route-8805a20e15762c3c.js +1 -0
  291. package/dist/web/standalone/.next/static/chunks/app/api/session/events/route-8805a20e15762c3c.js +1 -0
  292. package/dist/web/standalone/.next/static/chunks/app/api/session/manage/route-8805a20e15762c3c.js +1 -0
  293. package/dist/web/standalone/.next/static/chunks/app/api/settings-data/route-8805a20e15762c3c.js +1 -0
  294. package/dist/web/standalone/.next/static/chunks/app/api/shutdown/route-8805a20e15762c3c.js +1 -0
  295. package/dist/web/standalone/.next/static/chunks/app/api/skill-health/route-8805a20e15762c3c.js +1 -0
  296. package/dist/web/standalone/.next/static/chunks/app/api/steer/route-8805a20e15762c3c.js +1 -0
  297. package/dist/web/standalone/.next/static/chunks/app/api/switch-root/route-8805a20e15762c3c.js +1 -0
  298. package/dist/web/standalone/.next/static/chunks/app/api/terminal/input/route-8805a20e15762c3c.js +1 -0
  299. package/dist/web/standalone/.next/static/chunks/app/api/terminal/resize/route-8805a20e15762c3c.js +1 -0
  300. package/dist/web/standalone/.next/static/chunks/app/api/terminal/sessions/route-8805a20e15762c3c.js +1 -0
  301. package/dist/web/standalone/.next/static/chunks/app/api/terminal/stream/route-8805a20e15762c3c.js +1 -0
  302. package/dist/web/standalone/.next/static/chunks/app/api/terminal/upload/route-8805a20e15762c3c.js +1 -0
  303. package/dist/web/standalone/.next/static/chunks/app/api/undo/route-8805a20e15762c3c.js +1 -0
  304. package/dist/web/standalone/.next/static/chunks/app/api/update/route-8805a20e15762c3c.js +1 -0
  305. package/dist/web/standalone/.next/static/chunks/app/api/visualizer/route-8805a20e15762c3c.js +1 -0
  306. package/dist/web/standalone/.next/static/chunks/app/{layout-9ecfd95f343793f0.js → layout-a16c7a7ecdf0c2cf.js} +1 -1
  307. package/dist/web/standalone/.next/static/chunks/app/page-0c485498795110d6.js +1 -0
  308. package/dist/web/standalone/.next/static/chunks/main-app-fdab67f7802d7832.js +1 -0
  309. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/app-error-8805a20e15762c3c.js +1 -0
  310. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/forbidden-8805a20e15762c3c.js +1 -0
  311. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +1 -0
  312. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/not-found-8805a20e15762c3c.js +1 -0
  313. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/unauthorized-8805a20e15762c3c.js +1 -0
  314. package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
  315. package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
  316. package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
  317. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api.target.mk +14 -14
  318. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_except.target.mk +14 -14
  319. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_maybe.target.mk +14 -14
  320. package/dist/web/standalone/server.js +1 -1
  321. package/dist/welcome-screen.js +1 -1
  322. package/package.json +1 -1
  323. package/packages/pi-agent-core/dist/agent-loop.d.ts +8 -0
  324. package/packages/pi-agent-core/dist/agent-loop.d.ts.map +1 -1
  325. package/packages/pi-agent-core/dist/agent-loop.js +70 -3
  326. package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
  327. package/packages/pi-agent-core/src/agent-loop.test.ts +317 -5
  328. package/packages/pi-agent-core/src/agent-loop.ts +90 -6
  329. package/packages/pi-ai/dist/types.d.ts +16 -1
  330. package/packages/pi-ai/dist/types.d.ts.map +1 -1
  331. package/packages/pi-ai/dist/types.js.map +1 -1
  332. package/packages/pi-ai/src/types.ts +18 -1
  333. package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.d.ts +2 -0
  334. package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.d.ts.map +1 -0
  335. package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.js +38 -0
  336. package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.js.map +1 -0
  337. package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
  338. package/packages/pi-coding-agent/dist/core/agent-session.js +11 -0
  339. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  340. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts +9 -0
  341. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts.map +1 -1
  342. package/packages/pi-coding-agent/dist/core/auth-storage.js +50 -1
  343. package/packages/pi-coding-agent/dist/core/auth-storage.js.map +1 -1
  344. package/packages/pi-coding-agent/dist/core/auth-storage.test.js +41 -0
  345. package/packages/pi-coding-agent/dist/core/auth-storage.test.js.map +1 -1
  346. package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts +7 -0
  347. package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
  348. package/packages/pi-coding-agent/dist/core/extensions/loader.js +31 -4
  349. package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
  350. package/packages/pi-coding-agent/dist/core/extensions/loader.test.js +28 -1
  351. package/packages/pi-coding-agent/dist/core/extensions/loader.test.js.map +1 -1
  352. package/packages/pi-coding-agent/dist/core/extensions/provider-registration.test.d.ts +2 -0
  353. package/packages/pi-coding-agent/dist/core/extensions/provider-registration.test.d.ts.map +1 -0
  354. package/packages/pi-coding-agent/dist/core/extensions/provider-registration.test.js +46 -0
  355. package/packages/pi-coding-agent/dist/core/extensions/provider-registration.test.js.map +1 -0
  356. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts +2 -0
  357. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts.map +1 -1
  358. package/packages/pi-coding-agent/dist/core/extensions/types.js.map +1 -1
  359. package/packages/pi-coding-agent/dist/core/model-registry.d.ts +1 -0
  360. package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
  361. package/packages/pi-coding-agent/dist/core/model-registry.js +12 -0
  362. package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
  363. package/packages/pi-coding-agent/dist/core/model-resolver.js +3 -3
  364. package/packages/pi-coding-agent/dist/core/model-resolver.js.map +1 -1
  365. package/packages/pi-coding-agent/dist/core/resource-loader-cache-reset.test.d.ts +2 -0
  366. package/packages/pi-coding-agent/dist/core/resource-loader-cache-reset.test.d.ts.map +1 -0
  367. package/packages/pi-coding-agent/dist/core/resource-loader-cache-reset.test.js +24 -0
  368. package/packages/pi-coding-agent/dist/core/resource-loader-cache-reset.test.js.map +1 -0
  369. package/packages/pi-coding-agent/dist/core/resource-loader.d.ts +23 -1
  370. package/packages/pi-coding-agent/dist/core/resource-loader.d.ts.map +1 -1
  371. package/packages/pi-coding-agent/dist/core/resource-loader.js +84 -57
  372. package/packages/pi-coding-agent/dist/core/resource-loader.js.map +1 -1
  373. package/packages/pi-coding-agent/dist/core/sdk.d.ts.map +1 -1
  374. package/packages/pi-coding-agent/dist/core/sdk.js +9 -0
  375. package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
  376. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts +1 -0
  377. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  378. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +8 -0
  379. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
  380. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +6 -0
  381. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  382. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +36 -0
  383. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  384. package/packages/pi-coding-agent/package.json +1 -1
  385. package/packages/pi-coding-agent/src/core/agent-session-tool-refresh.test.ts +64 -0
  386. package/packages/pi-coding-agent/src/core/agent-session.ts +10 -0
  387. package/packages/pi-coding-agent/src/core/auth-storage.test.ts +53 -0
  388. package/packages/pi-coding-agent/src/core/auth-storage.ts +66 -1
  389. package/packages/pi-coding-agent/src/core/extensions/loader.test.ts +39 -1
  390. package/packages/pi-coding-agent/src/core/extensions/loader.ts +34 -4
  391. package/packages/pi-coding-agent/src/core/extensions/provider-registration.test.ts +81 -0
  392. package/packages/pi-coding-agent/src/core/extensions/types.ts +2 -0
  393. package/packages/pi-coding-agent/src/core/model-registry.ts +14 -0
  394. package/packages/pi-coding-agent/src/core/model-resolver.ts +3 -3
  395. package/packages/pi-coding-agent/src/core/resource-loader-cache-reset.test.ts +42 -0
  396. package/packages/pi-coding-agent/src/core/resource-loader.ts +94 -57
  397. package/packages/pi-coding-agent/src/core/sdk.ts +10 -0
  398. package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +9 -0
  399. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +33 -0
  400. package/packages/pi-tui/dist/components/loader.d.ts +4 -2
  401. package/packages/pi-tui/dist/components/loader.d.ts.map +1 -1
  402. package/packages/pi-tui/dist/components/loader.js +27 -9
  403. package/packages/pi-tui/dist/components/loader.js.map +1 -1
  404. package/packages/pi-tui/dist/components/text.d.ts.map +1 -1
  405. package/packages/pi-tui/dist/components/text.js +2 -0
  406. package/packages/pi-tui/dist/components/text.js.map +1 -1
  407. package/packages/pi-tui/dist/tui.d.ts +2 -0
  408. package/packages/pi-tui/dist/tui.d.ts.map +1 -1
  409. package/packages/pi-tui/dist/tui.js +35 -0
  410. package/packages/pi-tui/dist/tui.js.map +1 -1
  411. package/packages/pi-tui/src/components/loader.ts +27 -10
  412. package/packages/pi-tui/src/components/text.ts +1 -0
  413. package/packages/pi-tui/src/tui.ts +32 -0
  414. package/pkg/package.json +1 -1
  415. package/src/resources/extensions/bg-shell/bg-shell-lifecycle.ts +19 -7
  416. package/src/resources/extensions/bg-shell/process-manager.ts +8 -2
  417. package/src/resources/extensions/cmux/index.ts +18 -12
  418. package/src/resources/extensions/gsd/auto/detect-stuck.ts +27 -0
  419. package/src/resources/extensions/gsd/auto/finalize-timeout.ts +46 -0
  420. package/src/resources/extensions/gsd/auto/loop.ts +5 -0
  421. package/src/resources/extensions/gsd/auto/phases.ts +194 -33
  422. package/src/resources/extensions/gsd/auto/session.ts +14 -0
  423. package/src/resources/extensions/gsd/auto-dashboard.ts +16 -7
  424. package/src/resources/extensions/gsd/auto-model-selection.ts +36 -0
  425. package/src/resources/extensions/gsd/auto-post-unit.ts +263 -12
  426. package/src/resources/extensions/gsd/auto-prompts.ts +21 -0
  427. package/src/resources/extensions/gsd/auto-recovery.ts +9 -8
  428. package/src/resources/extensions/gsd/auto-start.ts +11 -20
  429. package/src/resources/extensions/gsd/auto-timers.ts +2 -1
  430. package/src/resources/extensions/gsd/auto-tool-tracking.ts +19 -0
  431. package/src/resources/extensions/gsd/auto-verification.ts +190 -2
  432. package/src/resources/extensions/gsd/auto-worktree.ts +14 -6
  433. package/src/resources/extensions/gsd/auto.ts +26 -1
  434. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +172 -88
  435. package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +15 -0
  436. package/src/resources/extensions/gsd/bootstrap/notify-interceptor.ts +34 -0
  437. package/src/resources/extensions/gsd/bootstrap/query-tools.ts +98 -0
  438. package/src/resources/extensions/gsd/bootstrap/register-extension.ts +4 -0
  439. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +44 -1
  440. package/src/resources/extensions/gsd/bootstrap/register-shortcuts.ts +19 -0
  441. package/src/resources/extensions/gsd/bootstrap/sanitize-complete-milestone.ts +57 -0
  442. package/src/resources/extensions/gsd/bootstrap/system-context.ts +59 -2
  443. package/src/resources/extensions/gsd/commands/catalog.ts +7 -1
  444. package/src/resources/extensions/gsd/commands/handlers/core.ts +1 -0
  445. package/src/resources/extensions/gsd/commands/handlers/notifications-handler.ts +139 -0
  446. package/src/resources/extensions/gsd/commands/handlers/ops.ts +5 -0
  447. package/src/resources/extensions/gsd/commands-handlers.ts +10 -4
  448. package/src/resources/extensions/gsd/constants.ts +44 -0
  449. package/src/resources/extensions/gsd/db-writer.ts +78 -4
  450. package/src/resources/extensions/gsd/forensics.ts +21 -5
  451. package/src/resources/extensions/gsd/gsd-db.ts +64 -17
  452. package/src/resources/extensions/gsd/guided-flow.ts +22 -0
  453. package/src/resources/extensions/gsd/metrics.ts +28 -1
  454. package/src/resources/extensions/gsd/native-git-bridge.ts +5 -3
  455. package/src/resources/extensions/gsd/notification-overlay.ts +267 -0
  456. package/src/resources/extensions/gsd/notification-store.ts +288 -0
  457. package/src/resources/extensions/gsd/notification-widget.ts +68 -0
  458. package/src/resources/extensions/gsd/post-execution-checks.ts +539 -0
  459. package/src/resources/extensions/gsd/pre-execution-checks.ts +573 -0
  460. package/src/resources/extensions/gsd/preferences-types.ts +44 -0
  461. package/src/resources/extensions/gsd/preferences-validation.ts +33 -0
  462. package/src/resources/extensions/gsd/preferences.ts +13 -2
  463. package/src/resources/extensions/gsd/prompt-loader.ts +8 -0
  464. package/src/resources/extensions/gsd/prompts/complete-milestone.md +2 -0
  465. package/src/resources/extensions/gsd/prompts/complete-slice.md +2 -0
  466. package/src/resources/extensions/gsd/prompts/doctor-heal.md +1 -0
  467. package/src/resources/extensions/gsd/prompts/forensics.md +2 -0
  468. package/src/resources/extensions/gsd/prompts/reassess-roadmap.md +2 -0
  469. package/src/resources/extensions/gsd/prompts/system.md +4 -7
  470. package/src/resources/extensions/gsd/prompts/validate-milestone.md +2 -0
  471. package/src/resources/extensions/gsd/roadmap-mutations.ts +1 -1
  472. package/src/resources/extensions/gsd/roadmap-slices.ts +10 -5
  473. package/src/resources/extensions/gsd/safety/content-validator.ts +98 -0
  474. package/src/resources/extensions/gsd/safety/destructive-guard.ts +49 -0
  475. package/src/resources/extensions/gsd/safety/evidence-collector.ts +151 -0
  476. package/src/resources/extensions/gsd/safety/evidence-cross-ref.ts +120 -0
  477. package/src/resources/extensions/gsd/safety/file-change-validator.ts +108 -0
  478. package/src/resources/extensions/gsd/safety/git-checkpoint.ts +106 -0
  479. package/src/resources/extensions/gsd/safety/safety-harness.ts +105 -0
  480. package/src/resources/extensions/gsd/slice-parallel-conflict.ts +86 -0
  481. package/src/resources/extensions/gsd/slice-parallel-eligibility.ts +73 -0
  482. package/src/resources/extensions/gsd/slice-parallel-orchestrator.ts +477 -0
  483. package/src/resources/extensions/gsd/state.ts +67 -12
  484. package/src/resources/extensions/gsd/status-guards.ts +13 -0
  485. package/src/resources/extensions/gsd/tests/artifact-corruption-2630.test.ts +288 -0
  486. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +34 -13
  487. package/src/resources/extensions/gsd/tests/auto-start-time-persistence.test.ts +50 -0
  488. package/src/resources/extensions/gsd/tests/cmux.test.ts +58 -0
  489. package/src/resources/extensions/gsd/tests/cold-resume-db-reopen.test.ts +51 -0
  490. package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +140 -0
  491. package/src/resources/extensions/gsd/tests/complete-slice-string-coercion.test.ts +247 -0
  492. package/src/resources/extensions/gsd/tests/complete-task.test.ts +39 -0
  493. package/src/resources/extensions/gsd/tests/dashboard-model-label-ordering.test.ts +107 -0
  494. package/src/resources/extensions/gsd/tests/db-access-guardrails.test.ts +109 -0
  495. package/src/resources/extensions/gsd/tests/db-path-worktree-symlink.test.ts +13 -9
  496. package/src/resources/extensions/gsd/tests/db-writer.test.ts +134 -0
  497. package/src/resources/extensions/gsd/tests/deferred-slice-dispatch.test.ts +203 -0
  498. package/src/resources/extensions/gsd/tests/discuss-tool-scope-leak.test.ts +76 -0
  499. package/src/resources/extensions/gsd/tests/discuss-tool-scoping.test.ts +130 -0
  500. package/src/resources/extensions/gsd/tests/doctor-fix-flag.test.ts +92 -0
  501. package/src/resources/extensions/gsd/tests/enhanced-verification-integration.test.ts +526 -0
  502. package/src/resources/extensions/gsd/tests/finalize-timeout-guard.test.ts +116 -0
  503. package/src/resources/extensions/gsd/tests/flat-rate-routing-guard.test.ts +50 -0
  504. package/src/resources/extensions/gsd/tests/forensics-stuck-loops.test.ts +103 -0
  505. package/src/resources/extensions/gsd/tests/git-checkpoint.test.ts +94 -0
  506. package/src/resources/extensions/gsd/tests/insert-slice-no-wipe.test.ts +88 -0
  507. package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +27 -7
  508. package/src/resources/extensions/gsd/tests/integration/idle-recovery.test.ts +34 -0
  509. package/src/resources/extensions/gsd/tests/metrics.test.ts +116 -1
  510. package/src/resources/extensions/gsd/tests/milestone-status-tool.test.ts +201 -0
  511. package/src/resources/extensions/gsd/tests/notification-store.test.ts +249 -0
  512. package/src/resources/extensions/gsd/tests/plan-milestone-title.test.ts +2 -1
  513. package/src/resources/extensions/gsd/tests/plan-milestone.test.ts +82 -18
  514. package/src/resources/extensions/gsd/tests/post-exec-retry-bypass.test.ts +312 -0
  515. package/src/resources/extensions/gsd/tests/post-execution-checks.test.ts +813 -0
  516. package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +999 -0
  517. package/src/resources/extensions/gsd/tests/pre-execution-fail-closed.test.ts +266 -0
  518. package/src/resources/extensions/gsd/tests/pre-execution-pause-wiring.test.ts +457 -0
  519. package/src/resources/extensions/gsd/tests/preferences.test.ts +10 -0
  520. package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +25 -0
  521. package/src/resources/extensions/gsd/tests/roadmap-slices.test.ts +69 -0
  522. package/src/resources/extensions/gsd/tests/shared-wal.test.ts +30 -0
  523. package/src/resources/extensions/gsd/tests/slice-context-injection.test.ts +50 -0
  524. package/src/resources/extensions/gsd/tests/slice-parallel-conflict.test.ts +92 -0
  525. package/src/resources/extensions/gsd/tests/slice-parallel-eligibility.test.ts +95 -0
  526. package/src/resources/extensions/gsd/tests/slice-parallel-orchestrator.test.ts +83 -0
  527. package/src/resources/extensions/gsd/tests/stuck-detection-coverage.test.ts +42 -0
  528. package/src/resources/extensions/gsd/tests/tool-invocation-error-loop-break.test.ts +103 -0
  529. package/src/resources/extensions/gsd/tests/tool-param-optionality.test.ts +349 -0
  530. package/src/resources/extensions/gsd/tests/unstructured-continue-context-injection.test.ts +163 -0
  531. package/src/resources/extensions/gsd/tests/worktree-health-dispatch.test.ts +35 -2
  532. package/src/resources/extensions/gsd/tests/worktree-health-monorepo.test.ts +73 -0
  533. package/src/resources/extensions/gsd/tests/worktree-resolver.test.ts +34 -0
  534. package/src/resources/extensions/gsd/tests/worktree-submodule-safety.test.ts +1 -1
  535. package/src/resources/extensions/gsd/tests/worktree-teardown-safety.test.ts +148 -0
  536. package/src/resources/extensions/gsd/tools/complete-milestone.ts +34 -20
  537. package/src/resources/extensions/gsd/tools/complete-slice.ts +41 -26
  538. package/src/resources/extensions/gsd/tools/complete-task.ts +12 -12
  539. package/src/resources/extensions/gsd/tools/plan-milestone.ts +55 -30
  540. package/src/resources/extensions/gsd/tools/plan-slice.ts +13 -8
  541. package/src/resources/extensions/gsd/types.ts +44 -22
  542. package/src/resources/extensions/gsd/verification-evidence.ts +68 -0
  543. package/src/resources/extensions/gsd/workflow-logger.ts +15 -1
  544. package/src/resources/extensions/gsd/workflow-projections.ts +23 -5
  545. package/src/resources/extensions/gsd/worktree-manager.ts +76 -28
  546. package/src/resources/extensions/gsd/worktree-resolver.ts +4 -3
  547. package/src/resources/extensions/mcp-client/auth.ts +149 -0
  548. package/src/resources/extensions/mcp-client/index.ts +16 -1
  549. package/src/resources/extensions/ollama/index.ts +26 -25
  550. package/src/resources/extensions/ollama/model-capabilities.ts +41 -34
  551. package/src/resources/extensions/ollama/ndjson-stream.ts +63 -0
  552. package/src/resources/extensions/ollama/ollama-auth-mode.test.ts +20 -0
  553. package/src/resources/extensions/ollama/ollama-chat-provider.ts +459 -0
  554. package/src/resources/extensions/ollama/ollama-client.ts +30 -30
  555. package/src/resources/extensions/ollama/ollama-discovery.ts +5 -8
  556. package/src/resources/extensions/ollama/ollama-tool.ts +69 -0
  557. package/src/resources/extensions/ollama/tests/ollama-chat-provider-stream.test.ts +82 -0
  558. package/src/resources/extensions/ollama/tests/ollama-discovery.test.ts +0 -27
  559. package/src/resources/extensions/ollama/thinking-parser.ts +116 -0
  560. package/src/resources/extensions/ollama/types.ts +23 -0
  561. package/dist/web/standalone/.next/server/chunks/2229.js +0 -12
  562. package/dist/web/standalone/.next/static/5FLUBNdqolRyyehCyChPd/_buildManifest.js +0 -1
  563. package/dist/web/standalone/.next/static/chunks/app/_global-error/page-c4cc189e7b117ea2.js +0 -1
  564. package/dist/web/standalone/.next/static/chunks/app/api/boot/route-c4cc189e7b117ea2.js +0 -1
  565. package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/input/route-c4cc189e7b117ea2.js +0 -1
  566. package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/resize/route-c4cc189e7b117ea2.js +0 -1
  567. package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/stream/route-c4cc189e7b117ea2.js +0 -1
  568. package/dist/web/standalone/.next/static/chunks/app/api/browse-directories/route-c4cc189e7b117ea2.js +0 -1
  569. package/dist/web/standalone/.next/static/chunks/app/api/captures/route-c4cc189e7b117ea2.js +0 -1
  570. package/dist/web/standalone/.next/static/chunks/app/api/cleanup/route-c4cc189e7b117ea2.js +0 -1
  571. package/dist/web/standalone/.next/static/chunks/app/api/dev-mode/route-c4cc189e7b117ea2.js +0 -1
  572. package/dist/web/standalone/.next/static/chunks/app/api/doctor/route-c4cc189e7b117ea2.js +0 -1
  573. package/dist/web/standalone/.next/static/chunks/app/api/experimental/route-c4cc189e7b117ea2.js +0 -1
  574. package/dist/web/standalone/.next/static/chunks/app/api/export-data/route-c4cc189e7b117ea2.js +0 -1
  575. package/dist/web/standalone/.next/static/chunks/app/api/files/route-c4cc189e7b117ea2.js +0 -1
  576. package/dist/web/standalone/.next/static/chunks/app/api/forensics/route-c4cc189e7b117ea2.js +0 -1
  577. package/dist/web/standalone/.next/static/chunks/app/api/git/route-c4cc189e7b117ea2.js +0 -1
  578. package/dist/web/standalone/.next/static/chunks/app/api/history/route-c4cc189e7b117ea2.js +0 -1
  579. package/dist/web/standalone/.next/static/chunks/app/api/hooks/route-c4cc189e7b117ea2.js +0 -1
  580. package/dist/web/standalone/.next/static/chunks/app/api/inspect/route-c4cc189e7b117ea2.js +0 -1
  581. package/dist/web/standalone/.next/static/chunks/app/api/knowledge/route-c4cc189e7b117ea2.js +0 -1
  582. package/dist/web/standalone/.next/static/chunks/app/api/live-state/route-c4cc189e7b117ea2.js +0 -1
  583. package/dist/web/standalone/.next/static/chunks/app/api/onboarding/route-c4cc189e7b117ea2.js +0 -1
  584. package/dist/web/standalone/.next/static/chunks/app/api/preferences/route-c4cc189e7b117ea2.js +0 -1
  585. package/dist/web/standalone/.next/static/chunks/app/api/projects/route-c4cc189e7b117ea2.js +0 -1
  586. package/dist/web/standalone/.next/static/chunks/app/api/recovery/route-c4cc189e7b117ea2.js +0 -1
  587. package/dist/web/standalone/.next/static/chunks/app/api/remote-questions/route-c4cc189e7b117ea2.js +0 -1
  588. package/dist/web/standalone/.next/static/chunks/app/api/session/browser/route-c4cc189e7b117ea2.js +0 -1
  589. package/dist/web/standalone/.next/static/chunks/app/api/session/command/route-c4cc189e7b117ea2.js +0 -1
  590. package/dist/web/standalone/.next/static/chunks/app/api/session/events/route-c4cc189e7b117ea2.js +0 -1
  591. package/dist/web/standalone/.next/static/chunks/app/api/session/manage/route-c4cc189e7b117ea2.js +0 -1
  592. package/dist/web/standalone/.next/static/chunks/app/api/settings-data/route-c4cc189e7b117ea2.js +0 -1
  593. package/dist/web/standalone/.next/static/chunks/app/api/shutdown/route-c4cc189e7b117ea2.js +0 -1
  594. package/dist/web/standalone/.next/static/chunks/app/api/skill-health/route-c4cc189e7b117ea2.js +0 -1
  595. package/dist/web/standalone/.next/static/chunks/app/api/steer/route-c4cc189e7b117ea2.js +0 -1
  596. package/dist/web/standalone/.next/static/chunks/app/api/switch-root/route-c4cc189e7b117ea2.js +0 -1
  597. package/dist/web/standalone/.next/static/chunks/app/api/terminal/input/route-c4cc189e7b117ea2.js +0 -1
  598. package/dist/web/standalone/.next/static/chunks/app/api/terminal/resize/route-c4cc189e7b117ea2.js +0 -1
  599. package/dist/web/standalone/.next/static/chunks/app/api/terminal/sessions/route-c4cc189e7b117ea2.js +0 -1
  600. package/dist/web/standalone/.next/static/chunks/app/api/terminal/stream/route-c4cc189e7b117ea2.js +0 -1
  601. package/dist/web/standalone/.next/static/chunks/app/api/terminal/upload/route-c4cc189e7b117ea2.js +0 -1
  602. package/dist/web/standalone/.next/static/chunks/app/api/undo/route-c4cc189e7b117ea2.js +0 -1
  603. package/dist/web/standalone/.next/static/chunks/app/api/update/route-c4cc189e7b117ea2.js +0 -1
  604. package/dist/web/standalone/.next/static/chunks/app/api/visualizer/route-c4cc189e7b117ea2.js +0 -1
  605. package/dist/web/standalone/.next/static/chunks/app/page-62be3b5fa91e4c8f.js +0 -1
  606. package/dist/web/standalone/.next/static/chunks/main-app-d3d4c336195465f9.js +0 -1
  607. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/app-error-c4cc189e7b117ea2.js +0 -1
  608. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/forbidden-c4cc189e7b117ea2.js +0 -1
  609. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ab5a8926e07ec673.js +0 -1
  610. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/not-found-c4cc189e7b117ea2.js +0 -1
  611. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/unauthorized-c4cc189e7b117ea2.js +0 -1
  612. /package/dist/web/standalone/.next/static/{5FLUBNdqolRyyehCyChPd → Vbx2-SrSBOgta6576xj9m}/_ssgManifest.js +0 -0
@@ -0,0 +1,349 @@
1
+ /**
2
+ * tool-param-optionality — Verifies that enrichment/metadata parameters on
3
+ * planning and completion tools are optional, not required.
4
+ *
5
+ * Models with limited tool-calling capability (e.g. kimi-k2.5, glm-5-turbo)
6
+ * cannot reliably populate 20+ top-level parameters in a single tool call.
7
+ * This test ensures that only the core identification and content parameters
8
+ * are required, while enrichment arrays (patterns, requirements, files, etc.)
9
+ * are optional — so any model can call the tool successfully.
10
+ *
11
+ * See: https://github.com/gsd-build/gsd-2/issues/2771
12
+ */
13
+
14
+ import { test } from "node:test";
15
+ import assert from "node:assert/strict";
16
+ import { registerDbTools } from "../bootstrap/db-tools.ts";
17
+ import { Value } from "@sinclair/typebox/value";
18
+
19
+ // ─── Mock PI ──────────────────────────────────────────────────────────────────
20
+
21
+ function makeMockPi() {
22
+ const tools: any[] = [];
23
+ return {
24
+ registerTool: (tool: any) => tools.push(tool),
25
+ tools,
26
+ } as any;
27
+ }
28
+
29
+ const pi = makeMockPi();
30
+ registerDbTools(pi);
31
+
32
+ function getTool(name: string) {
33
+ return pi.tools.find((t: any) => t.name === name);
34
+ }
35
+
36
+ // ─── Helper: count required top-level properties ─────────────────────────────
37
+
38
+ function getRequiredProps(tool: any): string[] {
39
+ const schema = tool.parameters;
40
+ return schema.required ?? [];
41
+ }
42
+
43
+ function getOptionalProps(tool: any): string[] {
44
+ const schema = tool.parameters;
45
+ const allProps = Object.keys(schema.properties ?? {});
46
+ const required = new Set(schema.required ?? []);
47
+ return allProps.filter((p: string) => !required.has(p));
48
+ }
49
+
50
+ // ─── gsd_slice_complete: enrichment arrays must be optional ──────────────────
51
+
52
+ test("gsd_slice_complete — enrichment arrays are optional", () => {
53
+ const tool = getTool("gsd_slice_complete");
54
+ assert.ok(tool, "gsd_slice_complete must be registered");
55
+
56
+ const required = new Set(getRequiredProps(tool));
57
+
58
+ // Core identification and content fields MUST be required
59
+ const coreRequired = [
60
+ "sliceId",
61
+ "milestoneId",
62
+ "sliceTitle",
63
+ "oneLiner",
64
+ "narrative",
65
+ "verification",
66
+ "uatContent",
67
+ ];
68
+ for (const field of coreRequired) {
69
+ assert.ok(required.has(field), `core field "${field}" must be required`);
70
+ }
71
+
72
+ // Enrichment/metadata arrays MUST be optional
73
+ const enrichmentFields = [
74
+ "keyFiles",
75
+ "keyDecisions",
76
+ "patternsEstablished",
77
+ "observabilitySurfaces",
78
+ "provides",
79
+ "requirementsSurfaced",
80
+ "drillDownPaths",
81
+ "affects",
82
+ "requirementsAdvanced",
83
+ "requirementsValidated",
84
+ "requirementsInvalidated",
85
+ "filesModified",
86
+ "requires",
87
+ "deviations",
88
+ "knownLimitations",
89
+ "followUps",
90
+ ];
91
+ for (const field of enrichmentFields) {
92
+ assert.ok(!required.has(field), `enrichment field "${field}" must be optional, not required`);
93
+ }
94
+ });
95
+
96
+ test("gsd_slice_complete — validates with only core params", () => {
97
+ const tool = getTool("gsd_slice_complete");
98
+ assert.ok(tool, "gsd_slice_complete must be registered");
99
+
100
+ const minimalParams = {
101
+ sliceId: "S01",
102
+ milestoneId: "M001",
103
+ sliceTitle: "Test slice",
104
+ oneLiner: "Did the thing",
105
+ narrative: "We did it step by step.",
106
+ verification: "Tests pass.",
107
+ uatContent: "## UAT\n- [x] Works",
108
+ };
109
+
110
+ // Should pass schema validation with only core params
111
+ const errors = [...Value.Errors(tool.parameters, minimalParams)];
112
+ assert.strictEqual(errors.length, 0, `Minimal params should validate but got errors: ${errors.map(e => `${e.path}: ${e.message}`).join(", ")}`);
113
+ });
114
+
115
+ // ─── gsd_plan_milestone: enrichment arrays must be optional ──────────────────
116
+
117
+ test("gsd_plan_milestone — enrichment arrays are optional", () => {
118
+ const tool = getTool("gsd_plan_milestone");
119
+ assert.ok(tool, "gsd_plan_milestone must be registered");
120
+
121
+ const required = new Set(getRequiredProps(tool));
122
+
123
+ // Core fields
124
+ const coreRequired = ["milestoneId", "title", "vision", "slices"];
125
+ for (const field of coreRequired) {
126
+ assert.ok(required.has(field), `core field "${field}" must be required`);
127
+ }
128
+
129
+ // Enrichment fields must be optional
130
+ const enrichmentFields = [
131
+ "successCriteria",
132
+ "keyRisks",
133
+ "proofStrategy",
134
+ "verificationContract",
135
+ "verificationIntegration",
136
+ "verificationOperational",
137
+ "verificationUat",
138
+ "definitionOfDone",
139
+ "requirementCoverage",
140
+ "boundaryMapMarkdown",
141
+ ];
142
+ for (const field of enrichmentFields) {
143
+ assert.ok(!required.has(field), `enrichment field "${field}" must be optional, not required`);
144
+ }
145
+ });
146
+
147
+ test("gsd_plan_milestone — validates with only core params", () => {
148
+ const tool = getTool("gsd_plan_milestone");
149
+ assert.ok(tool, "gsd_plan_milestone must be registered");
150
+
151
+ const minimalParams = {
152
+ milestoneId: "M001",
153
+ title: "Test milestone",
154
+ vision: "Build the thing.",
155
+ slices: [
156
+ {
157
+ sliceId: "S01",
158
+ title: "First slice",
159
+ risk: "Low",
160
+ depends: [],
161
+ demo: "After this, X works",
162
+ goal: "Set up X",
163
+ successCriteria: "X is set up",
164
+ proofLevel: "unit-tests",
165
+ integrationClosure: "N/A",
166
+ observabilityImpact: "None",
167
+ },
168
+ ],
169
+ };
170
+
171
+ const errors = [...Value.Errors(tool.parameters, minimalParams)];
172
+ assert.strictEqual(errors.length, 0, `Minimal params should validate but got errors: ${errors.map(e => `${e.path}: ${e.message}`).join(", ")}`);
173
+ });
174
+
175
+ // ─── gsd_task_complete: enrichment arrays must be optional ───────────────────
176
+
177
+ test("gsd_task_complete — enrichment arrays are optional", () => {
178
+ const tool = getTool("gsd_task_complete");
179
+ assert.ok(tool, "gsd_task_complete must be registered");
180
+
181
+ const required = new Set(getRequiredProps(tool));
182
+
183
+ // Core fields
184
+ const coreRequired = [
185
+ "taskId",
186
+ "sliceId",
187
+ "milestoneId",
188
+ "oneLiner",
189
+ "narrative",
190
+ "verification",
191
+ ];
192
+ for (const field of coreRequired) {
193
+ assert.ok(required.has(field), `core field "${field}" must be required`);
194
+ }
195
+
196
+ // Enrichment fields must be optional
197
+ const enrichmentFields = [
198
+ "keyFiles",
199
+ "keyDecisions",
200
+ "deviations",
201
+ "knownIssues",
202
+ "blockerDiscovered",
203
+ "verificationEvidence",
204
+ ];
205
+ for (const field of enrichmentFields) {
206
+ assert.ok(!required.has(field), `enrichment field "${field}" must be optional, not required`);
207
+ }
208
+ });
209
+
210
+ test("gsd_task_complete — validates with only core params", () => {
211
+ const tool = getTool("gsd_task_complete");
212
+ assert.ok(tool, "gsd_task_complete must be registered");
213
+
214
+ const minimalParams = {
215
+ taskId: "T01",
216
+ sliceId: "S01",
217
+ milestoneId: "M001",
218
+ oneLiner: "Implemented the feature",
219
+ narrative: "Created the module and wired it up.",
220
+ verification: "npm test passes.",
221
+ };
222
+
223
+ const errors = [...Value.Errors(tool.parameters, minimalParams)];
224
+ assert.strictEqual(errors.length, 0, `Minimal params should validate but got errors: ${errors.map(e => `${e.path}: ${e.message}`).join(", ")}`);
225
+ });
226
+
227
+ // ─── gsd_complete_milestone: enrichment arrays must be optional ──────────────
228
+
229
+ test("gsd_complete_milestone — enrichment arrays are optional", () => {
230
+ const tool = getTool("gsd_complete_milestone");
231
+ assert.ok(tool, "gsd_complete_milestone must be registered");
232
+
233
+ const required = new Set(getRequiredProps(tool));
234
+
235
+ // Core fields
236
+ const coreRequired = [
237
+ "milestoneId",
238
+ "title",
239
+ "oneLiner",
240
+ "narrative",
241
+ "verificationPassed",
242
+ ];
243
+ for (const field of coreRequired) {
244
+ assert.ok(required.has(field), `core field "${field}" must be required`);
245
+ }
246
+
247
+ // Enrichment fields must be optional
248
+ const enrichmentFields = [
249
+ "successCriteriaResults",
250
+ "definitionOfDoneResults",
251
+ "requirementOutcomes",
252
+ "keyDecisions",
253
+ "keyFiles",
254
+ "lessonsLearned",
255
+ ];
256
+ for (const field of enrichmentFields) {
257
+ assert.ok(!required.has(field), `enrichment field "${field}" must be optional, not required`);
258
+ }
259
+ });
260
+
261
+ test("gsd_complete_milestone — validates with only core params", () => {
262
+ const tool = getTool("gsd_complete_milestone");
263
+ assert.ok(tool, "gsd_complete_milestone must be registered");
264
+
265
+ const minimalParams = {
266
+ milestoneId: "M001",
267
+ title: "Test milestone",
268
+ oneLiner: "Finished it.",
269
+ narrative: "All work completed.",
270
+ verificationPassed: true,
271
+ };
272
+
273
+ const errors = [...Value.Errors(tool.parameters, minimalParams)];
274
+ assert.strictEqual(errors.length, 0, `Minimal params should validate but got errors: ${errors.map(e => `${e.path}: ${e.message}`).join(", ")}`);
275
+ });
276
+
277
+ // ─── gsd_plan_slice: enrichment fields must be optional ──────────────────────
278
+
279
+ test("gsd_plan_slice — enrichment fields are optional", () => {
280
+ const tool = getTool("gsd_plan_slice");
281
+ assert.ok(tool, "gsd_plan_slice must be registered");
282
+
283
+ const required = new Set(getRequiredProps(tool));
284
+
285
+ // Core fields
286
+ const coreRequired = ["milestoneId", "sliceId", "goal", "tasks"];
287
+ for (const field of coreRequired) {
288
+ assert.ok(required.has(field), `core field "${field}" must be required`);
289
+ }
290
+
291
+ // Enrichment fields
292
+ const enrichmentFields = [
293
+ "successCriteria",
294
+ "proofLevel",
295
+ "integrationClosure",
296
+ "observabilityImpact",
297
+ ];
298
+ for (const field of enrichmentFields) {
299
+ assert.ok(!required.has(field), `enrichment field "${field}" must be optional, not required`);
300
+ }
301
+ });
302
+
303
+ test("gsd_plan_slice — validates with only core params", () => {
304
+ const tool = getTool("gsd_plan_slice");
305
+ assert.ok(tool, "gsd_plan_slice must be registered");
306
+
307
+ const minimalParams = {
308
+ milestoneId: "M001",
309
+ sliceId: "S01",
310
+ goal: "Implement feature X",
311
+ tasks: [
312
+ {
313
+ taskId: "T01",
314
+ title: "Build X",
315
+ description: "Build the thing",
316
+ estimate: "2h",
317
+ files: ["src/x.ts"],
318
+ verify: "npm test",
319
+ inputs: [],
320
+ expectedOutput: ["src/x.ts"],
321
+ },
322
+ ],
323
+ };
324
+
325
+ const errors = [...Value.Errors(tool.parameters, minimalParams)];
326
+ assert.strictEqual(errors.length, 0, `Minimal params should validate but got errors: ${errors.map(e => `${e.path}: ${e.message}`).join(", ")}`);
327
+ });
328
+
329
+ // ─── Required param count ceiling ────────────────────────────────────────────
330
+
331
+ test("no planning/completion tool requires more than 10 top-level params", () => {
332
+ const heavyTools = [
333
+ "gsd_slice_complete",
334
+ "gsd_plan_milestone",
335
+ "gsd_task_complete",
336
+ "gsd_complete_milestone",
337
+ "gsd_plan_slice",
338
+ ];
339
+
340
+ for (const name of heavyTools) {
341
+ const tool = getTool(name);
342
+ assert.ok(tool, `${name} must be registered`);
343
+ const required = getRequiredProps(tool);
344
+ assert.ok(
345
+ required.length <= 10,
346
+ `${name} has ${required.length} required params (max 10) — required: ${required.join(", ")}`,
347
+ );
348
+ }
349
+ });
@@ -0,0 +1,163 @@
1
+ // GSD-2 — Regression test for #3615: unstructured "continue" must inject task context
2
+ // Copyright (c) 2026 Jeremy McSpadden <jeremy@fluxlabs.net>
3
+
4
+ /**
5
+ * Bug #3615: When a user types "continue" (or any bare text) to resume
6
+ * an in-progress session, buildGuidedExecuteContextInjection() only
7
+ * matched two hardcoded regex patterns (auto-dispatch and guided-resume).
8
+ * The function returned null for any other input, so no task context was
9
+ * injected — causing the agent to rebuild everything from scratch and
10
+ * burn ~86k tokens.
11
+ *
12
+ * This test verifies:
13
+ * 1. Structural: the fallback exists with phase + intent guards
14
+ * 2. Behavioral: RESUME_INTENT_PATTERNS matches expected prompts and
15
+ * rejects non-resume prompts (control, help, diagnostic, etc.)
16
+ */
17
+
18
+ import { describe, test } from "node:test";
19
+ import assert from "node:assert/strict";
20
+ import { readFileSync } from "node:fs";
21
+ import { join, dirname } from "node:path";
22
+ import { fileURLToPath } from "node:url";
23
+
24
+ const __dirname = dirname(fileURLToPath(import.meta.url));
25
+ const systemContextSource = readFileSync(
26
+ join(__dirname, "..", "bootstrap", "system-context.ts"),
27
+ "utf-8",
28
+ );
29
+
30
+ // ── Structural tests ────────────────────────────────────────────────
31
+
32
+ describe("#3615 — structural: fallback exists with correct guards", () => {
33
+ const fnStart = systemContextSource.indexOf("async function buildGuidedExecuteContextInjection(");
34
+ assert.ok(fnStart >= 0, "should find buildGuidedExecuteContextInjection");
35
+ const fnEnd = systemContextSource.indexOf("\nasync function ", fnStart + 1);
36
+ const fnBody = fnEnd >= 0
37
+ ? systemContextSource.slice(fnStart, fnEnd)
38
+ : systemContextSource.slice(fnStart);
39
+
40
+ test("has a deriveState fallback after the two regex branches", () => {
41
+ const deriveStateCalls = fnBody.match(/deriveState\(basePath\)/g);
42
+ assert.ok(
43
+ deriveStateCalls && deriveStateCalls.length >= 2,
44
+ `expected >=2 deriveState(basePath) calls, got ${deriveStateCalls?.length ?? 0}`,
45
+ );
46
+ });
47
+
48
+ test("fallback is phase-gated to executing only", () => {
49
+ const afterFallback = fnBody.indexOf("// Fallback:");
50
+ assert.ok(afterFallback >= 0, "should have a fallback comment");
51
+ const fallbackSection = fnBody.slice(afterFallback);
52
+ assert.ok(
53
+ fallbackSection.includes('state.phase === "executing"'),
54
+ 'fallback must be gated on state.phase === "executing"',
55
+ );
56
+ });
57
+
58
+ test("fallback is intent-gated via RESUME_INTENT_PATTERNS", () => {
59
+ const afterFallback = fnBody.indexOf("// Fallback:");
60
+ const fallbackSection = fnBody.slice(afterFallback);
61
+ assert.ok(
62
+ fallbackSection.includes("RESUME_INTENT_PATTERNS"),
63
+ "fallback must check RESUME_INTENT_PATTERNS before deriveState",
64
+ );
65
+ });
66
+
67
+ test("fallback calls buildTaskExecutionContextInjection with derived state", () => {
68
+ const afterFallback = fnBody.indexOf("// Fallback:");
69
+ const fallbackSection = fnBody.slice(afterFallback);
70
+ assert.ok(
71
+ fallbackSection.includes("buildTaskExecutionContextInjection") &&
72
+ fallbackSection.includes("state.activeMilestone.id") &&
73
+ fallbackSection.includes("state.activeSlice.id") &&
74
+ fallbackSection.includes("state.activeTask.id"),
75
+ "fallback must call buildTaskExecutionContextInjection with state-derived IDs",
76
+ );
77
+ });
78
+
79
+ test("only one return null at the end", () => {
80
+ const returnNulls = fnBody.match(/return null;/g);
81
+ assert.ok(
82
+ returnNulls && returnNulls.length === 1,
83
+ `expected exactly 1 'return null' (at end after fallback), got ${returnNulls?.length ?? 0}`,
84
+ );
85
+ });
86
+ });
87
+
88
+ // ── Behavioral tests: RESUME_INTENT_PATTERNS ────────────────────────
89
+
90
+ describe("#3615 — behavioral: RESUME_INTENT_PATTERNS matches resume prompts", () => {
91
+ // Extract the regex from source so the test stays in sync
92
+ const patternMatch = systemContextSource.match(/const RESUME_INTENT_PATTERNS\s*=\s*\/(.+)\/;/);
93
+ assert.ok(patternMatch, "should find RESUME_INTENT_PATTERNS definition");
94
+ const pattern = new RegExp(patternMatch[1]);
95
+
96
+ // Helper: normalize prompt the same way the production code does
97
+ const normalize = (s: string) => s.trim().toLowerCase().replace(/[.!?,]+$/g, "");
98
+
99
+ const shouldMatch = [
100
+ "continue",
101
+ "Continue",
102
+ "CONTINUE",
103
+ "continue.",
104
+ "continue!",
105
+ "resume",
106
+ "ok",
107
+ "OK",
108
+ "Ok!",
109
+ "go",
110
+ "go ahead",
111
+ "Go ahead.",
112
+ "proceed",
113
+ "keep going",
114
+ "carry on",
115
+ "next",
116
+ "yes",
117
+ "yeah",
118
+ "yep",
119
+ "sure",
120
+ "do it",
121
+ "let's go",
122
+ "pick up where you left off",
123
+ " continue ", // whitespace padded
124
+ ];
125
+
126
+ const shouldNotMatch = [
127
+ "help",
128
+ "status",
129
+ "/gsd auto",
130
+ "/gsd stats",
131
+ "what's the plan?",
132
+ "show me the logs",
133
+ "abort",
134
+ "stop",
135
+ "cancel",
136
+ "replan this slice",
137
+ "I think we should change the approach",
138
+ "can you explain what you just did?",
139
+ "run the tests",
140
+ "check the build",
141
+ "Execute the next task: T01",
142
+ "what files were changed",
143
+ "",
144
+ ];
145
+
146
+ for (const prompt of shouldMatch) {
147
+ test(`matches resume prompt: "${prompt}"`, () => {
148
+ assert.ok(
149
+ pattern.test(normalize(prompt)),
150
+ `expected RESUME_INTENT_PATTERNS to match "${prompt}" (normalized: "${normalize(prompt)}")`,
151
+ );
152
+ });
153
+ }
154
+
155
+ for (const prompt of shouldNotMatch) {
156
+ test(`rejects non-resume prompt: "${prompt}"`, () => {
157
+ assert.ok(
158
+ !pattern.test(normalize(prompt)),
159
+ `expected RESUME_INTENT_PATTERNS to NOT match "${prompt}" (normalized: "${normalize(prompt)}")`,
160
+ );
161
+ });
162
+ }
163
+ });
@@ -9,7 +9,7 @@
9
9
 
10
10
  import { describe, test, beforeEach, afterEach } from "node:test";
11
11
  import assert from "node:assert/strict";
12
- import { mkdtempSync, mkdirSync, writeFileSync, rmSync } from "node:fs";
12
+ import { mkdtempSync, mkdirSync, writeFileSync, rmSync, readdirSync } from "node:fs";
13
13
  import { join } from "node:path";
14
14
  import { tmpdir } from "node:os";
15
15
  import { execSync } from "node:child_process";
@@ -57,13 +57,20 @@ function hasRecognizedProjectFiles(basePath: string, existsSyncFn: (p: string) =
57
57
  return false;
58
58
  }
59
59
 
60
+ /** Simulate the phases.ts Xcode-bundle detection (readdirSync suffix scan). */
61
+ function hasXcodeBundle(basePath: string): boolean {
62
+ try {
63
+ return readdirSync(basePath).some((e) => e.endsWith(".xcodeproj") || e.endsWith(".xcworkspace"));
64
+ } catch { return false; }
65
+ }
66
+
60
67
  import { existsSync } from "node:fs";
61
68
 
62
69
  // ─── Tests ───────────────────────────────────────────────────────────────────
63
70
 
64
71
  test("PROJECT_FILES is exported and contains expected multi-ecosystem entries", () => {
65
72
  assert.ok(Array.isArray(PROJECT_FILES), "PROJECT_FILES is an array");
66
- assert.ok(PROJECT_FILES.length >= 17, `expected >= 17 entries, got ${PROJECT_FILES.length}`);
73
+ assert.ok(PROJECT_FILES.length >= 18, `expected >= 18 entries, got ${PROJECT_FILES.length}`);
67
74
  // Spot-check key ecosystems
68
75
  assert.ok(PROJECT_FILES.includes("Cargo.toml"), "includes Rust marker");
69
76
  assert.ok(PROJECT_FILES.includes("go.mod"), "includes Go marker");
@@ -140,3 +147,29 @@ describe("health check without git repo", () => {
140
147
  assert.ok(!wouldPassHealthCheck(dir, existsSync), "no-git directory should fail health check");
141
148
  });
142
149
  });
150
+
151
+ describe("health check with xcodegen and Xcode bundles", () => {
152
+ let dir: string;
153
+ beforeEach(() => { dir = createGitRepo(); });
154
+ afterEach(() => { rmSync(dir, { recursive: true, force: true }); });
155
+
156
+ test("health check passes for xcodegen project (project.yml, no Package.swift)", () => {
157
+ writeFileSync(join(dir, "project.yml"), "name: MyApp\ntargets:\n MyApp:\n type: application\n");
158
+ assert.ok(wouldPassHealthCheck(dir, existsSync), "xcodegen project should pass health check");
159
+ });
160
+
161
+ // Regression for the real-world failure in #1882: an iOS project with a
162
+ // project-specific Xcode bundle (Sudokuxyz.xcodeproj/) was blocked because
163
+ // PROJECT_FILES only probes exact filenames, not suffix-based directory names.
164
+ test("Xcode bundle (*.xcodeproj) is not in PROJECT_FILES but detected by suffix scan", () => {
165
+ mkdirSync(join(dir, "Sudokuxyz.xcodeproj"), { recursive: true });
166
+ mkdirSync(join(dir, "Sources", "Sudokuxyz"), { recursive: true });
167
+ writeFileSync(join(dir, "Sources", "Sudokuxyz", "ContentView.swift"), "import SwiftUI\n");
168
+ // PROJECT_FILES uses exact names — cannot match project-specific bundle names
169
+ assert.ok(!hasRecognizedProjectFiles(dir, existsSync), "xcodeproj bundle must NOT be in PROJECT_FILES");
170
+ // The readdirSync suffix scan used in phases.ts detects it
171
+ assert.ok(hasXcodeBundle(dir), "readdirSync suffix scan detects .xcodeproj bundle");
172
+ // Health check passes regardless (only requires .git)
173
+ assert.ok(wouldPassHealthCheck(dir, existsSync), "Xcode bundle project should pass health check");
174
+ });
175
+ });
@@ -0,0 +1,73 @@
1
+ /**
2
+ * worktree-health-monorepo.test.ts — #2347
3
+ *
4
+ * The worktree health check in auto/phases.ts falsely rejects monorepos
5
+ * where package.json (or other project markers) is in a parent directory.
6
+ * This test verifies that the health check walks parent directories.
7
+ */
8
+
9
+ import { readFileSync } from "node:fs";
10
+ import { join } from "node:path";
11
+ import { createTestContext } from "./test-helpers.ts";
12
+
13
+ const { assertTrue, report } = createTestContext();
14
+
15
+ const srcPath = join(import.meta.dirname, "..", "auto", "phases.ts");
16
+ const src = readFileSync(srcPath, "utf-8");
17
+
18
+ console.log("\n=== #2347: Worktree health check supports monorepos ===");
19
+
20
+ // ── Test 1: The health check region exists ──────────────────────────────
21
+
22
+ const healthCheckIdx = src.indexOf("Worktree health check");
23
+ assertTrue(healthCheckIdx > 0, "auto/phases.ts has worktree health check section");
24
+
25
+ const healthCheckRegion = src.slice(healthCheckIdx, healthCheckIdx + 2000);
26
+
27
+ // ── Test 2: The check walks parent directories for project markers ──────
28
+
29
+ // The fix should check parent directories for project files, not just s.basePath.
30
+ // Look for patterns like: walking up directories, dirname, parent, or a helper
31
+ // function that checks ancestors.
32
+ const checksParentDirs =
33
+ healthCheckRegion.includes("dirname") ||
34
+ healthCheckRegion.includes("parent") ||
35
+ healthCheckRegion.includes("ancestor") ||
36
+ healthCheckRegion.includes("walk") ||
37
+ // Or a helper function that's called with the base path
38
+ /hasProjectFileInAncestor|findProjectRoot|checkParent/i.test(healthCheckRegion);
39
+
40
+ assertTrue(
41
+ checksParentDirs,
42
+ "Health check should walk parent directories for project markers (monorepo support) (#2347)",
43
+ );
44
+
45
+ // ── Test 3: The parent walk stops at a .git boundary ──────────────────
46
+
47
+ // The parent directory walk must not escape the git repository root.
48
+ // Without this guard, ancestor directories like ~ or /usr/local that
49
+ // happen to contain package.json would cause false positive health checks.
50
+ const hasGitBoundary = healthCheckRegion.includes('.git') &&
51
+ (healthCheckRegion.includes('break') || healthCheckRegion.includes('stop'));
52
+
53
+ assertTrue(
54
+ hasGitBoundary,
55
+ "Parent directory walk must stop at .git repository boundary to prevent false positives",
56
+ );
57
+
58
+ // ── Test 4: The greenfield warning should only trigger when no parent has markers ─
59
+
60
+ // The original code was:
61
+ // const hasProjectFile = PROJECT_FILES.some((f) => deps.existsSync(join(s.basePath, f)));
62
+ // The fix should check parents too, so the greenfield warning only fires
63
+ // when NO ancestor directory has project markers either.
64
+ const hasParentCheck = healthCheckRegion.includes("parent") ||
65
+ healthCheckRegion.includes("dirname") ||
66
+ /ancestor|walk.*up/i.test(healthCheckRegion);
67
+
68
+ assertTrue(
69
+ hasParentCheck,
70
+ "Greenfield check should consider parent directories before warning (#2347)",
71
+ );
72
+
73
+ report();
@@ -550,6 +550,40 @@ test("mergeAndExit failure message tells user worktree and branch are preserved
550
550
  );
551
551
  });
552
552
 
553
+ test("mergeAndExit failure message references /gsd dispatch complete-milestone, not /complete-milestone (#1891)", () => {
554
+ // Regression test: the failure notification previously told users to
555
+ // "retry /complete-milestone" — a command that does not exist. The correct
556
+ // recovery command is "/gsd dispatch complete-milestone".
557
+ const s = makeSession({
558
+ basePath: "/project/.gsd/worktrees/M001",
559
+ originalBasePath: "/project",
560
+ });
561
+ const deps = makeDeps({
562
+ isInAutoWorktree: () => true,
563
+ getIsolationMode: () => "worktree",
564
+ mergeMilestoneToMain: () => {
565
+ throw new Error("dirty working tree");
566
+ },
567
+ });
568
+ const ctx = makeNotifyCtx();
569
+ const resolver = new WorktreeResolver(s, deps);
570
+
571
+ resolver.mergeAndExit("M001", ctx);
572
+
573
+ const warning = ctx.messages.find((m) => m.level === "warning");
574
+ assert.ok(warning, "a warning message is emitted");
575
+ // Must reference the correct dispatch command
576
+ assert.ok(
577
+ warning!.msg.includes("/gsd dispatch complete-milestone"),
578
+ "warning references /gsd dispatch complete-milestone, not bare /complete-milestone",
579
+ );
580
+ // Must NOT contain the bare (incorrect) command without the dispatch prefix
581
+ assert.ok(
582
+ !warning!.msg.match(/retry\s+\/complete-milestone(?!\S)/),
583
+ "warning must not reference the non-existent /complete-milestone command",
584
+ );
585
+ });
586
+
553
587
  // ─── mergeAndExit Tests (branch mode) ────────────────────────────────────────
554
588
 
555
589
  test("mergeAndExit in branch mode merges when on milestone branch", () => {