gsd-pi 2.49.0 → 2.50.0-dev.d210a87

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 (679) hide show
  1. package/README.md +2 -0
  2. package/dist/cli.js +26 -0
  3. package/dist/headless-ui.js +12 -2
  4. package/dist/headless.js +29 -13
  5. package/dist/loader.js +4 -0
  6. package/dist/resource-loader.d.ts +4 -1
  7. package/dist/resource-loader.js +138 -3
  8. package/dist/resources/extensions/async-jobs/async-bash-tool.js +3 -1
  9. package/dist/resources/extensions/bg-shell/interaction.js +3 -1
  10. package/dist/resources/extensions/bg-shell/process-manager.js +4 -1
  11. package/dist/resources/extensions/claude-code-cli/partial-builder.js +5 -0
  12. package/dist/resources/extensions/gsd/auto/infra-errors.js +1 -0
  13. package/dist/resources/extensions/gsd/auto/phases.js +27 -12
  14. package/dist/resources/extensions/gsd/auto/resolve.js +2 -2
  15. package/dist/resources/extensions/gsd/auto/run-unit.js +2 -2
  16. package/dist/resources/extensions/gsd/auto/session.js +9 -0
  17. package/dist/resources/extensions/gsd/auto-artifact-paths.js +8 -10
  18. package/dist/resources/extensions/gsd/auto-dashboard.js +28 -6
  19. package/dist/resources/extensions/gsd/auto-dispatch.js +113 -74
  20. package/dist/resources/extensions/gsd/auto-observability.js +54 -0
  21. package/dist/resources/extensions/gsd/auto-post-unit.js +53 -99
  22. package/dist/resources/extensions/gsd/auto-prompts.js +155 -17
  23. package/dist/resources/extensions/gsd/auto-recovery.js +79 -205
  24. package/dist/resources/extensions/gsd/auto-start.js +4 -31
  25. package/dist/resources/extensions/gsd/auto-timers.js +2 -2
  26. package/dist/resources/extensions/gsd/auto-utils.js +20 -0
  27. package/dist/resources/extensions/gsd/auto-verification.js +4 -7
  28. package/dist/resources/extensions/gsd/auto-worktree.js +257 -113
  29. package/dist/resources/extensions/gsd/auto.js +22 -10
  30. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +89 -0
  31. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +24 -1
  32. package/dist/resources/extensions/gsd/branch-patterns.js +13 -0
  33. package/dist/resources/extensions/gsd/crash-recovery.js +6 -2
  34. package/dist/resources/extensions/gsd/custom-execution-policy.js +3 -2
  35. package/dist/resources/extensions/gsd/custom-verification.js +3 -1
  36. package/dist/resources/extensions/gsd/custom-workflow-engine.js +3 -2
  37. package/dist/resources/extensions/gsd/dashboard-overlay.js +4 -0
  38. package/dist/resources/extensions/gsd/detection.js +589 -3
  39. package/dist/resources/extensions/gsd/dispatch-guard.js +2 -1
  40. package/dist/resources/extensions/gsd/docs/preferences-reference.md +15 -0
  41. package/dist/resources/extensions/gsd/doctor-checks.js +5 -1234
  42. package/dist/resources/extensions/gsd/doctor-engine-checks.js +168 -0
  43. package/dist/resources/extensions/gsd/doctor-environment.js +28 -7
  44. package/dist/resources/extensions/gsd/doctor-git-checks.js +405 -0
  45. package/dist/resources/extensions/gsd/doctor-global-checks.js +74 -0
  46. package/dist/resources/extensions/gsd/doctor-runtime-checks.js +600 -0
  47. package/dist/resources/extensions/gsd/doctor.js +9 -1
  48. package/dist/resources/extensions/gsd/extension-manifest.json +1 -1
  49. package/dist/resources/extensions/gsd/files.js +5 -1
  50. package/dist/resources/extensions/gsd/git-service.js +9 -10
  51. package/dist/resources/extensions/gsd/gsd-db.js +124 -1
  52. package/dist/resources/extensions/gsd/guided-flow-queue.js +10 -11
  53. package/dist/resources/extensions/gsd/guided-flow.js +10 -0
  54. package/dist/resources/extensions/gsd/init-wizard.js +9 -1
  55. package/dist/resources/extensions/gsd/markdown-renderer.js +33 -5
  56. package/dist/resources/extensions/gsd/model-router.js +25 -0
  57. package/dist/resources/extensions/gsd/notifications.js +23 -0
  58. package/dist/resources/extensions/gsd/observability-validator.js +422 -0
  59. package/dist/resources/extensions/gsd/preferences-skills.js +11 -5
  60. package/dist/resources/extensions/gsd/preferences-types.js +3 -1
  61. package/dist/resources/extensions/gsd/preferences-validation.js +64 -0
  62. package/dist/resources/extensions/gsd/preferences.js +3 -0
  63. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +27 -8
  64. package/dist/resources/extensions/gsd/prompts/complete-slice.md +9 -8
  65. package/dist/resources/extensions/gsd/prompts/execute-task.md +16 -13
  66. package/dist/resources/extensions/gsd/prompts/forensics.md +19 -8
  67. package/dist/resources/extensions/gsd/prompts/gate-evaluate.md +32 -0
  68. package/dist/resources/extensions/gsd/prompts/guided-complete-slice.md +1 -1
  69. package/dist/resources/extensions/gsd/prompts/guided-execute-task.md +1 -1
  70. package/dist/resources/extensions/gsd/prompts/guided-plan-milestone.md +1 -1
  71. package/dist/resources/extensions/gsd/prompts/guided-plan-slice.md +1 -1
  72. package/dist/resources/extensions/gsd/prompts/plan-milestone.md +1 -1
  73. package/dist/resources/extensions/gsd/prompts/plan-slice.md +8 -3
  74. package/dist/resources/extensions/gsd/prompts/reassess-roadmap.md +3 -0
  75. package/dist/resources/extensions/gsd/prompts/replan-slice.md +1 -1
  76. package/dist/resources/extensions/gsd/prompts/validate-milestone.md +6 -1
  77. package/dist/resources/extensions/gsd/provider-error-pause.js +8 -0
  78. package/dist/resources/extensions/gsd/repo-identity.js +29 -0
  79. package/dist/resources/extensions/gsd/roadmap-mutations.js +110 -0
  80. package/dist/resources/extensions/gsd/roadmap-slices.js +2 -2
  81. package/dist/resources/extensions/gsd/rtk-status.js +43 -0
  82. package/dist/resources/extensions/gsd/rule-registry.js +10 -11
  83. package/dist/resources/extensions/gsd/session-forensics.js +13 -14
  84. package/dist/resources/extensions/gsd/session-lock.js +67 -56
  85. package/dist/resources/extensions/gsd/skill-catalog.js +1026 -0
  86. package/dist/resources/extensions/gsd/skill-discovery.js +3 -2
  87. package/dist/resources/extensions/gsd/skill-health.js +2 -2
  88. package/dist/resources/extensions/gsd/skill-telemetry.js +15 -5
  89. package/dist/resources/extensions/gsd/state.js +51 -12
  90. package/dist/resources/extensions/gsd/templates/milestone-summary.md +8 -0
  91. package/dist/resources/extensions/gsd/templates/milestone-validation.md +12 -0
  92. package/dist/resources/extensions/gsd/templates/plan.md +16 -0
  93. package/dist/resources/extensions/gsd/templates/preferences.md +2 -0
  94. package/dist/resources/extensions/gsd/templates/roadmap.md +13 -0
  95. package/dist/resources/extensions/gsd/templates/slice-summary.md +9 -0
  96. package/dist/resources/extensions/gsd/templates/task-plan.md +24 -0
  97. package/dist/resources/extensions/gsd/tests/dist-redirect.mjs +28 -9
  98. package/dist/resources/extensions/gsd/tools/plan-slice.js +14 -1
  99. package/dist/resources/extensions/gsd/tools/validate-milestone.js +3 -3
  100. package/dist/resources/extensions/gsd/undo.js +8 -7
  101. package/dist/resources/extensions/gsd/unit-runtime.js +2 -1
  102. package/dist/resources/extensions/gsd/verdict-parser.js +84 -0
  103. package/dist/resources/extensions/gsd/verification-gate.js +3 -1
  104. package/dist/resources/extensions/gsd/worktree-resolver.js +24 -0
  105. package/dist/resources/extensions/gsd/worktree.js +3 -2
  106. package/dist/resources/extensions/remote-questions/config.js +3 -5
  107. package/dist/resources/extensions/search-the-web/native-search.js +8 -3
  108. package/dist/resources/extensions/search-the-web/tool-search.js +19 -2
  109. package/dist/resources/extensions/shared/rtk-session-stats.js +189 -0
  110. package/dist/resources/extensions/shared/rtk.js +100 -0
  111. package/dist/resources/skills/github-workflows/references/gh/SKILL.md +22 -1
  112. package/dist/rtk.d.ts +52 -0
  113. package/dist/rtk.js +332 -0
  114. package/dist/web/standalone/.next/BUILD_ID +1 -1
  115. package/dist/web/standalone/.next/app-path-routes-manifest.json +20 -19
  116. package/dist/web/standalone/.next/build-manifest.json +4 -4
  117. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  118. package/dist/web/standalone/.next/react-loadable-manifest.json +2 -2
  119. package/dist/web/standalone/.next/required-server-files.json +3 -3
  120. package/dist/web/standalone/.next/routes-manifest.json +6 -0
  121. package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
  122. package/dist/web/standalone/.next/server/app/_global-error/page.js.nft.json +1 -1
  123. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  124. package/dist/web/standalone/.next/server/app/_global-error.html +2 -2
  125. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  126. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  127. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  128. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  129. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  130. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  131. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  132. package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
  133. package/dist/web/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
  134. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  135. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  136. package/dist/web/standalone/.next/server/app/_not-found.rsc +4 -4
  137. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +4 -4
  138. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  139. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +4 -4
  140. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  141. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  142. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  143. package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
  144. package/dist/web/standalone/.next/server/app/api/boot/route.js.nft.json +1 -1
  145. package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
  146. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
  147. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js.nft.json +1 -1
  148. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
  149. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
  150. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js.nft.json +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.js.nft.json +1 -1
  154. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
  155. package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
  156. package/dist/web/standalone/.next/server/app/api/browse-directories/route.js.nft.json +1 -1
  157. package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
  158. package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
  159. package/dist/web/standalone/.next/server/app/api/captures/route.js.nft.json +1 -1
  160. package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
  161. package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
  162. package/dist/web/standalone/.next/server/app/api/cleanup/route.js.nft.json +1 -1
  163. package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
  164. package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
  165. package/dist/web/standalone/.next/server/app/api/dev-mode/route.js.nft.json +1 -1
  166. package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
  167. package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
  168. package/dist/web/standalone/.next/server/app/api/doctor/route.js.nft.json +1 -1
  169. package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
  170. package/dist/web/standalone/.next/server/app/api/experimental/route.js +3 -0
  171. package/dist/web/standalone/.next/server/app/api/experimental/route.js.nft.json +1 -0
  172. package/dist/web/standalone/.next/server/app/api/experimental/route_client-reference-manifest.js +1 -0
  173. package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
  174. package/dist/web/standalone/.next/server/app/api/export-data/route.js.nft.json +1 -1
  175. package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
  176. package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
  177. package/dist/web/standalone/.next/server/app/api/files/route.js.nft.json +1 -1
  178. package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
  179. package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
  180. package/dist/web/standalone/.next/server/app/api/forensics/route.js.nft.json +1 -1
  181. package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
  182. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  183. package/dist/web/standalone/.next/server/app/api/git/route.js.nft.json +1 -1
  184. package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  185. package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
  186. package/dist/web/standalone/.next/server/app/api/history/route.js.nft.json +1 -1
  187. package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
  188. package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
  189. package/dist/web/standalone/.next/server/app/api/hooks/route.js.nft.json +1 -1
  190. package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
  191. package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
  192. package/dist/web/standalone/.next/server/app/api/inspect/route.js.nft.json +1 -1
  193. package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
  194. package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
  195. package/dist/web/standalone/.next/server/app/api/knowledge/route.js.nft.json +1 -1
  196. package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
  197. package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
  198. package/dist/web/standalone/.next/server/app/api/live-state/route.js.nft.json +1 -1
  199. package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
  200. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  201. package/dist/web/standalone/.next/server/app/api/onboarding/route.js.nft.json +1 -1
  202. package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
  203. package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
  204. package/dist/web/standalone/.next/server/app/api/preferences/route.js.nft.json +1 -1
  205. package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
  206. package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
  207. package/dist/web/standalone/.next/server/app/api/projects/route.js.nft.json +1 -1
  208. package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  209. package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
  210. package/dist/web/standalone/.next/server/app/api/recovery/route.js.nft.json +1 -1
  211. package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
  212. package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +2 -26
  213. package/dist/web/standalone/.next/server/app/api/remote-questions/route.js.nft.json +1 -1
  214. package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
  215. package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
  216. package/dist/web/standalone/.next/server/app/api/session/browser/route.js.nft.json +1 -1
  217. package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
  218. package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
  219. package/dist/web/standalone/.next/server/app/api/session/command/route.js.nft.json +1 -1
  220. package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
  221. package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
  222. package/dist/web/standalone/.next/server/app/api/session/events/route.js.nft.json +1 -1
  223. package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
  224. package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
  225. package/dist/web/standalone/.next/server/app/api/session/manage/route.js.nft.json +1 -1
  226. package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
  227. package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
  228. package/dist/web/standalone/.next/server/app/api/settings-data/route.js.nft.json +1 -1
  229. package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
  230. package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
  231. package/dist/web/standalone/.next/server/app/api/shutdown/route.js.nft.json +1 -1
  232. package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
  233. package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
  234. package/dist/web/standalone/.next/server/app/api/skill-health/route.js.nft.json +1 -1
  235. package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
  236. package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
  237. package/dist/web/standalone/.next/server/app/api/steer/route.js.nft.json +1 -1
  238. package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
  239. package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
  240. package/dist/web/standalone/.next/server/app/api/switch-root/route.js.nft.json +1 -1
  241. package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
  242. package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +2 -2
  243. package/dist/web/standalone/.next/server/app/api/terminal/input/route.js.nft.json +1 -1
  244. package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
  245. package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
  246. package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js.nft.json +1 -1
  247. package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
  248. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +2 -2
  249. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js.nft.json +1 -1
  250. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
  251. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +4 -4
  252. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js.nft.json +1 -1
  253. package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
  254. package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
  255. package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js.nft.json +1 -1
  256. package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
  257. package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
  258. package/dist/web/standalone/.next/server/app/api/undo/route.js.nft.json +1 -1
  259. package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
  260. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  261. package/dist/web/standalone/.next/server/app/api/update/route.js.nft.json +1 -1
  262. package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  263. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  264. package/dist/web/standalone/.next/server/app/api/visualizer/route.js.nft.json +1 -1
  265. package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
  266. package/dist/web/standalone/.next/server/app/index.html +1 -1
  267. package/dist/web/standalone/.next/server/app/index.rsc +5 -5
  268. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  269. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +5 -5
  270. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  271. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +4 -4
  272. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  273. package/dist/web/standalone/.next/server/app/page.js +2 -2
  274. package/dist/web/standalone/.next/server/app/page.js.nft.json +1 -1
  275. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  276. package/dist/web/standalone/.next/server/app-paths-manifest.json +20 -19
  277. package/dist/web/standalone/.next/server/chunks/2229.js +12 -0
  278. package/dist/web/standalone/.next/server/chunks/2331.js +25 -0
  279. package/dist/web/standalone/.next/server/chunks/{741.js → 4741.js} +1 -1
  280. package/dist/web/standalone/.next/server/chunks/5822.js +2 -0
  281. package/dist/web/standalone/.next/server/chunks/7471.js +13 -0
  282. package/dist/web/standalone/.next/server/functions-config-manifest.json +1 -0
  283. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  284. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  285. package/dist/web/standalone/.next/server/middleware.js +3 -3
  286. package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
  287. package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
  288. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  289. package/dist/web/standalone/.next/server/pages/500.html +2 -2
  290. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  291. package/dist/web/standalone/.next/server/webpack-runtime.js +1 -1
  292. package/dist/web/standalone/.next/static/chunks/{485.243af25f0cdf50d6.js → 2008.817d0885545aaea9.js} +6 -6
  293. package/dist/web/standalone/.next/static/chunks/4024.9ad5def014d90ce4.js +9 -0
  294. package/dist/web/standalone/.next/static/chunks/app/_global-error/page-c4cc189e7b117ea2.js +1 -0
  295. package/dist/web/standalone/.next/static/chunks/app/_not-found/{page-2f24283c162b6ab3.js → page-f2a7482d42a5614b.js} +1 -1
  296. package/dist/web/standalone/.next/static/chunks/app/api/boot/route-c4cc189e7b117ea2.js +1 -0
  297. package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/input/route-c4cc189e7b117ea2.js +1 -0
  298. package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/resize/route-c4cc189e7b117ea2.js +1 -0
  299. package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/stream/route-c4cc189e7b117ea2.js +1 -0
  300. package/dist/web/standalone/.next/static/chunks/app/api/browse-directories/route-c4cc189e7b117ea2.js +1 -0
  301. package/dist/web/standalone/.next/static/chunks/app/api/captures/route-c4cc189e7b117ea2.js +1 -0
  302. package/dist/web/standalone/.next/static/chunks/app/api/cleanup/route-c4cc189e7b117ea2.js +1 -0
  303. package/dist/web/standalone/.next/static/chunks/app/api/dev-mode/route-c4cc189e7b117ea2.js +1 -0
  304. package/dist/web/standalone/.next/static/chunks/app/api/doctor/route-c4cc189e7b117ea2.js +1 -0
  305. package/dist/web/standalone/.next/static/chunks/app/api/experimental/route-c4cc189e7b117ea2.js +1 -0
  306. package/dist/web/standalone/.next/static/chunks/app/api/export-data/route-c4cc189e7b117ea2.js +1 -0
  307. package/dist/web/standalone/.next/static/chunks/app/api/files/route-c4cc189e7b117ea2.js +1 -0
  308. package/dist/web/standalone/.next/static/chunks/app/api/forensics/route-c4cc189e7b117ea2.js +1 -0
  309. package/dist/web/standalone/.next/static/chunks/app/api/git/route-c4cc189e7b117ea2.js +1 -0
  310. package/dist/web/standalone/.next/static/chunks/app/api/history/route-c4cc189e7b117ea2.js +1 -0
  311. package/dist/web/standalone/.next/static/chunks/app/api/hooks/route-c4cc189e7b117ea2.js +1 -0
  312. package/dist/web/standalone/.next/static/chunks/app/api/inspect/route-c4cc189e7b117ea2.js +1 -0
  313. package/dist/web/standalone/.next/static/chunks/app/api/knowledge/route-c4cc189e7b117ea2.js +1 -0
  314. package/dist/web/standalone/.next/static/chunks/app/api/live-state/route-c4cc189e7b117ea2.js +1 -0
  315. package/dist/web/standalone/.next/static/chunks/app/api/onboarding/route-c4cc189e7b117ea2.js +1 -0
  316. package/dist/web/standalone/.next/static/chunks/app/api/preferences/route-c4cc189e7b117ea2.js +1 -0
  317. package/dist/web/standalone/.next/static/chunks/app/api/projects/route-c4cc189e7b117ea2.js +1 -0
  318. package/dist/web/standalone/.next/static/chunks/app/api/recovery/route-c4cc189e7b117ea2.js +1 -0
  319. package/dist/web/standalone/.next/static/chunks/app/api/remote-questions/route-c4cc189e7b117ea2.js +1 -0
  320. package/dist/web/standalone/.next/static/chunks/app/api/session/browser/route-c4cc189e7b117ea2.js +1 -0
  321. package/dist/web/standalone/.next/static/chunks/app/api/session/command/route-c4cc189e7b117ea2.js +1 -0
  322. package/dist/web/standalone/.next/static/chunks/app/api/session/events/route-c4cc189e7b117ea2.js +1 -0
  323. package/dist/web/standalone/.next/static/chunks/app/api/session/manage/route-c4cc189e7b117ea2.js +1 -0
  324. package/dist/web/standalone/.next/static/chunks/app/api/settings-data/route-c4cc189e7b117ea2.js +1 -0
  325. package/dist/web/standalone/.next/static/chunks/app/api/shutdown/route-c4cc189e7b117ea2.js +1 -0
  326. package/dist/web/standalone/.next/static/chunks/app/api/skill-health/route-c4cc189e7b117ea2.js +1 -0
  327. package/dist/web/standalone/.next/static/chunks/app/api/steer/route-c4cc189e7b117ea2.js +1 -0
  328. package/dist/web/standalone/.next/static/chunks/app/api/switch-root/route-c4cc189e7b117ea2.js +1 -0
  329. package/dist/web/standalone/.next/static/chunks/app/api/terminal/input/route-c4cc189e7b117ea2.js +1 -0
  330. package/dist/web/standalone/.next/static/chunks/app/api/terminal/resize/route-c4cc189e7b117ea2.js +1 -0
  331. package/dist/web/standalone/.next/static/chunks/app/api/terminal/sessions/route-c4cc189e7b117ea2.js +1 -0
  332. package/dist/web/standalone/.next/static/chunks/app/api/terminal/stream/route-c4cc189e7b117ea2.js +1 -0
  333. package/dist/web/standalone/.next/static/chunks/app/api/terminal/upload/route-c4cc189e7b117ea2.js +1 -0
  334. package/dist/web/standalone/.next/static/chunks/app/api/undo/route-c4cc189e7b117ea2.js +1 -0
  335. package/dist/web/standalone/.next/static/chunks/app/api/update/route-c4cc189e7b117ea2.js +1 -0
  336. package/dist/web/standalone/.next/static/chunks/app/api/visualizer/route-c4cc189e7b117ea2.js +1 -0
  337. package/dist/web/standalone/.next/static/chunks/app/{layout-9ecfd95f343793f0.js → layout-a16c7a7ecdf0c2cf.js} +1 -1
  338. package/dist/web/standalone/.next/static/chunks/app/page-b950e4e384cc62b3.js +1 -0
  339. package/dist/web/standalone/.next/static/chunks/main-app-fdab67f7802d7832.js +1 -0
  340. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/app-error-c4cc189e7b117ea2.js +1 -0
  341. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/forbidden-c4cc189e7b117ea2.js +1 -0
  342. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +1 -0
  343. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/not-found-c4cc189e7b117ea2.js +1 -0
  344. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/unauthorized-c4cc189e7b117ea2.js +1 -0
  345. package/dist/web/standalone/.next/static/chunks/webpack-cfc9a116e6450a6b.js +1 -0
  346. package/dist/web/standalone/.next/static/css/de141508b083f922.css +1 -0
  347. package/dist/web/standalone/.next/static/yJIyd5cXPNpmXTv18ZlyC/_buildManifest.js +1 -0
  348. package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
  349. package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
  350. package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
  351. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api.target.mk +14 -14
  352. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_except.target.mk +14 -14
  353. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_maybe.target.mk +14 -14
  354. package/dist/web/standalone/server.js +1 -1
  355. package/package.json +1 -1
  356. package/packages/pi-agent-core/dist/agent-loop.d.ts.map +1 -1
  357. package/packages/pi-agent-core/dist/agent-loop.js +4 -1
  358. package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
  359. package/packages/pi-agent-core/src/agent-loop.ts +4 -1
  360. package/packages/pi-ai/dist/providers/openai-codex-responses.js +39 -10
  361. package/packages/pi-ai/dist/providers/openai-codex-responses.js.map +1 -1
  362. package/packages/pi-ai/dist/types.d.ts +1 -0
  363. package/packages/pi-ai/dist/types.d.ts.map +1 -1
  364. package/packages/pi-ai/dist/types.js.map +1 -1
  365. package/packages/pi-ai/src/providers/openai-codex-responses.ts +39 -8
  366. package/packages/pi-ai/src/types.ts +1 -1
  367. package/packages/pi-coding-agent/dist/core/agent-session.d.ts +1 -0
  368. package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
  369. package/packages/pi-coding-agent/dist/core/agent-session.js +1 -0
  370. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  371. package/packages/pi-coding-agent/dist/core/bash-executor.d.ts +3 -1
  372. package/packages/pi-coding-agent/dist/core/bash-executor.d.ts.map +1 -1
  373. package/packages/pi-coding-agent/dist/core/bash-executor.js +10 -1
  374. package/packages/pi-coding-agent/dist/core/bash-executor.js.map +1 -1
  375. package/packages/pi-coding-agent/dist/core/blob-store.d.ts.map +1 -1
  376. package/packages/pi-coding-agent/dist/core/blob-store.js +8 -3
  377. package/packages/pi-coding-agent/dist/core/blob-store.js.map +1 -1
  378. package/packages/pi-coding-agent/dist/core/discovery-cache.d.ts.map +1 -1
  379. package/packages/pi-coding-agent/dist/core/discovery-cache.js +9 -2
  380. package/packages/pi-coding-agent/dist/core/discovery-cache.js.map +1 -1
  381. package/packages/pi-coding-agent/dist/core/extensions/index.d.ts +1 -1
  382. package/packages/pi-coding-agent/dist/core/extensions/index.d.ts.map +1 -1
  383. package/packages/pi-coding-agent/dist/core/extensions/index.js.map +1 -1
  384. package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts +1 -0
  385. package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts.map +1 -1
  386. package/packages/pi-coding-agent/dist/core/extensions/runner.js +13 -0
  387. package/packages/pi-coding-agent/dist/core/extensions/runner.js.map +1 -1
  388. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts +19 -1
  389. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts.map +1 -1
  390. package/packages/pi-coding-agent/dist/core/extensions/types.js.map +1 -1
  391. package/packages/pi-coding-agent/dist/core/extensions/wrapper.d.ts.map +1 -1
  392. package/packages/pi-coding-agent/dist/core/extensions/wrapper.js +8 -0
  393. package/packages/pi-coding-agent/dist/core/extensions/wrapper.js.map +1 -1
  394. package/packages/pi-coding-agent/dist/core/package-manager.d.ts.map +1 -1
  395. package/packages/pi-coding-agent/dist/core/package-manager.js +8 -1
  396. package/packages/pi-coding-agent/dist/core/package-manager.js.map +1 -1
  397. package/packages/pi-coding-agent/dist/core/retry-handler.js +1 -1
  398. package/packages/pi-coding-agent/dist/core/retry-handler.js.map +1 -1
  399. package/packages/pi-coding-agent/dist/core/skills.d.ts +11 -1
  400. package/packages/pi-coding-agent/dist/core/skills.d.ts.map +1 -1
  401. package/packages/pi-coding-agent/dist/core/skills.js +30 -8
  402. package/packages/pi-coding-agent/dist/core/skills.js.map +1 -1
  403. package/packages/pi-coding-agent/dist/core/slash-commands.d.ts.map +1 -1
  404. package/packages/pi-coding-agent/dist/core/slash-commands.js +1 -0
  405. package/packages/pi-coding-agent/dist/core/slash-commands.js.map +1 -1
  406. package/packages/pi-coding-agent/dist/index.d.ts +2 -2
  407. package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
  408. package/packages/pi-coding-agent/dist/index.js +1 -1
  409. package/packages/pi-coding-agent/dist/index.js.map +1 -1
  410. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.d.ts.map +1 -1
  411. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js +3 -2
  412. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js.map +1 -1
  413. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  414. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +13 -36
  415. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  416. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.d.ts +5 -0
  417. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.d.ts.map +1 -1
  418. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.js +12 -0
  419. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.js.map +1 -1
  420. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.d.ts.map +1 -1
  421. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js +2 -1
  422. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js.map +1 -1
  423. package/packages/pi-coding-agent/dist/modes/rpc/jsonl.d.ts.map +1 -1
  424. package/packages/pi-coding-agent/dist/modes/rpc/jsonl.js +5 -0
  425. package/packages/pi-coding-agent/dist/modes/rpc/jsonl.js.map +1 -1
  426. package/packages/pi-coding-agent/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  427. package/packages/pi-coding-agent/dist/modes/rpc/rpc-client.js +0 -1
  428. package/packages/pi-coding-agent/dist/modes/rpc/rpc-client.js.map +1 -1
  429. package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.js +1 -1
  430. package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.js.map +1 -1
  431. package/packages/pi-coding-agent/package.json +1 -1
  432. package/packages/pi-coding-agent/src/core/agent-session.ts +2 -1
  433. package/packages/pi-coding-agent/src/core/bash-executor.ts +10 -2
  434. package/packages/pi-coding-agent/src/core/blob-store.ts +6 -3
  435. package/packages/pi-coding-agent/src/core/discovery-cache.ts +9 -2
  436. package/packages/pi-coding-agent/src/core/extensions/index.ts +2 -0
  437. package/packages/pi-coding-agent/src/core/extensions/runner.ts +18 -0
  438. package/packages/pi-coding-agent/src/core/extensions/types.ts +21 -0
  439. package/packages/pi-coding-agent/src/core/extensions/wrapper.ts +9 -0
  440. package/packages/pi-coding-agent/src/core/package-manager.ts +10 -1
  441. package/packages/pi-coding-agent/src/core/retry-handler.ts +1 -1
  442. package/packages/pi-coding-agent/src/core/skills.ts +35 -10
  443. package/packages/pi-coding-agent/src/core/slash-commands.ts +1 -0
  444. package/packages/pi-coding-agent/src/index.ts +4 -0
  445. package/packages/pi-coding-agent/src/modes/interactive/components/footer.ts +3 -2
  446. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +13 -36
  447. package/packages/pi-coding-agent/src/modes/interactive/slash-command-handlers.ts +15 -0
  448. package/packages/pi-coding-agent/src/modes/interactive/theme/themes.ts +2 -1
  449. package/packages/pi-coding-agent/src/modes/rpc/jsonl.ts +6 -0
  450. package/packages/pi-coding-agent/src/modes/rpc/rpc-client.ts +0 -2
  451. package/packages/pi-coding-agent/src/modes/rpc/rpc-mode.ts +2 -2
  452. package/pkg/dist/modes/interactive/theme/themes.d.ts.map +1 -1
  453. package/pkg/dist/modes/interactive/theme/themes.js +2 -1
  454. package/pkg/dist/modes/interactive/theme/themes.js.map +1 -1
  455. package/pkg/package.json +1 -1
  456. package/scripts/postinstall.js +163 -6
  457. package/src/resources/extensions/async-jobs/async-bash-tool.ts +3 -1
  458. package/src/resources/extensions/bg-shell/interaction.ts +3 -1
  459. package/src/resources/extensions/bg-shell/process-manager.ts +4 -1
  460. package/src/resources/extensions/claude-code-cli/partial-builder.ts +5 -0
  461. package/src/resources/extensions/claude-code-cli/tests/partial-builder.test.ts +105 -0
  462. package/src/resources/extensions/gsd/auto/infra-errors.ts +1 -0
  463. package/src/resources/extensions/gsd/auto/phases.ts +25 -12
  464. package/src/resources/extensions/gsd/auto/resolve.ts +3 -3
  465. package/src/resources/extensions/gsd/auto/run-unit.ts +2 -2
  466. package/src/resources/extensions/gsd/auto/session.ts +11 -0
  467. package/src/resources/extensions/gsd/auto/types.ts +13 -0
  468. package/src/resources/extensions/gsd/auto-artifact-paths.ts +19 -21
  469. package/src/resources/extensions/gsd/auto-dashboard.ts +36 -5
  470. package/src/resources/extensions/gsd/auto-dispatch.ts +122 -71
  471. package/src/resources/extensions/gsd/auto-loop.ts +1 -1
  472. package/src/resources/extensions/gsd/auto-observability.ts +72 -0
  473. package/src/resources/extensions/gsd/auto-post-unit.ts +73 -110
  474. package/src/resources/extensions/gsd/auto-prompts.ts +159 -17
  475. package/src/resources/extensions/gsd/auto-recovery.ts +80 -221
  476. package/src/resources/extensions/gsd/auto-start.ts +7 -27
  477. package/src/resources/extensions/gsd/auto-timers.ts +2 -2
  478. package/src/resources/extensions/gsd/auto-utils.ts +25 -0
  479. package/src/resources/extensions/gsd/auto-verification.ts +4 -7
  480. package/src/resources/extensions/gsd/auto-worktree.ts +305 -108
  481. package/src/resources/extensions/gsd/auto.ts +26 -15
  482. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +93 -0
  483. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +25 -0
  484. package/src/resources/extensions/gsd/branch-patterns.ts +16 -0
  485. package/src/resources/extensions/gsd/crash-recovery.ts +6 -2
  486. package/src/resources/extensions/gsd/custom-execution-policy.ts +3 -2
  487. package/src/resources/extensions/gsd/custom-verification.ts +3 -1
  488. package/src/resources/extensions/gsd/custom-workflow-engine.ts +3 -2
  489. package/src/resources/extensions/gsd/dashboard-overlay.ts +7 -0
  490. package/src/resources/extensions/gsd/detection.ts +662 -3
  491. package/src/resources/extensions/gsd/dispatch-guard.ts +2 -1
  492. package/src/resources/extensions/gsd/docs/preferences-reference.md +15 -0
  493. package/src/resources/extensions/gsd/doctor-checks.ts +5 -1291
  494. package/src/resources/extensions/gsd/doctor-engine-checks.ts +182 -0
  495. package/src/resources/extensions/gsd/doctor-environment.ts +30 -7
  496. package/src/resources/extensions/gsd/doctor-git-checks.ts +415 -0
  497. package/src/resources/extensions/gsd/doctor-global-checks.ts +84 -0
  498. package/src/resources/extensions/gsd/doctor-runtime-checks.ts +626 -0
  499. package/src/resources/extensions/gsd/doctor.ts +9 -1
  500. package/src/resources/extensions/gsd/extension-manifest.json +1 -1
  501. package/src/resources/extensions/gsd/files.ts +6 -1
  502. package/src/resources/extensions/gsd/git-service.ts +7 -15
  503. package/src/resources/extensions/gsd/gsd-db.ts +150 -2
  504. package/src/resources/extensions/gsd/guided-flow-queue.ts +11 -12
  505. package/src/resources/extensions/gsd/guided-flow.ts +11 -0
  506. package/src/resources/extensions/gsd/init-wizard.ts +9 -1
  507. package/src/resources/extensions/gsd/markdown-renderer.ts +37 -4
  508. package/src/resources/extensions/gsd/model-router.ts +25 -0
  509. package/src/resources/extensions/gsd/notifications.ts +23 -0
  510. package/src/resources/extensions/gsd/observability-validator.ts +456 -0
  511. package/src/resources/extensions/gsd/preferences-skills.ts +11 -5
  512. package/src/resources/extensions/gsd/preferences-types.ts +25 -1
  513. package/src/resources/extensions/gsd/preferences-validation.ts +63 -0
  514. package/src/resources/extensions/gsd/preferences.ts +3 -0
  515. package/src/resources/extensions/gsd/prompts/complete-milestone.md +27 -8
  516. package/src/resources/extensions/gsd/prompts/complete-slice.md +9 -8
  517. package/src/resources/extensions/gsd/prompts/execute-task.md +16 -13
  518. package/src/resources/extensions/gsd/prompts/forensics.md +19 -8
  519. package/src/resources/extensions/gsd/prompts/gate-evaluate.md +32 -0
  520. package/src/resources/extensions/gsd/prompts/guided-complete-slice.md +1 -1
  521. package/src/resources/extensions/gsd/prompts/guided-execute-task.md +1 -1
  522. package/src/resources/extensions/gsd/prompts/guided-plan-milestone.md +1 -1
  523. package/src/resources/extensions/gsd/prompts/guided-plan-slice.md +1 -1
  524. package/src/resources/extensions/gsd/prompts/plan-milestone.md +1 -1
  525. package/src/resources/extensions/gsd/prompts/plan-slice.md +8 -3
  526. package/src/resources/extensions/gsd/prompts/reassess-roadmap.md +3 -0
  527. package/src/resources/extensions/gsd/prompts/replan-slice.md +1 -1
  528. package/src/resources/extensions/gsd/prompts/validate-milestone.md +6 -1
  529. package/src/resources/extensions/gsd/provider-error-pause.ts +9 -0
  530. package/src/resources/extensions/gsd/repo-identity.ts +28 -0
  531. package/src/resources/extensions/gsd/roadmap-mutations.ts +134 -0
  532. package/src/resources/extensions/gsd/roadmap-slices.ts +2 -2
  533. package/src/resources/extensions/gsd/rtk-status.ts +53 -0
  534. package/src/resources/extensions/gsd/rule-registry.ts +10 -11
  535. package/src/resources/extensions/gsd/session-forensics.ts +13 -14
  536. package/src/resources/extensions/gsd/session-lock.ts +92 -64
  537. package/src/resources/extensions/gsd/skill-catalog.ts +1085 -0
  538. package/src/resources/extensions/gsd/skill-discovery.ts +3 -2
  539. package/src/resources/extensions/gsd/skill-health.ts +2 -2
  540. package/src/resources/extensions/gsd/skill-telemetry.ts +15 -5
  541. package/src/resources/extensions/gsd/state.ts +54 -10
  542. package/src/resources/extensions/gsd/templates/milestone-summary.md +8 -0
  543. package/src/resources/extensions/gsd/templates/milestone-validation.md +12 -0
  544. package/src/resources/extensions/gsd/templates/plan.md +16 -0
  545. package/src/resources/extensions/gsd/templates/preferences.md +2 -0
  546. package/src/resources/extensions/gsd/templates/roadmap.md +13 -0
  547. package/src/resources/extensions/gsd/templates/slice-summary.md +9 -0
  548. package/src/resources/extensions/gsd/templates/task-plan.md +24 -0
  549. package/src/resources/extensions/gsd/tests/agent-end-retry.test.ts +2 -2
  550. package/src/resources/extensions/gsd/tests/auto-dashboard.test.ts +16 -0
  551. package/src/resources/extensions/gsd/tests/auto-lock-creation.test.ts +2 -2
  552. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +103 -0
  553. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +1 -81
  554. package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +2 -2
  555. package/src/resources/extensions/gsd/tests/complete-slice.test.ts +2 -2
  556. package/src/resources/extensions/gsd/tests/complete-task.test.ts +2 -2
  557. package/src/resources/extensions/gsd/tests/completed-units-metrics-sync.test.ts +9 -12
  558. package/src/resources/extensions/gsd/tests/crash-recovery.test.ts +5 -3
  559. package/src/resources/extensions/gsd/tests/custom-verification.test.ts +33 -0
  560. package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +4 -3
  561. package/src/resources/extensions/gsd/tests/detection.test.ts +838 -0
  562. package/src/resources/extensions/gsd/tests/dist-redirect.mjs +28 -9
  563. package/src/resources/extensions/gsd/tests/doctor-environment.test.ts +115 -1
  564. package/src/resources/extensions/gsd/tests/doctor-fixlevel.test.ts +65 -1
  565. package/src/resources/extensions/gsd/tests/doctor-git.test.ts +50 -0
  566. package/src/resources/extensions/gsd/tests/double-merge-guard.test.ts +97 -0
  567. package/src/resources/extensions/gsd/tests/gate-dispatch.test.ts +189 -0
  568. package/src/resources/extensions/gsd/tests/gate-storage.test.ts +156 -0
  569. package/src/resources/extensions/gsd/tests/git-service.test.ts +49 -0
  570. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +1 -1
  571. package/src/resources/extensions/gsd/tests/idle-recovery.test.ts +63 -0
  572. package/src/resources/extensions/gsd/tests/infra-error.test.ts +12 -2
  573. package/src/resources/extensions/gsd/tests/journal-integration.test.ts +39 -0
  574. package/src/resources/extensions/gsd/tests/md-importer.test.ts +1 -1
  575. package/src/resources/extensions/gsd/tests/memory-store.test.ts +2 -2
  576. package/src/resources/extensions/gsd/tests/model-router.test.ts +40 -0
  577. package/src/resources/extensions/gsd/tests/notifications.test.ts +28 -6
  578. package/src/resources/extensions/gsd/tests/plan-quality-validator.test.ts +474 -0
  579. package/src/resources/extensions/gsd/tests/preferences.test.ts +50 -0
  580. package/src/resources/extensions/gsd/tests/quality-gates.test.ts +347 -0
  581. package/src/resources/extensions/gsd/tests/queue-completed-milestone-perf.test.ts +155 -0
  582. package/src/resources/extensions/gsd/tests/queue-reorder-e2e.test.ts +40 -0
  583. package/src/resources/extensions/gsd/tests/reactive-executor.test.ts +6 -6
  584. package/src/resources/extensions/gsd/tests/replan-slice.test.ts +2 -1
  585. package/src/resources/extensions/gsd/tests/repo-identity-worktree.test.ts +32 -0
  586. package/src/resources/extensions/gsd/tests/retry-diagnostic-reasoning.test.ts +161 -0
  587. package/src/resources/extensions/gsd/tests/retry-state-reset.test.ts +4 -5
  588. package/src/resources/extensions/gsd/tests/rewrite-count-persist.test.ts +82 -0
  589. package/src/resources/extensions/gsd/tests/roadmap-slices.test.ts +26 -0
  590. package/src/resources/extensions/gsd/tests/run-uat.test.ts +166 -16
  591. package/src/resources/extensions/gsd/tests/session-lock-transient-read.test.ts +223 -0
  592. package/src/resources/extensions/gsd/tests/sidecar-queue.test.ts +12 -12
  593. package/src/resources/extensions/gsd/tests/skill-activation.test.ts +44 -4
  594. package/src/resources/extensions/gsd/tests/skill-catalog.test.ts +193 -0
  595. package/src/resources/extensions/gsd/tests/terminated-transient.test.ts +24 -0
  596. package/src/resources/extensions/gsd/tests/tool-naming.test.ts +1 -1
  597. package/src/resources/extensions/gsd/tests/triage-dispatch.test.ts +2 -2
  598. package/src/resources/extensions/gsd/tests/validate-milestone.test.ts +2 -1
  599. package/src/resources/extensions/gsd/tests/verification-gate.test.ts +0 -16
  600. package/src/resources/extensions/gsd/tests/worktree-resolver.test.ts +67 -0
  601. package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +1 -1
  602. package/src/resources/extensions/gsd/tests/worktree-sync-overwrite-loop.test.ts +204 -0
  603. package/src/resources/extensions/gsd/tools/plan-slice.ts +16 -0
  604. package/src/resources/extensions/gsd/tools/validate-milestone.ts +3 -3
  605. package/src/resources/extensions/gsd/types.ts +32 -0
  606. package/src/resources/extensions/gsd/undo.ts +8 -7
  607. package/src/resources/extensions/gsd/unit-runtime.ts +2 -1
  608. package/src/resources/extensions/gsd/verdict-parser.ts +95 -0
  609. package/src/resources/extensions/gsd/verification-gate.ts +3 -3
  610. package/src/resources/extensions/gsd/worktree-resolver.ts +31 -0
  611. package/src/resources/extensions/gsd/worktree.ts +3 -2
  612. package/src/resources/extensions/remote-questions/config.ts +3 -5
  613. package/src/resources/extensions/search-the-web/native-search.ts +8 -3
  614. package/src/resources/extensions/search-the-web/tool-search.ts +22 -2
  615. package/src/resources/extensions/shared/rtk-session-stats.ts +249 -0
  616. package/src/resources/extensions/shared/rtk.ts +120 -0
  617. package/src/resources/skills/github-workflows/references/gh/SKILL.md +22 -1
  618. package/dist/resources/extensions/gsd/auto-worktree-sync.js +0 -191
  619. package/dist/resources/extensions/gsd/resource-version.js +0 -97
  620. package/dist/web/standalone/.next/server/chunks/229.js +0 -12
  621. package/dist/web/standalone/.next/server/chunks/441.js +0 -2
  622. package/dist/web/standalone/.next/server/chunks/471.js +0 -13
  623. package/dist/web/standalone/.next/static/chunks/4024.11ca5c01938e5948.js +0 -9
  624. package/dist/web/standalone/.next/static/chunks/app/_global-error/page-d83ba70a25a85472.js +0 -1
  625. package/dist/web/standalone/.next/static/chunks/app/api/boot/route-d83ba70a25a85472.js +0 -1
  626. package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/input/route-d83ba70a25a85472.js +0 -1
  627. package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/resize/route-d83ba70a25a85472.js +0 -1
  628. package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/stream/route-d83ba70a25a85472.js +0 -1
  629. package/dist/web/standalone/.next/static/chunks/app/api/browse-directories/route-d83ba70a25a85472.js +0 -1
  630. package/dist/web/standalone/.next/static/chunks/app/api/captures/route-d83ba70a25a85472.js +0 -1
  631. package/dist/web/standalone/.next/static/chunks/app/api/cleanup/route-d83ba70a25a85472.js +0 -1
  632. package/dist/web/standalone/.next/static/chunks/app/api/dev-mode/route-d83ba70a25a85472.js +0 -1
  633. package/dist/web/standalone/.next/static/chunks/app/api/doctor/route-d83ba70a25a85472.js +0 -1
  634. package/dist/web/standalone/.next/static/chunks/app/api/export-data/route-d83ba70a25a85472.js +0 -1
  635. package/dist/web/standalone/.next/static/chunks/app/api/files/route-d83ba70a25a85472.js +0 -1
  636. package/dist/web/standalone/.next/static/chunks/app/api/forensics/route-d83ba70a25a85472.js +0 -1
  637. package/dist/web/standalone/.next/static/chunks/app/api/git/route-d83ba70a25a85472.js +0 -1
  638. package/dist/web/standalone/.next/static/chunks/app/api/history/route-d83ba70a25a85472.js +0 -1
  639. package/dist/web/standalone/.next/static/chunks/app/api/hooks/route-d83ba70a25a85472.js +0 -1
  640. package/dist/web/standalone/.next/static/chunks/app/api/inspect/route-d83ba70a25a85472.js +0 -1
  641. package/dist/web/standalone/.next/static/chunks/app/api/knowledge/route-d83ba70a25a85472.js +0 -1
  642. package/dist/web/standalone/.next/static/chunks/app/api/live-state/route-d83ba70a25a85472.js +0 -1
  643. package/dist/web/standalone/.next/static/chunks/app/api/onboarding/route-d83ba70a25a85472.js +0 -1
  644. package/dist/web/standalone/.next/static/chunks/app/api/preferences/route-d83ba70a25a85472.js +0 -1
  645. package/dist/web/standalone/.next/static/chunks/app/api/projects/route-d83ba70a25a85472.js +0 -1
  646. package/dist/web/standalone/.next/static/chunks/app/api/recovery/route-d83ba70a25a85472.js +0 -1
  647. package/dist/web/standalone/.next/static/chunks/app/api/remote-questions/route-d83ba70a25a85472.js +0 -1
  648. package/dist/web/standalone/.next/static/chunks/app/api/session/browser/route-d83ba70a25a85472.js +0 -1
  649. package/dist/web/standalone/.next/static/chunks/app/api/session/command/route-d83ba70a25a85472.js +0 -1
  650. package/dist/web/standalone/.next/static/chunks/app/api/session/events/route-d83ba70a25a85472.js +0 -1
  651. package/dist/web/standalone/.next/static/chunks/app/api/session/manage/route-d83ba70a25a85472.js +0 -1
  652. package/dist/web/standalone/.next/static/chunks/app/api/settings-data/route-d83ba70a25a85472.js +0 -1
  653. package/dist/web/standalone/.next/static/chunks/app/api/shutdown/route-d83ba70a25a85472.js +0 -1
  654. package/dist/web/standalone/.next/static/chunks/app/api/skill-health/route-d83ba70a25a85472.js +0 -1
  655. package/dist/web/standalone/.next/static/chunks/app/api/steer/route-d83ba70a25a85472.js +0 -1
  656. package/dist/web/standalone/.next/static/chunks/app/api/switch-root/route-d83ba70a25a85472.js +0 -1
  657. package/dist/web/standalone/.next/static/chunks/app/api/terminal/input/route-d83ba70a25a85472.js +0 -1
  658. package/dist/web/standalone/.next/static/chunks/app/api/terminal/resize/route-d83ba70a25a85472.js +0 -1
  659. package/dist/web/standalone/.next/static/chunks/app/api/terminal/sessions/route-d83ba70a25a85472.js +0 -1
  660. package/dist/web/standalone/.next/static/chunks/app/api/terminal/stream/route-d83ba70a25a85472.js +0 -1
  661. package/dist/web/standalone/.next/static/chunks/app/api/terminal/upload/route-d83ba70a25a85472.js +0 -1
  662. package/dist/web/standalone/.next/static/chunks/app/api/undo/route-d83ba70a25a85472.js +0 -1
  663. package/dist/web/standalone/.next/static/chunks/app/api/update/route-d83ba70a25a85472.js +0 -1
  664. package/dist/web/standalone/.next/static/chunks/app/api/visualizer/route-d83ba70a25a85472.js +0 -1
  665. package/dist/web/standalone/.next/static/chunks/app/page-12dd5ece0df4badc.js +0 -1
  666. package/dist/web/standalone/.next/static/chunks/main-app-d3d4c336195465f9.js +0 -1
  667. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/app-error-d83ba70a25a85472.js +0 -1
  668. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/forbidden-d83ba70a25a85472.js +0 -1
  669. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ab5a8926e07ec673.js +0 -1
  670. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/not-found-d83ba70a25a85472.js +0 -1
  671. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/unauthorized-d83ba70a25a85472.js +0 -1
  672. package/dist/web/standalone/.next/static/chunks/webpack-0a4cd455ec4197d2.js +0 -1
  673. package/dist/web/standalone/.next/static/css/dd4ae3f58ac9b600.css +0 -1
  674. package/dist/web/standalone/.next/static/gj-y5hikmhS--NT8Web6M/_buildManifest.js +0 -1
  675. package/packages/pi-ai/pnpm-lock.yaml +0 -2022
  676. package/packages/pi-coding-agent/pnpm-lock.yaml +0 -454
  677. package/src/resources/extensions/gsd/auto-worktree-sync.ts +0 -234
  678. package/src/resources/extensions/gsd/resource-version.ts +0 -101
  679. /package/dist/web/standalone/.next/static/{gj-y5hikmhS--NT8Web6M → yJIyd5cXPNpmXTv18ZlyC}/_ssgManifest.js +0 -0
