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
@@ -75,25 +75,34 @@ function normalizeRows(rows) {
75
75
  }
76
76
  function createAdapter(rawDb) {
77
77
  const db = rawDb;
78
+ const stmtCache = new Map();
79
+ function wrapStmt(raw) {
80
+ return {
81
+ run(...params) {
82
+ return raw.run(...params);
83
+ },
84
+ get(...params) {
85
+ return normalizeRow(raw.get(...params));
86
+ },
87
+ all(...params) {
88
+ return normalizeRows(raw.all(...params));
89
+ },
90
+ };
91
+ }
78
92
  return {
79
93
  exec(sql) {
80
94
  db.exec(sql);
81
95
  },
82
96
  prepare(sql) {
83
- const stmt = db.prepare(sql);
84
- return {
85
- run(...params) {
86
- return stmt.run(...params);
87
- },
88
- get(...params) {
89
- return normalizeRow(stmt.get(...params));
90
- },
91
- all(...params) {
92
- return normalizeRows(stmt.all(...params));
93
- },
94
- };
97
+ let cached = stmtCache.get(sql);
98
+ if (cached)
99
+ return cached;
100
+ cached = wrapStmt(db.prepare(sql));
101
+ stmtCache.set(sql, cached);
102
+ return cached;
95
103
  },
96
104
  close() {
105
+ stmtCache.clear();
97
106
  db.close();
98
107
  },
99
108
  };
@@ -109,12 +118,21 @@ function openRawDb(path) {
109
118
  const Database = providerModule;
110
119
  return new Database(path);
111
120
  }
112
- const SCHEMA_VERSION = 12;
121
+ const SCHEMA_VERSION = 14;
113
122
  function initSchema(db, fileBacked) {
114
123
  if (fileBacked)
115
124
  db.exec("PRAGMA journal_mode=WAL");
116
125
  if (fileBacked)
117
126
  db.exec("PRAGMA busy_timeout = 5000");
127
+ if (fileBacked)
128
+ db.exec("PRAGMA synchronous = NORMAL");
129
+ if (fileBacked)
130
+ db.exec("PRAGMA auto_vacuum = INCREMENTAL");
131
+ if (fileBacked)
132
+ db.exec("PRAGMA cache_size = -8000"); // 8 MB page cache
133
+ if (fileBacked)
134
+ db.exec("PRAGMA mmap_size = 67108864"); // 64 MB mmap
135
+ db.exec("PRAGMA temp_store = MEMORY");
118
136
  db.exec("PRAGMA foreign_keys = ON");
119
137
  db.exec("BEGIN");
120
138
  try {
@@ -226,7 +244,7 @@ function initSchema(db, fileBacked) {
226
244
  proof_level TEXT NOT NULL DEFAULT '',
227
245
  integration_closure TEXT NOT NULL DEFAULT '',
228
246
  observability_impact TEXT NOT NULL DEFAULT '',
229
- sequence INTEGER DEFAULT 0, -- DEAD CODE: no tool exposes sequence always 0
247
+ sequence INTEGER DEFAULT 0, -- Ordering hint: tools may set this to control execution order
230
248
  replan_triggered_at TEXT DEFAULT NULL,
231
249
  PRIMARY KEY (milestone_id, id),
232
250
  FOREIGN KEY (milestone_id) REFERENCES milestones(id)
@@ -258,7 +276,7 @@ function initSchema(db, fileBacked) {
258
276
  expected_output TEXT NOT NULL DEFAULT '[]',
259
277
  observability_impact TEXT NOT NULL DEFAULT '',
260
278
  full_plan_md TEXT NOT NULL DEFAULT '',
261
- sequence INTEGER DEFAULT 0, -- DEAD CODE: no tool exposes sequence always 0
279
+ sequence INTEGER DEFAULT 0, -- Ordering hint: tools may set this to control execution order
262
280
  PRIMARY KEY (milestone_id, slice_id, id),
263
281
  FOREIGN KEY (milestone_id, slice_id) REFERENCES slices(milestone_id, id)
264
282
  )
@@ -318,9 +336,28 @@ function initSchema(db, fileBacked) {
318
336
  PRIMARY KEY (milestone_id, slice_id, gate_id, task_id),
319
337
  FOREIGN KEY (milestone_id, slice_id) REFERENCES slices(milestone_id, id)
320
338
  )
339
+ `);
340
+ // Slice dependency junction table (v14)
341
+ db.exec(`
342
+ CREATE TABLE IF NOT EXISTS slice_dependencies (
343
+ milestone_id TEXT NOT NULL,
344
+ slice_id TEXT NOT NULL,
345
+ depends_on_slice_id TEXT NOT NULL,
346
+ PRIMARY KEY (milestone_id, slice_id, depends_on_slice_id),
347
+ FOREIGN KEY (milestone_id, slice_id) REFERENCES slices(milestone_id, id),
348
+ FOREIGN KEY (milestone_id, depends_on_slice_id) REFERENCES slices(milestone_id, id)
349
+ )
321
350
  `);
322
351
  db.exec("CREATE INDEX IF NOT EXISTS idx_memories_active ON memories(superseded_by)");
323
352
  db.exec("CREATE INDEX IF NOT EXISTS idx_replan_history_milestone ON replan_history(milestone_id, created_at)");
353
+ // v13 indexes — hot-path dispatch queries
354
+ db.exec("CREATE INDEX IF NOT EXISTS idx_tasks_active ON tasks(milestone_id, slice_id, status)");
355
+ db.exec("CREATE INDEX IF NOT EXISTS idx_slices_active ON slices(milestone_id, status)");
356
+ db.exec("CREATE INDEX IF NOT EXISTS idx_milestones_status ON milestones(status)");
357
+ db.exec("CREATE INDEX IF NOT EXISTS idx_quality_gates_pending ON quality_gates(milestone_id, slice_id, status)");
358
+ db.exec("CREATE INDEX IF NOT EXISTS idx_verification_evidence_task ON verification_evidence(milestone_id, slice_id, task_id)");
359
+ // v14 index — slice dependency lookups
360
+ db.exec("CREATE INDEX IF NOT EXISTS idx_slice_deps_target ON slice_dependencies(milestone_id, depends_on_slice_id)");
324
361
  db.exec(`CREATE VIEW IF NOT EXISTS active_decisions AS SELECT * FROM decisions WHERE superseded_by IS NULL`);
325
362
  db.exec(`CREATE VIEW IF NOT EXISTS active_requirements AS SELECT * FROM requirements WHERE superseded_by IS NULL`);
326
363
  db.exec(`CREATE VIEW IF NOT EXISTS active_memories AS SELECT * FROM memories WHERE superseded_by IS NULL`);
@@ -599,6 +636,35 @@ function migrateSchema(db) {
599
636
  ":applied_at": new Date().toISOString(),
600
637
  });
601
638
  }
639
+ if (currentVersion < 13) {
640
+ // Hot-path indexes for auto-loop dispatch queries
641
+ db.exec("CREATE INDEX IF NOT EXISTS idx_tasks_active ON tasks(milestone_id, slice_id, status)");
642
+ db.exec("CREATE INDEX IF NOT EXISTS idx_slices_active ON slices(milestone_id, status)");
643
+ db.exec("CREATE INDEX IF NOT EXISTS idx_milestones_status ON milestones(status)");
644
+ db.exec("CREATE INDEX IF NOT EXISTS idx_quality_gates_pending ON quality_gates(milestone_id, slice_id, status)");
645
+ db.exec("CREATE INDEX IF NOT EXISTS idx_verification_evidence_task ON verification_evidence(milestone_id, slice_id, task_id)");
646
+ db.prepare("INSERT INTO schema_version (version, applied_at) VALUES (:version, :applied_at)").run({
647
+ ":version": 13,
648
+ ":applied_at": new Date().toISOString(),
649
+ });
650
+ }
651
+ if (currentVersion < 14) {
652
+ db.exec(`
653
+ CREATE TABLE IF NOT EXISTS slice_dependencies (
654
+ milestone_id TEXT NOT NULL,
655
+ slice_id TEXT NOT NULL,
656
+ depends_on_slice_id TEXT NOT NULL,
657
+ PRIMARY KEY (milestone_id, slice_id, depends_on_slice_id),
658
+ FOREIGN KEY (milestone_id, slice_id) REFERENCES slices(milestone_id, id),
659
+ FOREIGN KEY (milestone_id, depends_on_slice_id) REFERENCES slices(milestone_id, id)
660
+ )
661
+ `);
662
+ db.exec("CREATE INDEX IF NOT EXISTS idx_slice_deps_target ON slice_dependencies(milestone_id, depends_on_slice_id)");
663
+ db.prepare("INSERT INTO schema_version (version, applied_at) VALUES (:version, :applied_at)").run({
664
+ ":version": 14,
665
+ ":applied_at": new Date().toISOString(),
666
+ });
667
+ }
602
668
  db.exec("COMMIT");
603
669
  }
604
670
  catch (err) {
@@ -655,6 +721,11 @@ export function closeDatabase() {
655
721
  currentDb.exec('PRAGMA wal_checkpoint(TRUNCATE)');
656
722
  }
657
723
  catch { /* non-fatal — best effort before close */ }
724
+ try {
725
+ // Incremental vacuum to reclaim space without blocking
726
+ currentDb.exec('PRAGMA incremental_vacuum(64)');
727
+ }
728
+ catch { /* non-fatal */ }
658
729
  try {
659
730
  currentDb.close();
660
731
  }
@@ -666,9 +737,31 @@ export function closeDatabase() {
666
737
  currentPid = 0;
667
738
  }
668
739
  }
740
+ /** Run a full VACUUM — call sparingly (e.g. after milestone completion). */
741
+ export function vacuumDatabase() {
742
+ if (!currentDb)
743
+ return;
744
+ try {
745
+ currentDb.exec('VACUUM');
746
+ }
747
+ catch { /* non-fatal */ }
748
+ }
749
+ let _txDepth = 0;
669
750
  export function transaction(fn) {
670
751
  if (!currentDb)
671
752
  throw new GSDError(GSD_STALE_STATE, "gsd-db: No database open");
753
+ // Re-entrant: if already inside a transaction, just run fn() without
754
+ // starting a new one. SQLite does not support nested BEGIN/COMMIT.
755
+ if (_txDepth > 0) {
756
+ _txDepth++;
757
+ try {
758
+ return fn();
759
+ }
760
+ finally {
761
+ _txDepth--;
762
+ }
763
+ }
764
+ _txDepth++;
672
765
  currentDb.exec("BEGIN");
673
766
  try {
674
767
  const result = fn();
@@ -679,6 +772,9 @@ export function transaction(fn) {
679
772
  currentDb.exec("ROLLBACK");
680
773
  throw err;
681
774
  }
775
+ finally {
776
+ _txDepth--;
777
+ }
682
778
  }
683
779
  export function insertDecision(d) {
684
780
  if (!currentDb)
@@ -1112,6 +1208,16 @@ export function updateSliceStatus(milestoneId, sliceId, status, completedAt) {
1112
1208
  ":id": sliceId,
1113
1209
  });
1114
1210
  }
1211
+ export function setTaskSummaryMd(milestoneId, sliceId, taskId, md) {
1212
+ if (!currentDb)
1213
+ throw new GSDError(GSD_STALE_STATE, "gsd-db: No database open");
1214
+ currentDb.prepare(`UPDATE tasks SET full_summary_md = :md WHERE milestone_id = :mid AND slice_id = :sid AND id = :tid`).run({ ":mid": milestoneId, ":sid": sliceId, ":tid": taskId, ":md": md });
1215
+ }
1216
+ export function setSliceSummaryMd(milestoneId, sliceId, summaryMd, uatMd) {
1217
+ if (!currentDb)
1218
+ throw new GSDError(GSD_STALE_STATE, "gsd-db: No database open");
1219
+ currentDb.prepare(`UPDATE slices SET full_summary_md = :summary_md, full_uat_md = :uat_md WHERE milestone_id = :mid AND id = :sid`).run({ ":mid": milestoneId, ":sid": sliceId, ":summary_md": summaryMd, ":uat_md": uatMd });
1220
+ }
1115
1221
  function rowToTask(row) {
1116
1222
  return {
1117
1223
  milestone_id: row["milestone_id"],
@@ -1216,6 +1322,16 @@ export function getMilestone(id) {
1216
1322
  return null;
1217
1323
  return rowToMilestone(row);
1218
1324
  }
1325
+ /**
1326
+ * Update a milestone's status in the database.
1327
+ * Used by park/unpark to keep the DB in sync with the filesystem marker.
1328
+ * See: https://github.com/gsd-build/gsd-2/issues/2694
1329
+ */
1330
+ export function updateMilestoneStatus(milestoneId, status, completedAt) {
1331
+ if (!currentDb)
1332
+ throw new GSDError(GSD_STALE_STATE, "gsd-db: No database open");
1333
+ currentDb.prepare(`UPDATE milestones SET status = :status, completed_at = :completed_at WHERE id = :id`).run({ ":status": status, ":completed_at": completedAt ?? null, ":id": milestoneId });
1334
+ }
1219
1335
  export function getActiveMilestoneFromDb() {
1220
1336
  if (!currentDb)
1221
1337
  return null;
@@ -1227,18 +1343,22 @@ export function getActiveMilestoneFromDb() {
1227
1343
  export function getActiveSliceFromDb(milestoneId) {
1228
1344
  if (!currentDb)
1229
1345
  return null;
1230
- const rows = currentDb.prepare("SELECT * FROM slices WHERE milestone_id = :mid AND status NOT IN ('complete', 'done') ORDER BY sequence, id").all({ ":mid": milestoneId });
1231
- if (rows.length === 0)
1346
+ // Single query: find the first non-complete slice whose dependencies are all satisfied.
1347
+ // Uses json_each() to expand the JSON depends array and checks each dep is complete.
1348
+ const row = currentDb.prepare(`SELECT s.* FROM slices s
1349
+ WHERE s.milestone_id = :mid
1350
+ AND s.status NOT IN ('complete', 'done')
1351
+ AND NOT EXISTS (
1352
+ SELECT 1 FROM json_each(s.depends) AS dep
1353
+ WHERE dep.value NOT IN (
1354
+ SELECT id FROM slices WHERE milestone_id = :mid AND status IN ('complete', 'done')
1355
+ )
1356
+ )
1357
+ ORDER BY s.sequence, s.id
1358
+ LIMIT 1`).get({ ":mid": milestoneId });
1359
+ if (!row)
1232
1360
  return null;
1233
- const completedRows = currentDb.prepare("SELECT id FROM slices WHERE milestone_id = :mid AND status IN ('complete', 'done')").all({ ":mid": milestoneId });
1234
- const completedIds = new Set(completedRows.map((r) => r["id"]));
1235
- for (const row of rows) {
1236
- const slice = rowToSlice(row);
1237
- if (slice.depends.length === 0 || slice.depends.every((d) => completedIds.has(d))) {
1238
- return slice;
1239
- }
1240
- }
1241
- return null;
1361
+ return rowToSlice(row);
1242
1362
  }
1243
1363
  export function getActiveTaskFromDb(milestoneId, sliceId) {
1244
1364
  if (!currentDb)
@@ -1262,6 +1382,60 @@ export function getArtifact(path) {
1262
1382
  return null;
1263
1383
  return rowToArtifact(row);
1264
1384
  }
1385
+ // ─── Lightweight Query Variants (hot-path optimized) ─────────────────────
1386
+ /** Fast milestone status check — avoids deserializing JSON planning fields. */
1387
+ export function getActiveMilestoneIdFromDb() {
1388
+ if (!currentDb)
1389
+ return null;
1390
+ const row = currentDb.prepare("SELECT id, status FROM milestones WHERE status NOT IN ('complete', 'parked') ORDER BY id LIMIT 1").get();
1391
+ if (!row)
1392
+ return null;
1393
+ return { id: row["id"], status: row["status"] };
1394
+ }
1395
+ /** Fast slice status check — avoids deserializing JSON depends/planning fields. */
1396
+ export function getSliceStatusSummary(milestoneId) {
1397
+ if (!currentDb)
1398
+ return [];
1399
+ return currentDb.prepare("SELECT id, status FROM slices WHERE milestone_id = :mid ORDER BY sequence, id").all({ ":mid": milestoneId }).map((r) => ({ id: r["id"], status: r["status"] }));
1400
+ }
1401
+ /** Fast task status check — avoids deserializing JSON arrays and large text fields. */
1402
+ export function getActiveTaskIdFromDb(milestoneId, sliceId) {
1403
+ if (!currentDb)
1404
+ return null;
1405
+ const row = currentDb.prepare("SELECT id, status, title FROM tasks WHERE milestone_id = :mid AND slice_id = :sid AND status NOT IN ('complete', 'done') ORDER BY sequence, id LIMIT 1").get({ ":mid": milestoneId, ":sid": sliceId });
1406
+ if (!row)
1407
+ return null;
1408
+ return { id: row["id"], status: row["status"], title: row["title"] };
1409
+ }
1410
+ /** Count tasks by status for a slice — useful for progress reporting without full row load. */
1411
+ export function getSliceTaskCounts(milestoneId, sliceId) {
1412
+ if (!currentDb)
1413
+ return { total: 0, done: 0, pending: 0 };
1414
+ const row = currentDb.prepare(`SELECT
1415
+ COUNT(*) as total,
1416
+ SUM(CASE WHEN status IN ('complete', 'done') THEN 1 ELSE 0 END) as done,
1417
+ SUM(CASE WHEN status NOT IN ('complete', 'done') THEN 1 ELSE 0 END) as pending
1418
+ FROM tasks WHERE milestone_id = :mid AND slice_id = :sid`).get({ ":mid": milestoneId, ":sid": sliceId });
1419
+ if (!row)
1420
+ return { total: 0, done: 0, pending: 0 };
1421
+ return { total: row["total"] ?? 0, done: row["done"] ?? 0, pending: row["pending"] ?? 0 };
1422
+ }
1423
+ // ─── Slice Dependencies (junction table) ─────────────────────────────────
1424
+ /** Sync the slice_dependencies junction table from a slice's JSON depends array. */
1425
+ export function syncSliceDependencies(milestoneId, sliceId, depends) {
1426
+ if (!currentDb)
1427
+ return;
1428
+ currentDb.prepare("DELETE FROM slice_dependencies WHERE milestone_id = :mid AND slice_id = :sid").run({ ":mid": milestoneId, ":sid": sliceId });
1429
+ for (const dep of depends) {
1430
+ currentDb.prepare("INSERT OR IGNORE INTO slice_dependencies (milestone_id, slice_id, depends_on_slice_id) VALUES (:mid, :sid, :dep)").run({ ":mid": milestoneId, ":sid": sliceId, ":dep": dep });
1431
+ }
1432
+ }
1433
+ /** Get all slices that depend on a given slice. */
1434
+ export function getDependentSlices(milestoneId, sliceId) {
1435
+ if (!currentDb)
1436
+ return [];
1437
+ return currentDb.prepare("SELECT slice_id FROM slice_dependencies WHERE milestone_id = :mid AND depends_on_slice_id = :sid").all({ ":mid": milestoneId, ":sid": sliceId }).map((r) => r["slice_id"]);
1438
+ }
1265
1439
  // ─── Worktree DB Helpers ──────────────────────────────────────────────────
1266
1440
  export function copyWorktreeDb(srcDbPath, destDbPath) {
1267
1441
  try {
@@ -1278,10 +1452,13 @@ export function copyWorktreeDb(srcDbPath, destDbPath) {
1278
1452
  }
1279
1453
  }
1280
1454
  export function reconcileWorktreeDb(mainDbPath, worktreeDbPath) {
1281
- const zero = { decisions: 0, requirements: 0, artifacts: 0, conflicts: [] };
1455
+ const zero = { decisions: 0, requirements: 0, artifacts: 0, milestones: 0, slices: 0, tasks: 0, memories: 0, verification_evidence: 0, conflicts: [] };
1282
1456
  if (!existsSync(worktreeDbPath))
1283
1457
  return zero;
1284
- if (worktreeDbPath.includes("'")) {
1458
+ // Sanitize path: reject any characters that could break ATTACH syntax.
1459
+ // ATTACH DATABASE doesn't support parameterized paths in all providers,
1460
+ // so we use strict allowlist validation instead.
1461
+ if (/['";\x00]/.test(worktreeDbPath)) {
1285
1462
  process.stderr.write("gsd-db: worktree DB reconciliation failed: path contains unsafe characters\n");
1286
1463
  return zero;
1287
1464
  }
@@ -1305,17 +1482,19 @@ export function reconcileWorktreeDb(mainDbPath, worktreeDbPath) {
1305
1482
  const reqConf = adapter.prepare(`SELECT m.id FROM requirements m INNER JOIN wt.requirements w ON m.id = w.id WHERE m.description != w.description OR m.status != w.status OR m.notes != w.notes OR m.superseded_by IS NOT w.superseded_by`).all();
1306
1483
  for (const row of reqConf)
1307
1484
  conflicts.push(`requirement ${row["id"]}: modified in both`);
1308
- const merged = { decisions: 0, requirements: 0, artifacts: 0 };
1485
+ const merged = { decisions: 0, requirements: 0, artifacts: 0, milestones: 0, slices: 0, tasks: 0, memories: 0, verification_evidence: 0 };
1486
+ function countChanges(result) {
1487
+ return typeof result === "object" && result !== null ? (result.changes ?? 0) : 0;
1488
+ }
1309
1489
  adapter.exec("BEGIN");
1310
1490
  try {
1311
- const dR = adapter.prepare(`
1491
+ merged.decisions = countChanges(adapter.prepare(`
1312
1492
  INSERT OR REPLACE INTO decisions (
1313
1493
  id, when_context, scope, decision, choice, rationale, revisable, made_by, superseded_by
1314
1494
  )
1315
1495
  SELECT id, when_context, scope, decision, choice, rationale, revisable, ${hasMadeBy ? "made_by" : "'agent'"}, superseded_by FROM wt.decisions
1316
- `).run();
1317
- merged.decisions = typeof dR === "object" && dR !== null ? (dR.changes ?? 0) : 0;
1318
- const rR = adapter.prepare(`
1496
+ `).run());
1497
+ merged.requirements = countChanges(adapter.prepare(`
1319
1498
  INSERT OR REPLACE INTO requirements (
1320
1499
  id, class, status, description, why, source, primary_owner,
1321
1500
  supporting_slices, validation, notes, full_content, superseded_by
@@ -1323,16 +1502,74 @@ export function reconcileWorktreeDb(mainDbPath, worktreeDbPath) {
1323
1502
  SELECT id, class, status, description, why, source, primary_owner,
1324
1503
  supporting_slices, validation, notes, full_content, superseded_by
1325
1504
  FROM wt.requirements
1326
- `).run();
1327
- merged.requirements = typeof rR === "object" && rR !== null ? (rR.changes ?? 0) : 0;
1328
- const aR = adapter.prepare(`
1505
+ `).run());
1506
+ merged.artifacts = countChanges(adapter.prepare(`
1329
1507
  INSERT OR REPLACE INTO artifacts (
1330
1508
  path, artifact_type, milestone_id, slice_id, task_id, full_content, imported_at
1331
1509
  )
1332
1510
  SELECT path, artifact_type, milestone_id, slice_id, task_id, full_content, imported_at
1333
1511
  FROM wt.artifacts
1334
- `).run();
1335
- merged.artifacts = typeof aR === "object" && aR !== null ? (aR.changes ?? 0) : 0;
1512
+ `).run());
1513
+ // Merge milestones worktree may have updated status/planning fields
1514
+ merged.milestones = countChanges(adapter.prepare(`
1515
+ INSERT OR REPLACE INTO milestones (
1516
+ id, title, status, depends_on, created_at, completed_at,
1517
+ vision, success_criteria, key_risks, proof_strategy,
1518
+ verification_contract, verification_integration, verification_operational, verification_uat,
1519
+ definition_of_done, requirement_coverage, boundary_map_markdown
1520
+ )
1521
+ SELECT id, title, status, depends_on, created_at, completed_at,
1522
+ vision, success_criteria, key_risks, proof_strategy,
1523
+ verification_contract, verification_integration, verification_operational, verification_uat,
1524
+ definition_of_done, requirement_coverage, boundary_map_markdown
1525
+ FROM wt.milestones
1526
+ `).run());
1527
+ // Merge slices — preserve worktree progress (status, summaries, planning)
1528
+ merged.slices = countChanges(adapter.prepare(`
1529
+ INSERT OR REPLACE INTO slices (
1530
+ milestone_id, id, title, status, risk, depends, demo, created_at, completed_at,
1531
+ full_summary_md, full_uat_md, goal, success_criteria, proof_level,
1532
+ integration_closure, observability_impact, sequence, replan_triggered_at
1533
+ )
1534
+ SELECT milestone_id, id, title, status, risk, depends, demo, created_at, completed_at,
1535
+ full_summary_md, full_uat_md, goal, success_criteria, proof_level,
1536
+ integration_closure, observability_impact, sequence, replan_triggered_at
1537
+ FROM wt.slices
1538
+ `).run());
1539
+ // Merge tasks — preserve execution results, status, summaries
1540
+ merged.tasks = countChanges(adapter.prepare(`
1541
+ INSERT OR REPLACE INTO tasks (
1542
+ milestone_id, slice_id, id, title, status, one_liner, narrative,
1543
+ verification_result, duration, completed_at, blocker_discovered,
1544
+ deviations, known_issues, key_files, key_decisions, full_summary_md,
1545
+ description, estimate, files, verify, inputs, expected_output,
1546
+ observability_impact, full_plan_md, sequence
1547
+ )
1548
+ SELECT milestone_id, slice_id, id, title, status, one_liner, narrative,
1549
+ verification_result, duration, completed_at, blocker_discovered,
1550
+ deviations, known_issues, key_files, key_decisions, full_summary_md,
1551
+ description, estimate, files, verify, inputs, expected_output,
1552
+ observability_impact, full_plan_md, sequence
1553
+ FROM wt.tasks
1554
+ `).run());
1555
+ // Merge memories — keep worktree-learned insights
1556
+ merged.memories = countChanges(adapter.prepare(`
1557
+ INSERT OR REPLACE INTO memories (
1558
+ seq, id, category, content, confidence, source_unit_type, source_unit_id,
1559
+ created_at, updated_at, superseded_by, hit_count
1560
+ )
1561
+ SELECT seq, id, category, content, confidence, source_unit_type, source_unit_id,
1562
+ created_at, updated_at, superseded_by, hit_count
1563
+ FROM wt.memories
1564
+ `).run());
1565
+ // Merge verification evidence — append-only, use INSERT OR IGNORE to avoid duplicates
1566
+ merged.verification_evidence = countChanges(adapter.prepare(`
1567
+ INSERT OR IGNORE INTO verification_evidence (
1568
+ task_id, slice_id, milestone_id, command, exit_code, verdict, duration_ms, created_at
1569
+ )
1570
+ SELECT task_id, slice_id, milestone_id, command, exit_code, verdict, duration_ms, created_at
1571
+ FROM wt.verification_evidence
1572
+ `).run());
1336
1573
  adapter.exec("COMMIT");
1337
1574
  }
1338
1575
  catch (txErr) {
@@ -1388,20 +1625,36 @@ export function insertAssessment(entry) {
1388
1625
  ":created_at": new Date().toISOString(),
1389
1626
  });
1390
1627
  }
1391
- export function deleteTask(milestoneId, sliceId, taskId) {
1628
+ export function deleteAssessmentByScope(milestoneId, scope) {
1629
+ if (!currentDb)
1630
+ throw new GSDError(GSD_STALE_STATE, "gsd-db: No database open");
1631
+ currentDb.prepare(`DELETE FROM assessments WHERE milestone_id = :mid AND scope = :scope`).run({ ":mid": milestoneId, ":scope": scope });
1632
+ }
1633
+ export function deleteVerificationEvidence(milestoneId, sliceId, taskId) {
1392
1634
  if (!currentDb)
1393
1635
  throw new GSDError(GSD_STALE_STATE, "gsd-db: No database open");
1394
- // Must delete verification_evidence first (FK constraint)
1395
1636
  currentDb.prepare(`DELETE FROM verification_evidence WHERE milestone_id = :mid AND slice_id = :sid AND task_id = :tid`).run({ ":mid": milestoneId, ":sid": sliceId, ":tid": taskId });
1396
- currentDb.prepare(`DELETE FROM tasks WHERE milestone_id = :mid AND slice_id = :sid AND id = :tid`).run({ ":mid": milestoneId, ":sid": sliceId, ":tid": taskId });
1637
+ }
1638
+ export function deleteTask(milestoneId, sliceId, taskId) {
1639
+ if (!currentDb)
1640
+ throw new GSDError(GSD_STALE_STATE, "gsd-db: No database open");
1641
+ transaction(() => {
1642
+ // Must delete verification_evidence first (FK constraint)
1643
+ currentDb.prepare(`DELETE FROM verification_evidence WHERE milestone_id = :mid AND slice_id = :sid AND task_id = :tid`).run({ ":mid": milestoneId, ":sid": sliceId, ":tid": taskId });
1644
+ currentDb.prepare(`DELETE FROM tasks WHERE milestone_id = :mid AND slice_id = :sid AND id = :tid`).run({ ":mid": milestoneId, ":sid": sliceId, ":tid": taskId });
1645
+ });
1397
1646
  }
1398
1647
  export function deleteSlice(milestoneId, sliceId) {
1399
1648
  if (!currentDb)
1400
1649
  throw new GSDError(GSD_STALE_STATE, "gsd-db: No database open");
1401
- // Cascade-style manual deletion: evidence → tasks → slice
1402
- currentDb.prepare(`DELETE FROM verification_evidence WHERE milestone_id = :mid AND slice_id = :sid`).run({ ":mid": milestoneId, ":sid": sliceId });
1403
- currentDb.prepare(`DELETE FROM tasks WHERE milestone_id = :mid AND slice_id = :sid`).run({ ":mid": milestoneId, ":sid": sliceId });
1404
- currentDb.prepare(`DELETE FROM slices WHERE milestone_id = :mid AND id = :sid`).run({ ":mid": milestoneId, ":sid": sliceId });
1650
+ transaction(() => {
1651
+ // Cascade-style manual deletion: evidence tasks dependencies slice
1652
+ currentDb.prepare(`DELETE FROM verification_evidence WHERE milestone_id = :mid AND slice_id = :sid`).run({ ":mid": milestoneId, ":sid": sliceId });
1653
+ currentDb.prepare(`DELETE FROM tasks WHERE milestone_id = :mid AND slice_id = :sid`).run({ ":mid": milestoneId, ":sid": sliceId });
1654
+ currentDb.prepare(`DELETE FROM slice_dependencies WHERE milestone_id = :mid AND slice_id = :sid`).run({ ":mid": milestoneId, ":sid": sliceId });
1655
+ currentDb.prepare(`DELETE FROM slice_dependencies WHERE milestone_id = :mid AND depends_on_slice_id = :sid`).run({ ":mid": milestoneId, ":sid": sliceId });
1656
+ currentDb.prepare(`DELETE FROM slices WHERE milestone_id = :mid AND id = :sid`).run({ ":mid": milestoneId, ":sid": sliceId });
1657
+ });
1405
1658
  }
1406
1659
  export function updateSliceFields(milestoneId, sliceId, fields) {
1407
1660
  if (!currentDb)
@@ -353,7 +353,10 @@ async function buildDiscussSlicePrompt(mid, sid, sTitle, base, options) {
353
353
  }
354
354
  }
355
355
  // Completed slice summaries — what was already built that this slice builds on
356
+ // Ensure DB is open so getMilestoneSlices returns real data (#2560).
356
357
  {
358
+ const { ensureDbOpen } = await import("./bootstrap/dynamic-tools.js");
359
+ await ensureDbOpen();
357
360
  let normSlices = [];
358
361
  if (isDbAvailable()) {
359
362
  normSlices = getMilestoneSlices(mid).map(s => ({ id: s.id, done: s.status === "complete" }));
@@ -476,6 +479,13 @@ export async function showDiscuss(ctx, pi, basePath) {
476
479
  }
477
480
  return;
478
481
  }
482
+ // Ensure DB is open before querying slices (#2560).
483
+ // showDiscuss() is a command handler — unlike tool handlers, it has no
484
+ // automatic ensureDbOpen() call. Without this, isDbAvailable() returns
485
+ // false on cold-start sessions and normSlices falls to [] → false
486
+ // "All slices complete" exit.
487
+ const { ensureDbOpen } = await import("./bootstrap/dynamic-tools.js");
488
+ await ensureDbOpen();
479
489
  // Guard: no roadmap yet (unless DB has slices)
480
490
  const roadmapFile = resolveMilestoneFile(basePath, mid, "ROADMAP");
481
491
  const roadmapContent = roadmapFile ? await loadFile(roadmapFile) : null;
@@ -12,6 +12,7 @@ import { nativeInit } from "./native-git-bridge.js";
12
12
  import { ensureGitignore, untrackRuntimeFiles } from "./gitignore.js";
13
13
  import { gsdRoot } from "./paths.js";
14
14
  import { assertSafeDirectory } from "./validate-directory.js";
15
+ import { runSkillInstallStep } from "./skill-catalog.js";
15
16
  // ─── Defaults ───────────────────────────────────────────────────────────────────
16
17
  const DEFAULT_PREFS = {
17
18
  mode: "solo",
@@ -176,7 +177,14 @@ export async function showProjectInit(ctx, pi, basePath, detection) {
176
177
  if (advancedChoice === "customize") {
177
178
  await customizeAdvancedPrefs(ctx, prefs);
178
179
  }
179
- // ── Step 8: Bootstrap .gsd/ ────────────────────────────────────────────────
180
+ // ── Step 8: Skill Installation ─────────────────────────────────────────────
181
+ try {
182
+ await runSkillInstallStep(ctx, signals);
183
+ }
184
+ catch {
185
+ // Non-fatal — skill installation failure should never block project init
186
+ }
187
+ // ── Step 9: Bootstrap .gsd/ ────────────────────────────────────────────────
180
188
  bootstrapGsdDirectory(basePath, prefs, signals);
181
189
  // Ensure .gitignore
182
190
  ensureGitignore(basePath);
@@ -328,9 +336,9 @@ function bootstrapGsdDirectory(basePath, prefs, signals) {
328
336
  assertSafeDirectory(basePath);
329
337
  const gsd = gsdRoot(basePath);
330
338
  mkdirSync(join(gsd, "milestones"), { recursive: true });
331
- // Write preferences.md from wizard answers
339
+ // Write PREFERENCES.md from wizard answers
332
340
  const preferencesContent = buildPreferencesFile(prefs);
333
- writeFileSync(join(gsd, "preferences.md"), preferencesContent, "utf-8");
341
+ writeFileSync(join(gsd, "PREFERENCES.md"), preferencesContent, "utf-8");
334
342
  // Seed CONTEXT.md with detected project signals
335
343
  const contextContent = buildContextSeed(signals);
336
344
  if (contextContent) {
@@ -110,21 +110,12 @@ export function findProvider(idOrLabel) {
110
110
  */
111
111
  export function getAllKeyStatuses(auth) {
112
112
  return PROVIDER_REGISTRY.map((provider) => {
113
- const creds = auth.getCredentialsForProvider(provider.id);
113
+ const rawCreds = auth.getCredentialsForProvider(provider.id);
114
+ // Filter out empty-key entries (left by legacy removeProviderToken or skipped onboarding)
115
+ const creds = rawCreds.filter((c) => !(c.type === "api_key" && !c.key));
114
116
  const envKey = provider.envVar ? process.env[provider.envVar] : undefined;
115
117
  if (creds.length > 0) {
116
118
  const firstCred = creds[0];
117
- // Skip empty keys (from skipped onboarding)
118
- if (firstCred.type === "api_key" && !firstCred.key) {
119
- return {
120
- provider,
121
- configured: false,
122
- source: "none",
123
- credentialCount: 0,
124
- description: "empty key (skipped setup)",
125
- backedOff: false,
126
- };
127
- }
128
119
  const desc = creds.length > 1
129
120
  ? `${creds.length} keys (round-robin)`
130
121
  : describeCredential(firstCred);
@@ -222,7 +213,7 @@ export async function handleAddKey(providerArg, ctx, auth) {
222
213
  else {
223
214
  // Interactive provider picker
224
215
  const options = PROVIDER_REGISTRY.map((p) => {
225
- const creds = auth.getCredentialsForProvider(p.id);
216
+ const creds = auth.getCredentialsForProvider(p.id).filter((c) => !(c.type === "api_key" && !c.key));
226
217
  const existing = creds.length > 0 ? " (configured)" : "";
227
218
  return `[${p.category}] ${p.label}${existing}`;
228
219
  });
@@ -285,7 +276,7 @@ export async function handleRemoveKey(providerArg, ctx, auth) {
285
276
  else {
286
277
  // Show only configured providers
287
278
  const configured = PROVIDER_REGISTRY.filter((p) => {
288
- const creds = auth.getCredentialsForProvider(p.id);
279
+ const creds = auth.getCredentialsForProvider(p.id).filter((c) => !(c.type === "api_key" && !c.key));
289
280
  return creds.length > 0;
290
281
  });
291
282
  if (configured.length === 0) {
@@ -508,7 +499,7 @@ export async function handleRotateKey(providerArg, ctx, auth) {
508
499
  // Show only configured API key providers
509
500
  const configured = PROVIDER_REGISTRY.filter((p) => {
510
501
  const creds = auth.getCredentialsForProvider(p.id);
511
- return creds.some((c) => c.type === "api_key");
502
+ return creds.some((c) => c.type === "api_key" && c.key);
512
503
  });
513
504
  if (configured.length === 0) {
514
505
  ctx.ui.notify("No API keys configured to rotate.", "info");
@@ -646,7 +637,7 @@ export function runKeyDoctor(auth) {
646
637
  if (!envValue)
647
638
  continue;
648
639
  const creds = auth.getCredentialsForProvider(provider.id);
649
- const apiKey = creds.find((c) => c.type === "api_key");
640
+ const apiKey = creds.find((c) => c.type === "api_key" && c.key);
650
641
  if (apiKey?.key && apiKey.key !== envValue) {
651
642
  findings.push({
652
643
  severity: "warning",