gsd-pi 2.78.1-dev.84a383f51 → 2.78.1

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 (474) hide show
  1. package/README.md +7 -7
  2. package/dist/cli.js +55 -95
  3. package/dist/headless-query.d.ts +0 -22
  4. package/dist/headless-query.js +4 -24
  5. package/dist/headless.d.ts +0 -10
  6. package/dist/headless.js +1 -16
  7. package/dist/loader.js +10 -7
  8. package/dist/onboarding.d.ts +0 -10
  9. package/dist/onboarding.js +2 -2
  10. package/dist/provider-migrations.d.ts +2 -2
  11. package/dist/provider-migrations.js +2 -5
  12. package/dist/resource-loader.d.ts +2 -5
  13. package/dist/resource-loader.js +5 -28
  14. package/dist/resources/extensions/browser-tools/tests/browser-tools-integration.test.mjs +601 -0
  15. package/dist/resources/extensions/browser-tools/tests/browser-tools-unit.test.cjs +651 -0
  16. package/dist/resources/extensions/browser-tools/tests/capture-sharp-optional.test.cjs +91 -0
  17. package/dist/resources/extensions/gsd/auto/loop.js +0 -23
  18. package/dist/resources/extensions/gsd/auto/phases.js +2 -2
  19. package/dist/resources/extensions/gsd/auto/run-unit.js +1 -3
  20. package/dist/resources/extensions/gsd/auto/session.js +0 -3
  21. package/dist/resources/extensions/gsd/auto-recovery.js +4 -43
  22. package/dist/resources/extensions/gsd/auto-start.js +1 -1
  23. package/dist/resources/extensions/gsd/auto-tool-tracking.js +2 -2
  24. package/dist/resources/extensions/gsd/auto-worktree.js +0 -30
  25. package/dist/resources/extensions/gsd/auto.js +5 -14
  26. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +2 -14
  27. package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +5 -7
  28. package/dist/resources/extensions/gsd/bootstrap/query-tools.js +2 -2
  29. package/dist/resources/extensions/gsd/bootstrap/register-extension.js +4 -5
  30. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +31 -94
  31. package/dist/resources/extensions/gsd/bootstrap/register-shortcuts.js +6 -11
  32. package/dist/resources/extensions/gsd/bootstrap/system-context.js +8 -34
  33. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +2 -38
  34. package/dist/resources/extensions/gsd/commands/catalog.js +5 -69
  35. package/dist/resources/extensions/gsd/commands/handlers/core.js +1 -22
  36. package/dist/resources/extensions/gsd/commands-mcp-status.js +1 -3
  37. package/dist/resources/extensions/gsd/commands-prefs-wizard.js +1 -10
  38. package/dist/resources/extensions/gsd/dashboard-overlay.js +1 -1
  39. package/dist/resources/extensions/gsd/docs/preferences-reference.md +0 -4
  40. package/dist/resources/extensions/gsd/doctor-runtime-checks.js +1 -39
  41. package/dist/resources/extensions/gsd/error-classifier.js +1 -1
  42. package/dist/resources/extensions/gsd/forensics.js +2 -2
  43. package/dist/resources/extensions/gsd/git-service.js +5 -12
  44. package/dist/resources/extensions/gsd/gsd-db.js +2 -11
  45. package/dist/resources/extensions/gsd/guided-flow.js +23 -23
  46. package/dist/resources/extensions/gsd/memory-store.js +31 -66
  47. package/dist/resources/extensions/gsd/model-router.js +9 -114
  48. package/dist/resources/extensions/gsd/native-git-bridge.js +1 -7
  49. package/dist/resources/extensions/gsd/preferences-models.js +15 -91
  50. package/dist/resources/extensions/gsd/preferences-types.js +0 -2
  51. package/dist/resources/extensions/gsd/preferences-validation.js +0 -32
  52. package/dist/resources/extensions/gsd/preferences.js +3 -5
  53. package/dist/resources/extensions/gsd/prompt-loader.js +12 -23
  54. package/dist/resources/extensions/gsd/slice-parallel-orchestrator.js +3 -9
  55. package/dist/resources/extensions/gsd/state.js +0 -42
  56. package/dist/resources/extensions/gsd/templates/PREFERENCES.md +0 -1
  57. package/dist/resources/extensions/gsd/tests/auto-supervisor.test.mjs +53 -0
  58. package/dist/resources/extensions/gsd/tests/dist-redirect.mjs +112 -0
  59. package/dist/resources/extensions/gsd/tests/resolve-ts-hooks.mjs +23 -0
  60. package/dist/resources/extensions/gsd/tests/resolve-ts.mjs +5 -0
  61. package/dist/resources/extensions/gsd/tools/memory-tools.js +1 -18
  62. package/dist/resources/extensions/gsd/visualizer-overlay.js +1 -1
  63. package/dist/resources/extensions/gsd/watch/header-renderer.js +1 -3
  64. package/dist/resources/extensions/gsd/worktree-command.js +46 -26
  65. package/dist/resources/extensions/mcp-client/index.js +3 -6
  66. package/dist/resources/extensions/slash-commands/create-extension.js +22 -36
  67. package/dist/resources/skills/create-gsd-extension/SKILL.md +5 -9
  68. package/dist/resources/skills/create-gsd-extension/references/custom-commands.md +1 -1
  69. package/dist/resources/skills/create-gsd-extension/references/custom-rendering.md +5 -5
  70. package/dist/resources/skills/create-gsd-extension/references/custom-tools.md +4 -4
  71. package/dist/resources/skills/create-gsd-extension/references/custom-ui.md +6 -6
  72. package/dist/resources/skills/create-gsd-extension/references/events-reference.md +3 -3
  73. package/dist/resources/skills/create-gsd-extension/references/packaging-distribution.md +1 -1
  74. package/dist/resources/skills/create-gsd-extension/references/remote-execution-overrides.md +3 -3
  75. package/dist/resources/skills/create-gsd-extension/workflows/create-extension.md +12 -32
  76. package/dist/resources/skills/github-workflows/references/gh/tests/__init__.py +0 -0
  77. package/dist/resources/skills/github-workflows/references/gh/tests/test_github_project_setup.py +608 -0
  78. package/dist/rtk-shared.d.ts +0 -3
  79. package/dist/rtk-shared.js +0 -17
  80. package/dist/rtk.d.ts +5 -2
  81. package/dist/rtk.js +20 -3
  82. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  83. package/dist/web/standalone/.next/BUILD_ID +1 -1
  84. package/dist/web/standalone/.next/app-path-routes-manifest.json +13 -13
  85. package/dist/web/standalone/.next/build-manifest.json +4 -4
  86. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  87. package/dist/web/standalone/.next/react-loadable-manifest.json +4 -44
  88. package/dist/web/standalone/.next/required-server-files.json +3 -3
  89. package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
  90. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  91. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  92. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  93. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  94. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  95. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  96. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  97. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  98. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  99. package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
  100. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  101. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  102. package/dist/web/standalone/.next/server/app/_not-found.rsc +3 -3
  103. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
  104. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  105. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +3 -3
  106. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  107. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  108. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  109. package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
  110. package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
  111. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
  112. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
  113. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
  114. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
  115. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
  116. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
  117. package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
  118. package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
  119. package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
  120. package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
  121. package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
  122. package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
  123. package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
  124. package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
  125. package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
  126. package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
  127. package/dist/web/standalone/.next/server/app/api/experimental/route.js +2 -2
  128. package/dist/web/standalone/.next/server/app/api/experimental/route_client-reference-manifest.js +1 -1
  129. package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
  130. package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
  131. package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
  132. package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
  133. package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
  134. package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
  135. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  136. package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  137. package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
  138. package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
  139. package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
  140. package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
  141. package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
  142. package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
  143. package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
  144. package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
  145. package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
  146. package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
  147. package/dist/web/standalone/.next/server/app/api/notifications/route.js +2 -2
  148. package/dist/web/standalone/.next/server/app/api/notifications/route_client-reference-manifest.js +1 -1
  149. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  150. package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
  151. package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
  152. package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
  153. package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
  154. package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  155. package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
  156. package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
  157. package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +2 -2
  158. package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
  159. package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
  160. package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
  161. package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
  162. package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
  163. package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -4
  164. package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
  165. package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
  166. package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
  167. package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
  168. package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
  169. package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
  170. package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
  171. package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
  172. package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
  173. package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
  174. package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
  175. package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
  176. package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
  177. package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +2 -2
  178. package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
  179. package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
  180. package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
  181. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +2 -2
  182. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
  183. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +4 -4
  184. package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
  185. package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
  186. package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
  187. package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
  188. package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
  189. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  190. package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  191. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  192. package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
  193. package/dist/web/standalone/.next/server/app/index.html +1 -1
  194. package/dist/web/standalone/.next/server/app/index.rsc +4 -4
  195. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  196. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +4 -4
  197. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  198. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +3 -3
  199. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  200. package/dist/web/standalone/.next/server/app/page.js +2 -2
  201. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  202. package/dist/web/standalone/.next/server/app-paths-manifest.json +13 -13
  203. package/dist/web/standalone/.next/server/chunks/63.js +3 -3
  204. package/dist/web/standalone/.next/server/chunks/6897.js +1 -1
  205. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  206. package/dist/web/standalone/.next/server/middleware-manifest.json +5 -5
  207. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  208. package/dist/web/standalone/.next/server/middleware.js +2 -2
  209. package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
  210. package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
  211. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  212. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  213. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  214. package/dist/web/standalone/.next/server/webpack-runtime.js +1 -1
  215. package/dist/web/standalone/.next/static/chunks/2826.e9f5195e91f9cad2.js +11 -0
  216. package/dist/web/standalone/.next/static/chunks/3621.fc7480022c972438.js +20 -0
  217. package/dist/web/standalone/.next/static/chunks/app/_not-found/{page-f2a7482d42a5614b.js → page-2f24283c162b6ab3.js} +1 -1
  218. package/dist/web/standalone/.next/static/chunks/app/{layout-a16c7a7ecdf0c2cf.js → layout-9ecfd95f343793f0.js} +1 -1
  219. package/dist/web/standalone/.next/static/chunks/app/page-151349214571e2b6.js +1 -0
  220. package/dist/web/standalone/.next/static/chunks/main-app-d3d4c336195465f9.js +1 -0
  221. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ab5a8926e07ec673.js +1 -0
  222. package/dist/web/standalone/.next/static/chunks/webpack-2e68521d7c82f7c2.js +1 -0
  223. package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
  224. package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
  225. package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
  226. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api.target.mk +14 -14
  227. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_except.target.mk +14 -14
  228. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_maybe.target.mk +14 -14
  229. package/dist/web/standalone/package.json +1 -2
  230. package/dist/web/standalone/server.js +1 -1
  231. package/package.json +1 -1
  232. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  233. package/packages/mcp-server/dist/workflow-tools.js +46 -74
  234. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  235. package/packages/mcp-server/src/workflow-tools.test.ts +0 -26
  236. package/packages/mcp-server/src/workflow-tools.ts +58 -93
  237. package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
  238. package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -1
  239. package/packages/pi-ai/dist/providers/anthropic-shared.d.ts.map +1 -1
  240. package/packages/pi-ai/dist/providers/anthropic-shared.js +19 -48
  241. package/packages/pi-ai/dist/providers/anthropic-shared.js.map +1 -1
  242. package/packages/pi-ai/dist/types.d.ts +0 -13
  243. package/packages/pi-ai/dist/types.d.ts.map +1 -1
  244. package/packages/pi-ai/dist/types.js.map +1 -1
  245. package/packages/pi-ai/dist/utils/repair-tool-json.d.ts.map +1 -1
  246. package/packages/pi-ai/dist/utils/repair-tool-json.js +3 -24
  247. package/packages/pi-ai/dist/utils/repair-tool-json.js.map +1 -1
  248. package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.js +0 -26
  249. package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.js.map +1 -1
  250. package/packages/pi-ai/src/providers/anthropic-shared.ts +20 -52
  251. package/packages/pi-ai/src/types.ts +0 -13
  252. package/packages/pi-ai/src/utils/repair-tool-json.ts +3 -24
  253. package/packages/pi-ai/src/utils/tests/repair-tool-json.test.ts +0 -32
  254. package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
  255. package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
  256. package/packages/pi-coding-agent/dist/core/agent-session.js +0 -6
  257. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  258. package/packages/pi-coding-agent/dist/core/messages.d.ts.map +1 -1
  259. package/packages/pi-coding-agent/dist/core/messages.js +0 -4
  260. package/packages/pi-coding-agent/dist/core/messages.js.map +1 -1
  261. package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js +2 -19
  262. package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js.map +1 -1
  263. package/packages/pi-coding-agent/dist/core/model-registry.d.ts +0 -10
  264. package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
  265. package/packages/pi-coding-agent/dist/core/model-registry.js +0 -18
  266. package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
  267. package/packages/pi-coding-agent/dist/core/system-prompt.d.ts +0 -13
  268. package/packages/pi-coding-agent/dist/core/system-prompt.d.ts.map +1 -1
  269. package/packages/pi-coding-agent/dist/core/system-prompt.js +16 -20
  270. package/packages/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
  271. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js +1 -1
  272. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js.map +1 -1
  273. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js +1 -14
  274. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js.map +1 -1
  275. package/packages/pi-coding-agent/src/core/agent-session.ts +0 -7
  276. package/packages/pi-coding-agent/src/core/messages.ts +0 -4
  277. package/packages/pi-coding-agent/src/core/model-registry-auth-mode.test.ts +2 -32
  278. package/packages/pi-coding-agent/src/core/model-registry.ts +0 -21
  279. package/packages/pi-coding-agent/src/core/system-prompt.ts +15 -33
  280. package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.test.ts +1 -17
  281. package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.ts +1 -1
  282. package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
  283. package/packages/pi-tui/dist/__tests__/autocomplete.test.js +3 -17
  284. package/packages/pi-tui/dist/__tests__/autocomplete.test.js.map +1 -1
  285. package/packages/pi-tui/src/__tests__/autocomplete.test.ts +3 -20
  286. package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
  287. package/src/resources/extensions/gsd/auto/loop.ts +2 -24
  288. package/src/resources/extensions/gsd/auto/phases.ts +3 -3
  289. package/src/resources/extensions/gsd/auto/run-unit.ts +1 -3
  290. package/src/resources/extensions/gsd/auto/session.ts +0 -3
  291. package/src/resources/extensions/gsd/auto/types.ts +0 -1
  292. package/src/resources/extensions/gsd/auto-recovery.ts +8 -46
  293. package/src/resources/extensions/gsd/auto-start.ts +1 -1
  294. package/src/resources/extensions/gsd/auto-tool-tracking.ts +4 -2
  295. package/src/resources/extensions/gsd/auto-worktree.ts +0 -38
  296. package/src/resources/extensions/gsd/auto.ts +4 -14
  297. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +13 -15
  298. package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +7 -8
  299. package/src/resources/extensions/gsd/bootstrap/query-tools.ts +2 -2
  300. package/src/resources/extensions/gsd/bootstrap/register-extension.ts +9 -10
  301. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +31 -102
  302. package/src/resources/extensions/gsd/bootstrap/register-shortcuts.ts +6 -12
  303. package/src/resources/extensions/gsd/bootstrap/system-context.ts +8 -39
  304. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +11 -39
  305. package/src/resources/extensions/gsd/commands/catalog.ts +5 -75
  306. package/src/resources/extensions/gsd/commands/handlers/core.ts +1 -22
  307. package/src/resources/extensions/gsd/commands-mcp-status.ts +1 -3
  308. package/src/resources/extensions/gsd/commands-prefs-wizard.ts +1 -15
  309. package/src/resources/extensions/gsd/dashboard-overlay.ts +1 -1
  310. package/src/resources/extensions/gsd/docs/preferences-reference.md +0 -4
  311. package/src/resources/extensions/gsd/doctor-runtime-checks.ts +1 -39
  312. package/src/resources/extensions/gsd/doctor-types.ts +1 -3
  313. package/src/resources/extensions/gsd/error-classifier.ts +1 -1
  314. package/src/resources/extensions/gsd/forensics.ts +2 -2
  315. package/src/resources/extensions/gsd/git-service.ts +5 -13
  316. package/src/resources/extensions/gsd/gsd-db.ts +2 -12
  317. package/src/resources/extensions/gsd/guided-flow.ts +25 -25
  318. package/src/resources/extensions/gsd/memory-store.ts +28 -81
  319. package/src/resources/extensions/gsd/model-router.ts +9 -172
  320. package/src/resources/extensions/gsd/native-git-bridge.ts +1 -7
  321. package/src/resources/extensions/gsd/preferences-models.ts +15 -101
  322. package/src/resources/extensions/gsd/preferences-types.ts +0 -6
  323. package/src/resources/extensions/gsd/preferences-validation.ts +0 -35
  324. package/src/resources/extensions/gsd/preferences.ts +2 -16
  325. package/src/resources/extensions/gsd/prompt-loader.ts +12 -26
  326. package/src/resources/extensions/gsd/slice-parallel-orchestrator.ts +3 -9
  327. package/src/resources/extensions/gsd/state.ts +0 -42
  328. package/src/resources/extensions/gsd/templates/PREFERENCES.md +0 -1
  329. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +1 -178
  330. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +0 -58
  331. package/src/resources/extensions/gsd/tests/auto-session-encapsulation.test.ts +5 -9
  332. package/src/resources/extensions/gsd/tests/auto-supervisor.test.mjs +4 -21
  333. package/src/resources/extensions/gsd/tests/bootstrap-derive-state-db-open.test.ts +1 -1
  334. package/src/resources/extensions/gsd/tests/budget-prediction.test.ts +211 -138
  335. package/src/resources/extensions/gsd/tests/complete-slice-verification-gate.test.ts +59 -142
  336. package/src/resources/extensions/gsd/tests/complete-slice.test.ts +4 -7
  337. package/src/resources/extensions/gsd/tests/completed-at-reconcile.test.ts +32 -89
  338. package/src/resources/extensions/gsd/tests/copy-planning-artifacts-samepath.test.ts +22 -0
  339. package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +23 -41
  340. package/src/resources/extensions/gsd/tests/db-path-worktree-symlink.test.ts +43 -3
  341. package/src/resources/extensions/gsd/tests/debug-logger.test.ts +3 -5
  342. package/src/resources/extensions/gsd/tests/discuss-empty-db-fallback.test.ts +87 -22
  343. package/src/resources/extensions/gsd/tests/discuss-queued-milestones.test.ts +118 -7
  344. package/src/resources/extensions/gsd/tests/discuss-slice-structured-questions.test.ts +47 -0
  345. package/src/resources/extensions/gsd/tests/discuss-tool-scope-leak.test.ts +60 -18
  346. package/src/resources/extensions/gsd/tests/double-merge-guard.test.ts +76 -14
  347. package/src/resources/extensions/gsd/tests/empty-content-abort-loop.test.ts +75 -0
  348. package/src/resources/extensions/gsd/tests/false-degraded-mode-warning.test.ts +83 -22
  349. package/src/resources/extensions/gsd/tests/finalize-timeout-guard.test.ts +63 -1
  350. package/src/resources/extensions/gsd/tests/forensics-stuck-loops.test.ts +1 -26
  351. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +0 -30
  352. package/src/resources/extensions/gsd/tests/headless-answers.test.ts +4 -14
  353. package/src/resources/extensions/gsd/tests/health-widget.test.ts +12 -22
  354. package/src/resources/extensions/gsd/tests/init-prefs-routing.test.ts +1 -64
  355. package/src/resources/extensions/gsd/tests/integration/auto-worktree.test.ts +0 -22
  356. package/src/resources/extensions/gsd/tests/integration/token-savings.test.ts +23 -0
  357. package/src/resources/extensions/gsd/tests/memory-store.test.ts +0 -128
  358. package/src/resources/extensions/gsd/tests/memory-tools.test.ts +1 -33
  359. package/src/resources/extensions/gsd/tests/model-router.test.ts +8 -169
  360. package/src/resources/extensions/gsd/tests/orphaned-worktree-audit.test.ts +0 -8
  361. package/src/resources/extensions/gsd/tests/parallel-crash-recovery.test.ts +43 -32
  362. package/src/resources/extensions/gsd/tests/phases-merge-error-stops-auto.test.ts +10 -4
  363. package/src/resources/extensions/gsd/tests/preferences.test.ts +0 -127
  364. package/src/resources/extensions/gsd/tests/prompt-step-ordering.test.ts +0 -16
  365. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +0 -7
  366. package/src/resources/extensions/gsd/tests/quick-turn-end-cleanup.test.ts +6 -6
  367. package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +19 -168
  368. package/src/resources/extensions/gsd/tests/slice-parallel-orchestrator.test.ts +1 -7
  369. package/src/resources/extensions/gsd/tests/smart-entry-complete.test.ts +1 -23
  370. package/src/resources/extensions/gsd/tests/token-profile.test.ts +4 -51
  371. package/src/resources/extensions/gsd/tests/turn-epoch.test.ts +16 -7
  372. package/src/resources/extensions/gsd/tests/unstructured-continue-context-injection.test.ts +7 -5
  373. package/src/resources/extensions/gsd/tests/uok-gitops-turn-action.test.ts +1 -15
  374. package/src/resources/extensions/gsd/tests/visualizer-overlay.test.ts +6 -6
  375. package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +0 -15
  376. package/src/resources/extensions/gsd/tools/memory-tools.ts +1 -17
  377. package/src/resources/extensions/gsd/unit-context-manifest.ts +8 -8
  378. package/src/resources/extensions/gsd/visualizer-overlay.ts +1 -1
  379. package/src/resources/extensions/gsd/watch/header-renderer.ts +1 -3
  380. package/src/resources/extensions/gsd/workflow-logger.ts +0 -1
  381. package/src/resources/extensions/gsd/worktree-command.ts +44 -31
  382. package/src/resources/extensions/mcp-client/index.ts +3 -6
  383. package/src/resources/extensions/slash-commands/create-extension.ts +24 -38
  384. package/src/resources/skills/create-gsd-extension/SKILL.md +5 -9
  385. package/src/resources/skills/create-gsd-extension/references/custom-commands.md +1 -1
  386. package/src/resources/skills/create-gsd-extension/references/custom-rendering.md +5 -5
  387. package/src/resources/skills/create-gsd-extension/references/custom-tools.md +4 -4
  388. package/src/resources/skills/create-gsd-extension/references/custom-ui.md +6 -6
  389. package/src/resources/skills/create-gsd-extension/references/events-reference.md +3 -3
  390. package/src/resources/skills/create-gsd-extension/references/packaging-distribution.md +1 -1
  391. package/src/resources/skills/create-gsd-extension/references/remote-execution-overrides.md +3 -3
  392. package/src/resources/skills/create-gsd-extension/templates/extension-skeleton.ts +2 -2
  393. package/src/resources/skills/create-gsd-extension/templates/stateful-tool-skeleton.ts +3 -3
  394. package/src/resources/skills/create-gsd-extension/workflows/create-extension.md +12 -32
  395. package/dist/cli-policy.d.ts +0 -13
  396. package/dist/cli-policy.js +0 -17
  397. package/dist/resources/.managed-resources-content-hash +0 -1
  398. package/dist/resources/extensions/gsd/auto-runtime-state.js +0 -31
  399. package/dist/resources/extensions/gsd/milestone-id-reservation.js +0 -36
  400. package/dist/resources/extensions/gsd/worktree-session-state.js +0 -33
  401. package/dist/runtime-checks.d.ts +0 -27
  402. package/dist/runtime-checks.js +0 -38
  403. package/dist/web/standalone/.next/static/chunks/2556.0527fea66e123b7f.js +0 -1
  404. package/dist/web/standalone/.next/static/chunks/2824.08296bc2f9654698.js +0 -1
  405. package/dist/web/standalone/.next/static/chunks/3026.3af53b279375f082.js +0 -1
  406. package/dist/web/standalone/.next/static/chunks/315.6f68ae79b67d25cf.js +0 -1
  407. package/dist/web/standalone/.next/static/chunks/3497.4bfc60a3b3dea717.js +0 -1
  408. package/dist/web/standalone/.next/static/chunks/5516.4a07c872b5c3a663.js +0 -1
  409. package/dist/web/standalone/.next/static/chunks/8336.31b019697882acfb.js +0 -10
  410. package/dist/web/standalone/.next/static/chunks/8845.c9702695e8c5a9c5.js +0 -2
  411. package/dist/web/standalone/.next/static/chunks/9058.01ef3a463bda88f1.js +0 -20
  412. package/dist/web/standalone/.next/static/chunks/9441.1081da1125d1764f.js +0 -1
  413. package/dist/web/standalone/.next/static/chunks/app/page-9bf2e0c50fb2ca05.js +0 -1
  414. package/dist/web/standalone/.next/static/chunks/main-app-fdab67f7802d7832.js +0 -1
  415. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +0 -1
  416. package/dist/web/standalone/.next/static/chunks/webpack-f9f0dc45e4f3ac10.js +0 -1
  417. package/dist/worktree-status-banner.d.ts +0 -1
  418. package/dist/worktree-status-banner.js +0 -132
  419. package/packages/mcp-server/dist/alias-telemetry.d.ts +0 -8
  420. package/packages/mcp-server/dist/alias-telemetry.d.ts.map +0 -1
  421. package/packages/mcp-server/dist/alias-telemetry.js +0 -30
  422. package/packages/mcp-server/dist/alias-telemetry.js.map +0 -1
  423. package/packages/mcp-server/src/alias-telemetry.test.ts +0 -78
  424. package/packages/mcp-server/src/alias-telemetry.ts +0 -30
  425. package/packages/pi-ai/dist/providers/anthropic-shared.cache-breakpoint.test.d.ts +0 -2
  426. package/packages/pi-ai/dist/providers/anthropic-shared.cache-breakpoint.test.d.ts.map +0 -1
  427. package/packages/pi-ai/dist/providers/anthropic-shared.cache-breakpoint.test.js +0 -231
  428. package/packages/pi-ai/dist/providers/anthropic-shared.cache-breakpoint.test.js.map +0 -1
  429. package/packages/pi-ai/src/providers/anthropic-shared.cache-breakpoint.test.ts +0 -289
  430. package/packages/pi-coding-agent/dist/core/token-telemetry.d.ts +0 -37
  431. package/packages/pi-coding-agent/dist/core/token-telemetry.d.ts.map +0 -1
  432. package/packages/pi-coding-agent/dist/core/token-telemetry.js +0 -49
  433. package/packages/pi-coding-agent/dist/core/token-telemetry.js.map +0 -1
  434. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.d.ts +0 -2
  435. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.d.ts.map +0 -1
  436. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.js +0 -133
  437. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.js.map +0 -1
  438. package/packages/pi-coding-agent/dist/tests/system-prompt-cache-stability.test.d.ts +0 -2
  439. package/packages/pi-coding-agent/dist/tests/system-prompt-cache-stability.test.d.ts.map +0 -1
  440. package/packages/pi-coding-agent/dist/tests/system-prompt-cache-stability.test.js +0 -78
  441. package/packages/pi-coding-agent/dist/tests/system-prompt-cache-stability.test.js.map +0 -1
  442. package/packages/pi-coding-agent/dist/tests/token-telemetry.test.d.ts +0 -2
  443. package/packages/pi-coding-agent/dist/tests/token-telemetry.test.d.ts.map +0 -1
  444. package/packages/pi-coding-agent/dist/tests/token-telemetry.test.js +0 -181
  445. package/packages/pi-coding-agent/dist/tests/token-telemetry.test.js.map +0 -1
  446. package/packages/pi-coding-agent/src/core/token-telemetry.ts +0 -77
  447. package/packages/pi-coding-agent/src/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.ts +0 -212
  448. package/packages/pi-coding-agent/src/tests/system-prompt-cache-stability.test.ts +0 -102
  449. package/packages/pi-coding-agent/src/tests/token-telemetry.test.ts +0 -200
  450. package/packages/pi-tui/dist/components/__tests__/leak-fixes-runtime.test.d.ts +0 -2
  451. package/packages/pi-tui/dist/components/__tests__/leak-fixes-runtime.test.d.ts.map +0 -1
  452. package/packages/pi-tui/dist/components/__tests__/leak-fixes-runtime.test.js +0 -161
  453. package/packages/pi-tui/dist/components/__tests__/leak-fixes-runtime.test.js.map +0 -1
  454. package/packages/pi-tui/src/components/__tests__/leak-fixes-runtime.test.ts +0 -219
  455. package/src/resources/extensions/gsd/auto-runtime-state.ts +0 -51
  456. package/src/resources/extensions/gsd/milestone-id-reservation.ts +0 -47
  457. package/src/resources/extensions/gsd/tests/deferred-milestone-dir-4996.test.ts +0 -116
  458. package/src/resources/extensions/gsd/tests/doctor-orphan-milestone-4996.test.ts +0 -100
  459. package/src/resources/extensions/gsd/tests/ensure-preconditions-guard-4996.test.ts +0 -93
  460. package/src/resources/extensions/gsd/tests/find-missing-summaries-closed-runtime.test.ts +0 -47
  461. package/src/resources/extensions/gsd/tests/gitignore-bg-shell-runtime.test.ts +0 -63
  462. package/src/resources/extensions/gsd/tests/gsd-no-project-error-runtime.test.ts +0 -81
  463. package/src/resources/extensions/gsd/tests/help-menu-coverage.test.ts +0 -57
  464. package/src/resources/extensions/gsd/tests/import-done-milestones-runtime.test.ts +0 -145
  465. package/src/resources/extensions/gsd/tests/merge-self-branch-guard.test.ts +0 -124
  466. package/src/resources/extensions/gsd/tests/milestone-id-gap-reuse-4996.test.ts +0 -152
  467. package/src/resources/extensions/gsd/tests/native-git-infra-errors.test.ts +0 -50
  468. package/src/resources/extensions/gsd/tests/register-hooks-compaction-checkpoint.test.ts +0 -93
  469. package/src/resources/extensions/gsd/tests/system-context-message-routing.test.ts +0 -101
  470. package/src/resources/extensions/gsd/worktree-session-state.ts +0 -35
  471. package/src/resources/extensions/mcp-client/tests/global-config.test.ts +0 -91
  472. package/src/resources/skills/create-gsd-extension/templates/templates.test.ts +0 -58
  473. /package/dist/web/standalone/.next/static/{UF5VF4F1tB0miEtJS7LyX → 7afp7gq8-DVbxum83zRQ-}/_buildManifest.js +0 -0
  474. /package/dist/web/standalone/.next/static/{UF5VF4F1tB0miEtJS7LyX → 7afp7gq8-DVbxum83zRQ-}/_ssgManifest.js +0 -0