@@ -6,7 +6,8 @@
6
6
  * manages create, enter, detect, and teardown for auto-mode worktrees.
7
7
  */
8
8
  import { existsSync, cpSync, readFileSync, readdirSync, mkdirSync, realpathSync, rmSync, unlinkSync, lstatSync as lstatSyncFn, } from "node:fs";
9
- import { isAbsolute, join } from "node:path";
9
+ import { isAbsolute, join, sep as pathSep } from "node:path";
10
+ import { homedir } from "node:os";
10
11
  import { GSDError, GSD_IO_ERROR, GSD_GIT_ERROR } from "./errors.js";
11
12
  import { reconcileWorktreeDb, isDbAvailable, getMilestone, getMilestoneSlices, } from "./gsd-db.js";
12
13
  import { atomicWriteSync } from "./atomic-write.js";
@@ -20,6 +21,35 @@ import { debugLog } from "./debug-logger.js";
20
21
  import { logWarning } from "./workflow-logger.js";
21
22
  import { loadEffectiveGSDPreferences } from "./preferences.js";
22
23
  import { nativeGetCurrentBranch, nativeDetectMainBranch, nativeWorkingTreeStatus, nativeAddAllWithExclusions, nativeCommit, nativeCheckoutBranch, nativeMergeSquash, nativeConflictFiles, nativeCheckoutTheirs, nativeAddPaths, nativeRmForce, nativeBranchDelete, nativeBranchExists, nativeDiffNumstat, nativeUpdateRef, nativeIsAncestor, } from "./native-git-bridge.js";
