gsd-pi 2.78.0-dev.aeeb2ca00 → 2.78.1-dev.0fdacd524

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 (471) hide show
  1. package/README.md +8 -7
  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 +77 -38
  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 +90 -46
  21. package/dist/resources/extensions/google-search/index.js +2 -6
  22. package/dist/resources/extensions/gsd/auto/loop.js +23 -0
  23. package/dist/resources/extensions/gsd/auto/phases.js +5 -13
  24. package/dist/resources/extensions/gsd/auto/run-unit.js +26 -12
  25. package/dist/resources/extensions/gsd/auto/session.js +5 -6
  26. package/dist/resources/extensions/gsd/auto-dashboard.js +3 -2
  27. package/dist/resources/extensions/gsd/auto-direct-dispatch.js +55 -21
  28. package/dist/resources/extensions/gsd/auto-dispatch.js +18 -6
  29. package/dist/resources/extensions/gsd/auto-prompts.js +69 -2
  30. package/dist/resources/extensions/gsd/auto-recovery.js +43 -4
  31. package/dist/resources/extensions/gsd/auto-runtime-state.js +31 -0
  32. package/dist/resources/extensions/gsd/auto-start.js +1 -1
  33. package/dist/resources/extensions/gsd/auto-tool-tracking.js +2 -2
  34. package/dist/resources/extensions/gsd/auto-worktree.js +60 -13
  35. package/dist/resources/extensions/gsd/auto.js +39 -14
  36. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +14 -2
  37. package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +7 -5
  38. package/dist/resources/extensions/gsd/bootstrap/query-tools.js +2 -2
  39. package/dist/resources/extensions/gsd/bootstrap/register-extension.js +5 -4
  40. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +112 -31
  41. package/dist/resources/extensions/gsd/bootstrap/register-shortcuts.js +11 -6
  42. package/dist/resources/extensions/gsd/bootstrap/subagent-input.js +22 -0
  43. package/dist/resources/extensions/gsd/bootstrap/system-context.js +45 -8
  44. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +121 -3
  45. package/dist/resources/extensions/gsd/commands/catalog.js +76 -5
  46. package/dist/resources/extensions/gsd/commands/handlers/core.js +23 -1
  47. package/dist/resources/extensions/gsd/commands/handlers/ops.js +8 -0
  48. package/dist/resources/extensions/gsd/commands-config.js +3 -2
  49. package/dist/resources/extensions/gsd/commands-extensions.js +46 -3
  50. package/dist/resources/extensions/gsd/commands-handlers.js +3 -2
  51. package/dist/resources/extensions/gsd/commands-mcp-status.js +3 -1
  52. package/dist/resources/extensions/gsd/commands-prefs-wizard.js +10 -1
  53. package/dist/resources/extensions/gsd/commands-worktree.js +309 -0
  54. package/dist/resources/extensions/gsd/dashboard-overlay.js +1 -1
  55. package/dist/resources/extensions/gsd/docs/preferences-reference.md +10 -0
  56. package/dist/resources/extensions/gsd/doctor-providers.js +2 -1
  57. package/dist/resources/extensions/gsd/doctor-runtime-checks.js +39 -1
  58. package/dist/resources/extensions/gsd/error-classifier.js +1 -1
  59. package/dist/resources/extensions/gsd/forensics.js +10 -8
  60. package/dist/resources/extensions/gsd/git-service.js +12 -5
  61. package/dist/resources/extensions/gsd/gsd-db.js +11 -2
  62. package/dist/resources/extensions/gsd/guided-flow.js +25 -24
  63. package/dist/resources/extensions/gsd/home-dir.js +16 -0
  64. package/dist/resources/extensions/gsd/key-manager.js +2 -1
  65. package/dist/resources/extensions/gsd/memory-store.js +66 -31
  66. package/dist/resources/extensions/gsd/migrate/command.js +3 -2
  67. package/dist/resources/extensions/gsd/milestone-id-reservation.js +36 -0
  68. package/dist/resources/extensions/gsd/model-router.js +114 -9
  69. package/dist/resources/extensions/gsd/native-git-bridge.js +7 -1
  70. package/dist/resources/extensions/gsd/preferences-models.js +91 -15
  71. package/dist/resources/extensions/gsd/preferences-types.js +2 -0
  72. package/dist/resources/extensions/gsd/preferences-validation.js +32 -0
  73. package/dist/resources/extensions/gsd/preferences.js +5 -3
  74. package/dist/resources/extensions/gsd/prompt-loader.js +23 -12
  75. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +10 -0
  76. package/dist/resources/extensions/gsd/prompts/complete-slice.md +10 -0
  77. package/dist/resources/extensions/gsd/prompts/guided-discuss-milestone.md +2 -0
  78. package/dist/resources/extensions/gsd/prompts/parallel-research-slices.md +2 -0
  79. package/dist/resources/extensions/gsd/prompts/plan-slice.md +10 -0
  80. package/dist/resources/extensions/gsd/prompts/refine-slice.md +10 -0
  81. package/dist/resources/extensions/gsd/prompts/rewrite-docs.md +2 -0
  82. package/dist/resources/extensions/gsd/slice-parallel-orchestrator.js +9 -3
  83. package/dist/resources/extensions/gsd/state.js +42 -0
  84. package/dist/resources/extensions/gsd/templates/PREFERENCES.md +1 -0
  85. package/dist/resources/extensions/gsd/tools/memory-tools.js +18 -1
  86. package/dist/resources/extensions/gsd/unit-context-manifest.js +29 -4
  87. package/dist/resources/extensions/gsd/visualizer-overlay.js +1 -1
  88. package/dist/resources/extensions/gsd/watch/header-renderer.js +3 -1
  89. package/dist/resources/extensions/gsd/worktree-command.js +26 -46
  90. package/dist/resources/extensions/gsd/worktree-manager.js +20 -1
  91. package/dist/resources/extensions/gsd/worktree-resolver.js +4 -13
  92. package/dist/resources/extensions/gsd/worktree-root.js +124 -0
  93. package/dist/resources/extensions/gsd/worktree-session-state.js +33 -0
  94. package/dist/resources/extensions/gsd/worktree.js +4 -115
  95. package/dist/resources/extensions/mcp-client/index.js +6 -9
  96. package/dist/resources/extensions/ollama/index.js +15 -2
  97. package/dist/resources/extensions/ollama/model-capabilities.js +31 -0
  98. package/dist/resources/extensions/ollama/ollama-client.js +40 -4
  99. package/dist/resources/extensions/slash-commands/create-extension.js +36 -22
  100. package/dist/resources/extensions/subagent/index.js +324 -178
  101. package/dist/resources/skills/create-gsd-extension/SKILL.md +9 -5
  102. package/dist/resources/skills/create-gsd-extension/references/custom-commands.md +1 -1
  103. package/dist/resources/skills/create-gsd-extension/references/custom-rendering.md +5 -5
  104. package/dist/resources/skills/create-gsd-extension/references/custom-tools.md +4 -4
  105. package/dist/resources/skills/create-gsd-extension/references/custom-ui.md +6 -6
  106. package/dist/resources/skills/create-gsd-extension/references/events-reference.md +3 -3
  107. package/dist/resources/skills/create-gsd-extension/references/packaging-distribution.md +1 -1
  108. package/dist/resources/skills/create-gsd-extension/references/remote-execution-overrides.md +3 -3
  109. package/dist/resources/skills/create-gsd-extension/workflows/create-extension.md +32 -12
  110. package/dist/resources/skills/lint/SKILL.md +4 -0
  111. package/dist/resources/skills/review/SKILL.md +4 -0
  112. package/dist/resources/skills/test/SKILL.md +3 -0
  113. package/dist/rtk-shared.d.ts +3 -0
  114. package/dist/rtk-shared.js +17 -0
  115. package/dist/rtk.d.ts +2 -5
  116. package/dist/rtk.js +3 -20
  117. package/dist/runtime-checks.d.ts +27 -0
  118. package/dist/runtime-checks.js +38 -0
  119. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  120. package/dist/web/standalone/.next/BUILD_ID +1 -1
  121. package/dist/web/standalone/.next/app-path-routes-manifest.json +13 -13
  122. package/dist/web/standalone/.next/build-manifest.json +3 -3
  123. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  124. package/dist/web/standalone/.next/react-loadable-manifest.json +44 -4
  125. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  126. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  127. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  128. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  129. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  130. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  131. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  132. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  133. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  134. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  135. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  136. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  137. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  138. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  139. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  140. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  141. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  142. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  143. package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
  144. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  145. package/dist/web/standalone/.next/server/app/api/session/events/route.js +4 -2
  146. package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
  147. package/dist/web/standalone/.next/server/app/index.html +1 -1
  148. package/dist/web/standalone/.next/server/app/index.rsc +2 -2
  149. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  150. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +2 -2
  151. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  152. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  153. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  154. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  155. package/dist/web/standalone/.next/server/app-paths-manifest.json +13 -13
  156. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  157. package/dist/web/standalone/.next/server/middleware-manifest.json +5 -5
  158. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  159. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  160. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  161. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  162. package/dist/web/standalone/.next/server/webpack-runtime.js +1 -1
  163. package/dist/web/standalone/.next/static/chunks/2556.0527fea66e123b7f.js +1 -0
  164. package/dist/web/standalone/.next/static/chunks/2824.08296bc2f9654698.js +1 -0
  165. package/dist/web/standalone/.next/static/chunks/3026.3af53b279375f082.js +1 -0
  166. package/dist/web/standalone/.next/static/chunks/315.6f68ae79b67d25cf.js +1 -0
  167. package/dist/web/standalone/.next/static/chunks/3497.4bfc60a3b3dea717.js +1 -0
  168. package/dist/web/standalone/.next/static/chunks/5516.4a07c872b5c3a663.js +1 -0
  169. package/dist/web/standalone/.next/static/chunks/8336.31b019697882acfb.js +10 -0
  170. package/dist/web/standalone/.next/static/chunks/8845.c9702695e8c5a9c5.js +2 -0
  171. package/dist/web/standalone/.next/static/chunks/9058.01ef3a463bda88f1.js +20 -0
  172. package/dist/web/standalone/.next/static/chunks/9441.1081da1125d1764f.js +1 -0
  173. package/dist/web/standalone/.next/static/chunks/app/{page-5b113fd32bc2a1c3.js → page-9bf2e0c50fb2ca05.js} +1 -1
  174. package/dist/web/standalone/.next/static/chunks/webpack-f9f0dc45e4f3ac10.js +1 -0
  175. package/dist/web/standalone/package.json +2 -1
  176. package/dist/welcome-screen.js +27 -1
  177. package/dist/worktree-cli.d.ts +1 -0
  178. package/dist/worktree-cli.js +9 -3
  179. package/dist/worktree-status-banner.d.ts +1 -0
  180. package/dist/worktree-status-banner.js +132 -0
  181. package/package.json +1 -3
  182. package/packages/daemon/package.json +2 -2
  183. package/packages/mcp-server/dist/alias-telemetry.d.ts +8 -0
  184. package/packages/mcp-server/dist/alias-telemetry.d.ts.map +1 -0
  185. package/packages/mcp-server/dist/alias-telemetry.js +30 -0
  186. package/packages/mcp-server/dist/alias-telemetry.js.map +1 -0
  187. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  188. package/packages/mcp-server/dist/workflow-tools.js +74 -46
  189. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  190. package/packages/mcp-server/package.json +2 -2
  191. package/packages/mcp-server/src/alias-telemetry.test.ts +78 -0
  192. package/packages/mcp-server/src/alias-telemetry.ts +30 -0
  193. package/packages/mcp-server/src/workflow-tools.test.ts +78 -0
  194. package/packages/mcp-server/src/workflow-tools.ts +93 -58
  195. package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
  196. package/packages/native/package.json +1 -1
  197. package/packages/native/tsconfig.tsbuildinfo +1 -1
  198. package/packages/pi-agent-core/package.json +1 -1
  199. package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -1
  200. package/packages/pi-ai/dist/providers/anthropic-shared.cache-breakpoint.test.d.ts +2 -0
  201. package/packages/pi-ai/dist/providers/anthropic-shared.cache-breakpoint.test.d.ts.map +1 -0
  202. package/packages/pi-ai/dist/providers/anthropic-shared.cache-breakpoint.test.js +231 -0
  203. package/packages/pi-ai/dist/providers/anthropic-shared.cache-breakpoint.test.js.map +1 -0
  204. package/packages/pi-ai/dist/providers/anthropic-shared.d.ts.map +1 -1
  205. package/packages/pi-ai/dist/providers/anthropic-shared.js +48 -19
  206. package/packages/pi-ai/dist/providers/anthropic-shared.js.map +1 -1
  207. package/packages/pi-ai/dist/types.d.ts +13 -0
  208. package/packages/pi-ai/dist/types.d.ts.map +1 -1
  209. package/packages/pi-ai/dist/types.js.map +1 -1
  210. package/packages/pi-ai/dist/utils/repair-tool-json.d.ts.map +1 -1
  211. package/packages/pi-ai/dist/utils/repair-tool-json.js +24 -3
  212. package/packages/pi-ai/dist/utils/repair-tool-json.js.map +1 -1
  213. package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.js +26 -0
  214. package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.js.map +1 -1
  215. package/packages/pi-ai/package.json +1 -1
  216. package/packages/pi-ai/src/providers/anthropic-shared.cache-breakpoint.test.ts +289 -0
  217. package/packages/pi-ai/src/providers/anthropic-shared.ts +52 -20
  218. package/packages/pi-ai/src/types.ts +13 -0
  219. package/packages/pi-ai/src/utils/repair-tool-json.ts +24 -3
  220. package/packages/pi-ai/src/utils/tests/repair-tool-json.test.ts +32 -0
  221. package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
  222. package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
  223. package/packages/pi-coding-agent/dist/core/agent-session.js +6 -0
  224. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  225. package/packages/pi-coding-agent/dist/core/messages.d.ts.map +1 -1
  226. package/packages/pi-coding-agent/dist/core/messages.js +4 -0
  227. package/packages/pi-coding-agent/dist/core/messages.js.map +1 -1
  228. package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js +19 -2
  229. package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js.map +1 -1
  230. package/packages/pi-coding-agent/dist/core/model-registry.d.ts +10 -0
  231. package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
  232. package/packages/pi-coding-agent/dist/core/model-registry.js +18 -0
  233. package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
  234. package/packages/pi-coding-agent/dist/core/system-prompt.d.ts +13 -0
  235. package/packages/pi-coding-agent/dist/core/system-prompt.d.ts.map +1 -1
  236. package/packages/pi-coding-agent/dist/core/system-prompt.js +20 -16
  237. package/packages/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
  238. package/packages/pi-coding-agent/dist/core/token-telemetry.d.ts +37 -0
  239. package/packages/pi-coding-agent/dist/core/token-telemetry.d.ts.map +1 -0
  240. package/packages/pi-coding-agent/dist/core/token-telemetry.js +49 -0
  241. package/packages/pi-coding-agent/dist/core/token-telemetry.js.map +1 -0
  242. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.d.ts +2 -0
  243. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.d.ts.map +1 -0
  244. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.js +133 -0
  245. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.js.map +1 -0
  246. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js +1 -1
  247. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js.map +1 -1
  248. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js +14 -1
  249. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js.map +1 -1
  250. package/packages/pi-coding-agent/dist/tests/system-prompt-cache-stability.test.d.ts +2 -0
  251. package/packages/pi-coding-agent/dist/tests/system-prompt-cache-stability.test.d.ts.map +1 -0
  252. package/packages/pi-coding-agent/dist/tests/system-prompt-cache-stability.test.js +78 -0
  253. package/packages/pi-coding-agent/dist/tests/system-prompt-cache-stability.test.js.map +1 -0
  254. package/packages/pi-coding-agent/dist/tests/token-telemetry.test.d.ts +2 -0
  255. package/packages/pi-coding-agent/dist/tests/token-telemetry.test.d.ts.map +1 -0
  256. package/packages/pi-coding-agent/dist/tests/token-telemetry.test.js +181 -0
  257. package/packages/pi-coding-agent/dist/tests/token-telemetry.test.js.map +1 -0
  258. package/packages/pi-coding-agent/package.json +1 -1
  259. package/packages/pi-coding-agent/src/core/agent-session.ts +7 -0
  260. package/packages/pi-coding-agent/src/core/messages.ts +4 -0
  261. package/packages/pi-coding-agent/src/core/model-registry-auth-mode.test.ts +32 -2
  262. package/packages/pi-coding-agent/src/core/model-registry.ts +21 -0
  263. package/packages/pi-coding-agent/src/core/system-prompt.ts +33 -15
  264. package/packages/pi-coding-agent/src/core/token-telemetry.ts +77 -0
  265. package/packages/pi-coding-agent/src/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.ts +212 -0
  266. package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.test.ts +17 -1
  267. package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.ts +1 -1
  268. package/packages/pi-coding-agent/src/tests/system-prompt-cache-stability.test.ts +102 -0
  269. package/packages/pi-coding-agent/src/tests/token-telemetry.test.ts +200 -0
  270. package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
  271. package/packages/pi-tui/dist/__tests__/autocomplete.test.js +17 -3
  272. package/packages/pi-tui/dist/__tests__/autocomplete.test.js.map +1 -1
  273. package/packages/pi-tui/dist/components/__tests__/leak-fixes-runtime.test.d.ts +2 -0
  274. package/packages/pi-tui/dist/components/__tests__/leak-fixes-runtime.test.d.ts.map +1 -0
  275. package/packages/pi-tui/dist/components/__tests__/leak-fixes-runtime.test.js +161 -0
  276. package/packages/pi-tui/dist/components/__tests__/leak-fixes-runtime.test.js.map +1 -0
  277. package/packages/pi-tui/package.json +1 -1
  278. package/packages/pi-tui/src/__tests__/autocomplete.test.ts +20 -3
  279. package/packages/pi-tui/src/components/__tests__/leak-fixes-runtime.test.ts +219 -0
  280. package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
  281. package/packages/rpc-client/package.json +1 -1
  282. package/pkg/package.json +1 -1
  283. package/src/resources/extensions/claude-code-cli/readiness.ts +92 -47
  284. package/src/resources/extensions/google-search/index.ts +2 -9
  285. package/src/resources/extensions/gsd/auto/loop.ts +24 -2
  286. package/src/resources/extensions/gsd/auto/phases.ts +6 -14
  287. package/src/resources/extensions/gsd/auto/run-unit.ts +26 -12
  288. package/src/resources/extensions/gsd/auto/session.ts +5 -6
  289. package/src/resources/extensions/gsd/auto/types.ts +1 -0
  290. package/src/resources/extensions/gsd/auto-dashboard.ts +3 -2
  291. package/src/resources/extensions/gsd/auto-direct-dispatch.ts +60 -24
  292. package/src/resources/extensions/gsd/auto-dispatch.ts +18 -6
  293. package/src/resources/extensions/gsd/auto-prompts.ts +66 -2
  294. package/src/resources/extensions/gsd/auto-recovery.ts +46 -8
  295. package/src/resources/extensions/gsd/auto-runtime-state.ts +51 -0
  296. package/src/resources/extensions/gsd/auto-start.ts +1 -1
  297. package/src/resources/extensions/gsd/auto-tool-tracking.ts +2 -4
  298. package/src/resources/extensions/gsd/auto-worktree.ts +82 -12
  299. package/src/resources/extensions/gsd/auto.ts +37 -10
  300. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +15 -13
  301. package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +8 -7
  302. package/src/resources/extensions/gsd/bootstrap/query-tools.ts +2 -2
  303. package/src/resources/extensions/gsd/bootstrap/register-extension.ts +10 -9
  304. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +121 -31
  305. package/src/resources/extensions/gsd/bootstrap/register-shortcuts.ts +12 -6
  306. package/src/resources/extensions/gsd/bootstrap/subagent-input.ts +20 -0
  307. package/src/resources/extensions/gsd/bootstrap/system-context.ts +50 -8
  308. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +141 -11
  309. package/src/resources/extensions/gsd/commands/catalog.ts +82 -5
  310. package/src/resources/extensions/gsd/commands/handlers/core.ts +23 -1
  311. package/src/resources/extensions/gsd/commands/handlers/ops.ts +10 -0
  312. package/src/resources/extensions/gsd/commands-config.ts +3 -2
  313. package/src/resources/extensions/gsd/commands-extensions.ts +43 -3
  314. package/src/resources/extensions/gsd/commands-handlers.ts +3 -2
  315. package/src/resources/extensions/gsd/commands-mcp-status.ts +3 -1
  316. package/src/resources/extensions/gsd/commands-prefs-wizard.ts +15 -1
  317. package/src/resources/extensions/gsd/commands-worktree.ts +383 -0
  318. package/src/resources/extensions/gsd/dashboard-overlay.ts +1 -1
  319. package/src/resources/extensions/gsd/docs/preferences-reference.md +10 -0
  320. package/src/resources/extensions/gsd/doctor-providers.ts +2 -1
  321. package/src/resources/extensions/gsd/doctor-runtime-checks.ts +39 -1
  322. package/src/resources/extensions/gsd/doctor-types.ts +3 -1
  323. package/src/resources/extensions/gsd/error-classifier.ts +1 -1
  324. package/src/resources/extensions/gsd/forensics.ts +12 -7
  325. package/src/resources/extensions/gsd/git-service.ts +13 -5
  326. package/src/resources/extensions/gsd/gsd-db.ts +12 -2
  327. package/src/resources/extensions/gsd/guided-flow.ts +27 -26
  328. package/src/resources/extensions/gsd/home-dir.ts +19 -0
  329. package/src/resources/extensions/gsd/journal.ts +4 -1
  330. package/src/resources/extensions/gsd/key-manager.ts +2 -1
  331. package/src/resources/extensions/gsd/memory-store.ts +81 -28
  332. package/src/resources/extensions/gsd/migrate/command.ts +3 -2
  333. package/src/resources/extensions/gsd/milestone-id-reservation.ts +47 -0
  334. package/src/resources/extensions/gsd/model-router.ts +172 -9
  335. package/src/resources/extensions/gsd/native-git-bridge.ts +7 -1
  336. package/src/resources/extensions/gsd/preferences-models.ts +101 -15
  337. package/src/resources/extensions/gsd/preferences-types.ts +6 -0
  338. package/src/resources/extensions/gsd/preferences-validation.ts +35 -0
  339. package/src/resources/extensions/gsd/preferences.ts +16 -2
  340. package/src/resources/extensions/gsd/prompt-loader.ts +26 -12
  341. package/src/resources/extensions/gsd/prompts/complete-milestone.md +10 -0
  342. package/src/resources/extensions/gsd/prompts/complete-slice.md +10 -0
  343. package/src/resources/extensions/gsd/prompts/guided-discuss-milestone.md +2 -0
  344. package/src/resources/extensions/gsd/prompts/parallel-research-slices.md +2 -0
  345. package/src/resources/extensions/gsd/prompts/plan-slice.md +10 -0
  346. package/src/resources/extensions/gsd/prompts/refine-slice.md +10 -0
  347. package/src/resources/extensions/gsd/prompts/rewrite-docs.md +2 -0
  348. package/src/resources/extensions/gsd/slice-parallel-orchestrator.ts +9 -3
  349. package/src/resources/extensions/gsd/state.ts +42 -0
  350. package/src/resources/extensions/gsd/templates/PREFERENCES.md +1 -0
  351. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +179 -1
  352. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +58 -0
  353. package/src/resources/extensions/gsd/tests/auto-session-encapsulation.test.ts +24 -5
  354. package/src/resources/extensions/gsd/tests/auto-supervisor.test.mjs +21 -4
  355. package/src/resources/extensions/gsd/tests/bootstrap-derive-state-db-open.test.ts +1 -1
  356. package/src/resources/extensions/gsd/tests/budget-prediction.test.ts +138 -211
  357. package/src/resources/extensions/gsd/tests/bundled-skill-triggers.test.ts +50 -27
  358. package/src/resources/extensions/gsd/tests/commands-extensions-version-compare.test.ts +58 -0
  359. package/src/resources/extensions/gsd/tests/commands-worktree-clean.test.ts +48 -0
  360. package/src/resources/extensions/gsd/tests/complete-slice-verification-gate.test.ts +142 -59
  361. package/src/resources/extensions/gsd/tests/complete-slice.test.ts +7 -4
  362. package/src/resources/extensions/gsd/tests/completed-at-reconcile.test.ts +89 -32
  363. package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +41 -23
  364. package/src/resources/extensions/gsd/tests/db-path-worktree-symlink.test.ts +3 -43
  365. package/src/resources/extensions/gsd/tests/debug-logger.test.ts +5 -3
  366. package/src/resources/extensions/gsd/tests/deferred-milestone-dir-4996.test.ts +116 -0
  367. package/src/resources/extensions/gsd/tests/discuss-empty-db-fallback.test.ts +22 -87
  368. package/src/resources/extensions/gsd/tests/discuss-queued-milestones.test.ts +7 -118
  369. package/src/resources/extensions/gsd/tests/discuss-tool-scope-leak.test.ts +18 -60
  370. package/src/resources/extensions/gsd/tests/doctor-orphan-milestone-4996.test.ts +100 -0
  371. package/src/resources/extensions/gsd/tests/double-merge-guard.test.ts +14 -76
  372. package/src/resources/extensions/gsd/tests/ensure-preconditions-guard-4996.test.ts +93 -0
  373. package/src/resources/extensions/gsd/tests/false-degraded-mode-warning.test.ts +22 -83
  374. package/src/resources/extensions/gsd/tests/finalize-timeout-guard.test.ts +1 -63
  375. package/src/resources/extensions/gsd/tests/find-missing-summaries-closed-runtime.test.ts +47 -0
  376. package/src/resources/extensions/gsd/tests/forensics-stuck-loops.test.ts +26 -1
  377. package/src/resources/extensions/gsd/tests/gitignore-bg-shell-runtime.test.ts +63 -0
  378. package/src/resources/extensions/gsd/tests/google-search-stub.test.ts +25 -65
  379. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +30 -0
  380. package/src/resources/extensions/gsd/tests/gsd-no-project-error-runtime.test.ts +81 -0
  381. package/src/resources/extensions/gsd/tests/headless-answers.test.ts +14 -4
  382. package/src/resources/extensions/gsd/tests/health-widget.test.ts +22 -12
  383. package/src/resources/extensions/gsd/tests/help-menu-coverage.test.ts +57 -0
  384. package/src/resources/extensions/gsd/tests/home-dir.test.ts +52 -0
  385. package/src/resources/extensions/gsd/tests/import-done-milestones-runtime.test.ts +145 -0
  386. package/src/resources/extensions/gsd/tests/init-prefs-routing.test.ts +64 -1
  387. package/src/resources/extensions/gsd/tests/integration/auto-worktree.test.ts +72 -1
  388. package/src/resources/extensions/gsd/tests/integration/token-savings.test.ts +0 -23
  389. package/src/resources/extensions/gsd/tests/memory-store.test.ts +128 -0
  390. package/src/resources/extensions/gsd/tests/memory-tools.test.ts +33 -1
  391. package/src/resources/extensions/gsd/tests/merge-self-branch-guard.test.ts +124 -0
  392. package/src/resources/extensions/gsd/tests/milestone-id-gap-reuse-4996.test.ts +152 -0
  393. package/src/resources/extensions/gsd/tests/milestone-report-path.test.ts +18 -1
  394. package/src/resources/extensions/gsd/tests/model-router.test.ts +169 -8
  395. package/src/resources/extensions/gsd/tests/native-git-infra-errors.test.ts +50 -0
  396. package/src/resources/extensions/gsd/tests/orphaned-worktree-audit.test.ts +8 -0
  397. package/src/resources/extensions/gsd/tests/parallel-crash-recovery.test.ts +32 -43
  398. package/src/resources/extensions/gsd/tests/phases-merge-error-stops-auto.test.ts +4 -10
  399. package/src/resources/extensions/gsd/tests/preferences.test.ts +127 -0
  400. package/src/resources/extensions/gsd/tests/prompt-step-ordering.test.ts +16 -0
  401. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +7 -0
  402. package/src/resources/extensions/gsd/tests/quick-turn-end-cleanup.test.ts +6 -6
  403. package/src/resources/extensions/gsd/tests/register-hooks-compaction-checkpoint.test.ts +93 -0
  404. package/src/resources/extensions/gsd/tests/safety-harness-false-positives.test.ts +34 -0
  405. package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +168 -19
  406. package/src/resources/extensions/gsd/tests/slice-parallel-orchestrator.test.ts +7 -1
  407. package/src/resources/extensions/gsd/tests/smart-entry-complete.test.ts +23 -1
  408. package/src/resources/extensions/gsd/tests/steer-worktree-path.test.ts +17 -1
  409. package/src/resources/extensions/gsd/tests/system-context-message-routing.test.ts +101 -0
  410. package/src/resources/extensions/gsd/tests/token-profile.test.ts +51 -4
  411. package/src/resources/extensions/gsd/tests/turn-epoch.test.ts +7 -16
  412. package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +38 -3
  413. package/src/resources/extensions/gsd/tests/unstructured-continue-context-injection.test.ts +5 -7
  414. package/src/resources/extensions/gsd/tests/uok-gitops-turn-action.test.ts +15 -1
  415. package/src/resources/extensions/gsd/tests/visualizer-overlay.test.ts +6 -6
  416. package/src/resources/extensions/gsd/tests/worktree-path-injection.test.ts +235 -0
  417. package/src/resources/extensions/gsd/tests/worktree-symlink-removal.test.ts +34 -33
  418. package/src/resources/extensions/gsd/tests/worktree.test.ts +8 -0
  419. package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +131 -1
  420. package/src/resources/extensions/gsd/tools/memory-tools.ts +17 -1
  421. package/src/resources/extensions/gsd/unit-context-manifest.ts +44 -12
  422. package/src/resources/extensions/gsd/visualizer-overlay.ts +1 -1
  423. package/src/resources/extensions/gsd/watch/header-renderer.ts +3 -1
  424. package/src/resources/extensions/gsd/workflow-logger.ts +1 -0
  425. package/src/resources/extensions/gsd/worktree-command.ts +31 -44
  426. package/src/resources/extensions/gsd/worktree-manager.ts +40 -1
  427. package/src/resources/extensions/gsd/worktree-resolver.ts +4 -14
  428. package/src/resources/extensions/gsd/worktree-root.ts +144 -0
  429. package/src/resources/extensions/gsd/worktree-session-state.ts +35 -0
  430. package/src/resources/extensions/gsd/worktree.ts +8 -119
  431. package/src/resources/extensions/mcp-client/index.ts +6 -10
  432. package/src/resources/extensions/mcp-client/tests/global-config.test.ts +91 -0
  433. package/src/resources/extensions/ollama/index.ts +16 -2
  434. package/src/resources/extensions/ollama/model-capabilities.ts +34 -0
  435. package/src/resources/extensions/ollama/ollama-client.ts +41 -4
  436. package/src/resources/extensions/ollama/tests/model-capabilities.test.ts +96 -0
  437. package/src/resources/extensions/ollama/tests/ollama-client-timeout-env.test.ts +147 -0
  438. package/src/resources/extensions/slash-commands/create-extension.ts +38 -24
  439. package/src/resources/extensions/subagent/index.ts +165 -7
  440. package/src/resources/skills/create-gsd-extension/SKILL.md +9 -5
  441. package/src/resources/skills/create-gsd-extension/references/custom-commands.md +1 -1
  442. package/src/resources/skills/create-gsd-extension/references/custom-rendering.md +5 -5
  443. package/src/resources/skills/create-gsd-extension/references/custom-tools.md +4 -4
  444. package/src/resources/skills/create-gsd-extension/references/custom-ui.md +6 -6
  445. package/src/resources/skills/create-gsd-extension/references/events-reference.md +3 -3
  446. package/src/resources/skills/create-gsd-extension/references/packaging-distribution.md +1 -1
  447. package/src/resources/skills/create-gsd-extension/references/remote-execution-overrides.md +3 -3
  448. package/src/resources/skills/create-gsd-extension/templates/extension-skeleton.ts +2 -2
  449. package/src/resources/skills/create-gsd-extension/templates/stateful-tool-skeleton.ts +3 -3
  450. package/src/resources/skills/create-gsd-extension/templates/templates.test.ts +58 -0
  451. package/src/resources/skills/create-gsd-extension/workflows/create-extension.md +32 -12
  452. package/src/resources/skills/lint/SKILL.md +4 -0
  453. package/src/resources/skills/review/SKILL.md +4 -0
  454. package/src/resources/skills/test/SKILL.md +3 -0
  455. package/dist/resources/extensions/browser-tools/tests/browser-tools-integration.test.mjs +0 -601
  456. package/dist/resources/extensions/browser-tools/tests/browser-tools-unit.test.cjs +0 -651
  457. package/dist/resources/extensions/browser-tools/tests/capture-sharp-optional.test.cjs +0 -91
  458. package/dist/resources/extensions/gsd/tests/auto-supervisor.test.mjs +0 -53
  459. package/dist/resources/extensions/gsd/tests/dist-redirect.mjs +0 -112
  460. package/dist/resources/extensions/gsd/tests/resolve-ts-hooks.mjs +0 -23
  461. package/dist/resources/extensions/gsd/tests/resolve-ts.mjs +0 -5
  462. package/dist/resources/skills/github-workflows/references/gh/tests/__init__.py +0 -0
  463. package/dist/resources/skills/github-workflows/references/gh/tests/test_github_project_setup.py +0 -608
  464. package/dist/web/standalone/.next/static/chunks/2826.e9f5195e91f9cad2.js +0 -11
  465. package/dist/web/standalone/.next/static/chunks/3621.fc7480022c972438.js +0 -20
  466. package/dist/web/standalone/.next/static/chunks/webpack-2e68521d7c82f7c2.js +0 -1
  467. package/src/resources/extensions/gsd/tests/copy-planning-artifacts-samepath.test.ts +0 -22
  468. package/src/resources/extensions/gsd/tests/discuss-slice-structured-questions.test.ts +0 -47
  469. package/src/resources/extensions/gsd/tests/empty-content-abort-loop.test.ts +0 -75
  470. /package/dist/web/standalone/.next/static/{cAJH99yNS1UPbeSEiNRrV → 4iu6IYeYfxOq8OidlDqp6}/_buildManifest.js +0 -0
  471. /package/dist/web/standalone/.next/static/{cAJH99yNS1UPbeSEiNRrV → 4iu6IYeYfxOq8OidlDqp6}/_ssgManifest.js +0 -0
