gsd-pi 2.78.0 → 2.78.1-dev.84a383f51

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 (486) hide show
  1. package/README.md +59 -23
  2. package/dist/claude-cli-check.js +91 -32
  3. package/dist/cli-policy.d.ts +13 -0
  4. package/dist/cli-policy.js +17 -0
  5. package/dist/cli.js +95 -55
  6. package/dist/headless-query.d.ts +22 -0
  7. package/dist/headless-query.js +24 -4
  8. package/dist/headless.d.ts +10 -0
  9. package/dist/headless.js +16 -1
  10. package/dist/loader.js +7 -10
  11. package/dist/onboarding.d.ts +10 -0
  12. package/dist/onboarding.js +2 -2
  13. package/dist/provider-migrations.d.ts +2 -2
  14. package/dist/provider-migrations.js +5 -2
  15. package/dist/resource-loader.d.ts +5 -2
  16. package/dist/resource-loader.js +28 -5
  17. package/dist/resources/.managed-resources-content-hash +1 -0
  18. package/dist/resources/extensions/claude-code-cli/readiness.js +115 -31
  19. package/dist/resources/extensions/gsd/auto/loop.js +23 -0
  20. package/dist/resources/extensions/gsd/auto/phases.js +2 -2
  21. package/dist/resources/extensions/gsd/auto/run-unit.js +3 -1
  22. package/dist/resources/extensions/gsd/auto/session.js +3 -0
  23. package/dist/resources/extensions/gsd/auto-recovery.js +43 -4
  24. package/dist/resources/extensions/gsd/auto-runtime-state.js +31 -0
  25. package/dist/resources/extensions/gsd/auto-start.js +1 -1
  26. package/dist/resources/extensions/gsd/auto-tool-tracking.js +2 -2
  27. package/dist/resources/extensions/gsd/auto-worktree.js +30 -0
  28. package/dist/resources/extensions/gsd/auto.js +14 -5
  29. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +14 -2
  30. package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +7 -5
  31. package/dist/resources/extensions/gsd/bootstrap/query-tools.js +2 -2
  32. package/dist/resources/extensions/gsd/bootstrap/register-extension.js +5 -4
  33. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +94 -31
  34. package/dist/resources/extensions/gsd/bootstrap/register-shortcuts.js +11 -6
  35. package/dist/resources/extensions/gsd/bootstrap/system-context.js +34 -8
  36. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +38 -2
  37. package/dist/resources/extensions/gsd/commands/catalog.js +69 -5
  38. package/dist/resources/extensions/gsd/commands/handlers/core.js +22 -1
  39. package/dist/resources/extensions/gsd/commands-mcp-status.js +3 -1
  40. package/dist/resources/extensions/gsd/commands-prefs-wizard.js +10 -1
  41. package/dist/resources/extensions/gsd/dashboard-overlay.js +1 -1
  42. package/dist/resources/extensions/gsd/docs/preferences-reference.md +4 -0
  43. package/dist/resources/extensions/gsd/doctor-runtime-checks.js +39 -1
  44. package/dist/resources/extensions/gsd/error-classifier.js +1 -1
  45. package/dist/resources/extensions/gsd/forensics.js +2 -2
  46. package/dist/resources/extensions/gsd/git-service.js +12 -5
  47. package/dist/resources/extensions/gsd/gsd-db.js +11 -2
  48. package/dist/resources/extensions/gsd/guided-flow.js +23 -23
  49. package/dist/resources/extensions/gsd/memory-store.js +66 -31
  50. package/dist/resources/extensions/gsd/milestone-id-reservation.js +36 -0
  51. package/dist/resources/extensions/gsd/model-router.js +114 -9
  52. package/dist/resources/extensions/gsd/native-git-bridge.js +7 -1
  53. package/dist/resources/extensions/gsd/preferences-models.js +91 -15
  54. package/dist/resources/extensions/gsd/preferences-types.js +2 -0
  55. package/dist/resources/extensions/gsd/preferences-validation.js +32 -0
  56. package/dist/resources/extensions/gsd/preferences.js +5 -3
  57. package/dist/resources/extensions/gsd/prompt-loader.js +23 -12
  58. package/dist/resources/extensions/gsd/slice-parallel-orchestrator.js +9 -3
  59. package/dist/resources/extensions/gsd/state.js +42 -0
  60. package/dist/resources/extensions/gsd/templates/PREFERENCES.md +1 -0
  61. package/dist/resources/extensions/gsd/tools/memory-tools.js +18 -1
  62. package/dist/resources/extensions/gsd/visualizer-overlay.js +1 -1
  63. package/dist/resources/extensions/gsd/watch/header-renderer.js +3 -1
  64. package/dist/resources/extensions/gsd/worktree-command.js +26 -46
  65. package/dist/resources/extensions/gsd/worktree-session-state.js +33 -0
  66. package/dist/resources/extensions/mcp-client/index.js +6 -3
  67. package/dist/resources/extensions/slash-commands/create-extension.js +36 -22
  68. package/dist/resources/skills/create-gsd-extension/SKILL.md +9 -5
  69. package/dist/resources/skills/create-gsd-extension/references/custom-commands.md +1 -1
  70. package/dist/resources/skills/create-gsd-extension/references/custom-rendering.md +5 -5
  71. package/dist/resources/skills/create-gsd-extension/references/custom-tools.md +4 -4
  72. package/dist/resources/skills/create-gsd-extension/references/custom-ui.md +6 -6
  73. package/dist/resources/skills/create-gsd-extension/references/events-reference.md +3 -3
  74. package/dist/resources/skills/create-gsd-extension/references/packaging-distribution.md +1 -1
  75. package/dist/resources/skills/create-gsd-extension/references/remote-execution-overrides.md +3 -3
  76. package/dist/resources/skills/create-gsd-extension/workflows/create-extension.md +32 -12
  77. package/dist/rtk-shared.d.ts +3 -0
  78. package/dist/rtk-shared.js +17 -0
  79. package/dist/rtk.d.ts +2 -5
  80. package/dist/rtk.js +3 -20
  81. package/dist/runtime-checks.d.ts +27 -0
  82. package/dist/runtime-checks.js +38 -0
  83. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  84. package/dist/web/standalone/.next/BUILD_ID +1 -1
  85. package/dist/web/standalone/.next/app-path-routes-manifest.json +13 -13
  86. package/dist/web/standalone/.next/build-manifest.json +4 -4
  87. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  88. package/dist/web/standalone/.next/react-loadable-manifest.json +44 -4
  89. package/dist/web/standalone/.next/required-server-files.json +3 -3
  90. package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
  91. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  92. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  93. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  94. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  95. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  96. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  97. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  98. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  99. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  100. package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
  101. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  102. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  103. package/dist/web/standalone/.next/server/app/_not-found.rsc +3 -3
  104. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
  105. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  106. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +3 -3
  107. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  108. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  109. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  110. package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
  111. package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
  112. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
  113. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
  114. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
  115. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
  116. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
  117. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
  118. package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
  119. package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
  120. package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
  121. package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
  122. package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
  123. package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
  124. package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
  125. package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
  126. package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
  127. package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
  128. package/dist/web/standalone/.next/server/app/api/experimental/route.js +2 -2
  129. package/dist/web/standalone/.next/server/app/api/experimental/route_client-reference-manifest.js +1 -1
  130. package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
  131. package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
  132. package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
  133. package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
  134. package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
  135. package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
  136. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  137. package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  138. package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
  139. package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
  140. package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
  141. package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
  142. package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
  143. package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
  144. package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
  145. package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
  146. package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
  147. package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
  148. package/dist/web/standalone/.next/server/app/api/notifications/route.js +2 -2
  149. package/dist/web/standalone/.next/server/app/api/notifications/route_client-reference-manifest.js +1 -1
  150. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  151. package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
  152. package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
  153. package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
  154. package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
  155. package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  156. package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
  157. package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
  158. package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +2 -2
  159. package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
  160. package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
  161. package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
  162. package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
  163. package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
  164. package/dist/web/standalone/.next/server/app/api/session/events/route.js +4 -2
  165. package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
  166. package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
  167. package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
  168. package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
  169. package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
  170. package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
  171. package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
  172. package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
  173. package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
  174. package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
  175. package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
  176. package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
  177. package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
  178. package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +2 -2
  179. package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
  180. package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
  181. package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
  182. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +2 -2
  183. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
  184. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +4 -4
  185. package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
  186. package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
  187. package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
  188. package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
  189. package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
  190. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  191. package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  192. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  193. package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
  194. package/dist/web/standalone/.next/server/app/index.html +1 -1
  195. package/dist/web/standalone/.next/server/app/index.rsc +4 -4
  196. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  197. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +4 -4
  198. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  199. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +3 -3
  200. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  201. package/dist/web/standalone/.next/server/app/page.js +2 -2
  202. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  203. package/dist/web/standalone/.next/server/app-paths-manifest.json +13 -13
  204. package/dist/web/standalone/.next/server/chunks/63.js +3 -3
  205. package/dist/web/standalone/.next/server/chunks/6897.js +1 -1
  206. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  207. package/dist/web/standalone/.next/server/middleware-manifest.json +5 -5
  208. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  209. package/dist/web/standalone/.next/server/middleware.js +2 -2
  210. package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
  211. package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
  212. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  213. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  214. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  215. package/dist/web/standalone/.next/server/webpack-runtime.js +1 -1
  216. package/dist/web/standalone/.next/static/chunks/2556.0527fea66e123b7f.js +1 -0
  217. package/dist/web/standalone/.next/static/chunks/2824.08296bc2f9654698.js +1 -0
  218. package/dist/web/standalone/.next/static/chunks/3026.3af53b279375f082.js +1 -0
  219. package/dist/web/standalone/.next/static/chunks/315.6f68ae79b67d25cf.js +1 -0
  220. package/dist/web/standalone/.next/static/chunks/3497.4bfc60a3b3dea717.js +1 -0
  221. package/dist/web/standalone/.next/static/chunks/5516.4a07c872b5c3a663.js +1 -0
  222. package/dist/web/standalone/.next/static/chunks/8336.31b019697882acfb.js +10 -0
  223. package/dist/web/standalone/.next/static/chunks/8845.c9702695e8c5a9c5.js +2 -0
  224. package/dist/web/standalone/.next/static/chunks/9058.01ef3a463bda88f1.js +20 -0
  225. package/dist/web/standalone/.next/static/chunks/9441.1081da1125d1764f.js +1 -0
  226. package/dist/web/standalone/.next/static/chunks/app/_not-found/{page-2f24283c162b6ab3.js → page-f2a7482d42a5614b.js} +1 -1
  227. package/dist/web/standalone/.next/static/chunks/app/{layout-9ecfd95f343793f0.js → layout-a16c7a7ecdf0c2cf.js} +1 -1
  228. package/dist/web/standalone/.next/static/chunks/app/page-9bf2e0c50fb2ca05.js +1 -0
  229. package/dist/web/standalone/.next/static/chunks/main-app-fdab67f7802d7832.js +1 -0
  230. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +1 -0
  231. package/dist/web/standalone/.next/static/chunks/webpack-f9f0dc45e4f3ac10.js +1 -0
  232. package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
  233. package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
  234. package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
  235. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api.target.mk +14 -14
  236. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_except.target.mk +14 -14
  237. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_maybe.target.mk +14 -14
  238. package/dist/web/standalone/package.json +2 -1
  239. package/dist/web/standalone/server.js +1 -1
  240. package/dist/worktree-status-banner.d.ts +1 -0
  241. package/dist/worktree-status-banner.js +132 -0
  242. package/package.json +1 -1
  243. package/packages/daemon/package.json +2 -2
  244. package/packages/mcp-server/dist/alias-telemetry.d.ts +8 -0
  245. package/packages/mcp-server/dist/alias-telemetry.d.ts.map +1 -0
  246. package/packages/mcp-server/dist/alias-telemetry.js +30 -0
  247. package/packages/mcp-server/dist/alias-telemetry.js.map +1 -0
  248. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  249. package/packages/mcp-server/dist/workflow-tools.js +74 -46
  250. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  251. package/packages/mcp-server/package.json +2 -2
  252. package/packages/mcp-server/src/alias-telemetry.test.ts +78 -0
  253. package/packages/mcp-server/src/alias-telemetry.ts +30 -0
  254. package/packages/mcp-server/src/workflow-tools.test.ts +26 -0
  255. package/packages/mcp-server/src/workflow-tools.ts +93 -58
  256. package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
  257. package/packages/native/package.json +1 -1
  258. package/packages/pi-agent-core/package.json +1 -1
  259. package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -1
  260. package/packages/pi-ai/dist/providers/anthropic-shared.cache-breakpoint.test.d.ts +2 -0
  261. package/packages/pi-ai/dist/providers/anthropic-shared.cache-breakpoint.test.d.ts.map +1 -0
  262. package/packages/pi-ai/dist/providers/anthropic-shared.cache-breakpoint.test.js +231 -0
  263. package/packages/pi-ai/dist/providers/anthropic-shared.cache-breakpoint.test.js.map +1 -0
  264. package/packages/pi-ai/dist/providers/anthropic-shared.d.ts.map +1 -1
  265. package/packages/pi-ai/dist/providers/anthropic-shared.js +48 -19
  266. package/packages/pi-ai/dist/providers/anthropic-shared.js.map +1 -1
  267. package/packages/pi-ai/dist/types.d.ts +13 -0
  268. package/packages/pi-ai/dist/types.d.ts.map +1 -1
  269. package/packages/pi-ai/dist/types.js.map +1 -1
  270. package/packages/pi-ai/dist/utils/repair-tool-json.d.ts.map +1 -1
  271. package/packages/pi-ai/dist/utils/repair-tool-json.js +24 -3
  272. package/packages/pi-ai/dist/utils/repair-tool-json.js.map +1 -1
  273. package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.js +26 -0
  274. package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.js.map +1 -1
  275. package/packages/pi-ai/package.json +1 -1
  276. package/packages/pi-ai/src/providers/anthropic-shared.cache-breakpoint.test.ts +289 -0
  277. package/packages/pi-ai/src/providers/anthropic-shared.ts +52 -20
  278. package/packages/pi-ai/src/types.ts +13 -0
  279. package/packages/pi-ai/src/utils/repair-tool-json.ts +24 -3
  280. package/packages/pi-ai/src/utils/tests/repair-tool-json.test.ts +32 -0
  281. package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
  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 +6 -0
  284. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  285. package/packages/pi-coding-agent/dist/core/messages.d.ts.map +1 -1
  286. package/packages/pi-coding-agent/dist/core/messages.js +4 -0
  287. package/packages/pi-coding-agent/dist/core/messages.js.map +1 -1
  288. package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js +19 -2
  289. package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js.map +1 -1
  290. package/packages/pi-coding-agent/dist/core/model-registry.d.ts +10 -0
  291. package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
  292. package/packages/pi-coding-agent/dist/core/model-registry.js +18 -0
  293. package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
  294. package/packages/pi-coding-agent/dist/core/system-prompt.d.ts +13 -0
  295. package/packages/pi-coding-agent/dist/core/system-prompt.d.ts.map +1 -1
  296. package/packages/pi-coding-agent/dist/core/system-prompt.js +20 -16
  297. package/packages/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
  298. package/packages/pi-coding-agent/dist/core/token-telemetry.d.ts +37 -0
  299. package/packages/pi-coding-agent/dist/core/token-telemetry.d.ts.map +1 -0
  300. package/packages/pi-coding-agent/dist/core/token-telemetry.js +49 -0
  301. package/packages/pi-coding-agent/dist/core/token-telemetry.js.map +1 -0
  302. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.d.ts +2 -0
  303. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.d.ts.map +1 -0
  304. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.js +133 -0
  305. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.js.map +1 -0
  306. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js +1 -1
  307. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js.map +1 -1
  308. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js +14 -1
  309. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js.map +1 -1
  310. package/packages/pi-coding-agent/dist/tests/system-prompt-cache-stability.test.d.ts +2 -0
  311. package/packages/pi-coding-agent/dist/tests/system-prompt-cache-stability.test.d.ts.map +1 -0
  312. package/packages/pi-coding-agent/dist/tests/system-prompt-cache-stability.test.js +78 -0
  313. package/packages/pi-coding-agent/dist/tests/system-prompt-cache-stability.test.js.map +1 -0
  314. package/packages/pi-coding-agent/dist/tests/token-telemetry.test.d.ts +2 -0
  315. package/packages/pi-coding-agent/dist/tests/token-telemetry.test.d.ts.map +1 -0
  316. package/packages/pi-coding-agent/dist/tests/token-telemetry.test.js +181 -0
  317. package/packages/pi-coding-agent/dist/tests/token-telemetry.test.js.map +1 -0
  318. package/packages/pi-coding-agent/package.json +1 -1
  319. package/packages/pi-coding-agent/src/core/agent-session.ts +7 -0
  320. package/packages/pi-coding-agent/src/core/messages.ts +4 -0
  321. package/packages/pi-coding-agent/src/core/model-registry-auth-mode.test.ts +32 -2
  322. package/packages/pi-coding-agent/src/core/model-registry.ts +21 -0
  323. package/packages/pi-coding-agent/src/core/system-prompt.ts +33 -15
  324. package/packages/pi-coding-agent/src/core/token-telemetry.ts +77 -0
  325. package/packages/pi-coding-agent/src/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.ts +212 -0
  326. package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.test.ts +17 -1
  327. package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.ts +1 -1
  328. package/packages/pi-coding-agent/src/tests/system-prompt-cache-stability.test.ts +102 -0
  329. package/packages/pi-coding-agent/src/tests/token-telemetry.test.ts +200 -0
  330. package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
  331. package/packages/pi-tui/dist/__tests__/autocomplete.test.js +17 -3
  332. package/packages/pi-tui/dist/__tests__/autocomplete.test.js.map +1 -1
  333. package/packages/pi-tui/dist/components/__tests__/leak-fixes-runtime.test.d.ts +2 -0
  334. package/packages/pi-tui/dist/components/__tests__/leak-fixes-runtime.test.d.ts.map +1 -0
  335. package/packages/pi-tui/dist/components/__tests__/leak-fixes-runtime.test.js +161 -0
  336. package/packages/pi-tui/dist/components/__tests__/leak-fixes-runtime.test.js.map +1 -0
  337. package/packages/pi-tui/package.json +1 -1
  338. package/packages/pi-tui/src/__tests__/autocomplete.test.ts +20 -3
  339. package/packages/pi-tui/src/components/__tests__/leak-fixes-runtime.test.ts +219 -0
  340. package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
  341. package/packages/rpc-client/package.json +1 -1
  342. package/pkg/package.json +1 -1
  343. package/src/resources/extensions/claude-code-cli/readiness.ts +116 -29
  344. package/src/resources/extensions/gsd/auto/loop.ts +24 -2
  345. package/src/resources/extensions/gsd/auto/phases.ts +3 -3
  346. package/src/resources/extensions/gsd/auto/run-unit.ts +3 -1
  347. package/src/resources/extensions/gsd/auto/session.ts +3 -0
  348. package/src/resources/extensions/gsd/auto/types.ts +1 -0
  349. package/src/resources/extensions/gsd/auto-recovery.ts +46 -8
  350. package/src/resources/extensions/gsd/auto-runtime-state.ts +51 -0
  351. package/src/resources/extensions/gsd/auto-start.ts +1 -1
  352. package/src/resources/extensions/gsd/auto-tool-tracking.ts +2 -4
  353. package/src/resources/extensions/gsd/auto-worktree.ts +38 -0
  354. package/src/resources/extensions/gsd/auto.ts +14 -4
  355. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +15 -13
  356. package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +8 -7
  357. package/src/resources/extensions/gsd/bootstrap/query-tools.ts +2 -2
  358. package/src/resources/extensions/gsd/bootstrap/register-extension.ts +10 -9
  359. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +102 -31
  360. package/src/resources/extensions/gsd/bootstrap/register-shortcuts.ts +12 -6
  361. package/src/resources/extensions/gsd/bootstrap/system-context.ts +39 -8
  362. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +39 -11
  363. package/src/resources/extensions/gsd/commands/catalog.ts +75 -5
  364. package/src/resources/extensions/gsd/commands/handlers/core.ts +22 -1
  365. package/src/resources/extensions/gsd/commands-mcp-status.ts +3 -1
  366. package/src/resources/extensions/gsd/commands-prefs-wizard.ts +15 -1
  367. package/src/resources/extensions/gsd/dashboard-overlay.ts +1 -1
  368. package/src/resources/extensions/gsd/docs/preferences-reference.md +4 -0
  369. package/src/resources/extensions/gsd/doctor-runtime-checks.ts +39 -1
  370. package/src/resources/extensions/gsd/doctor-types.ts +3 -1
  371. package/src/resources/extensions/gsd/error-classifier.ts +1 -1
  372. package/src/resources/extensions/gsd/forensics.ts +2 -2
  373. package/src/resources/extensions/gsd/git-service.ts +13 -5
  374. package/src/resources/extensions/gsd/gsd-db.ts +12 -2
  375. package/src/resources/extensions/gsd/guided-flow.ts +25 -25
  376. package/src/resources/extensions/gsd/memory-store.ts +81 -28
  377. package/src/resources/extensions/gsd/milestone-id-reservation.ts +47 -0
  378. package/src/resources/extensions/gsd/model-router.ts +172 -9
  379. package/src/resources/extensions/gsd/native-git-bridge.ts +7 -1
  380. package/src/resources/extensions/gsd/preferences-models.ts +101 -15
  381. package/src/resources/extensions/gsd/preferences-types.ts +6 -0
  382. package/src/resources/extensions/gsd/preferences-validation.ts +35 -0
  383. package/src/resources/extensions/gsd/preferences.ts +16 -2
  384. package/src/resources/extensions/gsd/prompt-loader.ts +26 -12
  385. package/src/resources/extensions/gsd/slice-parallel-orchestrator.ts +9 -3
  386. package/src/resources/extensions/gsd/state.ts +42 -0
  387. package/src/resources/extensions/gsd/templates/PREFERENCES.md +1 -0
  388. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +178 -1
  389. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +58 -0
  390. package/src/resources/extensions/gsd/tests/auto-session-encapsulation.test.ts +9 -5
  391. package/src/resources/extensions/gsd/tests/auto-supervisor.test.mjs +21 -4
  392. package/src/resources/extensions/gsd/tests/bootstrap-derive-state-db-open.test.ts +1 -1
  393. package/src/resources/extensions/gsd/tests/budget-prediction.test.ts +138 -211
  394. package/src/resources/extensions/gsd/tests/complete-slice-verification-gate.test.ts +142 -59
  395. package/src/resources/extensions/gsd/tests/complete-slice.test.ts +7 -4
  396. package/src/resources/extensions/gsd/tests/completed-at-reconcile.test.ts +89 -32
  397. package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +41 -23
  398. package/src/resources/extensions/gsd/tests/db-path-worktree-symlink.test.ts +3 -43
  399. package/src/resources/extensions/gsd/tests/debug-logger.test.ts +5 -3
  400. package/src/resources/extensions/gsd/tests/deferred-milestone-dir-4996.test.ts +116 -0
  401. package/src/resources/extensions/gsd/tests/discuss-empty-db-fallback.test.ts +22 -87
  402. package/src/resources/extensions/gsd/tests/discuss-queued-milestones.test.ts +7 -118
  403. package/src/resources/extensions/gsd/tests/discuss-tool-scope-leak.test.ts +18 -60
  404. package/src/resources/extensions/gsd/tests/doctor-orphan-milestone-4996.test.ts +100 -0
  405. package/src/resources/extensions/gsd/tests/double-merge-guard.test.ts +14 -76
  406. package/src/resources/extensions/gsd/tests/ensure-preconditions-guard-4996.test.ts +93 -0
  407. package/src/resources/extensions/gsd/tests/false-degraded-mode-warning.test.ts +22 -83
  408. package/src/resources/extensions/gsd/tests/finalize-timeout-guard.test.ts +1 -63
  409. package/src/resources/extensions/gsd/tests/find-missing-summaries-closed-runtime.test.ts +47 -0
  410. package/src/resources/extensions/gsd/tests/forensics-stuck-loops.test.ts +26 -1
  411. package/src/resources/extensions/gsd/tests/gitignore-bg-shell-runtime.test.ts +63 -0
  412. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +30 -0
  413. package/src/resources/extensions/gsd/tests/gsd-no-project-error-runtime.test.ts +81 -0
  414. package/src/resources/extensions/gsd/tests/headless-answers.test.ts +14 -4
  415. package/src/resources/extensions/gsd/tests/health-widget.test.ts +22 -12
  416. package/src/resources/extensions/gsd/tests/help-menu-coverage.test.ts +57 -0
  417. package/src/resources/extensions/gsd/tests/import-done-milestones-runtime.test.ts +145 -0
  418. package/src/resources/extensions/gsd/tests/init-prefs-routing.test.ts +64 -1
  419. package/src/resources/extensions/gsd/tests/integration/auto-worktree.test.ts +22 -0
  420. package/src/resources/extensions/gsd/tests/integration/token-savings.test.ts +0 -23
  421. package/src/resources/extensions/gsd/tests/memory-store.test.ts +128 -0
  422. package/src/resources/extensions/gsd/tests/memory-tools.test.ts +33 -1
  423. package/src/resources/extensions/gsd/tests/merge-self-branch-guard.test.ts +124 -0
  424. package/src/resources/extensions/gsd/tests/milestone-id-gap-reuse-4996.test.ts +152 -0
  425. package/src/resources/extensions/gsd/tests/model-router.test.ts +169 -8
  426. package/src/resources/extensions/gsd/tests/native-git-infra-errors.test.ts +50 -0
  427. package/src/resources/extensions/gsd/tests/orphaned-worktree-audit.test.ts +8 -0
  428. package/src/resources/extensions/gsd/tests/parallel-crash-recovery.test.ts +32 -43
  429. package/src/resources/extensions/gsd/tests/phases-merge-error-stops-auto.test.ts +4 -10
  430. package/src/resources/extensions/gsd/tests/preferences.test.ts +127 -0
  431. package/src/resources/extensions/gsd/tests/prompt-step-ordering.test.ts +16 -0
  432. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +7 -0
  433. package/src/resources/extensions/gsd/tests/quick-turn-end-cleanup.test.ts +6 -6
  434. package/src/resources/extensions/gsd/tests/register-hooks-compaction-checkpoint.test.ts +93 -0
  435. package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +168 -19
  436. package/src/resources/extensions/gsd/tests/slice-parallel-orchestrator.test.ts +7 -1
  437. package/src/resources/extensions/gsd/tests/smart-entry-complete.test.ts +23 -1
  438. package/src/resources/extensions/gsd/tests/system-context-message-routing.test.ts +101 -0
  439. package/src/resources/extensions/gsd/tests/token-profile.test.ts +51 -4
  440. package/src/resources/extensions/gsd/tests/turn-epoch.test.ts +7 -16
  441. package/src/resources/extensions/gsd/tests/unstructured-continue-context-injection.test.ts +5 -7
  442. package/src/resources/extensions/gsd/tests/uok-gitops-turn-action.test.ts +15 -1
  443. package/src/resources/extensions/gsd/tests/visualizer-overlay.test.ts +6 -6
  444. package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +15 -0
  445. package/src/resources/extensions/gsd/tools/memory-tools.ts +17 -1
  446. package/src/resources/extensions/gsd/unit-context-manifest.ts +8 -8
  447. package/src/resources/extensions/gsd/visualizer-overlay.ts +1 -1
  448. package/src/resources/extensions/gsd/watch/header-renderer.ts +3 -1
  449. package/src/resources/extensions/gsd/workflow-logger.ts +1 -0
  450. package/src/resources/extensions/gsd/worktree-command.ts +31 -44
  451. package/src/resources/extensions/gsd/worktree-session-state.ts +35 -0
  452. package/src/resources/extensions/mcp-client/index.ts +6 -3
  453. package/src/resources/extensions/mcp-client/tests/global-config.test.ts +91 -0
  454. package/src/resources/extensions/slash-commands/create-extension.ts +38 -24
  455. package/src/resources/skills/create-gsd-extension/SKILL.md +9 -5
  456. package/src/resources/skills/create-gsd-extension/references/custom-commands.md +1 -1
  457. package/src/resources/skills/create-gsd-extension/references/custom-rendering.md +5 -5
  458. package/src/resources/skills/create-gsd-extension/references/custom-tools.md +4 -4
  459. package/src/resources/skills/create-gsd-extension/references/custom-ui.md +6 -6
  460. package/src/resources/skills/create-gsd-extension/references/events-reference.md +3 -3
  461. package/src/resources/skills/create-gsd-extension/references/packaging-distribution.md +1 -1
  462. package/src/resources/skills/create-gsd-extension/references/remote-execution-overrides.md +3 -3
  463. package/src/resources/skills/create-gsd-extension/templates/extension-skeleton.ts +2 -2
  464. package/src/resources/skills/create-gsd-extension/templates/stateful-tool-skeleton.ts +3 -3
  465. package/src/resources/skills/create-gsd-extension/templates/templates.test.ts +58 -0
  466. package/src/resources/skills/create-gsd-extension/workflows/create-extension.md +32 -12
  467. package/dist/resources/extensions/browser-tools/tests/browser-tools-integration.test.mjs +0 -601
  468. package/dist/resources/extensions/browser-tools/tests/browser-tools-unit.test.cjs +0 -651
  469. package/dist/resources/extensions/browser-tools/tests/capture-sharp-optional.test.cjs +0 -91
  470. package/dist/resources/extensions/gsd/tests/auto-supervisor.test.mjs +0 -53
  471. package/dist/resources/extensions/gsd/tests/dist-redirect.mjs +0 -112
  472. package/dist/resources/extensions/gsd/tests/resolve-ts-hooks.mjs +0 -23
  473. package/dist/resources/extensions/gsd/tests/resolve-ts.mjs +0 -5
  474. package/dist/resources/skills/github-workflows/references/gh/tests/__init__.py +0 -0
  475. package/dist/resources/skills/github-workflows/references/gh/tests/test_github_project_setup.py +0 -608
  476. package/dist/web/standalone/.next/static/chunks/2826.e9f5195e91f9cad2.js +0 -11
  477. package/dist/web/standalone/.next/static/chunks/3621.fc7480022c972438.js +0 -20
  478. package/dist/web/standalone/.next/static/chunks/app/page-151349214571e2b6.js +0 -1
  479. package/dist/web/standalone/.next/static/chunks/main-app-d3d4c336195465f9.js +0 -1
  480. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ab5a8926e07ec673.js +0 -1
  481. package/dist/web/standalone/.next/static/chunks/webpack-2e68521d7c82f7c2.js +0 -1
  482. package/src/resources/extensions/gsd/tests/copy-planning-artifacts-samepath.test.ts +0 -22
  483. package/src/resources/extensions/gsd/tests/discuss-slice-structured-questions.test.ts +0 -47
  484. package/src/resources/extensions/gsd/tests/empty-content-abort-loop.test.ts +0 -75
  485. /package/dist/web/standalone/.next/static/{C1zT2kEfoLhDdbWPWKrXd → UF5VF4F1tB0miEtJS7LyX}/_buildManifest.js +0 -0
  486. /package/dist/web/standalone/.next/static/{C1zT2kEfoLhDdbWPWKrXd → UF5VF4F1tB0miEtJS7LyX}/_ssgManifest.js +0 -0