24
+ const gsdHome = process.env.GSD_HOME || join(homedir(), ".gsd");
25
+ // ─── Shared Constants & Helpers ─────────────────────────────────────────────
26
+ /**
27
+ * Root-level .gsd/ state files synced between worktree and project root.
28
+ * Single source of truth — used by syncGsdStateToWorktree, syncWorktreeStateBack,
29
+ * and the dispatch-level sync functions.
30
+ */
31
+ const ROOT_STATE_FILES = [
32
+ "DECISIONS.md",
33
+ "REQUIREMENTS.md",
34
+ "PROJECT.md",
35
+ "KNOWLEDGE.md",
36
+ "OVERRIDES.md",
37
+ "QUEUE.md",
38
+ "completed-units.json",
39
+ "metrics.json",
40
+ ];
41
+ /**
42
+ * Check if two filesystem paths resolve to the same real location.
43
+ * Returns false if either path cannot be resolved (e.g. doesn't exist).
44
+ */
45
+ function isSamePath(a, b) {
46
+ try {
47
+ return realpathSync(a) === realpathSync(b);
48
+ }
49
+ catch {
50
+ return false;
51
+ }
52
+ }
23
53
  // ─── Module State ──────────────────────────────────────────────────────────
24
54
  /** Original project root before chdir into auto-worktree. */