@@ -5,16 +5,24 @@ import { isToolCallEventType } from "@gsd/pi-coding-agent";
5
5
 
6
6
  import type { GSDEcosystemBeforeAgentStartHandler } from "../ecosystem/gsd-extension-api.js";
7
7
  import { updateSnapshot } from "../ecosystem/gsd-extension-api.js";
8
+ import { getEcosystemReadyPromise } from "../ecosystem/loader.js";
8
9
 
9
10
  import { buildMilestoneFileName, resolveMilestonePath, resolveSliceFile, resolveSlicePath } from "../paths.js";
10
- import { clearDiscussionFlowState, isDepthConfirmationAnswer, isQueuePhaseActive, markDepthVerified, resetWriteGateState, shouldBlockContextWrite, shouldBlockPlanningUnit, shouldBlockQueueExecution, isGateQuestionId, setPendingGate, clearPendingGate, getPendingGate, shouldBlockPendingGate, shouldBlockPendingGateBash, extractDepthVerificationMilestoneId } from "./write-gate.js";
11
- import { resolveManifest } from "../unit-context-manifest.js";
11
+ import { buildBeforeAgentStartResult } from "./system-context.js";
12
+ import { handleAgentEnd } from "./agent-end-recovery.js";
13
+ import { clearDiscussionFlowState, isDepthConfirmationAnswer, isQueuePhaseActive, markDepthVerified, resetWriteGateState, shouldBlockContextWrite, shouldBlockQueueExecution, isGateQuestionId, setPendingGate, clearPendingGate, getPendingGate, shouldBlockPendingGate, shouldBlockPendingGateBash, extractDepthVerificationMilestoneId } from "./write-gate.js";
12
14
  import { isBlockedStateFile, isBashWriteToStateFile, BLOCKED_WRITE_ERROR } from "../write-intercept.js";