@@ -5,24 +5,16 @@ 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";
9
8
 
10
9
  import { buildMilestoneFileName, resolveMilestonePath, resolveSliceFile, resolveSlicePath } from "../paths.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";
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";
14
12
  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";
18
13
  import { loadFile, saveFile, formatContinue } from "../files.js";
19
- import { deriveState } from "../state.js";
20
- import { getAutoDashboardData, isAutoActive, isAutoPaused, markToolEnd, markToolStart, recordToolInvocationError } from "../auto.js";
14
+ import { getAutoRuntimeSnapshot, isAutoActive, isAutoPaused, markToolEnd, markToolStart, recordToolInvocationError } from "../auto-runtime-state.js";
21
15
 
22
- import { isParallelActive, shutdownParallel } from "../parallel-orchestrator.js";
23
16
  import { checkToolCallLoop, resetToolCallLoopGuard } from "./tool-call-loop-guard.js";
24
17
  import { saveActivityLog } from "../activity-log.js";
25
- import { resetAskUserQuestionsCache } from "../../ask-user-questions.js";
26
18
  import { recordToolCall as safetyRecordToolCall, recordToolResult as safetyRecordToolResult, saveEvidenceToDisk } from "../safety/evidence-collector.js";
27
19
  import { parseUnitId } from "../unit-id.js";
