gsd-pi 2.43.0 → 2.44.0-dev.0b97ffd

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 (693) hide show
  1. package/README.md +30 -12
  2. package/dist/cli.js +13 -1
  3. package/dist/help-text.js +24 -0
  4. package/dist/resources/extensions/bg-shell/overlay.js +3 -0
  5. package/dist/resources/extensions/github-sync/sync.js +2 -1
  6. package/dist/resources/extensions/gsd/auto/loop.js +0 -2
  7. package/dist/resources/extensions/gsd/auto/phases.js +7 -12
  8. package/dist/resources/extensions/gsd/auto-dashboard.js +19 -18
  9. package/dist/resources/extensions/gsd/auto-direct-dispatch.js +34 -19
  10. package/dist/resources/extensions/gsd/auto-dispatch.js +36 -21
  11. package/dist/resources/extensions/gsd/auto-post-unit.js +128 -14
  12. package/dist/resources/extensions/gsd/auto-prompts.js +202 -92
  13. package/dist/resources/extensions/gsd/auto-recovery.js +83 -135
  14. package/dist/resources/extensions/gsd/auto-start.js +10 -0
  15. package/dist/resources/extensions/gsd/auto-supervisor.js +14 -0
  16. package/dist/resources/extensions/gsd/auto-timeout-recovery.js +4 -7
  17. package/dist/resources/extensions/gsd/auto-verification.js +5 -10
  18. package/dist/resources/extensions/gsd/auto-worktree.js +123 -30
  19. package/dist/resources/extensions/gsd/auto.js +1 -4
  20. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +611 -0
  21. package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +28 -3
  22. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +7 -0
  23. package/dist/resources/extensions/gsd/commands/catalog.js +3 -1
  24. package/dist/resources/extensions/gsd/commands/handlers/ops.js +15 -1
  25. package/dist/resources/extensions/gsd/commands/handlers/workflow.js +5 -0
  26. package/dist/resources/extensions/gsd/commands-handlers.js +1 -1
  27. package/dist/resources/extensions/gsd/commands-maintenance.js +78 -3
  28. package/dist/resources/extensions/gsd/dashboard-overlay.js +32 -31
  29. package/dist/resources/extensions/gsd/db-writer.js +95 -4
  30. package/dist/resources/extensions/gsd/dispatch-guard.js +35 -30
  31. package/dist/resources/extensions/gsd/doctor-checks.js +28 -11
  32. package/dist/resources/extensions/gsd/doctor-environment.js +28 -0
  33. package/dist/resources/extensions/gsd/doctor-types.js +0 -15
  34. package/dist/resources/extensions/gsd/doctor.js +46 -282
  35. package/dist/resources/extensions/gsd/file-watcher.js +5 -1
  36. package/dist/resources/extensions/gsd/files.js +14 -198
  37. package/dist/resources/extensions/gsd/git-service.js +4 -0
  38. package/dist/resources/extensions/gsd/gitignore.js +4 -0
  39. package/dist/resources/extensions/gsd/gsd-db.js +819 -197
  40. package/dist/resources/extensions/gsd/guided-flow.js +18 -8
  41. package/dist/resources/extensions/gsd/markdown-renderer.js +862 -0
  42. package/dist/resources/extensions/gsd/md-importer.js +182 -4
  43. package/dist/resources/extensions/gsd/native-git-bridge.js +10 -1
  44. package/dist/resources/extensions/gsd/parallel-eligibility.js +14 -19
  45. package/dist/resources/extensions/gsd/parallel-orchestrator.js +38 -0
  46. package/dist/resources/extensions/gsd/parsers-legacy.js +239 -0
  47. package/dist/resources/extensions/gsd/preferences-types.js +1 -0
  48. package/dist/resources/extensions/gsd/preferences-validation.js +9 -0
  49. package/dist/resources/extensions/gsd/preferences.js +1 -0
  50. package/dist/resources/extensions/gsd/prompts/complete-slice.md +22 -9
  51. package/dist/resources/extensions/gsd/prompts/discuss.md +2 -2
  52. package/dist/resources/extensions/gsd/prompts/execute-task.md +15 -5
  53. package/dist/resources/extensions/gsd/prompts/guided-complete-slice.md +1 -1
  54. package/dist/resources/extensions/gsd/prompts/guided-execute-task.md +1 -1
  55. package/dist/resources/extensions/gsd/prompts/guided-plan-milestone.md +1 -1
  56. package/dist/resources/extensions/gsd/prompts/plan-milestone.md +6 -10
  57. package/dist/resources/extensions/gsd/prompts/plan-slice.md +4 -7
  58. package/dist/resources/extensions/gsd/prompts/reactive-execute.md +3 -3
  59. package/dist/resources/extensions/gsd/prompts/reassess-roadmap.md +6 -7
  60. package/dist/resources/extensions/gsd/prompts/replan-slice.md +6 -6
  61. package/dist/resources/extensions/gsd/reactive-graph.js +33 -3
  62. package/dist/resources/extensions/gsd/skill-health.js +3 -1
  63. package/dist/resources/extensions/gsd/state.js +484 -30
  64. package/dist/resources/extensions/gsd/tools/complete-milestone.js +128 -0
  65. package/dist/resources/extensions/gsd/tools/complete-slice.js +244 -0
  66. package/dist/resources/extensions/gsd/tools/complete-task.js +204 -0
  67. package/dist/resources/extensions/gsd/tools/plan-milestone.js +205 -0
  68. package/dist/resources/extensions/gsd/tools/plan-slice.js +155 -0
  69. package/dist/resources/extensions/gsd/tools/plan-task.js +94 -0
  70. package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +152 -0
  71. package/dist/resources/extensions/gsd/tools/replan-slice.js +146 -0
  72. package/dist/resources/extensions/gsd/triage-resolution.js +17 -1
  73. package/dist/resources/extensions/gsd/undo.js +197 -3
  74. package/dist/resources/extensions/gsd/visualizer-data.js +53 -16
  75. package/dist/resources/extensions/gsd/workspace-index.js +63 -39
  76. package/dist/web/standalone/.next/BUILD_ID +1 -1
  77. package/dist/web/standalone/.next/app-path-routes-manifest.json +18 -17
  78. package/dist/web/standalone/.next/build-manifest.json +4 -4
  79. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  80. package/dist/web/standalone/.next/react-loadable-manifest.json +1 -1
  81. package/dist/web/standalone/.next/required-server-files.json +4 -4
  82. package/dist/web/standalone/.next/routes-manifest.json +6 -0
  83. package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
  84. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  85. package/dist/web/standalone/.next/server/app/_global-error.html +2 -2
  86. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  87. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  88. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  89. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  90. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  91. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  92. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  93. package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
  94. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  95. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  96. package/dist/web/standalone/.next/server/app/_not-found.rsc +4 -4
  97. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +4 -4
  98. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  99. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +4 -4
  100. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  101. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  102. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  103. package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
  104. package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
  105. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
  106. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
  107. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
  108. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
  109. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
  110. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
  111. package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
  112. package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
  113. package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
  114. package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
  115. package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
  116. package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
  117. package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
  118. package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
  119. package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
  120. package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
  121. package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
  122. package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
  123. package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
  124. package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
  125. package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
  126. package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
  127. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  128. package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  129. package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
  130. package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
  131. package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
  132. package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
  133. package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
  134. package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
  135. package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
  136. package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
  137. package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
  138. package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
  139. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  140. package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
  141. package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
  142. package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
  143. package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
  144. package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  145. package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
  146. package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
  147. package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +5 -5
  148. package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
  149. package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
  150. package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
  151. package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
  152. package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
  153. package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
  154. package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
  155. package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
  156. package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
  157. package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
  158. package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
  159. package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
  160. package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
  161. package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
  162. package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
  163. package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
  164. package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
  165. package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -0
  166. package/dist/web/standalone/.next/server/app/api/switch-root/route.js.nft.json +1 -0
  167. package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -0
  168. package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +1 -1
  169. package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
  170. package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
  171. package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
  172. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +2 -2
  173. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
  174. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +4 -4
  175. package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
  176. package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
  177. package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
  178. package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
  179. package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
  180. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  181. package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  182. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  183. package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
  184. package/dist/web/standalone/.next/server/app/index.html +1 -1
  185. package/dist/web/standalone/.next/server/app/index.rsc +5 -5
  186. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  187. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +5 -5
  188. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  189. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +4 -4
  190. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  191. package/dist/web/standalone/.next/server/app/page.js +2 -2
  192. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  193. package/dist/web/standalone/.next/server/app-paths-manifest.json +18 -17
  194. package/dist/web/standalone/.next/server/chunks/229.js +3 -3
  195. package/dist/web/standalone/.next/server/chunks/471.js +3 -3
  196. package/dist/web/standalone/.next/server/functions-config-manifest.json +1 -0
  197. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  198. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  199. package/dist/web/standalone/.next/server/middleware.js +2 -2
  200. package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
  201. package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
  202. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  203. package/dist/web/standalone/.next/server/pages/500.html +2 -2
  204. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  205. package/dist/web/standalone/.next/static/alS4hoANx0TK4UVZY27da/_buildManifest.js +1 -0
  206. package/dist/web/standalone/.next/static/chunks/{4024.c195dc1fdd2adbea.js → 4024.0de81b543b28b9fe.js} +2 -2
  207. package/dist/web/standalone/.next/static/chunks/app/_global-error/{page-d07a2c023f1aef1e.js → page-d83ba70a25a85472.js} +1 -1
  208. package/dist/web/standalone/.next/static/chunks/app/_not-found/page-f2a7482d42a5614b.js +1 -0
  209. package/dist/web/standalone/.next/static/chunks/app/api/boot/{route-d07a2c023f1aef1e.js → route-d83ba70a25a85472.js} +1 -1
  210. package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/input/{route-d07a2c023f1aef1e.js → route-d83ba70a25a85472.js} +1 -1
  211. package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/resize/{route-d07a2c023f1aef1e.js → route-d83ba70a25a85472.js} +1 -1
  212. package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/stream/route-d83ba70a25a85472.js +1 -0
  213. package/dist/web/standalone/.next/static/chunks/app/api/browse-directories/route-d83ba70a25a85472.js +1 -0
  214. package/dist/web/standalone/.next/static/chunks/app/api/captures/route-d83ba70a25a85472.js +1 -0
  215. package/dist/web/standalone/.next/static/chunks/app/api/cleanup/route-d83ba70a25a85472.js +1 -0
  216. package/dist/web/standalone/.next/static/chunks/app/api/dev-mode/route-d83ba70a25a85472.js +1 -0
  217. package/dist/web/standalone/.next/static/chunks/app/api/doctor/route-d83ba70a25a85472.js +1 -0
  218. package/dist/web/standalone/.next/static/chunks/app/api/export-data/route-d83ba70a25a85472.js +1 -0
  219. package/dist/web/standalone/.next/static/chunks/app/api/files/route-d83ba70a25a85472.js +1 -0
  220. package/dist/web/standalone/.next/static/chunks/app/api/forensics/route-d83ba70a25a85472.js +1 -0
  221. package/dist/web/standalone/.next/static/chunks/app/api/git/route-d83ba70a25a85472.js +1 -0
  222. package/dist/web/standalone/.next/static/chunks/app/api/history/route-d83ba70a25a85472.js +1 -0
  223. package/dist/web/standalone/.next/static/chunks/app/api/hooks/route-d83ba70a25a85472.js +1 -0
  224. package/dist/web/standalone/.next/static/chunks/app/api/inspect/route-d83ba70a25a85472.js +1 -0
  225. package/dist/web/standalone/.next/static/chunks/app/api/knowledge/route-d83ba70a25a85472.js +1 -0
  226. package/dist/web/standalone/.next/static/chunks/app/api/live-state/route-d83ba70a25a85472.js +1 -0
  227. package/dist/web/standalone/.next/static/chunks/app/api/onboarding/route-d83ba70a25a85472.js +1 -0
  228. package/dist/web/standalone/.next/static/chunks/app/api/preferences/route-d83ba70a25a85472.js +1 -0
  229. package/dist/web/standalone/.next/static/chunks/app/api/projects/route-d83ba70a25a85472.js +1 -0
  230. package/dist/web/standalone/.next/static/chunks/app/api/recovery/route-d83ba70a25a85472.js +1 -0
  231. package/dist/web/standalone/.next/static/chunks/app/api/remote-questions/route-d83ba70a25a85472.js +1 -0
  232. package/dist/web/standalone/.next/static/chunks/app/api/session/browser/route-d83ba70a25a85472.js +1 -0
  233. package/dist/web/standalone/.next/static/chunks/app/api/session/command/route-d83ba70a25a85472.js +1 -0
  234. package/dist/web/standalone/.next/static/chunks/app/api/session/events/route-d83ba70a25a85472.js +1 -0
  235. package/dist/web/standalone/.next/static/chunks/app/api/session/manage/route-d83ba70a25a85472.js +1 -0
  236. package/dist/web/standalone/.next/static/chunks/app/api/settings-data/route-d83ba70a25a85472.js +1 -0
  237. package/dist/web/standalone/.next/static/chunks/app/api/shutdown/route-d83ba70a25a85472.js +1 -0
  238. package/dist/web/standalone/.next/static/chunks/app/api/skill-health/route-d83ba70a25a85472.js +1 -0
  239. package/dist/web/standalone/.next/static/chunks/app/api/steer/route-d83ba70a25a85472.js +1 -0
  240. package/dist/web/standalone/.next/static/chunks/app/api/switch-root/route-d83ba70a25a85472.js +1 -0
  241. package/dist/web/standalone/.next/static/chunks/app/api/terminal/input/route-d83ba70a25a85472.js +1 -0
  242. package/dist/web/standalone/.next/static/chunks/app/api/terminal/resize/route-d83ba70a25a85472.js +1 -0
  243. package/dist/web/standalone/.next/static/chunks/app/api/terminal/sessions/route-d83ba70a25a85472.js +1 -0
  244. package/dist/web/standalone/.next/static/chunks/app/api/terminal/stream/route-d83ba70a25a85472.js +1 -0
  245. package/dist/web/standalone/.next/static/chunks/app/api/terminal/upload/route-d83ba70a25a85472.js +1 -0
  246. package/dist/web/standalone/.next/static/chunks/app/api/undo/route-d83ba70a25a85472.js +1 -0
  247. package/dist/web/standalone/.next/static/chunks/app/api/update/route-d83ba70a25a85472.js +1 -0
  248. package/dist/web/standalone/.next/static/chunks/app/api/visualizer/route-d83ba70a25a85472.js +1 -0
  249. package/dist/web/standalone/.next/static/chunks/app/layout-a16c7a7ecdf0c2cf.js +1 -0
  250. package/dist/web/standalone/.next/static/chunks/app/page-b9367c5ae13b99c6.js +1 -0
  251. package/dist/web/standalone/.next/static/chunks/{main-app-2f2ee7b85712c2bd.js → main-app-fdab67f7802d7832.js} +1 -1
  252. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/app-error-d83ba70a25a85472.js +1 -0
  253. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/forbidden-d83ba70a25a85472.js +1 -0
  254. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +1 -0
  255. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/not-found-d83ba70a25a85472.js +1 -0
  256. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/unauthorized-d83ba70a25a85472.js +1 -0
  257. package/dist/web/standalone/.next/static/chunks/{webpack-fa307370fcf9fb2c.js → webpack-9014b5adb127a98a.js} +1 -1
  258. package/dist/web/standalone/.next/static/css/8a727f372cf53002.css +1 -0
  259. package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
  260. package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
  261. package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
  262. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api.target.mk +14 -14
  263. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_except.target.mk +14 -14
  264. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_maybe.target.mk +14 -14
  265. package/dist/web/standalone/server.js +1 -1
  266. package/package.json +4 -4
  267. package/packages/pi-ai/dist/models.custom.d.ts +173 -0
  268. package/packages/pi-ai/dist/models.custom.d.ts.map +1 -0
  269. package/packages/pi-ai/dist/models.custom.js +170 -0
  270. package/packages/pi-ai/dist/models.custom.js.map +1 -0
  271. package/packages/pi-ai/dist/models.d.ts.map +1 -1
  272. package/packages/pi-ai/dist/models.js +16 -1
  273. package/packages/pi-ai/dist/models.js.map +1 -1
  274. package/packages/pi-ai/dist/models.test.d.ts +2 -0
  275. package/packages/pi-ai/dist/models.test.d.ts.map +1 -0
  276. package/packages/pi-ai/dist/models.test.js +67 -0
  277. package/packages/pi-ai/dist/models.test.js.map +1 -0
  278. package/packages/pi-ai/src/models.custom.ts +172 -0
  279. package/packages/pi-ai/src/models.test.ts +85 -0
  280. package/packages/pi-ai/src/models.ts +17 -1
  281. package/packages/pi-coding-agent/dist/core/agent-session.d.ts +10 -3
  282. package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
  283. package/packages/pi-coding-agent/dist/core/agent-session.js +21 -34
  284. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  285. package/packages/pi-coding-agent/dist/core/auth-storage.test.js +6 -8
  286. package/packages/pi-coding-agent/dist/core/auth-storage.test.js.map +1 -1
  287. package/packages/pi-coding-agent/dist/core/compaction/branch-summarization.d.ts +2 -2
  288. package/packages/pi-coding-agent/dist/core/compaction/branch-summarization.d.ts.map +1 -1
  289. package/packages/pi-coding-agent/dist/core/compaction/branch-summarization.js.map +1 -1
  290. package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts +2 -2
  291. package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts.map +1 -1
  292. package/packages/pi-coding-agent/dist/core/compaction/compaction.js.map +1 -1
  293. package/packages/pi-coding-agent/dist/core/compaction-orchestrator.js +4 -4
  294. package/packages/pi-coding-agent/dist/core/compaction-orchestrator.js.map +1 -1
  295. package/packages/pi-coding-agent/dist/core/extensions/index.d.ts +1 -1
  296. package/packages/pi-coding-agent/dist/core/extensions/index.d.ts.map +1 -1
  297. package/packages/pi-coding-agent/dist/core/extensions/index.js.map +1 -1
  298. package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts +6 -0
  299. package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
  300. package/packages/pi-coding-agent/dist/core/extensions/loader.js +80 -0
  301. package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
  302. package/packages/pi-coding-agent/dist/core/extensions/loader.test.js +63 -0
  303. package/packages/pi-coding-agent/dist/core/extensions/loader.test.js.map +1 -1
  304. package/packages/pi-coding-agent/dist/core/extensions/runner.test.js +24 -26
  305. package/packages/pi-coding-agent/dist/core/extensions/runner.test.js.map +1 -1
  306. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts +37 -0
  307. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts.map +1 -1
  308. package/packages/pi-coding-agent/dist/core/extensions/types.js.map +1 -1
  309. package/packages/pi-coding-agent/dist/core/fallback-resolver.d.ts.map +1 -1
  310. package/packages/pi-coding-agent/dist/core/fallback-resolver.js +2 -3
  311. package/packages/pi-coding-agent/dist/core/fallback-resolver.js.map +1 -1
  312. package/packages/pi-coding-agent/dist/core/fallback-resolver.test.js +12 -2
  313. package/packages/pi-coding-agent/dist/core/fallback-resolver.test.js.map +1 -1
  314. package/packages/pi-coding-agent/dist/core/fs-utils.test.js +29 -48
  315. package/packages/pi-coding-agent/dist/core/fs-utils.test.js.map +1 -1
  316. package/packages/pi-coding-agent/dist/core/lifecycle-hooks.d.ts +38 -0
  317. package/packages/pi-coding-agent/dist/core/lifecycle-hooks.d.ts.map +1 -0
  318. package/packages/pi-coding-agent/dist/core/lifecycle-hooks.js +192 -0
  319. package/packages/pi-coding-agent/dist/core/lifecycle-hooks.js.map +1 -0
  320. package/packages/pi-coding-agent/dist/core/lsp/client.d.ts +5 -0
  321. package/packages/pi-coding-agent/dist/core/lsp/client.d.ts.map +1 -1
  322. package/packages/pi-coding-agent/dist/core/lsp/client.js +69 -21
  323. package/packages/pi-coding-agent/dist/core/lsp/client.js.map +1 -1
  324. package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.d.ts +2 -0
  325. package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.d.ts.map +1 -0
  326. package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js +255 -0
  327. package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js.map +1 -0
  328. package/packages/pi-coding-agent/dist/core/model-registry.d.ts +15 -0
  329. package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
  330. package/packages/pi-coding-agent/dist/core/model-registry.js +40 -3
  331. package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
  332. package/packages/pi-coding-agent/dist/core/package-commands.d.ts +25 -0
  333. package/packages/pi-coding-agent/dist/core/package-commands.d.ts.map +1 -0
  334. package/packages/pi-coding-agent/dist/core/package-commands.js +253 -0
  335. package/packages/pi-coding-agent/dist/core/package-commands.js.map +1 -0
  336. package/packages/pi-coding-agent/dist/core/package-commands.test.d.ts +2 -0
  337. package/packages/pi-coding-agent/dist/core/package-commands.test.d.ts.map +1 -0
  338. package/packages/pi-coding-agent/dist/core/package-commands.test.js +225 -0
  339. package/packages/pi-coding-agent/dist/core/package-commands.test.js.map +1 -0
  340. package/packages/pi-coding-agent/dist/core/resolve-config-value.test.js +34 -44
  341. package/packages/pi-coding-agent/dist/core/resolve-config-value.test.js.map +1 -1
  342. package/packages/pi-coding-agent/dist/core/sdk.d.ts.map +1 -1
  343. package/packages/pi-coding-agent/dist/core/sdk.js +4 -0
  344. package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
  345. package/packages/pi-coding-agent/dist/core/session-manager.test.js +30 -34
  346. package/packages/pi-coding-agent/dist/core/session-manager.test.js.map +1 -1
  347. package/packages/pi-coding-agent/dist/core/tools/edit-diff.test.js +10 -12
  348. package/packages/pi-coding-agent/dist/core/tools/edit-diff.test.js.map +1 -1
  349. package/packages/pi-coding-agent/dist/index.d.ts +3 -1
  350. package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
  351. package/packages/pi-coding-agent/dist/index.js +1 -0
  352. package/packages/pi-coding-agent/dist/index.js.map +1 -1
  353. package/packages/pi-coding-agent/dist/main.d.ts.map +1 -1
  354. package/packages/pi-coding-agent/dist/main.js +11 -199
  355. package/packages/pi-coding-agent/dist/main.js.map +1 -1
  356. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.d.ts +6 -0
  357. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.d.ts.map +1 -1
  358. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js +21 -0
  359. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js.map +1 -1
  360. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.d.ts +1 -1
  361. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  362. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.js +8 -15
  363. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.js.map +1 -1
  364. package/packages/pi-coding-agent/dist/modes/print-mode.d.ts.map +1 -1
  365. package/packages/pi-coding-agent/dist/modes/print-mode.js +45 -34
  366. package/packages/pi-coding-agent/dist/modes/print-mode.js.map +1 -1
  367. package/packages/pi-coding-agent/dist/modes/rpc/rpc-client.d.ts +1 -0
  368. package/packages/pi-coding-agent/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  369. package/packages/pi-coding-agent/dist/modes/rpc/rpc-client.js +7 -2
  370. package/packages/pi-coding-agent/dist/modes/rpc/rpc-client.js.map +1 -1
  371. package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  372. package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.js +2 -1
  373. package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.js.map +1 -1
  374. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.test.js +43 -47
  375. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.test.js.map +1 -1
  376. package/packages/pi-coding-agent/package.json +1 -1
  377. package/packages/pi-coding-agent/src/core/agent-session.ts +26 -37
  378. package/packages/pi-coding-agent/src/core/auth-storage.test.ts +7 -7
  379. package/packages/pi-coding-agent/src/core/compaction/branch-summarization.ts +2 -2
  380. package/packages/pi-coding-agent/src/core/compaction/compaction.ts +3 -3
  381. package/packages/pi-coding-agent/src/core/compaction-orchestrator.ts +4 -4
  382. package/packages/pi-coding-agent/src/core/extensions/index.ts +5 -0
  383. package/packages/pi-coding-agent/src/core/extensions/loader.test.ts +96 -0
  384. package/packages/pi-coding-agent/src/core/extensions/loader.ts +89 -0
  385. package/packages/pi-coding-agent/src/core/extensions/runner.test.ts +26 -26
  386. package/packages/pi-coding-agent/src/core/extensions/types.ts +44 -0
  387. package/packages/pi-coding-agent/src/core/fallback-resolver.test.ts +15 -2
  388. package/packages/pi-coding-agent/src/core/fallback-resolver.ts +2 -3
  389. package/packages/pi-coding-agent/src/core/fs-utils.test.ts +31 -43
  390. package/packages/pi-coding-agent/src/core/lifecycle-hooks.ts +274 -0
  391. package/packages/pi-coding-agent/src/core/lsp/client.ts +83 -21
  392. package/packages/pi-coding-agent/src/core/model-registry-auth-mode.test.ts +288 -0
  393. package/packages/pi-coding-agent/src/core/model-registry.ts +39 -3
  394. package/packages/pi-coding-agent/src/core/package-commands.test.ts +240 -0
  395. package/packages/pi-coding-agent/src/core/package-commands.ts +310 -0
  396. package/packages/pi-coding-agent/src/core/resolve-config-value.test.ts +40 -45
  397. package/packages/pi-coding-agent/src/core/sdk.ts +4 -0
  398. package/packages/pi-coding-agent/src/core/session-manager.test.ts +33 -33
  399. package/packages/pi-coding-agent/src/core/tools/edit-diff.test.ts +17 -17
  400. package/packages/pi-coding-agent/src/index.ts +7 -0
  401. package/packages/pi-coding-agent/src/main.ts +11 -232
  402. package/packages/pi-coding-agent/src/modes/interactive/components/footer.ts +20 -0
  403. package/packages/pi-coding-agent/src/modes/interactive/theme/theme.ts +9 -16
  404. package/packages/pi-coding-agent/src/modes/print-mode.ts +42 -32
  405. package/packages/pi-coding-agent/src/modes/rpc/rpc-client.ts +8 -2
  406. package/packages/pi-coding-agent/src/modes/rpc/rpc-mode.ts +2 -1
  407. package/packages/pi-coding-agent/src/resources/extensions/memory/storage.test.ts +74 -74
  408. package/pkg/dist/modes/interactive/theme/theme.d.ts +1 -1
  409. package/pkg/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  410. package/pkg/dist/modes/interactive/theme/theme.js +8 -15
  411. package/pkg/dist/modes/interactive/theme/theme.js.map +1 -1
  412. package/pkg/package.json +1 -1
  413. package/src/resources/extensions/bg-shell/overlay.ts +4 -0
  414. package/src/resources/extensions/github-sync/sync.ts +2 -1
  415. package/src/resources/extensions/gsd/auto/loop-deps.ts +0 -8
  416. package/src/resources/extensions/gsd/auto/loop.ts +0 -2
  417. package/src/resources/extensions/gsd/auto/phases.ts +7 -20
  418. package/src/resources/extensions/gsd/auto/types.ts +0 -1
  419. package/src/resources/extensions/gsd/auto-dashboard.ts +20 -16
  420. package/src/resources/extensions/gsd/auto-direct-dispatch.ts +34 -19
  421. package/src/resources/extensions/gsd/auto-dispatch.ts +38 -21
  422. package/src/resources/extensions/gsd/auto-post-unit.ts +150 -15
  423. package/src/resources/extensions/gsd/auto-prompts.ts +186 -103
  424. package/src/resources/extensions/gsd/auto-recovery.ts +77 -142
  425. package/src/resources/extensions/gsd/auto-start.ts +14 -0
  426. package/src/resources/extensions/gsd/auto-supervisor.ts +14 -0
  427. package/src/resources/extensions/gsd/auto-timeout-recovery.ts +6 -7
  428. package/src/resources/extensions/gsd/auto-verification.ts +4 -9
  429. package/src/resources/extensions/gsd/auto-worktree.ts +126 -30
  430. package/src/resources/extensions/gsd/auto.ts +0 -9
  431. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +675 -4
  432. package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +31 -3
  433. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +7 -0
  434. package/src/resources/extensions/gsd/commands/catalog.ts +3 -1
  435. package/src/resources/extensions/gsd/commands/handlers/ops.ts +15 -1
  436. package/src/resources/extensions/gsd/commands/handlers/workflow.ts +8 -0
  437. package/src/resources/extensions/gsd/commands-handlers.ts +1 -1
  438. package/src/resources/extensions/gsd/commands-maintenance.ts +86 -3
  439. package/src/resources/extensions/gsd/dashboard-overlay.ts +17 -13
  440. package/src/resources/extensions/gsd/db-writer.ts +105 -4
  441. package/src/resources/extensions/gsd/dispatch-guard.ts +32 -30
  442. package/src/resources/extensions/gsd/doctor-checks.ts +25 -11
  443. package/src/resources/extensions/gsd/doctor-environment.ts +31 -0
  444. package/src/resources/extensions/gsd/doctor-types.ts +0 -23
  445. package/src/resources/extensions/gsd/doctor.ts +45 -295
  446. package/src/resources/extensions/gsd/file-watcher.ts +4 -1
  447. package/src/resources/extensions/gsd/files.ts +16 -220
  448. package/src/resources/extensions/gsd/git-service.ts +4 -0
  449. package/src/resources/extensions/gsd/gitignore.ts +4 -0
  450. package/src/resources/extensions/gsd/gsd-db.ts +1157 -370
  451. package/src/resources/extensions/gsd/guided-flow.ts +20 -8
  452. package/src/resources/extensions/gsd/markdown-renderer.ts +1098 -0
  453. package/src/resources/extensions/gsd/md-importer.ts +211 -2
  454. package/src/resources/extensions/gsd/native-git-bridge.ts +12 -1
  455. package/src/resources/extensions/gsd/parallel-eligibility.ts +14 -18
  456. package/src/resources/extensions/gsd/parallel-orchestrator.ts +43 -0
  457. package/src/resources/extensions/gsd/parsers-legacy.ts +271 -0
  458. package/src/resources/extensions/gsd/preferences-types.ts +3 -0
  459. package/src/resources/extensions/gsd/preferences-validation.ts +9 -0
  460. package/src/resources/extensions/gsd/preferences.ts +1 -0
  461. package/src/resources/extensions/gsd/prompts/complete-slice.md +22 -9
  462. package/src/resources/extensions/gsd/prompts/discuss.md +2 -2
  463. package/src/resources/extensions/gsd/prompts/execute-task.md +15 -5
  464. package/src/resources/extensions/gsd/prompts/guided-complete-slice.md +1 -1
  465. package/src/resources/extensions/gsd/prompts/guided-execute-task.md +1 -1
  466. package/src/resources/extensions/gsd/prompts/guided-plan-milestone.md +1 -1
  467. package/src/resources/extensions/gsd/prompts/plan-milestone.md +6 -10
  468. package/src/resources/extensions/gsd/prompts/plan-slice.md +4 -7
  469. package/src/resources/extensions/gsd/prompts/reactive-execute.md +3 -3
  470. package/src/resources/extensions/gsd/prompts/reassess-roadmap.md +6 -7
  471. package/src/resources/extensions/gsd/prompts/replan-slice.md +6 -6
  472. package/src/resources/extensions/gsd/reactive-graph.ts +33 -3
  473. package/src/resources/extensions/gsd/skill-health.ts +2 -1
  474. package/src/resources/extensions/gsd/state.ts +547 -29
  475. package/src/resources/extensions/gsd/tests/all-milestones-complete-merge.test.ts +99 -99
  476. package/src/resources/extensions/gsd/tests/atomic-task-closeout.test.ts +8 -120
  477. package/src/resources/extensions/gsd/tests/auto-lock-creation.test.ts +14 -16
  478. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +20 -11
  479. package/src/resources/extensions/gsd/tests/auto-paused-session-validation.test.ts +43 -57
  480. package/src/resources/extensions/gsd/tests/auto-preflight.test.ts +11 -13
  481. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +600 -513
  482. package/src/resources/extensions/gsd/tests/auto-secrets-gate.test.ts +73 -75
  483. package/src/resources/extensions/gsd/tests/auto-start-needs-discussion.test.ts +34 -56
  484. package/src/resources/extensions/gsd/tests/auto-stash-merge.test.ts +121 -0
  485. package/src/resources/extensions/gsd/tests/auto-worktree-milestone-merge.test.ts +540 -668
  486. package/src/resources/extensions/gsd/tests/auto-worktree.test.ts +165 -143
  487. package/src/resources/extensions/gsd/tests/cache-staleness-regression.test.ts +29 -52
  488. package/src/resources/extensions/gsd/tests/captures.test.ts +148 -176
  489. package/src/resources/extensions/gsd/tests/claude-import-tui.test.ts +32 -33
  490. package/src/resources/extensions/gsd/tests/collect-from-manifest.test.ts +141 -143
  491. package/src/resources/extensions/gsd/tests/commands-inspect-open-db.test.ts +25 -25
  492. package/src/resources/extensions/gsd/tests/commands-logs.test.ts +81 -81
  493. package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +39 -60
  494. package/src/resources/extensions/gsd/tests/complete-slice.test.ts +375 -0
  495. package/src/resources/extensions/gsd/tests/complete-task.test.ts +387 -0
  496. package/src/resources/extensions/gsd/tests/context-store.test.ts +354 -367
  497. package/src/resources/extensions/gsd/tests/continue-here.test.ts +68 -72
  498. package/src/resources/extensions/gsd/tests/cost-projection.test.ts +92 -106
  499. package/src/resources/extensions/gsd/tests/crash-recovery.test.ts +27 -35
  500. package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +0 -2
  501. package/src/resources/extensions/gsd/tests/dashboard-budget.test.ts +220 -237
  502. package/src/resources/extensions/gsd/tests/db-writer.test.ts +390 -420
  503. package/src/resources/extensions/gsd/tests/definition-loader.test.ts +76 -92
  504. package/src/resources/extensions/gsd/tests/derive-state-crossval.test.ts +512 -0
  505. package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +644 -84
  506. package/src/resources/extensions/gsd/tests/derive-state-deps.test.ts +78 -101
  507. package/src/resources/extensions/gsd/tests/derive-state.test.ts +192 -227
  508. package/src/resources/extensions/gsd/tests/detection.test.ts +232 -278
  509. package/src/resources/extensions/gsd/tests/dev-engine-wrapper.test.ts +30 -34
  510. package/src/resources/extensions/gsd/tests/dispatch-guard.test.ts +192 -161
  511. package/src/resources/extensions/gsd/tests/dispatch-missing-task-plans.test.ts +43 -49
  512. package/src/resources/extensions/gsd/tests/dispatch-uat-last-completed.test.ts +28 -32
  513. package/src/resources/extensions/gsd/tests/doctor-completion-deferral.test.ts +30 -90
  514. package/src/resources/extensions/gsd/tests/doctor-delimiter-fix.test.ts +34 -38
  515. package/src/resources/extensions/gsd/tests/doctor-enhancements.test.ts +57 -80
  516. package/src/resources/extensions/gsd/tests/doctor-environment-worktree.test.ts +164 -0
  517. package/src/resources/extensions/gsd/tests/doctor-environment.test.ts +72 -97
  518. package/src/resources/extensions/gsd/tests/doctor-fixlevel.test.ts +55 -153
  519. package/src/resources/extensions/gsd/tests/doctor-git.test.ts +104 -145
  520. package/src/resources/extensions/gsd/tests/doctor-proactive.test.ts +84 -106
  521. package/src/resources/extensions/gsd/tests/doctor-roadmap-summary-atomicity.test.ts +53 -97
  522. package/src/resources/extensions/gsd/tests/doctor-runtime.test.ts +72 -93
  523. package/src/resources/extensions/gsd/tests/doctor.test.ts +109 -149
  524. package/src/resources/extensions/gsd/tests/ensure-db-open.test.ts +123 -131
  525. package/src/resources/extensions/gsd/tests/exit-command.test.ts +20 -24
  526. package/src/resources/extensions/gsd/tests/feature-branch-lifecycle-integration.test.ts +48 -57
  527. package/src/resources/extensions/gsd/tests/files-loadfile-eisdir.test.ts +5 -7
  528. package/src/resources/extensions/gsd/tests/flag-file-db.test.ts +278 -0
  529. package/src/resources/extensions/gsd/tests/freeform-decisions.test.ts +232 -0
  530. package/src/resources/extensions/gsd/tests/git-locale.test.ts +13 -27
  531. package/src/resources/extensions/gsd/tests/git-service.test.ts +291 -390
  532. package/src/resources/extensions/gsd/tests/gitignore-tracked-gsd.test.ts +31 -39
  533. package/src/resources/extensions/gsd/tests/graph-operations.test.ts +63 -69
  534. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +255 -264
  535. package/src/resources/extensions/gsd/tests/gsd-inspect.test.ts +108 -119
  536. package/src/resources/extensions/gsd/tests/gsd-recover.test.ts +440 -0
  537. package/src/resources/extensions/gsd/tests/gsd-tools.test.ts +229 -262
  538. package/src/resources/extensions/gsd/tests/headless-answers.test.ts +13 -13
  539. package/src/resources/extensions/gsd/tests/health-widget.test.ts +29 -37
  540. package/src/resources/extensions/gsd/tests/idle-recovery.test.ts +81 -270
  541. package/src/resources/extensions/gsd/tests/init-wizard.test.ts +16 -18
  542. package/src/resources/extensions/gsd/tests/integration-edge.test.ts +41 -46
  543. package/src/resources/extensions/gsd/tests/integration-lifecycle.test.ts +42 -53
  544. package/src/resources/extensions/gsd/tests/integration-mixed-milestones.test.ts +75 -91
  545. package/src/resources/extensions/gsd/tests/integration-proof.test.ts +643 -0
  546. package/src/resources/extensions/gsd/tests/journal-integration.test.ts +0 -3
  547. package/src/resources/extensions/gsd/tests/markdown-renderer.test.ts +1161 -0
  548. package/src/resources/extensions/gsd/tests/md-importer.test.ts +101 -125
  549. package/src/resources/extensions/gsd/tests/memory-extractor.test.ts +45 -54
  550. package/src/resources/extensions/gsd/tests/memory-store.test.ts +81 -94
  551. package/src/resources/extensions/gsd/tests/migrate-command.test.ts +57 -66
  552. package/src/resources/extensions/gsd/tests/migrate-hierarchy.test.ts +429 -0
  553. package/src/resources/extensions/gsd/tests/migrate-parser.test.ts +161 -170
  554. package/src/resources/extensions/gsd/tests/migrate-transformer.test.ts +125 -141
  555. package/src/resources/extensions/gsd/tests/migrate-validator-parsers.test.ts +107 -131
  556. package/src/resources/extensions/gsd/tests/migrate-writer-integration.test.ts +89 -97
  557. package/src/resources/extensions/gsd/tests/migrate-writer.test.ts +127 -164
  558. package/src/resources/extensions/gsd/tests/must-have-parser.test.ts +81 -94
  559. package/src/resources/extensions/gsd/tests/none-mode-gates.test.ts +35 -36
  560. package/src/resources/extensions/gsd/tests/overrides.test.ts +99 -106
  561. package/src/resources/extensions/gsd/tests/parallel-crash-recovery.test.ts +40 -47
  562. package/src/resources/extensions/gsd/tests/parallel-worker-monitoring.test.ts +25 -28
  563. package/src/resources/extensions/gsd/tests/parallel-workers-multi-milestone-e2e.test.ts +66 -83
  564. package/src/resources/extensions/gsd/tests/park-edge-cases.test.ts +54 -77
  565. package/src/resources/extensions/gsd/tests/park-milestone.test.ts +68 -115
  566. package/src/resources/extensions/gsd/tests/parsers.test.ts +548 -612
  567. package/src/resources/extensions/gsd/tests/paths.test.ts +72 -87
  568. package/src/resources/extensions/gsd/tests/plan-milestone.test.ts +176 -113
  569. package/src/resources/extensions/gsd/tests/plan-slice-prompt.test.ts +7 -0
  570. package/src/resources/extensions/gsd/tests/plan-slice.test.ts +179 -0
  571. package/src/resources/extensions/gsd/tests/plan-task.test.ts +145 -0
  572. package/src/resources/extensions/gsd/tests/planning-crossval.test.ts +305 -0
  573. package/src/resources/extensions/gsd/tests/post-unit-hooks.test.ts +77 -117
  574. package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +139 -0
  575. package/src/resources/extensions/gsd/tests/prompt-db.test.ts +56 -56
  576. package/src/resources/extensions/gsd/tests/queue-draft-detection.test.ts +93 -119
  577. package/src/resources/extensions/gsd/tests/queue-order.test.ts +70 -82
  578. package/src/resources/extensions/gsd/tests/queue-reorder-e2e.test.ts +42 -55
  579. package/src/resources/extensions/gsd/tests/quick-auto-guard.test.ts +100 -0
  580. package/src/resources/extensions/gsd/tests/quick-branch-lifecycle.test.ts +45 -73
  581. package/src/resources/extensions/gsd/tests/reassess-handler.test.ts +325 -0
  582. package/src/resources/extensions/gsd/tests/reassess-prompt.test.ts +28 -38
  583. package/src/resources/extensions/gsd/tests/replan-handler.test.ts +410 -0
  584. package/src/resources/extensions/gsd/tests/replan-slice.test.ts +73 -80
  585. package/src/resources/extensions/gsd/tests/repo-identity-worktree.test.ts +71 -74
  586. package/src/resources/extensions/gsd/tests/requirements.test.ts +70 -75
  587. package/src/resources/extensions/gsd/tests/retry-state-reset.test.ts +44 -66
  588. package/src/resources/extensions/gsd/tests/roadmap-parse-regression.test.ts +114 -181
  589. package/src/resources/extensions/gsd/tests/roadmap-slices.test.ts +1 -1
  590. package/src/resources/extensions/gsd/tests/rogue-file-detection.test.ts +296 -0
  591. package/src/resources/extensions/gsd/tests/rule-registry.test.ts +63 -65
  592. package/src/resources/extensions/gsd/tests/run-uat.test.ts +66 -128
  593. package/src/resources/extensions/gsd/tests/schema-v9-sequence.test.ts +176 -0
  594. package/src/resources/extensions/gsd/tests/session-lock-multipath.test.ts +18 -25
  595. package/src/resources/extensions/gsd/tests/session-lock-regression.test.ts +37 -44
  596. package/src/resources/extensions/gsd/tests/shared-wal.test.ts +209 -0
  597. package/src/resources/extensions/gsd/tests/sqlite-unavailable-gate.test.ts +63 -0
  598. package/src/resources/extensions/gsd/tests/stalled-tool-recovery.test.ts +6 -8
  599. package/src/resources/extensions/gsd/tests/symlink-numbered-variants.test.ts +22 -28
  600. package/src/resources/extensions/gsd/tests/token-cost-display.test.ts +118 -0
  601. package/src/resources/extensions/gsd/tests/token-savings.test.ts +54 -56
  602. package/src/resources/extensions/gsd/tests/tool-call-loop-guard.test.ts +23 -25
  603. package/src/resources/extensions/gsd/tests/tool-naming.test.ts +19 -13
  604. package/src/resources/extensions/gsd/tests/undo.test.ts +321 -1
  605. package/src/resources/extensions/gsd/tests/unique-milestone-ids.test.ts +66 -82
  606. package/src/resources/extensions/gsd/tests/unit-runtime.test.ts +46 -47
  607. package/src/resources/extensions/gsd/tests/validate-milestone.test.ts +1 -1
  608. package/src/resources/extensions/gsd/tests/verification-evidence.test.ts +0 -142
  609. package/src/resources/extensions/gsd/tests/visualizer-critical-path.test.ts +20 -22
  610. package/src/resources/extensions/gsd/tests/visualizer-data.test.ts +84 -86
  611. package/src/resources/extensions/gsd/tests/visualizer-overlay.test.ts +41 -43
  612. package/src/resources/extensions/gsd/tests/visualizer-views.test.ts +94 -96
  613. package/src/resources/extensions/gsd/tests/windows-path-normalization.test.ts +11 -13
  614. package/src/resources/extensions/gsd/tests/worker-registry.test.ts +27 -29
  615. package/src/resources/extensions/gsd/tests/workflow-templates.test.ts +50 -52
  616. package/src/resources/extensions/gsd/tests/worktree-bugfix.test.ts +10 -13
  617. package/src/resources/extensions/gsd/tests/worktree-db-integration.test.ts +14 -18
  618. package/src/resources/extensions/gsd/tests/worktree-db.test.ts +38 -39
  619. package/src/resources/extensions/gsd/tests/worktree-e2e.test.ts +17 -21
  620. package/src/resources/extensions/gsd/tests/worktree-health-dispatch.test.ts +12 -5
  621. package/src/resources/extensions/gsd/tests/worktree-health.test.ts +25 -30
  622. package/src/resources/extensions/gsd/tests/worktree-integration.test.ts +30 -37
  623. package/src/resources/extensions/gsd/tests/worktree-symlink-removal.test.ts +15 -22
  624. package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +59 -66
  625. package/src/resources/extensions/gsd/tests/worktree.test.ts +44 -50
  626. package/src/resources/extensions/gsd/tools/complete-milestone.ts +176 -0
  627. package/src/resources/extensions/gsd/tools/complete-slice.ts +300 -0
  628. package/src/resources/extensions/gsd/tools/complete-task.ts +245 -0
  629. package/src/resources/extensions/gsd/tools/plan-milestone.ts +249 -0
  630. package/src/resources/extensions/gsd/tools/plan-slice.ts +194 -0
  631. package/src/resources/extensions/gsd/tools/plan-task.ts +116 -0
  632. package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +203 -0
  633. package/src/resources/extensions/gsd/tools/replan-slice.ts +192 -0
  634. package/src/resources/extensions/gsd/triage-resolution.ts +20 -1
  635. package/src/resources/extensions/gsd/types.ts +50 -0
  636. package/src/resources/extensions/gsd/undo.ts +247 -3
  637. package/src/resources/extensions/gsd/visualizer-data.ts +54 -17
  638. package/src/resources/extensions/gsd/workspace-index.ts +64 -46
  639. package/dist/resources/extensions/gsd/auto-observability.js +0 -56
  640. package/dist/resources/extensions/gsd/observability-validator.js +0 -422
  641. package/dist/resources/extensions/gsd/roadmap-mutations.js +0 -110
  642. package/dist/web/standalone/.next/static/VvclDCW6TAWjEyLU-EYL1/_buildManifest.js +0 -1
  643. package/dist/web/standalone/.next/static/chunks/app/_not-found/page-e07acdb7dd069836.js +0 -1
  644. package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/stream/route-d07a2c023f1aef1e.js +0 -1
  645. package/dist/web/standalone/.next/static/chunks/app/api/browse-directories/route-d07a2c023f1aef1e.js +0 -1
  646. package/dist/web/standalone/.next/static/chunks/app/api/captures/route-d07a2c023f1aef1e.js +0 -1
  647. package/dist/web/standalone/.next/static/chunks/app/api/cleanup/route-d07a2c023f1aef1e.js +0 -1
  648. package/dist/web/standalone/.next/static/chunks/app/api/dev-mode/route-d07a2c023f1aef1e.js +0 -1
  649. package/dist/web/standalone/.next/static/chunks/app/api/doctor/route-d07a2c023f1aef1e.js +0 -1
  650. package/dist/web/standalone/.next/static/chunks/app/api/export-data/route-d07a2c023f1aef1e.js +0 -1
  651. package/dist/web/standalone/.next/static/chunks/app/api/files/route-d07a2c023f1aef1e.js +0 -1
  652. package/dist/web/standalone/.next/static/chunks/app/api/forensics/route-d07a2c023f1aef1e.js +0 -1
  653. package/dist/web/standalone/.next/static/chunks/app/api/git/route-d07a2c023f1aef1e.js +0 -1
  654. package/dist/web/standalone/.next/static/chunks/app/api/history/route-d07a2c023f1aef1e.js +0 -1
  655. package/dist/web/standalone/.next/static/chunks/app/api/hooks/route-d07a2c023f1aef1e.js +0 -1
  656. package/dist/web/standalone/.next/static/chunks/app/api/inspect/route-d07a2c023f1aef1e.js +0 -1
  657. package/dist/web/standalone/.next/static/chunks/app/api/knowledge/route-d07a2c023f1aef1e.js +0 -1
  658. package/dist/web/standalone/.next/static/chunks/app/api/live-state/route-d07a2c023f1aef1e.js +0 -1
  659. package/dist/web/standalone/.next/static/chunks/app/api/onboarding/route-d07a2c023f1aef1e.js +0 -1
  660. package/dist/web/standalone/.next/static/chunks/app/api/preferences/route-d07a2c023f1aef1e.js +0 -1
  661. package/dist/web/standalone/.next/static/chunks/app/api/projects/route-d07a2c023f1aef1e.js +0 -1
  662. package/dist/web/standalone/.next/static/chunks/app/api/recovery/route-d07a2c023f1aef1e.js +0 -1
  663. package/dist/web/standalone/.next/static/chunks/app/api/remote-questions/route-d07a2c023f1aef1e.js +0 -1
  664. package/dist/web/standalone/.next/static/chunks/app/api/session/browser/route-d07a2c023f1aef1e.js +0 -1
  665. package/dist/web/standalone/.next/static/chunks/app/api/session/command/route-d07a2c023f1aef1e.js +0 -1
  666. package/dist/web/standalone/.next/static/chunks/app/api/session/events/route-d07a2c023f1aef1e.js +0 -1
  667. package/dist/web/standalone/.next/static/chunks/app/api/session/manage/route-d07a2c023f1aef1e.js +0 -1
  668. package/dist/web/standalone/.next/static/chunks/app/api/settings-data/route-d07a2c023f1aef1e.js +0 -1
  669. package/dist/web/standalone/.next/static/chunks/app/api/shutdown/route-d07a2c023f1aef1e.js +0 -1
  670. package/dist/web/standalone/.next/static/chunks/app/api/skill-health/route-d07a2c023f1aef1e.js +0 -1
  671. package/dist/web/standalone/.next/static/chunks/app/api/steer/route-d07a2c023f1aef1e.js +0 -1
  672. package/dist/web/standalone/.next/static/chunks/app/api/terminal/input/route-d07a2c023f1aef1e.js +0 -1
  673. package/dist/web/standalone/.next/static/chunks/app/api/terminal/resize/route-d07a2c023f1aef1e.js +0 -1
  674. package/dist/web/standalone/.next/static/chunks/app/api/terminal/sessions/route-d07a2c023f1aef1e.js +0 -1
  675. package/dist/web/standalone/.next/static/chunks/app/api/terminal/stream/route-d07a2c023f1aef1e.js +0 -1
  676. package/dist/web/standalone/.next/static/chunks/app/api/terminal/upload/route-d07a2c023f1aef1e.js +0 -1
  677. package/dist/web/standalone/.next/static/chunks/app/api/undo/route-d07a2c023f1aef1e.js +0 -1
  678. package/dist/web/standalone/.next/static/chunks/app/api/update/route-d07a2c023f1aef1e.js +0 -1
  679. package/dist/web/standalone/.next/static/chunks/app/api/visualizer/route-d07a2c023f1aef1e.js +0 -1
  680. package/dist/web/standalone/.next/static/chunks/app/layout-745c6ed5fea5fb06.js +0 -1
  681. package/dist/web/standalone/.next/static/chunks/app/page-801b53eff6e83579.js +0 -1
  682. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/app-error-d07a2c023f1aef1e.js +0 -1
  683. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/forbidden-d07a2c023f1aef1e.js +0 -1
  684. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-e6255954dccfcf0a.js +0 -1
  685. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/not-found-d07a2c023f1aef1e.js +0 -1
  686. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/unauthorized-d07a2c023f1aef1e.js +0 -1
  687. package/dist/web/standalone/.next/static/css/123c0bb039697968.css +0 -1
  688. package/src/resources/extensions/gsd/auto-observability.ts +0 -74
  689. package/src/resources/extensions/gsd/observability-validator.ts +0 -456
  690. package/src/resources/extensions/gsd/roadmap-mutations.ts +0 -134
  691. package/src/resources/extensions/gsd/tests/doctor-task-done-missing-summary-slice-loop.test.ts +0 -174
  692. package/src/resources/extensions/gsd/tests/plan-quality-validator.test.ts +0 -474
  693. /package/dist/web/standalone/.next/static/{VvclDCW6TAWjEyLU-EYL1 → alS4hoANx0TK4UVZY27da}/_ssgManifest.js +0 -0