15
+ import { cleanupQuickBranch } from "../quick.js";
16
+ import { getDiscussionMilestoneId } from "../guided-flow.js";
17
+ import { loadToolApiKeys } from "../commands-config.js";
13
18
  import { loadFile, saveFile, formatContinue } from "../files.js";
14
- import { getAutoRuntimeSnapshot, isAutoActive, isAutoPaused, markToolEnd, markToolStart, recordToolInvocationError } from "../auto-runtime-state.js";
19
+ import { deriveState } from "../state.js";
20
+ import { getAutoDashboardData, isAutoActive, isAutoPaused, markToolEnd, markToolStart, recordToolInvocationError } from "../auto.js";
15
21
 
22
+ import { isParallelActive, shutdownParallel } from "../parallel-orchestrator.js";
16
23
  import { checkToolCallLoop, resetToolCallLoopGuard } from "./tool-call-loop-guard.js";
17
24
  import { saveActivityLog } from "../activity-log.js";
25
+ import { resetAskUserQuestionsCache } from "../../ask-user-questions.js";
18
26
  import { recordToolCall as safetyRecordToolCall, recordToolResult as safetyRecordToolResult, saveEvidenceToDisk } from "../safety/evidence-collector.js";
19
27
  import { parseUnitId } from "../unit-id.js";
