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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gsd/pi-coding-agent",
3
- "version": "2.63.0",
3
+ "version": "2.64.0",
4
4
  "description": "Coding agent CLI (vendored from pi-mono)",
5
5
  "type": "module",
6
6
  "piConfig": {
@@ -0,0 +1,64 @@
1
+ // GSD-2 — Regression tests for #3616: tool list persistence across newSession() calls
2
+ // Copyright (c) 2026 Jeremy McSpadden <jeremy@fluxlabs.net>
3
+
4
+ import test, { describe } from "node:test";
5
+ import assert from "node:assert/strict";
6
+ import { readFileSync } from "node:fs";
7
+ import { join } from "node:path";
8
+
9
+ const source = readFileSync(
10
+ join(process.cwd(), "packages/pi-coding-agent/src/core/agent-session.ts"),
11
+ "utf-8",
12
+ );
13
+
14
+ describe("#3616 — newSession() must restore full tool set", () => {
15
+ test("newSession() calls _refreshToolRegistry with includeAllExtensionTools when cwd is unchanged", () => {
16
+ // Find the newSession method
17
+ const newSessionStart = source.indexOf("async newSession(options?:");
18
+ assert.ok(newSessionStart >= 0, "should find newSession method");
19
+
20
+ // Get the method body (up to the next top-level method)
21
+ const methodBody = source.slice(newSessionStart, newSessionStart + 3000);
22
+
23
+ // Verify the cwd-changed branch rebuilds tools
24
+ assert.ok(
25
+ methodBody.includes("if (this._cwd !== previousCwd)"),
26
+ "should have cwd-change guard",
27
+ );
28
+
29
+ // Verify the else branch exists and refreshes tools with includeAllExtensionTools
30
+ const elseIdx = methodBody.indexOf("} else {");
31
+ assert.ok(elseIdx >= 0, "should have else branch for cwd-unchanged case");
32
+
33
+ const elseBranch = methodBody.slice(elseIdx, elseIdx + 800);
34
+ assert.ok(
35
+ elseBranch.includes("_refreshToolRegistry"),
36
+ "else branch should call _refreshToolRegistry",
37
+ );
38
+ assert.ok(
39
+ elseBranch.includes("includeAllExtensionTools: true"),
40
+ "else branch should pass includeAllExtensionTools: true to restore narrowed tools",
41
+ );
42
+ });
43
+
44
+ test("newSession() references #3616 in the else-branch comment", () => {
45
+ const idx = source.indexOf("#3616");
46
+ assert.ok(idx >= 0, "source should reference issue #3616 for the tool restore fix");
47
+ });
48
+
49
+ test("agent.reset() does not clear _state.tools (tools persist across reset)", () => {
50
+ // This is a structural invariant — if reset() starts clearing tools,
51
+ // the newSession() refresh becomes the only defense against tool loss.
52
+ const agentSource = readFileSync(
53
+ join(process.cwd(), "packages/pi-agent-core/src/agent.ts"),
54
+ "utf-8",
55
+ );
56
+ const resetStart = agentSource.indexOf("reset()");
57
+ assert.ok(resetStart >= 0, "should find reset() method");
58
+ const resetBody = agentSource.slice(resetStart, resetStart + 400);
59
+ assert.ok(
60
+ !resetBody.includes("tools"),
61
+ "reset() should NOT touch _state.tools — tools are managed by agent-session",
62
+ );
63
+ });
64
+ });
@@ -1577,6 +1577,16 @@ export class AgentSession {
1577
1577
  activeToolNames: this.getActiveToolNames(),
1578
1578
  includeAllExtensionTools: true,
1579
1579
  });
1580
+ } else {
1581
+ // Even when cwd hasn't changed, restore the full tool set (#3616).
1582
+ // Extensions (e.g., discuss flows) may narrow the active tool list
1583
+ // via setActiveTools() during a session. Without this refresh, the
1584
+ // narrowed set persists into the next session — causing tools like
1585
+ // gsd_plan_slice to be missing from auto-mode subagent sessions.
1586
+ this._refreshToolRegistry({
1587
+ activeToolNames: this.getActiveToolNames(),
1588
+ includeAllExtensionTools: true,
1589
+ });
1580
1590
  }
1581
1591
 
1582
1592
  // Run setup callback if provided (e.g., to append initial messages)
@@ -356,6 +356,59 @@ describe("AuthStorage — oauth credential for non-OAuth provider (#2083)", () =
356
356
  });