25
55
  let originalBase = null;
@@ -70,6 +100,187 @@ function clearProjectRootStateFiles(basePath, milestoneId) {
70
100
  }
71
101
  }
72
102
  }
103
+ // ─── Dispatch-Level Sync (project root ↔ worktree) ──────────────────────────
104
+ /**
105
+ * Sync milestone artifacts from project root INTO worktree before deriveState.
106
+ * Covers the case where the LLM wrote artifacts to the main repo filesystem
107
+ * (e.g. via absolute paths) but the worktree has stale data. Also deletes
108
+ * gsd.db in the worktree so it rebuilds from fresh disk state (#853).
109
+ * Non-fatal — sync failure should never block dispatch.
110
+ */
111
+ export function syncProjectRootToWorktree(projectRoot, worktreePath_, milestoneId) {
112
+ if (!worktreePath_ || !projectRoot || worktreePath_ === projectRoot)
113
+ return;
114
+ if (!milestoneId)
115
+ return;
116
+ const prGsd = join(projectRoot, ".gsd");
117
+ const wtGsd = join(worktreePath_, ".gsd");
118
+ // Copy milestone directory from project root to worktree — additive only.
119
+ // force:false prevents cpSync from overwriting existing worktree files.
120
+ // Without this, worktree-authoritative files (e.g. VALIDATION.md written
121
+ // by validate-milestone) get clobbered by stale project root copies,
122
+ // causing an infinite re-validation loop (#1886).
123
+ safeCopyRecursive(join(prGsd, "milestones", milestoneId), join(wtGsd, "milestones", milestoneId), { force: false });
124
+ // Forward-sync completed-units.json from project root to worktree.
125
+ // Project root is authoritative for completion state after crash recovery;
126
+ // without this, the worktree re-dispatches already-completed units (#1886).
127
+ safeCopy(join(prGsd, "completed-units.json"), join(wtGsd, "completed-units.json"), { force: true });
128
+ // Delete worktree gsd.db so it rebuilds from the freshly synced files.
129
+ // Stale DB rows are the root cause of the infinite skip loop (#853).
130
+ try {
131
+ const wtDb = join(wtGsd, "gsd.db");
132
+ if (existsSync(wtDb)) {
133
+ unlinkSync(wtDb);
134
+ }
135
+ }
136
+ catch {
137
+ /* non-fatal */
138
+ }
139
+ }
140
+ /**
141
+ * Sync dispatch-critical .gsd/ state files from worktree to project root.
142
+ * Only runs when inside an auto-worktree (worktreePath differs from projectRoot).
143
+ * Copies: STATE.md + active milestone directory (roadmap, slice plans, task summaries).
144
+ * Non-fatal — sync failure should never block dispatch.
145
+ */
146
+ export function syncStateToProjectRoot(worktreePath_, projectRoot, milestoneId) {
147
+ if (!worktreePath_ || !projectRoot || worktreePath_ === projectRoot)
148
+ return;
149
+ if (!milestoneId)
150
+ return;
151
+ const wtGsd = join(worktreePath_, ".gsd");
152
+ const prGsd = join(projectRoot, ".gsd");
153
+ // 1. STATE.md — the quick-glance status used by initial deriveState()
154
+ safeCopy(join(wtGsd, "STATE.md"), join(prGsd, "STATE.md"), { force: true });
155
+ // 2. Milestone directory — ROADMAP, slice PLANs, task summaries
156
+ // Copy the entire milestone .gsd subtree so deriveState reads current checkboxes
157
+ safeCopyRecursive(join(wtGsd, "milestones", milestoneId), join(prGsd, "milestones", milestoneId), { force: true });
158
+ // 3. metrics.json — session cost/token tracking (#2313).
159
+ // Without this, metrics accumulated in the worktree are invisible from the
160
+ // project root and never appear in the dashboard or skill-health reports.
161
+ safeCopy(join(wtGsd, "metrics.json"), join(prGsd, "metrics.json"), { force: true });
162
+ // 4. Runtime records — unit dispatch state used by selfHealRuntimeRecords().
163
+ // Without this, a crash during a unit leaves the runtime record only in the
164
+ // worktree. If the next session resolves basePath before worktree re-entry,
165
+ // selfHeal can't find or clear the stale record (#769).
166
+ safeCopyRecursive(join(wtGsd, "runtime", "units"), join(prGsd, "runtime", "units"), { force: true });
167
+ }
168
+ // ─── Resource Staleness ───────────────────────────────────────────────────
169
+ /**
170
+ * Read the resource version (semver) from the managed-resources manifest.
171
+ * Uses gsdVersion instead of syncedAt so that launching a second session
172
+ * doesn't falsely trigger staleness (#804).
173
+ */
174
+ export function readResourceVersion() {
175
+ const agentDir = process.env.GSD_CODING_AGENT_DIR || join(gsdHome, "agent");
176
+ const manifestPath = join(agentDir, "managed-resources.json");
177
+ try {
178
+ const manifest = JSON.parse(readFileSync(manifestPath, "utf-8"));
179
+ return typeof manifest?.gsdVersion === "string"
180
+ ? manifest.gsdVersion
181
+ : null;
182
+ }
183
+ catch {
184
+ return null;
185
+ }
186
+ }
187
+ /**
188
+ * Check if managed resources have been updated since session start.
189
+ * Returns a warning message if stale, null otherwise.
190
+ */
191
+ export function checkResourcesStale(versionOnStart) {
192
+ if (versionOnStart === null)
193
+ return null;
194
+ const current = readResourceVersion();
195
+ if (current === null)
196
+ return null;
197
+ if (current !== versionOnStart) {
198
+ return "GSD resources were updated since this session started. Restart gsd to load the new code.";
199
+ }
200
+ return null;
201
+ }
202
+ // ─── Stale Worktree Escape ────────────────────────────────────────────────
203
+ /**
204
+ * Detect and escape a stale worktree cwd (#608).
205
+ *
206
+ * After milestone completion + merge, the worktree directory is removed but
207
+ * the process cwd may still point inside `.gsd/worktrees/<MID>/`.
208
+ * When a new session starts, `process.cwd()` is passed as `base` to startAuto
209
+ * and all subsequent writes land in the wrong directory. This function detects
210
+ * that scenario and chdir back to the project root.
211
+ *
212
+ * Returns the corrected base path.
213
+ */
214
+ export function escapeStaleWorktree(base) {
215
+ // Direct layout: /.gsd/worktrees/
216
+ const directMarker = `${pathSep}.gsd${pathSep}worktrees${pathSep}`;
217
+ let idx = base.indexOf(directMarker);
218
+ if (idx === -1) {
219
+ // Symlink-resolved layout: /.gsd/projects/<hash>/worktrees/
220
+ const symlinkRe = new RegExp(`\\${pathSep}\\.gsd\\${pathSep}projects\\${pathSep}[a-f0-9]+\\${pathSep}worktrees\\${pathSep}`);
221
+ const match = base.match(symlinkRe);
222
+ if (!match || match.index === undefined)
223
+ return base;
224
+ idx = match.index;
225
+ }
226
+ // base is inside .gsd/worktrees/<something> — extract the project root
227
+ const projectRoot = base.slice(0, idx);
228
+ // Guard: If the candidate project root's .gsd IS the user-level ~/.gsd,
229
+ // the string-slice heuristic matched the wrong /.gsd/ boundary. This happens
230
+ // when .gsd is a symlink into ~/.gsd/projects/<hash> and process.cwd()
231
+ // resolved through the symlink. Returning ~ would be catastrophic (#1676).
232
+ const candidateGsd = join(projectRoot, ".gsd").replaceAll("\\", "/");
233
+ const gsdHomePath = gsdHome.replaceAll("\\", "/");
234
+ if (candidateGsd === gsdHomePath || candidateGsd.startsWith(gsdHomePath + "/")) {
235
+ // Don't chdir to home — return base unchanged.
236
+ // resolveProjectRoot() in worktree.ts has the full git-file-based recovery
237
+ // and will be called by the caller (startAuto → projectRoot()).
238
+ return base;
239
+ }
240
+ try {
241
+ process.chdir(projectRoot);
242
+ }
243
+ catch {
244
+ // If chdir fails, return the original — caller will handle errors downstream
245
+ return base;
246
+ }
247
+ return projectRoot;
248
+ }
249
+ /**
250
+ * Clean stale runtime unit files for completed milestones.
251
+ *
252
+ * After restart, stale runtime/units/*.json from prior milestones can
253
+ * cause deriveState to resume the wrong milestone (#887). Removes files
254
+ * for milestones that have a SUMMARY (fully complete).
255
+ */
256
+ export function cleanStaleRuntimeUnits(gsdRootPath, hasMilestoneSummary) {
257
+ const runtimeUnitsDir = join(gsdRootPath, "runtime", "units");
258
+ if (!existsSync(runtimeUnitsDir))
259
+ return 0;
260
+ let cleaned = 0;
261
+ try {
262
+ for (const file of readdirSync(runtimeUnitsDir)) {
263
+ if (!file.endsWith(".json"))
264
+ continue;
265
+ const midMatch = file.match(/(M\d+(?:-[a-z0-9]{6})?)/);
266
+ if (!midMatch)
267
+ continue;
268
+ if (hasMilestoneSummary(midMatch[1])) {
269
+ try {
270
+ unlinkSync(join(runtimeUnitsDir, file));
271
+ cleaned++;
272
+ }
273
+ catch {
274
+ /* non-fatal */
275
+ }
276
+ }
277
+ }
278
+ }
279
+ catch {
280
+ /* non-fatal */
281
+ }
282
+ return cleaned;
283
+ }
73
284
  // ─── Worktree ↔ Main Repo Sync (#1311) ──────────────────────────────────────
