gsd-pi 2.78.0 → 2.78.1-dev.82bcf6b71

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 (577) hide show
  1. package/README.md +60 -23
  2. package/dist/bundled-resource-path.d.ts +7 -0
  3. package/dist/bundled-resource-path.js +34 -2
  4. package/dist/claude-cli-check.js +104 -33
  5. package/dist/cli-policy.d.ts +13 -0
  6. package/dist/cli-policy.js +17 -0
  7. package/dist/cli.js +95 -55
  8. package/dist/headless-query.d.ts +22 -0
  9. package/dist/headless-query.js +43 -8
  10. package/dist/headless.d.ts +10 -0
  11. package/dist/headless.js +16 -1
  12. package/dist/loader.js +9 -13
  13. package/dist/onboarding.d.ts +10 -0
  14. package/dist/onboarding.js +2 -2
  15. package/dist/provider-migrations.d.ts +2 -2
  16. package/dist/provider-migrations.js +5 -2
  17. package/dist/resource-loader.d.ts +5 -2
  18. package/dist/resource-loader.js +30 -13
  19. package/dist/resources/.managed-resources-content-hash +1 -0
  20. package/dist/resources/extensions/claude-code-cli/readiness.js +128 -32
  21. package/dist/resources/extensions/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 +75 -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 +28 -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 +19 -19
  122. package/dist/web/standalone/.next/build-manifest.json +4 -4
  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/required-server-files.json +3 -3
  126. package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
  127. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  128. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  129. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  130. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  131. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  132. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  133. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  134. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  135. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  136. package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
  137. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  138. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  139. package/dist/web/standalone/.next/server/app/_not-found.rsc +3 -3
  140. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
  141. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  142. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +3 -3
  143. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  144. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  145. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  146. package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
  147. package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
  148. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
  149. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
  150. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
  151. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
  152. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
  153. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
  154. package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
  155. package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
  156. package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
  157. package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
  158. package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
  159. package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
  160. package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
  161. package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
  162. package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
  163. package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
  164. package/dist/web/standalone/.next/server/app/api/experimental/route.js +2 -2
  165. package/dist/web/standalone/.next/server/app/api/experimental/route_client-reference-manifest.js +1 -1
  166. package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
  167. package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
  168. package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
  169. package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
  170. package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
  171. package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
  172. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  173. package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  174. package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
  175. package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
  176. package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
  177. package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
  178. package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
  179. package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
  180. package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
  181. package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
  182. package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
  183. package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
  184. package/dist/web/standalone/.next/server/app/api/notifications/route.js +2 -2
  185. package/dist/web/standalone/.next/server/app/api/notifications/route_client-reference-manifest.js +1 -1
  186. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  187. package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
  188. package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
  189. package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
  190. package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
  191. package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  192. package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
  193. package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
  194. package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +2 -2
  195. package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
  196. package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
  197. package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
  198. package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
  199. package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
  200. package/dist/web/standalone/.next/server/app/api/session/events/route.js +4 -2
  201. package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
  202. package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
  203. package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
  204. package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
  205. package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
  206. package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
  207. package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
  208. package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
  209. package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
  210. package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
  211. package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
  212. package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
  213. package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
  214. package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +2 -2
  215. package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
  216. package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
  217. package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
  218. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +2 -2
  219. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
  220. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +4 -4
  221. package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
  222. package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
  223. package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
  224. package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
  225. package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
  226. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  227. package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  228. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  229. package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
  230. package/dist/web/standalone/.next/server/app/index.html +1 -1
  231. package/dist/web/standalone/.next/server/app/index.rsc +4 -4
  232. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  233. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +4 -4
  234. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  235. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +3 -3
  236. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  237. package/dist/web/standalone/.next/server/app/page.js +2 -2
  238. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  239. package/dist/web/standalone/.next/server/app-paths-manifest.json +19 -19
  240. package/dist/web/standalone/.next/server/chunks/63.js +3 -3
  241. package/dist/web/standalone/.next/server/chunks/6897.js +1 -1
  242. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  243. package/dist/web/standalone/.next/server/middleware-manifest.json +5 -5
  244. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  245. package/dist/web/standalone/.next/server/middleware.js +2 -2
  246. package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
  247. package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
  248. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  249. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  250. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  251. package/dist/web/standalone/.next/server/webpack-runtime.js +1 -1
  252. package/dist/web/standalone/.next/static/chunks/2556.0527fea66e123b7f.js +1 -0
  253. package/dist/web/standalone/.next/static/chunks/2824.08296bc2f9654698.js +1 -0
  254. package/dist/web/standalone/.next/static/chunks/3026.3af53b279375f082.js +1 -0
  255. package/dist/web/standalone/.next/static/chunks/315.6f68ae79b67d25cf.js +1 -0
  256. package/dist/web/standalone/.next/static/chunks/3497.4bfc60a3b3dea717.js +1 -0
  257. package/dist/web/standalone/.next/static/chunks/5516.4a07c872b5c3a663.js +1 -0
  258. package/dist/web/standalone/.next/static/chunks/8336.31b019697882acfb.js +10 -0
  259. package/dist/web/standalone/.next/static/chunks/8845.c9702695e8c5a9c5.js +2 -0
  260. package/dist/web/standalone/.next/static/chunks/9058.01ef3a463bda88f1.js +20 -0
  261. package/dist/web/standalone/.next/static/chunks/9441.1081da1125d1764f.js +1 -0
  262. package/dist/web/standalone/.next/static/chunks/app/_not-found/{page-2f24283c162b6ab3.js → page-f2a7482d42a5614b.js} +1 -1
  263. package/dist/web/standalone/.next/static/chunks/app/{layout-9ecfd95f343793f0.js → layout-a16c7a7ecdf0c2cf.js} +1 -1
  264. package/dist/web/standalone/.next/static/chunks/app/page-9bf2e0c50fb2ca05.js +1 -0
  265. package/dist/web/standalone/.next/static/chunks/main-app-fdab67f7802d7832.js +1 -0
  266. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +1 -0
  267. package/dist/web/standalone/.next/static/chunks/webpack-f9f0dc45e4f3ac10.js +1 -0
  268. package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
  269. package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
  270. package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
  271. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api.target.mk +14 -14
  272. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_except.target.mk +14 -14
  273. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_maybe.target.mk +14 -14
  274. package/dist/web/standalone/package.json +2 -1
  275. package/dist/web/standalone/server.js +1 -1
  276. package/dist/welcome-screen.js +27 -1
  277. package/dist/worktree-cli.d.ts +1 -0
  278. package/dist/worktree-cli.js +9 -3
  279. package/dist/worktree-status-banner.d.ts +1 -0
  280. package/dist/worktree-status-banner.js +132 -0
  281. package/package.json +1 -3
  282. package/packages/daemon/package.json +2 -2
  283. package/packages/mcp-server/dist/alias-telemetry.d.ts +8 -0
  284. package/packages/mcp-server/dist/alias-telemetry.d.ts.map +1 -0
  285. package/packages/mcp-server/dist/alias-telemetry.js +30 -0
  286. package/packages/mcp-server/dist/alias-telemetry.js.map +1 -0
  287. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  288. package/packages/mcp-server/dist/workflow-tools.js +74 -46
  289. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  290. package/packages/mcp-server/package.json +2 -2
  291. package/packages/mcp-server/src/alias-telemetry.test.ts +78 -0
  292. package/packages/mcp-server/src/alias-telemetry.ts +30 -0
  293. package/packages/mcp-server/src/workflow-tools.test.ts +78 -0
  294. package/packages/mcp-server/src/workflow-tools.ts +93 -58
  295. package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
  296. package/packages/native/package.json +1 -1
  297. package/packages/native/tsconfig.tsbuildinfo +1 -1
  298. package/packages/pi-agent-core/package.json +1 -1
  299. package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -1
  300. package/packages/pi-ai/dist/providers/anthropic-shared.cache-breakpoint.test.d.ts +2 -0
  301. package/packages/pi-ai/dist/providers/anthropic-shared.cache-breakpoint.test.d.ts.map +1 -0
  302. package/packages/pi-ai/dist/providers/anthropic-shared.cache-breakpoint.test.js +231 -0
  303. package/packages/pi-ai/dist/providers/anthropic-shared.cache-breakpoint.test.js.map +1 -0
  304. package/packages/pi-ai/dist/providers/anthropic-shared.d.ts.map +1 -1
  305. package/packages/pi-ai/dist/providers/anthropic-shared.js +48 -19
  306. package/packages/pi-ai/dist/providers/anthropic-shared.js.map +1 -1
  307. package/packages/pi-ai/dist/types.d.ts +13 -0
  308. package/packages/pi-ai/dist/types.d.ts.map +1 -1
  309. package/packages/pi-ai/dist/types.js.map +1 -1
  310. package/packages/pi-ai/dist/utils/repair-tool-json.d.ts.map +1 -1
  311. package/packages/pi-ai/dist/utils/repair-tool-json.js +24 -3
  312. package/packages/pi-ai/dist/utils/repair-tool-json.js.map +1 -1
  313. package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.js +26 -0
  314. package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.js.map +1 -1
  315. package/packages/pi-ai/package.json +1 -1
  316. package/packages/pi-ai/src/providers/anthropic-shared.cache-breakpoint.test.ts +289 -0
  317. package/packages/pi-ai/src/providers/anthropic-shared.ts +52 -20
  318. package/packages/pi-ai/src/types.ts +13 -0
  319. package/packages/pi-ai/src/utils/repair-tool-json.ts +24 -3
  320. package/packages/pi-ai/src/utils/tests/repair-tool-json.test.ts +32 -0
  321. package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
  322. package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
  323. package/packages/pi-coding-agent/dist/core/agent-session.js +6 -0
  324. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  325. package/packages/pi-coding-agent/dist/core/messages.d.ts.map +1 -1
  326. package/packages/pi-coding-agent/dist/core/messages.js +4 -0
  327. package/packages/pi-coding-agent/dist/core/messages.js.map +1 -1
  328. package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js +19 -2
  329. package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js.map +1 -1
  330. package/packages/pi-coding-agent/dist/core/model-registry.d.ts +10 -0
  331. package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
  332. package/packages/pi-coding-agent/dist/core/model-registry.js +18 -0
  333. package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
  334. package/packages/pi-coding-agent/dist/core/system-prompt.d.ts +13 -0
  335. package/packages/pi-coding-agent/dist/core/system-prompt.d.ts.map +1 -1
  336. package/packages/pi-coding-agent/dist/core/system-prompt.js +20 -16
  337. package/packages/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
  338. package/packages/pi-coding-agent/dist/core/token-telemetry.d.ts +37 -0
  339. package/packages/pi-coding-agent/dist/core/token-telemetry.d.ts.map +1 -0
  340. package/packages/pi-coding-agent/dist/core/token-telemetry.js +49 -0
  341. package/packages/pi-coding-agent/dist/core/token-telemetry.js.map +1 -0
  342. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.d.ts +2 -0
  343. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.d.ts.map +1 -0
  344. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.js +133 -0
  345. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.js.map +1 -0
  346. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js +1 -1
  347. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js.map +1 -1
  348. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js +14 -1
  349. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js.map +1 -1
  350. package/packages/pi-coding-agent/dist/tests/system-prompt-cache-stability.test.d.ts +2 -0
  351. package/packages/pi-coding-agent/dist/tests/system-prompt-cache-stability.test.d.ts.map +1 -0
  352. package/packages/pi-coding-agent/dist/tests/system-prompt-cache-stability.test.js +78 -0
  353. package/packages/pi-coding-agent/dist/tests/system-prompt-cache-stability.test.js.map +1 -0
  354. package/packages/pi-coding-agent/dist/tests/token-telemetry.test.d.ts +2 -0
  355. package/packages/pi-coding-agent/dist/tests/token-telemetry.test.d.ts.map +1 -0
  356. package/packages/pi-coding-agent/dist/tests/token-telemetry.test.js +181 -0
  357. package/packages/pi-coding-agent/dist/tests/token-telemetry.test.js.map +1 -0
  358. package/packages/pi-coding-agent/package.json +1 -1
  359. package/packages/pi-coding-agent/src/core/agent-session.ts +7 -0
  360. package/packages/pi-coding-agent/src/core/messages.ts +4 -0
  361. package/packages/pi-coding-agent/src/core/model-registry-auth-mode.test.ts +32 -2
  362. package/packages/pi-coding-agent/src/core/model-registry.ts +21 -0
  363. package/packages/pi-coding-agent/src/core/system-prompt.ts +33 -15
  364. package/packages/pi-coding-agent/src/core/token-telemetry.ts +77 -0
  365. package/packages/pi-coding-agent/src/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.ts +212 -0
  366. package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.test.ts +17 -1
  367. package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.ts +1 -1
  368. package/packages/pi-coding-agent/src/tests/system-prompt-cache-stability.test.ts +102 -0
  369. package/packages/pi-coding-agent/src/tests/token-telemetry.test.ts +200 -0
  370. package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
  371. package/packages/pi-tui/dist/__tests__/autocomplete.test.js +17 -3
  372. package/packages/pi-tui/dist/__tests__/autocomplete.test.js.map +1 -1
  373. package/packages/pi-tui/dist/components/__tests__/leak-fixes-runtime.test.d.ts +2 -0
  374. package/packages/pi-tui/dist/components/__tests__/leak-fixes-runtime.test.d.ts.map +1 -0
  375. package/packages/pi-tui/dist/components/__tests__/leak-fixes-runtime.test.js +161 -0
  376. package/packages/pi-tui/dist/components/__tests__/leak-fixes-runtime.test.js.map +1 -0
  377. package/packages/pi-tui/package.json +1 -1
  378. package/packages/pi-tui/src/__tests__/autocomplete.test.ts +20 -3
  379. package/packages/pi-tui/src/components/__tests__/leak-fixes-runtime.test.ts +219 -0
  380. package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
  381. package/packages/rpc-client/package.json +1 -1
  382. package/pkg/package.json +1 -1
  383. package/src/resources/extensions/claude-code-cli/readiness.ts +130 -30
  384. package/src/resources/extensions/google-search/index.ts +2 -9
  385. package/src/resources/extensions/gsd/auto/loop.ts +24 -2
  386. package/src/resources/extensions/gsd/auto/phases.ts +6 -14
  387. package/src/resources/extensions/gsd/auto/run-unit.ts +26 -12
  388. package/src/resources/extensions/gsd/auto/session.ts +5 -6
  389. package/src/resources/extensions/gsd/auto/types.ts +1 -0
  390. package/src/resources/extensions/gsd/auto-dashboard.ts +3 -2
  391. package/src/resources/extensions/gsd/auto-direct-dispatch.ts +60 -24
  392. package/src/resources/extensions/gsd/auto-dispatch.ts +18 -6
  393. package/src/resources/extensions/gsd/auto-prompts.ts +66 -2
  394. package/src/resources/extensions/gsd/auto-recovery.ts +46 -8
  395. package/src/resources/extensions/gsd/auto-runtime-state.ts +51 -0
  396. package/src/resources/extensions/gsd/auto-start.ts +1 -1
  397. package/src/resources/extensions/gsd/auto-tool-tracking.ts +2 -4
  398. package/src/resources/extensions/gsd/auto-worktree.ts +97 -12
  399. package/src/resources/extensions/gsd/auto.ts +37 -10
  400. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +15 -13
  401. package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +8 -7
  402. package/src/resources/extensions/gsd/bootstrap/query-tools.ts +2 -2
  403. package/src/resources/extensions/gsd/bootstrap/register-extension.ts +10 -9
  404. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +121 -31
  405. package/src/resources/extensions/gsd/bootstrap/register-shortcuts.ts +12 -6
  406. package/src/resources/extensions/gsd/bootstrap/subagent-input.ts +20 -0
  407. package/src/resources/extensions/gsd/bootstrap/system-context.ts +50 -8
  408. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +141 -11
  409. package/src/resources/extensions/gsd/commands/catalog.ts +82 -5
  410. package/src/resources/extensions/gsd/commands/handlers/core.ts +23 -1
  411. package/src/resources/extensions/gsd/commands/handlers/ops.ts +10 -0
  412. package/src/resources/extensions/gsd/commands-config.ts +3 -2
  413. package/src/resources/extensions/gsd/commands-extensions.ts +43 -3
  414. package/src/resources/extensions/gsd/commands-handlers.ts +3 -2
  415. package/src/resources/extensions/gsd/commands-mcp-status.ts +3 -1
  416. package/src/resources/extensions/gsd/commands-prefs-wizard.ts +15 -1
  417. package/src/resources/extensions/gsd/commands-worktree.ts +383 -0
  418. package/src/resources/extensions/gsd/dashboard-overlay.ts +1 -1
  419. package/src/resources/extensions/gsd/docs/preferences-reference.md +10 -0
  420. package/src/resources/extensions/gsd/doctor-providers.ts +2 -1
  421. package/src/resources/extensions/gsd/doctor-runtime-checks.ts +39 -1
  422. package/src/resources/extensions/gsd/doctor-types.ts +3 -1
  423. package/src/resources/extensions/gsd/error-classifier.ts +1 -1
  424. package/src/resources/extensions/gsd/forensics.ts +12 -7
  425. package/src/resources/extensions/gsd/git-service.ts +13 -5
  426. package/src/resources/extensions/gsd/gsd-db.ts +12 -2
  427. package/src/resources/extensions/gsd/guided-flow.ts +27 -26
  428. package/src/resources/extensions/gsd/home-dir.ts +19 -0
  429. package/src/resources/extensions/gsd/journal.ts +4 -1
  430. package/src/resources/extensions/gsd/key-manager.ts +2 -1
  431. package/src/resources/extensions/gsd/memory-store.ts +81 -28
  432. package/src/resources/extensions/gsd/migrate/command.ts +3 -2
  433. package/src/resources/extensions/gsd/milestone-id-reservation.ts +47 -0
  434. package/src/resources/extensions/gsd/model-router.ts +172 -9
  435. package/src/resources/extensions/gsd/native-git-bridge.ts +7 -1
  436. package/src/resources/extensions/gsd/preferences-models.ts +101 -15
  437. package/src/resources/extensions/gsd/preferences-types.ts +6 -0
  438. package/src/resources/extensions/gsd/preferences-validation.ts +35 -0
  439. package/src/resources/extensions/gsd/preferences.ts +16 -2
  440. package/src/resources/extensions/gsd/prompt-loader.ts +26 -12
  441. package/src/resources/extensions/gsd/prompts/complete-milestone.md +10 -0
  442. package/src/resources/extensions/gsd/prompts/complete-slice.md +10 -0
  443. package/src/resources/extensions/gsd/prompts/guided-discuss-milestone.md +2 -0
  444. package/src/resources/extensions/gsd/prompts/parallel-research-slices.md +2 -0
  445. package/src/resources/extensions/gsd/prompts/plan-slice.md +10 -0
  446. package/src/resources/extensions/gsd/prompts/refine-slice.md +10 -0
  447. package/src/resources/extensions/gsd/prompts/rewrite-docs.md +2 -0
  448. package/src/resources/extensions/gsd/slice-parallel-orchestrator.ts +9 -3
  449. package/src/resources/extensions/gsd/state.ts +42 -0
  450. package/src/resources/extensions/gsd/templates/PREFERENCES.md +1 -0
  451. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +179 -1
  452. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +58 -0
  453. package/src/resources/extensions/gsd/tests/auto-session-encapsulation.test.ts +24 -5
  454. package/src/resources/extensions/gsd/tests/auto-supervisor.test.mjs +21 -4
  455. package/src/resources/extensions/gsd/tests/bootstrap-derive-state-db-open.test.ts +1 -1
  456. package/src/resources/extensions/gsd/tests/budget-prediction.test.ts +138 -211
  457. package/src/resources/extensions/gsd/tests/bundled-skill-triggers.test.ts +50 -27
  458. package/src/resources/extensions/gsd/tests/commands-extensions-version-compare.test.ts +58 -0
  459. package/src/resources/extensions/gsd/tests/commands-worktree-clean.test.ts +48 -0
  460. package/src/resources/extensions/gsd/tests/complete-slice-verification-gate.test.ts +142 -59
  461. package/src/resources/extensions/gsd/tests/complete-slice.test.ts +7 -4
  462. package/src/resources/extensions/gsd/tests/completed-at-reconcile.test.ts +89 -32
  463. package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +41 -23
  464. package/src/resources/extensions/gsd/tests/db-path-worktree-symlink.test.ts +3 -43
  465. package/src/resources/extensions/gsd/tests/debug-logger.test.ts +5 -3
  466. package/src/resources/extensions/gsd/tests/deferred-milestone-dir-4996.test.ts +116 -0
  467. package/src/resources/extensions/gsd/tests/discuss-empty-db-fallback.test.ts +22 -87
  468. package/src/resources/extensions/gsd/tests/discuss-queued-milestones.test.ts +7 -118
  469. package/src/resources/extensions/gsd/tests/discuss-tool-scope-leak.test.ts +18 -60
  470. package/src/resources/extensions/gsd/tests/doctor-orphan-milestone-4996.test.ts +100 -0
  471. package/src/resources/extensions/gsd/tests/double-merge-guard.test.ts +14 -76
  472. package/src/resources/extensions/gsd/tests/ensure-preconditions-guard-4996.test.ts +93 -0
  473. package/src/resources/extensions/gsd/tests/false-degraded-mode-warning.test.ts +22 -83
  474. package/src/resources/extensions/gsd/tests/finalize-timeout-guard.test.ts +1 -63
  475. package/src/resources/extensions/gsd/tests/find-missing-summaries-closed-runtime.test.ts +47 -0
  476. package/src/resources/extensions/gsd/tests/forensics-stuck-loops.test.ts +26 -1
  477. package/src/resources/extensions/gsd/tests/gitignore-bg-shell-runtime.test.ts +63 -0
  478. package/src/resources/extensions/gsd/tests/google-search-stub.test.ts +25 -65
  479. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +30 -0
  480. package/src/resources/extensions/gsd/tests/gsd-no-project-error-runtime.test.ts +81 -0
  481. package/src/resources/extensions/gsd/tests/headless-answers.test.ts +14 -4
  482. package/src/resources/extensions/gsd/tests/health-widget.test.ts +22 -12
  483. package/src/resources/extensions/gsd/tests/help-menu-coverage.test.ts +57 -0
  484. package/src/resources/extensions/gsd/tests/home-dir.test.ts +52 -0
  485. package/src/resources/extensions/gsd/tests/import-done-milestones-runtime.test.ts +145 -0
  486. package/src/resources/extensions/gsd/tests/init-prefs-routing.test.ts +64 -1
  487. package/src/resources/extensions/gsd/tests/integration/auto-worktree.test.ts +72 -1
  488. package/src/resources/extensions/gsd/tests/integration/token-savings.test.ts +0 -23
  489. package/src/resources/extensions/gsd/tests/memory-store.test.ts +128 -0
  490. package/src/resources/extensions/gsd/tests/memory-tools.test.ts +33 -1
  491. package/src/resources/extensions/gsd/tests/merge-self-branch-guard.test.ts +124 -0
  492. package/src/resources/extensions/gsd/tests/milestone-id-gap-reuse-4996.test.ts +152 -0
  493. package/src/resources/extensions/gsd/tests/milestone-report-path.test.ts +18 -1
  494. package/src/resources/extensions/gsd/tests/model-router.test.ts +169 -8
  495. package/src/resources/extensions/gsd/tests/native-git-infra-errors.test.ts +50 -0
  496. package/src/resources/extensions/gsd/tests/orphaned-worktree-audit.test.ts +8 -0
  497. package/src/resources/extensions/gsd/tests/parallel-crash-recovery.test.ts +32 -43
  498. package/src/resources/extensions/gsd/tests/phases-merge-error-stops-auto.test.ts +4 -10
  499. package/src/resources/extensions/gsd/tests/preferences.test.ts +127 -0
  500. package/src/resources/extensions/gsd/tests/prompt-step-ordering.test.ts +16 -0
  501. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +7 -0
  502. package/src/resources/extensions/gsd/tests/quick-turn-end-cleanup.test.ts +6 -6
  503. package/src/resources/extensions/gsd/tests/register-hooks-compaction-checkpoint.test.ts +93 -0
  504. package/src/resources/extensions/gsd/tests/safety-harness-false-positives.test.ts +34 -0
  505. package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +168 -19
  506. package/src/resources/extensions/gsd/tests/slice-parallel-orchestrator.test.ts +7 -1
  507. package/src/resources/extensions/gsd/tests/smart-entry-complete.test.ts +23 -1
  508. package/src/resources/extensions/gsd/tests/stash-pop-gsd-conflict.test.ts +8 -2
  509. package/src/resources/extensions/gsd/tests/stash-queued-context-files.test.ts +12 -6
  510. package/src/resources/extensions/gsd/tests/steer-worktree-path.test.ts +17 -1
  511. package/src/resources/extensions/gsd/tests/system-context-message-routing.test.ts +101 -0
  512. package/src/resources/extensions/gsd/tests/token-profile.test.ts +51 -4
  513. package/src/resources/extensions/gsd/tests/turn-epoch.test.ts +7 -16
  514. package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +38 -3
  515. package/src/resources/extensions/gsd/tests/unstructured-continue-context-injection.test.ts +5 -7
  516. package/src/resources/extensions/gsd/tests/uok-gitops-turn-action.test.ts +15 -1
  517. package/src/resources/extensions/gsd/tests/visualizer-overlay.test.ts +6 -6
  518. package/src/resources/extensions/gsd/tests/worktree-path-injection.test.ts +235 -0
  519. package/src/resources/extensions/gsd/tests/worktree-resolver.test.ts +85 -0
  520. package/src/resources/extensions/gsd/tests/worktree-symlink-removal.test.ts +34 -33
  521. package/src/resources/extensions/gsd/tests/worktree.test.ts +8 -0
  522. package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +131 -1
  523. package/src/resources/extensions/gsd/tools/memory-tools.ts +17 -1
  524. package/src/resources/extensions/gsd/unit-context-manifest.ts +44 -12
  525. package/src/resources/extensions/gsd/visualizer-overlay.ts +1 -1
  526. package/src/resources/extensions/gsd/watch/header-renderer.ts +3 -1
  527. package/src/resources/extensions/gsd/workflow-logger.ts +1 -0
  528. package/src/resources/extensions/gsd/worktree-command.ts +31 -44
  529. package/src/resources/extensions/gsd/worktree-manager.ts +40 -1
  530. package/src/resources/extensions/gsd/worktree-resolver.ts +28 -14
  531. package/src/resources/extensions/gsd/worktree-root.ts +144 -0
  532. package/src/resources/extensions/gsd/worktree-session-state.ts +35 -0
  533. package/src/resources/extensions/gsd/worktree.ts +8 -119
  534. package/src/resources/extensions/mcp-client/index.ts +6 -10
  535. package/src/resources/extensions/mcp-client/tests/global-config.test.ts +91 -0
  536. package/src/resources/extensions/ollama/index.ts +16 -2
  537. package/src/resources/extensions/ollama/model-capabilities.ts +34 -0
  538. package/src/resources/extensions/ollama/ollama-client.ts +41 -4
  539. package/src/resources/extensions/ollama/tests/model-capabilities.test.ts +96 -0
  540. package/src/resources/extensions/ollama/tests/ollama-client-timeout-env.test.ts +147 -0
  541. package/src/resources/extensions/slash-commands/create-extension.ts +38 -24
  542. package/src/resources/extensions/subagent/index.ts +165 -7
  543. package/src/resources/skills/create-gsd-extension/SKILL.md +9 -5
  544. package/src/resources/skills/create-gsd-extension/references/custom-commands.md +1 -1
  545. package/src/resources/skills/create-gsd-extension/references/custom-rendering.md +5 -5
  546. package/src/resources/skills/create-gsd-extension/references/custom-tools.md +4 -4
  547. package/src/resources/skills/create-gsd-extension/references/custom-ui.md +6 -6
  548. package/src/resources/skills/create-gsd-extension/references/events-reference.md +3 -3
  549. package/src/resources/skills/create-gsd-extension/references/packaging-distribution.md +1 -1
  550. package/src/resources/skills/create-gsd-extension/references/remote-execution-overrides.md +3 -3
  551. package/src/resources/skills/create-gsd-extension/templates/extension-skeleton.ts +2 -2
  552. package/src/resources/skills/create-gsd-extension/templates/stateful-tool-skeleton.ts +3 -3
  553. package/src/resources/skills/create-gsd-extension/templates/templates.test.ts +58 -0
  554. package/src/resources/skills/create-gsd-extension/workflows/create-extension.md +32 -12
  555. package/src/resources/skills/lint/SKILL.md +4 -0
  556. package/src/resources/skills/review/SKILL.md +4 -0
  557. package/src/resources/skills/test/SKILL.md +3 -0
  558. package/dist/resources/extensions/browser-tools/tests/browser-tools-integration.test.mjs +0 -601
  559. package/dist/resources/extensions/browser-tools/tests/browser-tools-unit.test.cjs +0 -651
  560. package/dist/resources/extensions/browser-tools/tests/capture-sharp-optional.test.cjs +0 -91
  561. package/dist/resources/extensions/gsd/tests/auto-supervisor.test.mjs +0 -53
  562. package/dist/resources/extensions/gsd/tests/dist-redirect.mjs +0 -112
  563. package/dist/resources/extensions/gsd/tests/resolve-ts-hooks.mjs +0 -23
  564. package/dist/resources/extensions/gsd/tests/resolve-ts.mjs +0 -5
  565. package/dist/resources/skills/github-workflows/references/gh/tests/__init__.py +0 -0
  566. package/dist/resources/skills/github-workflows/references/gh/tests/test_github_project_setup.py +0 -608
  567. package/dist/web/standalone/.next/static/chunks/2826.e9f5195e91f9cad2.js +0 -11
  568. package/dist/web/standalone/.next/static/chunks/3621.fc7480022c972438.js +0 -20
  569. package/dist/web/standalone/.next/static/chunks/app/page-151349214571e2b6.js +0 -1
  570. package/dist/web/standalone/.next/static/chunks/main-app-d3d4c336195465f9.js +0 -1
  571. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ab5a8926e07ec673.js +0 -1
  572. package/dist/web/standalone/.next/static/chunks/webpack-2e68521d7c82f7c2.js +0 -1
  573. package/src/resources/extensions/gsd/tests/copy-planning-artifacts-samepath.test.ts +0 -22
  574. package/src/resources/extensions/gsd/tests/discuss-slice-structured-questions.test.ts +0 -47
  575. package/src/resources/extensions/gsd/tests/empty-content-abort-loop.test.ts +0 -75
  576. /package/dist/web/standalone/.next/static/{C1zT2kEfoLhDdbWPWKrXd → hcvW7f3yv1JHzlWe7tIc6}/_buildManifest.js +0 -0
  577. /package/dist/web/standalone/.next/static/{C1zT2kEfoLhDdbWPWKrXd → hcvW7f3yv1JHzlWe7tIc6}/_ssgManifest.js +0 -0