20
28
  import { classifyCommand } from "../safety/destructive-guard.js";
@@ -22,45 +30,17 @@ import { logWarning as safetyLogWarning } from "../workflow-logger.js";
22
30
  import { installNotifyInterceptor } from "./notify-interceptor.js";
23
31
  import { initNotificationStore } from "../notification-store.js";
24
32
  import { initNotificationWidget } from "../notification-widget.js";
33
+ import { initHealthWidget } from "../health-widget.js";
25
34
 
26
35
  // Skip the welcome screen on the very first session_start — cli.ts already
27
36
  // printed it before the TUI launched. Only re-print on /clear (subsequent sessions).
28
37
  let isFirstSession = true;
29
38
 
30
- async function deriveGsdState(basePath: string) {
31
- const { deriveState } = await import("../state.js");
32
- return deriveState(basePath);
33
- }
34
-
35
- async function getDiscussionMilestoneIdFor(basePath: string): Promise<string | null> {
36
- const { getDiscussionMilestoneId } = await import("../guided-flow.js");
37
- return getDiscussionMilestoneId(basePath);
38
- }
39
-
40
- async function loadToolApiKeysForSession(): Promise<void> {
41
- const { loadToolApiKeys } = await import("../commands-config.js");
42
- loadToolApiKeys();
43
- }
44
-
45
- async function resetAskUserQuestionsTurnCache(): Promise<void> {
46
- const { resetAskUserQuestionsCache } = await import("../../ask-user-questions.js");
47
- resetAskUserQuestionsCache();
48
- }
49
-
50
39
  async function syncServiceTierStatus(ctx: ExtensionContext): Promise<void> {
51
40
  const { getEffectiveServiceTier, formatServiceTierFooterStatus } = await import("../service-tier.js");
52
41
  ctx.ui.setStatus("gsd-fast", formatServiceTierFooterStatus(getEffectiveServiceTier(), ctx.model?.id));
53
42
  }
