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
@@ -110,25 +110,35 @@ function createAdapter(rawDb: unknown): DbAdapter {
110
110
  close(): void;
111
111
  };
112
112
 
113
+ const stmtCache = new Map<string, DbStatement>();
114
+
115
+ function wrapStmt(raw: { run(...a: unknown[]): unknown; get(...a: unknown[]): unknown; all(...a: unknown[]): unknown[] }): DbStatement {
116
+ return {
117
+ run(...params: unknown[]): unknown {
118
+ return raw.run(...params);
119
+ },
120
+ get(...params: unknown[]): Record<string, unknown> | undefined {
121
+ return normalizeRow(raw.get(...params));
122
+ },
123
+ all(...params: unknown[]): Record<string, unknown>[] {
124
+ return normalizeRows(raw.all(...params));
125
+ },
126
+ };
127
+ }
128
+
113
129
  return {
114
130
  exec(sql: string): void {
115
131
  db.exec(sql);
116
132
  },
117
133
  prepare(sql: string): DbStatement {
118
- const stmt = db.prepare(sql);
119
- return {
120
- run(...params: unknown[]): unknown {
121
- return stmt.run(...params);
122
- },
123
- get(...params: unknown[]): Record<string, unknown> | undefined {
124
- return normalizeRow(stmt.get(...params));
125
- },
126
- all(...params: unknown[]): Record<string, unknown>[] {
127
- return normalizeRows(stmt.all(...params));
128
- },
129
- };
134
+ let cached = stmtCache.get(sql);
135
+ if (cached) return cached;
136
+ cached = wrapStmt(db.prepare(sql));
137
+ stmtCache.set(sql, cached);
138
+ return cached;
130
139
  },
131
140
  close(): void {
141
+ stmtCache.clear();
132
142
  db.close();
133
143
  },
134
144
  };
@@ -149,11 +159,16 @@ function openRawDb(path: string): unknown {
149
159
  return new Database(path);
150
160
  }
151
161
 
152
- const SCHEMA_VERSION = 12;
162
+ const SCHEMA_VERSION = 14;
153
163
 
