gsd-pi 2.50.0 → 2.51.0-dev.7d435fe

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 (681) hide show
  1. package/README.md +6 -4
  2. package/dist/cli.js +26 -0
  3. package/dist/headless-events.d.ts +18 -0
  4. package/dist/headless-events.js +36 -0
  5. package/dist/headless-types.d.ts +28 -0
  6. package/dist/headless-types.js +7 -0
  7. package/dist/headless.d.ts +8 -3
  8. package/dist/headless.js +47 -16
  9. package/dist/help-text.js +16 -5
  10. package/dist/loader.js +4 -0
  11. package/dist/onboarding.js +5 -4
  12. package/dist/remote-questions-config.js +1 -1
  13. package/dist/resource-loader.d.ts +4 -1
  14. package/dist/resource-loader.js +138 -3
  15. package/dist/resources/extensions/async-jobs/async-bash-tool.js +32 -18
  16. package/dist/resources/extensions/bg-shell/interaction.js +3 -1
  17. package/dist/resources/extensions/bg-shell/process-manager.js +4 -1
  18. package/dist/resources/extensions/claude-code-cli/partial-builder.js +5 -0
  19. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +18 -19
  20. package/dist/resources/extensions/gsd/auto/phases.js +16 -1
  21. package/dist/resources/extensions/gsd/auto/session.js +5 -0
  22. package/dist/resources/extensions/gsd/auto-dashboard.js +22 -3
  23. package/dist/resources/extensions/gsd/auto-dispatch.js +98 -53
  24. package/dist/resources/extensions/gsd/auto-observability.js +54 -0
  25. package/dist/resources/extensions/gsd/auto-post-unit.js +37 -76
  26. package/dist/resources/extensions/gsd/auto-prompts.js +57 -0
  27. package/dist/resources/extensions/gsd/auto-recovery.js +21 -25
  28. package/dist/resources/extensions/gsd/auto-start.js +2 -0
  29. package/dist/resources/extensions/gsd/auto-timers.js +24 -2
  30. package/dist/resources/extensions/gsd/auto-tool-tracking.js +25 -7
  31. package/dist/resources/extensions/gsd/auto-utils.js +20 -0
  32. package/dist/resources/extensions/gsd/auto-worktree.js +21 -0
  33. package/dist/resources/extensions/gsd/auto.js +19 -7
  34. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +95 -69
  35. package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +12 -2
  36. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +17 -1
  37. package/dist/resources/extensions/gsd/claude-import.js +60 -9
  38. package/dist/resources/extensions/gsd/commands/handlers/auto.js +69 -6
  39. package/dist/resources/extensions/gsd/commands-config.js +10 -5
  40. package/dist/resources/extensions/gsd/commands-prefs-wizard.js +1 -1
  41. package/dist/resources/extensions/gsd/crash-recovery.js +6 -2
  42. package/dist/resources/extensions/gsd/custom-execution-policy.js +3 -2
  43. package/dist/resources/extensions/gsd/custom-verification.js +3 -1
  44. package/dist/resources/extensions/gsd/custom-workflow-engine.js +3 -2
  45. package/dist/resources/extensions/gsd/dashboard-overlay.js +4 -0
  46. package/dist/resources/extensions/gsd/detection.js +595 -9
  47. package/dist/resources/extensions/gsd/dispatch-guard.js +2 -1
  48. package/dist/resources/extensions/gsd/docs/preferences-reference.md +18 -3
  49. package/dist/resources/extensions/gsd/error-classifier.js +105 -0
  50. package/dist/resources/extensions/gsd/files.js +5 -1
  51. package/dist/resources/extensions/gsd/gitignore.js +7 -7
  52. package/dist/resources/extensions/gsd/gsd-db.js +298 -45
  53. package/dist/resources/extensions/gsd/guided-flow.js +10 -0
  54. package/dist/resources/extensions/gsd/init-wizard.js +11 -3
  55. package/dist/resources/extensions/gsd/key-manager.js +7 -16
  56. package/dist/resources/extensions/gsd/memory-store.js +28 -13
  57. package/dist/resources/extensions/gsd/milestone-actions.js +19 -0
  58. package/dist/resources/extensions/gsd/model-router.js +25 -0
  59. package/dist/resources/extensions/gsd/notifications.js +23 -0
  60. package/dist/resources/extensions/gsd/observability-validator.js +422 -0
  61. package/dist/resources/extensions/gsd/preferences-models.js +1 -13
  62. package/dist/resources/extensions/gsd/preferences-skills.js +11 -5
  63. package/dist/resources/extensions/gsd/preferences-types.js +1 -0
  64. package/dist/resources/extensions/gsd/preferences-validation.js +25 -0
  65. package/dist/resources/extensions/gsd/preferences.js +16 -13
  66. package/dist/resources/extensions/gsd/prompts/forensics.md +11 -7
  67. package/dist/resources/extensions/gsd/prompts/system.md +1 -1
  68. package/dist/resources/extensions/gsd/prompts/validate-milestone.md +6 -1
  69. package/dist/resources/extensions/gsd/provider-error-pause.js +0 -36
  70. package/dist/resources/extensions/gsd/roadmap-mutations.js +110 -0
  71. package/dist/resources/extensions/gsd/rtk-status.js +43 -0
  72. package/dist/resources/extensions/gsd/rule-registry.js +11 -12
  73. package/dist/resources/extensions/gsd/service-tier.js +13 -2
  74. package/dist/resources/extensions/gsd/session-forensics.js +7 -3
  75. package/dist/resources/extensions/gsd/skill-catalog.js +1026 -0
  76. package/dist/resources/extensions/gsd/skill-discovery.js +3 -2
  77. package/dist/resources/extensions/gsd/skill-health.js +2 -2
  78. package/dist/resources/extensions/gsd/skill-telemetry.js +15 -5
  79. package/dist/resources/extensions/gsd/state.js +38 -7
  80. package/dist/resources/extensions/gsd/templates/{preferences.md → PREFERENCES.md} +2 -0
  81. package/dist/resources/extensions/gsd/templates/milestone-validation.md +12 -0
  82. package/dist/resources/extensions/gsd/tests/dist-redirect.mjs +28 -9
  83. package/dist/resources/extensions/gsd/tools/complete-milestone.js +3 -10
  84. package/dist/resources/extensions/gsd/tools/complete-slice.js +3 -17
  85. package/dist/resources/extensions/gsd/tools/complete-task.js +7 -18
  86. package/dist/resources/extensions/gsd/tools/plan-milestone.js +26 -17
  87. package/dist/resources/extensions/gsd/tools/plan-slice.js +25 -14
  88. package/dist/resources/extensions/gsd/tools/plan-task.js +21 -11
  89. package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +47 -37
  90. package/dist/resources/extensions/gsd/tools/replan-slice.js +49 -38
  91. package/dist/resources/extensions/gsd/tools/validate-milestone.js +23 -16
  92. package/dist/resources/extensions/gsd/undo.js +8 -7
  93. package/dist/resources/extensions/gsd/unit-runtime.js +2 -1
  94. package/dist/resources/extensions/gsd/verification-gate.js +3 -1
  95. package/dist/resources/extensions/gsd/workflow-logger.js +0 -1
  96. package/dist/resources/extensions/remote-questions/config.js +1 -1
  97. package/dist/resources/extensions/remote-questions/remote-command.js +1 -1
  98. package/dist/resources/extensions/search-the-web/native-search.js +1 -1
  99. package/dist/resources/extensions/search-the-web/provider.js +1 -1
  100. package/dist/resources/extensions/shared/rtk-session-stats.js +189 -0
  101. package/dist/resources/extensions/shared/rtk.js +100 -0
  102. package/dist/rtk.d.ts +52 -0
  103. package/dist/rtk.js +332 -0
  104. package/dist/web/standalone/.next/BUILD_ID +1 -1
  105. package/dist/web/standalone/.next/app-path-routes-manifest.json +18 -17
  106. package/dist/web/standalone/.next/build-manifest.json +4 -4
  107. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  108. package/dist/web/standalone/.next/react-loadable-manifest.json +2 -2
  109. package/dist/web/standalone/.next/required-server-files.json +3 -3
  110. package/dist/web/standalone/.next/routes-manifest.json +6 -0
  111. package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
  112. package/dist/web/standalone/.next/server/app/_global-error/page.js.nft.json +1 -1
  113. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  114. package/dist/web/standalone/.next/server/app/_global-error.html +2 -2
  115. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  116. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  117. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  118. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  119. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  120. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  121. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  122. package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
  123. package/dist/web/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
  124. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  125. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  126. package/dist/web/standalone/.next/server/app/_not-found.rsc +4 -4
  127. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +4 -4
  128. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  129. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +4 -4
  130. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  131. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  132. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  133. package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
  134. package/dist/web/standalone/.next/server/app/api/boot/route.js.nft.json +1 -1
  135. package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
  136. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
  137. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js.nft.json +1 -1
  138. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
  139. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
  140. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js.nft.json +1 -1
  141. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
  142. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
  143. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js.nft.json +1 -1
  144. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
  145. package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
  146. package/dist/web/standalone/.next/server/app/api/browse-directories/route.js.nft.json +1 -1
  147. package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
  148. package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
  149. package/dist/web/standalone/.next/server/app/api/captures/route.js.nft.json +1 -1
  150. package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
  151. package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
  152. package/dist/web/standalone/.next/server/app/api/cleanup/route.js.nft.json +1 -1
  153. package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
  154. package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
  155. package/dist/web/standalone/.next/server/app/api/dev-mode/route.js.nft.json +1 -1
  156. package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
  157. package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
  158. package/dist/web/standalone/.next/server/app/api/doctor/route.js.nft.json +1 -1
  159. package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
  160. package/dist/web/standalone/.next/server/app/api/experimental/route.js +3 -0
  161. package/dist/web/standalone/.next/server/app/api/experimental/route.js.nft.json +1 -0
  162. package/dist/web/standalone/.next/server/app/api/experimental/route_client-reference-manifest.js +1 -0
  163. package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
  164. package/dist/web/standalone/.next/server/app/api/export-data/route.js.nft.json +1 -1
  165. package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
  166. package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
  167. package/dist/web/standalone/.next/server/app/api/files/route.js.nft.json +1 -1
  168. package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
  169. package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
  170. package/dist/web/standalone/.next/server/app/api/forensics/route.js.nft.json +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.js.nft.json +1 -1
  174. package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  175. package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
  176. package/dist/web/standalone/.next/server/app/api/history/route.js.nft.json +1 -1
  177. package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
  178. package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
  179. package/dist/web/standalone/.next/server/app/api/hooks/route.js.nft.json +1 -1
  180. package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
  181. package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
  182. package/dist/web/standalone/.next/server/app/api/inspect/route.js.nft.json +1 -1
  183. package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
  184. package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
  185. package/dist/web/standalone/.next/server/app/api/knowledge/route.js.nft.json +1 -1
  186. package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
  187. package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
  188. package/dist/web/standalone/.next/server/app/api/live-state/route.js.nft.json +1 -1
  189. package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
  190. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  191. package/dist/web/standalone/.next/server/app/api/onboarding/route.js.nft.json +1 -1
  192. package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
  193. package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
  194. package/dist/web/standalone/.next/server/app/api/preferences/route.js.nft.json +1 -1
  195. package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
  196. package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
  197. package/dist/web/standalone/.next/server/app/api/projects/route.js.nft.json +1 -1
  198. package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  199. package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
  200. package/dist/web/standalone/.next/server/app/api/recovery/route.js.nft.json +1 -1
  201. package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
  202. package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +2 -26
  203. package/dist/web/standalone/.next/server/app/api/remote-questions/route.js.nft.json +1 -1
  204. package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
  205. package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
  206. package/dist/web/standalone/.next/server/app/api/session/browser/route.js.nft.json +1 -1
  207. package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
  208. package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
  209. package/dist/web/standalone/.next/server/app/api/session/command/route.js.nft.json +1 -1
  210. package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
  211. package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
  212. package/dist/web/standalone/.next/server/app/api/session/events/route.js.nft.json +1 -1
  213. package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
  214. package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
  215. package/dist/web/standalone/.next/server/app/api/session/manage/route.js.nft.json +1 -1
  216. package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
  217. package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
  218. package/dist/web/standalone/.next/server/app/api/settings-data/route.js.nft.json +1 -1
  219. package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
  220. package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
  221. package/dist/web/standalone/.next/server/app/api/shutdown/route.js.nft.json +1 -1
  222. package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
  223. package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
  224. package/dist/web/standalone/.next/server/app/api/skill-health/route.js.nft.json +1 -1
  225. package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
  226. package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
  227. package/dist/web/standalone/.next/server/app/api/steer/route.js.nft.json +1 -1
  228. package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
  229. package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
  230. package/dist/web/standalone/.next/server/app/api/switch-root/route.js.nft.json +1 -1
  231. package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
  232. package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +2 -2
  233. package/dist/web/standalone/.next/server/app/api/terminal/input/route.js.nft.json +1 -1
  234. package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
  235. package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
  236. package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js.nft.json +1 -1
  237. package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
  238. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +2 -2
  239. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js.nft.json +1 -1
  240. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
  241. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +4 -4
  242. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js.nft.json +1 -1
  243. package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
  244. package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
  245. package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js.nft.json +1 -1
  246. package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
  247. package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
  248. package/dist/web/standalone/.next/server/app/api/undo/route.js.nft.json +1 -1
  249. package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
  250. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  251. package/dist/web/standalone/.next/server/app/api/update/route.js.nft.json +1 -1
  252. package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  253. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  254. package/dist/web/standalone/.next/server/app/api/visualizer/route.js.nft.json +1 -1
  255. package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
  256. package/dist/web/standalone/.next/server/app/index.html +1 -1
  257. package/dist/web/standalone/.next/server/app/index.rsc +5 -5
  258. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  259. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +5 -5
  260. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  261. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +4 -4
  262. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  263. package/dist/web/standalone/.next/server/app/page.js +2 -2
  264. package/dist/web/standalone/.next/server/app/page.js.nft.json +1 -1
  265. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  266. package/dist/web/standalone/.next/server/app-paths-manifest.json +18 -17
  267. package/dist/web/standalone/.next/server/chunks/2229.js +12 -0
  268. package/dist/web/standalone/.next/server/chunks/2331.js +25 -0
  269. package/dist/web/standalone/.next/server/chunks/{741.js → 4741.js} +1 -1
  270. package/dist/web/standalone/.next/server/chunks/5822.js +2 -0
  271. package/dist/web/standalone/.next/server/chunks/7471.js +13 -0
  272. package/dist/web/standalone/.next/server/functions-config-manifest.json +1 -0
  273. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  274. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  275. package/dist/web/standalone/.next/server/middleware.js +3 -3
  276. package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
  277. package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
  278. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  279. package/dist/web/standalone/.next/server/pages/500.html +2 -2
  280. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  281. package/dist/web/standalone/.next/server/webpack-runtime.js +1 -1
  282. package/dist/web/standalone/.next/static/RqOU-jOv9uZ1Q03P6L6nn/_buildManifest.js +1 -0
  283. package/dist/web/standalone/.next/static/chunks/{485.243af25f0cdf50d6.js → 2008.817d0885545aaea9.js} +6 -6
  284. package/dist/web/standalone/.next/static/chunks/4024.21054f459af5cc78.js +9 -0
  285. package/dist/web/standalone/.next/static/chunks/app/_global-error/page-c4cc189e7b117ea2.js +1 -0
  286. package/dist/web/standalone/.next/static/chunks/app/_not-found/{page-2f24283c162b6ab3.js → page-f2a7482d42a5614b.js} +1 -1
  287. package/dist/web/standalone/.next/static/chunks/app/api/boot/route-c4cc189e7b117ea2.js +1 -0
  288. package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/input/route-c4cc189e7b117ea2.js +1 -0
  289. package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/resize/route-c4cc189e7b117ea2.js +1 -0
  290. package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/stream/route-c4cc189e7b117ea2.js +1 -0
  291. package/dist/web/standalone/.next/static/chunks/app/api/browse-directories/route-c4cc189e7b117ea2.js +1 -0
  292. package/dist/web/standalone/.next/static/chunks/app/api/captures/route-c4cc189e7b117ea2.js +1 -0
  293. package/dist/web/standalone/.next/static/chunks/app/api/cleanup/route-c4cc189e7b117ea2.js +1 -0
  294. package/dist/web/standalone/.next/static/chunks/app/api/dev-mode/route-c4cc189e7b117ea2.js +1 -0
  295. package/dist/web/standalone/.next/static/chunks/app/api/doctor/route-c4cc189e7b117ea2.js +1 -0
  296. package/dist/web/standalone/.next/static/chunks/app/api/experimental/route-c4cc189e7b117ea2.js +1 -0
  297. package/dist/web/standalone/.next/static/chunks/app/api/export-data/route-c4cc189e7b117ea2.js +1 -0
  298. package/dist/web/standalone/.next/static/chunks/app/api/files/route-c4cc189e7b117ea2.js +1 -0
  299. package/dist/web/standalone/.next/static/chunks/app/api/forensics/route-c4cc189e7b117ea2.js +1 -0
  300. package/dist/web/standalone/.next/static/chunks/app/api/git/route-c4cc189e7b117ea2.js +1 -0
  301. package/dist/web/standalone/.next/static/chunks/app/api/history/route-c4cc189e7b117ea2.js +1 -0
  302. package/dist/web/standalone/.next/static/chunks/app/api/hooks/route-c4cc189e7b117ea2.js +1 -0
  303. package/dist/web/standalone/.next/static/chunks/app/api/inspect/route-c4cc189e7b117ea2.js +1 -0
  304. package/dist/web/standalone/.next/static/chunks/app/api/knowledge/route-c4cc189e7b117ea2.js +1 -0
  305. package/dist/web/standalone/.next/static/chunks/app/api/live-state/route-c4cc189e7b117ea2.js +1 -0
  306. package/dist/web/standalone/.next/static/chunks/app/api/onboarding/route-c4cc189e7b117ea2.js +1 -0
  307. package/dist/web/standalone/.next/static/chunks/app/api/preferences/route-c4cc189e7b117ea2.js +1 -0
  308. package/dist/web/standalone/.next/static/chunks/app/api/projects/route-c4cc189e7b117ea2.js +1 -0
  309. package/dist/web/standalone/.next/static/chunks/app/api/recovery/route-c4cc189e7b117ea2.js +1 -0
  310. package/dist/web/standalone/.next/static/chunks/app/api/remote-questions/route-c4cc189e7b117ea2.js +1 -0
  311. package/dist/web/standalone/.next/static/chunks/app/api/session/browser/route-c4cc189e7b117ea2.js +1 -0
  312. package/dist/web/standalone/.next/static/chunks/app/api/session/command/route-c4cc189e7b117ea2.js +1 -0
  313. package/dist/web/standalone/.next/static/chunks/app/api/session/events/route-c4cc189e7b117ea2.js +1 -0
  314. package/dist/web/standalone/.next/static/chunks/app/api/session/manage/route-c4cc189e7b117ea2.js +1 -0
  315. package/dist/web/standalone/.next/static/chunks/app/api/settings-data/route-c4cc189e7b117ea2.js +1 -0
  316. package/dist/web/standalone/.next/static/chunks/app/api/shutdown/route-c4cc189e7b117ea2.js +1 -0
  317. package/dist/web/standalone/.next/static/chunks/app/api/skill-health/route-c4cc189e7b117ea2.js +1 -0
  318. package/dist/web/standalone/.next/static/chunks/app/api/steer/route-c4cc189e7b117ea2.js +1 -0
  319. package/dist/web/standalone/.next/static/chunks/app/api/switch-root/route-c4cc189e7b117ea2.js +1 -0
  320. package/dist/web/standalone/.next/static/chunks/app/api/terminal/input/route-c4cc189e7b117ea2.js +1 -0
  321. package/dist/web/standalone/.next/static/chunks/app/api/terminal/resize/route-c4cc189e7b117ea2.js +1 -0
  322. package/dist/web/standalone/.next/static/chunks/app/api/terminal/sessions/route-c4cc189e7b117ea2.js +1 -0
  323. package/dist/web/standalone/.next/static/chunks/app/api/terminal/stream/route-c4cc189e7b117ea2.js +1 -0
  324. package/dist/web/standalone/.next/static/chunks/app/api/terminal/upload/route-c4cc189e7b117ea2.js +1 -0
  325. package/dist/web/standalone/.next/static/chunks/app/api/undo/route-c4cc189e7b117ea2.js +1 -0
  326. package/dist/web/standalone/.next/static/chunks/app/api/update/route-c4cc189e7b117ea2.js +1 -0
  327. package/dist/web/standalone/.next/static/chunks/app/api/visualizer/route-c4cc189e7b117ea2.js +1 -0
  328. package/dist/web/standalone/.next/static/chunks/app/{layout-9ecfd95f343793f0.js → layout-a16c7a7ecdf0c2cf.js} +1 -1
  329. package/dist/web/standalone/.next/static/chunks/app/page-b950e4e384cc62b3.js +1 -0
  330. package/dist/web/standalone/.next/static/chunks/main-app-fdab67f7802d7832.js +1 -0
  331. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/app-error-c4cc189e7b117ea2.js +1 -0
  332. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/forbidden-c4cc189e7b117ea2.js +1 -0
  333. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +1 -0
  334. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/not-found-c4cc189e7b117ea2.js +1 -0
  335. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/unauthorized-c4cc189e7b117ea2.js +1 -0
  336. package/dist/web/standalone/.next/static/chunks/webpack-024d82be84800e52.js +1 -0
  337. package/dist/web/standalone/.next/static/css/a58ef8a151aa0493.css +1 -0
  338. package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
  339. package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
  340. package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
  341. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api.target.mk +14 -14
  342. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_except.target.mk +14 -14
  343. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_maybe.target.mk +14 -14
  344. package/dist/web/standalone/server.js +1 -1
  345. package/dist/wizard.js +4 -1
  346. package/package.json +2 -2
  347. package/packages/pi-ai/dist/models.d.ts +14 -3
  348. package/packages/pi-ai/dist/models.d.ts.map +1 -1
  349. package/packages/pi-ai/dist/models.js +53 -10
  350. package/packages/pi-ai/dist/models.js.map +1 -1
  351. package/packages/pi-ai/dist/models.test.js +102 -1
  352. package/packages/pi-ai/dist/models.test.js.map +1 -1
  353. package/packages/pi-ai/dist/types.d.ts +31 -0
  354. package/packages/pi-ai/dist/types.d.ts.map +1 -1
  355. package/packages/pi-ai/dist/types.js.map +1 -1
  356. package/packages/pi-ai/src/models.test.ts +114 -1
  357. package/packages/pi-ai/src/models.ts +70 -13
  358. package/packages/pi-ai/src/types.ts +32 -1
  359. package/packages/pi-coding-agent/dist/cli/args.d.ts +2 -0
  360. package/packages/pi-coding-agent/dist/cli/args.d.ts.map +1 -1
  361. package/packages/pi-coding-agent/dist/cli/args.js +3 -0
  362. package/packages/pi-coding-agent/dist/cli/args.js.map +1 -1
  363. package/packages/pi-coding-agent/dist/core/agent-session.d.ts +1 -0
  364. package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
  365. package/packages/pi-coding-agent/dist/core/agent-session.js +1 -0
  366. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  367. package/packages/pi-coding-agent/dist/core/bash-executor.d.ts +3 -1
  368. package/packages/pi-coding-agent/dist/core/bash-executor.d.ts.map +1 -1
  369. package/packages/pi-coding-agent/dist/core/bash-executor.js +15 -2
  370. package/packages/pi-coding-agent/dist/core/bash-executor.js.map +1 -1
  371. package/packages/pi-coding-agent/dist/core/extensions/index.d.ts +1 -1
  372. package/packages/pi-coding-agent/dist/core/extensions/index.d.ts.map +1 -1
  373. package/packages/pi-coding-agent/dist/core/extensions/index.js.map +1 -1
  374. package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts +1 -0
  375. package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts.map +1 -1
  376. package/packages/pi-coding-agent/dist/core/extensions/runner.js +13 -0
  377. package/packages/pi-coding-agent/dist/core/extensions/runner.js.map +1 -1
  378. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts +19 -1
  379. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts.map +1 -1
  380. package/packages/pi-coding-agent/dist/core/extensions/types.js.map +1 -1
  381. package/packages/pi-coding-agent/dist/core/extensions/wrapper.d.ts.map +1 -1
  382. package/packages/pi-coding-agent/dist/core/extensions/wrapper.js +8 -0
  383. package/packages/pi-coding-agent/dist/core/extensions/wrapper.js.map +1 -1
  384. package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
  385. package/packages/pi-coding-agent/dist/core/model-registry.js +9 -4
  386. package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
  387. package/packages/pi-coding-agent/dist/core/package-manager.d.ts.map +1 -1
  388. package/packages/pi-coding-agent/dist/core/package-manager.js +8 -1
  389. package/packages/pi-coding-agent/dist/core/package-manager.js.map +1 -1
  390. package/packages/pi-coding-agent/dist/core/skills.d.ts +11 -1
  391. package/packages/pi-coding-agent/dist/core/skills.d.ts.map +1 -1
  392. package/packages/pi-coding-agent/dist/core/skills.js +30 -8
  393. package/packages/pi-coding-agent/dist/core/skills.js.map +1 -1
  394. package/packages/pi-coding-agent/dist/core/slash-commands.d.ts.map +1 -1
  395. package/packages/pi-coding-agent/dist/core/slash-commands.js +1 -0
  396. package/packages/pi-coding-agent/dist/core/slash-commands.js.map +1 -1
  397. package/packages/pi-coding-agent/dist/core/tools/bash-spawn-windows.test.d.ts +19 -0
  398. package/packages/pi-coding-agent/dist/core/tools/bash-spawn-windows.test.d.ts.map +1 -0
  399. package/packages/pi-coding-agent/dist/core/tools/bash-spawn-windows.test.js +83 -0
  400. package/packages/pi-coding-agent/dist/core/tools/bash-spawn-windows.test.js.map +1 -0
  401. package/packages/pi-coding-agent/dist/core/tools/bash.d.ts.map +1 -1
  402. package/packages/pi-coding-agent/dist/core/tools/bash.js +5 -1
  403. package/packages/pi-coding-agent/dist/core/tools/bash.js.map +1 -1
  404. package/packages/pi-coding-agent/dist/index.d.ts +3 -3
  405. package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
  406. package/packages/pi-coding-agent/dist/index.js +1 -1
  407. package/packages/pi-coding-agent/dist/index.js.map +1 -1
  408. package/packages/pi-coding-agent/dist/main.d.ts.map +1 -1
  409. package/packages/pi-coding-agent/dist/main.js +5 -3
  410. package/packages/pi-coding-agent/dist/main.js.map +1 -1
  411. package/packages/pi-coding-agent/dist/modes/index.d.ts +1 -1
  412. package/packages/pi-coding-agent/dist/modes/index.d.ts.map +1 -1
  413. package/packages/pi-coding-agent/dist/modes/index.js.map +1 -1
  414. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.d.ts.map +1 -1
  415. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js +3 -2
  416. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js.map +1 -1
  417. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  418. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +0 -2
  419. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  420. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  421. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +6 -4
  422. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  423. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.d.ts +5 -0
  424. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.d.ts.map +1 -1
  425. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.js +12 -0
  426. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.js.map +1 -1
  427. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.d.ts.map +1 -1
  428. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js +2 -1
  429. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js.map +1 -1
  430. package/packages/pi-coding-agent/dist/modes/rpc/rpc-client.d.ts +28 -1
  431. package/packages/pi-coding-agent/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  432. package/packages/pi-coding-agent/dist/modes/rpc/rpc-client.js +49 -0
  433. package/packages/pi-coding-agent/dist/modes/rpc/rpc-client.js.map +1 -1
  434. package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.d.ts +1 -1
  435. package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  436. package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.js +114 -6
  437. package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.js.map +1 -1
  438. package/packages/pi-coding-agent/dist/modes/rpc/rpc-protocol-v2.test.d.ts +9 -0
  439. package/packages/pi-coding-agent/dist/modes/rpc/rpc-protocol-v2.test.d.ts.map +1 -0
  440. package/packages/pi-coding-agent/dist/modes/rpc/rpc-protocol-v2.test.js +831 -0
  441. package/packages/pi-coding-agent/dist/modes/rpc/rpc-protocol-v2.test.js.map +1 -0
  442. package/packages/pi-coding-agent/dist/modes/rpc/rpc-types.d.ts +66 -0
  443. package/packages/pi-coding-agent/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  444. package/packages/pi-coding-agent/dist/modes/rpc/rpc-types.js.map +1 -1
  445. package/packages/pi-coding-agent/dist/utils/shell.d.ts.map +1 -1
  446. package/packages/pi-coding-agent/dist/utils/shell.js +0 -1
  447. package/packages/pi-coding-agent/dist/utils/shell.js.map +1 -1
  448. package/packages/pi-coding-agent/package.json +1 -1
  449. package/packages/pi-coding-agent/src/cli/args.ts +4 -0
  450. package/packages/pi-coding-agent/src/core/agent-session.ts +2 -1
  451. package/packages/pi-coding-agent/src/core/bash-executor.ts +15 -3
  452. package/packages/pi-coding-agent/src/core/extensions/index.ts +2 -0
  453. package/packages/pi-coding-agent/src/core/extensions/runner.ts +18 -0
  454. package/packages/pi-coding-agent/src/core/extensions/types.ts +21 -0
  455. package/packages/pi-coding-agent/src/core/extensions/wrapper.ts +9 -0
  456. package/packages/pi-coding-agent/src/core/model-registry.ts +10 -3
  457. package/packages/pi-coding-agent/src/core/package-manager.ts +10 -1
  458. package/packages/pi-coding-agent/src/core/skills.ts +35 -10
  459. package/packages/pi-coding-agent/src/core/slash-commands.ts +1 -0
  460. package/packages/pi-coding-agent/src/core/tools/bash-spawn-windows.test.ts +101 -0
  461. package/packages/pi-coding-agent/src/core/tools/bash.ts +5 -1
  462. package/packages/pi-coding-agent/src/index.ts +7 -0
  463. package/packages/pi-coding-agent/src/main.ts +5 -3
  464. package/packages/pi-coding-agent/src/modes/index.ts +8 -1
  465. package/packages/pi-coding-agent/src/modes/interactive/components/footer.ts +3 -2
  466. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +0 -2
  467. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +6 -4
  468. package/packages/pi-coding-agent/src/modes/interactive/slash-command-handlers.ts +15 -0
  469. package/packages/pi-coding-agent/src/modes/interactive/theme/themes.ts +2 -1
  470. package/packages/pi-coding-agent/src/modes/rpc/rpc-client.ts +54 -1
  471. package/packages/pi-coding-agent/src/modes/rpc/rpc-mode.ts +124 -6
  472. package/packages/pi-coding-agent/src/modes/rpc/rpc-protocol-v2.test.ts +971 -0
  473. package/packages/pi-coding-agent/src/modes/rpc/rpc-types.ts +61 -4
  474. package/packages/pi-coding-agent/src/utils/shell.ts +0 -1
  475. package/pkg/dist/modes/interactive/theme/themes.d.ts.map +1 -1
  476. package/pkg/dist/modes/interactive/theme/themes.js +2 -1
  477. package/pkg/dist/modes/interactive/theme/themes.js.map +1 -1
  478. package/pkg/package.json +1 -1
  479. package/scripts/postinstall.js +163 -6
  480. package/src/resources/extensions/async-jobs/async-bash-tool.ts +25 -12
  481. package/src/resources/extensions/bg-shell/interaction.ts +3 -1
  482. package/src/resources/extensions/bg-shell/process-manager.ts +4 -1
  483. package/src/resources/extensions/claude-code-cli/partial-builder.ts +5 -0
  484. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +19 -20
  485. package/src/resources/extensions/claude-code-cli/tests/partial-builder.test.ts +105 -0
  486. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +21 -0
  487. package/src/resources/extensions/gsd/auto/phases.ts +15 -1
  488. package/src/resources/extensions/gsd/auto/session.ts +6 -0
  489. package/src/resources/extensions/gsd/auto-dashboard.ts +31 -3
  490. package/src/resources/extensions/gsd/auto-dispatch.ts +102 -50
  491. package/src/resources/extensions/gsd/auto-observability.ts +72 -0
  492. package/src/resources/extensions/gsd/auto-post-unit.ts +56 -83
  493. package/src/resources/extensions/gsd/auto-prompts.ts +48 -0
  494. package/src/resources/extensions/gsd/auto-recovery.ts +19 -26
  495. package/src/resources/extensions/gsd/auto-start.ts +2 -0
  496. package/src/resources/extensions/gsd/auto-timers.ts +25 -1
  497. package/src/resources/extensions/gsd/auto-tool-tracking.ts +30 -6
  498. package/src/resources/extensions/gsd/auto-utils.ts +25 -0
  499. package/src/resources/extensions/gsd/auto-worktree.ts +21 -0
  500. package/src/resources/extensions/gsd/auto.ts +20 -7
  501. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +115 -72
  502. package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +11 -2
  503. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +18 -1
  504. package/src/resources/extensions/gsd/claude-import.ts +58 -9
  505. package/src/resources/extensions/gsd/commands/handlers/auto.ts +73 -6
  506. package/src/resources/extensions/gsd/commands-config.ts +11 -5
  507. package/src/resources/extensions/gsd/commands-prefs-wizard.ts +1 -1
  508. package/src/resources/extensions/gsd/crash-recovery.ts +6 -2
  509. package/src/resources/extensions/gsd/custom-execution-policy.ts +3 -2
  510. package/src/resources/extensions/gsd/custom-verification.ts +3 -1
  511. package/src/resources/extensions/gsd/custom-workflow-engine.ts +3 -2
  512. package/src/resources/extensions/gsd/dashboard-overlay.ts +7 -0
  513. package/src/resources/extensions/gsd/detection.ts +668 -9
  514. package/src/resources/extensions/gsd/dispatch-guard.ts +2 -1
  515. package/src/resources/extensions/gsd/docs/preferences-reference.md +18 -3
  516. package/src/resources/extensions/gsd/error-classifier.ts +139 -0
  517. package/src/resources/extensions/gsd/files.ts +6 -1
  518. package/src/resources/extensions/gsd/gitignore.ts +7 -7
  519. package/src/resources/extensions/gsd/gsd-db.ts +355 -63
  520. package/src/resources/extensions/gsd/guided-flow.ts +11 -0
  521. package/src/resources/extensions/gsd/init-wizard.ts +11 -3
  522. package/src/resources/extensions/gsd/key-manager.ts +7 -16
  523. package/src/resources/extensions/gsd/memory-store.ts +29 -18
  524. package/src/resources/extensions/gsd/milestone-actions.ts +17 -0
  525. package/src/resources/extensions/gsd/model-router.ts +25 -0
  526. package/src/resources/extensions/gsd/notifications.ts +23 -0
  527. package/src/resources/extensions/gsd/observability-validator.ts +456 -0
  528. package/src/resources/extensions/gsd/preferences-models.ts +1 -13
  529. package/src/resources/extensions/gsd/preferences-skills.ts +11 -5
  530. package/src/resources/extensions/gsd/preferences-types.ts +20 -0
  531. package/src/resources/extensions/gsd/preferences-validation.ts +26 -0
  532. package/src/resources/extensions/gsd/preferences.ts +15 -13
  533. package/src/resources/extensions/gsd/prompts/forensics.md +11 -7
  534. package/src/resources/extensions/gsd/prompts/system.md +1 -1
  535. package/src/resources/extensions/gsd/prompts/validate-milestone.md +6 -1
  536. package/src/resources/extensions/gsd/provider-error-pause.ts +0 -48
  537. package/src/resources/extensions/gsd/roadmap-mutations.ts +134 -0
  538. package/src/resources/extensions/gsd/rtk-status.ts +53 -0
  539. package/src/resources/extensions/gsd/rule-registry.ts +11 -12
  540. package/src/resources/extensions/gsd/service-tier.ts +14 -2
  541. package/src/resources/extensions/gsd/session-forensics.ts +7 -3
  542. package/src/resources/extensions/gsd/skill-catalog.ts +1085 -0
  543. package/src/resources/extensions/gsd/skill-discovery.ts +3 -2
  544. package/src/resources/extensions/gsd/skill-health.ts +2 -2
  545. package/src/resources/extensions/gsd/skill-telemetry.ts +15 -5
  546. package/src/resources/extensions/gsd/state.ts +38 -7
  547. package/src/resources/extensions/gsd/templates/{preferences.md → PREFERENCES.md} +2 -0
  548. package/src/resources/extensions/gsd/templates/milestone-validation.md +12 -0
  549. package/src/resources/extensions/gsd/tests/auto-dashboard.test.ts +16 -0
  550. package/src/resources/extensions/gsd/tests/auto-lock-creation.test.ts +2 -2
  551. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +68 -0
  552. package/src/resources/extensions/gsd/tests/auto-milestone-target.test.ts +61 -0
  553. package/src/resources/extensions/gsd/tests/claude-import-marketplace-discovery.test.ts +191 -0
  554. package/src/resources/extensions/gsd/tests/claude-import-tui.test.ts +1 -1
  555. package/src/resources/extensions/gsd/tests/commands-config.test.ts +24 -0
  556. package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +2 -2
  557. package/src/resources/extensions/gsd/tests/complete-slice.test.ts +2 -2
  558. package/src/resources/extensions/gsd/tests/complete-task-rollback-evidence.test.ts +106 -0
  559. package/src/resources/extensions/gsd/tests/complete-task.test.ts +2 -2
  560. package/src/resources/extensions/gsd/tests/crash-recovery.test.ts +5 -3
  561. package/src/resources/extensions/gsd/tests/custom-verification.test.ts +33 -0
  562. package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +39 -10
  563. package/src/resources/extensions/gsd/tests/detection.test.ts +839 -1
  564. package/src/resources/extensions/gsd/tests/dist-redirect.mjs +28 -9
  565. package/src/resources/extensions/gsd/tests/doctor-git.test.ts +4 -4
  566. package/src/resources/extensions/gsd/tests/doctor-proactive.test.ts +1 -1
  567. package/src/resources/extensions/gsd/tests/doctor-providers.test.ts +2 -2
  568. package/src/resources/extensions/gsd/tests/double-merge-guard.test.ts +97 -0
  569. package/src/resources/extensions/gsd/tests/empty-db-reconciliation.test.ts +79 -0
  570. package/src/resources/extensions/gsd/tests/git-service.test.ts +1 -1
  571. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +1 -1
  572. package/src/resources/extensions/gsd/tests/idle-recovery.test.ts +63 -0
  573. package/src/resources/extensions/gsd/tests/idle-watchdog-stall-override.test.ts +125 -0
  574. package/src/resources/extensions/gsd/tests/init-wizard.test.ts +1 -1
  575. package/src/resources/extensions/gsd/tests/interactive-tool-idle-exemption.test.ts +119 -0
  576. package/src/resources/extensions/gsd/tests/key-manager.test.ts +16 -1
  577. package/src/resources/extensions/gsd/tests/md-importer.test.ts +1 -1
  578. package/src/resources/extensions/gsd/tests/memory-store.test.ts +2 -2
  579. package/src/resources/extensions/gsd/tests/model-router.test.ts +40 -0
  580. package/src/resources/extensions/gsd/tests/none-mode-gates.test.ts +7 -7
  581. package/src/resources/extensions/gsd/tests/notifications.test.ts +28 -6
  582. package/src/resources/extensions/gsd/tests/park-db-sync.test.ts +85 -0
  583. package/src/resources/extensions/gsd/tests/plan-quality-validator.test.ts +474 -0
  584. package/src/resources/extensions/gsd/tests/preferences-worktree-sync.test.ts +91 -0
  585. package/src/resources/extensions/gsd/tests/preferences.test.ts +51 -1
  586. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +77 -70
  587. package/src/resources/extensions/gsd/tests/queue-reorder-e2e.test.ts +40 -0
  588. package/src/resources/extensions/gsd/tests/reactive-executor.test.ts +6 -6
  589. package/src/resources/extensions/gsd/tests/remediation-completion-guard.test.ts +110 -0
  590. package/src/resources/extensions/gsd/tests/remote-questions.test.ts +29 -0
  591. package/src/resources/extensions/gsd/tests/retry-diagnostic-reasoning.test.ts +161 -0
  592. package/src/resources/extensions/gsd/tests/retry-state-reset.test.ts +4 -5
  593. package/src/resources/extensions/gsd/tests/rewrite-count-persist.test.ts +82 -0
  594. package/src/resources/extensions/gsd/tests/run-uat.test.ts +146 -0
  595. package/src/resources/extensions/gsd/tests/sidecar-queue.test.ts +12 -12
  596. package/src/resources/extensions/gsd/tests/skill-catalog.test.ts +193 -0
  597. package/src/resources/extensions/gsd/tests/terminated-transient.test.ts +56 -21
  598. package/src/resources/extensions/gsd/tests/token-cost-display.test.ts +2 -2
  599. package/src/resources/extensions/gsd/tests/triage-dispatch.test.ts +2 -2
  600. package/src/resources/extensions/gsd/tests/vacuous-truth-slices.test.ts +115 -0
  601. package/src/resources/extensions/gsd/tests/validate-milestone-write-order.test.ts +90 -0
  602. package/src/resources/extensions/gsd/tests/workflow-logger.test.ts +81 -1
  603. package/src/resources/extensions/gsd/tests/worktree-preferences-sync.test.ts +130 -0
  604. package/src/resources/extensions/gsd/tools/complete-milestone.ts +3 -14
  605. package/src/resources/extensions/gsd/tools/complete-slice.ts +3 -21
  606. package/src/resources/extensions/gsd/tools/complete-task.ts +9 -22
  607. package/src/resources/extensions/gsd/tools/plan-milestone.ts +28 -18
  608. package/src/resources/extensions/gsd/tools/plan-slice.ts +28 -16
  609. package/src/resources/extensions/gsd/tools/plan-task.ts +24 -12
  610. package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +54 -42
  611. package/src/resources/extensions/gsd/tools/replan-slice.ts +53 -40
  612. package/src/resources/extensions/gsd/tools/validate-milestone.ts +26 -20
  613. package/src/resources/extensions/gsd/types.ts +2 -0
  614. package/src/resources/extensions/gsd/undo.ts +8 -7
  615. package/src/resources/extensions/gsd/unit-runtime.ts +2 -1
  616. package/src/resources/extensions/gsd/verification-gate.ts +3 -1
  617. package/src/resources/extensions/gsd/workflow-logger.ts +0 -1
  618. package/src/resources/extensions/remote-questions/config.ts +1 -1
  619. package/src/resources/extensions/remote-questions/remote-command.ts +1 -1
  620. package/src/resources/extensions/search-the-web/native-search.ts +1 -1
  621. package/src/resources/extensions/search-the-web/provider.ts +1 -1
  622. package/src/resources/extensions/shared/rtk-session-stats.ts +249 -0
  623. package/src/resources/extensions/shared/rtk.ts +120 -0
  624. package/dist/web/standalone/.next/server/chunks/229.js +0 -12
  625. package/dist/web/standalone/.next/server/chunks/441.js +0 -2
  626. package/dist/web/standalone/.next/server/chunks/471.js +0 -13
  627. package/dist/web/standalone/.next/static/MQOhBnkC_TLtNn_JvZWDj/_buildManifest.js +0 -1
  628. package/dist/web/standalone/.next/static/chunks/4024.7c75ac378de0f2b5.js +0 -9
  629. package/dist/web/standalone/.next/static/chunks/app/_global-error/page-d83ba70a25a85472.js +0 -1
  630. package/dist/web/standalone/.next/static/chunks/app/api/boot/route-d83ba70a25a85472.js +0 -1
  631. package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/input/route-d83ba70a25a85472.js +0 -1
  632. package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/resize/route-d83ba70a25a85472.js +0 -1
  633. package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/stream/route-d83ba70a25a85472.js +0 -1
  634. package/dist/web/standalone/.next/static/chunks/app/api/browse-directories/route-d83ba70a25a85472.js +0 -1
  635. package/dist/web/standalone/.next/static/chunks/app/api/captures/route-d83ba70a25a85472.js +0 -1
  636. package/dist/web/standalone/.next/static/chunks/app/api/cleanup/route-d83ba70a25a85472.js +0 -1
  637. package/dist/web/standalone/.next/static/chunks/app/api/dev-mode/route-d83ba70a25a85472.js +0 -1
  638. package/dist/web/standalone/.next/static/chunks/app/api/doctor/route-d83ba70a25a85472.js +0 -1
  639. package/dist/web/standalone/.next/static/chunks/app/api/export-data/route-d83ba70a25a85472.js +0 -1
  640. package/dist/web/standalone/.next/static/chunks/app/api/files/route-d83ba70a25a85472.js +0 -1
  641. package/dist/web/standalone/.next/static/chunks/app/api/forensics/route-d83ba70a25a85472.js +0 -1
  642. package/dist/web/standalone/.next/static/chunks/app/api/git/route-d83ba70a25a85472.js +0 -1
  643. package/dist/web/standalone/.next/static/chunks/app/api/history/route-d83ba70a25a85472.js +0 -1
  644. package/dist/web/standalone/.next/static/chunks/app/api/hooks/route-d83ba70a25a85472.js +0 -1
  645. package/dist/web/standalone/.next/static/chunks/app/api/inspect/route-d83ba70a25a85472.js +0 -1
  646. package/dist/web/standalone/.next/static/chunks/app/api/knowledge/route-d83ba70a25a85472.js +0 -1
  647. package/dist/web/standalone/.next/static/chunks/app/api/live-state/route-d83ba70a25a85472.js +0 -1
  648. package/dist/web/standalone/.next/static/chunks/app/api/onboarding/route-d83ba70a25a85472.js +0 -1
  649. package/dist/web/standalone/.next/static/chunks/app/api/preferences/route-d83ba70a25a85472.js +0 -1
  650. package/dist/web/standalone/.next/static/chunks/app/api/projects/route-d83ba70a25a85472.js +0 -1
  651. package/dist/web/standalone/.next/static/chunks/app/api/recovery/route-d83ba70a25a85472.js +0 -1
  652. package/dist/web/standalone/.next/static/chunks/app/api/remote-questions/route-d83ba70a25a85472.js +0 -1
  653. package/dist/web/standalone/.next/static/chunks/app/api/session/browser/route-d83ba70a25a85472.js +0 -1
  654. package/dist/web/standalone/.next/static/chunks/app/api/session/command/route-d83ba70a25a85472.js +0 -1
  655. package/dist/web/standalone/.next/static/chunks/app/api/session/events/route-d83ba70a25a85472.js +0 -1
  656. package/dist/web/standalone/.next/static/chunks/app/api/session/manage/route-d83ba70a25a85472.js +0 -1
  657. package/dist/web/standalone/.next/static/chunks/app/api/settings-data/route-d83ba70a25a85472.js +0 -1
  658. package/dist/web/standalone/.next/static/chunks/app/api/shutdown/route-d83ba70a25a85472.js +0 -1
  659. package/dist/web/standalone/.next/static/chunks/app/api/skill-health/route-d83ba70a25a85472.js +0 -1
  660. package/dist/web/standalone/.next/static/chunks/app/api/steer/route-d83ba70a25a85472.js +0 -1
  661. package/dist/web/standalone/.next/static/chunks/app/api/switch-root/route-d83ba70a25a85472.js +0 -1
  662. package/dist/web/standalone/.next/static/chunks/app/api/terminal/input/route-d83ba70a25a85472.js +0 -1
  663. package/dist/web/standalone/.next/static/chunks/app/api/terminal/resize/route-d83ba70a25a85472.js +0 -1
  664. package/dist/web/standalone/.next/static/chunks/app/api/terminal/sessions/route-d83ba70a25a85472.js +0 -1
  665. package/dist/web/standalone/.next/static/chunks/app/api/terminal/stream/route-d83ba70a25a85472.js +0 -1
  666. package/dist/web/standalone/.next/static/chunks/app/api/terminal/upload/route-d83ba70a25a85472.js +0 -1
  667. package/dist/web/standalone/.next/static/chunks/app/api/undo/route-d83ba70a25a85472.js +0 -1
  668. package/dist/web/standalone/.next/static/chunks/app/api/update/route-d83ba70a25a85472.js +0 -1
  669. package/dist/web/standalone/.next/static/chunks/app/api/visualizer/route-d83ba70a25a85472.js +0 -1
  670. package/dist/web/standalone/.next/static/chunks/app/page-12dd5ece0df4badc.js +0 -1
  671. package/dist/web/standalone/.next/static/chunks/main-app-d3d4c336195465f9.js +0 -1
  672. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/app-error-d83ba70a25a85472.js +0 -1
  673. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/forbidden-d83ba70a25a85472.js +0 -1
  674. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ab5a8926e07ec673.js +0 -1
  675. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/not-found-d83ba70a25a85472.js +0 -1
  676. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/unauthorized-d83ba70a25a85472.js +0 -1
  677. package/dist/web/standalone/.next/static/chunks/webpack-2473ce2c3879fff4.js +0 -1
  678. package/dist/web/standalone/.next/static/css/dd4ae3f58ac9b600.css +0 -1
  679. package/packages/pi-ai/pnpm-lock.yaml +0 -2022
  680. package/packages/pi-coding-agent/pnpm-lock.yaml +0 -454
  681. /package/dist/web/standalone/.next/static/{MQOhBnkC_TLtNn_JvZWDj → RqOU-jOv9uZ1Q03P6L6nn}/_ssgManifest.js +0 -0