54
43
 
55
- async function applyDisabledModelProviderPolicy(ctx: ExtensionContext): Promise<void> {
56
- try {
57
- const { resolveDisabledModelProvidersFromPreferences } = await import("../preferences.js");
58
- ctx.modelRegistry.setDisabledModelProviders(resolveDisabledModelProvidersFromPreferences());
59
- } catch {
60
- // Non-fatal: keep default provider visibility if preferences cannot be loaded.
61
- }
62
- }
63
-
64
44
  export function registerHooks(
65
45
  pi: ExtensionAPI,
66
46
  ecosystemHandlers: GSDEcosystemBeforeAgentStartHandler[],
@@ -70,14 +50,12 @@ export function registerHooks(
70
50
  installNotifyInterceptor(ctx);
71
51
  initNotificationWidget(ctx);
72
52
  if (!isAutoActive()) {
73
- const { initHealthWidget } = await import("../health-widget.js");
74
53
  initHealthWidget(ctx);
75
54
  }
76
55
  resetWriteGateState();
77
56
  resetToolCallLoopGuard();
78
- await resetAskUserQuestionsTurnCache();
57
+ resetAskUserQuestionsCache();
79
58
  await syncServiceTierStatus(ctx);
80
- await applyDisabledModelProviderPolicy(ctx);
81
59
  // Skip MCP auto-prep when running inside an auto-worktree (see session_switch below).
82
60
  const { isInAutoWorktree } = await import("../auto-worktree.js");
83
61
  if (!isInAutoWorktree(process.cwd())) {
@@ -113,7 +91,7 @@ export function registerHooks(
113
91
  }
114
92
  } catch { /* non-fatal */ }
115
93
  }
116
- await loadToolApiKeysForSession();
94
+ loadToolApiKeys();
117
95
  if (isAutoActive()) {
118
96
  ctx.ui.setWidget("gsd-health", undefined);
119
97
  }
@@ -124,10 +102,9 @@ export function registerHooks(
124
102
  installNotifyInterceptor(ctx);
125
103
  resetWriteGateState();
126
104
  resetToolCallLoopGuard();
127
- await resetAskUserQuestionsTurnCache();
105
+ resetAskUserQuestionsCache();
128
106
  clearDiscussionFlowState();
129
107
  await syncServiceTierStatus(ctx);
130
- await applyDisabledModelProviderPolicy(ctx);
131
108
  // Skip MCP auto-prep when running inside an auto-worktree. The worktree
132
109
  // already has .mcp.json from createAutoWorktree, and re-running the writer
133
110
  // post-chdir rewrites the file mid-run (non-idempotent due to cwd-relative
@@ -137,28 +114,23 @@ export function registerHooks(
137
114
  const { prepareWorkflowMcpForProject } = await import("../workflow-mcp-auto-prep.js");
138
115
  prepareWorkflowMcpForProject(ctx, process.cwd());
139
116
  }
140
- await loadToolApiKeysForSession();
141
- if (!isAutoActive()) {
142
- const { initHealthWidget } = await import("../health-widget.js");
143
- initHealthWidget(ctx);
144
- } else {
117
+ loadToolApiKeys();
118
+ if (isAutoActive()) {
145
119
  ctx.ui.setWidget("gsd-health", undefined);
146
120
  }
147
121
  });
148
122
 
149
123
  pi.on("before_agent_start", async (event, ctx: ExtensionContext) => {
150
124
  // Wait for ecosystem loader to finish (no-op after first turn).
151
- const { getEcosystemReadyPromise } = await import("../ecosystem/loader.js");
152
125
  await getEcosystemReadyPromise();
153
126
 
154
127
  // GSD's own context injection (existing behavior — unchanged).
155
- const { buildBeforeAgentStartResult } = await import("./system-context.js");
156
128
  const gsdResult = await buildBeforeAgentStartResult(event, ctx);
157
129
 
158
130
  // Refresh the snapshot used by ecosystem getPhase()/getActiveUnit().
159
131
  // deriveState has its own ~100ms cache so this is cheap on repeat calls.
160
132
  try {
161
- const state = await deriveGsdState(process.cwd());
133
+ const state = await deriveState(process.cwd());
162
134
  updateSnapshot(state);
163
135
  } catch {
164
136
  updateSnapshot(null);
@@ -197,8 +169,7 @@ export function registerHooks(
197
169
 
198
170
  pi.on("agent_end", async (event, ctx: ExtensionContext) => {
199
171
  resetToolCallLoopGuard();
200
- await resetAskUserQuestionsTurnCache();
201
- const { handleAgentEnd } = await import("./agent-end-recovery.js");
172
+ resetAskUserQuestionsCache();
202
173
  await handleAgentEnd(pi, event, ctx);
203
174
  });
204
175
 
@@ -207,7 +178,6 @@ export function registerHooks(
207
178
  // quick-return state is pending, so this is safe to call on every turn.
208
179
  pi.on("turn_end", async () => {
209
180
  try {
210
- const { cleanupQuickBranch } = await import("../quick.js");
211
181
  cleanupQuickBranch();
212
182
  } catch {
213
183
  // Best-effort: don't break the turn lifecycle if cleanup fails.
@@ -224,8 +194,8 @@ export function registerHooks(
224
194
  const basePath = process.cwd();
225
195
  const { ensureDbOpen } = await import("./dynamic-tools.js");
226
196
  await ensureDbOpen();
227
- const state = await deriveGsdState(basePath);
228
- if (!state.activeMilestone || !state.activeSlice) return;
197
+ const state = await deriveState(basePath);
198
+ if (!state.activeMilestone || !state.activeSlice || !state.activeTask) return;
229
199
  // Write checkpoint for ALL phases, not just "executing" — discuss, research,
230
200
  // and planning also carry in-memory state (user answers, gate verification)
231
201
  // that would be lost on compaction (#4258).
@@ -240,31 +210,21 @@ export function registerHooks(
240
210
  if (await loadFile(legacyContinue)) return;
241
211
 
242
212
  const continuePath = join(sliceDir, `${state.activeSlice.id}-CONTINUE.md`);
243
- const taskId = state.activeTask?.id ?? "none";
244
- const taskTitle = state.activeTask?.title ?? "";
245
- const phaseLabel = state.phase.replace(/-/g, " ");
246
-
247
213
  await saveFile(continuePath, formatContinue({
248
214
  frontmatter: {
249
215
  milestone: state.activeMilestone.id,
250
216
  slice: state.activeSlice.id,
251
- task: taskId,
217
+ task: state.activeTask.id,
252
218
  step: 0,
253
219
  totalSteps: 0,
254
220
  status: "compacted" as const,
255
221
  savedAt: new Date().toISOString(),
256
222
  },
257
- completedWork: state.activeTask
258
- ? `Task ${taskId} (${taskTitle}) was in progress when compaction occurred.`
259
- : `Slice ${state.activeSlice.id} was in ${phaseLabel} phase when compaction occurred.`,
260
- remainingWork: state.activeTask
261
- ? "Check the task plan for remaining steps."
262
- : "Continue this slice from the latest planning/research/discussion artifacts.",
223
+ completedWork: `Task ${state.activeTask.id} (${state.activeTask.title}) was in progress when compaction occurred.`,
224
+ remainingWork: "Check the task plan for remaining steps.",
263
225
  decisions: "Check task summary files for prior decisions.",
264
226
  context: "Session was auto-compacted by Pi. Resume with /gsd.",
265
- nextAction: state.activeTask
266
- ? `Resume task ${taskId}: ${taskTitle}.`
267
- : `Resume ${phaseLabel} work for slice ${state.activeSlice.id}.`,
227
+ nextAction: `Resume task ${state.activeTask.id}: ${state.activeTask.title}.`,
268
228
  }));
269
229
  });
270
230
 
@@ -286,7 +246,7 @@ export function registerHooks(
286
246
  const basePath = process.cwd();
287
247
  let activeContext: string | null = null;
288
248
  try {
289
- const state = await deriveGsdState(basePath);
249
+ const state = await deriveState(basePath);
290
250
  if (state.activeMilestone && state.activeSlice && state.activeTask) {
291
251
  activeContext =
292
252
  `Active: ${state.activeMilestone.id} / ${state.activeSlice.id} / ${state.activeTask.id}` +
@@ -305,7 +265,6 @@ export function registerHooks(
305
265
  });
306
266
 
307
267
  pi.on("session_shutdown", async (_event, ctx: ExtensionContext) => {
308
- const { isParallelActive, shutdownParallel } = await import("../parallel-orchestrator.js");
309
268
  if (isParallelActive()) {
310
269
  try {
311
270
  await shutdownParallel(process.cwd());
@@ -314,7 +273,7 @@ export function registerHooks(
314
273
  }
315
274
  }
316
275
  if (!isAutoActive() && !isAutoPaused()) return;
317
- const dash = getAutoRuntimeSnapshot();
276
+ const dash = getAutoDashboardData();
318
277
  if (dash.currentUnit) {
319
278
  saveActivityLog(ctx, dash.basePath, dash.currentUnit.type, dash.currentUnit.id);
320
279
  }
@@ -343,7 +302,7 @@ export function registerHooks(
343
302
  // If ask_user_questions was called with a gate ID but hasn't been confirmed,
344
303
  // block all non-read-only tool calls to prevent the model from skipping gates.
345
304
  if (getPendingGate()) {
346
- const milestoneId = await getDiscussionMilestoneIdFor(discussionBasePath);
305
+ const milestoneId = getDiscussionMilestoneId(discussionBasePath);
347
306
  if (isToolCallEventType("bash", event)) {
348
307
  const bashGuard = shouldBlockPendingGateBash(
349
308
  event.input.command,
@@ -378,36 +337,6 @@ export function registerHooks(
378
337
  if (queueGuard.block) return queueGuard;
379
338
  }
380
339
 
381
- // ── Planning-unit tools-policy enforcement (#4934): runtime half ─────
382
- // The active auto-mode unit's manifest declares a ToolsPolicy. For
383
- // planning/docs/read-only modes, deny writes outside .gsd/ (or the
384
- // manifest's allowedPathGlobs), bash that isn't read-only, and
385
- // subagent dispatch. Closes the b23 bug class where a discuss-milestone
386
- // turn used the host Edit tool to modify user source files.
387
- const dash = getAutoRuntimeSnapshot();
388
- const activeUnitType = dash.currentUnit?.type;
389
- if (activeUnitType) {
390
- const manifest = resolveManifest(activeUnitType);
391
- if (manifest) {
392
- let planningInput = "";
393
- if (isToolCallEventType("write", event)) {
394
- planningInput = event.input.path;
395
- } else if (isToolCallEventType("edit", event)) {
396
- planningInput = event.input.path;
397
- } else if (isToolCallEventType("bash", event)) {
398
- planningInput = event.input.command;
399
- }
400
- const planningGuard = shouldBlockPlanningUnit(
401
- event.toolName,
402
- planningInput,
403
- dash.basePath || discussionBasePath,
404
- activeUnitType,
405
- manifest.tools,
406
- );
407
- if (planningGuard.block) return planningGuard;
408
- }
409
- }
410
-
411
340
  // ── Single-writer engine: block direct writes to STATE.md ──────────
412
341
  // Covers write, edit, and bash tools to prevent bypass vectors.
413
342
  if (isToolCallEventType("write", event)) {
@@ -433,7 +362,7 @@ export function registerHooks(
433
362
  const result = shouldBlockContextWrite(
434
363
  event.toolName,
435
364
  event.input.path,
436
- await getDiscussionMilestoneIdFor(discussionBasePath),
365
+ getDiscussionMilestoneId(discussionBasePath),
437
366
  isQueuePhaseActive(),
438
367
  );
439
368
  if (result.block) return result;
@@ -478,7 +407,7 @@ export function registerHooks(
478
407
  recordToolInvocationError(event.toolName, errorText);
479
408
  }
480
409
  if (event.toolName !== "ask_user_questions") return;
481
- const milestoneId = await getDiscussionMilestoneIdFor(process.cwd());
410
+ const milestoneId = getDiscussionMilestoneId(process.cwd());
482
411
  const queueActive = isQueuePhaseActive();
483
412
 
484
413
  const details = event.details as any;
@@ -577,7 +506,7 @@ export function registerHooks(
577
506
  safetyRecordToolResult(event.toolCallId, event.toolName, event.result, event.isError);
578
507
  // Persist evidence to disk after each tool result so it survives a session
579
508
  // restart mid-unit (Bug #4385 — non-persisted evidence false positives).
580
- const dash = getAutoRuntimeSnapshot();
509
+ const dash = getAutoDashboardData();
581
510
  if (dash.basePath && dash.currentUnit?.type === "execute-task") {
582
511
  const { milestone: pMid, slice: pSid, task: pTid } = parseUnitId(dash.currentUnit.id);
583
512
  if (pMid && pSid && pTid) {
@@ -4,14 +4,13 @@ import { join } from "node:path";
4
4
  import type { ExtensionAPI, ExtensionContext } from "@gsd/pi-coding-agent";
5
5
  import { Key } from "@gsd/pi-tui";
6
6
 
7
+ import { GSDDashboardOverlay } from "../dashboard-overlay.js";
8
+ import { GSDNotificationOverlay } from "../notification-overlay.js";
9
+ import { ParallelMonitorOverlay } from "../parallel-monitor-overlay.js";
7
10
  import { GSD_SHORTCUTS } from "../shortcut-defs.js";
11
+ import { projectRoot } from "../commands/context.js";
8
12
  import { shortcutDesc } from "../../shared/mod.js";
9
13
 
10
- async function getProjectRoot(): Promise<string> {
11
- const { projectRoot } = await import("../commands/context.js");
12
- return projectRoot();
13
- }
14
-
15
14
  export function registerShortcuts(pi: ExtensionAPI): void {
16
15
  const overlayOptions = {
17
16
  width: "90%",
@@ -21,10 +20,7 @@ export function registerShortcuts(pi: ExtensionAPI): void {
21
20
  } as const;
22
21
 
23
22
  const openDashboardOverlay = async (ctx: ExtensionContext) => {
24
- const [{ GSDDashboardOverlay }, basePath] = await Promise.all([
25
- import("../dashboard-overlay.js"),
26
- getProjectRoot(),
27
- ]);
23
+ const basePath = projectRoot();
28
24
  if (!existsSync(join(basePath, ".gsd"))) {
29
25
  ctx.ui.notify("No .gsd/ directory found. Run /gsd to start.", "info");
30
26
  return;
@@ -39,7 +35,6 @@ export function registerShortcuts(pi: ExtensionAPI): void {
39
35
  };
40
36
 
41
37
  const openNotificationsOverlay = async (ctx: ExtensionContext) => {
42
- const { GSDNotificationOverlay } = await import("../notification-overlay.js");
43
38
  await ctx.ui.custom<boolean>(
44
39
  (tui, theme, _kb, done) => new GSDNotificationOverlay(tui, theme, () => done(true)),
45
40
  {
@@ -56,13 +51,12 @@ export function registerShortcuts(pi: ExtensionAPI): void {
56
51
  };
57
52
 
58
53
  const openParallelOverlay = async (ctx: ExtensionContext) => {
59
- const basePath = await getProjectRoot();
54
+ const basePath = projectRoot();
60
55
  const parallelDir = join(basePath, ".gsd", "parallel");
61
56
  if (!existsSync(parallelDir)) {
62
57
  ctx.ui.notify("No parallel workers found. Run /gsd parallel start first.", "info");
63
58
  return;
64
59
  }
65
- const { ParallelMonitorOverlay } = await import("../parallel-monitor-overlay.js");
66
60
  await ctx.ui.custom<boolean>(
67
61
  (tui, theme, _kb, done) => new ParallelMonitorOverlay(tui, theme, () => done(true), basePath),
68
62
  {
@@ -15,7 +15,7 @@ import { resolveGsdRootFile, resolveSliceFile, resolveSlicePath, resolveTaskFile
15
15
  import { ensureCodebaseMapFresh, readCodebaseMap } from "../codebase-generator.js";
16
16
  import { hasSkillSnapshot, detectNewSkills, formatSkillsXml } from "../skill-discovery.js";
17
17
  import { getActiveAutoWorktreeContext } from "../auto-worktree.js";
18
- import { getActiveWorktreeName, getWorktreeOriginalCwd } from "../worktree-session-state.js";
18
+ import { getActiveWorktreeName, getWorktreeOriginalCwd } from "../worktree-command.js";
19
19
  import { deriveState } from "../state.js";
20
20
  import { formatOverridesSection, formatShortcut, loadActiveOverrides, loadFile, parseContinue, parseSummary } from "../files.js";
21
21
  import { toPosixPath } from "../../shared/mod.js";
@@ -207,14 +207,7 @@ export async function buildBeforeAgentStartResult(
207
207
  ? `\n\n## Subagent Model\n\nWhen spawning subagents via the \`subagent\` tool, always pass \`model: "${subagentModelConfig.primary}"\` in the tool call parameters. Never omit this — always specify it explicitly.`
208
208
  : "";
209
209
 
210
- // memoryBlock is FTS-queried against the user prompt and changes per call.
211
- // Removing it from `fullSystem` keeps the system-prompt cache breakpoint
212
- // stable across calls — the only scoped goal of this fix. The pi-ai
213
- // Anthropic adapter additionally cache-marks the last user turn, so the
214
- // memoryBlock injected via the context message may itself be cached up to
215
- // that boundary; that's orthogonal and unchanged from prior behavior. The
216
- // load-bearing win here is preserving the system+tools cache hit. (#5019)
217
- const fullSystem = `${event.systemPrompt}\n\n[SYSTEM CONTEXT — GSD]\n\n${systemContent}${preferenceBlock}${knowledgeBlock}${codebaseBlock}${newSkillsBlock}${worktreeBlock}${subagentModelBlock}`;
210
+ const fullSystem = `${event.systemPrompt}\n\n[SYSTEM CONTEXT GSD]\n\n${systemContent}${preferenceBlock}${knowledgeBlock}${codebaseBlock}${memoryBlock}${newSkillsBlock}${worktreeBlock}${subagentModelBlock}`;
218
211
 
219
212
  stopContextTimer({
220
213
  systemPromptSize: fullSystem.length,
@@ -223,7 +216,12 @@ export async function buildBeforeAgentStartResult(
223
216
  hasNewSkills: newSkillsBlock.length > 0,
224
217
  });
225
218
 
226
- const contextMessage = buildContextMessage({ memoryBlock, injection, forensicsInjection });
219
+ // Determine which context message to inject (guided execute takes priority)
220
+ const contextMessage = injection
221
+ ? { customType: "gsd-guided-context", content: injection, display: false as const }
222
+ : forensicsInjection
223
+ ? { customType: "gsd-forensics", content: forensicsInjection, display: false as const }
224
+ : null;
227
225
 
228
226
  return {
229
227
  systemPrompt: fullSystem,
@@ -231,35 +229,6 @@ export async function buildBeforeAgentStartResult(
231
229
  };
232
230
  }
233
231
 
234
- /**
235
- * Route the per-call dynamic blocks (memory, guided-execute, forensics) into a
236
- * single user-message context payload so they ride the volatile suffix instead
237
- * of the cached system prefix. Priority when both memory and an injection are
238
- * present: guided > forensics > memory-only. (#5019)
239
- *
240
- * Exported for direct unit testing — the surrounding bootstrap has too many
241
- * filesystem and DB dependencies to exercise this routing logic in-place.
242
- */
243
- export function buildContextMessage(opts: {
244
- memoryBlock: string;
245
- injection: string | null;
246
- forensicsInjection: string | null;
247
- }): { customType: string; content: string; display: false } | null {
248
- const memoryContent = opts.memoryBlock.trim();
249
- if (opts.injection) {
250
- const content = memoryContent ? `${memoryContent}\n\n${opts.injection}` : opts.injection;
251
- return { customType: "gsd-guided-context", content, display: false as const };
252
- }
253
- if (opts.forensicsInjection) {
254
- const content = memoryContent ? `${memoryContent}\n\n${opts.forensicsInjection}` : opts.forensicsInjection;
255
- return { customType: "gsd-forensics", content, display: false as const };
256
- }
257
- if (memoryContent) {
258
- return { customType: "gsd-memory", content: memoryContent, display: false as const };
259
- }
260
- return null;
261
- }
262
-
263
232
  /**
264
233
  * ADR-013 step 4 — auto-injection parity for the memories table.
265
234
  *
@@ -3,7 +3,15 @@ import { isAbsolute, join, relative, resolve, sep } from "node:path";
3
3
 
4
4
  import { minimatch } from "minimatch";
5
5
 
6
- import type { ToolsPolicy } from "../unit-context-manifest.js";
6
+ /**
7
+ * Declarative tools-policy for a unit. Inlined here because the worktree
8
+ * branch predates the full unit-context-manifest export (#4934).
9
+ */
10
+ export type ToolsPolicy =
11
+ | { mode: "all" }
12
+ | { mode: "read-only" }
13
+ | { mode: "planning" }
14
+ | { mode: "docs"; allowedPathGlobs: readonly string[] };
7
15
 
8
16
  /**
9
17
  * Regex matching milestone CONTEXT.md file names in both legacy M001
@@ -527,33 +535,10 @@ export function shouldBlockQueueExecutionInSnapshot(
527
535
  }
528
536
 
529
537
  // ─── Planning-unit tools-policy enforcement (#4934) ───────────────────────
530
- //
531
- // Runtime half of the declarative ToolsPolicy on UnitContextManifest. The
532
- // manifest assigns each unit type a tools mode; this predicate is what
533
- // actually rejects a tool call that violates it.
534
- //
535
- // Forensics: a discuss-milestone LLM turn used the host Edit tool to modify
536
- // index.html in test app b23 (~/Github/test-apps/b23). With this predicate
537
- // wired into the tool_call hook, the same call returns block=true with a
538
- // HARD BLOCK reason that the model cannot rationalize past.
539
- //
540
- // Activation: the hook supplies the policy resolved from the active unit's
541
- // manifest. When no unit is active (interactive sessions, unknown unit
542
- // types), the hook passes null and this predicate is a no-op — falling
543
- // through to the existing pendingGate / queue-execution / context-write
544
- // guards.
545
538
 
546
539
  const PLANNING_WRITE_TOOLS = new Set(["write", "edit", "multi_edit", "notebook_edit"]);
547
540
  const PLANNING_SUBAGENT_TOOLS = new Set(["subagent", "task"]);
548
541
 
549
- /**
550
- * Read-only / planning-safe tools that any non-"all" mode allows. Mirrors
551
- * QUEUE_SAFE_TOOLS / GATE_SAFE_TOOLS but is the inclusive default for
552
- * planning units (which need their full discussion + research surface).
553
- *
554
- * gsd_* MCP tools are passed through unconditionally — they have their own
555
- * domain validation (e.g. depth-verification gate, single-writer DB).
556
- */
557
542
  const PLANNING_SAFE_TOOLS = new Set([
558
543
  "read", "grep", "find", "ls", "glob",
559
544
  "ask_user_questions",
@@ -570,7 +555,6 @@ function isPathUnderGsd(absPath: string, basePath: string): boolean {
570
555
  function matchesAllowedGlob(absPath: string, basePath: string, globs: readonly string[]): boolean {
571
556
  const rel = relative(basePath, absPath);
572
557
  if (rel.startsWith("..") || isAbsolute(rel)) return false;
573
- // Normalize Windows separators for minimatch.
574
558
  const posix = rel.split(sep).join("/");
575
559
  return globs.some(g => minimatch(posix, g, { dot: false, nocase: false }));
576
560
  }
@@ -595,12 +579,7 @@ function blockReason(unitType: string, mode: string, what: string): string {
595
579
  * - "docs" → like "planning" but also allows writes to paths
596
580
  * matching `allowedPathGlobs` relative to basePath.
597
581
  *
598
- * `pathOrCommand` is the file path for write/edit-shaped tools and the
599
- * shell command for bash. Other tools ignore this argument.
600
- *
601
- * `policy` of null means "no manifest resolved" — pass-through. Callers
602
- * that have no active unit (interactive sessions) pass null and this
603
- * predicate is a no-op.
582
+ * `policy` of null means "no manifest resolved" pass-through.
604
583
  */
605
584
  export function shouldBlockPlanningUnit(
606
585
  toolName: string,
@@ -614,18 +593,16 @@ export function shouldBlockPlanningUnit(
614
593
 
615
594
  const tool = toolName;
616
595
 
617
- // Read-only mode: only Read-class tools are permitted.
618
596
  if (policy.mode === "read-only") {
619
597
  if (PLANNING_SAFE_TOOLS.has(tool)) return { block: false };
620
598
  if (tool.startsWith("gsd_")) return { block: false };
621
599
  if (PLANNING_WRITE_TOOLS.has(tool) || tool === "bash" || PLANNING_SUBAGENT_TOOLS.has(tool)) {
622
600
  return { block: true, reason: blockReason(unitType, policy.mode, `${tool} is not permitted (read-only)`) };
623
601
  }
624
- // Unknown tool in read-only mode — block by default.
625
602
  return { block: true, reason: blockReason(unitType, policy.mode, `tool "${tool}" is not on the read-only allowlist`) };
626
603
  }
627
604
 
628
- // planning / docs modes share the same surface for safe tools, bash, and subagent.
605
+ // planning / docs modes
629
606
  if (PLANNING_SAFE_TOOLS.has(tool)) return { block: false };
630
607
  if (tool.startsWith("gsd_")) return { block: false };
631
608
 
@@ -651,10 +628,8 @@ export function shouldBlockPlanningUnit(
651
628
  }
652
629
  const absPath = isAbsolute(pathOrCommand) ? pathOrCommand : resolve(basePath, pathOrCommand);
653
630
 
654
- // Always allow .gsd/ writes — that's where planning artifacts live.
655
631
  if (isPathUnderGsd(absPath, basePath)) return { block: false };
656
632
 
657
- // docs mode additionally allows the manifest's allowedPathGlobs.
658
633
  if (policy.mode === "docs" && matchesAllowedGlob(absPath, basePath, policy.allowedPathGlobs)) {
659
634
  return { block: false };
660
635
  }
@@ -669,8 +644,5 @@ export function shouldBlockPlanningUnit(
669
644
  };
670
645
  }
671
646
 
672
- // Unknown tool name — pass through. Other layers (queue, pending-gate,
673
- // CONTEXT.md write) catch known mutating shapes; defaulting to allow here
674
- // avoids breaking gsd_* MCP tools or future safe additions.
675
647
  return { block: false };
676
648
  }
@@ -1,8 +1,9 @@
1
1
  import { existsSync, readFileSync, readdirSync } from "node:fs";
2
2
  import { homedir } from "node:os";
3
- import { join, resolve } from "node:path";
3
+ import { join } from "node:path";
4
4
 
5
5
  import { loadRegistry } from "../workflow-templates.js";
6
+ import { resolveProjectRoot } from "../worktree.js";
6
7
 
7
8
  const gsdHome = process.env.GSD_HOME || join(homedir(), ".gsd");
8
9
 
@@ -14,7 +15,7 @@ export interface GsdCommandDefinition {
14
15
  type CompletionMap = Record<string, readonly GsdCommandDefinition[]>;
15
16
 
16
17
  export const GSD_COMMAND_DESCRIPTION =
17
- "GSD — Get Shit Done: /gsd help|start|templates|next|auto|stop|pause|status|widget|visualize|queue|quick|discuss|capture|triage|dispatch|history|undo|undo-task|reset-slice|rate|skip|export|cleanup|model|mode|prefs|config|keys|hooks|run-hook|skill-health|doctor|debug|logs|forensics|changelog|migrate|remote|steer|knowledge|new-milestone|parallel|cmux|park|unpark|init|setup|onboarding|inspect|extensions|update|fast|mcp|rethink|workflow|codebase|notifications|ship|do|session-report|backlog|pr-branch|add-tests|scan|language";
18
+ "GSD — Get Shit Done: /gsd help|start|templates|next|auto|stop|pause|status|widget|visualize|queue|quick|discuss|capture|triage|dispatch|history|undo|undo-task|reset-slice|rate|skip|export|cleanup|model|mode|prefs|config|keys|hooks|run-hook|skill-health|doctor|debug|logs|forensics|changelog|migrate|remote|steer|knowledge|new-milestone|parallel|cmux|park|unpark|init|setup|onboarding|inspect|extensions|update|fast|mcp|rethink|codebase|notifications|ship|do|session-report|backlog|pr-branch|add-tests|scan|language";
18
19
 
19
20
  export const TOP_LEVEL_SUBCOMMANDS: readonly GsdCommandDefinition[] = [
20
21
  { cmd: "help", desc: "Categorized command reference with descriptions" },
@@ -345,77 +346,6 @@ function getExtensionCompletions(prefix: string, action: string) {
345
346
  }
346
347
  }
347
348
 
348
- function normalizePathForCompare(path: string): string {
349
- return path.replaceAll("\\", "/").replace(/\/+$/, "");
350
- }
351
-
352
- function findWorktreeSegment(normalizedPath: string): { gsdIdx: number; afterWorktrees: number } | null {
353
- const directMarker = "/.gsd/worktrees/";
354
- const directIdx = normalizedPath.indexOf(directMarker);
355
- if (directIdx !== -1) {
356
- return { gsdIdx: directIdx, afterWorktrees: directIdx + directMarker.length };
357
- }
358
-
359
- const symlinkMatch = normalizedPath.match(/\/\.gsd\/projects\/[a-f0-9]+\/worktrees\//);
360
- if (symlinkMatch?.index !== undefined) {
361
- return { gsdIdx: symlinkMatch.index, afterWorktrees: symlinkMatch.index + symlinkMatch[0].length };
362
- }
363
-
364
- return null;
365
- }
366
-
367
- function resolveProjectRootFromGitFile(worktreePath: string): string | null {
368
- try {
369
- let dir = worktreePath;
370
- for (let i = 0; i < 30; i++) {
371
- const gitPath = join(dir, ".git");
372
- if (existsSync(gitPath)) {
373
- const content = readFileSync(gitPath, "utf8").trim();
374
- if (content.startsWith("gitdir: ")) {
375
- const gitDir = resolve(dir, content.slice(8));
376
- const dotGitDir = resolve(gitDir, "..", "..");
377
- if (dotGitDir.endsWith(".git") || dotGitDir.endsWith(".git/") || dotGitDir.endsWith(".git\\")) {
378
- return resolve(dotGitDir, "..");
379
- }
380
- const commonDirPath = join(gitDir, "commondir");
381
- if (existsSync(commonDirPath)) {
382
- const commonDir = readFileSync(commonDirPath, "utf8").trim();
383
- return resolve(resolve(gitDir, commonDir), "..");
384
- }
385
- }
386
- break;
387
- }
388
- const parent = resolve(dir, "..");
389
- if (parent === dir) break;
390
- dir = parent;
391
- }
392
- } catch {
393
- // Completion must stay best-effort.
394
- }
395
- return null;
396
- }
397
-
398
- function resolveProjectRootForCompletion(basePath: string): string {
399
- if (process.env.GSD_PROJECT_ROOT) return process.env.GSD_PROJECT_ROOT;
400
-
401
- const normalizedPath = normalizePathForCompare(basePath);
402
- const segment = findWorktreeSegment(normalizedPath);
403
- if (!segment) return basePath;
404
-
405
- const separator = basePath.includes("\\") ? "\\" : "/";
406
- const gsdMarker = `${separator}.gsd${separator}`;
407
- const gsdIdx = basePath.indexOf(gsdMarker);
408
- const candidate = gsdIdx !== -1 ? basePath.slice(0, gsdIdx) : basePath.slice(0, segment.gsdIdx);
409
-
410
- const normalizedGsdHome = normalizePathForCompare(gsdHome);
411
- const candidateGsdPath = normalizePathForCompare(join(candidate, ".gsd"));
412
- if (candidateGsdPath === normalizedGsdHome || candidateGsdPath.startsWith(`${normalizedGsdHome}/`)) {
413
- return resolveProjectRootFromGitFile(basePath) ?? basePath;
414
- }
415
-
416
- return candidate;
417
- }
418
-
419
349
  export function getGsdArgumentCompletions(prefix: string) {
420
350
  const hasTrailingSpace = prefix.endsWith(" ");
421
351
  const parts = prefix.trim().split(/\s+/);
@@ -476,7 +406,7 @@ export function getGsdArgumentCompletions(prefix: string) {
476
406
  // Workflow definition-name completion for `workflow run <name>` and `workflow validate <name>`
477
407
  if (command === "workflow" && (subcommand === "run" || subcommand === "validate") && parts.length <= 3) {
478
408
  try {
479
- const defsDir = join(resolveProjectRootForCompletion(process.cwd()), ".gsd", "workflow-defs");
409
+ const defsDir = join(resolveProjectRoot(process.cwd()), ".gsd", "workflow-defs");
480
410
  if (existsSync(defsDir)) {
481
411
  return readdirSync(defsDir)
482
412
  .filter((f) => f.endsWith(".yaml") && f.startsWith(third))
@@ -513,7 +443,7 @@ export function getGsdArgumentCompletions(prefix: string) {
513
443
  } catch { /* ignore */ }
514
444
  };
515
445
  try {
516
- const base = resolveProjectRootForCompletion(process.cwd());
446
+ const base = resolveProjectRoot(process.cwd());
517
447
  scanDir(join(base, ".gsd", "workflows"), "project");
518
448
  scanDir(join(base, ".gsd", "workflow-defs"), "project-legacy");
519
449
  scanDir(join(gsdHome, "workflows"), "global");