74
285
  /**
75
286
  * Sync .gsd/ state from the main repo into the worktree.
@@ -90,29 +301,12 @@ export function syncGsdStateToWorktree(mainBasePath, worktreePath_) {
90
301
  const wtGsd = gsdRoot(worktreePath_);
91
302
  const synced = [];
92
303
  // If both resolve to the same directory (symlink), no sync needed
93
- try {
94
- const mainResolved = realpathSync(mainGsd);
95
- const wtResolved = realpathSync(wtGsd);
96
- if (mainResolved === wtResolved)
97
- return { synced };
98
- }
99
- catch {
100
- // Can't resolve — proceed with sync as a safety measure
101
- }
304
+ if (isSamePath(mainGsd, wtGsd))
305
+ return { synced };
102
306
  if (!existsSync(mainGsd) || !existsSync(wtGsd))
103
307
  return { synced };
104
308
  // Sync root-level .gsd/ files (DECISIONS, REQUIREMENTS, PROJECT, KNOWLEDGE, etc.)
105
- const rootFiles = [
106
- "DECISIONS.md",
107
- "REQUIREMENTS.md",
108
- "PROJECT.md",
109
- "KNOWLEDGE.md",
110
- "OVERRIDES.md",
111
- "QUEUE.md",
112
- "completed-units.json",
113
- "metrics.json",
114
- ];
115
- for (const f of rootFiles) {
309
+ for (const f of ROOT_STATE_FILES) {
116
310
  const src = join(mainGsd, f);
117
311
  const dst = join(wtGsd, f);
118
312
  if (existsSync(src) && !existsSync(dst)) {
@@ -241,15 +435,8 @@ export function syncWorktreeStateBack(mainBasePath, worktreePath, milestoneId) {
241
435
  const wtGsd = gsdRoot(worktreePath);
242
436
  const synced = [];
243
437
  // If both resolve to the same directory (symlink), no sync needed
244
- try {
245
- const mainResolved = realpathSync(mainGsd);
246
- const wtResolved = realpathSync(wtGsd);
247
- if (mainResolved === wtResolved)
248
- return { synced };
249
- }
250
- catch {
251
- // Can't resolve — proceed with sync
252
- }
438
+ if (isSamePath(mainGsd, wtGsd))
439
+ return { synced };
253
440
  if (!existsSync(wtGsd) || !existsSync(mainGsd))
254
441
  return { synced };
255
442
  // ── 0. Pre-upgrade worktree DB reconciliation ────────────────────────
@@ -274,17 +461,7 @@ export function syncWorktreeStateBack(mainBasePath, worktreePath, milestoneId) {
274
461
  // Also includes QUEUE.md, completed-units.json, and metrics.json which are
275
462
  // written during milestone closeout and lost on teardown without explicit sync
276
463
  // (#1787, #2313).
277
- const rootFiles = [
278
- "DECISIONS.md",
279
- "REQUIREMENTS.md",
280
- "PROJECT.md",
281
- "KNOWLEDGE.md",
282
- "OVERRIDES.md",
283
- "QUEUE.md",
284
- "completed-units.json",
285
- "metrics.json",
286
- ];
287
- for (const f of rootFiles) {
464
+ for (const f of ROOT_STATE_FILES) {
288
465
  const src = join(wtGsd, f);
289
466
  const dst = join(mainGsd, f);
290
467
  if (existsSync(src)) {
@@ -321,92 +498,59 @@ export function syncWorktreeStateBack(mainBasePath, worktreePath, milestoneId) {
321
498
  * Sync a single milestone directory from worktree to main.
322
499
  * Copies milestone-level .md files, slice-level files, and task summaries.
323
500
  */