package/README.md CHANGED
@@ -27,34 +27,70 @@ One command. Walk away. Come back to a built project with clean git history.
27
27
 
28
28
  ---
29
29
 
30
- ## What's New in v2.77
30
+ ## What's New in v2.78
31
31
 
32
- ### Context Mode & Execution
32
+ ### Worktree Lifecycle & Forensics
33
33
 
34
- - **Context Mode** — a dispatch behavior that builds task-ready context automatically: it pulls in the most relevant project artifacts, prior session state, milestone/slice signals, and execution metadata before the model runs. This reduces manual prompt assembly, improves continuity across turns, and helps tasks start with the right files and constraints from the first dispatch. Enabled by default for new projects (opt out with `enabled: false`).
35
- - **Sandboxed execution tools** — added `gsd_exec_search`, `gsd_resume`, and sandboxed tool-output execution paths for context-mode flows, so search/resume and follow-up execution can run with tighter boundaries and more predictable runtime behavior.
36
- - **Preflight hardening** — milestone completion now performs stricter clean-root preflight checks and can auto-stash when needed, reducing accidental dirty-tree transitions and helping completion flows fail fast with clearer remediation.
34
+ - **Slice-cadence worktree collapse (#4765)** — new `git.collapse_cadence: "milestone" | "slice"` preference. With `slice`, each validated slice squash-merges to main immediately, shrinking the orphan window from milestone-size to slice-size. Pair with `git.milestone_resquash: true` to collapse per-slice commits into one milestone commit at completion.
35
+ - **Worktree telemetry (#4764)** — new journal events (`worktree-created`, `worktree-merged`, `worktree-orphaned`, `auto-exit`, `canonical-root-redirect`, `slice-merged`, `milestone-resquash`) and a `summarizeWorktreeTelemetry` aggregator that reports orphan breakdowns, merge durations, conflict counts, exit reasons, and unmerged-exit metrics.
36
+ - **`/gsd forensics` worktree section** — surfaces the telemetry above with two new anomalies: `worktree-orphan` and `worktree-unmerged-exit`.
37
+ - **Worktree-aware canonical milestone root (#4761)** — `resolveCanonicalMilestoneRoot` routes validators and cross-session readers through the live worktree, so milestone validation no longer silently reads stale project-root state.
38
+ - **Bootstrap orphan audit (#4762)** — in-progress milestones with commits ahead of main no longer get skipped; the audit emits a warning with commit count and worktree location so interrupted auto-runs are visible.
37
39
 
38
- ### Memory Architecture (ADR-013)
40
+ ### Auto Pipeline & Component System
39
41
 
40
- - **Memories table is now authoritative** — all memory reads and writes now flow through the `memories` table as the single source of truth. By removing split legacy paths, memory state stays consistent across agents, tools, and UI surfaces, with fewer reconciliation edge cases and less sync drift.
41
- - **Structured memory fields** — `structured_fields` adds typed metadata (instead of only free-form text), so memories can carry machine-usable attributes for more accurate retrieval, stronger filtering, and more dependable downstream automation and tooling.
42
- - **Dual-write migration completed** — the staged migration that wrote to both old and new paths is now fully landed, including decisions backfill and parity wiring across agents, MCP tools, and extract-learnings flows. That gives a safer upgrade path while preserving historical data and reducing cutover risk.
42
+ - **Unified component system** — skills, agents, pipelines, and marketplace are now one component model wired through runtime, dispatch, and telemetry, replacing per-surface plumbing.
43
+ - **UnitContextManifest v2 (#4924, #4934)** — auto dispatch runs through a typed manifest with declarative tools-policy and typed computed artifacts. CI guards the schema so drift fails fast.
44
+ - **Composer migration phase 3 (#4782)** — `complete-slice`, `research-milestone`, `run-uat`, and `reassess-roadmap` now build context through the manifest composer for a consistent shape across units.
45
+ - **Milestone scope classifier + pipeline variants (#4781)** — auto picks a pipeline variant from milestone shape, so research-heavy and execution-heavy milestones no longer share a one-size dispatch path.
46
+ - **Per-unit-type skill manifest resolver (#4779)** — skills wire into specific unit types instead of being globally on, with manifests expanded across the remaining types.
47
+ - **Single-writer-v3 control plane** — closes outstanding gaps in the durable-state writer model so concurrent writers can't desync workflow state.
48
+ - **Opt-in `reassess-roadmap` (#4778)** — gated behind the `skip_clean_reassess` preference per ADR-003 §4; auto no longer triggers reassessment unprompted.
43
49
 
44
- ### Skills, Tooling, and UX
50
+ ### Extensions Framework
45
51
 
46
- - **Skill coverage expanded** — 9 gap-closing skills landed and 6 planning/design skills were surfaced, improving end-to-end workflow coverage and making specialized guidance easier to discover at the point of use.
47
- - **Hook stack upgrades** — Layer 0 shell hooks and additional Layer 2 events were added to widen extension integration points: hooks can act earlier in command execution, and lifecycle consumers now receive richer event signals for orchestration, policy checks, and observability.
48
- - **TUI polish** — skill invocations now render in a dedicated chat-frame style for clearer scanability, and active-row overflow handling was fixed to prevent terminal layout breakage during long outputs.
52
+ - **Extension lifecycle commands** — `gsd extensions install / update / uninstall / list / info / validate` for npm, git, and local sources, with dependency warnings and user-metadata tracking.
53
+ - **Topological extension load order** — Kahn's-algorithm sort with surfaced `ExtensionLoadWarning`s, so dependent extensions resolve deterministically and misconfigurations are visible instead of silent.
54
+ - **cmux ↔ gsd decoupling** — static cross-imports replaced with a shared `cmux-events` contract and dynamic imports, isolating extension boundaries.
55
+ - **Extracted `@gsd-extensions/google-search` workspace** — first reference extension carved out of core; legacy in-tree source replaced with a deprecation stub.
56
+
57
+ ### Models, Agent, and UX
58
+
59
+ - **GPT-5.5 Codex support** — added across `gsd` and `pi-ai`, including `xhigh` thinking level for custom GPT-5.5 models.
60
+ - **Auth mode in `/model`** — providers display alongside auth mode for clearer routing.
61
+ - **Permission granularity picker** — Claude Code "Always Allow" prompts let you scope the grant instead of approving the broad case.
62
+ - **Headless auto default → `bypassPermissions` (#4657)** — Claude Code CLI headless auto-mode runs without permission prompts by default.
63
+ - **`skillFilter` for system prompts** — `pi-coding-agent` filters which skills are surfaced in `buildSystemPrompt`, with consumer exceptions guarded.
64
+ - **Visual postinstall (#4641)** — install shows a spinner/banner UX so first-run state is legible.
65
+ - **PR-risk verification** — risk prompt emits a copy-pasteable code block to make follow-up commands one step.
49
66
 
50
67
  ### Reliability & Safety
51
68
 
52
- - **Worktree and dispatch resilience** — crash-recovery dispatch is more robust, path derivation is safer, and worktree context fallback is improved, reducing stuck states and misrouted artifact operations after interruptions.
53
- - **DB/schema guardrails** — migration/index ordering and schema version stamping were tightened so upgrades apply deterministically and avoid index/version drift across mixed or legacy states.
54
- - **Security and validation fixes** — multiple hardening fixes landed across redaction paths, file/path checks, and pre-execution validation, closing false-positive/false-negative gaps while improving safety boundaries.
69
+ - **Major git-safety pass** — clarified TOCTOU ancestry guard, atomic sync-lock acquire with PID-verified stale override, `.git/index.lock` force-removal gated by 5-min age, `GIT_DIR`/`GIT_WORK_TREE`/`GIT_INDEX_FILE` stripped from env overlays, rebase/cherry-pick/revert state detected and aborted in recovery, working tree stashed before `reset --hard` in self-heal/rollback, worktree create guarded against unborn branches, and user hooks + `commit.gpgsign` honored on auto-commits.
70
+ - **Atomic `.gsd/` state writes** — file-locks now actually lock and throw on contention; appends are lock-wrapped to prevent interleaved writes.
71
+ - **Compaction correctness (#4665)** — fixed chunker/truncation mismatch and silent chunk-drops that produced degenerate or empty summaries.
72
+ - **Write-gate (#4950)** — fail-closed depth confirmation, EXDEV-safe snapshot rename, opt-out persistence default, off-by-one max-attempts fix, exception capture in `gate.execute`, and audit/DB rows for unknown gate ids.
73
+ - **Auto state machine** — deterministic policy errors classified non-retriable (#4973), depth-verification bypass for non-interactive sessions, baseline restored between units (#4961), `restoreToolBaseline` gated by `isAutoMode` (#4966).
74
+ - **Slice + crash recovery** — slice orchestrator state persists across crashes; ancestry-guarded force-reset, detached-HEAD refusal, and stash-by-ref recovery.
75
+ - **Empty-turn recovery** — Claude Code CLI tool-block shape canonicalized so empty-turn recovery matches real provider output.
55
76
 
56
77
  See the full [Changelog](./CHANGELOG.md) for details on every release.
57
78
 
79
+ <details>
80
+ <summary>v2.77 highlights</summary>
81
+
82
+ - **Context Mode** — dispatch builds task-ready context automatically (artifacts, prior session, milestone/slice signals, execution metadata); enabled by default for new projects
83
+ - **Sandboxed execution tools** — `gsd_exec_search`, `gsd_resume`, and sandboxed tool-output paths for context-mode flows
84
+ - **Memory architecture (ADR-013)** — `memories` table is now authoritative; `structured_fields` adds typed metadata; dual-write migration landed with decisions backfill
85
+ - **Skill coverage** — 9 gap-closing skills landed plus 6 planning/design skills surfaced
86
+ - **Hook stack** — Layer 0 shell hooks and additional Layer 2 lifecycle events
87
+ - **TUI polish** — dedicated chat-frame style for skill invocations; active-row overflow fixes
88
+ - **Worktree + dispatch resilience** — crash-recovery dispatch hardened, safer path derivation, improved worktree context fallback
89
+ - **DB/schema guardrails** — migration/index ordering and schema version stamping tightened
90
+ - **Preflight hardening** — milestone completion enforces stricter clean-root checks with auto-stash
91
+
92
+ </details>
93
+
58
94
  <details>
59
95
  <summary>v2.75 highlights</summary>
60
96
 
@@ -589,19 +625,19 @@ Start GSD with `gsd --debug` to enable structured JSONL diagnostic logging. Debu
589
625
 
590
626
  ### Token Optimization
591
627
 
592
- GSD includes a coordinated token optimization system that reduces usage by 40-60% on cost-sensitive workloads. Set a single preference to coordinate model selection, phase skipping, and context compression:
628
+ GSD includes a coordinated token optimization system that reduces usage by 40-60% on cost-sensitive workloads. Set a single preference to coordinate model tier selection, phase skipping, and context compression:
593
629
 
594
630
  ```yaml
595
631
  token_profile: budget # or balanced (default), quality
596
632
  ```
597
633
 
598
- | Profile | Savings | What It Does |
599
- | ---------- | ------- | -------------------------------------------------------------- |
600
- | `budget` | 40-60% | Cheap models, skip research/reassess, minimal context inlining |
601
- | `balanced` | 10-20% | Default models, skip slice research, standard context |
602
- | `quality` | 0% | All phases, all context, full model power |
634
+ | Profile | Savings | What It Does |
635
+ | ---------- | ------- | -------------------------------------------------------------------------------- |
636
+ | `budget` | 40-60% | Light/standard tier defaults, skip research/reassess, minimal context inlining |
637
+ | `balanced` | 10-20% | Standard tier for core work, light tier for simple work, standard context |
638
+ | `quality` | 0% | Heavy tier for planning, standard tier for core work, full context |
603
639
 
604
- **Complexity-based routing** automatically classifies tasks as simple/standard/complex and routes to appropriate models. Simple docs tasks get Haiku; complex architectural work gets Opus. The classification is heuristic (sub-millisecond, no LLM calls) and learns from outcomes via a persistent routing history.
640
+ **Complexity-based routing** automatically classifies tasks as simple/standard/complex and routes to appropriate available models. Token profiles define provider-agnostic tier intentions, so simple docs tasks use a light-tier configured model and complex architectural work can use a heavy-tier configured model. The classification is heuristic (sub-millisecond, no LLM calls) and learns from outcomes via a persistent routing history.
605
641
 
606
642
  **Budget pressure** graduates model downgrading as you approach your budget ceiling — 50%, 75%, and 90% thresholds progressively shift work to cheaper tiers.
607
643
 
@@ -1,6 +1,9 @@
1
1
  // GSD2 — Claude CLI binary detection for onboarding
2
2
  // Lightweight check used at onboarding time (before extensions load).
3
3
  // The full readiness check with caching lives in the claude-code-cli extension.
4
+ //
5
+ // Set GSD_CLAUDE_DEBUG=1 to log probe output to stderr. Useful when
6
+ // diagnosing platform-specific detection failures (Issue #4997).
4
7
  import { execFileSync } from 'node:child_process';
5
8
  /**
6
9
  * Platform-correct binary name for the Claude Code CLI.
@@ -20,60 +23,116 @@ export const CLAUDE_COMMAND = process.platform === 'win32' ? 'claude.cmd' : 'cla
20
23
  * expose a bare `claude` shim. Try all three so no valid install is missed.
21
24
  */
22
25
  const CLAUDE_COMMAND_CANDIDATES = process.platform === 'win32' ? [CLAUDE_COMMAND, 'claude.exe', 'claude'] : [CLAUDE_COMMAND];
26
+ const VERSION_TIMEOUT_MS = 5_000;
27
+ // Auth probe needs more headroom on Windows because the spawn goes through
28
+ // cmd.exe → claude.cmd → node → Claude CLI.
29
+ const AUTH_TIMEOUT_MS = 15_000;
30
+ function debugLog(...parts) {
31
+ if (process.env.GSD_CLAUDE_DEBUG) {
32
+ process.stderr.write(`[claude-cli-check] ${parts.map(p => (typeof p === 'string' ? p : JSON.stringify(p))).join(' ')}\n`);
33
+ }
34
+ }
23
35
  /**
24
- * Try to run `args` against each candidate binary.
25
- * Returns the output buffer on first success, throws the last error if all fail.
36
+ * Find the first candidate that responds to `--version`. Returns the
37
+ * candidate name on success, null if none worked.
38
+ *
39
+ * On Windows with `shell: true`, a missing candidate surfaces as a
40
+ * non-zero exit from cmd.exe rather than ENOENT — so we cannot rely on
41
+ * the error code to decide "try next". Treat any failure as "try next"
42
+ * for the version probe.
26
43
  */
27
- function execClaudeCheck(args) {
28
- let lastError;
44
+ function findWorkingCommand() {
29
45
  for (const command of CLAUDE_COMMAND_CANDIDATES) {
30
46
  try {
31
- return execFileSync(command, args, {
32
- timeout: 5_000,
47
+ execFileSync(command, ['--version'], {
48
+ timeout: VERSION_TIMEOUT_MS,
33
49
  stdio: 'pipe',
34
50
  shell: process.platform === 'win32',
35
51
  });
52
+ debugLog('version probe ok via', command);
53
+ return command;
36
54
  }
37
55
  catch (error) {
38
- lastError = error;
39
- const code = error?.code;
40
- // EINVAL can surface on Windows Git Bash for .cmd spawn failures.
41
- if (code === 'ENOENT' || code === 'EINVAL')
42
- continue;
43
- throw error;
56
+ debugLog('version probe failed for', command, 'code=', error?.code);
57
+ continue;
44
58
  }
45
59
  }
46
- throw lastError ?? new Error(`Claude CLI not found (tried: ${CLAUDE_COMMAND_CANDIDATES.join(', ')})`);
60
+ return null;
47
61
  }
48
62
  /**
49
- * Check if the `claude` binary is installed (regardless of auth state).
63
+ * Decide auth state from `claude auth status` output.
64
+ *
65
+ * Newer Claude CLI builds emit JSON with a `loggedIn` boolean. Older builds
66
+ * emit free-form text. Prefer the structured signal; fall back to a text
67
+ * heuristic. The text heuristic only covers English phrasing.
50
68
  */
51
- export function isClaudeBinaryInstalled() {
52
- try {
53
- execClaudeCheck(['--version']);
54
- return true;
69
+ function parseAuthStatus(output) {
70
+ const trimmed = output.trim();
71
+ if (!trimmed)
72
+ return null;
73
+ if (trimmed.startsWith('{')) {
74
+ try {
75
+ const parsed = JSON.parse(trimmed);
76
+ if (typeof parsed.loggedIn === 'boolean') {
77
+ return parsed.loggedIn;
78
+ }
79
+ }
80
+ catch {
81
+ // Fall through to text heuristic.
82
+ }
55
83
  }
56
- catch {
84
+ const lower = trimmed.toLowerCase();
85
+ if (/not logged in|no credentials|unauthenticated|not authenticated/.test(lower)) {
57
86
  return false;
58
87
  }
88
+ if (/logged in|authenticated|signed in|email|subscription/.test(lower)) {
89
+ return true;
90
+ }
91
+ return null;
59
92
  }
60
- /**
61
- * Check if the `claude` CLI is installed AND authenticated.
62
- */
63
- export function isClaudeCliReady() {
93
+ function probeAuth(command) {
94
+ // Try --json first (newer CLIs).
64
95
  try {
65
- execClaudeCheck(['--version']);
96
+ const out = execFileSync(command, ['auth', 'status', '--json'], {
97
+ timeout: AUTH_TIMEOUT_MS,
98
+ stdio: 'pipe',
99
+ shell: process.platform === 'win32',
100
+ }).toString();
101
+ debugLog('auth status --json output:', out.slice(0, 200));
102
+ const parsed = parseAuthStatus(out);
103
+ if (parsed !== null)
104
+ return parsed;
66
105
  }
67
- catch {
68
- return false;
106
+ catch (error) {
107
+ debugLog('auth status --json threw:', error.message?.slice(0, 200));
69
108
  }
109
+ // Fallback: plain `auth status` (older CLIs that don't accept --json).
70
110
  try {
71
- const output = execClaudeCheck(['auth', 'status'])
72
- .toString()
73
- .toLowerCase();
74
- return !(/not logged in|no credentials|unauthenticated|not authenticated/i.test(output));
111
+ const out = execFileSync(command, ['auth', 'status'], {
112
+ timeout: AUTH_TIMEOUT_MS,
113
+ stdio: 'pipe',
114
+ shell: process.platform === 'win32',
115
+ }).toString();
116
+ debugLog('auth status output:', out.slice(0, 200));
117
+ return parseAuthStatus(out);
75
118
  }
76
- catch {
77
- return false;
119
+ catch (error) {
120
+ debugLog('auth status threw:', error.message?.slice(0, 200));
121
+ return null;
78
122
  }
79
123
  }
124
+ /**
125
+ * Check if the `claude` binary is installed (regardless of auth state).
126
+ */
127
+ export function isClaudeBinaryInstalled() {
128
+ return findWorkingCommand() !== null;
129
+ }
130
+ /**
131
+ * Check if the `claude` CLI is installed AND authenticated.
132
+ */
133
+ export function isClaudeCliReady() {
134
+ const command = findWorkingCommand();
135
+ if (!command)
136
+ return false;
137
+ return probeAuth(command) === true;
138
+ }
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Subcommands that must bypass the managed-resource-mismatch gate.
3
+ *
4
+ * When the synced resource manifest claims a newer gsd version than the
5
+ * running binary, exitIfManagedResourcesAreNewer() blocks every command
6
+ * with a "Version mismatch detected" diagnostic. The `update` subcommand
7
+ * MUST bypass that gate so the user can recover by upgrading the binary —
8
+ * otherwise they're stuck in a broken state with no escape hatch.
9
+ *
10
+ * Any new bypassed subcommand goes here. cli.ts dispatches on this
11
+ * predicate before calling exitIfManagedResourcesAreNewer().
12
+ */
13
+ export declare function shouldBypassManagedResourceMismatchGate(firstMessage: string | undefined): boolean;
@@ -0,0 +1,17 @@
1
+ // Policy helpers for cli.ts — extracted as pure functions so they can be
2
+ // unit-tested without executing cli.ts's top-level script body.
3
+ /**
4
+ * Subcommands that must bypass the managed-resource-mismatch gate.
5
+ *
6
+ * When the synced resource manifest claims a newer gsd version than the
7
+ * running binary, exitIfManagedResourcesAreNewer() blocks every command
8
+ * with a "Version mismatch detected" diagnostic. The `update` subcommand
9
+ * MUST bypass that gate so the user can recover by upgrading the binary —
10
+ * otherwise they're stuck in a broken state with no escape hatch.
11
+ *
12
+ * Any new bypassed subcommand goes here. cli.ts dispatches on this
13
+ * predicate before calling exitIfManagedResourcesAreNewer().
14
+ */
15
+ export function shouldBypassManagedResourceMismatchGate(firstMessage) {
16
+ return firstMessage === 'update';
17
+ }
package/dist/cli.js CHANGED
@@ -1,4 +1,3 @@
1
- import { AuthStorage, DefaultResourceLoader, ModelRegistry, runPackageCommand, SettingsManager, SessionManager, createAgentSession, InteractiveMode, runPrintMode, runRpcMode, } from '@gsd/pi-coding-agent';
2
1
  import { readFileSync } from 'node:fs';
3
2
  import { join } from 'node:path';
4
3
  import { agentDir, sessionsDir, authFilePath } from './app-paths.js';
@@ -9,6 +8,7 @@ import { migratePiCredentials } from './pi-migration.js';
9
8
  import { shouldRunOnboarding, runOnboarding } from './onboarding.js';
10
9
  import chalk from 'chalk';
11
10
  import { checkForUpdates } from './update-check.js';
11
+ import { shouldBypassManagedResourceMismatchGate } from './cli-policy.js';
12
12
  import { printHelp, printSubcommandHelp } from './help-text.js';
13
13
  import { applySecurityOverrides } from './security-overrides.js';
14
14
  import { validateConfiguredModel } from './startup-model-validation.js';
@@ -17,8 +17,11 @@ import { buildHeadlessAutoArgs, parseCliArgs, runWebCliBranch, migrateLegacyFlat
17
17
  import { stopWebMode } from './web-mode.js';
18
18
  import { getProjectSessionsDir } from './project-sessions.js';
19
19
  import { markStartup, printStartupTimings } from './startup-timings.js';
20
- import { bootstrapRtk, GSD_RTK_DISABLED_ENV } from './rtk.js';
21
- import { loadEffectiveGSDPreferences } from './resources/extensions/gsd/preferences.js';
20
+ import { applyRtkProcessEnv, GSD_RTK_DISABLED_ENV, isTruthy } from './rtk-shared.js';
21
+ let piCodingAgentModulePromise;
22
+ function loadPiCodingAgentModule() {
23
+ return (piCodingAgentModulePromise ??= import('@gsd/pi-coding-agent'));
24
+ }
22
25
  // ---------------------------------------------------------------------------
23
26
  // V8 compile cache — Node 22+ can cache compiled bytecode across runs,
24
27
  // eliminating repeated parse/compile overhead for unchanged modules.
@@ -129,27 +132,53 @@ if (process.argv.includes('--help') || process.argv.includes('-h')) {
129
132
  // so concurrent callers await the same initialization.
130
133
  let rtkBootstrapPromise;
131
134
  async function doRtkBootstrap() {
135
+ let rtkStatus;
136
+ let rtkDisabled = isTruthy(process.env[GSD_RTK_DISABLED_ENV]);
132
137
  // RTK is opt-in via experimental.rtk preference. Default: disabled.
133
138
  // Honor GSD_RTK_DISABLED if already explicitly set in the environment
134
139
  // (env var takes precedence over preferences for manual override).
135
- if (!process.env[GSD_RTK_DISABLED_ENV]) {
140
+ if (!rtkDisabled) {
141
+ const { loadEffectiveGSDPreferences } = await import('./resources/extensions/gsd/preferences.js');
136
142
  const prefs = loadEffectiveGSDPreferences();
137
143
  const rtkEnabled = prefs?.preferences.experimental?.rtk === true;
138
144
  if (!rtkEnabled) {
139
145
  process.env[GSD_RTK_DISABLED_ENV] = '1';
146
+ rtkDisabled = true;
140
147
  }
141
148
  }
142
- const rtkStatus = await bootstrapRtk();
149
+ markStartup('rtkPreferenceCheck');
150
+ if (rtkDisabled) {
151
+ applyRtkProcessEnv(process.env);
152
+ rtkStatus = {
153
+ enabled: false,
154
+ supported: true,
155
+ available: false,
156
+ source: 'disabled',
157
+ reason: `${GSD_RTK_DISABLED_ENV} is set`,
158
+ };
159
+ }
160
+ else {
161
+ const { bootstrapRtk } = await import('./rtk.js');
162
+ rtkStatus = await bootstrapRtk();
163
+ }
143
164
  markStartup('bootstrapRtk');
144
165
  if (!rtkStatus.available && rtkStatus.supported && rtkStatus.enabled && rtkStatus.reason) {
145
166
  process.stderr.write(`[gsd] Warning: RTK unavailable — continuing without shell-command compression (${rtkStatus.reason}).\n`);
146
167
  }
147
168
  }
148
169
  function ensureRtkBootstrap() {
149
- return (rtkBootstrapPromise ??= doRtkBootstrap());
150
- }
151
- // `gsd update` — update to the latest version via npm
152
- if (cliFlags.messages[0] === 'update') {
170
+ if (!rtkBootstrapPromise) {
171
+ markStartup('preRtkBootstrap');
172
+ rtkBootstrapPromise = doRtkBootstrap();
173
+ }
174
+ return rtkBootstrapPromise;
175
+ }
176
+ // `gsd update` — update to the latest version via npm.
177
+ // MUST run before exitIfManagedResourcesAreNewer(): when the bundled resource
178
+ // manifest is from a newer version than the running binary, every other
179
+ // command is blocked — only `update` should bypass the gate so the user can
180
+ // actually upgrade out of the broken state. See shouldBypassManagedResourceMismatchGate.
181
+ if (shouldBypassManagedResourceMismatchGate(cliFlags.messages[0])) {
153
182
  const { runUpdate } = await import('./update-cmd.js');
154
183
  await runUpdate();
155
184
  process.exit(0);
@@ -246,20 +275,25 @@ const hasSubcommand = cliFlags.messages.length > 0;
246
275
  if (!process.stdin.isTTY && !isPrintMode && !hasSubcommand && !cliFlags.listModels && !cliFlags.web) {
247
276
  printNonTtyErrorAndExit(undefined, false);
248
277
  }
249
- const packageCommand = await runPackageCommand({
250
- appName: 'gsd',
251
- args: process.argv.slice(2),
252
- cwd: process.cwd(),
253
- agentDir,
254
- stdout: process.stdout,
255
- stderr: process.stderr,
256
- allowedCommands: new Set(['install', 'remove', 'list']),
257
- });
258
- if (packageCommand.handled) {
259
- process.exit(packageCommand.exitCode);
278
+ const packageCommandNames = new Set(['install', 'remove', 'list']);
279
+ if (packageCommandNames.has(cliFlags.messages[0])) {
280
+ const { runPackageCommand } = await loadPiCodingAgentModule();
281
+ const packageCommand = await runPackageCommand({
282
+ appName: 'gsd',
283
+ args: process.argv.slice(2),
284
+ cwd: process.cwd(),
285
+ agentDir,
286
+ stdout: process.stdout,
287
+ stderr: process.stderr,
288
+ allowedCommands: packageCommandNames,
289
+ });
290
+ if (packageCommand.handled) {
291
+ process.exit(packageCommand.exitCode);
292
+ }
260
293
  }
261
294
  // `gsd config` — replay the setup wizard and exit
262
295
  if (cliFlags.messages[0] === 'config') {
296
+ const { AuthStorage } = await loadPiCodingAgentModule();
263
297
  const authStorage = AuthStorage.create(authFilePath);
264
298
  loadStoredEnvKeys(authStorage);
265
299
  await runOnboarding(authStorage);
@@ -291,6 +325,7 @@ if (cliFlags.web || (cliFlags.messages[0] === 'web' && cliFlags.messages[1] !==
291
325
  }
292
326
  // `gsd sessions` — list past sessions and pick one to resume
293
327
  if (cliFlags.messages[0] === 'sessions') {
328
+ const { SessionManager } = await loadPiCodingAgentModule();
294
329
  const cwd = process.cwd();
295
330
  const safePath = `--${cwd.replace(/^[/\\]/, '').replace(/[/\\:]/g, '-')}--`;
296
331
  const projectSessionsDir = join(sessionsDir, safePath);
@@ -380,6 +415,35 @@ function flushPendingProviderRegistrations(resourceLoader, modelRegistry) {
380
415
  if (cliFlags.messages[0] === 'auto') {
381
416
  await runHeadlessFromAuto(buildHeadlessAutoArgs(cliFlags));
382
417
  }
418
+ // ---------------------------------------------------------------------------
419
+ // Worktree subcommand — `gsd worktree <list|merge|clean|remove>`
420
+ // ---------------------------------------------------------------------------
421
+ if (!isPrintMode &&
422
+ cliFlags.listModels === undefined &&
423
+ (cliFlags.messages[0] === 'worktree' || cliFlags.messages[0] === 'wt')) {
424
+ const { handleList, handleMerge, handleClean, handleRemove } = await import('./worktree-cli.js');
425
+ const sub = cliFlags.messages[1];
426
+ const subArgs = cliFlags.messages.slice(2);
427
+ if (!sub || sub === 'list') {
428
+ await handleList(process.cwd());
429
+ }
430
+ else if (sub === 'merge') {
431
+ await handleMerge(process.cwd(), subArgs);
432
+ }
433
+ else if (sub === 'clean') {
434
+ await handleClean(process.cwd());
435
+ }
436
+ else if (sub === 'remove' || sub === 'rm') {
437
+ await handleRemove(process.cwd(), subArgs);
438
+ }
439
+ else {
440
+ process.stderr.write(`Unknown worktree command: ${sub}\n`);
441
+ process.stderr.write('Commands: list, merge [name], clean, remove <name>\n');
442
+ }
443
+ process.exit(0);
444
+ }
445
+ const { AuthStorage, DefaultResourceLoader, ModelRegistry, SettingsManager, SessionManager, createAgentSession, InteractiveMode, runPrintMode, runRpcMode, } = await loadPiCodingAgentModule();
446
+ markStartup('loadPiCodingAgent');
383
447
  // Pi's tool bootstrap can mis-detect already-installed fd/rg on some systems
384
448
  // because spawnSync(..., ["--version"]) returns EPERM despite a zero exit code.
385
449
  // Provision local managed binaries first so Pi sees them without probing PATH.
@@ -431,11 +495,7 @@ if (cliFlags.listModels !== undefined) {
431
495
  additionalExtensionPaths: cliFlags.extensions.length > 0 ? cliFlags.extensions : undefined,
432
496
  });
433
497
  await listModelsLoader.reload();
434
- const listModelsExtensions = listModelsLoader.getExtensions();
435
- for (const { name, config } of listModelsExtensions.runtime.pendingProviderRegistrations) {
436
- modelRegistry.registerProvider(name, config);
437
- }
438
- listModelsExtensions.runtime.pendingProviderRegistrations = [];
498
+ flushPendingProviderRegistrations(listModelsLoader, modelRegistry);
439
499
  const models = modelRegistry.getAvailable();
440
500
  if (models.length === 0) {
441
501
  console.log('No models available. Set API keys in environment variables.');
@@ -483,6 +543,7 @@ if (!settingsManager.getQuietStartup()) {
483
543
  if (!settingsManager.getCollapseChangelog()) {
484
544
  settingsManager.setCollapseChangelog(true);
485
545
  }
546
+ markStartup('startupSettings');
486
547
  // ---------------------------------------------------------------------------
487
548
  // Print / subagent mode — single-shot execution, no TTY required
488
549
  // ---------------------------------------------------------------------------
@@ -515,7 +576,7 @@ if (isPrintMode) {
515
576
  flushPendingProviderRegistrations(resourceLoader, modelRegistry);
516
577
  migrateAnthropicDefaultToClaudeCode({
517
578
  authStorage,
518
- isClaudeCodeReady: modelRegistry.isProviderRequestReady('claude-code'),
579
+ isClaudeCodeReady: () => modelRegistry.isProviderRequestReady('claude-code'),
519
580
  settingsManager,
520
581
  modelRegistry,
521
582
  });
@@ -577,31 +638,6 @@ if (isPrintMode) {
577
638
  process.exit(0);
578
639
  }
579
640
  // ---------------------------------------------------------------------------
580
- // Worktree subcommand — `gsd worktree <list|merge|clean|remove>`
581
- // ---------------------------------------------------------------------------
582
- if (cliFlags.messages[0] === 'worktree' || cliFlags.messages[0] === 'wt') {
583
- const { handleList, handleMerge, handleClean, handleRemove } = await import('./worktree-cli.js');
584
- const sub = cliFlags.messages[1];
585
- const subArgs = cliFlags.messages.slice(2);
586
- if (!sub || sub === 'list') {
587
- await handleList(process.cwd());
588
- }
589
- else if (sub === 'merge') {
590
- await handleMerge(process.cwd(), subArgs);
591
- }
592
- else if (sub === 'clean') {
593
- await handleClean(process.cwd());
594
- }
595
- else if (sub === 'remove' || sub === 'rm') {
596
- await handleRemove(process.cwd(), subArgs);
597
- }
598
- else {
599
- process.stderr.write(`Unknown worktree command: ${sub}\n`);
600
- process.stderr.write('Commands: list, merge [name], clean, remove <name>\n');
601
- }
602
- process.exit(0);
603
- }
604
- // ---------------------------------------------------------------------------
605
641
  // Worktree flag (-w) — create/resume a worktree for the interactive session
606
642
  // ---------------------------------------------------------------------------
607
643
  if (cliFlags.worktree) {
@@ -613,11 +649,12 @@ if (cliFlags.worktree) {
613
649
  // ---------------------------------------------------------------------------
614
650
  if (!cliFlags.worktree && !isPrintMode) {
615
651
  try {
616
- const { handleStatusBanner } = await import('./worktree-cli.js');
617
- await handleStatusBanner(process.cwd());
652
+ const { showWorktreeStatusBanner } = await import('./worktree-status-banner.js');
653
+ showWorktreeStatusBanner(process.cwd());
618
654
  }
619
655
  catch { /* non-fatal */ }
620
656
  }
657
+ markStartup('worktreeStatusBanner');
621
658
  // ---------------------------------------------------------------------------
622
659
  // Auto-redirect: `gsd auto` with piped stdout → headless mode (#2732)
623
660
  // When stdout is not a TTY (e.g. `gsd auto | cat`, `gsd auto > file`),
@@ -651,7 +688,9 @@ markStartup('initResources');
651
688
  // Overlap resource loading with session manager setup — both are independent.
652
689
  // resourceLoader.reload() is the most expensive step (jiti compilation), so
653
690
  // starting it early shaves ~50-200ms off interactive startup.
654
- const resourceLoader = buildResourceLoader(agentDir);
691
+ const resourceLoader = await buildResourceLoader(agentDir, {
692
+ additionalExtensionPaths: cliFlags.extensions.length > 0 ? cliFlags.extensions : undefined,
693
+ });
655
694
  const resourceLoadPromise = resourceLoader.reload();
656
695
  // While resources load, let session manager finish any async I/O it needs.
657
696
  // Then await the resource promise before creating the agent session.
@@ -660,10 +699,11 @@ markStartup('resourceLoader.reload');
660
699
  flushPendingProviderRegistrations(resourceLoader, modelRegistry);
661
700
  migrateAnthropicDefaultToClaudeCode({
662
701
  authStorage,
663
- isClaudeCodeReady: modelRegistry.isProviderRequestReady('claude-code'),
702
+ isClaudeCodeReady: () => modelRegistry.isProviderRequestReady('claude-code'),
664
703
  settingsManager,
665
704
  modelRegistry,
666
705
  });
706
+ markStartup('providerMigrations');
667
707
  const { session, extensionsResult, modelFallbackMessage: interactiveFallbackMsg } = await createAgentSession({
668
708
  authStorage,
669
709
  modelRegistry,
@@ -14,6 +14,28 @@
14
14
  * bypassing the extension loader's jiti setup (#1137).
15
15
  */
16
16
  import type { GSDState } from './resources/extensions/gsd/types.js';
17
+ /**
18
+ * Resolve the GSD extensions root for headless-query. Prefers the synced
19
+ * agent directory (so headless-query loads the same extension copy as
20
+ * interactive/auto modes — #3471) and falls back to the bundled source
21
+ * resource for source-tree dev workflows.
22
+ *
23
+ * Pure on the given inputs (env + fs probe + bundled resolver) so the
24
+ * #3471 contract can be exercised in tests without spawning a subprocess.
25
+ */
26
+ export declare function resolveGsdAgentExtensionsDir(env?: NodeJS.ProcessEnv): string;
27
+ /**
28
+ * Decide whether headless-query should load extensions from the agent
29
+ * sync directory (#3471) or fall back to bundled source. Returns the
30
+ * agent dir alongside the decision so a caller can use it directly.
31
+ */
32
+ export declare function shouldUseAgentExtensionsDir(opts: {
33
+ env?: NodeJS.ProcessEnv;
34
+ fileExists?: (path: string) => boolean;
35
+ }): {
36
+ agentDir: string;
37
+ useAgentDir: boolean;
38
+ };
17
39
  export interface QuerySnapshot {
18
40
  state: GSDState;
19
41
  next: {