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
@@ -0,0 +1,51 @@
1
+ // GSD auto-mode runtime state
2
+ import { AutoSession } from "./auto/session.js";
3
+ import type { CurrentUnit } from "./auto/session.js";
4
+ import {
5
+ isDeterministicPolicyError,
6
+ isQueuedUserMessageSkip,
7
+ isToolInvocationError,
8
+ markToolEnd as markTrackedToolEnd,
9
+ markToolStart as markTrackedToolStart,
10
+ } from "./auto-tool-tracking.js";
11
+
12
+ export const autoSession = new AutoSession();
13
+
14
+ export type AutoRuntimeSnapshot = {
15
+ active: boolean;
16
+ paused: boolean;
17
+ currentUnit: CurrentUnit | null;
18
+ basePath: string;
19
+ };
20
+
21
+ export function getAutoRuntimeSnapshot(): AutoRuntimeSnapshot {
22
+ return {
23
+ active: autoSession.active,
24
+ paused: autoSession.paused,
25
+ currentUnit: autoSession.currentUnit ? { ...autoSession.currentUnit } : null,
26
+ basePath: autoSession.basePath,
27
+ };
28
+ }
29
+
30
+ export function isAutoActive(): boolean {
31
+ return autoSession.active;
32
+ }
33
+
34
+ export function isAutoPaused(): boolean {
35
+ return autoSession.paused;
36
+ }
37
+
38
+ export function markToolStart(toolCallId: string, toolName?: string): void {
39
+ markTrackedToolStart(toolCallId, autoSession.active, toolName);
40
+ }
41
+
42
+ export function markToolEnd(toolCallId: string): void {
43
+ markTrackedToolEnd(toolCallId);
44
+ }
45
+
46
+ export function recordToolInvocationError(toolName: string, errorMsg: string): void {
47
+ if (!autoSession.active) return;
48
+ if (isToolInvocationError(errorMsg) || isQueuedUserMessageSkip(errorMsg) || isDeterministicPolicyError(errorMsg)) {
49
+ autoSession.lastToolInvocationError = `${toolName}: ${errorMsg}`;
50
+ }
51
+ }
@@ -315,7 +315,7 @@ export function auditOrphanedMilestoneBranches(
315
315
  // Branch is NOT merged — preserve for safety, warn the user
316
316
  warnings.push(
317
317
  `Branch ${branch} exists for completed milestone ${milestoneId} but is NOT merged into ${mainBranch}. ` +
318
- `This may contain unmerged work. Merge manually or run \`/gsd health --fix\` to resolve.`,
318
+ `This may contain unmerged work. Merge manually or run \`/gsd doctor fix\` to resolve.`,
319
319
  );
320
320
 
321
321
  // #4764 telemetry
@@ -151,8 +151,6 @@ export const DETERMINISTIC_POLICY_ERROR_STRINGS = [
151
151
  */
152
152
  export function isDeterministicPolicyError(errorMsg: string): boolean {
153
153
  if (!errorMsg) return false;
154
- return (
155
- DETERMINISTIC_POLICY_ERROR_RE.test(errorMsg) ||
156
- DETERMINISTIC_POLICY_ERROR_STRINGS.some(s => errorMsg.includes(s))
157
- );
154
+ return DETERMINISTIC_POLICY_ERROR_RE.test(errorMsg)
155
+ || DETERMINISTIC_POLICY_ERROR_STRINGS.some(s => errorMsg.includes(s));
158
156
  }
@@ -46,6 +46,11 @@ import {
46
46
  resolveGitHeadPath,
47
47
  nudgeGitBranchCache,
48
48
  } from "./worktree.js";
49
+ import {
50
+ isGsdWorktreePath,
51
+ normalizeWorktreePathForCompare,
52
+ resolveWorktreeProjectRoot,
53
+ } from "./worktree-root.js";
49
54
  import { MergeConflictError, readIntegrationBranch, RUNTIME_EXCLUSION_PATHS } from "./git-service.js";
50
55
  import { debugLog } from "./debug-logger.js";
51
56
  import { logWarning, logError } from "./workflow-logger.js";
@@ -990,6 +995,12 @@ export function autoWorktreeBranch(milestoneId: string): string {
990
995
  return `milestone/${milestoneId}`;
991
996
  }
992
997
 
998
+ function normalizeLocalBranchRef(branch: string): string {
999
+ return branch.startsWith("refs/heads/")
1000
+ ? branch.slice("refs/heads/".length)
1001
+ : branch;
1002
+ }
1003
+
993
1004
  // ─── Branch-mode Entry ─────────────────────────────────────────────────────
994
1005
 
995
1006
  /**
@@ -1196,6 +1207,18 @@ export function createAutoWorktree(
1196
1207
  basePath: string,
1197
1208
  milestoneId: string,
1198
1209
  ): string {
1210
+ basePath = resolveWorktreeProjectRoot(basePath);
1211
+
1212
+ // Check if repo has commits — git worktree requires a valid HEAD
1213
+ try {
1214
+ execFileSync("git", ["rev-parse", "--verify", "HEAD"], { cwd: basePath, stdio: "pipe" });
1215
+ } catch {
1216
+ throw new GSDError(
1217
+ GSD_GIT_ERROR,
1218
+ `Cannot create worktree: repository has no commits yet. Worktree isolation requires at least one commit.`,
1219
+ );
1220
+ }
1221
+
1199
1222
  const branch = autoWorktreeBranch(milestoneId);
1200
1223
 
1201
1224
  // Check if the milestone branch already exists — it survives auto-mode
@@ -1345,6 +1368,8 @@ export function teardownAutoWorktree(
1345
1368
  milestoneId: string,
1346
1369
  opts: { preserveBranch?: boolean } = {},
1347
1370
  ): void {
1371
+ originalBasePath = resolveWorktreeProjectRoot(originalBasePath);
1372
+
1348
1373
  const branch = autoWorktreeBranch(milestoneId);
1349
1374
  const { preserveBranch = false } = opts;
1350
1375
  const previousCwd = process.cwd();
@@ -1396,16 +1421,28 @@ export function teardownAutoWorktree(
1396
1421
 
1397
1422
  /**
1398
1423
  * Detect if the process is currently inside an auto-worktree.
1399
- * Checks both module state and git branch prefix.
1424
+ * Uses the current directory structure plus git branch prefix so detection
1425
+ * still works after process restart when module state has been reset.
1400
1426
  */
1401
1427
  export function isInAutoWorktree(basePath: string): boolean {
1402
- if (!originalBase) return false;
1403
1428
  const cwd = process.cwd();
1404
- const resolvedBase = existsSync(basePath) ? realpathSync(basePath) : basePath;
1405
- const wtDir = join(resolvedBase, ".gsd", "worktrees");
1406
- if (!cwd.startsWith(wtDir)) return false;
1407
- const branch = nativeGetCurrentBranch(cwd);
1408
- return branch.startsWith("milestone/");
1429
+ if (!isGsdWorktreePath(cwd)) return false;
1430
+
1431
+ const projectRoot = resolveWorktreeProjectRoot(basePath, originalBase);
1432
+ const cwdProjectRoot = resolveWorktreeProjectRoot(cwd, originalBase);
1433
+ if (
1434
+ normalizeWorktreePathForCompare(projectRoot) !==
1435
+ normalizeWorktreePathForCompare(cwdProjectRoot)
1436
+ ) {
1437
+ return false;
1438
+ }
1439
+
1440
+ try {
1441
+ const branch = nativeGetCurrentBranch(cwd);
1442
+ return branch.startsWith("milestone/");
1443
+ } catch {
1444
+ return false;
1445
+ }
1409
1446
  }
1410
1447
 
1411
1448
  /**
@@ -1420,6 +1457,8 @@ export function getAutoWorktreePath(
1420
1457
  basePath: string,
1421
1458
  milestoneId: string,
1422
1459
  ): string | null {
1460
+ basePath = resolveWorktreeProjectRoot(basePath);
1461
+
1423
1462
  const p = worktreePath(basePath, milestoneId);
1424
1463
  if (!existsSync(p)) return null;
1425
1464
 
@@ -1448,6 +1487,8 @@ export function enterAutoWorktree(
1448
1487
  basePath: string,
1449
1488
  milestoneId: string,
1450
1489
  ): string {
1490
+ basePath = resolveWorktreeProjectRoot(basePath);
1491
+
1451
1492
  const p = worktreePath(basePath, milestoneId);
1452
1493
  if (!existsSync(p)) {
1453
1494
  throw new GSDError(
@@ -1504,6 +1545,10 @@ export function getAutoWorktreeOriginalBase(): string | null {
1504
1545
  return originalBase;
1505
1546
  }
1506
1547
 
1548
+ export function _resetAutoWorktreeOriginalBaseForTests(): void {
1549
+ originalBase = null;
1550
+ }
1551
+
1507
1552
  export function getActiveAutoWorktreeContext(): {
1508
1553
  originalBase: string;
1509
1554
  worktreeName: string;
@@ -1511,11 +1556,14 @@ export function getActiveAutoWorktreeContext(): {
1511
1556
  } | null {
1512
1557
  if (!originalBase) return null;
1513
1558
  const cwd = process.cwd();
1514
- const resolvedBase = existsSync(originalBase)
1515
- ? realpathSync(originalBase)
1516
- : originalBase;
1517
- const wtDir = join(resolvedBase, ".gsd", "worktrees");
1518
- if (!cwd.startsWith(wtDir)) return null;
1559
+ if (!isGsdWorktreePath(cwd)) return null;
1560
+ const cwdProjectRoot = resolveWorktreeProjectRoot(cwd, originalBase);
1561
+ if (
1562
+ normalizeWorktreePathForCompare(cwdProjectRoot) !==
1563
+ normalizeWorktreePathForCompare(originalBase)
1564
+ ) {
1565
+ return null;
1566
+ }
1519
1567
  const worktreeName = detectWorktreeName(cwd);
1520
1568
  if (!worktreeName) return null;
1521
1569
  const branch = nativeGetCurrentBranch(cwd);
@@ -1636,6 +1684,10 @@ export function mergeMilestoneToMain(
1636
1684
  }
1637
1685
 
1638
1686
  // 3. chdir to original base
1687
+ // Note: previousCwd captures the cwd at this point — i.e. the worktree cwd
1688
+ // entering the function. Subsequent throws restore to previousCwd, leaving
1689
+ // the caller in worktree-cwd; callers (worktree-resolver) are responsible
1690
+ // for any further cwd movement on the error path.
1639
1691
  const previousCwd = process.cwd();
1640
1692
  process.chdir(originalBasePath_);
1641
1693
 
@@ -1656,6 +1708,24 @@ export function mergeMilestoneToMain(
1656
1708
  const mainBranch =
1657
1709
  integrationBranch ?? validatedPrefBranch ?? nativeDetectMainBranch(originalBasePath_);
1658
1710
 
1711
+ // Fail closed when the resolved integration branch is the milestone branch
1712
+ // itself (#5024). Stale or corrupt metadata (e.g. integrationBranch recorded
1713
+ // as "milestone/<MID>") would otherwise let the squash merge resolve to a
1714
+ // self-merge: nothing-to-commit + empty self-diff in the post-merge safety
1715
+ // check (#1792) collapse to a false success, and the worktree-resolver
1716
+ // emits worktree-merged for work that never landed on a distinct
1717
+ // integration branch.
1718
+ if (normalizeLocalBranchRef(mainBranch) === milestoneBranch) {
1719
+ process.chdir(previousCwd);
1720
+ throw new GSDError(
1721
+ GSD_GIT_ERROR,
1722
+ `Resolved integration branch "${mainBranch}" is the same ref as milestone branch ` +
1723
+ `"${milestoneBranch}" — refusing to self-merge. Integration branch metadata is invalid; ` +
1724
+ `set a distinct main_branch in GSD preferences or repair the milestone integration record ` +
1725
+ `before retrying milestone completion.`,
1726
+ );
1727
+ }
1728
+
1659
1729
  // Remove transient project-root state files before any branch or merge
1660
1730
  // operation. Untracked milestone metadata can otherwise block squash merges.
1661
1731
  clearProjectRootStateFiles(originalBasePath_, milestoneId);
@@ -232,7 +232,6 @@ import { reorderForCaching } from "./prompt-ordering.js";
232
232
  // ─── Session State ─────────────────────────────────────────────────────────
233
233
 
234
234
  import {
235
- AutoSession,
236
235
  STUB_RECOVERY_THRESHOLD,
237
236
  NEW_SESSION_TIMEOUT_MS,
238
237
  } from "./auto/session.js";
@@ -250,11 +249,12 @@ export type {
250
249
  UnitRouting,
251
250
  StartModel,
252
251
  } from "./auto/session.js";
252
+ import { autoSession as s } from "./auto-runtime-state.js";
253
253
 
254
254
  // ── ENCAPSULATION INVARIANT ─────────────────────────────────────────────────
255
255
  // ALL mutable auto-mode state lives in the AutoSession class (auto/session.ts).
256
256
  // This file must NOT declare module-level `let` or `var` variables for state.
257
- // The single `s` instance below is the only mutable module-level binding.
257
+ // The single shared `s` instance below is the only mutable AutoSession binding.
258
258
  //
259
259
  // When adding features or fixing bugs:
260
260
  // - New mutable state → add a property to AutoSession, not a module-level variable
@@ -263,7 +263,6 @@ export type {
263
263
  //
264
264
  // Tests in auto-session-encapsulation.test.ts enforce this invariant.
265
265
  // ─────────────────────────────────────────────────────────────────────────────
266
- const s = new AutoSession();
267
266
 
268
267
  /** Throttle STATE.md rebuilds — at most once per 30 seconds */
269
268
  const STATE_REBUILD_MIN_INTERVAL_MS = 30_000;
@@ -1812,7 +1811,7 @@ const widgetStateAccessors: WidgetStateAccessors = {
1812
1811
  * Ensure directories, branches, and other prerequisites exist before
1813
1812
  * dispatching a unit. The LLM should never need to mkdir or git checkout.
1814
1813
  */
1815
- function ensurePreconditions(
1814
+ export function ensurePreconditions(
1816
1815
  unitType: string,
1817
1816
  unitId: string,
1818
1817
  base: string,
@@ -1822,6 +1821,17 @@ function ensurePreconditions(
1822
1821
 
1823
1822
  const mDir = resolveMilestonePath(base, mid);
1824
1823
  if (!mDir) {
1824
+ // Fix #4996: When dispatching a slice unit against an unrecognised milestone,
1825
+ // only create the directory if the milestone has a DB row.
1826
+ // Without this guard, forward-referenced unit IDs (e.g. from REQUIREMENTS.md)
1827
+ // silently scaffold empty stub directories that later skew nextMilestoneId.
1828
+ if (sid !== undefined) {
1829
+ const hasDbRow = isDbAvailable() && getMilestone(mid) != null;
1830
+ if (!hasDbRow) {
1831
+ logWarning("engine", `ensurePreconditions: skipping mkdir for unrecognised milestone ${mid} referenced by slice unit ${unitId} — no DB row exists`, { file: "auto.ts" });
1832
+ return;
1833
+ }
1834
+ }
1825
1835
  const newDir = join(milestonesDir(base), mid);
1826
1836
  mkdirSync(join(newDir, "slices"), { recursive: true });
1827
1837
  }
@@ -1854,16 +1864,21 @@ export async function dispatchHookUnit(
1854
1864
  hookModel: string | undefined,
1855
1865
  targetBasePath: string,
1856
1866
  ): Promise<boolean> {
1867
+ const wasActive = s.active;
1868
+ const previousBasePath = s.basePath;
1869
+ const previousCurrentUnit = s.currentUnit ? { ...s.currentUnit } : null;
1870
+
1857
1871
  if (!s.active) {
1858
1872
  s.active = true;
1859
1873
  s.stepMode = true;
1860
1874
  s.cmdCtx = ctx as ExtensionCommandContext;
1861
- s.basePath = targetBasePath;
1862
1875
  s.autoStartTime = Date.now();
1863
1876
  s.currentUnit = null;
1864
1877
  s.pendingQuickTasks = [];
1865
1878
  }
1866
1879
 
1880
+ s.basePath = targetBasePath;
1881
+
1867
1882
  const hookUnitType = `hook/${hookName}`;
1868
1883
  const hookStartedAt = Date.now();
1869
1884
 
@@ -1873,6 +1888,23 @@ export async function dispatchHookUnit(
1873
1888
  startedAt: hookStartedAt,
1874
1889
  };
1875
1890
 
1891
+ // Ensure cwd matches basePath BEFORE newSession() captures it (#1389).
1892
+ // newSession() snapshots process.cwd() during construction; chdir-ing
1893
+ // afterward leaves the session rooted to whatever cwd was when the call
1894
+ // was made. Must be synchronous — no awaits between chdir and newSession.
1895
+ try { if (process.cwd() !== s.basePath) process.chdir(s.basePath); } catch (err) {
1896
+ const msg = `Failed to chdir before hook newSession (basePath: ${s.basePath}): ${err instanceof Error ? err.message : String(err)}`;
1897
+ logWarning("engine", msg, { file: "auto.ts", basePath: s.basePath, error: err instanceof Error ? err.message : String(err) });
1898
+ ctx.ui.notify(`${msg}. Cancelling hook dispatch to avoid running in the wrong directory.`, "error");
1899
+ if (wasActive) {
1900
+ s.basePath = previousBasePath;
1901
+ s.currentUnit = previousCurrentUnit;
1902
+ } else {
1903
+ s.reset();
1904
+ }
1905
+ return false;
1906
+ }
1907
+
1876
1908
  const result = await s.cmdCtx!.newSession();
1877
1909
  if (result.cancelled) {
1878
1910
  await stopAuto(ctx, pi);
@@ -1929,11 +1961,6 @@ export async function dispatchHookUnit(
1929
1961
  ctx.ui.setStatus("gsd-auto", s.stepMode ? "next" : "auto");
1930
1962
  ctx.ui.notify(`Running post-unit hook: ${hookName}`, "info");
1931
1963
 
1932
- // Ensure cwd matches basePath before hook dispatch (#1389)
1933
- try { if (process.cwd() !== s.basePath) process.chdir(s.basePath); } catch (err) {
1934
- logWarning("engine", `chdir failed before hook dispatch: ${err instanceof Error ? err.message : String(err)}`, { file: "auto.ts" });
1935
- }
1936
-
1937
1964
  debugLog("dispatchHookUnit", {
1938
1965
  phase: "send-message",
1939
1966
  promptLength: hookPrompt.length,
@@ -2,24 +2,15 @@ import { Type } from "@sinclair/typebox";
2
2
  import type { ExtensionAPI } from "@gsd/pi-coding-agent";
3
3
  import { Text } from "@gsd/pi-tui";
4
4
 
5
- import { findMilestoneIds, nextMilestoneId, claimReservedId, getReservedMilestoneIds } from "../guided-flow.js";
6
5
  import { loadEffectiveGSDPreferences } from "../preferences.js";
7
6
  import { ensureDbOpen } from "./dynamic-tools.js";
8
7
  import { StringEnum } from "@gsd/pi-ai";
9
8
  import { logError } from "../workflow-logger.js";
10
9
  import { getErrorMessage } from "../error-utils.js";
11
- import {
12
- executeCompleteMilestone,
13
- executePlanMilestone,
14
- executePlanSlice,
15
- executeReplanSlice,
16
- executeReassessRoadmap,
17
- executeSaveGateResult,
18
- executeSliceComplete,
19
- executeSummarySave,
20
- executeTaskComplete,
21
- executeValidateMilestone,
22
- } from "../tools/workflow-tool-executors.js";
10
+
11
+ async function loadWorkflowExecutors(): Promise<typeof import("../tools/workflow-tool-executors.js")> {
12
+ return import("../tools/workflow-tool-executors.js");
13
+ }
23
14
 
24
15
  /**
25
16
  * Register an alias tool that shares the same execute function as its canonical counterpart.
@@ -302,6 +293,7 @@ export function registerDbTools(pi: ExtensionAPI): void {
302
293
  // ─── gsd_summary_save (formerly gsd_save_summary) ──────────────────────
303
294
 
304
295
  const summarySaveExecute = async (_toolCallId: string, params: any, _signal: AbortSignal | undefined, _onUpdate: unknown, _ctx: unknown) => {
296
+ const { executeSummarySave } = await loadWorkflowExecutors();
305
297
  return executeSummarySave(params, process.cwd());
306
298
  };
307
299
 
@@ -354,6 +346,7 @@ export function registerDbTools(pi: ExtensionAPI): void {
354
346
  try {
355
347
  // Claim a reserved ID if the guided-flow already previewed one to the user.
356
348
  // This guarantees the ID shown in the UI matches the one materialised on disk.
349
+ const { claimReservedId, findMilestoneIds, getReservedMilestoneIds, nextMilestoneId } = await import("../guided-flow.js");
357
350
  const reserved = claimReservedId();
358
351
  if (reserved) {
359
352
  await ensureMilestoneDbRow(reserved);
@@ -435,6 +428,7 @@ export function registerDbTools(pi: ExtensionAPI): void {
435
428
  // ─── gsd_plan_milestone (gsd_milestone_plan alias) ─────────────────────
436
429
 
437
430
  const planMilestoneExecute = async (_toolCallId: string, params: any, _signal: AbortSignal | undefined, _onUpdate: unknown, _ctx: unknown) => {
431
+ const { executePlanMilestone } = await loadWorkflowExecutors();
438
432
  return executePlanMilestone(params, process.cwd());
439
433
  };
440
434
 
@@ -504,6 +498,7 @@ export function registerDbTools(pi: ExtensionAPI): void {
504
498
  // ─── gsd_plan_slice (gsd_slice_plan alias) ─────────────────────────────
505
499
 
506
500
  const planSliceExecute = async (_toolCallId: string, params: any, _signal: AbortSignal | undefined, _onUpdate: unknown, _ctx: unknown) => {
501
+ const { executePlanSlice } = await loadWorkflowExecutors();
507
502
  return executePlanSlice(params, process.cwd());
508
503
  };
509
504
 
@@ -626,6 +621,7 @@ export function registerDbTools(pi: ExtensionAPI): void {
626
621
  // ─── gsd_task_complete (gsd_complete_task alias) ────────────────────────
627
622
 
628
623
  const taskCompleteExecute = async (_toolCallId: string, params: any, _signal: AbortSignal | undefined, _onUpdate: unknown, _ctx: unknown) => {
624
+ const { executeTaskComplete } = await loadWorkflowExecutors();
629
625
  return executeTaskComplete(params, process.cwd());
630
626
  };
631
627
 
@@ -696,6 +692,7 @@ export function registerDbTools(pi: ExtensionAPI): void {
696
692
  // ─── gsd_slice_complete (gsd_complete_slice alias) ─────────────────────
697
693
 
698
694
  const sliceCompleteExecute = async (_toolCallId: string, params: any, _signal: AbortSignal | undefined, _onUpdate: unknown, _ctx: unknown) => {
695
+ const { executeSliceComplete } = await loadWorkflowExecutors();
699
696
  return executeSliceComplete(params, process.cwd());
700
697
  };
701
698
 
@@ -888,6 +885,7 @@ export function registerDbTools(pi: ExtensionAPI): void {
888
885
  // ─── gsd_complete_milestone ────────────────────────────────────────────
889
886
 
890
887
  const milestoneCompleteExecute = async (_toolCallId: string, params: any, _signal: AbortSignal | undefined, _onUpdate: unknown, _ctx: unknown) => {
888
+ const { executeCompleteMilestone } = await loadWorkflowExecutors();
891
889
  return executeCompleteMilestone(params, process.cwd());
892
890
  };
893
891
 
@@ -933,6 +931,7 @@ export function registerDbTools(pi: ExtensionAPI): void {
933
931
  // ─── gsd_validate_milestone (gsd_milestone_validate alias) ─────────────
934
932
 
935
933
  const milestoneValidateExecute = async (_toolCallId: string, params: any, _signal: AbortSignal | undefined, _onUpdate: unknown, _ctx: unknown) => {
934
+ const { executeValidateMilestone } = await loadWorkflowExecutors();
936
935
  return executeValidateMilestone(params, process.cwd());
937
936
  };
938
937
 
@@ -970,6 +969,7 @@ export function registerDbTools(pi: ExtensionAPI): void {
970
969
  // ─── gsd_replan_slice (gsd_slice_replan alias) ─────────────────────────
971
970
 
972
971
  const replanSliceExecute = async (_toolCallId: string, params: any, _signal: AbortSignal | undefined, _onUpdate: unknown, _ctx: unknown) => {
972
+ const { executeReplanSlice } = await loadWorkflowExecutors();
973
973
  return executeReplanSlice(params, process.cwd());
974
974
  };
975
975
 
@@ -1020,6 +1020,7 @@ export function registerDbTools(pi: ExtensionAPI): void {
1020
1020
  // ─── gsd_reassess_roadmap (gsd_roadmap_reassess alias) ─────────────────
1021
1021
 
1022
1022
  const reassessRoadmapExecute = async (_toolCallId: string, params: any, _signal: AbortSignal | undefined, _onUpdate: unknown, _ctx: unknown) => {
1023
+ const { executeReassessRoadmap } = await loadWorkflowExecutors();
1023
1024
  return executeReassessRoadmap(params, process.cwd());
1024
1025
  };
1025
1026
 
@@ -1275,6 +1276,7 @@ export function registerDbTools(pi: ExtensionAPI): void {
1275
1276
  // ─── gsd_save_gate_result ──────────────────────────────────────────────
1276
1277
 
1277
1278
  const saveGateResultExecute = async (_toolCallId: string, params: any, _signal: AbortSignal | undefined, _onUpdate: unknown, _ctx: unknown) => {
1279
+ const { executeSaveGateResult } = await loadWorkflowExecutors();
1278
1280
  return executeSaveGateResult(params, process.cwd());
1279
1281
  };
1280
1282
 
@@ -6,12 +6,6 @@
6
6
  import { Type } from "@sinclair/typebox";
7
7
  import type { ExtensionAPI } from "@gsd/pi-coding-agent";
8
8
 
9
- import { executeGsdExec } from "../tools/exec-tool.js";
10
- import { executeExecSearch } from "../tools/exec-search-tool.js";
11
- import { executeResume } from "../tools/resume-tool.js";
12
- import { loadEffectiveGSDPreferences } from "../preferences.js";
13
- import { logWarning } from "../workflow-logger.js";
14
-
15
9
  export function registerExecTools(pi: ExtensionAPI): void {
16
10
  pi.registerTool({
17
11
  name: "gsd_exec",
@@ -46,7 +40,12 @@ export function registerExecTools(pi: ExtensionAPI): void {
46
40
  ),
47
41
  }),
48
42
  async execute(_toolCallId, params, _signal, _onUpdate, _ctx) {
49
- let prefs: Awaited<ReturnType<typeof loadEffectiveGSDPreferences>> | null = null;
43
+ const [{ executeGsdExec }, { loadEffectiveGSDPreferences }, { logWarning }] = await Promise.all([
44
+ import("../tools/exec-tool.js"),
45
+ import("../preferences.js"),
46
+ import("../workflow-logger.js"),
47
+ ]);
48
+ let prefs: ReturnType<typeof loadEffectiveGSDPreferences> | null = null;
50
49
  try {
51
50
  prefs = loadEffectiveGSDPreferences();
52
51
  } catch (err) {
@@ -81,6 +80,7 @@ export function registerExecTools(pi: ExtensionAPI): void {
81
80
  limit: Type.Optional(Type.Number({ description: "Max results (default 20, cap 200)", minimum: 1, maximum: 200 })),
82
81
  }),
83
82
  async execute(_toolCallId, params, _signal, _onUpdate, _ctx) {
83
+ const { executeExecSearch } = await import("../tools/exec-search-tool.js");
84
84
  return executeExecSearch(params as Parameters<typeof executeExecSearch>[0], {
85
85
  baseDir: process.cwd(),
86
86
  });
@@ -101,6 +101,7 @@ export function registerExecTools(pi: ExtensionAPI): void {
101
101
  ],
102
102
  parameters: Type.Object({}),
103
103
  async execute(_toolCallId, params, _signal, _onUpdate, _ctx) {
104
+ const { executeResume } = await import("../tools/resume-tool.js");
104
105
  return executeResume(params as Parameters<typeof executeResume>[0], {
105
106
  baseDir: process.cwd(),
106
107
  });
@@ -3,8 +3,6 @@
3
3
  import { Type } from "@sinclair/typebox";
4
4
  import type { ExtensionAPI } from "@gsd/pi-coding-agent";
5
5
  import { ensureDbOpen } from "./dynamic-tools.js";
6
- import { executeMilestoneStatus } from "../tools/workflow-tool-executors.js";
7
- import { checkpointDatabase } from "../gsd-db.js";
8
6
 
9
7
  export function registerQueryTools(pi: ExtensionAPI): void {
10
8
  pi.registerTool({
@@ -29,6 +27,7 @@ export function registerQueryTools(pi: ExtensionAPI): void {
29
27
  details: { operation: "milestone_status", error: "db_unavailable" },
30
28
  };
31
29
  }
30
+ const { executeMilestoneStatus } = await import("../tools/workflow-tool-executors.js");
32
31
  return executeMilestoneStatus(params);
33
32
  },
34
33
  });
@@ -55,6 +54,7 @@ export function registerQueryTools(pi: ExtensionAPI): void {
55
54
  details: { operation: "checkpoint_db", error: "db_unavailable" },
56
55
  };
57
56
  }
57
+ const { checkpointDatabase } = await import("../gsd-db.js");
58
58
  checkpointDatabase();
59
59
  return {
60
60
  content: [{ type: "text", text: "WAL checkpoint complete. gsd.db is now up to date and safe to stage with git add." }],
@@ -3,9 +3,8 @@
3
3
  import type { ExtensionAPI, ExtensionCommandContext } from "@gsd/pi-coding-agent";
4
4
 
5
5
  import { registerExitCommand } from "../exit-command.js";
6
- import { registerWorktreeCommand } from "../worktree-command.js";
6
+ import { registerLazyWorktreeCommands } from "../worktree-command-bootstrap.js";
7
7
  import type { GSDEcosystemBeforeAgentStartHandler } from "../ecosystem/gsd-extension-api.js";
8
- import { loadEcosystemExtensions } from "../ecosystem/loader.js";
9
8
  import { registerDbTools } from "./db-tools.js";
10
9
  import { registerDynamicTools } from "./dynamic-tools.js";
11
10
  import { registerExecTools } from "./exec-tools.js";
@@ -71,7 +70,7 @@ function installEpipeGuard(): void {
71
70
  export function registerGsdExtension(pi: ExtensionAPI): void {
72
71
  // Note: registerGSDCommand is called by index.ts before this function,
73
72
  // so we intentionally skip it here to avoid double-registration.
74
- registerWorktreeCommand(pi);
73
+ registerLazyWorktreeCommands(pi);
75
74
  registerExitCommand(pi);
76
75
 
77
76
  // Wire the Layer 2 event emitter bridge so deeply-nested GSD code can emit
@@ -116,12 +115,14 @@ export function registerGsdExtension(pi: ExtensionAPI): void {
116
115
  ["cmux-events", () => initCmuxEventListeners(pi.events)],
117
116
  ["hooks", () => registerHooks(pi, ecosystemHandlers)],
118
117
  ["ecosystem", () => {
119
- void loadEcosystemExtensions(pi, ecosystemHandlers).catch((err) => {
120
- logWarning(
121
- "ecosystem",
122
- `loader failed: ${err instanceof Error ? err.message : String(err)}`,
123
- );
124
- });
118
+ void import("../ecosystem/loader.js")
119
+ .then(({ loadEcosystemExtensions }) => loadEcosystemExtensions(pi, ecosystemHandlers))
120
+ .catch((err) => {
121
+ logWarning(
122
+ "ecosystem",
123
+ `loader failed: ${err instanceof Error ? err.message : String(err)}`,
124
+ );
125
+ });
125
126
  }],
126
127
  ];
127
128