@@ -255,6 +255,10 @@ export class AgentSession {
255
255
  private _cumulativeOutputTokens = 0;
256
256
  private _cumulativeToolCalls = 0;
257
257
 
258
+ /** Cost of the most recent assistant response (for per-prompt display). */
259
+ private _lastTurnCost = 0;
260
+
261
+
258
262
  // Bash execution state
259
263
  private _bashAbortController: AbortController | undefined = undefined;
260
264
  private _pendingBashMessages: BashExecutionMessage[] = [];
@@ -454,6 +458,7 @@ export class AgentSession {
454
458
 
455
459
  // Accumulate session stats that survive compaction (#1423)
456
460
  const assistantMsg = event.message as AssistantMessage;
461
+ this._lastTurnCost = assistantMsg.usage?.cost?.total ?? 0;
457
462
  this._cumulativeCost += assistantMsg.usage?.cost?.total ?? 0;
458
463
  this._cumulativeInputTokens += assistantMsg.usage?.input ?? 0;
459
464
  this._cumulativeOutputTokens += assistantMsg.usage?.output ?? 0;
@@ -1049,9 +1054,8 @@ export class AgentSession {
1049
1054
  });
1050
1055
  }
1051
1056
 
1052
- // Validate API key
1053
- const apiKey = await this._modelRegistry.getApiKey(this.model, this.sessionId);
1054
- if (!apiKey) {
1057
+ // Validate provider readiness
1058
+ if (!this._modelRegistry.isProviderRequestReady(this.model.provider)) {
1055
1059
  const isOAuth = this._modelRegistry.isUsingOAuth(this.model);
1056
1060
  if (isOAuth) {
1057
1061
  throw new Error(
@@ -1609,12 +1613,11 @@ export class AgentSession {
1609
1613
 
1610
1614
  /**
1611
1615
  * Set model directly.
1612
- * Validates API key, saves to session and settings.
1613
- * @throws Error if no API key available for the model
1616
+ * Validates provider readiness, saves to session and settings.
1617
+ * @throws Error if provider is not ready (missing credentials for apiKey/oauth providers)
1614
1618
  */
1615
1619
  async setModel(model: Model<any>, options?: { persist?: boolean }): Promise<void> {
1616
- const apiKey = await this._modelRegistry.getApiKey(model, this.sessionId);
1617
- if (!apiKey) {
1620
+ if (!this._modelRegistry.isProviderRequestReady(model.provider)) {
1618
1621
  throw new Error(`No API key for ${model.provider}/${model.id}`);
1619
1622
  }
1620
1623
 
@@ -1635,30 +1638,14 @@ export class AgentSession {
1635
1638
  return this._cycleAvailableModel(direction, options);
1636
1639
  }
1637
1640
 
1638
- private async _getScopedModelsWithApiKey(): Promise<Array<{ model: Model<any>; thinkingLevel?: ThinkingLevel }>> {
1639
- const apiKeysByProvider = new Map<string, string | undefined>();
1640
- const result: Array<{ model: Model<any>; thinkingLevel?: ThinkingLevel }> = [];
1641
-
1642
- for (const scoped of this._scopedModels) {
1643
- const provider = scoped.model.provider;
1644
- let apiKey: string | undefined;
1645
- if (apiKeysByProvider.has(provider)) {
1646
- apiKey = apiKeysByProvider.get(provider);
1647
- } else {
1648
- apiKey = await this._modelRegistry.getApiKeyForProvider(provider, this.sessionId);
1649
- apiKeysByProvider.set(provider, apiKey);
1650
- }
1651
-
1652
- if (apiKey) {
1653
- result.push(scoped);
1654
- }
1655
- }
1656
-
1657
- return result;
1641
+ private _getReadyScopedModels(): Array<{ model: Model<any>; thinkingLevel?: ThinkingLevel }> {
1642
+ return this._scopedModels.filter((scoped) =>
1643
+ this._modelRegistry.isProviderRequestReady(scoped.model.provider),
1644
+ );
1658
1645
  }
1659
1646
 
1660
1647
  private async _cycleScopedModel(direction: "forward" | "backward", options?: { persist?: boolean }): Promise<ModelCycleResult | undefined> {
1661
- const scopedModels = await this._getScopedModelsWithApiKey();
1648
+ const scopedModels = this._getReadyScopedModels();
1662
1649
  if (scopedModels.length <= 1) return undefined;
1663
1650
 
1664
1651
  const currentModel = this.model;
@@ -1689,11 +1676,6 @@ export class AgentSession {
1689
1676
  const nextIndex = direction === "forward" ? (currentIndex + 1) % len : (currentIndex - 1 + len) % len;
1690
1677
  const nextModel = availableModels[nextIndex];
1691
1678
 
1692
- const apiKey = await this._modelRegistry.getApiKey(nextModel, this.sessionId);
1693
- if (!apiKey) {
1694
- throw new Error(`No API key for ${nextModel.provider}/${nextModel.id}`);
1695
- }
1696
-
1697
1679
  const thinkingLevel = this._getThinkingLevelForModelSwitch();
1698
1680
  await this._applyModelChange(nextModel, thinkingLevel, "cycle", options);
1699
1681
 
@@ -2032,8 +2014,7 @@ export class AgentSession {
2032
2014
  refreshTools: () => this._refreshToolRegistry(),
2033
2015
  getCommands,
2034
2016
  setModel: async (model, options) => {
2035
- const key = await this.modelRegistry.getApiKey(model, this.sessionId);
2036
- if (!key) return false;
2017
+ if (!this.modelRegistry.isProviderRequestReady(model.provider)) return false;
2037
2018
  await this.setModel(model, options);
2038
2019
  return true;
2039
2020
  },
@@ -2603,10 +2584,10 @@ export class AgentSession {
2603
2584
  let summaryDetails: unknown;
2604
2585
  if (options.summarize && entriesToSummarize.length > 0 && !extensionSummary) {
2605
2586
  const model = this.model!;
2606
- const apiKey = await this._modelRegistry.getApiKey(model, this.sessionId);
2607
- if (!apiKey) {
2587
+ if (!this._modelRegistry.isProviderRequestReady(model.provider)) {
2608
2588
  throw new Error(`No API key for ${model.provider}`);
2609
2589
  }
2590
+ const apiKey = await this._modelRegistry.getApiKey(model, this.sessionId);
2610
2591
  const branchSummarySettings = this.settingsManager.getBranchSummarySettings();
2611
2592
  const result = await generateBranchSummary(entriesToSummarize, {
2612
2593
  model,
@@ -2780,6 +2761,14 @@ export class AgentSession {
2780
2761
  };
2781
2762
  }
2782
2763
 
2764
+ /**
2765
+ * Get the cost of the most recent assistant response.
2766
+ * Returns 0 if no assistant message has been received yet.
2767
+ */
2768
+ getLastTurnCost(): number {
2769
+ return this._lastTurnCost;
2770
+ }
2771
+
2783
2772
  getContextUsage(): ContextUsage | undefined {
2784
2773
  const model = this.model;
2785
2774
  if (!model) return undefined;
@@ -287,7 +287,7 @@ describe("AuthStorage — oauth credential for non-OAuth provider (#2083)", () =
287
287
  assert.equal(key, undefined);
288
288
  });
289
289
 
290
- it("falls through to env var when openrouter has type:oauth credential", async () => {
290
+ it("falls through to env var when openrouter has type:oauth credential", async (t) => {
291
291
  const storage = inMemory({
292
292
  openrouter: {
293
293
  type: "oauth",
@@ -299,17 +299,17 @@ describe("AuthStorage — oauth credential for non-OAuth provider (#2083)", () =
299
299
 
300
300
  // Simulate OPENROUTER_API_KEY being set via env
301
301
  const origEnv = process.env.OPENROUTER_API_KEY;
302
- try {
303
- process.env.OPENROUTER_API_KEY = "sk-or-v1-env-key";
304
- const key = await storage.getApiKey("openrouter");
305
- assert.equal(key, "sk-or-v1-env-key");
306
- } finally {
302
+ t.after(() => {
307
303
  if (origEnv === undefined) {
308
304
  delete process.env.OPENROUTER_API_KEY;
309
305
  } else {
310
306
  process.env.OPENROUTER_API_KEY = origEnv;
311
307
  }
312
- }
308
+ });
309
+
310
+ process.env.OPENROUTER_API_KEY = "sk-or-v1-env-key";
311
+ const key = await storage.getApiKey("openrouter");
312
+ assert.equal(key, "sk-or-v1-env-key");
313
313
  });
314
314
 
315
315
  it("falls through to fallback resolver when openrouter has type:oauth credential", async () => {
@@ -64,8 +64,8 @@ export interface CollectEntriesResult {
64
64
  export interface GenerateBranchSummaryOptions {
65
65
  /** Model to use for summarization */
66
66
  model: Model<any>;
67
- /** API key for the model */
68
- apiKey: string;
67
+ /** API key for the model. Undefined for externalCli/none providers. */
68
+ apiKey: string | undefined;
69
69
  /** Abort signal for cancellation */
70
70
  signal: AbortSignal;
71
71
  /** Optional custom instructions for summarization */
@@ -497,7 +497,7 @@ export async function generateSummary(
497
497
  currentMessages: AgentMessage[],
498
498
  model: Model<any>,
499
499
  reserveTokens: number,
500
- apiKey: string,
500
+ apiKey: string | undefined,
501
501
  signal?: AbortSignal,
502
502
  customInstructions?: string,
503
503
  previousSummary?: string,
@@ -660,7 +660,7 @@ Be concise. Focus on what's needed to understand the kept suffix.`;
660
660
  export async function compact(
661
661
  preparation: CompactionPreparation,
662
662
  model: Model<any>,
663
- apiKey: string,
663
+ apiKey: string | undefined,
664
664
  customInstructions?: string,
665
665
  signal?: AbortSignal,
666
666
  ): Promise<CompactionResult> {
@@ -732,7 +732,7 @@ async function generateTurnPrefixSummary(
732
732
  messages: AgentMessage[],
733
733
  model: Model<any>,
734
734
  reserveTokens: number,
735
- apiKey: string,
735
+ apiKey: string | undefined,
736
736
  signal?: AbortSignal,
737
737
  ): Promise<string> {
738
738
  const maxTokens = Math.floor(0.5 * reserveTokens); // Smaller budget for turn prefix
@@ -94,10 +94,10 @@ export class CompactionOrchestrator {
94
94
  throw new Error("No model selected");
95
95
  }
96
96
 
97
- const apiKey = await this._deps.modelRegistry.getApiKey(model, this._deps.getSessionId());
98
- if (!apiKey) {
97
+ if (!this._deps.modelRegistry.isProviderRequestReady(model.provider)) {
99
98
  throw new Error(`No API key for ${model.provider}`);
100
99
  }
100
+ const apiKey = await this._deps.modelRegistry.getApiKey(model, this._deps.getSessionId());
101
101
 
102
102
  const pathEntries = this._deps.sessionManager.getBranch();
103
103
  const settings = this._deps.settingsManager.getCompactionSettings();
@@ -299,11 +299,11 @@ export class CompactionOrchestrator {
299
299
  return;
300
300
  }
301
301
 
302
- const apiKey = await this._deps.modelRegistry.getApiKey(model, this._deps.getSessionId());
303
- if (!apiKey) {
302
+ if (!this._deps.modelRegistry.isProviderRequestReady(model.provider)) {
304
303
  this._deps.emit({ type: "auto_compaction_end", result: undefined, aborted: false, willRetry: false });
305
304
  return;
306
305
  }
306
+ const apiKey = await this._deps.modelRegistry.getApiKey(model, this._deps.getSessionId());
307
307
 
308
308
  const pathEntries = this._deps.sessionManager.getBranch();
309
309
  const preparation = prepareCompaction(pathEntries, settings);
@@ -94,6 +94,11 @@ export type {
94
94
  // Provider Registration
95
95
  ProviderConfig,
96
96
  ProviderModelConfig,
97
+ LifecycleHookContext,
98
+ LifecycleHookHandler,
99
+ LifecycleHookMap,
100
+ LifecycleHookPhase,
101
+ LifecycleHookScope,
97
102
  ReadToolCallEvent,
98
103
  ReadToolResultEvent,
99
104
  // Commands
@@ -4,6 +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
8
 
8
9
  // ─── helpers ──────────────────────────────────────────────────────────────────
9
10
 
@@ -139,3 +140,98 @@ describe("getUntrustedExtensionPaths", () => {
139
140
  assert.deepEqual(result, paths);
140
141
  });
141
142
  });
143
+
144
+ // ─── containsTypeScriptSyntax ─────────────────────────────────────────────────
145
+
146
+ describe("containsTypeScriptSyntax", () => {
147
+ it("detects parameter type annotations", () => {
148
+ assert.ok(containsTypeScriptSyntax(`export default function activate(api: ExtensionAPI) {}`));
149
+ });
150
+
151
+ it("detects interface declarations", () => {
152
+ assert.ok(containsTypeScriptSyntax(`interface Config { name: string; }`));
153
+ });
154
+
155
+ it("detects type alias declarations", () => {
156
+ assert.ok(containsTypeScriptSyntax(`type Handler = (event: string) => void;`));
157
+ });
158
+
159
+ it("detects enum declarations", () => {
160
+ assert.ok(containsTypeScriptSyntax(`enum Direction { Up, Down, Left, Right }`));
161
+ });
162
+
163
+ it("detects return type annotations", () => {
164
+ assert.ok(containsTypeScriptSyntax(`function foo(): Promise<void> {}`));
165
+ });
166
+
167
+ it("detects generic type parameters on functions", () => {
168
+ assert.ok(containsTypeScriptSyntax(`function identity<T>(arg) { return arg; }`));
169
+ });
170
+
171
+ it("detects variable type annotations", () => {
172
+ assert.ok(containsTypeScriptSyntax(`const name: string = "hello";`));
173
+ });
174
+
175
+ it("returns false for plain JavaScript", () => {
176
+ assert.equal(containsTypeScriptSyntax(`export default function activate(api) { api.on("init", () => {}); }`), false);
177
+ });
178
+
179
+ it("returns false for empty string", () => {
180
+ assert.equal(containsTypeScriptSyntax(""), false);
181
+ });
182
+
183
+ it("returns false for JSDoc comments with type-like syntax", () => {
184
+ // JSDoc uses different syntax: @param {string} name
185
+ assert.equal(containsTypeScriptSyntax(`/** @param {string} name */\nexport default function activate(api) {}`), false);
186
+ });
187
+ });
188
+
189
+ // ─── loadExtensions: TypeScript syntax in .js files ───────────────────────────
190
+
191
+ describe("loadExtensions", () => {
192
+ let tmpDir: string;
193
+
194
+ beforeEach(() => {
195
+ tmpDir = makeTempDir();
196
+ });
197
+
198
+ afterEach(() => {
199
+ cleanDir(tmpDir);
200
+ });
201
+
202
+ it("reports helpful error when .js file contains TypeScript syntax", async () => {
203
+ // Create a .js file that uses TypeScript type annotations
204
+ const extPath = path.join(tmpDir, "my-extension.js");
205
+ fs.writeFileSync(
206
+ extPath,
207
+ `export default function activate(api: ExtensionAPI) {\n api.on("init", async () => {});\n}\n`,
208
+ );
209
+
210
+ const result = await loadExtensions([extPath], tmpDir);
211
+
212
+ assert.equal(result.errors.length, 1);
213
+ const errorMsg = result.errors[0].error;
214
+ // The error should mention TypeScript syntax and suggest .ts extension
215
+ assert.ok(
216
+ /TypeScript/.test(errorMsg) && /\.ts\b/.test(errorMsg),
217
+ `Expected error to mention TypeScript syntax and .ts extension, got: ${errorMsg}`,
218
+ );
219
+ });
220
+
221
+ it("reports helpful error when .js file contains TS interface declaration", async () => {
222
+ const extPath = path.join(tmpDir, "typed-ext.js");
223
+ fs.writeFileSync(
224
+ extPath,
225
+ `interface Config { name: string; }\nexport default function activate(api) { return; }\n`,
226
+ );
227
+
228
+ const result = await loadExtensions([extPath], tmpDir);
229
+
230
+ assert.equal(result.errors.length, 1);
231
+ const errorMsg = result.errors[0].error;
232
+ assert.ok(
233
+ /TypeScript/.test(errorMsg) && /\.ts\b/.test(errorMsg),
234
+ `Expected error to mention TypeScript syntax and .ts extension, got: ${errorMsg}`,
235
+ );
236
+ });
237
+ });
@@ -42,6 +42,7 @@ import type {
42
42
  Extension,
43
43
  ExtensionAPI,
44
44
  ExtensionFactory,
45
+ LifecycleHookHandler,
45
46
  ExtensionRuntime,
46
47
  LoadExtensionsResult,
47
48
  MessageRenderer,
@@ -463,6 +464,22 @@ function createExtensionAPI(
463
464
  extension.commands.set(name, { name, ...options });
464
465
  },
465
466
 
467
+ registerBeforeInstall(handler: LifecycleHookHandler): void {
468
+ extension.lifecycleHooks.beforeInstall.push(handler);
469
+ },
470
+
471
+ registerAfterInstall(handler: LifecycleHookHandler): void {
472
+ extension.lifecycleHooks.afterInstall.push(handler);
473
+ },
474
+
475
+ registerBeforeRemove(handler: LifecycleHookHandler): void {
476
+ extension.lifecycleHooks.beforeRemove.push(handler);
477
+ },
478
+
479
+ registerAfterRemove(handler: LifecycleHookHandler): void {
480
+ extension.lifecycleHooks.afterRemove.push(handler);
481
+ },
482
+
466
483
  registerShortcut(
467
484
  shortcut: KeyId,
468
485
  options: {
@@ -568,6 +585,39 @@ function createExtensionAPI(
568
585
  return api;
569
586
  }
570
587
 
588
+ /**
589
+ * Heuristic patterns that indicate TypeScript syntax in a source file.
590
+ * Used to detect when a .js file accidentally contains TypeScript code
591
+ * and provide a helpful error message instead of a cryptic parse failure.
592
+ */
593
+ const TS_SYNTAX_PATTERNS: RegExp[] = [
594
+ // Variable type annotations: const name: string, let count: number
595
+ /\b(?:const|let|var)\s+\w+\s*:\s*(?:string|number|boolean|any|void|never|unknown|object|bigint|symbol|undefined|null)\b/,
596
+ // Parameter type annotations: (api: ExtensionAPI)
597
+ /\(\s*\w+\s*:\s*[A-Z]\w*/,
598
+ // Return type annotations: ): Promise<void> { or ): string =>
599
+ /\)\s*:\s*(?:Promise|string|number|boolean|void|any|never|unknown)\b/,
600
+ // Interface declarations
601
+ /\binterface\s+[A-Z]\w*\s*(?:<[^>]*>)?\s*\{/,
602
+ // Type alias declarations
603
+ /\btype\s+[A-Z]\w*\s*(?:<[^>]*>)?\s*=/,
604
+ // Angle-bracket type assertions: <Type>value
605
+ /(?:as\s+\w+(?:<[^>]*>)?)\s*[;,)\]}]/,
606
+ // Generic type parameters on functions: function foo<T>
607
+ /\bfunction\s+\w+\s*<[^>]+>/,
608
+ // Enum declarations
609
+ /\benum\s+[A-Z]\w*\s*\{/,
610
+ ];
611
+
612
+ /**
613
+ * Check whether a source string likely contains TypeScript syntax.
614
+ * This is a heuristic — it may produce false positives for unusual JS,
615
+ * but is tuned to catch the most common TS-in-JS mistakes.
616
+ */
617
+ export function containsTypeScriptSyntax(source: string): boolean {
618
+ return TS_SYNTAX_PATTERNS.some((pattern) => pattern.test(source));
619
+ }
620
+
571
621
  async function loadExtensionModule(extensionPath: string) {
572
622
  // Pre-compiled extension loading: if the source is .ts and a sibling .js
573
623
  // file exists with matching or newer mtime, use native import() to skip
@@ -650,6 +700,12 @@ function createExtension(extensionPath: string, resolvedPath: string): Extension
650
700
  commands: new Map(),
651
701
  flags: new Map(),
652
702
  shortcuts: new Map(),
703
+ lifecycleHooks: {
704
+ beforeInstall: [],
705
+ afterInstall: [],
706
+ beforeRemove: [],
707
+ afterRemove: [],
708
+ },
653
709
  };
654
710
  }
655
711
 
@@ -672,6 +728,22 @@ async function loadExtension(
672
728
  return { extension: null, error: null };
673
729
  }
674
730
  logExtensionTiming(extensionPath, Date.now() - start, "failed");
731
+
732
+ // Check if a .js file contains TypeScript syntax
733
+ if (resolvedPath.endsWith(".js")) {
734
+ try {
735
+ const source = fs.readFileSync(resolvedPath, "utf-8");
736
+ if (containsTypeScriptSyntax(source)) {
737
+ return {
738
+ extension: null,
739
+ error: `Extension file "${extensionPath}" appears to contain TypeScript syntax but has a .js extension. Rename it to .ts so the loader can compile it.`,
740
+ };
741
+ }
742
+ } catch {
743
+ // Could not read file — fall through to generic error
744
+ }
745
+ }
746
+
675
747
  return { extension: null, error: `Extension does not export a valid factory function: ${extensionPath}` };
676
748
  }
677
749
 
@@ -684,6 +756,23 @@ async function loadExtension(
684
756
  } catch (err) {
685
757
  const message = err instanceof Error ? err.message : String(err);
686
758
  logExtensionTiming(extensionPath, Date.now() - start, "failed");
759
+
760
+ // Check if a .js file contains TypeScript syntax — the parse error from
761
+ // jiti/Node is often cryptic, so surface a clearer diagnostic.
762
+ if (resolvedPath.endsWith(".js")) {
763
+ try {
764
+ const source = fs.readFileSync(resolvedPath, "utf-8");
765
+ if (containsTypeScriptSyntax(source)) {
766
+ return {
767
+ extension: null,
768
+ error: `Extension file "${extensionPath}" appears to contain TypeScript syntax but has a .js extension. Rename it to .ts so the loader can compile it.`,
769
+ };
770
+ }
771
+ } catch {
772
+ // Could not read file — fall through to generic error
773
+ }
774
+ }
775
+
687
776
  return { extension: null, error: `Failed to load extension: ${message}` };
688
777
  }
689
778
  }
@@ -48,37 +48,37 @@ function makeThrowingExtension(eventType: string, error: Error): Extension {
48
48
  }
49
49
 
50
50
  describe("ExtensionRunner.emitToolCall", () => {
51
- it("catches throwing extension handler and routes to emitError", async () => {
51
+ it("catches throwing extension handler and routes to emitError", async (t) => {
52
52
  const dir = mkdtempSync(join(tmpdir(), "runner-test-"));
53
- try {
54
- const sessionManager = SessionManager.create(dir, dir);
55
- const authStorage = AuthStorage.create();
56
- const modelRegistry = new ModelRegistry(authStorage, join(dir, "models.json"));
53
+ t.after(() => {
54
+ rmSync(dir, { recursive: true, force: true });
55
+ });
57
56
 
58
- const throwingExt = makeThrowingExtension("tool_call", new Error("handler crashed"));
59
- const runtime = makeMinimalRuntime();
60
- const runner = new ExtensionRunner([throwingExt], runtime, dir, sessionManager, modelRegistry);
57
+ const sessionManager = SessionManager.create(dir, dir);
58
+ const authStorage = AuthStorage.create();
59
+ const modelRegistry = new ModelRegistry(authStorage, join(dir, "models.json"));
61
60
 
62
- const errors: any[] = [];
63
- runner.onError((err) => errors.push(err));
61
+ const throwingExt = makeThrowingExtension("tool_call", new Error("handler crashed"));
62
+ const runtime = makeMinimalRuntime();
63
+ const runner = new ExtensionRunner([throwingExt], runtime, dir, sessionManager, modelRegistry);
64
64
 
65
- const event: ToolCallEvent = {
66
- type: "tool_call",
67
- toolCallId: "test-123",
68
- toolName: "test_tool",
69
- input: {},
70
- } as ToolCallEvent;
65
+ const errors: any[] = [];
66
+ runner.onError((err) => errors.push(err));
71
67
 
72
- const result = await runner.emitToolCall(event);
68
+ const event: ToolCallEvent = {
69
+ type: "tool_call",
70
+ toolCallId: "test-123",
71
+ toolName: "test_tool",
72
+ input: {},
73
+ } as ToolCallEvent;
73
74
 
74
- // Should not throw — error is caught and routed to emitError
75
- assert.equal(result, undefined);
76
- assert.equal(errors.length, 1);
77
- assert.equal(errors[0].error, "handler crashed");
78
- assert.equal(errors[0].event, "tool_call");
79
- assert.equal(errors[0].extensionPath, "/test/throwing-ext");
80
- } finally {
81
- rmSync(dir, { recursive: true, force: true });
82
- }
75
+ const result = await runner.emitToolCall(event);
76
+
77
+ // Should not throw — error is caught and routed to emitError
78
+ assert.equal(result, undefined);
79
+ assert.equal(errors.length, 1);
80
+ assert.equal(errors[0].error, "handler crashed");
81
+ assert.equal(errors[0].event, "tool_call");
82
+ assert.equal(errors[0].extensionPath, "/test/throwing-ext");
83
83
  });
84
84
  });
@@ -949,6 +949,33 @@ export interface RegisteredCommand {
949
949
  handler: (args: string, ctx: ExtensionCommandContext) => Promise<void>;
950
950
  }
951
951
 
952
+ export type LifecycleHookScope = "user" | "project";
953
+ export type LifecycleHookPhase = "beforeInstall" | "afterInstall" | "beforeRemove" | "afterRemove";
954
+
955
+ export interface LifecycleHookContext {
956
+ /** Lifecycle phase currently being executed. */
957
+ phase: LifecycleHookPhase;
958
+ /** Package source string passed to install (npm:, git:, https://, local path). */
959
+ source: string;
960
+ /** Resolved installed package path (or resolved local path), when available for this phase. */
961
+ installedPath?: string;
962
+ /** Where the package was installed. */
963
+ scope: LifecycleHookScope;
964
+ /** Current working directory for the install invocation. */
965
+ cwd: string;
966
+ /** Whether install is running in an interactive TTY. */
967
+ interactive: boolean;
968
+ /** Info-level logging sink for install output. */
969
+ log(message: string): void;
970
+ /** Warning-level logging sink for install output. */
971
+ warn(message: string): void;
972
+ /** Error-level logging sink for install output. */
973
+ error(message: string): void;
974
+ }
975
+
976
+ export type LifecycleHookHandler = (ctx: LifecycleHookContext) => Promise<void> | void;
977
+ export type LifecycleHookMap = Record<LifecycleHookPhase, LifecycleHookHandler[]>;
978
+
952
979
  // ============================================================================
953
980
  // Extension API
954
981
  // ============================================================================
@@ -1019,6 +1046,18 @@ export interface ExtensionAPI {
1019
1046
  /** Register a custom command. */
1020
1047
  registerCommand(name: string, options: Omit<RegisteredCommand, "name">): void;
1021
1048
 
1049
+ /** Register a lifecycle hook run before package installation starts. */
1050
+ registerBeforeInstall(handler: LifecycleHookHandler): void;
1051
+
1052
+ /** Register a lifecycle hook run after package installation completes. */
1053
+ registerAfterInstall(handler: LifecycleHookHandler): void;
1054
+
1055
+ /** Register a lifecycle hook run before package removal starts. */
1056
+ registerBeforeRemove(handler: LifecycleHookHandler): void;
1057
+
1058
+ /** Register a lifecycle hook run after package removal completes. */
1059
+ registerAfterRemove(handler: LifecycleHookHandler): void;
1060
+
1022
1061
  /** Register a keyboard shortcut. */
1023
1062
  registerShortcut(
1024
1063
  shortcut: KeyId,
@@ -1201,6 +1240,10 @@ export interface ExtensionAPI {
1201
1240
 
1202
1241
  /** Configuration for registering a provider via pi.registerProvider(). */
1203
1242
  export interface ProviderConfig {
1243
+ /** Auth behavior for provider availability and request key handling. Defaults to "apiKey". */
1244
+ authMode?: "apiKey" | "oauth" | "externalCli" | "none";
1245
+ /** Optional readiness check. Return false if the provider cannot accept requests (e.g., CLI not authenticated, API key invalid). Called before default auth checks. */
1246
+ isReady?: () => boolean;
1204
1247
  /** Base URL for the API endpoint. Required when defining models. */
1205
1248
  baseUrl?: string;
1206
1249
  /** API key or environment variable name. Required when defining models (unless oauth provided). */
@@ -1382,6 +1425,7 @@ export interface Extension {
1382
1425
  commands: Map<string, RegisteredCommand>;
1383
1426
  flags: Map<string, ExtensionFlag>;
1384
1427
  shortcuts: Map<KeyId, ExtensionShortcut>;
1428
+ lifecycleHooks: LifecycleHookMap;
1385
1429
  }
1386
1430
 
1387
1431
  /** Result of loading extensions. */
@@ -38,6 +38,7 @@ function createResolver(overrides?: {
38
38
  enabled?: boolean;
39
39
  isProviderAvailable?: (provider: string) => boolean;
40
40
  hasAuth?: (provider: string) => boolean;
41
+ isProviderRequestReady?: (provider: string) => boolean;
41
42
  find?: (provider: string, modelId: string) => Model<Api> | undefined;
42
43
  }) {
43
44
  const settingsManager = {
@@ -60,6 +61,7 @@ function createResolver(overrides?: {
60
61
  if (provider === "openai" && modelId === "gpt-4.1") return openaiModel;
61
62
  return undefined;
62
63
  }),
64
+ isProviderRequestReady: overrides?.isProviderRequestReady ?? overrides?.hasAuth ?? (() => true),
63
65
  } as unknown as ModelRegistry;
64
66
 
65
67
  return { resolver: new FallbackResolver(settingsManager, authStorage, modelRegistry), authStorage };
@@ -122,9 +124,9 @@ describe("FallbackResolver — findFallback", () => {
122
124
  assert.equal(result, null);
123
125
  });
124
126
 
125
- it("skips providers without auth", async () => {
127
+ it("skips providers that are not request-ready", async () => {
126
128
  const { resolver } = createResolver({
127
- hasAuth: (provider: string) => provider !== "alibaba",
129
+ isProviderRequestReady: (provider: string) => provider !== "alibaba",
128
130
  });
129
131
 
130
132
  const result = await resolver.findFallback(zaiModel, "quota_exhausted");
@@ -133,6 +135,17 @@ describe("FallbackResolver — findFallback", () => {
133
135
  assert.equal(result!.model.provider, "openai");
134
136
  });
135
137
 
138
+ it("allows fallback to external-cli style providers without stored auth", async () => {
139
+ const { resolver } = createResolver({
140
+ hasAuth: () => false,
141
+ isProviderRequestReady: (provider: string) => provider === "alibaba",
142
+ });
143
+
144
+ const result = await resolver.findFallback(zaiModel, "quota_exhausted");
145
+ assert.notEqual(result, null);
146
+ assert.equal(result!.model.provider, "alibaba");
147
+ });
148
+
136
149
  it("skips providers with no model in registry", async () => {
137
150
  const { resolver } = createResolver({
138
151
  find: (provider: string, modelId: string) => {
@@ -149,9 +149,8 @@ export class FallbackResolver {
149
149
  const model = this.modelRegistry.find(entry.provider, entry.model);
150
150
  if (!model) continue;
151
151
 
152
- // Check if API key is available
153
- const hasAuth = this.authStorage.hasAuth(entry.provider);
154
- if (!hasAuth) continue;
152
+ // Check if provider is request-ready for fallback (authMode-aware)
153
+ if (!this.modelRegistry.isProviderRequestReady(entry.provider)) continue;
155
154
 
156
155
  return {
157
156
  model,