28
20
  import { classifyCommand } from "../safety/destructive-guard.js";
@@ -30,17 +22,46 @@ import { logWarning as safetyLogWarning } from "../workflow-logger.js";
30
22
  import { installNotifyInterceptor } from "./notify-interceptor.js";
31
23
  import { initNotificationStore } from "../notification-store.js";
32
24
  import { initNotificationWidget } from "../notification-widget.js";
33
- import { initHealthWidget } from "../health-widget.js";
25
+ import { extractSubagentAgentClasses } from "./subagent-input.js";
34
26
 
35
27
  // Skip the welcome screen on the very first session_start — cli.ts already
36
28
  // printed it before the TUI launched. Only re-print on /clear (subsequent sessions).
37
29
  let isFirstSession = true;
38
30
 
31
+ async function deriveGsdState(basePath: string) {
32
+ const { deriveState } = await import("../state.js");
33
+ return deriveState(basePath);
34
+ }
35
+
36
+ async function getDiscussionMilestoneIdFor(basePath: string): Promise<string | null> {
37
+ const { getDiscussionMilestoneId } = await import("../guided-flow.js");
38
+ return getDiscussionMilestoneId(basePath);
39
+ }
40
+
41
+ async function loadToolApiKeysForSession(): Promise<void> {
42
+ const { loadToolApiKeys } = await import("../commands-config.js");
43
+ loadToolApiKeys();
44
+ }
45
+
46
+ async function resetAskUserQuestionsTurnCache(): Promise<void> {
47
+ const { resetAskUserQuestionsCache } = await import("../../ask-user-questions.js");
48
+ resetAskUserQuestionsCache();
49
+ }
50
+
39
51
  async function syncServiceTierStatus(ctx: ExtensionContext): Promise<void> {
40
52
  const { getEffectiveServiceTier, formatServiceTierFooterStatus } = await import("../service-tier.js");
41
53
  ctx.ui.setStatus("gsd-fast", formatServiceTierFooterStatus(getEffectiveServiceTier(), ctx.model?.id));
42
54
  }