@@ -9,7 +9,7 @@ import { readUnitRuntimeRecord, writeUnitRuntimeRecord } from "./unit-runtime.js
9
9
  import { isDbAvailable, getMilestoneSlices, getSliceTasks } from "./gsd-db.js";
10
10
  import { resolveAutoSupervisorConfig } from "./preferences.js";
11
11
  import { computeBudgets, resolveExecutorContextWindow } from "./context-budget.js";
12
- import { getInFlightToolCount, getOldestInFlightToolStart, } from "./auto-tool-tracking.js";
12
+ import { getInFlightToolCount, getOldestInFlightToolStart, clearInFlightTools, hasInteractiveToolInFlight, } from "./auto-tool-tracking.js";
13
13
  import { detectWorkingTreeActivity } from "./auto-supervisor.js";
14
14
  import { closeoutUnit } from "./auto-unit-closeout.js";
15
15
  import { saveActivityLog } from "./activity-log.js";
@@ -116,7 +116,17 @@ export function startUnitSupervision(sctx) {
116
116
  return;
117
117
  // Agent has tool calls currently executing — not idle, just waiting.
118
118
  // But only suppress recovery if the tool started recently.
119
+ let stalledToolDetected = false;
119
120
  if (getInFlightToolCount() > 0) {
121
+ // User-interactive tools (ask_user_questions, secure_env_collect) block
122
+ // waiting for human input by design — never treat them as stalled (#2676).
123
+ if (hasInteractiveToolInFlight()) {
124
+ writeUnitRuntimeRecord(s.basePath, unitType, unitId, s.currentUnit.startedAt, {
125
+ lastProgressAt: Date.now(),
126
+ lastProgressKind: "interactive-tool-waiting",
127
+ });
128
+ return;
129
+ }
120
130
  const oldestStart = getOldestInFlightToolStart();
121
131
  const toolAgeMs = Date.now() - oldestStart;
122
132
  if (toolAgeMs < idleTimeoutMs) {
@@ -126,10 +136,18 @@ export function startUnitSupervision(sctx) {
126
136
  });
127
137
  return;
128
138
  }
139
+ // Tool has been in-flight longer than idle timeout — treat as hung.
140
+ // Clear the stale entries so subsequent ticks don't re-detect them,
141
+ // and set the flag so the filesystem-activity check below does not
142
+ // override the stall verdict (#2527).
143
+ stalledToolDetected = true;
144
+ clearInFlightTools();
129
145
  ctx.ui.notify(`Stalled tool detected: a tool has been in-flight for ${Math.round(toolAgeMs / 60000)}min. Treating as hung — attempting idle recovery.`, "warning");
130
146
  }