357
357
  });
358
358
 
359
+ // ─── Gemini CLI OAuth token detection ─────────────────────────────────────────
360
+
361
+ describe("AuthStorage — Gemini CLI OAuth token detection", () => {
362
+ it("rejects Google OAuth access token (ya29. prefix) stored as api_key for google provider", () => {
363
+ const storage = inMemory({});
364
+ assert.throws(
365
+ () => storage.set("google", makeKey("ya29.a0ARrdaM_fake_oauth_token_from_gemini_cli")),
366
+ (err: Error) => {
367
+ assert.ok(err.message.includes("OAuth access token"), `Expected message about OAuth token, got: ${err.message}`);
368
+ assert.ok(
369
+ err.message.includes("GEMINI_API_KEY") || err.message.includes("google-gemini-cli"),
370
+ `Expected guidance about GEMINI_API_KEY or google-gemini-cli, got: ${err.message}`,
371
+ );
372
+ return true;
373
+ },
374
+ );
375
+ });
376
+
377
+ it("rejects Google OAuth access token for google provider via getApiKey when set as env var", async () => {
378
+ const storage = inMemory({});
379
+ // Simulate runtime override with OAuth token
380
+ storage.setRuntimeApiKey("google", "ya29.c.b0AXv0zTPQ_fake_oauth_token");
381
+ const key = await storage.getApiKey("google");
382
+ // Should return undefined (blocked) or throw
383
+ assert.equal(key, undefined, "OAuth token should be blocked for google provider");
384
+ });
385
+
386
+ it("allows legitimate Google API keys (AIza prefix) for google provider", () => {
387
+ const storage = inMemory({});
388
+ storage.set("google", makeKey("AIzaSyD_fake_legitimate_api_key_here"));
389
+ const creds = storage.getCredentialsForProvider("google");
390
+ assert.equal(creds.length, 1);
391
+ });
392
+
393
+ it("allows ya29 tokens for google-gemini-cli provider (OAuth is expected there)", () => {
394
+ // google-gemini-cli stores OAuth credentials with type: "oauth", not "api_key"
395
+ // But if someone somehow stored an api_key, it shouldn't be blocked for OAuth providers
396
+ const storage = inMemory({});
397
+ storage.set("google-gemini-cli", makeKey("ya29.a0ARrdaM_token_for_gemini_cli"));
398
+ const creds = storage.getCredentialsForProvider("google-gemini-cli");
399
+ assert.equal(creds.length, 1);
400
+ });
401
+
402
+ it("rejects Google OAuth token (ya29. prefix) for openai provider that uses GEMINI_API_KEY indirectly", () => {
403
+ // Only google provider should be blocked, not others
404
+ const storage = inMemory({});
405
+ // This should NOT throw - other providers can have whatever keys they want
406
+ storage.set("openai", makeKey("ya29.some_value"));
407
+ const creds = storage.getCredentialsForProvider("openai");
408
+ assert.equal(creds.length, 1);
409
+ });
410
+ });
411
+
359
412
  // ─── getAll truncation ────────────────────────────────────────────────────────
360
413
 