43
55
 
56
+ async function applyDisabledModelProviderPolicy(ctx: ExtensionContext): Promise<void> {
57
+ try {
58
+ const { resolveDisabledModelProvidersFromPreferences } = await import("../preferences.js");
59
+ ctx.modelRegistry.setDisabledModelProviders(resolveDisabledModelProvidersFromPreferences());
60
+ } catch {
61
+ // Non-fatal: keep default provider visibility if preferences cannot be loaded.
62
+ }
63
+ }
64
+
44
65
  export function registerHooks(
45
66
  pi: ExtensionAPI,
46
67
  ecosystemHandlers: GSDEcosystemBeforeAgentStartHandler[],
@@ -50,12 +71,14 @@ export function registerHooks(
50
71
  installNotifyInterceptor(ctx);
51
72
  initNotificationWidget(ctx);
52
73
  if (!isAutoActive()) {
74
+ const { initHealthWidget } = await import("../health-widget.js");
53
75
  initHealthWidget(ctx);
54
76
  }
55
77
  resetWriteGateState();
56
78
  resetToolCallLoopGuard();
57
- resetAskUserQuestionsCache();
79
+ await resetAskUserQuestionsTurnCache();
58
80
  await syncServiceTierStatus(ctx);
81
+ await applyDisabledModelProviderPolicy(ctx);
59
82
  // Skip MCP auto-prep when running inside an auto-worktree (see session_switch below).
60
83
  const { isInAutoWorktree } = await import("../auto-worktree.js");
61
84
  if (!isInAutoWorktree(process.cwd())) {
@@ -91,7 +114,7 @@ export function registerHooks(
91
114
  }
92
115
  } catch { /* non-fatal */ }
93
116
  }
94
- loadToolApiKeys();
117
+ await loadToolApiKeysForSession();
95
118
  if (isAutoActive()) {
96
119
  ctx.ui.setWidget("gsd-health", undefined);
97
120
  }
@@ -102,9 +125,10 @@ export function registerHooks(
102
125
  installNotifyInterceptor(ctx);
103
126
  resetWriteGateState();
104
127
  resetToolCallLoopGuard();
105
- resetAskUserQuestionsCache();
128
+ await resetAskUserQuestionsTurnCache();
106
129
  clearDiscussionFlowState();
107
130
  await syncServiceTierStatus(ctx);
131
+ await applyDisabledModelProviderPolicy(ctx);
108
132
  // Skip MCP auto-prep when running inside an auto-worktree. The worktree
109
133
  // already has .mcp.json from createAutoWorktree, and re-running the writer
110
134
  // post-chdir rewrites the file mid-run (non-idempotent due to cwd-relative
@@ -114,23 +138,28 @@ export function registerHooks(
114
138
  const { prepareWorkflowMcpForProject } = await import("../workflow-mcp-auto-prep.js");
115
139
  prepareWorkflowMcpForProject(ctx, process.cwd());
116
140
  }
117
- loadToolApiKeys();
118
- if (isAutoActive()) {
141
+ await loadToolApiKeysForSession();
142
+ if (!isAutoActive()) {
143
+ const { initHealthWidget } = await import("../health-widget.js");
144
+ initHealthWidget(ctx);
145
+ } else {
119
146
  ctx.ui.setWidget("gsd-health", undefined);
120
147
  }
121
148
  });
122
149
 
123
150
  pi.on("before_agent_start", async (event, ctx: ExtensionContext) => {
124
151
  // Wait for ecosystem loader to finish (no-op after first turn).
152
+ const { getEcosystemReadyPromise } = await import("../ecosystem/loader.js");
125
153
  await getEcosystemReadyPromise();
126
154
 
127
155
  // GSD's own context injection (existing behavior — unchanged).
156
+ const { buildBeforeAgentStartResult } = await import("./system-context.js");
128
157
  const gsdResult = await buildBeforeAgentStartResult(event, ctx);
129
158
 
130
159
  // Refresh the snapshot used by ecosystem getPhase()/getActiveUnit().
131
160
  // deriveState has its own ~100ms cache so this is cheap on repeat calls.
132
161
  try {
133
- const state = await deriveState(process.cwd());
162
+ const state = await deriveGsdState(process.cwd());
134
163
  updateSnapshot(state);
135
164
  } catch {
136
165
  updateSnapshot(null);
@@ -169,7 +198,8 @@ export function registerHooks(
169
198
 
170
199
  pi.on("agent_end", async (event, ctx: ExtensionContext) => {
171
200
  resetToolCallLoopGuard();
172
- resetAskUserQuestionsCache();
201
+ await resetAskUserQuestionsTurnCache();
202
+ const { handleAgentEnd } = await import("./agent-end-recovery.js");
173
203
  await handleAgentEnd(pi, event, ctx);
174
204
  });
175
205
 
@@ -178,6 +208,7 @@ export function registerHooks(
178
208
  // quick-return state is pending, so this is safe to call on every turn.
179
209
  pi.on("turn_end", async () => {
180
210
  try {
211
+ const { cleanupQuickBranch } = await import("../quick.js");
181
212
  cleanupQuickBranch();
182
213
  } catch {
183
214
  // Best-effort: don't break the turn lifecycle if cleanup fails.
@@ -194,8 +225,8 @@ export function registerHooks(
194
225
  const basePath = process.cwd();
195
226
  const { ensureDbOpen } = await import("./dynamic-tools.js");
196
227
  await ensureDbOpen();
197
- const state = await deriveState(basePath);
198
- if (!state.activeMilestone || !state.activeSlice || !state.activeTask) return;
228
+ const state = await deriveGsdState(basePath);
229
+ if (!state.activeMilestone || !state.activeSlice) return;
199
230
  // Write checkpoint for ALL phases, not just "executing" — discuss, research,
200
231
  // and planning also carry in-memory state (user answers, gate verification)
201
232
  // that would be lost on compaction (#4258).
@@ -210,21 +241,31 @@ export function registerHooks(
210
241
  if (await loadFile(legacyContinue)) return;
211
242
 
212
243
  const continuePath = join(sliceDir, `${state.activeSlice.id}-CONTINUE.md`);
244
+ const taskId = state.activeTask?.id ?? "none";
245
+ const taskTitle = state.activeTask?.title ?? "";
246
+ const phaseLabel = state.phase.replace(/-/g, " ");
247
+
213
248
  await saveFile(continuePath, formatContinue({
214
249
  frontmatter: {
215
250
  milestone: state.activeMilestone.id,
216
251
  slice: state.activeSlice.id,
217
- task: state.activeTask.id,
252
+ task: taskId,
218
253
  step: 0,
219
254
  totalSteps: 0,
220
255
  status: "compacted" as const,
221
256
  savedAt: new Date().toISOString(),
222
257
  },
223
- completedWork: `Task ${state.activeTask.id} (${state.activeTask.title}) was in progress when compaction occurred.`,
224
- remainingWork: "Check the task plan for remaining steps.",
258
+ completedWork: state.activeTask
259
+ ? `Task ${taskId} (${taskTitle}) was in progress when compaction occurred.`
260
+ : `Slice ${state.activeSlice.id} was in ${phaseLabel} phase when compaction occurred.`,
261
+ remainingWork: state.activeTask
262
+ ? "Check the task plan for remaining steps."
263
+ : "Continue this slice from the latest planning/research/discussion artifacts.",
225
264
  decisions: "Check task summary files for prior decisions.",
226
265
  context: "Session was auto-compacted by Pi. Resume with /gsd.",
227
- nextAction: `Resume task ${state.activeTask.id}: ${state.activeTask.title}.`,
266
+ nextAction: state.activeTask
267
+ ? `Resume task ${taskId}: ${taskTitle}.`
268
+ : `Resume ${phaseLabel} work for slice ${state.activeSlice.id}.`,
228
269
  }));
229
270
  });
230
271
 
@@ -246,7 +287,7 @@ export function registerHooks(
246
287
  const basePath = process.cwd();
247
288
  let activeContext: string | null = null;
248
289
  try {
249
- const state = await deriveState(basePath);
290
+ const state = await deriveGsdState(basePath);
250
291
  if (state.activeMilestone && state.activeSlice && state.activeTask) {
251
292
  activeContext =
252
293
  `Active: ${state.activeMilestone.id} / ${state.activeSlice.id} / ${state.activeTask.id}` +
@@ -265,6 +306,7 @@ export function registerHooks(
265
306
  });
266
307
 
267
308
  pi.on("session_shutdown", async (_event, ctx: ExtensionContext) => {
309
+ const { isParallelActive, shutdownParallel } = await import("../parallel-orchestrator.js");
268
310
  if (isParallelActive()) {
269
311
  try {
270
312
  await shutdownParallel(process.cwd());
@@ -273,7 +315,7 @@ export function registerHooks(
273
315
  }
274
316
  }
275
317
  if (!isAutoActive() && !isAutoPaused()) return;
276
- const dash = getAutoDashboardData();
318
+ const dash = getAutoRuntimeSnapshot();
277
319
  if (dash.currentUnit) {
278
320
  saveActivityLog(ctx, dash.basePath, dash.currentUnit.type, dash.currentUnit.id);
279
321
  }
@@ -302,7 +344,7 @@ export function registerHooks(
302
344
  // If ask_user_questions was called with a gate ID but hasn't been confirmed,
303
345
  // block all non-read-only tool calls to prevent the model from skipping gates.
304
346
  if (getPendingGate()) {
305
- const milestoneId = getDiscussionMilestoneId(discussionBasePath);
347
+ const milestoneId = await getDiscussionMilestoneIdFor(discussionBasePath);
306
348
  if (isToolCallEventType("bash", event)) {
307
349
  const bashGuard = shouldBlockPendingGateBash(
308
350
  event.input.command,
@@ -337,6 +379,41 @@ export function registerHooks(
337
379
  if (queueGuard.block) return queueGuard;
338
380
  }
339
381
 
382
+ // ── Planning-unit tools-policy enforcement (#4934): runtime half ─────
383
+ // The active auto-mode unit's manifest declares a ToolsPolicy. For
384
+ // planning/docs/read-only modes, deny writes outside .gsd/ (or the
385
+ // manifest's allowedPathGlobs), bash that isn't read-only, and
386
+ // subagent dispatch. Closes the b23 bug class where a discuss-milestone
387
+ // turn used the host Edit tool to modify user source files.
388
+ const dash = getAutoRuntimeSnapshot();
389
+ const activeUnitType = dash.currentUnit?.type;
390
+ if (activeUnitType) {
391
+ const manifest = resolveManifest(activeUnitType);
392
+ if (manifest) {
393
+ let planningInput = "";
394
+ let agentClasses: string[] | undefined;
395
+ if (isToolCallEventType("write", event)) {
396
+ planningInput = event.input.path;
397
+ } else if (isToolCallEventType("edit", event)) {
398
+ planningInput = event.input.path;
399
+ } else if (isToolCallEventType("bash", event)) {
400
+ planningInput = event.input.command;
401
+ } else if (event.toolName === "subagent" || event.toolName === "task") {
402
+ // Subagent inputs use { agent }, { tasks: [{ agent }] }, or { chain: [{ agent }] }.
403
+ agentClasses = extractSubagentAgentClasses((event as { input?: unknown }).input);
404
+ }
405
+ const planningGuard = shouldBlockPlanningUnit(
406
+ event.toolName,
407
+ planningInput,
408
+ dash.basePath || discussionBasePath,
409
+ activeUnitType,
410
+ manifest.tools,
411
+ agentClasses,
412
+ );
413
+ if (planningGuard.block) return planningGuard;
414
+ }
415
+ }
416
+
340
417
  // ── Single-writer engine: block direct writes to STATE.md ──────────
341
418
  // Covers write, edit, and bash tools to prevent bypass vectors.
342
419
  if (isToolCallEventType("write", event)) {
@@ -362,7 +439,7 @@ export function registerHooks(
362
439
  const result = shouldBlockContextWrite(
363
440
  event.toolName,
364
441
  event.input.path,
365
- getDiscussionMilestoneId(discussionBasePath),
442
+ await getDiscussionMilestoneIdFor(discussionBasePath),
366
443
  isQueuePhaseActive(),
367
444
  );
368
445
  if (result.block) return result;
@@ -374,6 +451,19 @@ export function registerHooks(
374
451
  markToolStart(event.toolCallId, event.toolName);
375
452
  safetyRecordToolCall(event.toolCallId, event.toolName, event.input as Record<string, unknown>);
376
453
 
454
+ // Persist immediately at dispatch so a mid-unit re-dispatch — which calls
455
+ // resetEvidence() + loadEvidenceFromDisk() in runUnitPhase — cannot wipe
456
+ // the entry between tool_call and tool_execution_end. Without this, the
457
+ // race window equals the tool's runtime, producing the "no bash calls"
458
+ // false positive when the LLM clearly ran a verification command.
459
+ const callDash = getAutoRuntimeSnapshot();
460
+ if (callDash.basePath && callDash.currentUnit?.type === "execute-task") {
461
+ const { milestone: cMid, slice: cSid, task: cTid } = parseUnitId(callDash.currentUnit.id);
462
+ if (cMid && cSid && cTid) {
463
+ saveEvidenceToDisk(callDash.basePath, cMid, cSid, cTid);
464
+ }
465
+ }
466
+
377
467
  // Destructive command classification (warn only, never block)
378
468
  if (isToolCallEventType("bash", event)) {
379
469
  const classification = classifyCommand(event.input.command);
@@ -407,7 +497,7 @@ export function registerHooks(
407
497
  recordToolInvocationError(event.toolName, errorText);
408
498
  }
409
499
  if (event.toolName !== "ask_user_questions") return;
410
- const milestoneId = getDiscussionMilestoneId(process.cwd());
500
+ const milestoneId = await getDiscussionMilestoneIdFor(process.cwd());
411
501
  const queueActive = isQueuePhaseActive();
412
502
 
413
503
  const details = event.details as any;
@@ -506,7 +596,7 @@ export function registerHooks(
506
596
  safetyRecordToolResult(event.toolCallId, event.toolName, event.result, event.isError);
507
597
  // Persist evidence to disk after each tool result so it survives a session
508
598
  // restart mid-unit (Bug #4385 — non-persisted evidence false positives).
509
- const dash = getAutoDashboardData();
599
+ const dash = getAutoRuntimeSnapshot();
510
600
  if (dash.basePath && dash.currentUnit?.type === "execute-task") {
511
601
  const { milestone: pMid, slice: pSid, task: pTid } = parseUnitId(dash.currentUnit.id);
512
602
  if (pMid && pSid && pTid) {
@@ -4,13 +4,14 @@ 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";
10
7
  import { GSD_SHORTCUTS } from "../shortcut-defs.js";
11
- import { projectRoot } from "../commands/context.js";
12
8
  import { shortcutDesc } from "../../shared/mod.js";
13
9
 
10
+ async function getProjectRoot(): Promise<string> {
11
+ const { projectRoot } = await import("../commands/context.js");
12
+ return projectRoot();
13
+ }
14
+
14
15
  export function registerShortcuts(pi: ExtensionAPI): void {
15
16
  const overlayOptions = {
16
17
  width: "90%",
@@ -20,7 +21,10 @@ export function registerShortcuts(pi: ExtensionAPI): void {
20
21
  } as const;
21
22
 
22
23
  const openDashboardOverlay = async (ctx: ExtensionContext) => {
23
- const basePath = projectRoot();
24
+ const [{ GSDDashboardOverlay }, basePath] = await Promise.all([
25
+ import("../dashboard-overlay.js"),
26
+ getProjectRoot(),
27
+ ]);
24
28
  if (!existsSync(join(basePath, ".gsd"))) {
25
29
  ctx.ui.notify("No .gsd/ directory found. Run /gsd to start.", "info");
26
30
  return;
@@ -35,6 +39,7 @@ export function registerShortcuts(pi: ExtensionAPI): void {
35
39
  };
36
40
 
37
41
  const openNotificationsOverlay = async (ctx: ExtensionContext) => {
42
+ const { GSDNotificationOverlay } = await import("../notification-overlay.js");
38
43
  await ctx.ui.custom<boolean>(
39
44
  (tui, theme, _kb, done) => new GSDNotificationOverlay(tui, theme, () => done(true)),
40
45
  {
@@ -51,12 +56,13 @@ export function registerShortcuts(pi: ExtensionAPI): void {
51
56
  };
52
57
 
53
58
  const openParallelOverlay = async (ctx: ExtensionContext) => {
54
- const basePath = projectRoot();
59
+ const basePath = await getProjectRoot();
55
60
  const parallelDir = join(basePath, ".gsd", "parallel");
56
61
  if (!existsSync(parallelDir)) {
57
62
  ctx.ui.notify("No parallel workers found. Run /gsd parallel start first.", "info");
58
63
  return;
59
64
  }
65
+ const { ParallelMonitorOverlay } = await import("../parallel-monitor-overlay.js");
60
66
  await ctx.ui.custom<boolean>(
61
67
  (tui, theme, _kb, done) => new ParallelMonitorOverlay(tui, theme, () => done(true), basePath),
62
68
  {
@@ -0,0 +1,20 @@
1
+ export function extractSubagentAgentClasses(input: unknown): string[] {
2
+ if (!input || typeof input !== "object") return [];
3
+
4
+ const record = input as Record<string, unknown>;
5
+ const agentClasses: string[] = [];
6
+ const addAgentClass = (value: unknown): void => {
7
+ if (typeof value === "string" && value.trim().length > 0) agentClasses.push(value.trim());
8
+ };
9
+ const addFromItems = (value: unknown): void => {
10
+ if (!Array.isArray(value)) return;
11
+ for (const item of value) {
12
+ if (item && typeof item === "object") addAgentClass((item as Record<string, unknown>).agent);
13
+ }
14
+ };
15
+
16
+ addAgentClass(record.agent);
17
+ addFromItems(record.tasks);
18
+ addFromItems(record.chain);
19
+ return agentClasses;
20
+ }
@@ -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-command.js";
18
+ import { getActiveWorktreeName, getWorktreeOriginalCwd } from "../worktree-session-state.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";
@@ -52,6 +52,17 @@ export const BUNDLED_SKILL_TRIGGERS: Array<{ trigger: string; skill: string }> =
52
52
  { trigger: "HTTP/REST/GraphQL API design — verbs, status codes, pagination, errors, idempotency, versioning", skill: "api-design" },
53
53
  { trigger: "Dependency upgrades — risk-batched, verified between batches, one major per commit", skill: "dependency-upgrade" },
54
54
  { trigger: "Agent-first observability — structured logs, persisted failure state, health surfaces, explicit failure modes", skill: "observability" },
55
+ { trigger: "React/Next.js performance — components, data fetching, bundle optimization, rendering patterns from Vercel Engineering", skill: "react-best-practices" },
56
+ { trigger: "Core Web Vitals — fix LCP, CLS, INP; layout shifts; page experience optimization", skill: "core-web-vitals" },
57
+ { trigger: "GitHub Actions CI/CD — write, run, and debug workflow files; live syntax and run monitoring", skill: "github-workflows" },
58
+ { trigger: "Comprehensive web quality audit — performance, accessibility, SEO, and best-practices (Lighthouse-style)", skill: "web-quality-audit" },
59
+ { trigger: "Browser automation — open sites, fill forms, click, screenshot, scrape, or test web apps programmatically", skill: "agent-browser" },
60
+ { trigger: "Review UI code for Web Interface Guidelines compliance — UX, design, and accessibility patterns", skill: "web-design-guidelines" },
61
+ { trigger: "UI/UX patterns reference — animations, CSS, typography, prefetching, icons (file:line findings)", skill: "userinterface-wiki" },
62
+ { trigger: "Author or refine a GSD skill — SKILL.md structure, frontmatter, and best practices", skill: "create-skill" },
63
+ { trigger: "Create or debug a GSD extension — tools, commands, event hooks, custom TUI, providers", skill: "create-gsd-extension" },
64
+ { trigger: "Author a YAML workflow definition — steps, triggers, and templates", skill: "create-workflow" },
65
+ { trigger: "Deep code optimization audit — perf anti-patterns, memory leaks, algorithmic complexity, bundle size, I/O, caching, dead code (parallel pattern-based hunt)", skill: "code-optimizer" },
55
66
  ];
56
67
 
57
68
  function buildBundledSkillsTable(): string {
@@ -207,7 +218,14 @@ export async function buildBeforeAgentStartResult(
207
218
  ? `\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
219
  : "";
209
220
 
210
- const fullSystem = `${event.systemPrompt}\n\n[SYSTEM CONTEXT GSD]\n\n${systemContent}${preferenceBlock}${knowledgeBlock}${codebaseBlock}${memoryBlock}${newSkillsBlock}${worktreeBlock}${subagentModelBlock}`;
221
+ // memoryBlock is FTS-queried against the user prompt and changes per call.
222
+ // Removing it from `fullSystem` keeps the system-prompt cache breakpoint
223
+ // stable across calls — the only scoped goal of this fix. The pi-ai
224
+ // Anthropic adapter additionally cache-marks the last user turn, so the
225
+ // memoryBlock injected via the context message may itself be cached up to
226
+ // that boundary; that's orthogonal and unchanged from prior behavior. The
227
+ // load-bearing win here is preserving the system+tools cache hit. (#5019)
228
+ const fullSystem = `${event.systemPrompt}\n\n[SYSTEM CONTEXT — GSD]\n\n${systemContent}${preferenceBlock}${knowledgeBlock}${codebaseBlock}${newSkillsBlock}${worktreeBlock}${subagentModelBlock}`;
211
229
 
212
230
  stopContextTimer({
213
231
  systemPromptSize: fullSystem.length,
@@ -216,12 +234,7 @@ export async function buildBeforeAgentStartResult(
216
234
  hasNewSkills: newSkillsBlock.length > 0,
217
235
  });
218
236
 
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;
237
+ const contextMessage = buildContextMessage({ memoryBlock, injection, forensicsInjection });
225
238
 
226
239
  return {
227
240
  systemPrompt: fullSystem,
@@ -229,6 +242,35 @@ export async function buildBeforeAgentStartResult(
229
242
  };
230
243
  }
231
244
 
245
+ /**
246
+ * Route the per-call dynamic blocks (memory, guided-execute, forensics) into a
247
+ * single user-message context payload so they ride the volatile suffix instead
248
+ * of the cached system prefix. Priority when both memory and an injection are
249
+ * present: guided > forensics > memory-only. (#5019)
250
+ *
251
+ * Exported for direct unit testing — the surrounding bootstrap has too many
252
+ * filesystem and DB dependencies to exercise this routing logic in-place.
253
+ */
254
+ export function buildContextMessage(opts: {
255
+ memoryBlock: string;
256
+ injection: string | null;
257
+ forensicsInjection: string | null;
258
+ }): { customType: string; content: string; display: false } | null {
259
+ const memoryContent = opts.memoryBlock.trim();
260
+ if (opts.injection) {
261
+ const content = memoryContent ? `${memoryContent}\n\n${opts.injection}` : opts.injection;
262
+ return { customType: "gsd-guided-context", content, display: false as const };
263
+ }
264
+ if (opts.forensicsInjection) {
265
+ const content = memoryContent ? `${memoryContent}\n\n${opts.forensicsInjection}` : opts.forensicsInjection;
266
+ return { customType: "gsd-forensics", content, display: false as const };
267
+ }
268
+ if (memoryContent) {
269
+ return { customType: "gsd-memory", content: memoryContent, display: false as const };
270
+ }
271
+ return null;
272
+ }
273
+
232
274
  /**
233
275
  * ADR-013 step 4 — auto-injection parity for the memories table.
234
276
  *