131
147
  // Check if the agent is producing work on disk.
132
- if (detectWorkingTreeActivity(s.basePath)) {
148
+ // Skip this when a stalled tool was just detected — filesystem changes
149
+ // from earlier in the task should not override the stall verdict (#2527).
150
+ if (!stalledToolDetected && detectWorkingTreeActivity(s.basePath)) {
133
151
  writeUnitRuntimeRecord(s.basePath, unitType, unitId, s.currentUnit.startedAt, {
134
152
  lastProgressAt: Date.now(),
135
153
  lastProgressKind: "filesystem-activity",
@@ -145,6 +163,10 @@ export function startUnitSupervision(sctx) {
145
163
  const recovery = await recoverTimedOutUnit(ctx, pi, unitType, unitId, "idle", buildRecoveryContext());
146
164
  if (recovery === "recovered")
147
165
  return;
166
+ // Guard: recoverTimedOutUnit is async — pauseAuto/stopAuto may have
167
+ // set s.currentUnit = null during the await (#2527).
168
+ if (!s.currentUnit)
169
+ return;
148
170
  writeUnitRuntimeRecord(s.basePath, unitType, unitId, s.currentUnit.startedAt, {
149
171
  phase: "paused",
150
172
  });
@@ -4,14 +4,20 @@
4
4
  * can distinguish "waiting for tool completion" from "truly idle".
5
5
  */
6
6
  const inFlightTools = new Map();
7
+ /**
8
+ * Tools that block waiting for human input by design.
9
+ * The idle watchdog must not treat these as stalled.
10
+ */
11
+ const INTERACTIVE_TOOLS = new Set(["ask_user_questions", "secure_env_collect"]);
7
12
  /**
8
13
  * Mark a tool execution as in-flight.
9
- * Records start time so the idle watchdog can detect tools hung longer than the idle timeout.
14
+ * Records start time and tool name so the idle watchdog can detect tools
15
+ * hung longer than the idle timeout while exempting interactive tools.
10
16
  */
11
- export function markToolStart(toolCallId, isActive) {
17
+ export function markToolStart(toolCallId, isActive, toolName) {
12
18
  if (!isActive)
13
19
  return;
14
- inFlightTools.set(toolCallId, Date.now());
20
+ inFlightTools.set(toolCallId, { startedAt: Date.now(), toolName: toolName ?? "unknown" });
15
21
  }
16
22
  /**
17
23
  * Mark a tool execution as completed.
@@ -27,8 +33,8 @@ export function getOldestInFlightToolAgeMs() {
27
33
  return 0;
28
34
  let oldestStart = Infinity;
29
35
  for (const t of inFlightTools.values()) {
30
- if (t < oldestStart)
31
- oldestStart = t;
36
+ if (t.startedAt < oldestStart)
37
+ oldestStart = t.startedAt;
32
38
  }
33
39
  return Date.now() - oldestStart;
34
40
  }
@@ -46,11 +52,23 @@ export function getOldestInFlightToolStart() {
46
52
  return undefined;
47
53
  let oldest = Infinity;
48
54
  for (const t of inFlightTools.values()) {
49
- if (t < oldest)
50
- oldest = t;
55
+ if (t.startedAt < oldest)
56
+ oldest = t.startedAt;
51
57
  }
52
58
  return oldest;
53
59
  }
60
+ /**
61
+ * Returns true if any currently in-flight tool is a user-interactive tool
62
+ * (e.g. ask_user_questions, secure_env_collect) that blocks waiting for
63
+ * human input. These must be exempt from idle stall detection.
64
+ */
65
+ export function hasInteractiveToolInFlight() {
66
+ for (const { toolName } of inFlightTools.values()) {
67
+ if (INTERACTIVE_TOOLS.has(toolName))
68
+ return true;
69
+ }
70
+ return false;
71
+ }
54
72
  /**
55
73
  * Clear all in-flight tool tracking state.
56
74
  */
@@ -0,0 +1,20 @@
1
+ // Shared utilities for the auto-loop modules (auto-post-unit, auto, etc.).
2
+ import { debugLog } from "./debug-logger.js";
3
+ /**
4
+ * Run a non-fatal operation, logging any error via `debugLog` and continuing.
5
+ *
6
+ * Replaces the repeated try-catch-debugLog-continue boilerplate that wraps
7
+ * operations whose failure should not abort the post-unit pipeline.
8
+ *
9
+ * @param context - The debugLog event name (e.g. "postUnit")
10
+ * @param phase - The phase label attached to the debug entry
11
+ * @param fn - The operation to execute (may be sync or async)
12
+ */
13
+ export async function runSafely(context, phase, fn) {
14
+ try {
15
+ await fn();
16
+ }
17
+ catch (e) {
18
+ debugLog(context, { phase, error: String(e) });
19
+ }
20
+ }
@@ -37,6 +37,10 @@ const ROOT_STATE_FILES = [
37
37
  "QUEUE.md",
38
38
  "completed-units.json",
39
39
  "metrics.json",
40
+ // NOTE: preferences.md is intentionally NOT in ROOT_STATE_FILES.
41
+ // Forward-sync (main → worktree) is handled explicitly in syncGsdStateToWorktree().
42
+ // Back-sync (worktree → main) must NEVER overwrite the project root's copy
43
+ // because the project root is authoritative for preferences (#2684).
40
44
  ];
41
45
  /**
42
46
  * Check if two filesystem paths resolve to the same real location.
@@ -319,6 +323,22 @@ export function syncGsdStateToWorktree(mainBasePath, worktreePath_) {
319
323
  }
320
324
  }
321
325
  }
326
+ // Forward-sync preferences.md from project root to worktree (additive only).
327
+ // NOT in ROOT_STATE_FILES because syncWorktreeStateBack() must never overwrite
328
+ // the project root's preferences — the project root is authoritative (#2684).
329
+ {
330
+ const src = join(mainGsd, "preferences.md");
331
+ const dst = join(wtGsd, "preferences.md");
332
+ if (existsSync(src) && !existsSync(dst)) {
333
+ try {
334
+ cpSync(src, dst);
335
+ synced.push("preferences.md");
336
+ }
337
+ catch {
338
+ /* non-fatal */
339
+ }
340
+ }
341
+ }
322
342
  // Sync milestones: copy entire milestone directories that are missing
323
343
  const mainMilestonesDir = join(mainGsd, "milestones");
324
344
  const wtMilestonesDir = join(wtGsd, "milestones");
@@ -801,6 +821,7 @@ function copyPlanningArtifacts(srcBase, wtPath) {
801
821
  "STATE.md",
802
822
  "KNOWLEDGE.md",
803
823
  "OVERRIDES.md",
824
+ "preferences.md",
804
825
  ]) {
805
826
  safeCopy(join(srcGsd, file), join(dstGsd, file), { force: true });
806
827
  }
@@ -10,6 +10,7 @@
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";
@@ -31,7 +32,9 @@ import { runGSDDoctor, rebuildState } from "./doctor.js";
31
32
  import { preDispatchHealthGate, resetProactiveHealing, setLevelChangeCallback, } from "./doctor-proactive.js";
32
33
  import { clearSkillSnapshot } from "./skill-discovery.js";
33
34
  import { captureAvailableSkills, resetSkillTelemetry, } from "./skill-telemetry.js";
35
+ import { getRtkSessionSavings } from "../shared/rtk-session-stats.js";
34
36
  import { initMetrics, resetMetrics, getLedger, getProjectTotals, formatCost, formatTokenCount, } from "./metrics.js";
37
+ import { setLogBasePath } from "./workflow-logger.js";
35
38
  import { join } from "node:path";
36
39
  import { readFileSync, existsSync, mkdirSync, writeFileSync, unlinkSync } from "node:fs";
37
40
  import { atomicWriteSync } from "./atomic-write.js";
@@ -122,6 +125,11 @@ function deregisterSigtermHandler() {
122
125
  export function getAutoDashboardData() {
123
126
  const ledger = getLedger();
124
127
  const totals = ledger ? getProjectTotals(ledger.units) : null;
128
+ const sessionId = s.cmdCtx?.sessionManager?.getSessionId?.() ?? null;
129
+ const rtkSavings = sessionId && s.basePath
130
+ ? getRtkSessionSavings(s.basePath, sessionId)
131
+ : null;
132
+ const rtkEnabled = loadEffectiveGSDPreferences()?.preferences.experimental?.rtk === true;
125
133
  // Pending capture count — lazy check, non-fatal
126
134
  let pendingCaptureCount = 0;
127
135
  try {
@@ -145,6 +153,8 @@ export function getAutoDashboardData() {
145
153
  totalCost: totals?.cost ?? 0,
146
154
  totalTokens: totals?.tokens.total ?? 0,
147
155
  pendingCaptureCount,
156
+ rtkSavings,
157
+ rtkEnabled,
148
158
  };
149
159
  }
150
160
  // ─── Public API ───────────────────────────────────────────────────────────────
@@ -175,8 +185,8 @@ export function getAutoModeStartModel() {
175
185
  return s.autoModeStartModel;
176
186
  }
177
187
  // Tool tracking — delegates to auto-tool-tracking.ts
178
- export function markToolStart(toolCallId) {
179
- _markToolStart(toolCallId, s.active);
188
+ export function markToolStart(toolCallId, toolName) {
189
+ _markToolStart(toolCallId, s.active, toolName);
180
190
  }
181
191
  export function markToolEnd(toolCallId) {
182
192
  _markToolEnd(toolCallId);
@@ -361,8 +371,11 @@ export async function stopAuto(ctx, pi, reason) {
361
371
  // When the milestone is complete (has a SUMMARY), merge the worktree branch
362
372
  // back to main so code isn't stranded on the worktree branch (#2317).
363
373
  // For incomplete milestones, preserve the branch for later resumption.
374
+ //
375
+ // Skip if phases.ts already merged this milestone — avoids the double
376
+ // mergeAndExit that fails because the branch was already deleted (#2645).
364
377
  try {
365
- if (s.currentMilestoneId) {
378
+ if (s.currentMilestoneId && !s.milestoneMergedInPhases) {
366
379
  const notifyCtx = ctx
367
380
  ? { notify: ctx.ui.notify.bind(ctx.ui) }
368
381
  : { notify: () => { } };
@@ -803,6 +816,7 @@ export async function startAuto(ctx, pi, base, verboseMode, options) {
803
816
  s.stepMode = requestedStepMode;
804
817
  s.cmdCtx = ctx;
805
818
  s.basePath = base;
819
+ setLogBasePath(base);
806
820
  s.unitDispatchCount.clear();
807
821
  s.unitLifetimeDispatches.clear();
808
822
  if (!getLedger())
@@ -927,15 +941,13 @@ const widgetStateAccessors = {
927
941
  * dispatching a unit. The LLM should never need to mkdir or git checkout.
928
942
  */
929
943
  function ensurePreconditions(unitType, unitId, base, state) {
930
- const parts = unitId.split("/");
931
- const mid = parts[0];
944
+ const { milestone: mid, slice: sid } = parseUnitId(unitId);
932
945
  const mDir = resolveMilestonePath(base, mid);
933
946
  if (!mDir) {
934
947
  const newDir = join(milestonesDir(base), mid);
935
948
  mkdirSync(join(newDir, "slices"), { recursive: true });
936
949
  }
937
- if (parts.length >= 2) {
938
- const sid = parts[1];
950
+ if (sid !== undefined) {
939
951
  const mDirResolved = resolveMilestonePath(base, mid);
940
952
  if (mDirResolved) {
941
953
  const slicesDir = join(mDirResolved, "slices");
@@ -1,12 +1,33 @@
1
1
  import { checkAutoStartAfterDiscuss } from "../guided-flow.js";
2
2
  import { getAutoDashboardData, getAutoModeStartModel, isAutoActive, pauseAuto } from "../auto.js";
3
- import { getNextFallbackModel, isTransientNetworkError, resolveModelWithFallbacksForUnit } from "../preferences.js";
4
- import { classifyProviderError, pauseAutoForProviderError } from "../provider-error-pause.js";
3
+ import { getNextFallbackModel, resolveModelWithFallbacksForUnit } from "../preferences.js";
4
+ import { pauseAutoForProviderError } from "../provider-error-pause.js";
5
5
  import { isSessionSwitchInFlight, resolveAgentEnd } from "../auto-loop.js";
6
+ import { resolveModelId } from "../auto-model-selection.js";
6
7
  import { clearDiscussionFlowState } from "./write-gate.js";
7
- const networkRetryCounters = new Map();
8
+ import { classifyError, createRetryState, resetRetryState, isTransient, } from "../error-classifier.js";
9
+ const retryState = createRetryState();
10
+ const MAX_NETWORK_RETRIES = 2;
8
11
  const MAX_TRANSIENT_AUTO_RESUMES = 3;
9
- let consecutiveTransientErrors = 0;
12
+ async function pauseTransientWithBackoff(cls, pi, ctx, errorDetail, isRateLimit) {
13
+ retryState.consecutiveTransientCount += 1;
14
+ const baseRetryAfterMs = "retryAfterMs" in cls ? cls.retryAfterMs : 15_000;
15
+ const retryAfterMs = baseRetryAfterMs * 2 ** Math.max(0, retryState.consecutiveTransientCount - 1);
16
+ const allowAutoResume = retryState.consecutiveTransientCount <= MAX_TRANSIENT_AUTO_RESUMES;
17
+ if (!allowAutoResume) {
18
+ ctx.ui.notify(`Transient provider errors persisted after ${MAX_TRANSIENT_AUTO_RESUMES} auto-resume attempts. Pausing for manual review.`, "warning");
19
+ }
20
+ await pauseAutoForProviderError(ctx.ui, errorDetail, () => pauseAuto(ctx, pi), {
21
+ isRateLimit,
22
+ isTransient: allowAutoResume,
23
+ retryAfterMs,
24
+ resume: allowAutoResume
25
+ ? () => {
26
+ pi.sendMessage({ customType: "gsd-auto-timeout-recovery", content: "Continue execution — provider error recovery delay elapsed.", display: false }, { triggerTurn: true });
27
+ }
28
+ : undefined,
29
+ });
30
+ }
10
31
  export async function handleAgentEnd(pi, event, ctx) {
11
32
  if (checkAutoStartAfterDiscuss()) {
12
33
  clearDiscussionFlowState();
@@ -24,93 +45,98 @@ export async function handleAgentEnd(pi, event, ctx) {
24
45
  if (lastMsg && "stopReason" in lastMsg && lastMsg.stopReason === "error") {
25
46
  const errorDetail = "errorMessage" in lastMsg && lastMsg.errorMessage ? `: ${lastMsg.errorMessage}` : "";
26
47
  const errorMsg = ("errorMessage" in lastMsg && lastMsg.errorMessage) ? String(lastMsg.errorMessage) : "";
27
- if (isTransientNetworkError(errorMsg)) {
48
+ const explicitRetryAfterMs = ("retryAfterMs" in lastMsg && typeof lastMsg.retryAfterMs === "number") ? lastMsg.retryAfterMs : undefined;
49
+ // ── 1. Classify ──────────────────────────────────────────────────────
50
+ const cls = classifyError(errorMsg, explicitRetryAfterMs);
51
+ // ── 2. Decide & Act ──────────────────────────────────────────────────
52
+ // --- Network errors: same-model retry with backoff ---
53
+ if (cls.kind === "network") {
28
54
  const currentModelId = ctx.model?.id ?? "unknown";
29
- const retryKey = `network-retry:${currentModelId}`;
30
- const currentRetries = networkRetryCounters.get(retryKey) ?? 0;
31
- const maxRetries = 2;
32
- if (currentRetries < maxRetries) {
33
- networkRetryCounters.set(retryKey, currentRetries + 1);
34
- const attempt = currentRetries + 1;
35
- const delayMs = attempt * 3000;
36
- ctx.ui.notify(`Network error on ${currentModelId}${errorDetail}. Retry ${attempt}/${maxRetries} in ${delayMs / 1000}s...`, "warning");
55
+ if (retryState.currentRetryModelId !== currentModelId) {
56
+ retryState.networkRetryCount = 0;
57
+ retryState.currentRetryModelId = currentModelId;
58
+ }
59
+ if (retryState.networkRetryCount < MAX_NETWORK_RETRIES) {
60
+ retryState.networkRetryCount += 1;
61
+ retryState.consecutiveTransientCount += 1;
62
+ const attempt = retryState.networkRetryCount;
63
+ const delayMs = attempt * cls.retryAfterMs;
64
+ ctx.ui.notify(`Network error on ${currentModelId}${errorDetail}. Retry ${attempt}/${MAX_NETWORK_RETRIES} in ${delayMs / 1000}s...`, "warning");
37
65
  setTimeout(() => {
38
66
  pi.sendMessage({ customType: "gsd-auto-timeout-recovery", content: "Continue execution — retrying after transient network error.", display: false }, { triggerTurn: true });
39
67
  }, delayMs);
40
68
  return;
41
69
  }
42
- networkRetryCounters.delete(retryKey);
70
+ // Network retries exhausted — fall through to model fallback
71
+ retryState.networkRetryCount = 0;
72
+ retryState.currentRetryModelId = undefined;
43
73
  ctx.ui.notify(`Network retries exhausted for ${currentModelId}. Attempting model fallback.`, "warning");
44
74
  }
45
- const dash = getAutoDashboardData();
46
- if (dash.currentUnit) {
47
- const modelConfig = resolveModelWithFallbacksForUnit(dash.currentUnit.type);
48
- if (modelConfig && modelConfig.fallbacks.length > 0) {
49
- const availableModels = ctx.modelRegistry.getAvailable();
50
- const nextModelId = getNextFallbackModel(ctx.model?.id, modelConfig);
51
- if (nextModelId) {
52
- networkRetryCounters.clear();
53
- const slashIdx = nextModelId.indexOf("/");
54
- const modelToSet = slashIdx !== -1
55
- ? availableModels.find((m) => m.provider.toLowerCase() === nextModelId.substring(0, slashIdx).toLowerCase() && m.id.toLowerCase() === nextModelId.substring(slashIdx + 1).toLowerCase())
56
- : (availableModels.find((m) => m.id === nextModelId && m.provider === ctx.model?.provider) ?? availableModels.find((m) => m.id === nextModelId));
57
- if (modelToSet) {
58
- const ok = await pi.setModel(modelToSet, { persist: false });
59
- if (ok) {
60
- ctx.ui.notify(`Model error${errorDetail}. Switched to fallback: ${nextModelId} and resuming.`, "warning");
61
- pi.sendMessage({ customType: "gsd-auto-timeout-recovery", content: "Continue execution.", display: false }, { triggerTurn: true });
62
- return;
75
+ // --- Rate limit: skip model fallback, go straight to pause ---
76
+ // Rate-limiting is a provider issue, not a model issue.
77
+ // Switching models won't help if the provider is throttling you.
78
+ if (cls.kind === "rate-limit") {
79
+ await pauseTransientWithBackoff(cls, pi, ctx, errorDetail, true);
80
+ return;
81
+ }
82
+ // --- Server/connection/stream errors: try model fallback first ---
83
+ if (cls.kind === "network" || cls.kind === "server" || cls.kind === "connection" || cls.kind === "stream") {
84
+ // Try model fallback
85
+ const dash = getAutoDashboardData();
86
+ if (dash.currentUnit) {
87
+ const modelConfig = resolveModelWithFallbacksForUnit(dash.currentUnit.type);
88
+ if (modelConfig && modelConfig.fallbacks.length > 0) {
89
+ const availableModels = ctx.modelRegistry.getAvailable();
90
+ const nextModelId = getNextFallbackModel(ctx.model?.id, modelConfig);
91
+ if (nextModelId) {
92
+ retryState.networkRetryCount = 0;
93
+ retryState.currentRetryModelId = undefined;
94
+ const modelToSet = resolveModelId(nextModelId, availableModels, ctx.model?.provider);
95
+ if (modelToSet) {
96
+ const ok = await pi.setModel(modelToSet, { persist: false });
97
+ if (ok) {
98
+ ctx.ui.notify(`Model error${errorDetail}. Switched to fallback: ${nextModelId} and resuming.`, "warning");
99
+ pi.sendMessage({ customType: "gsd-auto-timeout-recovery", content: "Continue execution.", display: false }, { triggerTurn: true });
100
+ return;
101
+ }
63
102
  }
64
103
  }
65
104
  }
66
105
  }
67
- }
68
- const sessionModel = getAutoModeStartModel();
69
- if (sessionModel) {
70
- if (ctx.model?.id !== sessionModel.id || ctx.model?.provider !== sessionModel.provider) {
71
- const startModel = ctx.modelRegistry.getAvailable().find((m) => m.provider === sessionModel.provider && m.id === sessionModel.id);
72
- if (startModel) {
73
- const ok = await pi.setModel(startModel, { persist: false });
74
- if (ok) {
75
- networkRetryCounters.clear();
76
- ctx.ui.notify(`Model error${errorDetail}. Restored session model: ${sessionModel.provider}/${sessionModel.id} and resuming.`, "warning");
77
- pi.sendMessage({ customType: "gsd-auto-timeout-recovery", content: "Continue execution.", display: false }, { triggerTurn: true });
78
- return;
106
+ // Try restoring session model
107
+ const sessionModel = getAutoModeStartModel();
108
+ if (sessionModel) {
109
+ if (ctx.model?.id !== sessionModel.id || ctx.model?.provider !== sessionModel.provider) {
110
+ const startModel = ctx.modelRegistry.getAvailable().find((m) => m.provider === sessionModel.provider && m.id === sessionModel.id);
111
+ if (startModel) {
112
+ const ok = await pi.setModel(startModel, { persist: false });
113
+ if (ok) {
114
+ retryState.networkRetryCount = 0;
115
+ retryState.currentRetryModelId = undefined;
116
+ ctx.ui.notify(`Model error${errorDetail}. Restored session model: ${sessionModel.provider}/${sessionModel.id} and resuming.`, "warning");
117
+ pi.sendMessage({ customType: "gsd-auto-timeout-recovery", content: "Continue execution.", display: false }, { triggerTurn: true });
118
+ return;
119
+ }
79
120
  }
80
121
  }
81
122
  }
82
123
  }
83
- const classification = classifyProviderError(errorMsg);
84
- const explicitRetryAfterMs = ("retryAfterMs" in lastMsg && typeof lastMsg.retryAfterMs === "number") ? lastMsg.retryAfterMs : undefined;
85
- if (classification.isTransient) {
86
- consecutiveTransientErrors += 1;
87
- }
88
- else {
89
- consecutiveTransientErrors = 0;
90
- }
91
- const baseRetryAfterMs = explicitRetryAfterMs ?? classification.suggestedDelayMs;
92
- const retryAfterMs = classification.isTransient
93
- ? baseRetryAfterMs * 2 ** Math.max(0, consecutiveTransientErrors - 1)
94
- : baseRetryAfterMs;
95
- const allowAutoResume = classification.isTransient && consecutiveTransientErrors <= MAX_TRANSIENT_AUTO_RESUMES;
96
- if (classification.isTransient && !allowAutoResume) {
97
- ctx.ui.notify(`Transient provider errors persisted after ${MAX_TRANSIENT_AUTO_RESUMES} auto-resume attempts. Pausing for manual review.`, "warning");
124
+ // --- Transient fallback: pause with auto-resume ---
125
+ if (isTransient(cls)) {
126
+ await pauseTransientWithBackoff(cls, pi, ctx, errorDetail, false);
127
+ return;
98
128
  }
129
+ // --- Permanent / unknown: pause indefinitely ---
99
130
  await pauseAutoForProviderError(ctx.ui, errorDetail, () => pauseAuto(ctx, pi), {
100
- isRateLimit: classification.isRateLimit,
101
- isTransient: allowAutoResume,
102
- retryAfterMs,
103
- resume: allowAutoResume
104
- ? () => {
105
- pi.sendMessage({ customType: "gsd-auto-timeout-recovery", content: "Continue execution — provider error recovery delay elapsed.", display: false }, { triggerTurn: true });
106
- }
107
- : undefined,
131
+ isRateLimit: false,
132
+ isTransient: false,
133
+ retryAfterMs: 0,
108
134
  });
109
135
  return;
110
136
  }
137
+ // ── Success path ─────────────────────────────────────────────────────────
111
138
  try {
112
- consecutiveTransientErrors = 0;
113
- networkRetryCounters.clear();
139
+ resetRetryState(retryState);
114
140
  resolveAgentEnd(event);
115
141
  }
116
142
  catch (err) {
@@ -2,6 +2,7 @@ import { existsSync } from "node:fs";
2
2
  import { join, sep } from "node:path";
3
3
  import { createBashTool, createEditTool, createReadTool, createWriteTool } from "@gsd/pi-coding-agent";
4
4
  import { DEFAULT_BASH_TIMEOUT_SECS } from "../constants.js";
5
+ import { setLogBasePath } from "../workflow-logger.js";
5
6
  /**
6
7
  * Resolve the correct DB path for the current working directory.
7
8
  * If `basePath` is inside a `.gsd/worktrees/<MID>/` directory, returns
@@ -35,9 +36,14 @@ export async function ensureDbOpen() {
35
36
  const basePath = process.cwd();
36
37
  const dbPath = resolveProjectRootDbPath(basePath);
37
38
  const gsdDir = join(basePath, ".gsd");
39
+ // Derive the project root from the DB path (strip .gsd/gsd.db)
40
+ const projectRoot = join(dbPath, "..", "..");
38
41
  // Open existing DB file (may be at project root for worktrees)
39
42
  if (existsSync(dbPath)) {
40
- return db.openDatabase(dbPath);
43
+ const opened = db.openDatabase(dbPath);
44
+ if (opened)
45
+ setLogBasePath(projectRoot);
46
+ return opened;
41
47
  }
42
48
  // No DB file — create + migrate from Markdown if .gsd/ has content
43
49
  if (existsSync(gsdDir)) {
@@ -47,6 +53,7 @@ export async function ensureDbOpen() {
47
53
  if (hasDecisions || hasRequirements || hasMilestones) {
48
54
  const opened = db.openDatabase(dbPath);
49
55
  if (opened) {
56
+ setLogBasePath(projectRoot);
50
57
  try {
51
58
  const { migrateFromMarkdown } = await import("../md-importer.js");
52
59
  migrateFromMarkdown(basePath);
@@ -58,7 +65,10 @@ export async function ensureDbOpen() {
58
65
  return opened;
59
66
  }
60
67
  // .gsd/ exists but has no Markdown content (fresh project) — create empty DB
61
- return db.openDatabase(dbPath);
68
+ const opened = db.openDatabase(dbPath);
69
+ if (opened)
70
+ setLogBasePath(projectRoot);
71
+ return opened;
62
72
  }
63
73
  return false;
64
74
  }
@@ -13,6 +13,8 @@ import { getAutoDashboardData, isAutoActive, isAutoPaused, markToolEnd, markTool
13
13
  import { isParallelActive, shutdownParallel } from "../parallel-orchestrator.js";
14
14
  import { checkToolCallLoop, resetToolCallLoopGuard } from "./tool-call-loop-guard.js";
15
15
  import { saveActivityLog } from "../activity-log.js";
16
+ import { startRtkStatusUpdates, stopRtkStatusUpdates } from "../rtk-status.js";
17
+ import { rewriteCommandWithRtk } from "../../shared/rtk.js";
16
18
  // Skip the welcome screen on the very first session_start — cli.ts already
17
19
  // printed it before the TUI launched. Only re-print on /clear (subsequent sessions).
18
20
  let isFirstSession = true;
@@ -21,10 +23,19 @@ async function syncServiceTierStatus(ctx) {
21
23
  ctx.ui.setStatus("gsd-fast", formatServiceTierFooterStatus(getEffectiveServiceTier(), ctx.model?.id));
22
24
  }
23
25
  export function registerHooks(pi) {
26
+ // Route all agent bash tool commands through RTK rewrite when opted in.
27
+ // This is a no-op when RTK is disabled or not installed.
28
+ pi.on("bash_transform", async (event) => {
29
+ const rewritten = rewriteCommandWithRtk(event.command);
30
+ if (rewritten === event.command)
31
+ return undefined;
32
+ return { command: rewritten };
33
+ });
24
34
  pi.on("session_start", async (_event, ctx) => {
25
35
  resetWriteGateState();
26
36
  resetToolCallLoopGuard();
27
37
  await syncServiceTierStatus(ctx);
38
+ startRtkStatusUpdates(ctx);
28
39
  // Apply show_token_cost preference (#1515)
29
40
  try {
30
41
  const { loadEffectiveGSDPreferences } = await import("../preferences.js");
@@ -69,6 +80,10 @@ export function registerHooks(pi) {
69
80
  clearDiscussionFlowState();
70
81
  await syncServiceTierStatus(ctx);
71
82
  loadToolApiKeys();
83
+ startRtkStatusUpdates(ctx);
84
+ });
85
+ pi.on("session_fork", async (_event, ctx) => {
86
+ startRtkStatusUpdates(ctx);
72
87
  });
73
88
  pi.on("before_agent_start", async (event, ctx) => {
74
89
  return buildBeforeAgentStartResult(event, ctx);
@@ -115,6 +130,7 @@ export function registerHooks(pi) {
115
130
  }));
116
131
  });
117
132
  pi.on("session_shutdown", async (_event, ctx) => {
133
+ stopRtkStatusUpdates(ctx);
118
134
  if (isParallelActive()) {
119
135
  try {
120
136
  await shutdownParallel(process.cwd());
@@ -211,7 +227,7 @@ export function registerHooks(pi) {
211
227
  pi.on("tool_execution_start", async (event) => {
212
228
  if (!isAutoActive())
213
229
  return;
214
- markToolStart(event.toolCallId);
230
+ markToolStart(event.toolCallId, event.toolName);
215
231
  });
216
232
  pi.on("tool_execution_end", async (event) => {
217
233
  markToolEnd(event.toolCallId);