154
164
  function initSchema(db: DbAdapter, fileBacked: boolean): void {
155
165
  if (fileBacked) db.exec("PRAGMA journal_mode=WAL");
156
166
  if (fileBacked) db.exec("PRAGMA busy_timeout = 5000");
167
+ if (fileBacked) db.exec("PRAGMA synchronous = NORMAL");
168
+ if (fileBacked) db.exec("PRAGMA auto_vacuum = INCREMENTAL");
169
+ if (fileBacked) db.exec("PRAGMA cache_size = -8000"); // 8 MB page cache
170
+ if (fileBacked) db.exec("PRAGMA mmap_size = 67108864"); // 64 MB mmap
171
+ db.exec("PRAGMA temp_store = MEMORY");
157
172
  db.exec("PRAGMA foreign_keys = ON");
158
173
 
159
174
  db.exec("BEGIN");
@@ -273,7 +288,7 @@ function initSchema(db: DbAdapter, fileBacked: boolean): void {
273
288
  proof_level TEXT NOT NULL DEFAULT '',
274
289
  integration_closure TEXT NOT NULL DEFAULT '',
275
290
  observability_impact TEXT NOT NULL DEFAULT '',
276
- sequence INTEGER DEFAULT 0, -- DEAD CODE: no tool exposes sequence always 0
291
+ sequence INTEGER DEFAULT 0, -- Ordering hint: tools may set this to control execution order
277
292
  replan_triggered_at TEXT DEFAULT NULL,
278
293
  PRIMARY KEY (milestone_id, id),
279
294
  FOREIGN KEY (milestone_id) REFERENCES milestones(id)
@@ -306,7 +321,7 @@ function initSchema(db: DbAdapter, fileBacked: boolean): void {
306
321
  expected_output TEXT NOT NULL DEFAULT '[]',
307
322
  observability_impact TEXT NOT NULL DEFAULT '',
308
323
  full_plan_md TEXT NOT NULL DEFAULT '',
309
- sequence INTEGER DEFAULT 0, -- DEAD CODE: no tool exposes sequence always 0
324
+ sequence INTEGER DEFAULT 0, -- Ordering hint: tools may set this to control execution order
310
325
  PRIMARY KEY (milestone_id, slice_id, id),
311
326
  FOREIGN KEY (milestone_id, slice_id) REFERENCES slices(milestone_id, id)
312
327
  )
@@ -372,9 +387,31 @@ function initSchema(db: DbAdapter, fileBacked: boolean): void {
372
387
  )
373
388
  `);
374
389
 
390
+ // Slice dependency junction table (v14)
391
+ db.exec(`
392
+ CREATE TABLE IF NOT EXISTS slice_dependencies (
393
+ milestone_id TEXT NOT NULL,
394
+ slice_id TEXT NOT NULL,
395
+ depends_on_slice_id TEXT NOT NULL,
396
+ PRIMARY KEY (milestone_id, slice_id, depends_on_slice_id),
397
+ FOREIGN KEY (milestone_id, slice_id) REFERENCES slices(milestone_id, id),
398
+ FOREIGN KEY (milestone_id, depends_on_slice_id) REFERENCES slices(milestone_id, id)
399
+ )
400
+ `);
401
+
375
402
  db.exec("CREATE INDEX IF NOT EXISTS idx_memories_active ON memories(superseded_by)");
376
403
  db.exec("CREATE INDEX IF NOT EXISTS idx_replan_history_milestone ON replan_history(milestone_id, created_at)");
377
404
 
405
+ // v13 indexes — hot-path dispatch queries
406
+ db.exec("CREATE INDEX IF NOT EXISTS idx_tasks_active ON tasks(milestone_id, slice_id, status)");
407
+ db.exec("CREATE INDEX IF NOT EXISTS idx_slices_active ON slices(milestone_id, status)");
408
+ db.exec("CREATE INDEX IF NOT EXISTS idx_milestones_status ON milestones(status)");
409
+ db.exec("CREATE INDEX IF NOT EXISTS idx_quality_gates_pending ON quality_gates(milestone_id, slice_id, status)");
410
+ db.exec("CREATE INDEX IF NOT EXISTS idx_verification_evidence_task ON verification_evidence(milestone_id, slice_id, task_id)");
411
+
412
+ // v14 index — slice dependency lookups
413
+ db.exec("CREATE INDEX IF NOT EXISTS idx_slice_deps_target ON slice_dependencies(milestone_id, depends_on_slice_id)");
414
+
378
415
  db.exec(`CREATE VIEW IF NOT EXISTS active_decisions AS SELECT * FROM decisions WHERE superseded_by IS NULL`);
379
416
  db.exec(`CREATE VIEW IF NOT EXISTS active_requirements AS SELECT * FROM requirements WHERE superseded_by IS NULL`);
380
417
  db.exec(`CREATE VIEW IF NOT EXISTS active_memories AS SELECT * FROM memories WHERE superseded_by IS NULL`);
@@ -677,6 +714,37 @@ function migrateSchema(db: DbAdapter): void {
677
714
  });
678
715
  }
679
716
 
717
+ if (currentVersion < 13) {
718
+ // Hot-path indexes for auto-loop dispatch queries
719
+ db.exec("CREATE INDEX IF NOT EXISTS idx_tasks_active ON tasks(milestone_id, slice_id, status)");
720
+ db.exec("CREATE INDEX IF NOT EXISTS idx_slices_active ON slices(milestone_id, status)");
721
+ db.exec("CREATE INDEX IF NOT EXISTS idx_milestones_status ON milestones(status)");
722
+ db.exec("CREATE INDEX IF NOT EXISTS idx_quality_gates_pending ON quality_gates(milestone_id, slice_id, status)");
723
+ db.exec("CREATE INDEX IF NOT EXISTS idx_verification_evidence_task ON verification_evidence(milestone_id, slice_id, task_id)");
724
+ db.prepare("INSERT INTO schema_version (version, applied_at) VALUES (:version, :applied_at)").run({
725
+ ":version": 13,
726
+ ":applied_at": new Date().toISOString(),
727
+ });
728
+ }
729
+
730
+ if (currentVersion < 14) {
731
+ db.exec(`
732
+ CREATE TABLE IF NOT EXISTS slice_dependencies (
733
+ milestone_id TEXT NOT NULL,
734
+ slice_id TEXT NOT NULL,
735
+ depends_on_slice_id TEXT NOT NULL,
736
+ PRIMARY KEY (milestone_id, slice_id, depends_on_slice_id),
737
+ FOREIGN KEY (milestone_id, slice_id) REFERENCES slices(milestone_id, id),
738
+ FOREIGN KEY (milestone_id, depends_on_slice_id) REFERENCES slices(milestone_id, id)
739
+ )
740
+ `);
741
+ db.exec("CREATE INDEX IF NOT EXISTS idx_slice_deps_target ON slice_dependencies(milestone_id, depends_on_slice_id)");
742
+ db.prepare("INSERT INTO schema_version (version, applied_at) VALUES (:version, :applied_at)").run({
743
+ ":version": 14,
744
+ ":applied_at": new Date().toISOString(),
745
+ });
746
+ }
747
+
680
748
  db.exec("COMMIT");
681
749
  } catch (err) {
682
750
  db.exec("ROLLBACK");
@@ -731,6 +799,10 @@ export function closeDatabase(): void {
731
799
  try {
732
800
  currentDb.exec('PRAGMA wal_checkpoint(TRUNCATE)');
733
801
  } catch { /* non-fatal — best effort before close */ }
802
+ try {
803
+ // Incremental vacuum to reclaim space without blocking
804
+ currentDb.exec('PRAGMA incremental_vacuum(64)');
805
+ } catch { /* non-fatal */ }
734
806
  try {
735
807
  currentDb.close();
736
808
  } catch {
@@ -742,8 +814,31 @@ export function closeDatabase(): void {
742
814
  }
743
815
  }
744
816
 
817
+ /** Run a full VACUUM — call sparingly (e.g. after milestone completion). */
818
+ export function vacuumDatabase(): void {
819
+ if (!currentDb) return;
820
+ try {
821
+ currentDb.exec('VACUUM');
822
+ } catch { /* non-fatal */ }
823
+ }
824
+
825
+ let _txDepth = 0;
826
+
745
827
  export function transaction<T>(fn: () => T): T {
746
828
  if (!currentDb) throw new GSDError(GSD_STALE_STATE, "gsd-db: No database open");
829
+
830
+ // Re-entrant: if already inside a transaction, just run fn() without
831
+ // starting a new one. SQLite does not support nested BEGIN/COMMIT.
832
+ if (_txDepth > 0) {
833
+ _txDepth++;
834
+ try {
835
+ return fn();
836
+ } finally {
837
+ _txDepth--;
838
+ }
839
+ }
840
+
841
+ _txDepth++;
747
842
  currentDb.exec("BEGIN");
748
843
  try {
749
844
  const result = fn();
@@ -752,6 +847,8 @@ export function transaction<T>(fn: () => T): T {
752
847
  } catch (err) {
753
848
  currentDb.exec("ROLLBACK");
754
849
  throw err;
850
+ } finally {
851
+ _txDepth--;
755
852
  }
756
853
  }
757
854
 
@@ -1308,6 +1405,20 @@ export function updateSliceStatus(milestoneId: string, sliceId: string, status:
1308
1405
  });
1309
1406
  }
1310
1407
 
1408
+ export function setTaskSummaryMd(milestoneId: string, sliceId: string, taskId: string, md: string): void {
1409
+ if (!currentDb) throw new GSDError(GSD_STALE_STATE, "gsd-db: No database open");
1410
+ currentDb.prepare(
1411
+ `UPDATE tasks SET full_summary_md = :md WHERE milestone_id = :mid AND slice_id = :sid AND id = :tid`,
1412
+ ).run({ ":mid": milestoneId, ":sid": sliceId, ":tid": taskId, ":md": md });
1413
+ }
1414
+
1415
+ export function setSliceSummaryMd(milestoneId: string, sliceId: string, summaryMd: string, uatMd: string): void {
1416
+ if (!currentDb) throw new GSDError(GSD_STALE_STATE, "gsd-db: No database open");
1417
+ currentDb.prepare(
1418
+ `UPDATE slices SET full_summary_md = :summary_md, full_uat_md = :uat_md WHERE milestone_id = :mid AND id = :sid`,
1419
+ ).run({ ":mid": milestoneId, ":sid": sliceId, ":summary_md": summaryMd, ":uat_md": uatMd });
1420
+ }
1421
+
1311
1422
  export interface TaskRow {
1312
1423
  milestone_id: string;
1313
1424
  slice_id: string;
@@ -1485,6 +1596,18 @@ export function getMilestone(id: string): MilestoneRow | null {
1485
1596
  return rowToMilestone(row);
1486
1597
  }
1487
1598
 
1599
+ /**
1600
+ * Update a milestone's status in the database.
1601
+ * Used by park/unpark to keep the DB in sync with the filesystem marker.
1602
+ * See: https://github.com/gsd-build/gsd-2/issues/2694
1603
+ */
1604
+ export function updateMilestoneStatus(milestoneId: string, status: string, completedAt?: string | null): void {
1605
+ if (!currentDb) throw new GSDError(GSD_STALE_STATE, "gsd-db: No database open");
1606
+ currentDb.prepare(
1607
+ `UPDATE milestones SET status = :status, completed_at = :completed_at WHERE id = :id`,
1608
+ ).run({ ":status": status, ":completed_at": completedAt ?? null, ":id": milestoneId });
1609
+ }
1610
+
1488
1611
  export function getActiveMilestoneFromDb(): MilestoneRow | null {
1489
1612
  if (!currentDb) return null;
1490
1613
  const row = currentDb.prepare(
@@ -1496,23 +1619,24 @@ export function getActiveMilestoneFromDb(): MilestoneRow | null {
1496
1619
 
1497
1620
  export function getActiveSliceFromDb(milestoneId: string): SliceRow | null {
1498
1621
  if (!currentDb) return null;
1499
- const rows = currentDb.prepare(
1500
- "SELECT * FROM slices WHERE milestone_id = :mid AND status NOT IN ('complete', 'done') ORDER BY sequence, id",
1501
- ).all({ ":mid": milestoneId });
1502
- if (rows.length === 0) return null;
1503
1622
 
1504
- const completedRows = currentDb.prepare(
1505
- "SELECT id FROM slices WHERE milestone_id = :mid AND status IN ('complete', 'done')",
1506
- ).all({ ":mid": milestoneId });
1507
- const completedIds = new Set(completedRows.map((r) => r["id"] as string));
1508
-
1509
- for (const row of rows) {
1510
- const slice = rowToSlice(row);
1511
- if (slice.depends.length === 0 || slice.depends.every((d) => completedIds.has(d))) {
1512
- return slice;
1513
- }
1514
- }
1515
- return null;
1623
+ // Single query: find the first non-complete slice whose dependencies are all satisfied.
1624
+ // Uses json_each() to expand the JSON depends array and checks each dep is complete.
1625
+ const row = currentDb.prepare(
1626
+ `SELECT s.* FROM slices s
1627
+ WHERE s.milestone_id = :mid
1628
+ AND s.status NOT IN ('complete', 'done')
1629
+ AND NOT EXISTS (
1630
+ SELECT 1 FROM json_each(s.depends) AS dep
1631
+ WHERE dep.value NOT IN (
1632
+ SELECT id FROM slices WHERE milestone_id = :mid AND status IN ('complete', 'done')
1633
+ )
1634
+ )
1635
+ ORDER BY s.sequence, s.id
1636
+ LIMIT 1`,
1637
+ ).get({ ":mid": milestoneId });
1638
+ if (!row) return null;
1639
+ return rowToSlice(row);
1516
1640
  }
1517
1641
 
1518
1642
  export function getActiveTaskFromDb(milestoneId: string, sliceId: string): TaskRow | null {
@@ -1537,6 +1661,73 @@ export function getArtifact(path: string): ArtifactRow | null {
1537
1661
  return rowToArtifact(row);
1538
1662
  }
1539
1663
 
1664
+ // ─── Lightweight Query Variants (hot-path optimized) ─────────────────────
1665
+
1666
+ /** Fast milestone status check — avoids deserializing JSON planning fields. */
1667
+ export function getActiveMilestoneIdFromDb(): { id: string; status: string } | null {
1668
+ if (!currentDb) return null;
1669
+ const row = currentDb.prepare(
1670
+ "SELECT id, status FROM milestones WHERE status NOT IN ('complete', 'parked') ORDER BY id LIMIT 1",
1671
+ ).get();
1672
+ if (!row) return null;
1673
+ return { id: row["id"] as string, status: row["status"] as string };
1674
+ }
1675
+
1676
+ /** Fast slice status check — avoids deserializing JSON depends/planning fields. */
1677
+ export function getSliceStatusSummary(milestoneId: string): Array<{ id: string; status: string }> {
1678
+ if (!currentDb) return [];
1679
+ return currentDb.prepare(
1680
+ "SELECT id, status FROM slices WHERE milestone_id = :mid ORDER BY sequence, id",
1681
+ ).all({ ":mid": milestoneId }).map((r) => ({ id: r["id"] as string, status: r["status"] as string }));
1682
+ }
1683
+
1684
+ /** Fast task status check — avoids deserializing JSON arrays and large text fields. */
1685
+ export function getActiveTaskIdFromDb(milestoneId: string, sliceId: string): { id: string; status: string; title: string } | null {
1686
+ if (!currentDb) return null;
1687
+ const row = currentDb.prepare(
1688
+ "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",
1689
+ ).get({ ":mid": milestoneId, ":sid": sliceId });
1690
+ if (!row) return null;
1691
+ return { id: row["id"] as string, status: row["status"] as string, title: row["title"] as string };
1692
+ }
1693
+
1694
+ /** Count tasks by status for a slice — useful for progress reporting without full row load. */
1695
+ export function getSliceTaskCounts(milestoneId: string, sliceId: string): { total: number; done: number; pending: number } {
1696
+ if (!currentDb) return { total: 0, done: 0, pending: 0 };
1697
+ const row = currentDb.prepare(
1698
+ `SELECT
1699
+ COUNT(*) as total,
1700
+ SUM(CASE WHEN status IN ('complete', 'done') THEN 1 ELSE 0 END) as done,
1701
+ SUM(CASE WHEN status NOT IN ('complete', 'done') THEN 1 ELSE 0 END) as pending
1702
+ FROM tasks WHERE milestone_id = :mid AND slice_id = :sid`,
1703
+ ).get({ ":mid": milestoneId, ":sid": sliceId });
1704
+ if (!row) return { total: 0, done: 0, pending: 0 };
1705
+ return { total: (row["total"] as number) ?? 0, done: (row["done"] as number) ?? 0, pending: (row["pending"] as number) ?? 0 };
1706
+ }
1707
+
1708
+ // ─── Slice Dependencies (junction table) ─────────────────────────────────
1709
+
1710
+ /** Sync the slice_dependencies junction table from a slice's JSON depends array. */
1711
+ export function syncSliceDependencies(milestoneId: string, sliceId: string, depends: string[]): void {
1712
+ if (!currentDb) return;
1713
+ currentDb.prepare(
1714
+ "DELETE FROM slice_dependencies WHERE milestone_id = :mid AND slice_id = :sid",
1715
+ ).run({ ":mid": milestoneId, ":sid": sliceId });
1716
+ for (const dep of depends) {
1717
+ currentDb.prepare(
1718
+ "INSERT OR IGNORE INTO slice_dependencies (milestone_id, slice_id, depends_on_slice_id) VALUES (:mid, :sid, :dep)",
1719
+ ).run({ ":mid": milestoneId, ":sid": sliceId, ":dep": dep });
1720
+ }
1721
+ }
1722
+
1723
+ /** Get all slices that depend on a given slice. */
1724
+ export function getDependentSlices(milestoneId: string, sliceId: string): string[] {
1725
+ if (!currentDb) return [];
1726
+ return currentDb.prepare(
1727
+ "SELECT slice_id FROM slice_dependencies WHERE milestone_id = :mid AND depends_on_slice_id = :sid",
1728
+ ).all({ ":mid": milestoneId, ":sid": sliceId }).map((r) => r["slice_id"] as string);
1729
+ }
1730
+
1540
1731
  // ─── Worktree DB Helpers ──────────────────────────────────────────────────
1541
1732
 
1542
1733
  export function copyWorktreeDb(srcDbPath: string, destDbPath: string): boolean {
@@ -1552,18 +1743,28 @@ export function copyWorktreeDb(srcDbPath: string, destDbPath: string): boolean {
1552
1743
  }
1553
1744
  }
1554
1745
 
1555
- export function reconcileWorktreeDb(
1556
- mainDbPath: string,
1557
- worktreeDbPath: string,
1558
- ): {
1746
+ export interface ReconcileResult {
1559
1747
  decisions: number;
1560
1748
  requirements: number;
1561
1749
  artifacts: number;
1750
+ milestones: number;
1751
+ slices: number;
1752
+ tasks: number;
1753
+ memories: number;
1754
+ verification_evidence: number;
1562
1755
  conflicts: string[];
1563
- } {
1564
- const zero = { decisions: 0, requirements: 0, artifacts: 0, conflicts: [] as string[] };
1756
+ }
1757
+
1758
+ export function reconcileWorktreeDb(
1759
+ mainDbPath: string,
1760
+ worktreeDbPath: string,
1761
+ ): ReconcileResult {
1762
+ const zero: ReconcileResult = { decisions: 0, requirements: 0, artifacts: 0, milestones: 0, slices: 0, tasks: 0, memories: 0, verification_evidence: 0, conflicts: [] };
1565
1763
  if (!existsSync(worktreeDbPath)) return zero;
1566
- if (worktreeDbPath.includes("'")) {
1764
+ // Sanitize path: reject any characters that could break ATTACH syntax.
1765
+ // ATTACH DATABASE doesn't support parameterized paths in all providers,
1766
+ // so we use strict allowlist validation instead.
1767
+ if (/['";\x00]/.test(worktreeDbPath)) {
1567
1768
  process.stderr.write("gsd-db: worktree DB reconciliation failed: path contains unsafe characters\n");
1568
1769
  return zero;
1569
1770
  }
@@ -1594,20 +1795,24 @@ export function reconcileWorktreeDb(
1594
1795
  ).all();
1595
1796
  for (const row of reqConf) conflicts.push(`requirement ${(row as Record<string, unknown>)["id"]}: modified in both`);
1596
1797
 
1597
- const merged = { decisions: 0, requirements: 0, artifacts: 0 };
1798
+ const merged: Omit<ReconcileResult, "conflicts"> = { decisions: 0, requirements: 0, artifacts: 0, milestones: 0, slices: 0, tasks: 0, memories: 0, verification_evidence: 0 };
1799
+
1800
+ function countChanges(result: unknown): number {
1801
+ return typeof result === "object" && result !== null ? ((result as { changes?: number }).changes ?? 0) : 0;
1802
+ }
1803
+
1598
1804
  adapter.exec("BEGIN");
1599
1805
  try {
1600
- const dR = adapter.prepare(`
1806
+ merged.decisions = countChanges(adapter.prepare(`
1601
1807
  INSERT OR REPLACE INTO decisions (
1602
1808
  id, when_context, scope, decision, choice, rationale, revisable, made_by, superseded_by
1603
1809
  )
1604
1810
  SELECT id, when_context, scope, decision, choice, rationale, revisable, ${
1605
1811
  hasMadeBy ? "made_by" : "'agent'"
1606
1812
  }, superseded_by FROM wt.decisions
1607
- `).run();
1608
- merged.decisions = typeof dR === "object" && dR !== null ? ((dR as { changes?: number }).changes ?? 0) : 0;
1813
+ `).run());
1609
1814
 
1610
- const rR = adapter.prepare(`
1815
+ merged.requirements = countChanges(adapter.prepare(`
1611
1816
  INSERT OR REPLACE INTO requirements (
1612
1817
  id, class, status, description, why, source, primary_owner,
1613
1818
  supporting_slices, validation, notes, full_content, superseded_by
@@ -1615,17 +1820,80 @@ export function reconcileWorktreeDb(
1615
1820
  SELECT id, class, status, description, why, source, primary_owner,
1616
1821
  supporting_slices, validation, notes, full_content, superseded_by
1617
1822
  FROM wt.requirements
1618
- `).run();
1619
- merged.requirements = typeof rR === "object" && rR !== null ? ((rR as { changes?: number }).changes ?? 0) : 0;
1823
+ `).run());
1620
1824
 
1621
- const aR = adapter.prepare(`
1825
+ merged.artifacts = countChanges(adapter.prepare(`
1622
1826
  INSERT OR REPLACE INTO artifacts (
1623
1827
  path, artifact_type, milestone_id, slice_id, task_id, full_content, imported_at
1624
1828
  )
1625
1829
  SELECT path, artifact_type, milestone_id, slice_id, task_id, full_content, imported_at
1626
1830
  FROM wt.artifacts
1627
- `).run();
1628
- merged.artifacts = typeof aR === "object" && aR !== null ? ((aR as { changes?: number }).changes ?? 0) : 0;
1831
+ `).run());
1832
+
1833
+ // Merge milestones — worktree may have updated status/planning fields
1834
+ merged.milestones = countChanges(adapter.prepare(`
1835
+ INSERT OR REPLACE INTO milestones (
1836
+ id, title, status, depends_on, created_at, completed_at,
1837
+ vision, success_criteria, key_risks, proof_strategy,
1838
+ verification_contract, verification_integration, verification_operational, verification_uat,
1839
+ definition_of_done, requirement_coverage, boundary_map_markdown
1840
+ )
1841
+ SELECT id, title, status, depends_on, created_at, completed_at,
1842
+ vision, success_criteria, key_risks, proof_strategy,
1843
+ verification_contract, verification_integration, verification_operational, verification_uat,
1844
+ definition_of_done, requirement_coverage, boundary_map_markdown
1845
+ FROM wt.milestones
1846
+ `).run());
1847
+
1848
+ // Merge slices — preserve worktree progress (status, summaries, planning)
1849
+ merged.slices = countChanges(adapter.prepare(`
1850
+ INSERT OR REPLACE INTO slices (
1851
+ milestone_id, id, title, status, risk, depends, demo, created_at, completed_at,
1852
+ full_summary_md, full_uat_md, goal, success_criteria, proof_level,
1853
+ integration_closure, observability_impact, sequence, replan_triggered_at
1854
+ )
1855
+ SELECT milestone_id, id, title, status, risk, depends, demo, created_at, completed_at,
1856
+ full_summary_md, full_uat_md, goal, success_criteria, proof_level,
1857
+ integration_closure, observability_impact, sequence, replan_triggered_at
1858
+ FROM wt.slices
1859
+ `).run());
1860
+
1861
+ // Merge tasks — preserve execution results, status, summaries
1862
+ merged.tasks = countChanges(adapter.prepare(`
1863
+ INSERT OR REPLACE INTO tasks (
1864
+ milestone_id, slice_id, id, title, status, one_liner, narrative,
1865
+ verification_result, duration, completed_at, blocker_discovered,
1866
+ deviations, known_issues, key_files, key_decisions, full_summary_md,
1867
+ description, estimate, files, verify, inputs, expected_output,
1868
+ observability_impact, full_plan_md, sequence
1869
+ )
1870
+ SELECT milestone_id, slice_id, id, title, status, one_liner, narrative,
1871
+ verification_result, duration, completed_at, blocker_discovered,
1872
+ deviations, known_issues, key_files, key_decisions, full_summary_md,
1873
+ description, estimate, files, verify, inputs, expected_output,
1874
+ observability_impact, full_plan_md, sequence
1875
+ FROM wt.tasks
1876
+ `).run());
1877
+
1878
+ // Merge memories — keep worktree-learned insights
1879
+ merged.memories = countChanges(adapter.prepare(`
1880
+ INSERT OR REPLACE INTO memories (
1881
+ seq, id, category, content, confidence, source_unit_type, source_unit_id,
1882
+ created_at, updated_at, superseded_by, hit_count
1883
+ )
1884
+ SELECT seq, id, category, content, confidence, source_unit_type, source_unit_id,
1885
+ created_at, updated_at, superseded_by, hit_count
1886
+ FROM wt.memories
1887
+ `).run());
1888
+
1889
+ // Merge verification evidence — append-only, use INSERT OR IGNORE to avoid duplicates
1890
+ merged.verification_evidence = countChanges(adapter.prepare(`
1891
+ INSERT OR IGNORE INTO verification_evidence (
1892
+ task_id, slice_id, milestone_id, command, exit_code, verdict, duration_ms, created_at
1893
+ )
1894
+ SELECT task_id, slice_id, milestone_id, command, exit_code, verdict, duration_ms, created_at
1895
+ FROM wt.verification_evidence
1896
+ `).run());
1629
1897
 
1630
1898
  adapter.exec("COMMIT");
1631
1899
  } catch (txErr) {
@@ -1694,29 +1962,53 @@ export function insertAssessment(entry: {
1694
1962
  });
1695
1963
  }
1696
1964
 
1697
- export function deleteTask(milestoneId: string, sliceId: string, taskId: string): void {
1965
+ export function deleteAssessmentByScope(milestoneId: string, scope: string): void {
1698
1966
  if (!currentDb) throw new GSDError(GSD_STALE_STATE, "gsd-db: No database open");
1699
- // Must delete verification_evidence first (FK constraint)
1700
1967
  currentDb.prepare(
1701
- `DELETE FROM verification_evidence WHERE milestone_id = :mid AND slice_id = :sid AND task_id = :tid`,
1702
- ).run({ ":mid": milestoneId, ":sid": sliceId, ":tid": taskId });
1968
+ `DELETE FROM assessments WHERE milestone_id = :mid AND scope = :scope`,
1969
+ ).run({ ":mid": milestoneId, ":scope": scope });
1970
+ }
1971
+
1972
+ export function deleteVerificationEvidence(milestoneId: string, sliceId: string, taskId: string): void {
1973
+ if (!currentDb) throw new GSDError(GSD_STALE_STATE, "gsd-db: No database open");
1703
1974
  currentDb.prepare(
1704
- `DELETE FROM tasks WHERE milestone_id = :mid AND slice_id = :sid AND id = :tid`,
1975
+ `DELETE FROM verification_evidence WHERE milestone_id = :mid AND slice_id = :sid AND task_id = :tid`,
1705
1976
  ).run({ ":mid": milestoneId, ":sid": sliceId, ":tid": taskId });
1706
1977
  }
1707
1978
 
1979
+ export function deleteTask(milestoneId: string, sliceId: string, taskId: string): void {
1980
+ if (!currentDb) throw new GSDError(GSD_STALE_STATE, "gsd-db: No database open");
1981
+ transaction(() => {
1982
+ // Must delete verification_evidence first (FK constraint)
1983
+ currentDb!.prepare(
1984
+ `DELETE FROM verification_evidence WHERE milestone_id = :mid AND slice_id = :sid AND task_id = :tid`,
1985
+ ).run({ ":mid": milestoneId, ":sid": sliceId, ":tid": taskId });
1986
+ currentDb!.prepare(
1987
+ `DELETE FROM tasks WHERE milestone_id = :mid AND slice_id = :sid AND id = :tid`,
1988
+ ).run({ ":mid": milestoneId, ":sid": sliceId, ":tid": taskId });
1989
+ });
1990
+ }
1991
+
1708
1992
  export function deleteSlice(milestoneId: string, sliceId: string): void {
1709
1993
  if (!currentDb) throw new GSDError(GSD_STALE_STATE, "gsd-db: No database open");
1710
- // Cascade-style manual deletion: evidence → tasks → slice
1711
- currentDb.prepare(
1712
- `DELETE FROM verification_evidence WHERE milestone_id = :mid AND slice_id = :sid`,
1713
- ).run({ ":mid": milestoneId, ":sid": sliceId });
1714
- currentDb.prepare(
1715
- `DELETE FROM tasks WHERE milestone_id = :mid AND slice_id = :sid`,
1716
- ).run({ ":mid": milestoneId, ":sid": sliceId });
1717
- currentDb.prepare(
1718
- `DELETE FROM slices WHERE milestone_id = :mid AND id = :sid`,
1719
- ).run({ ":mid": milestoneId, ":sid": sliceId });
1994
+ transaction(() => {
1995
+ // Cascade-style manual deletion: evidence → tasks → dependencies → slice
1996
+ currentDb!.prepare(
1997
+ `DELETE FROM verification_evidence WHERE milestone_id = :mid AND slice_id = :sid`,
1998
+ ).run({ ":mid": milestoneId, ":sid": sliceId });
1999
+ currentDb!.prepare(
2000
+ `DELETE FROM tasks WHERE milestone_id = :mid AND slice_id = :sid`,
2001
+ ).run({ ":mid": milestoneId, ":sid": sliceId });
2002
+ currentDb!.prepare(
2003
+ `DELETE FROM slice_dependencies WHERE milestone_id = :mid AND slice_id = :sid`,
2004
+ ).run({ ":mid": milestoneId, ":sid": sliceId });
2005
+ currentDb!.prepare(
2006
+ `DELETE FROM slice_dependencies WHERE milestone_id = :mid AND depends_on_slice_id = :sid`,
2007
+ ).run({ ":mid": milestoneId, ":sid": sliceId });
2008
+ currentDb!.prepare(
2009
+ `DELETE FROM slices WHERE milestone_id = :mid AND id = :sid`,
2010
+ ).run({ ":mid": milestoneId, ":sid": sliceId });
2011
+ });
1720
2012
  }
1721
2013
 
1722
2014
  export function updateSliceFields(milestoneId: string, sliceId: string, fields: {
@@ -450,7 +450,10 @@ async function buildDiscussSlicePrompt(
450
450
  }
451
451
 
452
452
  // Completed slice summaries — what was already built that this slice builds on
453
+ // Ensure DB is open so getMilestoneSlices returns real data (#2560).
453
454
  {
455
+ const { ensureDbOpen } = await import("./bootstrap/dynamic-tools.js");
456
+ await ensureDbOpen();
454
457
  type NormSlice = { id: string; done: boolean };
455
458
  let normSlices: NormSlice[] = [];
456
459
  if (isDbAvailable()) {
@@ -588,6 +591,14 @@ export async function showDiscuss(
588
591
  return;
589
592
  }
590
593
 
594
+ // Ensure DB is open before querying slices (#2560).
595
+ // showDiscuss() is a command handler — unlike tool handlers, it has no
596
+ // automatic ensureDbOpen() call. Without this, isDbAvailable() returns
597
+ // false on cold-start sessions and normSlices falls to [] → false
598
+ // "All slices complete" exit.
599
+ const { ensureDbOpen } = await import("./bootstrap/dynamic-tools.js");
600
+ await ensureDbOpen();
601
+
591
602
  // Guard: no roadmap yet (unless DB has slices)
592
603
  const roadmapFile = resolveMilestoneFile(basePath, mid, "ROADMAP");
593
604
  const roadmapContent = roadmapFile ? await loadFile(roadmapFile) : null;
@@ -15,6 +15,7 @@ import { ensureGitignore, untrackRuntimeFiles } from "./gitignore.js";
15
15
  import { gsdRoot } from "./paths.js";
16
16
  import { assertSafeDirectory } from "./validate-directory.js";
17
17
  import type { ProjectDetection, ProjectSignals } from "./detection.js";
18
+ import { runSkillInstallStep } from "./skill-catalog.js";
18
19
 
19
20
  // ─── Types ──────────────────────────────────────────────────────────────────────
20
21
 
@@ -223,7 +224,14 @@ export async function showProjectInit(
223
224
  await customizeAdvancedPrefs(ctx, prefs);
224
225
  }
225
226
 
226
- // ── Step 8: Bootstrap .gsd/ ────────────────────────────────────────────────
227
+ // ── Step 8: Skill Installation ─────────────────────────────────────────────
228
+ try {
229
+ await runSkillInstallStep(ctx, signals);
230
+ } catch {
231
+ // Non-fatal — skill installation failure should never block project init
232
+ }
233
+
234
+ // ── Step 9: Bootstrap .gsd/ ────────────────────────────────────────────────
227
235
  bootstrapGsdDirectory(basePath, prefs, signals);
228
236
 
229
237
  // Ensure .gitignore
@@ -414,9 +422,9 @@ function bootstrapGsdDirectory(
414
422
  const gsd = gsdRoot(basePath);
415
423
  mkdirSync(join(gsd, "milestones"), { recursive: true });
416
424
 
417
- // Write preferences.md from wizard answers
425
+ // Write PREFERENCES.md from wizard answers
418
426
  const preferencesContent = buildPreferencesFile(prefs);
419
- writeFileSync(join(gsd, "preferences.md"), preferencesContent, "utf-8");
427
+ writeFileSync(join(gsd, "PREFERENCES.md"), preferencesContent, "utf-8");
420
428
 
421
429
  // Seed CONTEXT.md with detected project signals
422
430
  const contextContent = buildContextSeed(signals);