gsd-pi 2.78.0 → 2.78.1-dev.9d08d820b

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