501
+ /** Copy matching files from srcDir to dstDir (non-fatal per file). */
502
+ function syncDirFiles(srcDir, dstDir, filter, synced, prefix) {
503
+ try {
504
+ for (const entry of readdirSync(srcDir, { withFileTypes: true })) {
505
+ if (!entry.isFile() || !filter(entry.name))
506
+ continue;
507
+ try {
508
+ cpSync(join(srcDir, entry.name), join(dstDir, entry.name), { force: true });
509
+ synced.push(`${prefix}${entry.name}`);
510
+ }
511
+ catch {
512
+ /* non-fatal */
513
+ }
514
+ }
515
+ }
516
+ catch {
517
+ /* non-fatal — srcDir may not be readable */
518
+ }
519
+ }
324
520
  function syncMilestoneDir(wtGsd, mainGsd, mid, synced) {
325
521
  const wtMilestoneDir = join(wtGsd, "milestones", mid);
326
522
  const mainMilestoneDir = join(mainGsd, "milestones", mid);
327
523
  if (!existsSync(wtMilestoneDir))
328
524
  return;
329
525
  mkdirSync(mainMilestoneDir, { recursive: true });
526
+ const isMd = (name) => name.endsWith(".md");
330
527
  // Sync milestone-level files (SUMMARY, VALIDATION, ROADMAP, CONTEXT)
528
+ syncDirFiles(wtMilestoneDir, mainMilestoneDir, isMd, synced, `milestones/${mid}/`);
529
+ // Sync slice-level files (summaries, UATs) and task summaries (#1678)
530
+ const wtSlicesDir = join(wtMilestoneDir, "slices");
531
+ const mainSlicesDir = join(mainMilestoneDir, "slices");
532
+ if (!existsSync(wtSlicesDir))
533
+ return;
331
534
  try {
332
- for (const entry of readdirSync(wtMilestoneDir, { withFileTypes: true })) {
333
- if (entry.isFile() && entry.name.endsWith(".md")) {
334
- const src = join(wtMilestoneDir, entry.name);
335
- const dst = join(mainMilestoneDir, entry.name);
336
- try {
337
- cpSync(src, dst, { force: true });
338
- synced.push(`milestones/${mid}/${entry.name}`);
339
- }
340
- catch {
341
- /* non-fatal */
342
- }
535
+ for (const sliceEntry of readdirSync(wtSlicesDir, { withFileTypes: true })) {
536
+ if (!sliceEntry.isDirectory())
537
+ continue;
538
+ const sid = sliceEntry.name;
539
+ const wtSliceDir = join(wtSlicesDir, sid);
540
+ const mainSliceDir = join(mainSlicesDir, sid);
541
+ mkdirSync(mainSliceDir, { recursive: true });
542
+ syncDirFiles(wtSliceDir, mainSliceDir, isMd, synced, `milestones/${mid}/slices/${sid}/`);
543
+ const wtTasksDir = join(wtSliceDir, "tasks");
544
+ const mainTasksDir = join(mainSliceDir, "tasks");
545
+ if (existsSync(wtTasksDir)) {
546
+ mkdirSync(mainTasksDir, { recursive: true });
547
+ syncDirFiles(wtTasksDir, mainTasksDir, isMd, synced, `milestones/${mid}/slices/${sid}/tasks/`);
343
548
  }
344
549
  }
345
550
  }
346
551
  catch {
347
552
  /* non-fatal */
348
553
  }
349
- // Sync slice-level files (summaries, UATs)
350
- const wtSlicesDir = join(wtMilestoneDir, "slices");
351
- const mainSlicesDir = join(mainMilestoneDir, "slices");
352
- if (existsSync(wtSlicesDir)) {
353
- try {
354
- for (const sliceEntry of readdirSync(wtSlicesDir, {
355
- withFileTypes: true,
356
- })) {
357
- if (!sliceEntry.isDirectory())
358
- continue;
359
- const sid = sliceEntry.name;
360
- const wtSliceDir = join(wtSlicesDir, sid);
361
- const mainSliceDir = join(mainSlicesDir, sid);
362
- mkdirSync(mainSliceDir, { recursive: true });
363
- for (const fileEntry of readdirSync(wtSliceDir, {
364
- withFileTypes: true,
365
- })) {
366
- if (fileEntry.isFile() && fileEntry.name.endsWith(".md")) {
367
- const src = join(wtSliceDir, fileEntry.name);
368
- const dst = join(mainSliceDir, fileEntry.name);
369
- try {
370
- cpSync(src, dst, { force: true });
371
- synced.push(`milestones/${mid}/slices/${sid}/${fileEntry.name}`);
372
- }
373
- catch {
374
- /* non-fatal */
375
- }
376
- }
377
- else if (fileEntry.isDirectory() && fileEntry.name === "tasks") {
378
- // Recurse into tasks/ subdirectory to sync task summaries (#1678).
379
- // Without this, T01-SUMMARY.md etc. are silently dropped on
380
- // worktree teardown because the loop only processes isFile() entries.
381
- const wtTasksDir = join(wtSliceDir, "tasks");
382
- const mainTasksDir = join(mainSliceDir, "tasks");
383
- mkdirSync(mainTasksDir, { recursive: true });
384
- try {
385
- for (const taskEntry of readdirSync(wtTasksDir, { withFileTypes: true })) {
386
- if (taskEntry.isFile() && taskEntry.name.endsWith(".md")) {
387
- const taskSrc = join(wtTasksDir, taskEntry.name);
388
- const taskDst = join(mainTasksDir, taskEntry.name);
389
- try {
390
- cpSync(taskSrc, taskDst, { force: true });
391
- synced.push(`milestones/${mid}/slices/${sid}/tasks/${taskEntry.name}`);
392
- }
393
- catch {
394
- /* non-fatal */
395
- }
396
- }
397
- }
398
- }
399
- catch {
400
- /* non-fatal: tasks dir read failure */
401
- }
402
- }
403
- }
404
- }
405
- }
406
- catch {
407
- /* non-fatal */
408
- }
409
- }
410
554
  }
411
555
  // ─── Worktree Post-Create Hook (#597) ────────────────────────────────────────
412
556
  /**
@@ -10,13 +10,14 @@
10
10
  * telling the LLM which files to read and what to do.
11
11
  */
12
12
  import { deriveState } from "./state.js";
13
+ import { parseUnitId } from "./unit-id.js";
13
14
  import { getManifestStatus } from "./files.js";
14
15
  export { inlinePriorMilestoneSummary } from "./files.js";
15
16
  import { collectSecretsFromManifest } from "../get-secrets-from-user.js";
16
17
  import { gsdRoot, resolveMilestoneFile, resolveMilestonePath, resolveDir, milestonesDir, } from "./paths.js";
17
18
  import { invalidateAllCaches } from "./cache.js";
18
19
  import { clearActivityLogState } from "./activity-log.js";
19
- import { synthesizeCrashRecovery, getDeepDiagnostic, } from "./session-forensics.js";
20
+ import { synthesizeCrashRecovery, getDeepDiagnostic, readActiveMilestoneId, } from "./session-forensics.js";
20
21
  import { writeLock, clearLock, readCrashLock, isLockProcessAlive, } from "./crash-recovery.js";
21
22
  import { acquireSessionLock, getSessionLockStatus, releaseSessionLock, updateSessionLock, } from "./session-lock.js";
22
23
  import { resolveAutoSupervisorConfig, loadEffectiveGSDPreferences, getIsolationMode, } from "./preferences.js";
@@ -25,13 +26,13 @@ import { getBudgetAlertLevel, getNewBudgetAlertLevel, getBudgetEnforcementAction
25
26
  import { markToolStart as _markToolStart, markToolEnd as _markToolEnd, getOldestInFlightToolAgeMs as _getOldestInFlightToolAgeMs, clearInFlightTools, } from "./auto-tool-tracking.js";
26
27
  import { closeoutUnit } from "./auto-unit-closeout.js";
27
28
  import { selectAndApplyModel, resolveModelId } from "./auto-model-selection.js";
28
- import { syncProjectRootToWorktree, checkResourcesStale, escapeStaleWorktree, } from "./auto-worktree-sync.js";
29
29
  import { resetRoutingHistory, recordOutcome } from "./routing-history.js";
30
30
  import { resetHookState, runPreDispatchHooks, restoreHookState, clearPersistedHookState, } from "./post-unit-hooks.js";
31
31
  import { runGSDDoctor, rebuildState } from "./doctor.js";
32
32
  import { preDispatchHealthGate, resetProactiveHealing, setLevelChangeCallback, } from "./doctor-proactive.js";
33
33
  import { clearSkillSnapshot } from "./skill-discovery.js";
34
34
  import { captureAvailableSkills, resetSkillTelemetry, } from "./skill-telemetry.js";
35
+ import { getRtkSessionSavings } from "../shared/rtk-session-stats.js";
35
36
  import { initMetrics, resetMetrics, getLedger, getProjectTotals, formatCost, formatTokenCount, } from "./metrics.js";
36
37
  import { join } from "node:path";
37
38
  import { readFileSync, existsSync, mkdirSync, writeFileSync, unlinkSync } from "node:fs";
@@ -39,7 +40,7 @@ import { atomicWriteSync } from "./atomic-write.js";
39
40
  import { autoCommitCurrentBranch, captureIntegrationBranch, detectWorktreeName, getCurrentBranch, getMainBranch, setActiveMilestoneId, } from "./worktree.js";
40
41
  import { GitServiceImpl } from "./git-service.js";
41
42
  import { getPriorSliceCompletionBlocker } from "./dispatch-guard.js";
42
- import { createAutoWorktree, enterAutoWorktree, teardownAutoWorktree, isInAutoWorktree, getAutoWorktreePath, mergeMilestoneToMain, autoWorktreeBranch, syncWorktreeStateBack, } from "./auto-worktree.js";
43
+ import { createAutoWorktree, enterAutoWorktree, teardownAutoWorktree, isInAutoWorktree, getAutoWorktreePath, mergeMilestoneToMain, autoWorktreeBranch, syncWorktreeStateBack, syncProjectRootToWorktree, checkResourcesStale, escapeStaleWorktree, } from "./auto-worktree.js";
43
44
  import { pruneQueueOrder } from "./queue-order.js";
44
45
  import { debugLog, isDebugEnabled, writeDebugSummary } from "./debug-logger.js";
45
46
  import { reconcileMergeState, } from "./auto-recovery.js";
@@ -59,7 +60,6 @@ import { bootstrapAutoSession } from "./auto-start.js";
59
60
  import { autoLoop, resolveAgentEnd, resolveAgentEndCancelled, _resetPendingResolve, isSessionSwitchInFlight } from "./auto-loop.js";
60
61
  import { WorktreeResolver, } from "./worktree-resolver.js";
61
62
  import { reorderForCaching } from "./prompt-ordering.js";
62
- // Worktree sync, resource staleness, stale worktree escape → auto-worktree-sync.ts
63
63
  // ─── Session State ─────────────────────────────────────────────────────────
64
64
  import { AutoSession, } from "./auto/session.js";
65
65
  export { MAX_UNIT_DISPATCHES, STUB_RECOVERY_THRESHOLD, MAX_LIFETIME_DISPATCHES, NEW_SESSION_TIMEOUT_MS, } from "./auto/session.js";
@@ -124,6 +124,11 @@ function deregisterSigtermHandler() {
124
124
  export function getAutoDashboardData() {
125
125
  const ledger = getLedger();
126
126
  const totals = ledger ? getProjectTotals(ledger.units) : null;
127
+ const sessionId = s.cmdCtx?.sessionManager?.getSessionId?.() ?? null;
128
+ const rtkSavings = sessionId && s.basePath
129
+ ? getRtkSessionSavings(s.basePath, sessionId)
130
+ : null;
131
+ const rtkEnabled = loadEffectiveGSDPreferences()?.preferences.experimental?.rtk === true;
127
132
  // Pending capture count — lazy check, non-fatal
128
133
  let pendingCaptureCount = 0;
129
134
  try {
@@ -147,6 +152,8 @@ export function getAutoDashboardData() {
147
152
  totalCost: totals?.cost ?? 0,
148
153
  totalTokens: totals?.tokens.total ?? 0,
149
154
  pendingCaptureCount,
155
+ rtkSavings,
156
+ rtkEnabled,
150
157
  };
151
158
  }
152
159
  // ─── Public API ───────────────────────────────────────────────────────────────
@@ -363,8 +370,11 @@ export async function stopAuto(ctx, pi, reason) {
363
370
  // When the milestone is complete (has a SUMMARY), merge the worktree branch
364
371
  // back to main so code isn't stranded on the worktree branch (#2317).
365
372
  // For incomplete milestones, preserve the branch for later resumption.
373
+ //
374
+ // Skip if phases.ts already merged this milestone — avoids the double
375
+ // mergeAndExit that fails because the branch was already deleted (#2645).
366
376
  try {
367
- if (s.currentMilestoneId) {
377
+ if (s.currentMilestoneId && !s.milestoneMergedInPhases) {
368
378
  const notifyCtx = ctx
369
379
  ? { notify: ctx.ui.notify.bind(ctx.ui) }
370
380
  : { notify: () => { } };
@@ -706,7 +716,11 @@ function buildLoopDeps() {
706
716
  resolveModelId,
707
717
  startUnitSupervision,
708
718
  // Prompt helpers
709
- getDeepDiagnostic,
719
+ getDeepDiagnostic: (basePath) => {
720
+ const mid = readActiveMilestoneId(basePath);
721
+ const wtPath = mid ? getAutoWorktreePath(basePath, mid) : undefined;
722
+ return getDeepDiagnostic(basePath, wtPath ?? undefined);
723
+ },
710
724
  isDbAvailable,
711
725
  reorderForCaching,
712
726
  // Filesystem
@@ -925,15 +939,13 @@ const widgetStateAccessors = {
925
939
  * dispatching a unit. The LLM should never need to mkdir or git checkout.
926
940
  */
927
941
  function ensurePreconditions(unitType, unitId, base, state) {
928
- const parts = unitId.split("/");
929
- const mid = parts[0];
942
+ const { milestone: mid, slice: sid } = parseUnitId(unitId);
930
943
  const mDir = resolveMilestonePath(base, mid);
931
944
  if (!mDir) {
932
945
  const newDir = join(milestonesDir(base), mid);
933
946
  mkdirSync(join(newDir, "slices"), { recursive: true });
934
947
  }
935
- if (parts.length >= 2) {
936
- const sid = parts[1];
948
+ if (sid !== undefined) {
937
949
  const mDirResolved = resolveMilestonePath(base, mid);
938
950
  if (mDirResolved) {
939
951
  const slicesDir = join(mDirResolved, "slices");
@@ -1042,4 +1042,93 @@ export function registerDbTools(pi) {
1042
1042
  };
1043
1043
  pi.registerTool(reassessRoadmapTool);
1044
1044
  registerAlias(pi, reassessRoadmapTool, "gsd_roadmap_reassess", "gsd_reassess_roadmap");
1045
+ // ─── gsd_save_gate_result ──────────────────────────────────────────────
1046
+ const saveGateResultExecute = async (_toolCallId, params, _signal, _onUpdate, _ctx) => {
1047
+ const dbAvailable = await ensureDbOpen();
1048
+ if (!dbAvailable) {
1049
+ return {
1050
+ content: [{ type: "text", text: "Error: GSD database is not available." }],
1051
+ details: { operation: "save_gate_result", error: "db_unavailable" },
1052
+ };
1053
+ }
1054
+ const validGates = ["Q3", "Q4", "Q5", "Q6", "Q7", "Q8"];
1055
+ if (!validGates.includes(params.gateId)) {
1056
+ return {
1057
+ content: [{ type: "text", text: `Error: Invalid gateId "${params.gateId}". Must be one of: ${validGates.join(", ")}` }],
1058
+ details: { operation: "save_gate_result", error: "invalid_gate_id" },
1059
+ };
1060
+ }
1061
+ const validVerdicts = ["pass", "flag", "omitted"];
1062
+ if (!validVerdicts.includes(params.verdict)) {
1063
+ return {
1064
+ content: [{ type: "text", text: `Error: Invalid verdict "${params.verdict}". Must be one of: ${validVerdicts.join(", ")}` }],
1065
+ details: { operation: "save_gate_result", error: "invalid_verdict" },
1066
+ };
1067
+ }
1068
+ try {
1069
+ const { saveGateResult } = await import("../gsd-db.js");
1070
+ const { invalidateStateCache } = await import("../state.js");
1071
+ saveGateResult({
1072
+ milestoneId: params.milestoneId,
1073
+ sliceId: params.sliceId,
1074
+ gateId: params.gateId,
1075
+ taskId: params.taskId ?? "",
1076
+ verdict: params.verdict,
1077
+ rationale: params.rationale,
1078
+ findings: params.findings ?? "",
1079
+ });
1080
+ invalidateStateCache();
1081
+ return {
1082
+ content: [{ type: "text", text: `Gate ${params.gateId} result saved: verdict=${params.verdict}` }],
1083
+ details: { operation: "save_gate_result", gateId: params.gateId, verdict: params.verdict },
1084
+ };
1085
+ }
1086
+ catch (err) {
1087
+ const msg = err instanceof Error ? err.message : String(err);
1088
+ logError("tool", `gsd_save_gate_result failed: ${msg}`, { tool: "gsd_save_gate_result", error: String(err) });
1089
+ return {
1090
+ content: [{ type: "text", text: `Error saving gate result: ${msg}` }],
1091
+ details: { operation: "save_gate_result", error: msg },
1092
+ };
1093
+ }
1094
+ };
1095
+ const saveGateResultTool = {
1096
+ name: "gsd_save_gate_result",
1097
+ label: "Save Gate Result",
1098
+ description: "Save the result of a quality gate evaluation (Q3-Q8) to the GSD database. " +
1099
+ "Called by gate evaluation sub-agents after analyzing a specific quality question.",
1100
+ promptSnippet: "Save quality gate evaluation result (verdict, rationale, findings)",
1101
+ promptGuidelines: [
1102
+ "Use gsd_save_gate_result after evaluating a quality gate question.",
1103
+ "gateId must be one of: Q3, Q4, Q5, Q6, Q7, Q8.",
1104
+ "verdict must be: pass (no concerns), flag (concerns found), or omitted (not applicable).",
1105
+ "rationale should be a one-sentence justification for the verdict.",
1106
+ "findings should contain detailed markdown analysis (or empty string if omitted).",
1107
+ ],
1108
+ parameters: Type.Object({
1109
+ milestoneId: Type.String({ description: "Milestone ID (e.g. M001)" }),
1110
+ sliceId: Type.String({ description: "Slice ID (e.g. S01)" }),
1111
+ gateId: Type.String({ description: "Gate ID: Q3, Q4, Q5, Q6, Q7, or Q8" }),
1112
+ taskId: Type.Optional(Type.String({ description: "Task ID for task-scoped gates (Q5/Q6/Q7)" })),
1113
+ verdict: Type.String({ description: "pass, flag, or omitted" }),
1114
+ rationale: Type.String({ description: "One-sentence justification" }),
1115
+ findings: Type.Optional(Type.String({ description: "Detailed markdown findings" })),
1116
+ }),
1117
+ execute: saveGateResultExecute,
1118
+ renderCall(args, theme) {
1119
+ let text = theme.fg("toolTitle", theme.bold("save_gate_result "));
1120
+ text += theme.fg("accent", args.gateId ?? "");
1121
+ text += theme.fg("dim", ` → ${args.verdict ?? ""}`);
1122
+ return new Text(text, 0, 0);
1123
+ },
1124
+ renderResult(result, _options, theme) {
1125
+ const d = result.details;
1126
+ if (result.isError || d?.error) {
1127
+ return new Text(theme.fg("error", `Error: ${d?.error ?? "unknown"}`), 0, 0);
1128
+ }
1129
+ const color = d?.verdict === "flag" ? "warning" : "success";
1130
+ return new Text(theme.fg(color, `${d?.gateId}: ${d?.verdict}`), 0, 0);
1131
+ },
1132
+ };
1133
+ pi.registerTool(saveGateResultTool);
1045
1134
  }