361
414
  describe("AuthStorage — getAll()", () => {
@@ -34,6 +34,46 @@ export type OAuthCredential = {
34
34
 
35
35
  export type AuthCredential = ApiKeyCredential | OAuthCredential;
36
36
 
37
+ // ============================================================================
38
+ // Google OAuth token detection
39
+ // ============================================================================
40
+
41
+ /**
42
+ * Providers that use Google AI Studio API keys (not OAuth tokens).
43
+ * OAuth access tokens (ya29.*) are not valid API keys for these providers.
44
+ */
45
+ const GOOGLE_API_KEY_PROVIDERS = new Set(["google"]);
46
+
47
+ /**
48
+ * Detect if a string is a Google OAuth access token rather than an API key.
49
+ * Google OAuth access tokens start with "ya29." — these are issued by
50
+ * Google's OAuth2 token endpoint and are not valid as AI Studio API keys.
51
+ *
52
+ * Users who installed Google's Gemini CLI may have these tokens and
53
+ * mistakenly set them as GEMINI_API_KEY.
54
+ */
55
+ export function isGoogleOAuthToken(key: string): boolean {
56
+ return key.startsWith("ya29.");
57
+ }
58
+
59
+ /**
60
+ * Validate that an API key is not a Google OAuth token being used for
61
+ * a provider that requires actual API keys (e.g., Google AI Studio).
62
+ * Throws a descriptive error if the key appears to be an OAuth token.
63
+ */
64
+ function validateNotGoogleOAuthToken(provider: string, key: string): void {
65
+ if (GOOGLE_API_KEY_PROVIDERS.has(provider) && isGoogleOAuthToken(key)) {
66
+ throw new Error(
67
+ `The provided key for "${provider}" appears to be a Google OAuth access token (ya29.*), ` +
68
+ `not a valid API key. Google AI Studio requires an API key starting with "AIza...". ` +
69
+ `\n\nIf you're using Google's Gemini CLI, its OAuth tokens are not compatible. ` +
70
+ `Either:\n` +
71
+ ` 1. Get an API key from https://aistudio.google.com/apikey and set GEMINI_API_KEY\n` +
72
+ ` 2. Use '/login google-gemini-cli' to authenticate via Cloud Code Assist`,
73
+ );
74
+ }
75
+ }
76
+
37
77
  /**
38
78
  * On-disk format: each provider maps to a single credential or an array of credentials.
39
79
  * Single credentials are normalized to arrays at load time for internal use.
@@ -360,6 +400,9 @@ export class AuthStorage {
360
400
  */
361
401
  set(provider: string, credential: AuthCredential): void {
362
402
  if (credential.type === "api_key") {
403
+ // Block Google OAuth tokens being stored as API keys for AI Studio providers
404
+ validateNotGoogleOAuthToken(provider, credential.key);
405
+
363
406
  const existing = this.getCredentialsForProvider(provider);
364
407
  // Deduplicate: don't add if same key already exists
365
408
  const isDuplicate = existing.some(
@@ -762,6 +805,16 @@ export class AuthStorage {
762
805
  // Runtime override takes highest priority
763
806
  const runtimeKey = this.runtimeOverrides.get(providerId);
764
807
  if (runtimeKey) {
808
+ // Block Google OAuth tokens used as runtime API key overrides
809
+ if (GOOGLE_API_KEY_PROVIDERS.has(providerId) && isGoogleOAuthToken(runtimeKey)) {
810
+ this.recordError(
811
+ new Error(
812
+ `Blocked Google OAuth access token (ya29.*) for provider "${providerId}". ` +
813
+ `Use an API key from https://aistudio.google.com/apikey or '/login google-gemini-cli'.`,
814
+ ),
815
+ );
816
+ return undefined;
817
+ }
765
818
  return runtimeKey;
766
819
  }
767
820
 
@@ -780,7 +833,19 @@ export class AuthStorage {
780
833
 
781
834
  // Fall back to environment variable
782
835
  const envKey = getEnvApiKey(providerId);
783
- if (envKey) return envKey;
836
+ if (envKey) {
837
+ // Block Google OAuth tokens from environment variables (e.g., GEMINI_API_KEY=ya29.*)
838
+ if (GOOGLE_API_KEY_PROVIDERS.has(providerId) && isGoogleOAuthToken(envKey)) {
839
+ this.recordError(
840
+ new Error(
841
+ `GEMINI_API_KEY contains a Google OAuth access token (ya29.*), not an API key. ` +
842
+ `Get an API key from https://aistudio.google.com/apikey or use '/login google-gemini-cli'.`,
843
+ ),
844
+ );
845
+ return undefined;
846
+ }
847
+ return envKey;
848
+ }
784
849
 
785
850
  // Fall back to custom resolver (e.g., models.json custom providers)
786
851
  return this.fallbackResolver?.(providerId) ?? undefined;
@@ -4,7 +4,7 @@ import * as fs from "node:fs";
4
4
  import * as os from "node:os";
5
5
  import * as path from "node:path";
6
6
  import { isProjectTrusted, trustProject, getUntrustedExtensionPaths } from "./project-trust.js";
7
- import { containsTypeScriptSyntax, loadExtensions } from "./loader.js";
7
+ import { containsTypeScriptSyntax, loadExtensions, resetExtensionLoaderCache } from "./loader.js";
8
8
 
9
9
  // ─── helpers ──────────────────────────────────────────────────────────────────
10
10
 
@@ -235,3 +235,41 @@ describe("loadExtensions", () => {
235
235
  );
236
236
  });
237
237
  });
238
+
239
+ // ─── resetExtensionLoaderCache ───────────────────────────────────────────────
240
+
241
+ describe("resetExtensionLoaderCache", () => {
242
+ let tmpDir: string;
243
+
244
+ beforeEach(() => {
245
+ tmpDir = makeTempDir();
246
+ // Always start with a clean cache so tests are independent
247
+ resetExtensionLoaderCache();
248
+ });
249
+
250
+ afterEach(() => {
251
+ resetExtensionLoaderCache();
252
+ cleanDir(tmpDir);
253
+ });
254
+
255
+ it("clears the jiti singleton so a fresh instance is created on next load", async () => {
256
+ // Write a minimal valid extension that returns a name
257
+ const extPath = path.join(tmpDir, "cache-ext.ts");
258
+ fs.writeFileSync(
259
+ extPath,
260
+ `export default function activate(api: any) { return { name: "cache-ext" }; }\n`,
261
+ );
262
+
263
+ // First load — creates the jiti singleton and caches the module
264
+ const result1 = await loadExtensions([extPath], tmpDir);
265
+ assert.equal(result1.extensions.length, 1, "first load should succeed");
266
+
267
+ // Reset the cache — nulls the singleton
268
+ resetExtensionLoaderCache();
269
+
270
+ // Second load — should create a new jiti instance (not reuse the old one)
271
+ // and still successfully load the extension
272
+ const result2 = await loadExtensions([extPath], tmpDir);
273
+ assert.equal(result2.extensions.length, 1, "load after reset should succeed with fresh jiti");
274
+ });
275
+ });
@@ -624,6 +624,39 @@ export function containsTypeScriptSyntax(source: string): boolean {
624
624
  return TS_SYNTAX_PATTERNS.some((pattern) => pattern.test(source));
625
625
  }
626
626
 
627
+ /**
628
+ * Shared jiti instance for loading extension modules.
629
+ *
630
+ * Before this fix (#2108), each extension created a NEW jiti instance with
631
+ * `moduleCache: false`, causing shared dependencies (e.g. @gsd/pi-agent-core)
632
+ * to be recompiled for every extension — turning a ~3s parallel load into a
633
+ * ~15-30s serial compilation bottleneck.
634
+ *
635
+ * Using a single shared instance with `moduleCache: true` means shared modules
636
+ * are compiled once and reused across all extensions.
637
+ */
638
+ let _extensionLoaderJiti: ReturnType<typeof createJiti> | null = null;
639
+
640
+ /**
641
+ * Reset the shared jiti singleton so the next call to getExtensionLoaderJiti()
642
+ * creates a fresh instance. This prevents memory leaks in long-running daemon
643
+ * processes (every loaded module stays cached forever) and ensures stale modules
644
+ * are not returned when extension source changes on disk.
645
+ */
646
+ export function resetExtensionLoaderCache(): void {
647
+ _extensionLoaderJiti = null;
648
+ }
649
+
650
+ function getExtensionLoaderJiti() {
651
+ if (!_extensionLoaderJiti) {
652
+ _extensionLoaderJiti = createJiti(import.meta.url, {
653
+ moduleCache: true,
654
+ ...getJitiOptions(),
655
+ });
656
+ }
657
+ return _extensionLoaderJiti;
658
+ }
659
+
627
660
  async function loadExtensionModule(extensionPath: string) {
628
661
  // Pre-compiled extension loading: if the source is .ts and a sibling .js
629
662
  // file exists with matching or newer mtime, use native import() to skip
@@ -643,10 +676,7 @@ async function loadExtensionModule(extensionPath: string) {
643
676
  }
644
677
  }
645
678
 
646
- const jiti = createJiti(import.meta.url, {
647
- moduleCache: false,
648
- ...getJitiOptions(),
649
- });
679
+ const jiti = getExtensionLoaderJiti();
650
680
 
651
681
  const module = await jiti.import(extensionPath, { default: true });
652
682
  const factory = module as ExtensionFactory;
@@ -0,0 +1,81 @@
1
+ // GSD2 — Regression test: pendingProviderRegistrations must be flushed exactly once (#3576)
2
+ // Copyright (c) 2026 Jeremy McSpadden <jeremy@fluxlabs.net>
3
+
4
+ import { describe, it } from "node:test";
5
+ import assert from "node:assert/strict";
6
+
7
+ /**
8
+ * This test validates that the provider preflush pattern in sdk.ts clears
9
+ * pendingProviderRegistrations after iterating, so bindCore() doesn't
10
+ * re-register the same providers.
11
+ *
12
+ * The bug: createAgentSession() iterated pendingProviderRegistrations but
13
+ * did not clear the array. Later, bindCore() replayed and registered the
14
+ * same providers again, stacking wrappers.
15
+ */
16
+
17
+ interface ProviderEntry {
18
+ name: string;
19
+ config: Record<string, unknown>;
20
+ }
21
+
22
+ interface MockRuntime {
23
+ pendingProviderRegistrations: ProviderEntry[];
24
+ }
25
+
26
+ describe("provider registration preflush", () => {
27
+ it("clears pending registrations after preflush so bindCore does not replay", () => {
28
+ const registered: string[] = [];
29
+ const runtime: MockRuntime = {
30
+ pendingProviderRegistrations: [
31
+ { name: "ollama", config: { type: "ollama" } },
32
+ { name: "custom-provider", config: { type: "custom" } },
33
+ ],
34
+ };
35
+
36
+ // Simulate sdk.ts preflush (lines 220-223)
37
+ for (const { name } of runtime.pendingProviderRegistrations) {
38
+ registered.push(name);
39
+ }
40
+ // The fix: clear after preflush
41
+ runtime.pendingProviderRegistrations = [];
42
+
43
+ // Simulate bindCore() flush (runner.ts lines 268-271)
44
+ for (const { name } of runtime.pendingProviderRegistrations) {
45
+ registered.push(name);
46
+ }
47
+ runtime.pendingProviderRegistrations = [];
48
+
49
+ assert.deepEqual(
50
+ registered,
51
+ ["ollama", "custom-provider"],
52
+ "each provider should be registered exactly once",
53
+ );
54
+ });
55
+
56
+ it("without the fix, providers are registered twice", () => {
57
+ const registered: string[] = [];
58
+ const runtime: MockRuntime = {
59
+ pendingProviderRegistrations: [
60
+ { name: "ollama", config: { type: "ollama" } },
61
+ ],
62
+ };
63
+
64
+ // Old behavior: preflush without clearing
65
+ for (const { name } of runtime.pendingProviderRegistrations) {
66
+ registered.push(name);
67
+ }
68
+ // NOT clearing — simulating the old bug
69
+
70
+ // bindCore() replays the same queue
71
+ for (const { name } of runtime.pendingProviderRegistrations) {
72
+ registered.push(name);
73
+ }
74
+
75
+ assert.deepEqual(
76
+ registered,
77
+ ["ollama", "ollama"],
78
+ "without clearing, providers are registered twice (demonstrating the bug)",
79
+ );
80
+ });
81
+ });
@@ -1341,6 +1341,8 @@ export interface ProviderModelConfig {
1341
1341
  headers?: Record<string, string>;
1342
1342
  /** OpenAI compatibility settings. */
1343
1343
  compat?: Model<Api>["compat"];
1344
+ /** Opaque provider-specific options (e.g. Ollama keep_alive, num_gpu). */
1345
+ providerOptions?: Record<string, unknown>;
1344
1346
  }
1345
1347
 
1346
1348
  /** Extension factory function type. Supports both sync and async initialization. */
@@ -467,6 +467,18 @@ export class ModelRegistry {
467
467
  this.customProviderApiKeys.set(providerName, providerConfig.apiKey);
468
468
  }
469
469
 
470
+ // Register custom providers so isProviderRequestReady() can find
471
+ // them (#3531). Without this, models.json providers with apiKey
472
+ // fail the auth check and are invisible to the fallback resolver.
473
+ if (!this.registeredProviders.has(providerName)) {
474
+ this.registeredProviders.set(providerName, {
475
+ authMode: providerConfig.apiKey ? "apiKey" : "none",
476
+ apiKey: providerConfig.apiKey,
477
+ baseUrl: providerConfig.baseUrl,
478
+ isReady: providerConfig.apiKey ? () => true : undefined,
479
+ } as any);
480
+ }
481
+
470
482
  for (const modelDef of modelDefs) {
471
483
  const api = modelDef.api || providerConfig.api;
472
484
  if (!api) continue;
@@ -742,6 +754,7 @@ export class ModelRegistry {
742
754
  maxTokens: modelDef.maxTokens,
743
755
  headers,
744
756
  compat: modelDef.compat,
757
+ providerOptions: modelDef.providerOptions,
745
758
  } as Model<Api>);
746
759
  }
747
760
 
@@ -917,5 +930,6 @@ export interface ProviderConfigInput {
917
930
  maxTokens: number;
918
931
  headers?: Record<string, string>;
919
932
  compat?: Model<Api>["compat"];
933
+ providerOptions?: Record<string, unknown>;
920
934
  }>;
921
935
  }
@@ -13,7 +13,7 @@ import type { ModelRegistry } from "./model-registry.js";
13
13
  /** Default model IDs for each known provider */
14
14
  const defaultModelPerProvider: Record<KnownProvider, string> = {
15
15
  "amazon-bedrock": "us.anthropic.claude-opus-4-6-v1",
16
- anthropic: "claude-opus-4-6[1m]",
16
+ anthropic: "claude-opus-4-6",
17
17
  "anthropic-vertex": "claude-sonnet-4-6",
18
18
  openai: "gpt-5.4",
19
19
  "azure-openai-responses": "gpt-5.2",
@@ -24,7 +24,7 @@ const defaultModelPerProvider: Record<KnownProvider, string> = {
24
24
  "google-vertex": "gemini-3-pro-preview",
25
25
  "github-copilot": "gpt-4o",
26
26
  openrouter: "openai/gpt-5.1-codex",
27
- "vercel-ai-gateway": "anthropic/claude-opus-4-6[1m]",
27
+ "vercel-ai-gateway": "anthropic/claude-opus-4-6",
28
28
  xai: "grok-4-fast-non-reasoning",
29
29
  groq: "openai/gpt-oss-120b",
30
30
  cerebras: "zai-glm-4.6",
@@ -507,7 +507,7 @@ export async function findInitialModel(options: {
507
507
  const found = modelRegistry.find(defaultProvider, defaultModelId);
508
508
  if (found) {
509
509
  // Check if the provider's recommended default is a higher-capability variant
510
- // of the saved model (e.g. saved "claude-opus-4-6" vs recommended "claude-opus-4-6[1m]").
510
+ // of the saved model (e.g. saved "claude-opus-4-6" vs recommended "claude-opus-4-6-extended").
511
511
  // If so, prefer the recommended variant to avoid using a smaller context window (#1125).
512
512
  const recommendedId = defaultModelPerProvider[defaultProvider as KnownProvider];
513
513
  if (recommendedId && recommendedId !== defaultModelId && recommendedId.startsWith(defaultModelId)) {
@@ -0,0 +1,42 @@
1
+ // GSD-2 — Regression test for #3616: reload() must reset jiti extension loader cache
2
+ // Copyright (c) 2026 Jeremy McSpadden <jeremy@fluxlabs.net>
3
+
4
+ import test, { describe } from "node:test";
5
+ import assert from "node:assert/strict";
6
+ import { readFileSync } from "node:fs";
7
+ import { join } from "node:path";
8
+
9
+ const source = readFileSync(
10
+ join(process.cwd(), "packages/pi-coding-agent/src/core/resource-loader.ts"),
11
+ "utf-8",
12
+ );
13
+
14
+ describe("#3616 — reload() must invalidate jiti module cache", () => {
15
+ test("resource-loader imports resetExtensionLoaderCache from loader.js", () => {
16
+ assert.ok(
17
+ source.includes("resetExtensionLoaderCache"),
18
+ "resource-loader.ts should import resetExtensionLoaderCache",
19
+ );
20
+ assert.ok(
21
+ source.includes('from "./extensions/loader.js"'),
22
+ "resetExtensionLoaderCache should be imported from extensions/loader.js",
23
+ );
24
+ });
25
+
26
+ test("reload() calls resetExtensionLoaderCache before loadExtensions", () => {
27
+ const reloadStart = source.indexOf("async reload(): Promise<void>");
28
+ assert.ok(reloadStart >= 0, "should find reload() method");
29
+ const reloadBody = source.slice(reloadStart, reloadStart + 4000);
30
+
31
+ const resetIdx = reloadBody.indexOf("resetExtensionLoaderCache()");
32
+ assert.ok(resetIdx >= 0, "reload() should call resetExtensionLoaderCache()");
33
+
34
+ const loadIdx = reloadBody.indexOf("loadExtensions(");
35
+ assert.ok(loadIdx >= 0, "reload() should call loadExtensions");
36
+
37
+ assert.ok(
38
+ resetIdx < loadIdx,
39
+ "resetExtensionLoaderCache() must be called BEFORE loadExtensions to ensure fresh modules",
40
+ );
41
+ });
42
+ });