@@ -18,28 +18,13 @@ import { createWorktree, listWorktrees, removeWorktree, mergeWorktreeToMain, dif
18
18
  import { inferCommitType } from "./git-service.js";
19
19
  import { existsSync, realpathSync, readdirSync, rmSync, unlinkSync } from "node:fs";
20
20
  import { nativeMergeAbort } from "./native-git-bridge.js";
21
- import { join, sep } from "node:path";
21
+ import { join } from "node:path";
22
+ import { clearWorktreeOriginalCwd, ensureWorktreeOriginalCwdFromPath, getActiveWorktreeName, getWorktreeOriginalCwd, setWorktreeOriginalCwd, } from "./worktree-session-state.js";
23
+ export { getActiveWorktreeName, getWorktreeOriginalCwd } from "./worktree-session-state.js";
22
24
  /**
23
25
  * Tracks the original project root so we can switch back.
24
26
  * Set when we first chdir into a worktree, cleared on return.
25
27
  */
26
- let originalCwd = null;
27
- /** Get the original project root if currently in a worktree, or null. */
28
- export function getWorktreeOriginalCwd() {
29
- return originalCwd;
30
- }
31
- /** Get the name of the active worktree, or null if not in one. */
32
- export function getActiveWorktreeName() {
33
- if (!originalCwd)
34
- return null;
35
- const cwd = process.cwd();
36
- const wtDir = join(originalCwd, ".gsd", "worktrees");
37
- if (!cwd.startsWith(wtDir))
38
- return null;
39
- const rel = cwd.slice(wtDir.length + 1);
40
- const name = rel.split("/")[0] ?? rel.split("\\")[0];
41
- return name || null;
42
- }
43
28
  // ─── Shared completions and handler (used by both /worktree and /wt) ────────
44
29
  function worktreeCompletions(prefix) {
45
30
  const parts = prefix.trim().split(/\s+/);
@@ -111,7 +96,7 @@ async function worktreeHandler(args, ctx, pi, alias) {
111
96
  return;
112
97
  }
113
98
  // create and switch both do the same thing: switch if exists, create if not
114
- const mainBase = originalCwd ?? basePath;
99
+ const mainBase = getWorktreeOriginalCwd() ?? basePath;
115
100
  const existing = listWorktrees(mainBase);
116
101
  if (existing.some(wt => wt.name === name)) {
117
102
  await handleSwitch(basePath, name, ctx);
@@ -123,7 +108,7 @@ async function worktreeHandler(args, ctx, pi, alias) {
123
108
  }
124
109
  if (trimmed === "merge" || trimmed.startsWith("merge ")) {
125
110
  const mergeArgs = trimmed.replace(/^merge\s*/, "").trim().split(/\s+/).filter(Boolean);
126
- const mainBase = originalCwd ?? basePath;
111
+ const mainBase = getWorktreeOriginalCwd() ?? basePath;
127
112
  const activeWt = getActiveWorktreeName();
128
113
  if (mergeArgs.length === 0) {
129
114
  // Bare "/worktree merge" — only valid when inside a worktree
@@ -154,7 +139,7 @@ async function worktreeHandler(args, ctx, pi, alias) {
154
139
  }
155
140
  if (trimmed === "remove" || trimmed.startsWith("remove ")) {
156
141
  const name = trimmed.replace(/^remove\s*/, "").trim();
157
- const mainBase = originalCwd ?? basePath;
142
+ const mainBase = getWorktreeOriginalCwd() ?? basePath;
158
143
  if (name === "all") {
159
144
  await handleRemoveAll(mainBase, ctx);
160
145
  return;
@@ -171,7 +156,7 @@ async function worktreeHandler(args, ctx, pi, alias) {
171
156
  ctx.ui.notify(`Usage: /${alias} ${trimmed}${trimmed === "list" || trimmed === "return" ? "" : " <name>"}`, "warning");
172
157
  return;
173
158
  }
174
- const mainBase = originalCwd ?? basePath;
159
+ const mainBase = getWorktreeOriginalCwd() ?? basePath;
175
160
  const nameOnly = trimmed.split(/\s+/)[0];
176
161
  if (trimmed !== nameOnly) {
177
162
  ctx.ui.notify(`Unknown command. Did you mean /${alias} switch ${nameOnly}?`, "warning");
@@ -192,14 +177,7 @@ export function registerWorktreeCommand(pi) {
192
177
  // Restore worktree state after /reload.
193
178
  // The module-level originalCwd resets to null when extensions are re-loaded,
194
179
  // but process.cwd() is still inside the worktree. Detect this and recover.
195
- if (!originalCwd) {
196
- const cwd = process.cwd();
197
- const marker = `${sep}.gsd${sep}worktrees${sep}`;
198
- const markerIdx = cwd.indexOf(marker);
199
- if (markerIdx !== -1) {
200
- originalCwd = cwd.slice(0, markerIdx);
201
- }
202
- }
180
+ ensureWorktreeOriginalCwdFromPath();
203
181
  pi.registerCommand("worktree", {
204
182
  description: "Git worktrees (also /wt): /worktree <name> | list | merge | remove",
205
183
  getArgumentCompletions: worktreeCompletions,
@@ -260,7 +238,7 @@ async function handleCreate(basePath, name, ctx) {
260
238
  // before createWorktree so the new worktree forks from committed HEAD)
261
239
  const commitMsg = autoCommitCurrentBranch(basePath, "worktree-switch", name);
262
240
  // Create from the main tree, not from inside another worktree
263
- const mainBase = originalCwd ?? basePath;
241
+ const mainBase = getWorktreeOriginalCwd() ?? basePath;
264
242
  const info = createWorktree(mainBase, name);
265
243
  // Run user-configured post-create hook (#597) — e.g. copy .env, symlink assets
266
244
  const hookError = runWorktreePostCreateHook(mainBase, info.path);
@@ -268,8 +246,8 @@ async function handleCreate(basePath, name, ctx) {
268
246
  ctx.ui.notify(hookError, "warning");
269
247
  }
270
248
  // Track original cwd before switching
271
- if (!originalCwd)
272
- originalCwd = basePath;
249
+ if (!getWorktreeOriginalCwd())
250
+ setWorktreeOriginalCwd(basePath);
273
251
  const prevCwd = process.cwd();
274
252
  process.chdir(info.path);
275
253
  nudgeGitBranchCache(prevCwd);
@@ -319,7 +297,7 @@ async function handleCreate(basePath, name, ctx) {
319
297
  }
320
298
  async function handleSwitch(basePath, name, ctx) {
321
299
  try {
322
- const mainBase = originalCwd ?? basePath;
300
+ const mainBase = getWorktreeOriginalCwd() ?? basePath;
323
301
  const wtPath = worktreePath(mainBase, name);
324
302
  if (!existsSync(wtPath)) {
325
303
  ctx.ui.notify(`Worktree "${name}" not found. Run /worktree list to see available worktrees.`, "warning");
@@ -328,8 +306,8 @@ async function handleSwitch(basePath, name, ctx) {
328
306
  // Auto-commit dirty files before leaving current workspace
329
307
  const commitMsg = autoCommitCurrentBranch(basePath, "worktree-switch", name);
330
308
  // Track original cwd before switching
331
- if (!originalCwd)
332
- originalCwd = basePath;
309
+ if (!getWorktreeOriginalCwd())
310
+ setWorktreeOriginalCwd(basePath);
333
311
  const prevCwd = process.cwd();
334
312
  process.chdir(wtPath);
335
313
  nudgeGitBranchCache(prevCwd);
@@ -352,6 +330,7 @@ async function handleSwitch(basePath, name, ctx) {
352
330
  }
353
331
  }
354
332
  async function handleReturn(ctx) {
333
+ const originalCwd = getWorktreeOriginalCwd();
355
334
  if (!originalCwd) {
356
335
  ctx.ui.notify("Already in the main project tree.", "info");
357
336
  return;
@@ -359,7 +338,7 @@ async function handleReturn(ctx) {
359
338
  // Auto-commit dirty files before leaving worktree
360
339
  const commitMsg = autoCommitCurrentBranch(process.cwd(), "worktree-return", "worktree");
361
340
  const returnTo = originalCwd;
362
- originalCwd = null;
341
+ clearWorktreeOriginalCwd();
363
342
  const prevCwd = process.cwd();
364
343
  process.chdir(returnTo);
365
344
  nudgeGitBranchCache(prevCwd);
@@ -409,7 +388,7 @@ const CLR = {
409
388
  };
410
389
  async function handleList(basePath, ctx) {
411
390
  try {
412
- const mainBase = originalCwd ?? basePath;
391
+ const mainBase = getWorktreeOriginalCwd() ?? basePath;
413
392
  const worktrees = listWorktrees(mainBase);
414
393
  if (worktrees.length === 0) {
415
394
  ctx.ui.notify("No GSD worktrees found. Create one with /worktree <name>.", "info");
@@ -452,6 +431,7 @@ async function handleList(basePath, ctx) {
452
431
  }
453
432
  lines.push("");
454
433
  }
434
+ const originalCwd = getWorktreeOriginalCwd();
455
435
  if (originalCwd) {
456
436
  lines.push(` ${CLR.label("main tree")} ${CLR.path(originalCwd)}`);
457
437
  }
@@ -539,11 +519,11 @@ async function handleMerge(basePath, name, ctx, pi, targetBranch) {
539
519
  }
540
520
  // Switch to the main tree before merging.
541
521
  // Must be on the main branch to run git merge --squash.
542
- if (originalCwd) {
522
+ if (getWorktreeOriginalCwd()) {
543
523
  const prevCwd = process.cwd();
544
524
  process.chdir(basePath);
545
525
  nudgeGitBranchCache(prevCwd);
546
- originalCwd = null;
526
+ clearWorktreeOriginalCwd();
547
527
  }
548
528
  // --- Deterministic merge path (preferred) ---
549
529
  // Try a direct squash-merge first. Only fall back to LLM on conflict.
@@ -620,7 +600,7 @@ async function handleMerge(basePath, name, ctx, pi, targetBranch) {
620
600
  }
621
601
  async function handleRemove(basePath, name, ctx) {
622
602
  try {
623
- const mainBase = originalCwd ?? basePath;
603
+ const mainBase = getWorktreeOriginalCwd() ?? basePath;
624
604
  // Validate the worktree exists before attempting removal
625
605
  const worktrees = listWorktrees(mainBase);
626
606
  const wt = worktrees.find(w => w.name === name);
@@ -641,9 +621,9 @@ async function handleRemove(basePath, name, ctx) {
641
621
  const prevCwd = process.cwd();
642
622
  removeWorktree(mainBase, name, { deleteBranch: true });
643
623
  // If we were in that worktree, removeWorktree chdir'd us out — clear tracking
644
- if (originalCwd && process.cwd() !== prevCwd) {
624
+ if (getWorktreeOriginalCwd() && process.cwd() !== prevCwd) {
645
625
  nudgeGitBranchCache(prevCwd);
646
- originalCwd = null;
626
+ clearWorktreeOriginalCwd();
647
627
  }
648
628
  ctx.ui.notify(`${CLR.ok("✓")} Worktree ${CLR.name(name)} removed ${CLR.muted("(branch deleted)")}.`, "info");
649
629
  }
@@ -654,7 +634,7 @@ async function handleRemove(basePath, name, ctx) {
654
634
  }
655
635
  async function handleRemoveAll(basePath, ctx) {
656
636
  try {
657
- const mainBase = originalCwd ?? basePath;
637
+ const mainBase = getWorktreeOriginalCwd() ?? basePath;
658
638
  const worktrees = listWorktrees(mainBase);
659
639
  if (worktrees.length === 0) {
660
640
  ctx.ui.notify("No worktrees to remove.", "info");
@@ -684,9 +664,9 @@ async function handleRemoveAll(basePath, ctx) {
684
664
  }
685
665
  }
686
666
  // If we were in a worktree that got removed, clear tracking
687
- if (originalCwd && process.cwd() !== prevCwd) {
667
+ if (getWorktreeOriginalCwd() && process.cwd() !== prevCwd) {
688
668
  nudgeGitBranchCache(prevCwd);
689
- originalCwd = null;
669
+ clearWorktreeOriginalCwd();
690
670
  }
691
671
  const lines = [];
692
672
  if (removed.length > 0)
@@ -21,6 +21,7 @@ import { GSDError, GSD_PARSE_ERROR, GSD_STALE_STATE, GSD_LOCK_HELD, GSD_GIT_ERRO
21
21
  import { logWarning } from "./workflow-logger.js";
22
22
  import { nativeBranchDelete, nativeBranchExists, nativeBranchForceReset, nativeCommit, nativeDetectMainBranch, nativeDiffContent, nativeDiffNameStatus, nativeDiffNumstat, nativeGetCurrentBranch, nativeIsAncestor, nativeLogOneline, nativeMergeSquash, nativeWorktreeAdd, nativeWorktreeList, nativeWorktreePrune, nativeWorktreeRemove, } from "./native-git-bridge.js";
23
23
  import { emitCanonicalRootRedirect } from "./worktree-telemetry.js";
24
+ import { isGsdWorktreePath, normalizeWorktreePathForCompare, resolveWorktreeProjectRoot, } from "./worktree-root.js";
24
25
  // ─── Path Helpers ──────────────────────────────────────────────────────────
25
26
  function normalizePathForComparison(path) {
26
27
  const normalized = path
@@ -29,6 +30,14 @@ function normalizePathForComparison(path) {
29
30
  .replace(/\/+$/, "");
30
31
  return process.platform === "win32" ? normalized.toLowerCase() : normalized;
31
32
  }
33
+ function normalizeBasePathForWorktreeOps(basePath) {
34
+ const resolved = resolveWorktreeProjectRoot(basePath);
35
+ if (isGsdWorktreePath(basePath) &&
36
+ normalizeWorktreePathForCompare(resolved) === normalizeWorktreePathForCompare(basePath)) {
37
+ throw new GSDError(GSD_GIT_ERROR, `Cannot resolve project root from worktree path: ${basePath}. Run the command from the project root or set GSD_PROJECT_ROOT.`);
38
+ }
39
+ return resolved;
40
+ }
32
41
  // ─── resolveGitDir ─────────────────────────────────────────────────────────
33
42
  /**
34
43
  * Resolve the actual git directory for a given repository path.
@@ -61,7 +70,7 @@ export function resolveGitDir(basePath) {
61
70
  return gitPath;
62
71
  }
63
72
  export function worktreesDir(basePath) {
64
- return join(basePath, ".gsd", "worktrees");
73
+ return join(resolveWorktreeProjectRoot(basePath), ".gsd", "worktrees");
65
74
  }
66
75
  export function worktreePath(basePath, name) {
67
76
  return join(worktreesDir(basePath), name);
@@ -143,6 +152,7 @@ export function resolveCanonicalMilestoneRoot(basePath, milestoneId) {
143
152
  * @param opts.branch — override the default `worktree/<name>` branch name
144
153
  */
145
154
  export function createWorktree(basePath, name, opts = {}) {
155
+ basePath = normalizeBasePathForWorktreeOps(basePath);
146
156
  // Validate name: alphanumeric, hyphens, underscores only
147
157
  if (!/^[a-zA-Z0-9_-]+$/.test(name)) {
148
158
  throw new GSDError(GSD_PARSE_ERROR, `Invalid worktree name "${name}". Use only letters, numbers, hyphens, and underscores.`);
@@ -227,6 +237,7 @@ export function createWorktree(basePath, name, opts = {}) {
227
237
  * Uses native worktree list and filters to those under .gsd/worktrees/.
228
238
  */
229
239
  export function listWorktrees(basePath) {
240
+ basePath = normalizeBasePathForWorktreeOps(basePath);
230
241
  const baseVariants = [resolve(basePath)];
231
242
  if (existsSync(basePath)) {
232
243
  baseVariants.push(realpathSync(basePath));
@@ -366,6 +377,7 @@ export function findNestedGitDirs(rootPath) {
366
377
  * If the process is currently inside the worktree, chdir out first.
367
378
  */
368
379
  export function removeWorktree(basePath, name, opts = {}) {
380
+ basePath = normalizeBasePathForWorktreeOps(basePath);
369
381
  let wtPath = worktreePath(basePath, name);
370
382
  const branch = opts.branch ?? worktreeBranchName(name);
371
383
  const { deleteBranch = true, force = true } = opts;
@@ -614,6 +626,7 @@ function parseDiffNameStatus(entries) {
614
626
  * Returns a summary of added, modified, and removed GSD artifacts.
615
627
  */
616
628
  export function diffWorktreeGSD(basePath, name) {
629
+ basePath = normalizeBasePathForWorktreeOps(basePath);
617
630
  const branch = worktreeBranchName(name);
618
631
  const mainBranch = nativeDetectMainBranch(basePath);
619
632
  const entries = nativeDiffNameStatus(basePath, mainBranch, branch, ".gsd/", true);
@@ -626,6 +639,7 @@ export function diffWorktreeGSD(basePath, name) {
626
639
  * content, this correctly returns an empty diff.
627
640
  */
628
641
  export function diffWorktreeAll(basePath, name) {
642
+ basePath = normalizeBasePathForWorktreeOps(basePath);
629
643
  const branch = worktreeBranchName(name);
630
644
  const mainBranch = nativeDetectMainBranch(basePath);
631
645
  const entries = nativeDiffNameStatus(basePath, mainBranch, branch);
@@ -636,6 +650,7 @@ export function diffWorktreeAll(basePath, name) {
636
650
  * Uses direct diff (not merge-base) so the preview matches the actual merge outcome.
637
651
  */
638
652
  export function diffWorktreeNumstat(basePath, name) {
653
+ basePath = normalizeBasePathForWorktreeOps(basePath);
639
654
  const branch = worktreeBranchName(name);
640
655
  const mainBranch = nativeDetectMainBranch(basePath);
641
656
  const rawStats = nativeDiffNumstat(basePath, mainBranch, branch);
@@ -652,6 +667,7 @@ export function diffWorktreeNumstat(basePath, name) {
652
667
  * Returns the raw unified diff for LLM consumption.
653
668
  */
654
669
  export function getWorktreeGSDDiff(basePath, name) {
670
+ basePath = normalizeBasePathForWorktreeOps(basePath);
655
671
  const branch = worktreeBranchName(name);
656
672
  const mainBranch = nativeDetectMainBranch(basePath);
657
673
  return nativeDiffContent(basePath, mainBranch, branch, ".gsd/", undefined, true);
@@ -661,6 +677,7 @@ export function getWorktreeGSDDiff(basePath, name) {
661
677
  * Returns the raw unified diff for LLM consumption.
662
678
  */
663
679
  export function getWorktreeCodeDiff(basePath, name) {
680
+ basePath = normalizeBasePathForWorktreeOps(basePath);
664
681
  const branch = worktreeBranchName(name);
665
682
  const mainBranch = nativeDetectMainBranch(basePath);
666
683
  return nativeDiffContent(basePath, mainBranch, branch, undefined, ".gsd/", true);
@@ -669,6 +686,7 @@ export function getWorktreeCodeDiff(basePath, name) {
669
686
  * Get commit log for the worktree branch since it diverged from main.
670
687
  */
671
688
  export function getWorktreeLog(basePath, name) {
689
+ basePath = normalizeBasePathForWorktreeOps(basePath);
672
690
  const branch = worktreeBranchName(name);
673
691
  const mainBranch = nativeDetectMainBranch(basePath);
674
692
  const entries = nativeLogOneline(basePath, mainBranch, branch);
@@ -680,6 +698,7 @@ export function getWorktreeLog(basePath, name) {
680
698
  * Returns the merge commit message.
681
699
  */
682
700
  export function mergeWorktreeToMain(basePath, name, commitMessage) {
701
+ basePath = normalizeBasePathForWorktreeOps(basePath);
683
702
  const branch = worktreeBranchName(name);
684
703
  const mainBranch = nativeDetectMainBranch(basePath);
685
704
  const current = nativeGetCurrentBranch(basePath);
@@ -20,28 +20,19 @@ import { emitJournalEvent } from "./journal.js";
20
20
  import { emitWorktreeCreated, emitWorktreeMerged } from "./worktree-telemetry.js";
21
21
  import { getCollapseCadence, getMilestoneResquash, resquashMilestoneOnMain } from "./slice-cadence.js";
22
22
  import { loadEffectiveGSDPreferences } from "./preferences.js";
23
+ import { resolveWorktreeProjectRoot } from "./worktree-root.js";
23
24
  // ─── Path Helpers ──────────────────────────────────────────────────────────
24
- /**
25
- * Worktree marker segment — present in any path produced by worktreePath().
26
- * Used to strip the worktree suffix and recover the project root (#3729).
27
- */
28
- const WORKTREE_MARKER = "/.gsd/worktrees/";
29
25
  /**
30
26
  * Resolve the project root from session path state.
31
27
  *
32
28
  * Prefers `originalBasePath` (always the project root when set), but falls
33
29
  * back to `basePath` when `originalBasePath` is falsy (e.g. fresh AutoSession
34
30
  * with default empty string). If `basePath` itself is inside a worktree
35
- * directory (contains `/.gsd/worktrees/`), strip that suffix to recover the
36
- * actual project root preventing double-nested worktree paths (#3729).
31
+ * directory (including symlink-resolved ~/.gsd/projects/<hash>/worktrees
32
+ * paths), recover the actual project root to prevent double nesting (#3729).
37
33
  */
38
34
  export function resolveProjectRoot(originalBasePath, basePath) {
39
- let resolved = originalBasePath || basePath;
40
- const markerIdx = resolved.indexOf(WORKTREE_MARKER);
41
- if (markerIdx !== -1) {
42
- resolved = resolved.slice(0, markerIdx);
43
- }
44
- return resolved;
35
+ return resolveWorktreeProjectRoot(basePath, originalBasePath);
45
36
  }
46
37
  // ─── WorktreeResolver ──────────────────────────────────────────────────────
47
38
  export class WorktreeResolver {
@@ -306,6 +297,30 @@ export class WorktreeResolver {
306
297
  */
307
298
  mergeAndExit(milestoneId, ctx) {
308
299
  this.validateMilestoneId(milestoneId);
300
+ // Anchor cwd at the project root before any merge work. Some merge code
301
+ // paths (mergeMilestoneToMain, slice-cadence) chdir explicitly; others
302
+ // (branch-mode, isolation-degraded skip, missing-original-base skip)
303
+ // do not. If the worktree dir is later torn down while cwd still points
304
+ // into it, every subsequent process.cwd() throws ENOENT — and after
305
+ // de73fb43d that surfaces as a session-failed cancel and (in headless
306
+ // mode) terminates the whole gsd process. Best-effort: silent on
307
+ // failure so existing test fixtures that use synthetic paths still pass.
308
+ if (this.s.originalBasePath) {
309
+ try {
310
+ // process.cwd() can throw ENOENT when cwd was removed, so attempt
311
+ // recovery directly.
312
+ process.chdir(this.s.originalBasePath);
313
+ }
314
+ catch (err) {
315
+ debugLog("WorktreeResolver", {
316
+ action: "mergeAndExit",
317
+ phase: "pre-merge-chdir-failed",
318
+ milestoneId,
319
+ originalBasePath: this.s.originalBasePath,
320
+ error: err instanceof Error ? err.message : String(err),
321
+ });
322
+ }
323
+ }
309
324
  // #4764 — telemetry: record start timestamp so we can emit merge duration.
310
325
  const mergeStartedAt = new Date().toISOString();
311
326
  const mergeStartMs = Date.now();
@@ -0,0 +1,124 @@
1
+ import { existsSync, readFileSync, realpathSync, statSync } from "node:fs";
2
+ import { homedir } from "node:os";
3
+ import { join, resolve } from "node:path";
4
+ export function normalizeWorktreePathForCompare(path) {
5
+ let normalized;
6
+ try {
7
+ normalized = realpathSync(path);
8
+ }
9
+ catch {
10
+ normalized = resolve(path);
11
+ }
12
+ const slashed = normalized.replaceAll("\\", "/");
13
+ const trimmed = slashed.replace(/\/+$/, "");
14
+ return process.platform === "win32" ? (trimmed || "/").toLowerCase() : (trimmed || "/");
15
+ }
16
+ /**
17
+ * Find the GSD worktree segment in both direct project layout and the
18
+ * symlink-resolved external-state layout used by ~/.gsd/projects/<hash>.
19
+ */
20
+ export function findWorktreeSegment(normalizedPath) {
21
+ const directMarker = "/.gsd/worktrees/";
22
+ const directIdx = normalizedPath.indexOf(directMarker);
23
+ if (directIdx !== -1) {
24
+ return { gsdIdx: directIdx, afterWorktrees: directIdx + directMarker.length };
25
+ }
26
+ const externalRe = /\/\.gsd\/projects\/[^/]+\/worktrees\//;
27
+ const externalMatch = normalizedPath.match(externalRe);
28
+ if (externalMatch && externalMatch.index !== undefined) {
29
+ return {
30
+ gsdIdx: externalMatch.index,
31
+ afterWorktrees: externalMatch.index + externalMatch[0].length,
32
+ };
33
+ }
34
+ return null;
35
+ }
36
+ export function isGsdWorktreePath(path) {
37
+ return findWorktreeSegment(path.replaceAll("\\", "/")) !== null;
38
+ }
39
+ /**
40
+ * Resolve the canonical project root for worktree operations.
41
+ *
42
+ * `originalBasePath` wins when available because session state already knows the
43
+ * root. `GSD_PROJECT_ROOT` is the next strongest signal for worker processes.
44
+ * Otherwise, derive the root from direct `.gsd/worktrees` paths, or recover it
45
+ * from the worktree `.git` file for symlink-resolved ~/.gsd/project paths.
46
+ */
47
+ export function resolveWorktreeProjectRoot(basePath, originalBasePath) {
48
+ const preferred = originalBasePath?.trim() ||
49
+ process.env.GSD_PROJECT_ROOT?.trim() ||
50
+ basePath;
51
+ return resolveProjectRootFromPath(preferred);
52
+ }
53
+ function resolveProjectRootFromPath(path) {
54
+ const normalizedPath = path.replaceAll("\\", "/");
55
+ const segment = findWorktreeSegment(normalizedPath);
56
+ if (!segment)
57
+ return resolveGitWorkingTreeRoot(path) ?? path;
58
+ const sepChar = path.includes("\\") ? "\\" : "/";
59
+ const gsdMarker = `${sepChar}.gsd${sepChar}`;
60
+ const markerIdx = path.indexOf(gsdMarker);
61
+ const candidate = markerIdx !== -1
62
+ ? path.slice(0, markerIdx)
63
+ : path.slice(0, segment.gsdIdx);
64
+ const gsdHome = normalizeWorktreePathForCompare(process.env.GSD_HOME || join(homedir(), ".gsd"));
65
+ const candidateGsdPath = normalizeWorktreePathForCompare(join(candidate, ".gsd"));
66
+ if (candidateGsdPath === gsdHome || candidateGsdPath.startsWith(`${gsdHome}/`)) {
67
+ const realRoot = resolveProjectRootFromGitFile(path);
68
+ return realRoot ?? path;
69
+ }
70
+ return candidate;
71
+ }
72
+ function resolveGitWorkingTreeRoot(path) {
73
+ try {
74
+ let dir = existsSync(path) && !statSync(path).isDirectory()
75
+ ? resolve(path, "..")
76
+ : path;
77
+ for (let i = 0; i < 30; i++) {
78
+ const gitPath = join(dir, ".git");
79
+ if (existsSync(gitPath))
80
+ return dir;
81
+ const parent = resolve(dir, "..");
82
+ if (parent === dir)
83
+ break;
84
+ dir = parent;
85
+ }
86
+ }
87
+ catch {
88
+ // Non-fatal: callers either keep the original path or fail closed.
89
+ }
90
+ return null;
91
+ }
92
+ function resolveProjectRootFromGitFile(worktreePath) {
93
+ try {
94
+ let dir = worktreePath;
95
+ for (let i = 0; i < 30; i++) {
96
+ const gitPath = join(dir, ".git");
97
+ if (existsSync(gitPath)) {
98
+ const content = readFileSync(gitPath, "utf8").trim();
99
+ if (content.startsWith("gitdir: ")) {
100
+ const gitDir = resolve(dir, content.slice(8));
101
+ const dotGitDir = resolve(gitDir, "..", "..");
102
+ if (dotGitDir.endsWith(".git") || dotGitDir.endsWith(".git/") || dotGitDir.endsWith(".git\\")) {
103
+ return resolve(dotGitDir, "..");
104
+ }
105
+ const commonDirPath = join(gitDir, "commondir");
106
+ if (existsSync(commonDirPath)) {
107
+ const commonDir = readFileSync(commonDirPath, "utf8").trim();
108
+ const resolvedCommonDir = resolve(gitDir, commonDir);
109
+ return resolve(resolvedCommonDir, "..");
110
+ }
111
+ }
112
+ break;
113
+ }
114
+ const parent = resolve(dir, "..");
115
+ if (parent === dir)
116
+ break;
117
+ dir = parent;
118
+ }
119
+ }
120
+ catch {
121
+ // Non-fatal: callers either keep the original path or fail closed.
122
+ }
123
+ return null;
124
+ }
@@ -0,0 +1,33 @@
1
+ // GSD worktree session state
2
+ let originalCwd = null;
3
+ export function getWorktreeOriginalCwd() {
4
+ return originalCwd;
5
+ }
6
+ export function setWorktreeOriginalCwd(cwd) {
7
+ originalCwd = cwd;
8
+ }
9
+ export function clearWorktreeOriginalCwd() {
10
+ originalCwd = null;
11
+ }
12
+ export function ensureWorktreeOriginalCwdFromPath(cwd = process.cwd()) {
13
+ if (originalCwd)
14
+ return originalCwd;
15
+ const marker = `${/\\/.test(cwd) ? "\\" : "/"}.gsd${/\\/.test(cwd) ? "\\" : "/"}worktrees${/\\/.test(cwd) ? "\\" : "/"}`;
16
+ const markerIdx = cwd.indexOf(marker);
17
+ if (markerIdx !== -1) {
18
+ originalCwd = cwd.slice(0, markerIdx);
19
+ }
20
+ return originalCwd;
21
+ }
22
+ export function getActiveWorktreeName() {
23
+ if (!originalCwd)
24
+ return null;
25
+ const cwd = process.cwd();
26
+ const wtDir = `${originalCwd.replace(/[\\/]+$/, "")}/.gsd/worktrees`.replaceAll("\\", "/");
27
+ const normalizedCwd = cwd.replaceAll("\\", "/");
28
+ if (!normalizedCwd.startsWith(`${wtDir}/`))
29
+ return null;
30
+ const rel = normalizedCwd.slice(wtDir.length + 1);
31
+ const name = rel.split("/")[0];
32
+ return name || null;
33
+ }