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
@@ -23,19 +23,19 @@ describe("quick task turn_end cleanup (#2668)", () => {
23
23
  "utf-8",
24
24
  );
25
25
 
26
- it("register-hooks.ts imports cleanupQuickBranch from quick.ts", () => {
26
+ it("register-hooks.ts loads cleanupQuickBranch from quick.ts", () => {
27
27
  assert.ok(
28
28
  hooksSource.includes("cleanupQuickBranch"),
29
29
  "register-hooks.ts must reference cleanupQuickBranch",
30
30
  );
31
31
 
32
- // Verify it's imported (not just mentioned in a comment)
33
- const importMatch = hooksSource.match(
34
- /import\s*\{[^}]*cleanupQuickBranch[^}]*\}\s*from\s*["'][^"']*quick/,
35
- );
32
+ // Verify it is loaded from quick.ts (static or lazy), not just mentioned in a comment.
33
+ const importMatch =
34
+ hooksSource.match(/import\s*\{[^}]*cleanupQuickBranch[^}]*\}\s*from\s*["'][^"']*quick/) ||
35
+ hooksSource.match(/const\s+\{\s*cleanupQuickBranch\s*\}\s*=\s*await\s+import\(["'][^"']*quick\.js["']\)/);
36
36
  assert.ok(
37
37
  importMatch,
38
- "cleanupQuickBranch must be imported from quick module",
38
+ "cleanupQuickBranch must be loaded from quick module",
39
39
  );
40
40
  });
41
41
 
@@ -0,0 +1,93 @@
1
+ import test from "node:test";
2
+ import assert from "node:assert/strict";
3
+ import { existsSync, mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
4
+ import { join } from "node:path";
5
+ import { tmpdir } from "node:os";
6
+
7
+ import { registerHooks } from "../bootstrap/register-hooks.ts";
8
+ import { parseContinue } from "../files.ts";
9
+ import { closeDatabase } from "../gsd-db.ts";
10
+ import { deriveState, invalidateStateCache } from "../state.ts";
11
+
12
+ function createPlanningFixtureBase(): string {
13
+ const base = mkdtempSync(join(tmpdir(), "gsd-compact-checkpoint-"));
14
+ const milestoneDir = join(base, ".gsd", "milestones", "M001");
15
+ const sliceDir = join(milestoneDir, "slices", "S01");
16
+ mkdirSync(sliceDir, { recursive: true });
17
+
18
+ writeFileSync(
19
+ join(milestoneDir, "M001-ROADMAP.md"),
20
+ `# M001: Test Milestone
21
+
22
+ **Vision:** Validate compaction checkpointing.
23
+
24
+ ## Slices
25
+
26
+ - [ ] **S01: Test Slice** \`risk:low\` \`depends:[]\`
27
+ > After this: Slice is done.
28
+ `,
29
+ );
30
+
31
+ writeFileSync(
32
+ join(sliceDir, "S01-PLAN.md"),
33
+ `# S01: Test Slice
34
+
35
+ **Goal:** Validate planning checkpoint.
36
+ **Demo:** Checkpoint exists after compaction.
37
+
38
+ ## Tasks
39
+ `,
40
+ );
41
+
42
+ return base;
43
+ }
44
+
45
+ test("register-hooks writes CONTINUE checkpoint during planning phase without active task (#4258)", async (t) => {
46
+ const base = createPlanningFixtureBase();
47
+ const originalCwd = process.cwd();
48
+ process.chdir(base);
49
+ invalidateStateCache();
50
+ closeDatabase();
51
+
52
+ t.after(() => {
53
+ invalidateStateCache();
54
+ closeDatabase();
55
+ process.chdir(originalCwd);
56
+ rmSync(base, { recursive: true, force: true });
57
+ });
58
+
59
+ const state = await deriveState(base);
60
+ assert.equal(state.phase, "planning", "fixture should derive planning phase");
61
+ assert.equal(state.activeMilestone?.id, "M001", "fixture should have active milestone");
62
+ assert.equal(state.activeSlice?.id, "S01", "fixture should have active slice");
63
+ assert.equal(state.activeTask, null, "fixture should have no active task");
64
+
65
+ const handlers = new Map<string, Array<(event: any, ctx?: any) => Promise<any> | any>>();
66
+ const pi = {
67
+ on(event: string, handler: (event: any, ctx?: any) => Promise<any> | any) {
68
+ const existing = handlers.get(event) ?? [];
69
+ existing.push(handler);
70
+ handlers.set(event, existing);
71
+ },
72
+ } as any;
73
+
74
+ registerHooks(pi, []);
75
+
76
+ const compactHandlers = handlers.get("session_before_compact");
77
+ assert.ok(compactHandlers && compactHandlers.length > 0, "session_before_compact handler should be registered");
78
+
79
+ for (const handler of compactHandlers ?? []) {
80
+ await handler({});
81
+ }
82
+
83
+ const continuePath = join(base, ".gsd", "milestones", "M001", "slices", "S01", "S01-CONTINUE.md");
84
+ assert.ok(existsSync(continuePath), "compaction should create slice CONTINUE checkpoint");
85
+
86
+ const parsed = parseContinue(readFileSync(continuePath, "utf-8"));
87
+ assert.equal(parsed.frontmatter.milestone, "M001");
88
+ assert.equal(parsed.frontmatter.slice, "S01");
89
+ assert.equal(parsed.frontmatter.task, "none", "planning checkpoint should use non-task placeholder");
90
+ assert.equal(parsed.frontmatter.status, "compacted");
91
+ assert.match(parsed.completedWork, /planning phase/i, "completed-work should capture non-executing phase context");
92
+ assert.match(parsed.nextAction, /slice S01/i, "next action should route resume to the active slice");
93
+ });
@@ -18,9 +18,11 @@ import { shouldBlockQueueExecution } from "../bootstrap/write-gate.ts";
18
18
  import {
19
19
  resetEvidence,
20
20
  recordToolCall,
21
+ recordToolResult,
21
22
  getEvidence,
22
23
  saveEvidenceToDisk,
23
24
  loadEvidenceFromDisk,
25
+ type BashEvidence,
24
26
  } from "../safety/evidence-collector.ts";
25
27
  import { validateFileChanges } from "../safety/file-change-validator.ts";
26
28
 
@@ -110,6 +112,38 @@ test("safety-harness-bug2: loadEvidenceFromDisk returns empty array when no file
110
112
  assert.equal(getEvidence().length, 0, "no evidence on fresh unit is correct — not a false positive");
111
113
  });
112
114
 
115
+ test("safety-harness-bug2-race: bash evidence survives mid-unit reset between tool_call and tool_execution_end", (t) => {
116
+ // Reproduces the race where runUnitPhase re-fires (resetEvidence + loadEvidenceFromDisk)
117
+ // between a bash tool_call and its tool_execution_end. Pre-fix, the call entry lived
118
+ // only in memory until tool_execution_end; the reset wiped it and recordToolResult
119
+ // silently no-op'd, producing the "task complete with no bash calls" false positive.
120
+ // Post-fix, register-hooks.ts persists at tool_call time too — so the entry survives
121
+ // the reset via the disk round-trip.
122
+ const base = mkdtempSync(join(tmpdir(), "gsd-evidence-race-"));
123
+ t.after(() => rmSync(base, { recursive: true, force: true }));
124
+
125
+ resetEvidence();
126
+
127
+ // tool_call fires: record AND persist (post-fix register-hooks.ts behavior).
128
+ recordToolCall("tc-bash-1", "bash", { command: "grep -q saveTodos app.js" });
129
+ saveEvidenceToDisk(base, "M001", "S01", "T02");
130
+
131
+ // Mid-unit race: runUnitPhase re-fires, calling resetEvidence + loadEvidenceFromDisk.
132
+ resetEvidence();
133
+ assert.equal(getEvidence().length, 0, "memory cleared by mid-unit reset");
134
+ loadEvidenceFromDisk(base, "M001", "S01", "T02");
135
+ assert.equal(getEvidence().length, 1, "entry restored from disk-persisted tool_call");
136
+
137
+ // tool_execution_end fires: result must update the restored entry by toolCallId.
138
+ recordToolResult("tc-bash-1", "bash", "Command exited with code 0\nfound\n", false);
139
+
140
+ const bash = getEvidence().filter((e): e is BashEvidence => e.kind === "bash");
141
+ assert.equal(bash.length, 1, "bash entry must survive race + result update");
142
+ assert.equal(bash[0].exitCode, 0, "result populated the restored entry");
143
+ assert.equal(bash[0].command, "grep -q saveTodos app.js", "command preserved across race");
144
+ assert.ok(bash[0].outputSnippet.includes("found"), "output snippet captured");
145
+ });
146
+
113
147
  // ─── Bug 3: git diff HEAD~1 scope check ─────────────────────────────────────
114
148
 
115
149
  test("safety-harness-bug3: validateFileChanges works on initial commit (no HEAD~1)", (t) => {
@@ -7,20 +7,20 @@
7
7
  *
8
8
  * Testing strategy:
9
9
  * 1. Source-code regression guards: structural checks on register-hooks.ts.
10
- * 2. Behavioral integration test: fires the live session_start handler with a
11
- * fake ctx when isAutoActive() is false (default) and confirms neither
12
- * setFooter nor setWidget("gsd-health") is called.
10
+ * 2. Behavioral integration tests: fire the live session handlers with fake
11
+ * contexts and confirm footer/widget behavior from runtime effects.
13
12
  *
14
13
  * Relates to #4314.
15
14
  */
16
15
 
17
16
  import test from "node:test";
18
17
  import assert from "node:assert/strict";
19
- import { mkdirSync, readFileSync, rmSync } from "node:fs";
18
+ import { mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
20
19
  import { join, dirname } from "node:path";
21
20
  import { tmpdir } from "node:os";
22
21
  import { fileURLToPath } from "node:url";
23
22
 
23
+ import { autoSession } from "../auto-runtime-state.ts";
24
24
  import { registerHooks } from "../bootstrap/register-hooks.ts";
25
25
 
26
26
  const __dirname = dirname(fileURLToPath(import.meta.url));
@@ -68,27 +68,89 @@ test("session_start handler guards initHealthWidget with !isAutoActive()", () =>
68
68
  );
69
69
  });
70
70
 
71
- test("session_switch handler suppresses gsd-health when isAutoActive()", () => {
72
- const sessionSwitchIdx = HOOKS_SOURCE.indexOf('"session_switch"');
73
- assert.ok(sessionSwitchIdx > -1, "session_switch handler must exist");
71
+ test("session_switch toggles gsd-health from runtime auto state without touching the footer", async (t) => {
72
+ const dir = join(
73
+ tmpdir(),
74
+ `gsd-session-switch-widget-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
75
+ );
76
+ mkdirSync(join(dir, ".gsd"), { recursive: true });
77
+ const tempGsdHome = join(dir, "home");
78
+ mkdirSync(tempGsdHome, { recursive: true });
74
79
 
75
- const beforeAgentStartIdx = HOOKS_SOURCE.indexOf('"before_agent_start"');
76
- assert.ok(beforeAgentStartIdx > sessionSwitchIdx, "before_agent_start handler must follow session_switch");
80
+ const originalCwd = process.cwd();
81
+ const originalGsdHome = process.env.GSD_HOME;
82
+ process.env.GSD_HOME = tempGsdHome;
83
+ process.chdir(dir);
84
+ autoSession.reset();
85
+ t.after(() => {
86
+ autoSession.reset();
87
+ process.chdir(originalCwd);
88
+ if (originalGsdHome === undefined) delete process.env.GSD_HOME;
89
+ else process.env.GSD_HOME = originalGsdHome;
90
+ try { rmSync(dir, { recursive: true, force: true }); } catch { /* best-effort */ }
91
+ });
77
92
 
78
- const sessionSwitchBody = HOOKS_SOURCE.slice(sessionSwitchIdx, beforeAgentStartIdx);
93
+ const handlers = new Map<string, (event: unknown, ctx: any) => Promise<void> | void>();
94
+ const pi = {
95
+ on(event: string, handler: (event: unknown, ctx: any) => Promise<void> | void) {
96
+ handlers.set(event, handler);
97
+ },
98
+ } as any;
79
99
 
80
- assert.ok(
81
- sessionSwitchBody.includes("isAutoActive()"),
82
- "session_switch handler must call isAutoActive()",
83
- );
84
- assert.ok(
85
- sessionSwitchBody.includes('setWidget("gsd-health", undefined)'),
86
- "session_switch handler must call setWidget(\"gsd-health\", undefined) when auto is active",
100
+ registerHooks(pi, []);
101
+
102
+ const sessionSwitch = handlers.get("session_switch");
103
+ assert.ok(sessionSwitch, "session_switch handler must be registered");
104
+
105
+ let setFooterCallCount = 0;
106
+ const widgetCalls: Array<{ key: string; value: unknown }> = [];
107
+ const ctx = {
108
+ hasUI: true,
109
+ ui: {
110
+ notify: () => {},
111
+ setStatus: () => {},
112
+ setFooter: (_footer: unknown) => {
113
+ setFooterCallCount++;
114
+ },
115
+ setWorkingMessage: () => {},
116
+ onTerminalInput: () => () => {},
117
+ setWidget: (key: string, value: unknown) => {
118
+ widgetCalls.push({ key, value });
119
+ },
120
+ },
121
+ sessionManager: { getSessionId: () => null },
122
+ model: null,
123
+ modelRegistry: {
124
+ setDisabledModelProviders: () => {},
125
+ getProviderAuthMode: () => undefined,
126
+ isProviderRequestReady: () => false,
127
+ },
128
+ };
129
+
130
+ autoSession.active = true;
131
+ await sessionSwitch!({ reason: "resume" }, ctx);
132
+ assert.deepEqual(
133
+ widgetCalls.filter((call) => call.key === "gsd-health").map((call) => call.value),
134
+ [undefined],
135
+ "session_switch should hide gsd-health when auto is active",
87
136
  );
137
+ assert.equal(setFooterCallCount, 0, "session_switch must not call setFooter when auto is active");
138
+
139
+ widgetCalls.length = 0;
140
+ autoSession.active = false;
141
+ await sessionSwitch!({ reason: "resume" }, ctx);
142
+ const healthWidgetValues = widgetCalls
143
+ .filter((call) => call.key === "gsd-health")
144
+ .map((call) => call.value);
145
+
146
+ assert.ok(healthWidgetValues.length >= 2, "session_switch should initialize gsd-health when auto is inactive");
88
147
  assert.ok(
89
- !sessionSwitchBody.includes("setFooter"),
90
- "session_switch handler must NOT call setFooter",
148
+ healthWidgetValues.every((value) => value !== undefined),
149
+ "session_switch must not hide gsd-health when auto is inactive",
91
150
  );
151
+ assert.ok(Array.isArray(healthWidgetValues[0]), "initHealthWidget should publish initial health lines");
152
+ assert.equal(typeof healthWidgetValues.at(-1), "function", "initHealthWidget should register the live widget factory");
153
+ assert.equal(setFooterCallCount, 0, "session_switch must not call setFooter when auto is inactive");
92
154
  });
93
155
 
94
156
  // ─── Behavioral test: neither setFooter nor health suppression when auto inactive ─
@@ -143,3 +205,90 @@ test("session_start does NOT call setFooter or suppress gsd-health when isAutoAc
143
205
  assert.equal(setFooterCallCount, 0, "setFooter must NOT be called when isAutoActive() is false");
144
206
  assert.equal(healthWidgetHideCount, 0, "gsd-health must NOT be hidden when isAutoActive() is false");
145
207
  });
208
+
209
+ test("session_start and session_switch apply disabled model provider policy from current preferences", async (t) => {
210
+ const dir = join(
211
+ tmpdir(),
212
+ `gsd-disabled-provider-policy-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
213
+ );
214
+ mkdirSync(join(dir, ".gsd"), { recursive: true });
215
+ const tempGsdHome = join(dir, "home");
216
+ mkdirSync(tempGsdHome, { recursive: true });
217
+
218
+ const originalCwd = process.cwd();
219
+ const originalGsdHome = process.env.GSD_HOME;
220
+ process.env.GSD_HOME = tempGsdHome;
221
+ process.chdir(dir);
222
+ t.after(() => {
223
+ process.chdir(originalCwd);
224
+ if (originalGsdHome === undefined) delete process.env.GSD_HOME;
225
+ else process.env.GSD_HOME = originalGsdHome;
226
+ try { rmSync(dir, { recursive: true, force: true }); } catch { /* best-effort */ }
227
+ });
228
+
229
+ const writePrefs = (providers: string[]) => {
230
+ writeFileSync(
231
+ join(dir, ".gsd", "PREFERENCES.md"),
232
+ [
233
+ "---",
234
+ "version: 1",
235
+ "disabled_model_providers:",
236
+ ...providers.map((provider) => ` - ${provider}`),
237
+ "---",
238
+ "",
239
+ ].join("\n"),
240
+ "utf-8",
241
+ );
242
+ };
243
+
244
+ const appliedPolicies: string[][] = [];
245
+ const handlers = new Map<string, (event: unknown, ctx: any) => Promise<void> | void>();
246
+ const pi = {
247
+ on(event: string, handler: (event: unknown, ctx: any) => Promise<void> | void) {
248
+ handlers.set(event, handler);
249
+ },
250
+ } as any;
251
+ const ctx = {
252
+ hasUI: true,
253
+ ui: {
254
+ notify: () => {},
255
+ setStatus: () => {},
256
+ setFooter: () => {},
257
+ setWorkingMessage: () => {},
258
+ onTerminalInput: () => () => {},
259
+ setWidget: () => {},
260
+ },
261
+ sessionManager: { getSessionId: () => null },
262
+ model: null,
263
+ modelRegistry: {
264
+ setDisabledModelProviders: (providers: string[]) => {
265
+ appliedPolicies.push([...providers]);
266
+ },
267
+ getProviderAuthMode: () => undefined,
268
+ isProviderRequestReady: () => false,
269
+ },
270
+ };
271
+
272
+ registerHooks(pi, []);
273
+
274
+ const sessionStart = handlers.get("session_start");
275
+ const sessionSwitch = handlers.get("session_switch");
276
+ assert.ok(sessionStart, "session_start handler must be registered");
277
+ assert.ok(sessionSwitch, "session_switch handler must be registered");
278
+
279
+ writePrefs(["google-gemini-cli", " google-gemini-cli ", "openai-codex"]);
280
+ await sessionStart!({}, ctx);
281
+ assert.deepEqual(
282
+ appliedPolicies.at(-1),
283
+ ["google-gemini-cli", "openai-codex"],
284
+ "session_start should apply normalized disabled providers before the first agent turn",
285
+ );
286
+
287
+ writePrefs(["anthropic"]);
288
+ await sessionSwitch!({ reason: "resume" }, ctx);
289
+ assert.deepEqual(
290
+ appliedPolicies.at(-1),
291
+ ["anthropic"],
292
+ "session_switch should re-read preferences for the switched project/session context",
293
+ );
294
+ });
@@ -11,7 +11,7 @@ import { existsSync, mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync
11
11
  import { join, dirname } from "node:path";
12
12
  import { tmpdir } from "node:os";
13
13
  import { fileURLToPath } from "node:url";
14
- import { restoreSliceState } from "../slice-parallel-orchestrator.ts";
14
+ import { restoreSliceState, SLICE_WORKER_AUTO_ARGS } from "../slice-parallel-orchestrator.ts";
15
15
 
16
16
  const __dirname = dirname(fileURLToPath(import.meta.url));
17
17
  const gsdDir = join(__dirname, "..");
@@ -100,6 +100,12 @@ describe("slice-parallel-orchestrator structural tests", () => {
100
100
  );
101
101
  });
102
102
 
103
+ it("slice workers use headless auto instead of print-mode slash commands", () => {
104
+ const args: readonly string[] = SLICE_WORKER_AUTO_ARGS;
105
+ assert.deepEqual([...args], ["headless", "--json", "auto"]);
106
+ assert.equal(args.includes("--print"), false);
107
+ });
108
+
103
109
  it("maxWorkers default is 2", () => {
104
110
  const source = readFileSync(join(gsdDir, "slice-parallel-orchestrator.ts"), "utf-8");
105
111
  // Check that default max workers is 2 (in opts.maxWorkers ?? 2 or similar)
@@ -48,6 +48,28 @@ test("guided-flow complete branch offers a chooser for next milestone or status"
48
48
 
49
49
  assert.match(branchChunk, /showNextAction\(/, "complete branch should present a chooser");
50
50
  assert.match(branchChunk, /findMilestoneIds\(basePath\)/, "complete branch should compute the next milestone id");
51
- assert.match(branchChunk, /nextMilestoneId(?:Reserved)?\(milestoneIds, uniqueMilestoneIds\)/, "complete branch should derive the next milestone id");
51
+ assert.match(
52
+ branchChunk,
53
+ /nextMilestoneIdReserved\(milestoneIds,\s*uniqueMilestoneIds,\s*basePath\)/,
54
+ "complete branch should derive the next milestone id",
55
+ );
52
56
  assert.match(branchChunk, /dispatchWorkflow\(pi, await prepareAndBuildDiscussPrompt\(/, "complete branch should dispatch the prepared discuss prompt");
53
57
  });
58
+
59
+ test("guided-flow needs-discussion skip branch opens the project DB before reserving a new milestone", () => {
60
+ const guidedFlowSource = readFileSync(join(import.meta.dirname, "..", "guided-flow.ts"), "utf-8");
61
+ const laterDbOpenIdx = guidedFlowSource.indexOf("// Ensure DB is open before querying slices (#2560).");
62
+ assert.ok(laterDbOpenIdx > -1, "guided-flow.ts should contain the post-draft DB-open guard");
63
+
64
+ const branchPrefix = guidedFlowSource.slice(0, laterDbOpenIdx);
65
+ const skipBranchIdx = branchPrefix.lastIndexOf('choice === "skip_milestone"');
66
+ assert.ok(skipBranchIdx > -1, "needs-discussion skip branch should be present");
67
+
68
+ const branchChunk = branchPrefix.slice(skipBranchIdx);
69
+ const ensureIdx = branchChunk.indexOf("ensureDbOpen(basePath)");
70
+ const reserveIdx = branchChunk.indexOf("nextMilestoneIdReserved");
71
+
72
+ assert.ok(ensureIdx > -1, "skip branch should open the project DB");
73
+ assert.ok(reserveIdx > -1, "skip branch should reserve the next milestone ID");
74
+ assert.ok(ensureIdx < reserveIdx, "project DB must be opened before milestone ID reservation");
75
+ });
@@ -21,6 +21,7 @@ import { _clearGsdRootCache } from "../paths.ts";
21
21
  // Isolate from user's global preferences (which may have git.main_branch set)
22
22
  let originalHome: string | undefined;
23
23
  let fakeHome: string;
24
+ const testCwd = process.cwd();
24
25
 
25
26
  test.before(() => {
26
27
  originalHome = process.env.HOME;
@@ -37,6 +38,11 @@ test.after(() => {
37
38
  rmSync(fakeHome, { recursive: true, force: true });
38
39
  });
39
40
 
41
+ function cleanupTempRepo(repo: string): void {
42
+ try { process.chdir(testCwd); } catch { /* best-effort */ }
43
+ try { rmSync(repo, { recursive: true, force: true, maxRetries: 3, retryDelay: 100 }); } catch { /* cleanup best-effort */ }
44
+ }
45
+
40
46
  function run(cmd: string, cwd: string): string {
41
47
  return execSync(cmd, { cwd, stdio: ["ignore", "pipe", "pipe"], encoding: "utf-8" }).trim();
42
48
  }
@@ -106,7 +112,7 @@ test("#2766: stash pop conflict on .gsd/ files is auto-resolved", () => {
106
112
  try { stashList = run("git stash list", repo); } catch { /* empty stash */ }
107
113
  assert.strictEqual(stashList, "", "stash is empty after .gsd/ conflict auto-resolution");
108
114
  } finally {
109
- try { rmSync(repo, { recursive: true, force: true, maxRetries: 3, retryDelay: 100 }); } catch { /* cleanup best-effort */ }
115
+ cleanupTempRepo(repo);
110
116
  }
111
117
  });
112
118
 
@@ -141,6 +147,6 @@ test("#2766: stash pop conflict on non-.gsd files preserves stash for manual res
141
147
  "merge succeeds even with non-.gsd stash pop conflict",
142
148
  );
143
149
  } finally {
144
- try { rmSync(repo, { recursive: true, force: true, maxRetries: 3, retryDelay: 100 }); } catch { /* cleanup best-effort */ }
150
+ cleanupTempRepo(repo);
145
151
  }
146
152
  });
@@ -35,6 +35,7 @@ import { _clearGsdRootCache } from "../paths.ts";
35
35
  // Isolate from user's global preferences (which may have git.main_branch set)
36
36
  let originalHome: string | undefined;
37
37
  let fakeHome: string;
38
+ const testCwd = process.cwd();
38
39
 
39
40
  test.before(() => {
40
41
  originalHome = process.env.HOME;
@@ -51,6 +52,13 @@ test.after(() => {
51
52
  rmSync(fakeHome, { recursive: true, force: true });
52
53
  });
53
54
 
55
+ function cleanupTempPaths(...paths: string[]): void {
56
+ try { process.chdir(testCwd); } catch { /* best-effort */ }
57
+ for (const p of paths) {
58
+ rmSync(p, { recursive: true, force: true });
59
+ }
60
+ }
61
+
54
62
  function run(cmd: string, cwd: string): string {
55
63
  return execSync(cmd, {
56
64
  cwd,
@@ -271,7 +279,7 @@ test("#2505: mergeMilestoneToMain preserves queued CONTEXT files (not swept into
271
279
  }
272
280
  }
273
281
  } finally {
274
- rmSync(repo, { recursive: true, force: true });
282
+ cleanupTempPaths(repo);
275
283
  }
276
284
  });
277
285
 
@@ -308,8 +316,7 @@ test("#2505: pre-merge stash handles symlinked .gsd without traversing it", () =
308
316
  assert.equal(readFileSync(join(repo, "README.md"), "utf-8").replace(/\r\n/g, "\n"), "# test\n\nDirty change.\n");
309
317
  assert.equal(readFileSync(join(repo, "local-note.txt"), "utf-8"), "local scratch\n");
310
318
  } finally {
311
- rmSync(repo, { recursive: true, force: true });
312
- rmSync(stateDir, { recursive: true, force: true });
319
+ cleanupTempPaths(repo, stateDir);
313
320
  }
314
321
  });
315
322
 
@@ -375,7 +382,7 @@ test("#2505: back-to-back merges preserve queued CONTEXT files", () => {
375
382
  "M013 context content preserved after back-to-back merges",
376
383
  );
377
384
  } finally {
378
- rmSync(repo, { recursive: true, force: true });
385
+ cleanupTempPaths(repo);
379
386
  }
380
387
  });
381
388
 
@@ -430,7 +437,6 @@ test("#4573: gitignored .gsd symlink does not break pre-merge stash", () => {
430
437
  ".gsd symlink remains in place",
431
438
  );
432
439
  } finally {
433
- rmSync(repo, { recursive: true, force: true });
434
- rmSync(stateDir, { recursive: true, force: true });
440
+ cleanupTempPaths(repo, stateDir);
435
441
  }
436
442
  });
@@ -4,7 +4,7 @@
4
4
 
5
5
  import { describe, test, beforeEach, afterEach } from "node:test";
6
6
  import assert from "node:assert/strict";
7
- import { mkdtempSync, mkdirSync, existsSync, readFileSync, rmSync } from "node:fs";
7
+ import { mkdtempSync, mkdirSync, existsSync, readFileSync, rmSync, writeFileSync } from "node:fs";
8
8
  import { join } from "node:path";
9
9
  import { tmpdir } from "node:os";
10
10
  import { appendOverride, loadActiveOverrides } from "../files.ts";
@@ -73,6 +73,22 @@ describe("steer worktree path resolution (#3476)", () => {
73
73
  assert.equal(result, null, "returns null for worktree without .git file");
74
74
  });
75
75
 
76
+ test("getAutoWorktreePath returns null when .git is a directory", () => {
77
+ mkdirSync(join(worktreePath, ".git"), { recursive: true });
78
+
79
+ const result = getAutoWorktreePath(projectRoot, "M001");
80
+
81
+ assert.equal(result, null, "returns null for standalone .git directories");
82
+ });
83
+
84
+ test("getAutoWorktreePath returns null when .git file is not a gitdir pointer", () => {
85
+ writeFileSync(join(worktreePath, ".git"), "not-a-gitdir\n", "utf-8");
86
+
87
+ const result = getAutoWorktreePath(projectRoot, "M001");
88
+
89
+ assert.equal(result, null, "returns null for invalid .git files");
90
+ });
91
+
76
92
  test("override routing: inactive worktree directory should not receive overrides", async () => {
77
93
  // Simulate the handleSteer path-resolution logic:
78
94
  // When no auto-mode is running, even if a worktree dir exists,
@@ -0,0 +1,101 @@
1
+ // GSD bootstrap + system-context-message-routing.test — regression coverage
2
+ // for #5019. `memoryBlock` is FTS-queried against the user prompt and changes
3
+ // per call; embedding it in the cached system prefix invalidates Anthropic
4
+ // prompt-cache hits on every request. The fix routes memory through the
5
+ // existing context-message channel (volatile user-message suffix) and combines
6
+ // it with any active guided-execute or forensics injection.
7
+
8
+ import { describe, test } from "node:test";
9
+ import assert from "node:assert/strict";
10
+
11
+ import { buildContextMessage } from "../bootstrap/system-context.ts";
12
+
13
+ describe("buildContextMessage (#5019 — memory routing)", () => {
14
+ test("returns null when nothing to inject", () => {
15
+ const result = buildContextMessage({
16
+ memoryBlock: "",
17
+ injection: null,
18
+ forensicsInjection: null,
19
+ });
20
+ assert.equal(result, null);
21
+ });
22
+
23
+ test("whitespace-only memoryBlock counts as empty", () => {
24
+ const result = buildContextMessage({
25
+ memoryBlock: " \n\n ",
26
+ injection: null,
27
+ forensicsInjection: null,
28
+ });
29
+ assert.equal(result, null);
30
+ });
31
+
32
+ test("memory-only path emits gsd-memory message with trimmed content", () => {
33
+ const result = buildContextMessage({
34
+ memoryBlock: "\n\n[MEMORY]\nrule one\nrule two\n\n",
35
+ injection: null,
36
+ forensicsInjection: null,
37
+ });
38
+ assert.ok(result, "expected a context message");
39
+ assert.equal(result.customType, "gsd-memory");
40
+ assert.equal(result.content, "[MEMORY]\nrule one\nrule two");
41
+ assert.equal(result.display, false);
42
+ });
43
+
44
+ test("guided-execute injection alone emits gsd-guided-context", () => {
45
+ const result = buildContextMessage({
46
+ memoryBlock: "",
47
+ injection: "[GUIDED]\nexecute T01",
48
+ forensicsInjection: null,
49
+ });
50
+ assert.ok(result);
51
+ assert.equal(result.customType, "gsd-guided-context");
52
+ assert.equal(result.content, "[GUIDED]\nexecute T01");
53
+ });
54
+
55
+ test("forensics injection alone emits gsd-forensics", () => {
56
+ const result = buildContextMessage({
57
+ memoryBlock: "",
58
+ injection: null,
59
+ forensicsInjection: "[FORENSICS]\ninvestigation context",
60
+ });
61
+ assert.ok(result);
62
+ assert.equal(result.customType, "gsd-forensics");
63
+ assert.equal(result.content, "[FORENSICS]\ninvestigation context");
64
+ });
65
+
66
+ test("memory + guided injection: memory prepended, customType is gsd-guided-context", () => {
67
+ const result = buildContextMessage({
68
+ memoryBlock: "[MEMORY]\nrule one",
69
+ injection: "[GUIDED]\nexecute T01",
70
+ forensicsInjection: null,
71
+ });
72
+ assert.ok(result);
73
+ assert.equal(result.customType, "gsd-guided-context");
74
+ assert.equal(result.content, "[MEMORY]\nrule one\n\n[GUIDED]\nexecute T01");
75
+ });
76
+
77
+ test("memory + forensics: memory prepended, customType is gsd-forensics", () => {
78
+ const result = buildContextMessage({
79
+ memoryBlock: "[MEMORY]\nrule one",
80
+ injection: null,
81
+ forensicsInjection: "[FORENSICS]\ninvestigation context",
82
+ });
83
+ assert.ok(result);
84
+ assert.equal(result.customType, "gsd-forensics");
85
+ assert.equal(result.content, "[MEMORY]\nrule one\n\n[FORENSICS]\ninvestigation context");
86
+ });
87
+
88
+ test("guided takes precedence over forensics when both are somehow present", () => {
89
+ // The caller in buildBeforeAgentStartResult already gates forensics on
90
+ // `!injection`, but the helper's documented priority is guided > forensics.
91
+ // Test the contract directly so a future refactor can't silently flip it.
92
+ const result = buildContextMessage({
93
+ memoryBlock: "",
94
+ injection: "[GUIDED]",
95
+ forensicsInjection: "[FORENSICS]",
96
+ });
97
+ assert.ok(result);
98
+ assert.equal(result.customType, "gsd-guided-context");
99
+ assert.equal(result.content, "[GUIDED]");
100
+ });
101
+ });