gsd-pi 2.75.0-dev.063e5a3 → 2.75.0-dev.96d4bb599

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 (760) hide show
  1. package/README.md +186 -149
  2. package/dist/claude-cli-check.d.ts +10 -0
  3. package/dist/claude-cli-check.js +13 -3
  4. package/dist/headless-events.d.ts +1 -1
  5. package/dist/headless-events.js +5 -2
  6. package/dist/headless.js +5 -6
  7. package/dist/loader.js +0 -0
  8. package/dist/onboarding.d.ts +20 -1
  9. package/dist/onboarding.js +99 -39
  10. package/dist/resources/extensions/ask-user-questions.js +17 -5
  11. package/dist/resources/extensions/claude-code-cli/models.js +9 -0
  12. package/dist/resources/extensions/claude-code-cli/readiness.js +12 -2
  13. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +76 -4
  14. package/dist/resources/extensions/gsd/auto/detect-stuck.js +9 -0
  15. package/dist/resources/extensions/gsd/auto/loop.js +67 -4
  16. package/dist/resources/extensions/gsd/auto/phases.js +70 -47
  17. package/dist/resources/extensions/gsd/auto/resolve.js +1 -1
  18. package/dist/resources/extensions/gsd/auto/run-unit.js +10 -1
  19. package/dist/resources/extensions/gsd/auto/session.js +5 -0
  20. package/dist/resources/extensions/gsd/auto-artifact-paths.js +20 -0
  21. package/dist/resources/extensions/gsd/auto-dashboard.js +15 -7
  22. package/dist/resources/extensions/gsd/auto-dispatch.js +112 -6
  23. package/dist/resources/extensions/gsd/auto-loop.js +1 -1
  24. package/dist/resources/extensions/gsd/auto-model-selection.js +11 -3
  25. package/dist/resources/extensions/gsd/auto-post-unit.js +10 -8
  26. package/dist/resources/extensions/gsd/auto-prompts.js +173 -39
  27. package/dist/resources/extensions/gsd/auto-recovery.js +57 -0
  28. package/dist/resources/extensions/gsd/auto-start.js +5 -3
  29. package/dist/resources/extensions/gsd/auto-verification.js +3 -3
  30. package/dist/resources/extensions/gsd/auto-worktree.js +55 -1
  31. package/dist/resources/extensions/gsd/auto.js +57 -25
  32. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +8 -21
  33. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +45 -23
  34. package/dist/resources/extensions/gsd/bootstrap/memory-tools.js +128 -0
  35. package/dist/resources/extensions/gsd/bootstrap/query-tools.js +29 -0
  36. package/dist/resources/extensions/gsd/bootstrap/register-extension.js +2 -0
  37. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +22 -0
  38. package/dist/resources/extensions/gsd/bootstrap/system-context.js +17 -4
  39. package/dist/resources/extensions/gsd/commands/catalog.js +81 -9
  40. package/dist/resources/extensions/gsd/commands/handlers/core.js +64 -24
  41. package/dist/resources/extensions/gsd/commands/handlers/escalate.js +171 -0
  42. package/dist/resources/extensions/gsd/commands/handlers/onboarding.js +159 -0
  43. package/dist/resources/extensions/gsd/commands/handlers/ops.js +21 -0
  44. package/dist/resources/extensions/gsd/commands/handlers/workflow.js +228 -29
  45. package/dist/resources/extensions/gsd/commands-cmux.js +5 -2
  46. package/dist/resources/extensions/gsd/commands-config.js +5 -0
  47. package/dist/resources/extensions/gsd/commands-debug.js +388 -0
  48. package/dist/resources/extensions/gsd/commands-do.js +1 -0
  49. package/dist/resources/extensions/gsd/commands-extract-learnings.js +233 -75
  50. package/dist/resources/extensions/gsd/commands-handlers.js +21 -2
  51. package/dist/resources/extensions/gsd/commands-memory.js +462 -0
  52. package/dist/resources/extensions/gsd/commands-prefs-wizard.js +40 -12
  53. package/dist/resources/extensions/gsd/commands-scan.js +94 -0
  54. package/dist/resources/extensions/gsd/commands-workflow-templates.js +101 -2
  55. package/dist/resources/extensions/gsd/custom-workflow-engine.js +74 -54
  56. package/dist/resources/extensions/gsd/db-writer.js +1 -0
  57. package/dist/resources/extensions/gsd/debug-session-store.js +238 -0
  58. package/dist/resources/extensions/gsd/definition-loader.js +7 -0
  59. package/dist/resources/extensions/gsd/docs/preferences-reference.md +9 -9
  60. package/dist/resources/extensions/gsd/doctor-environment.js +2 -1
  61. package/dist/resources/extensions/gsd/doctor-git-checks.js +5 -1
  62. package/dist/resources/extensions/gsd/doctor-proactive.js +4 -1
  63. package/dist/resources/extensions/gsd/doctor-providers.js +48 -20
  64. package/dist/resources/extensions/gsd/doctor-runtime-checks.js +22 -4
  65. package/dist/resources/extensions/gsd/doctor.js +7 -1
  66. package/dist/resources/extensions/gsd/error-classifier.js +6 -3
  67. package/dist/resources/extensions/gsd/escalation.js +321 -0
  68. package/dist/resources/extensions/gsd/forensics.js +26 -29
  69. package/dist/resources/extensions/gsd/git-service.js +0 -1
  70. package/dist/resources/extensions/gsd/graph.js +26 -2
  71. package/dist/resources/extensions/gsd/gsd-db.js +490 -32
  72. package/dist/resources/extensions/gsd/health-widget-core.js +42 -14
  73. package/dist/resources/extensions/gsd/health-widget.js +7 -4
  74. package/dist/resources/extensions/gsd/init-wizard.js +86 -45
  75. package/dist/resources/extensions/gsd/markdown-renderer.js +5 -5
  76. package/dist/resources/extensions/gsd/memory-embeddings.js +219 -0
  77. package/dist/resources/extensions/gsd/memory-extractor.js +78 -27
  78. package/dist/resources/extensions/gsd/memory-ingest.js +218 -0
  79. package/dist/resources/extensions/gsd/memory-relations.js +189 -0
  80. package/dist/resources/extensions/gsd/memory-source-store.js +113 -0
  81. package/dist/resources/extensions/gsd/memory-store.js +299 -6
  82. package/dist/resources/extensions/gsd/metrics.js +1 -0
  83. package/dist/resources/extensions/gsd/model-cost-table.js +3 -1
  84. package/dist/resources/extensions/gsd/model-router.js +16 -6
  85. package/dist/resources/extensions/gsd/native-git-bridge.js +137 -5
  86. package/dist/resources/extensions/gsd/notification-overlay.js +7 -22
  87. package/dist/resources/extensions/gsd/notification-widget.js +24 -39
  88. package/dist/resources/extensions/gsd/notifications.js +4 -0
  89. package/dist/resources/extensions/gsd/onboarding-state.js +133 -0
  90. package/dist/resources/extensions/gsd/post-execution-checks.js +27 -11
  91. package/dist/resources/extensions/gsd/pre-execution-checks.js +97 -4
  92. package/dist/resources/extensions/gsd/preferences-models.js +1 -0
  93. package/dist/resources/extensions/gsd/preferences-types.js +2 -1
  94. package/dist/resources/extensions/gsd/preferences-validation.js +42 -8
  95. package/dist/resources/extensions/gsd/preferences.js +10 -10
  96. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +4 -1
  97. package/dist/resources/extensions/gsd/prompts/debug-diagnose.md +25 -0
  98. package/dist/resources/extensions/gsd/prompts/debug-session-manager.md +80 -0
  99. package/dist/resources/extensions/gsd/prompts/execute-task.md +12 -0
  100. package/dist/resources/extensions/gsd/prompts/plan-milestone.md +12 -0
  101. package/dist/resources/extensions/gsd/prompts/refine-slice.md +69 -0
  102. package/dist/resources/extensions/gsd/prompts/scan.md +79 -0
  103. package/dist/resources/extensions/gsd/prompts/workflow-oneshot.md +26 -0
  104. package/dist/resources/extensions/gsd/python-resolver.js +70 -0
  105. package/dist/resources/extensions/gsd/run-manager.js +37 -17
  106. package/dist/resources/extensions/gsd/setup-catalog.js +75 -0
  107. package/dist/resources/extensions/gsd/state.js +47 -3
  108. package/dist/resources/extensions/gsd/templates/PREFERENCES.md +7 -7
  109. package/dist/resources/extensions/gsd/tools/complete-task.js +80 -0
  110. package/dist/resources/extensions/gsd/tools/memory-tools.js +306 -0
  111. package/dist/resources/extensions/gsd/tools/plan-milestone.js +37 -12
  112. package/dist/resources/extensions/gsd/tools/plan-slice.js +5 -2
  113. package/dist/resources/extensions/gsd/tools/skip-slice.js +78 -0
  114. package/dist/resources/extensions/gsd/uok/flags.js +7 -7
  115. package/dist/resources/extensions/gsd/uok/kernel.js +8 -3
  116. package/dist/resources/extensions/gsd/verification-gate.js +2 -1
  117. package/dist/resources/extensions/gsd/workflow-dispatch.js +64 -0
  118. package/dist/resources/extensions/gsd/workflow-install.js +327 -0
  119. package/dist/resources/extensions/gsd/workflow-manifest.js +8 -0
  120. package/dist/resources/extensions/gsd/workflow-mcp.js +1 -6
  121. package/dist/resources/extensions/gsd/workflow-plugins.js +346 -0
  122. package/dist/resources/extensions/gsd/workflow-projections.js +17 -15
  123. package/dist/resources/extensions/gsd/workflow-templates/accessibility-audit.md +88 -0
  124. package/dist/resources/extensions/gsd/workflow-templates/api-breaking-change.md +117 -0
  125. package/dist/resources/extensions/gsd/workflow-templates/bugfix.md +1 -0
  126. package/dist/resources/extensions/gsd/workflow-templates/changelog-gen.md +82 -0
  127. package/dist/resources/extensions/gsd/workflow-templates/ci-bootstrap.md +144 -0
  128. package/dist/resources/extensions/gsd/workflow-templates/dead-code.md +81 -0
  129. package/dist/resources/extensions/gsd/workflow-templates/dep-upgrade.md +1 -0
  130. package/dist/resources/extensions/gsd/workflow-templates/docs-sync.yaml +76 -0
  131. package/dist/resources/extensions/gsd/workflow-templates/env-audit.yaml +88 -0
  132. package/dist/resources/extensions/gsd/workflow-templates/full-project.md +1 -0
  133. package/dist/resources/extensions/gsd/workflow-templates/hotfix.md +1 -0
  134. package/dist/resources/extensions/gsd/workflow-templates/issue-triage.md +84 -0
  135. package/dist/resources/extensions/gsd/workflow-templates/observability-setup.md +133 -0
  136. package/dist/resources/extensions/gsd/workflow-templates/onboarding-check.md +74 -0
  137. package/dist/resources/extensions/gsd/workflow-templates/performance-audit.md +125 -0
  138. package/dist/resources/extensions/gsd/workflow-templates/pr-review.md +67 -0
  139. package/dist/resources/extensions/gsd/workflow-templates/pr-triage.md +83 -0
  140. package/dist/resources/extensions/gsd/workflow-templates/refactor.md +1 -0
  141. package/dist/resources/extensions/gsd/workflow-templates/registry.json +184 -0
  142. package/dist/resources/extensions/gsd/workflow-templates/release.md +118 -0
  143. package/dist/resources/extensions/gsd/workflow-templates/rename-symbol.yaml +99 -0
  144. package/dist/resources/extensions/gsd/workflow-templates/security-audit.md +1 -0
  145. package/dist/resources/extensions/gsd/workflow-templates/small-feature.md +1 -0
  146. package/dist/resources/extensions/gsd/workflow-templates/spike.md +1 -0
  147. package/dist/resources/extensions/gsd/workflow-templates/test-backfill.yaml +73 -0
  148. package/dist/resources/extensions/gsd/worktree-resolver.js +42 -1
  149. package/dist/resources/extensions/remote-questions/commands.js +380 -0
  150. package/dist/resources/extensions/remote-questions/manager.js +39 -5
  151. package/dist/resources/extensions/remote-questions/telegram-adapter.js +79 -4
  152. package/dist/resources/extensions/shared/interview-ui.js +189 -1
  153. package/dist/resources/extensions/shared/layout-utils.js +17 -0
  154. package/dist/resources/extensions/shared/rtk-shared.js +47 -0
  155. package/dist/resources/extensions/shared/rtk.js +3 -46
  156. package/dist/resources/skills/create-workflow/SKILL.md +33 -6
  157. package/dist/rtk-shared.d.ts +10 -0
  158. package/dist/rtk-shared.js +47 -0
  159. package/dist/rtk.d.ts +2 -6
  160. package/dist/rtk.js +3 -48
  161. package/dist/shared/workspace-types.d.ts +52 -0
  162. package/dist/shared/workspace-types.js +1 -0
  163. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  164. package/dist/update-check.d.ts +10 -0
  165. package/dist/update-check.js +24 -3
  166. package/dist/web/standalone/.next/BUILD_ID +1 -1
  167. package/dist/web/standalone/.next/app-path-routes-manifest.json +5 -5
  168. package/dist/web/standalone/.next/build-manifest.json +3 -3
  169. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  170. package/dist/web/standalone/.next/react-loadable-manifest.json +2 -2
  171. package/dist/web/standalone/.next/required-server-files.json +1 -1
  172. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  173. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  174. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  175. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  176. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  177. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  178. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  179. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  180. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  181. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  182. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  183. package/dist/web/standalone/.next/server/app/_not-found.rsc +2 -2
  184. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
  185. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  186. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +2 -2
  187. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  188. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  189. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  190. package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
  191. package/dist/web/standalone/.next/server/app/api/boot/route.js.nft.json +1 -1
  192. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
  193. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js.nft.json +1 -1
  194. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
  195. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js.nft.json +1 -1
  196. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
  197. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js.nft.json +1 -1
  198. package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
  199. package/dist/web/standalone/.next/server/app/api/captures/route.js.nft.json +1 -1
  200. package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
  201. package/dist/web/standalone/.next/server/app/api/cleanup/route.js.nft.json +1 -1
  202. package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
  203. package/dist/web/standalone/.next/server/app/api/doctor/route.js.nft.json +1 -1
  204. package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
  205. package/dist/web/standalone/.next/server/app/api/export-data/route.js.nft.json +1 -1
  206. package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
  207. package/dist/web/standalone/.next/server/app/api/files/route.js.nft.json +1 -1
  208. package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
  209. package/dist/web/standalone/.next/server/app/api/forensics/route.js.nft.json +1 -1
  210. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  211. package/dist/web/standalone/.next/server/app/api/git/route.js.nft.json +1 -1
  212. package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
  213. package/dist/web/standalone/.next/server/app/api/history/route.js.nft.json +1 -1
  214. package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
  215. package/dist/web/standalone/.next/server/app/api/hooks/route.js.nft.json +1 -1
  216. package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
  217. package/dist/web/standalone/.next/server/app/api/inspect/route.js.nft.json +1 -1
  218. package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
  219. package/dist/web/standalone/.next/server/app/api/knowledge/route.js.nft.json +1 -1
  220. package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
  221. package/dist/web/standalone/.next/server/app/api/live-state/route.js.nft.json +1 -1
  222. package/dist/web/standalone/.next/server/app/api/notifications/route.js +2 -2
  223. package/dist/web/standalone/.next/server/app/api/notifications/route.js.nft.json +1 -1
  224. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  225. package/dist/web/standalone/.next/server/app/api/onboarding/route.js.nft.json +1 -1
  226. package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
  227. package/dist/web/standalone/.next/server/app/api/projects/route.js.nft.json +1 -1
  228. package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
  229. package/dist/web/standalone/.next/server/app/api/recovery/route.js.nft.json +1 -1
  230. package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
  231. package/dist/web/standalone/.next/server/app/api/session/browser/route.js.nft.json +1 -1
  232. package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
  233. package/dist/web/standalone/.next/server/app/api/session/command/route.js.nft.json +1 -1
  234. package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
  235. package/dist/web/standalone/.next/server/app/api/session/events/route.js.nft.json +1 -1
  236. package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
  237. package/dist/web/standalone/.next/server/app/api/session/manage/route.js.nft.json +1 -1
  238. package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
  239. package/dist/web/standalone/.next/server/app/api/settings-data/route.js.nft.json +1 -1
  240. package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
  241. package/dist/web/standalone/.next/server/app/api/skill-health/route.js.nft.json +1 -1
  242. package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
  243. package/dist/web/standalone/.next/server/app/api/steer/route.js.nft.json +1 -1
  244. package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
  245. package/dist/web/standalone/.next/server/app/api/switch-root/route.js.nft.json +1 -1
  246. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +2 -2
  247. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js.nft.json +1 -1
  248. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +2 -2
  249. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js.nft.json +1 -1
  250. package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
  251. package/dist/web/standalone/.next/server/app/api/undo/route.js.nft.json +1 -1
  252. package/dist/web/standalone/.next/server/app/api/update/route.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/index.html +1 -1
  256. package/dist/web/standalone/.next/server/app/index.rsc +3 -3
  257. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  258. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +3 -3
  259. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  260. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +2 -2
  261. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  262. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  263. package/dist/web/standalone/.next/server/app-paths-manifest.json +5 -5
  264. package/dist/web/standalone/.next/server/chunks/6897.js +2 -2
  265. package/dist/web/standalone/.next/server/chunks/7461.js +1 -0
  266. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  267. package/dist/web/standalone/.next/server/middleware-manifest.json +5 -5
  268. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  269. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  270. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  271. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  272. package/dist/web/standalone/.next/static/chunks/2826.e59e8578e2e28639.js +9 -0
  273. package/dist/web/standalone/.next/static/chunks/{2008.71ee9230ad78df21.js → 3621.fc7480022c972438.js} +2 -2
  274. package/dist/web/standalone/.next/static/chunks/app/{page-f1e30ab6bb269149.js → page-5b113fd32bc2a1c3.js} +1 -1
  275. package/dist/web/standalone/.next/static/chunks/{webpack-b868033a5834586d.js → webpack-5fc74f13a25fa1bb.js} +1 -1
  276. package/dist/web/standalone/.next/static/css/632cd626b1731d88.css +1 -0
  277. package/dist/web/standalone/server.js +1 -1
  278. package/dist/welcome-screen.js +48 -24
  279. package/dist/wizard.js +2 -2
  280. package/dist/worktree-cli.d.ts +6 -5
  281. package/dist/worktree-cli.js +23 -7
  282. package/package.json +3 -3
  283. package/packages/mcp-server/dist/server.d.ts.map +1 -1
  284. package/packages/mcp-server/dist/server.js +12 -10
  285. package/packages/mcp-server/dist/server.js.map +1 -1
  286. package/packages/mcp-server/dist/session-manager.d.ts.map +1 -1
  287. package/packages/mcp-server/dist/session-manager.js +8 -1
  288. package/packages/mcp-server/dist/session-manager.js.map +1 -1
  289. package/packages/mcp-server/dist/workflow-tools.d.ts +1 -0
  290. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  291. package/packages/mcp-server/dist/workflow-tools.js +113 -14
  292. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  293. package/packages/mcp-server/src/mcp-server.test.ts +40 -4
  294. package/packages/mcp-server/src/server.ts +12 -10
  295. package/packages/mcp-server/src/session-manager.ts +10 -3
  296. package/packages/mcp-server/src/workflow-tools.test.ts +91 -1
  297. package/packages/mcp-server/src/workflow-tools.ts +128 -18
  298. package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
  299. package/packages/native/tsconfig.tsbuildinfo +1 -1
  300. package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -1
  301. package/packages/pi-ai/dist/models/capability-patches.d.ts.map +1 -1
  302. package/packages/pi-ai/dist/models/capability-patches.js +3 -2
  303. package/packages/pi-ai/dist/models/capability-patches.js.map +1 -1
  304. package/packages/pi-ai/dist/models/generated/amazon-bedrock.d.ts +68 -0
  305. package/packages/pi-ai/dist/models/generated/amazon-bedrock.d.ts.map +1 -1
  306. package/packages/pi-ai/dist/models/generated/amazon-bedrock.js +68 -0
  307. package/packages/pi-ai/dist/models/generated/amazon-bedrock.js.map +1 -1
  308. package/packages/pi-ai/dist/models/generated/anthropic.d.ts +17 -0
  309. package/packages/pi-ai/dist/models/generated/anthropic.d.ts.map +1 -1
  310. package/packages/pi-ai/dist/models/generated/anthropic.js +17 -0
  311. package/packages/pi-ai/dist/models/generated/anthropic.js.map +1 -1
  312. package/packages/pi-ai/dist/models/generated/google-antigravity.d.ts +17 -0
  313. package/packages/pi-ai/dist/models/generated/google-antigravity.d.ts.map +1 -1
  314. package/packages/pi-ai/dist/models/generated/google-antigravity.js +17 -0
  315. package/packages/pi-ai/dist/models/generated/google-antigravity.js.map +1 -1
  316. package/packages/pi-ai/dist/models/generated/groq.d.ts +0 -153
  317. package/packages/pi-ai/dist/models/generated/groq.d.ts.map +1 -1
  318. package/packages/pi-ai/dist/models/generated/groq.js +0 -153
  319. package/packages/pi-ai/dist/models/generated/groq.js.map +1 -1
  320. package/packages/pi-ai/dist/models/generated/index.d.ts +136 -153
  321. package/packages/pi-ai/dist/models/generated/index.d.ts.map +1 -1
  322. package/packages/pi-ai/dist/models/generated/openai-codex.d.ts +17 -0
  323. package/packages/pi-ai/dist/models/generated/openai-codex.d.ts.map +1 -1
  324. package/packages/pi-ai/dist/models/generated/openai-codex.js +17 -0
  325. package/packages/pi-ai/dist/models/generated/openai-codex.js.map +1 -1
  326. package/packages/pi-ai/dist/models/generated/openrouter.d.ts +17 -0
  327. package/packages/pi-ai/dist/models/generated/openrouter.d.ts.map +1 -1
  328. package/packages/pi-ai/dist/models/generated/openrouter.js +17 -0
  329. package/packages/pi-ai/dist/models/generated/openrouter.js.map +1 -1
  330. package/packages/pi-ai/dist/models.generated.test.js +17 -0
  331. package/packages/pi-ai/dist/models.generated.test.js.map +1 -1
  332. package/packages/pi-ai/dist/providers/amazon-bedrock.d.ts +22 -1
  333. package/packages/pi-ai/dist/providers/amazon-bedrock.d.ts.map +1 -1
  334. package/packages/pi-ai/dist/providers/amazon-bedrock.js +40 -6
  335. package/packages/pi-ai/dist/providers/amazon-bedrock.js.map +1 -1
  336. package/packages/pi-ai/dist/providers/amazon-bedrock.test.d.ts +2 -0
  337. package/packages/pi-ai/dist/providers/amazon-bedrock.test.d.ts.map +1 -0
  338. package/packages/pi-ai/dist/providers/amazon-bedrock.test.js +106 -0
  339. package/packages/pi-ai/dist/providers/amazon-bedrock.test.js.map +1 -0
  340. package/packages/pi-ai/dist/providers/anthropic-auth.test.js +42 -1
  341. package/packages/pi-ai/dist/providers/anthropic-auth.test.js.map +1 -1
  342. package/packages/pi-ai/dist/providers/anthropic-shared.d.ts +20 -1
  343. package/packages/pi-ai/dist/providers/anthropic-shared.d.ts.map +1 -1
  344. package/packages/pi-ai/dist/providers/anthropic-shared.js +32 -2
  345. package/packages/pi-ai/dist/providers/anthropic-shared.js.map +1 -1
  346. package/packages/pi-ai/dist/providers/anthropic-shared.test.js +12 -1
  347. package/packages/pi-ai/dist/providers/anthropic-shared.test.js.map +1 -1
  348. package/packages/pi-ai/dist/providers/anthropic.d.ts +11 -0
  349. package/packages/pi-ai/dist/providers/anthropic.d.ts.map +1 -1
  350. package/packages/pi-ai/dist/providers/anthropic.js +18 -1
  351. package/packages/pi-ai/dist/providers/anthropic.js.map +1 -1
  352. package/packages/pi-ai/dist/utils/oauth/openai-codex.d.ts.map +1 -1
  353. package/packages/pi-ai/dist/utils/oauth/openai-codex.js +12 -0
  354. package/packages/pi-ai/dist/utils/oauth/openai-codex.js.map +1 -1
  355. package/packages/pi-ai/package.json +1 -1
  356. package/packages/pi-ai/scripts/generate-models.ts +50 -0
  357. package/packages/pi-ai/src/models/capability-patches.ts +5 -2
  358. package/packages/pi-ai/src/models/generated/amazon-bedrock.ts +68 -0
  359. package/packages/pi-ai/src/models/generated/anthropic.ts +17 -0
  360. package/packages/pi-ai/src/models/generated/google-antigravity.ts +17 -0
  361. package/packages/pi-ai/src/models/generated/groq.ts +0 -153
  362. package/packages/pi-ai/src/models/generated/openai-codex.ts +17 -0
  363. package/packages/pi-ai/src/models/generated/openrouter.ts +17 -0
  364. package/packages/pi-ai/src/models.generated.test.ts +17 -0
  365. package/packages/pi-ai/src/providers/amazon-bedrock.test.ts +164 -0
  366. package/packages/pi-ai/src/providers/amazon-bedrock.ts +41 -7
  367. package/packages/pi-ai/src/providers/anthropic-auth.test.ts +47 -1
  368. package/packages/pi-ai/src/providers/anthropic-shared.test.ts +15 -1
  369. package/packages/pi-ai/src/providers/anthropic-shared.ts +36 -3
  370. package/packages/pi-ai/src/providers/anthropic.ts +19 -1
  371. package/packages/pi-ai/src/utils/oauth/openai-codex.ts +15 -0
  372. package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
  373. package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.d.ts +2 -0
  374. package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.d.ts.map +1 -0
  375. package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js +38 -0
  376. package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js.map +1 -0
  377. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts +14 -0
  378. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts.map +1 -1
  379. package/packages/pi-coding-agent/dist/core/auth-storage.js +34 -0
  380. package/packages/pi-coding-agent/dist/core/auth-storage.js.map +1 -1
  381. package/packages/pi-coding-agent/dist/core/auth-storage.test.js +74 -0
  382. package/packages/pi-coding-agent/dist/core/auth-storage.test.js.map +1 -1
  383. package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js +4 -1
  384. package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js.map +1 -1
  385. package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js +32 -0
  386. package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js.map +1 -1
  387. package/packages/pi-coding-agent/dist/core/sdk.d.ts.map +1 -1
  388. package/packages/pi-coding-agent/dist/core/sdk.js +32 -0
  389. package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
  390. package/packages/pi-coding-agent/dist/core/skill-tool.test.js +2 -2
  391. package/packages/pi-coding-agent/dist/core/skill-tool.test.js.map +1 -1
  392. package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.d.ts.map +1 -1
  393. package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.js +17 -7
  394. package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.js.map +1 -1
  395. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.d.ts.map +1 -1
  396. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js +48 -34
  397. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js.map +1 -1
  398. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts +4 -0
  399. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  400. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +83 -33
  401. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  402. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-schema.d.ts +70 -0
  403. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-schema.d.ts.map +1 -0
  404. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-schema.js +77 -0
  405. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-schema.js.map +1 -0
  406. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.d.ts +1 -66
  407. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  408. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.js +1 -75
  409. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.js.map +1 -1
  410. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.d.ts +1 -1
  411. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.d.ts.map +1 -1
  412. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js +192 -24
  413. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js.map +1 -1
  414. package/packages/pi-coding-agent/src/core/agent-session-abort-order.test.ts +56 -0
  415. package/packages/pi-coding-agent/src/core/auth-storage.test.ts +83 -0
  416. package/packages/pi-coding-agent/src/core/auth-storage.ts +35 -0
  417. package/packages/pi-coding-agent/src/core/chat-controller-ordering.test.ts +4 -1
  418. package/packages/pi-coding-agent/src/core/model-registry-auth-mode.test.ts +37 -1
  419. package/packages/pi-coding-agent/src/core/sdk.ts +41 -0
  420. package/packages/pi-coding-agent/src/core/skill-tool.test.ts +2 -2
  421. package/packages/pi-coding-agent/src/modes/interactive/components/chat-frame.ts +19 -7
  422. package/packages/pi-coding-agent/src/modes/interactive/components/footer.ts +53 -31
  423. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +88 -36
  424. package/packages/pi-coding-agent/src/modes/interactive/theme/theme-schema.ts +83 -0
  425. package/packages/pi-coding-agent/src/modes/interactive/theme/theme.ts +2 -83
  426. package/packages/pi-coding-agent/src/modes/interactive/theme/themes.ts +208 -27
  427. package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
  428. package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
  429. package/packages/rpc-client/tsconfig.tsbuildinfo +1 -1
  430. package/pkg/dist/modes/interactive/theme/theme-schema.d.ts +70 -0
  431. package/pkg/dist/modes/interactive/theme/theme-schema.d.ts.map +1 -0
  432. package/pkg/dist/modes/interactive/theme/theme-schema.js +77 -0
  433. package/pkg/dist/modes/interactive/theme/theme-schema.js.map +1 -0
  434. package/pkg/dist/modes/interactive/theme/theme.d.ts +1 -66
  435. package/pkg/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  436. package/pkg/dist/modes/interactive/theme/theme.js +1 -75
  437. package/pkg/dist/modes/interactive/theme/theme.js.map +1 -1
  438. package/pkg/dist/modes/interactive/theme/themes.d.ts +1 -1
  439. package/pkg/dist/modes/interactive/theme/themes.d.ts.map +1 -1
  440. package/pkg/dist/modes/interactive/theme/themes.js +192 -24
  441. package/pkg/dist/modes/interactive/theme/themes.js.map +1 -1
  442. package/src/resources/extensions/ask-user-questions.ts +24 -6
  443. package/src/resources/extensions/claude-code-cli/models.ts +9 -0
  444. package/src/resources/extensions/claude-code-cli/readiness.ts +13 -2
  445. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +94 -4
  446. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +84 -0
  447. package/src/resources/extensions/gsd/auto/detect-stuck.ts +10 -0
  448. package/src/resources/extensions/gsd/auto/loop-deps.ts +1 -0
  449. package/src/resources/extensions/gsd/auto/loop.ts +109 -3
  450. package/src/resources/extensions/gsd/auto/phases.ts +94 -60
  451. package/src/resources/extensions/gsd/auto/resolve.ts +1 -1
  452. package/src/resources/extensions/gsd/auto/run-unit.ts +11 -1
  453. package/src/resources/extensions/gsd/auto/session.ts +7 -0
  454. package/src/resources/extensions/gsd/auto-artifact-paths.ts +20 -0
  455. package/src/resources/extensions/gsd/auto-dashboard.ts +21 -4
  456. package/src/resources/extensions/gsd/auto-dispatch.ts +123 -5
  457. package/src/resources/extensions/gsd/auto-loop.ts +1 -1
  458. package/src/resources/extensions/gsd/auto-model-selection.ts +14 -3
  459. package/src/resources/extensions/gsd/auto-post-unit.ts +10 -8
  460. package/src/resources/extensions/gsd/auto-prompts.ts +201 -40
  461. package/src/resources/extensions/gsd/auto-recovery.ts +63 -1
  462. package/src/resources/extensions/gsd/auto-start.ts +8 -6
  463. package/src/resources/extensions/gsd/auto-verification.ts +3 -3
  464. package/src/resources/extensions/gsd/auto-worktree.ts +65 -0
  465. package/src/resources/extensions/gsd/auto.ts +61 -28
  466. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +8 -21
  467. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +46 -24
  468. package/src/resources/extensions/gsd/bootstrap/memory-tools.ts +158 -0
  469. package/src/resources/extensions/gsd/bootstrap/query-tools.ts +31 -0
  470. package/src/resources/extensions/gsd/bootstrap/register-extension.ts +2 -0
  471. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +22 -0
  472. package/src/resources/extensions/gsd/bootstrap/system-context.ts +20 -4
  473. package/src/resources/extensions/gsd/commands/catalog.ts +74 -9
  474. package/src/resources/extensions/gsd/commands/handlers/core.ts +69 -27
  475. package/src/resources/extensions/gsd/commands/handlers/escalate.ts +216 -0
  476. package/src/resources/extensions/gsd/commands/handlers/onboarding.ts +196 -0
  477. package/src/resources/extensions/gsd/commands/handlers/ops.ts +21 -0
  478. package/src/resources/extensions/gsd/commands/handlers/workflow.ts +279 -29
  479. package/src/resources/extensions/gsd/commands-cmux.ts +6 -2
  480. package/src/resources/extensions/gsd/commands-config.ts +10 -0
  481. package/src/resources/extensions/gsd/commands-debug.ts +484 -0
  482. package/src/resources/extensions/gsd/commands-do.ts +1 -0
  483. package/src/resources/extensions/gsd/commands-extract-learnings.ts +295 -76
  484. package/src/resources/extensions/gsd/commands-handlers.ts +19 -2
  485. package/src/resources/extensions/gsd/commands-memory.ts +551 -0
  486. package/src/resources/extensions/gsd/commands-prefs-wizard.ts +49 -12
  487. package/src/resources/extensions/gsd/commands-scan.ts +125 -0
  488. package/src/resources/extensions/gsd/commands-workflow-templates.ts +129 -2
  489. package/src/resources/extensions/gsd/custom-workflow-engine.ts +85 -60
  490. package/src/resources/extensions/gsd/db-writer.ts +3 -0
  491. package/src/resources/extensions/gsd/debug-session-store.ts +377 -0
  492. package/src/resources/extensions/gsd/definition-loader.ts +7 -0
  493. package/src/resources/extensions/gsd/docs/preferences-reference.md +9 -9
  494. package/src/resources/extensions/gsd/doctor-environment.ts +2 -1
  495. package/src/resources/extensions/gsd/doctor-git-checks.ts +5 -1
  496. package/src/resources/extensions/gsd/doctor-proactive.ts +4 -1
  497. package/src/resources/extensions/gsd/doctor-providers.ts +52 -22
  498. package/src/resources/extensions/gsd/doctor-runtime-checks.ts +23 -4
  499. package/src/resources/extensions/gsd/doctor-types.ts +1 -0
  500. package/src/resources/extensions/gsd/doctor.ts +7 -1
  501. package/src/resources/extensions/gsd/error-classifier.ts +6 -3
  502. package/src/resources/extensions/gsd/escalation.ts +367 -0
  503. package/src/resources/extensions/gsd/forensics.ts +25 -29
  504. package/src/resources/extensions/gsd/git-service.ts +0 -1
  505. package/src/resources/extensions/gsd/graph.ts +33 -3
  506. package/src/resources/extensions/gsd/gsd-db.ts +578 -32
  507. package/src/resources/extensions/gsd/health-widget-core.ts +43 -14
  508. package/src/resources/extensions/gsd/health-widget.ts +7 -3
  509. package/src/resources/extensions/gsd/init-wizard.ts +87 -54
  510. package/src/resources/extensions/gsd/markdown-renderer.ts +5 -5
  511. package/src/resources/extensions/gsd/memory-embeddings.ts +235 -0
  512. package/src/resources/extensions/gsd/memory-extractor.ts +100 -34
  513. package/src/resources/extensions/gsd/memory-ingest.ts +286 -0
  514. package/src/resources/extensions/gsd/memory-relations.ts +240 -0
  515. package/src/resources/extensions/gsd/memory-source-store.ts +138 -0
  516. package/src/resources/extensions/gsd/memory-store.ts +351 -7
  517. package/src/resources/extensions/gsd/metrics.ts +1 -0
  518. package/src/resources/extensions/gsd/model-cost-table.ts +3 -1
  519. package/src/resources/extensions/gsd/model-router.ts +25 -6
  520. package/src/resources/extensions/gsd/native-git-bridge.ts +134 -6
  521. package/src/resources/extensions/gsd/notification-overlay.ts +9 -19
  522. package/src/resources/extensions/gsd/notification-widget.ts +25 -43
  523. package/src/resources/extensions/gsd/notifications.ts +6 -0
  524. package/src/resources/extensions/gsd/onboarding-state.ts +146 -0
  525. package/src/resources/extensions/gsd/post-execution-checks.ts +37 -14
  526. package/src/resources/extensions/gsd/pre-execution-checks.ts +98 -8
  527. package/src/resources/extensions/gsd/preferences-models.ts +1 -0
  528. package/src/resources/extensions/gsd/preferences-types.ts +10 -2
  529. package/src/resources/extensions/gsd/preferences-validation.ts +33 -7
  530. package/src/resources/extensions/gsd/preferences.ts +10 -10
  531. package/src/resources/extensions/gsd/prompts/complete-milestone.md +4 -1
  532. package/src/resources/extensions/gsd/prompts/debug-diagnose.md +25 -0
  533. package/src/resources/extensions/gsd/prompts/debug-session-manager.md +80 -0
  534. package/src/resources/extensions/gsd/prompts/execute-task.md +12 -0
  535. package/src/resources/extensions/gsd/prompts/plan-milestone.md +12 -0
  536. package/src/resources/extensions/gsd/prompts/refine-slice.md +69 -0
  537. package/src/resources/extensions/gsd/prompts/scan.md +79 -0
  538. package/src/resources/extensions/gsd/prompts/workflow-oneshot.md +26 -0
  539. package/src/resources/extensions/gsd/python-resolver.ts +76 -0
  540. package/src/resources/extensions/gsd/run-manager.ts +53 -19
  541. package/src/resources/extensions/gsd/setup-catalog.ts +105 -0
  542. package/src/resources/extensions/gsd/state.ts +50 -2
  543. package/src/resources/extensions/gsd/templates/PREFERENCES.md +7 -7
  544. package/src/resources/extensions/gsd/tests/agent-end-retry.test.ts +1 -34
  545. package/src/resources/extensions/gsd/tests/artifact-corruption-2630.test.ts +7 -0
  546. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +45 -31
  547. package/src/resources/extensions/gsd/tests/auto-migrating-recovery.test.ts +63 -0
  548. package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +12 -0
  549. package/src/resources/extensions/gsd/tests/auto-prompts-fallback.test.ts +35 -0
  550. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +123 -1
  551. package/src/resources/extensions/gsd/tests/auto-wrapup-inflight-guard.test.ts +39 -0
  552. package/src/resources/extensions/gsd/tests/autocomplete-regressions-1675.test.ts +39 -0
  553. package/src/resources/extensions/gsd/tests/commands-do.test.ts +48 -0
  554. package/src/resources/extensions/gsd/tests/commands-extract-learnings.test.ts +333 -21
  555. package/src/resources/extensions/gsd/tests/commands-scan.test.ts +351 -0
  556. package/src/resources/extensions/gsd/tests/commands-workflow-custom.test.ts +8 -6
  557. package/src/resources/extensions/gsd/tests/complete-slice.test.ts +6 -8
  558. package/src/resources/extensions/gsd/tests/complete-task.test.ts +2 -2
  559. package/src/resources/extensions/gsd/tests/custom-workflow-engine.test.ts +63 -0
  560. package/src/resources/extensions/gsd/tests/debug-command-handler.test.ts +905 -0
  561. package/src/resources/extensions/gsd/tests/debug-command-lifecycle.integration.test.ts +1229 -0
  562. package/src/resources/extensions/gsd/tests/debug-session-store.test.ts +565 -0
  563. package/src/resources/extensions/gsd/tests/discuss-milestone-structured-questions.test.ts +64 -0
  564. package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +67 -0
  565. package/src/resources/extensions/gsd/tests/doctor-providers.test.ts +62 -18
  566. package/src/resources/extensions/gsd/tests/enhanced-verification-integration.test.ts +5 -0
  567. package/src/resources/extensions/gsd/tests/escalation.test.ts +818 -0
  568. package/src/resources/extensions/gsd/tests/finalize-timeout-guard.test.ts +29 -12
  569. package/src/resources/extensions/gsd/tests/flat-rate-routing-guard.test.ts +106 -0
  570. package/src/resources/extensions/gsd/tests/forensics-hook-key-parse.test.ts +74 -0
  571. package/src/resources/extensions/gsd/tests/graph-operations.test.ts +0 -4
  572. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +44 -1
  573. package/src/resources/extensions/gsd/tests/health-widget.test.ts +8 -2
  574. package/src/resources/extensions/gsd/tests/init-prefs-routing.test.ts +190 -0
  575. package/src/resources/extensions/gsd/tests/integration/doctor-git.test.ts +39 -0
  576. package/src/resources/extensions/gsd/tests/integration/doctor-proactive.test.ts +44 -0
  577. package/src/resources/extensions/gsd/tests/integration/doctor-runtime.test.ts +68 -1
  578. package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +109 -11
  579. package/src/resources/extensions/gsd/tests/integration/idle-recovery.test.ts +51 -0
  580. package/src/resources/extensions/gsd/tests/integration/integration-proof.test.ts +2 -2
  581. package/src/resources/extensions/gsd/tests/integration/test-isolation.ts +53 -0
  582. package/src/resources/extensions/gsd/tests/journal-integration.test.ts +171 -1
  583. package/src/resources/extensions/gsd/tests/md-importer.test.ts +1 -1
  584. package/src/resources/extensions/gsd/tests/memory-embeddings.test.ts +213 -0
  585. package/src/resources/extensions/gsd/tests/memory-ingest.test.ts +153 -0
  586. package/src/resources/extensions/gsd/tests/memory-maintenance.test.ts +107 -0
  587. package/src/resources/extensions/gsd/tests/memory-relations.test.ts +175 -0
  588. package/src/resources/extensions/gsd/tests/memory-store.test.ts +2 -2
  589. package/src/resources/extensions/gsd/tests/memory-tools.test.ts +295 -0
  590. package/src/resources/extensions/gsd/tests/milestone-status-tool.test.ts +3 -2
  591. package/src/resources/extensions/gsd/tests/model-cost-table.test.ts +2 -2
  592. package/src/resources/extensions/gsd/tests/model-router.test.ts +51 -1
  593. package/src/resources/extensions/gsd/tests/model-unittype-mapping.test.ts +59 -0
  594. package/src/resources/extensions/gsd/tests/notification-overlay.test.ts +56 -37
  595. package/src/resources/extensions/gsd/tests/notification-widget.test.ts +1 -1
  596. package/src/resources/extensions/gsd/tests/onboarding-state.test.ts +105 -0
  597. package/src/resources/extensions/gsd/tests/plan-milestone-boundary-map-preservation.test.ts +114 -0
  598. package/src/resources/extensions/gsd/tests/plan-milestone.test.ts +4 -5
  599. package/src/resources/extensions/gsd/tests/plan-slice.test.ts +17 -0
  600. package/src/resources/extensions/gsd/tests/post-execution-checks.test.ts +105 -1
  601. package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +275 -6
  602. package/src/resources/extensions/gsd/tests/preferences.test.ts +69 -1
  603. package/src/resources/extensions/gsd/tests/progressive-planning.test.ts +539 -0
  604. package/src/resources/extensions/gsd/tests/projection-no-plan-overwrite.test.ts +11 -2
  605. package/src/resources/extensions/gsd/tests/projection-regression.test.ts +7 -0
  606. package/src/resources/extensions/gsd/tests/prompt-budget-enforcement.test.ts +27 -0
  607. package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +24 -0
  608. package/src/resources/extensions/gsd/tests/prompt-db.test.ts +1 -1
  609. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +33 -0
  610. package/src/resources/extensions/gsd/tests/python-resolver.test.ts +131 -0
  611. package/src/resources/extensions/gsd/tests/register-hooks-depth-verification.test.ts +67 -0
  612. package/src/resources/extensions/gsd/tests/remote-notification-from-desktop.test.ts +107 -0
  613. package/src/resources/extensions/gsd/tests/requirements.test.ts +9 -0
  614. package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +153 -0
  615. package/src/resources/extensions/gsd/tests/skip-slice-cascades-tasks.test.ts +125 -0
  616. package/src/resources/extensions/gsd/tests/slice-context-injection.test.ts +16 -4
  617. package/src/resources/extensions/gsd/tests/state-corruption-2945.test.ts +3 -0
  618. package/src/resources/extensions/gsd/tests/stuck-detection-coverage.test.ts +15 -0
  619. package/src/resources/extensions/gsd/tests/summary-render-parity.test.ts +5 -0
  620. package/src/resources/extensions/gsd/tests/uok-contracts.test.ts +2 -1
  621. package/src/resources/extensions/gsd/tests/uok-flags.test.ts +31 -1
  622. package/src/resources/extensions/gsd/tests/uok-kernel-path.test.ts +166 -0
  623. package/src/resources/extensions/gsd/tests/verification-gate.test.ts +35 -0
  624. package/src/resources/extensions/gsd/tests/workflow-install.test.ts +113 -0
  625. package/src/resources/extensions/gsd/tests/workflow-logger-wiring.test.ts +15 -6
  626. package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +2 -2
  627. package/src/resources/extensions/gsd/tests/workflow-plugins.test.ts +310 -0
  628. package/src/resources/extensions/gsd/tests/workflow-projections.test.ts +7 -0
  629. package/src/resources/extensions/gsd/tests/workflow-templates.test.ts +8 -2
  630. package/src/resources/extensions/gsd/tests/worktree-journal-events.test.ts +2 -1
  631. package/src/resources/extensions/gsd/tests/worktree-resolver.test.ts +77 -2
  632. package/src/resources/extensions/gsd/tools/complete-task.ts +87 -0
  633. package/src/resources/extensions/gsd/tools/memory-tools.ts +380 -0
  634. package/src/resources/extensions/gsd/tools/plan-milestone.ts +42 -8
  635. package/src/resources/extensions/gsd/tools/plan-slice.ts +6 -1
  636. package/src/resources/extensions/gsd/tools/skip-slice.ts +133 -0
  637. package/src/resources/extensions/gsd/types.ts +62 -0
  638. package/src/resources/extensions/gsd/unit-runtime.ts +1 -0
  639. package/src/resources/extensions/gsd/uok/contracts.ts +2 -1
  640. package/src/resources/extensions/gsd/uok/flags.ts +7 -7
  641. package/src/resources/extensions/gsd/uok/kernel.ts +16 -4
  642. package/src/resources/extensions/gsd/verification-gate.ts +2 -1
  643. package/src/resources/extensions/gsd/workflow-dispatch.ts +106 -0
  644. package/src/resources/extensions/gsd/workflow-install.ts +423 -0
  645. package/src/resources/extensions/gsd/workflow-logger.ts +3 -1
  646. package/src/resources/extensions/gsd/workflow-manifest.ts +8 -0
  647. package/src/resources/extensions/gsd/workflow-mcp.ts +1 -6
  648. package/src/resources/extensions/gsd/workflow-plugins.ts +403 -0
  649. package/src/resources/extensions/gsd/workflow-projections.ts +18 -16
  650. package/src/resources/extensions/gsd/workflow-templates/accessibility-audit.md +88 -0
  651. package/src/resources/extensions/gsd/workflow-templates/api-breaking-change.md +117 -0
  652. package/src/resources/extensions/gsd/workflow-templates/bugfix.md +1 -0
  653. package/src/resources/extensions/gsd/workflow-templates/changelog-gen.md +82 -0
  654. package/src/resources/extensions/gsd/workflow-templates/ci-bootstrap.md +144 -0
  655. package/src/resources/extensions/gsd/workflow-templates/dead-code.md +81 -0
  656. package/src/resources/extensions/gsd/workflow-templates/dep-upgrade.md +1 -0
  657. package/src/resources/extensions/gsd/workflow-templates/docs-sync.yaml +76 -0
  658. package/src/resources/extensions/gsd/workflow-templates/env-audit.yaml +88 -0
  659. package/src/resources/extensions/gsd/workflow-templates/full-project.md +1 -0
  660. package/src/resources/extensions/gsd/workflow-templates/hotfix.md +1 -0
  661. package/src/resources/extensions/gsd/workflow-templates/issue-triage.md +84 -0
  662. package/src/resources/extensions/gsd/workflow-templates/observability-setup.md +133 -0
  663. package/src/resources/extensions/gsd/workflow-templates/onboarding-check.md +74 -0
  664. package/src/resources/extensions/gsd/workflow-templates/performance-audit.md +125 -0
  665. package/src/resources/extensions/gsd/workflow-templates/pr-review.md +67 -0
  666. package/src/resources/extensions/gsd/workflow-templates/pr-triage.md +83 -0
  667. package/src/resources/extensions/gsd/workflow-templates/refactor.md +1 -0
  668. package/src/resources/extensions/gsd/workflow-templates/registry.json +184 -0
  669. package/src/resources/extensions/gsd/workflow-templates/release.md +118 -0
  670. package/src/resources/extensions/gsd/workflow-templates/rename-symbol.yaml +99 -0
  671. package/src/resources/extensions/gsd/workflow-templates/security-audit.md +1 -0
  672. package/src/resources/extensions/gsd/workflow-templates/small-feature.md +1 -0
  673. package/src/resources/extensions/gsd/workflow-templates/spike.md +1 -0
  674. package/src/resources/extensions/gsd/workflow-templates/test-backfill.yaml +73 -0
  675. package/src/resources/extensions/gsd/workflow-templates.ts +7 -0
  676. package/src/resources/extensions/gsd/workspace-index.ts +9 -4
  677. package/src/resources/extensions/gsd/worktree-resolver.ts +47 -1
  678. package/src/resources/extensions/remote-questions/commands.ts +480 -0
  679. package/src/resources/extensions/remote-questions/manager.ts +49 -4
  680. package/src/resources/extensions/remote-questions/telegram-adapter.ts +86 -4
  681. package/src/resources/extensions/remote-questions/tests/command-polling.test.ts +246 -0
  682. package/src/resources/extensions/remote-questions/tests/remote-answer-normalization.test.ts +92 -0
  683. package/src/resources/extensions/remote-questions/tests/telegram-commands.test.ts +267 -0
  684. package/src/resources/extensions/shared/interview-ui.ts +195 -1
  685. package/src/resources/extensions/shared/layout-utils.ts +26 -0
  686. package/src/resources/extensions/shared/rtk-shared.ts +58 -0
  687. package/src/resources/extensions/shared/rtk.ts +12 -52
  688. package/src/resources/extensions/shared/tests/interview-preview.test.ts +177 -0
  689. package/src/resources/extensions/shared/tests/preview-layout.test.ts +120 -0
  690. package/src/resources/skills/create-workflow/SKILL.md +33 -6
  691. package/dist/web/standalone/.next/static/chunks/2826.dd3dc8bbd3025fa5.js +0 -9
  692. package/dist/web/standalone/.next/static/css/f6e8833d46e738d8.css +0 -1
  693. package/packages/native/dist/ps/types.d.ts +0 -5
  694. package/packages/native/dist/ps/types.js +0 -2
  695. package/packages/native/src/ps/types.ts +0 -5
  696. package/packages/pi-ai/node_modules/@smithy/node-http-handler/LICENSE +0 -201
  697. package/packages/pi-ai/node_modules/@smithy/node-http-handler/README.md +0 -9
  698. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-cjs/index.js +0 -762
  699. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/build-abort-error.js +0 -19
  700. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/constants.js +0 -1
  701. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/get-transformed-headers.js +0 -9
  702. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/index.js +0 -3
  703. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/node-http-handler.js +0 -230
  704. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/node-http2-connection-manager.js +0 -87
  705. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/node-http2-connection-pool.js +0 -32
  706. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/node-http2-handler.js +0 -169
  707. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/readable.mock.js +0 -21
  708. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/server.mock.js +0 -88
  709. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/set-connection-timeout.js +0 -36
  710. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/set-request-timeout.js +0 -21
  711. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/set-socket-keep-alive.js +0 -22
  712. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/set-socket-timeout.js +0 -23
  713. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/stream-collector/collector.js +0 -8
  714. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/stream-collector/index.js +0 -41
  715. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/stream-collector/readable.mock.js +0 -21
  716. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/timing.js +0 -4
  717. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/write-request-body.js +0 -63
  718. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/build-abort-error.d.ts +0 -10
  719. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/constants.d.ts +0 -5
  720. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/get-transformed-headers.d.ts +0 -4
  721. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/index.d.ts +0 -3
  722. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/node-http-handler.d.ts +0 -46
  723. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/node-http2-connection-manager.d.ts +0 -24
  724. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/node-http2-connection-pool.d.ts +0 -12
  725. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/node-http2-handler.d.ts +0 -63
  726. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/readable.mock.d.ts +0 -13
  727. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/server.mock.d.ts +0 -12
  728. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/set-connection-timeout.d.ts +0 -2
  729. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/set-request-timeout.d.ts +0 -6
  730. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/set-socket-keep-alive.d.ts +0 -6
  731. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/set-socket-timeout.d.ts +0 -2
  732. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/stream-collector/collector.d.ts +0 -5
  733. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/stream-collector/index.d.ts +0 -6
  734. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/stream-collector/readable.mock.d.ts +0 -13
  735. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/timing.d.ts +0 -8
  736. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/build-abort-error.d.ts +0 -10
  737. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/constants.d.ts +0 -5
  738. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/get-transformed-headers.d.ts +0 -4
  739. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/index.d.ts +0 -3
  740. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/node-http-handler.d.ts +0 -46
  741. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/node-http2-connection-manager.d.ts +0 -24
  742. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/node-http2-connection-pool.d.ts +0 -12
  743. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/node-http2-handler.d.ts +0 -63
  744. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/readable.mock.d.ts +0 -13
  745. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/server.mock.d.ts +0 -12
  746. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/set-connection-timeout.d.ts +0 -2
  747. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/set-request-timeout.d.ts +0 -6
  748. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/set-socket-keep-alive.d.ts +0 -6
  749. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/set-socket-timeout.d.ts +0 -2
  750. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/stream-collector/collector.d.ts +0 -5
  751. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/stream-collector/index.d.ts +0 -6
  752. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/stream-collector/readable.mock.d.ts +0 -13
  753. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/timing.d.ts +0 -8
  754. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/write-request-body.d.ts +0 -12
  755. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/write-request-body.d.ts +0 -12
  756. package/packages/pi-ai/node_modules/@smithy/node-http-handler/package.json +0 -68
  757. package/packages/pi-ai/oauth.d.ts +0 -1
  758. package/packages/pi-ai/oauth.js +0 -1
  759. /package/dist/web/standalone/.next/static/{j7IBD35UgrL2b298GLK3V → o61X3klsB6C0UE0X1x3PA}/_buildManifest.js +0 -0
  760. /package/dist/web/standalone/.next/static/{j7IBD35UgrL2b298GLK3V → o61X3klsB6C0UE0X1x3PA}/_ssgManifest.js +0 -0
@@ -180,7 +180,7 @@ function openRawDb(path: string): unknown {
180
180
  return new Database(path);
181
181
  }
182
182
 
183
- const SCHEMA_VERSION = 15;
183
+ const SCHEMA_VERSION = 20;
184
184
 
185
185
  function indexExists(db: DbAdapter, name: string): boolean {
186
186
  return !!db.prepare(
@@ -235,6 +235,7 @@ function initSchema(db: DbAdapter, fileBacked: boolean): void {
235
235
  rationale TEXT NOT NULL DEFAULT '',
236
236
  revisable TEXT NOT NULL DEFAULT '',
237
237
  made_by TEXT NOT NULL DEFAULT 'agent',
238
+ source TEXT NOT NULL DEFAULT 'discussion', -- ADR-011 P2: 'discussion' | 'planning' | 'escalation'
238
239
  superseded_by TEXT DEFAULT NULL
239
240
  )
240
241
  `);
@@ -280,7 +281,9 @@ function initSchema(db: DbAdapter, fileBacked: boolean): void {
280
281
  created_at TEXT NOT NULL,
281
282
  updated_at TEXT NOT NULL,
282
283
  superseded_by TEXT DEFAULT NULL,
283
- hit_count INTEGER NOT NULL DEFAULT 0
284
+ hit_count INTEGER NOT NULL DEFAULT 0,
285
+ scope TEXT NOT NULL DEFAULT 'project',
286
+ tags TEXT NOT NULL DEFAULT '[]'
284
287
  )
285
288
  `);
286
289
 
@@ -292,6 +295,45 @@ function initSchema(db: DbAdapter, fileBacked: boolean): void {
292
295
  )
293
296
  `);
294
297
 
298
+ db.exec(`
299
+ CREATE TABLE IF NOT EXISTS memory_sources (
300
+ id TEXT PRIMARY KEY,
301
+ kind TEXT NOT NULL,
302
+ uri TEXT,
303
+ title TEXT,
304
+ content TEXT NOT NULL,
305
+ content_hash TEXT NOT NULL UNIQUE,
306
+ imported_at TEXT NOT NULL,
307
+ scope TEXT NOT NULL DEFAULT 'project',
308
+ tags TEXT NOT NULL DEFAULT '[]'
309
+ )
310
+ `);
311
+
312
+ db.exec(`
313
+ CREATE TABLE IF NOT EXISTS memory_embeddings (
314
+ memory_id TEXT PRIMARY KEY,
315
+ model TEXT NOT NULL,
316
+ dim INTEGER NOT NULL,
317
+ vector BLOB NOT NULL,
318
+ updated_at TEXT NOT NULL
319
+ )
320
+ `);
321
+
322
+ db.exec(`
323
+ CREATE TABLE IF NOT EXISTS memory_relations (
324
+ from_id TEXT NOT NULL,
325
+ to_id TEXT NOT NULL,
326
+ rel TEXT NOT NULL,
327
+ confidence REAL NOT NULL DEFAULT 0.8,
328
+ created_at TEXT NOT NULL,
329
+ PRIMARY KEY (from_id, to_id, rel)
330
+ )
331
+ `);
332
+
333
+ // FTS5 virtual table mirroring memories.content for fast keyword search.
334
+ // Optional — if the SQLite build lacks FTS5, we fall back to LIKE scans.
335
+ tryCreateMemoriesFts(db);
336
+
295
337
  db.exec(`
296
338
  CREATE TABLE IF NOT EXISTS milestones (
297
339
  id TEXT PRIMARY KEY,
@@ -334,6 +376,8 @@ function initSchema(db: DbAdapter, fileBacked: boolean): void {
334
376
  observability_impact TEXT NOT NULL DEFAULT '',
335
377
  sequence INTEGER DEFAULT 0, -- Ordering hint: tools may set this to control execution order
336
378
  replan_triggered_at TEXT DEFAULT NULL,
379
+ is_sketch INTEGER NOT NULL DEFAULT 0, -- ADR-011: 1 = slice is a sketch awaiting refinement
380
+ sketch_scope TEXT NOT NULL DEFAULT '', -- ADR-011: 2-3 sentence rough scope from plan-milestone
337
381
  PRIMARY KEY (milestone_id, id),
338
382
  FOREIGN KEY (milestone_id) REFERENCES milestones(id)
339
383
  )
@@ -352,6 +396,11 @@ function initSchema(db: DbAdapter, fileBacked: boolean): void {
352
396
  duration TEXT NOT NULL DEFAULT '',
353
397
  completed_at TEXT DEFAULT NULL,
354
398
  blocker_discovered INTEGER DEFAULT 0,
399
+ blocker_source TEXT NOT NULL DEFAULT '', -- ADR-011 P2: provenance for blocker_discovered (e.g. 'reject-escalation')
400
+ escalation_pending INTEGER NOT NULL DEFAULT 0, -- ADR-011 P2: pause-on-escalation flag
401
+ escalation_awaiting_review INTEGER NOT NULL DEFAULT 0, -- ADR-011 P2: artifact exists but continueWithDefault=true (no pause)
402
+ escalation_artifact_path TEXT DEFAULT NULL, -- ADR-011 P2: path to T##-ESCALATION.json
403
+ escalation_override_applied_at TEXT DEFAULT NULL, -- ADR-011 P2: DB claim lock for idempotent override injection
355
404
  deviations TEXT NOT NULL DEFAULT '',
356
405
  known_issues TEXT NOT NULL DEFAULT '',
357
406
  key_files TEXT NOT NULL DEFAULT '[]',
@@ -508,6 +557,11 @@ function initSchema(db: DbAdapter, fileBacked: boolean): void {
508
557
  `);
509
558
 
510
559
  db.exec("CREATE INDEX IF NOT EXISTS idx_memories_active ON memories(superseded_by)");
560
+ db.exec("CREATE INDEX IF NOT EXISTS idx_memories_scope ON memories(scope)");
561
+ db.exec("CREATE INDEX IF NOT EXISTS idx_memory_sources_kind ON memory_sources(kind)");
562
+ db.exec("CREATE INDEX IF NOT EXISTS idx_memory_sources_scope ON memory_sources(scope)");
563
+ db.exec("CREATE INDEX IF NOT EXISTS idx_memory_relations_from ON memory_relations(from_id)");
564
+ db.exec("CREATE INDEX IF NOT EXISTS idx_memory_relations_to ON memory_relations(to_id)");
511
565
  db.exec("CREATE INDEX IF NOT EXISTS idx_replan_history_milestone ON replan_history(milestone_id, created_at)");
512
566
 
513
567
  // v13 indexes — hot-path dispatch queries
@@ -525,6 +579,9 @@ function initSchema(db: DbAdapter, fileBacked: boolean): void {
525
579
  db.exec("CREATE INDEX IF NOT EXISTS idx_turn_git_tx_turn ON turn_git_transactions(trace_id, turn_id)");
526
580
  db.exec("CREATE INDEX IF NOT EXISTS idx_audit_events_trace ON audit_events(trace_id, ts)");
527
581
  db.exec("CREATE INDEX IF NOT EXISTS idx_audit_events_turn ON audit_events(trace_id, turn_id, ts)");
582
+ // ADR-011 Phase 2 — also created by the v17 migration; fresh installs
583
+ // skip migrations so the index must be created here too.
584
+ db.exec("CREATE INDEX IF NOT EXISTS idx_tasks_escalation_pending ON tasks(milestone_id, slice_id, escalation_pending)");
528
585
 
529
586
  db.exec(`CREATE VIEW IF NOT EXISTS active_decisions AS SELECT * FROM decisions WHERE superseded_by IS NULL`);
530
587
  db.exec(`CREATE VIEW IF NOT EXISTS active_requirements AS SELECT * FROM requirements WHERE superseded_by IS NULL`);
@@ -554,6 +611,56 @@ function columnExists(db: DbAdapter, table: string, column: string): boolean {
554
611
  return rows.some((row) => row["name"] === column);
555
612
  }
556
613
 
614
+ /**
615
+ * Create the FTS5 virtual table for memories plus the triggers that keep it
616
+ * in sync with the base table. FTS5 may be unavailable on stripped-down
617
+ * SQLite builds — callers should treat failure as non-fatal and fall back
618
+ * to LIKE-based scans in `memory-store.queryMemoriesRanked`.
619
+ */
620
+ export function tryCreateMemoriesFts(db: DbAdapter): boolean {
621
+ try {
622
+ db.exec(`
623
+ CREATE VIRTUAL TABLE IF NOT EXISTS memories_fts
624
+ USING fts5(content, content='memories', content_rowid='seq', tokenize='porter unicode61')
625
+ `);
626
+ // Triggers mirror inserts / updates / deletes on the base memories table.
627
+ db.exec(`
628
+ CREATE TRIGGER IF NOT EXISTS memories_ai
629
+ AFTER INSERT ON memories BEGIN
630
+ INSERT INTO memories_fts(rowid, content) VALUES (new.seq, new.content);
631
+ END
632
+ `);
633
+ db.exec(`
634
+ CREATE TRIGGER IF NOT EXISTS memories_ad
635
+ AFTER DELETE ON memories BEGIN
636
+ INSERT INTO memories_fts(memories_fts, rowid, content) VALUES ('delete', old.seq, old.content);
637
+ END
638
+ `);
639
+ db.exec(`
640
+ CREATE TRIGGER IF NOT EXISTS memories_au
641
+ AFTER UPDATE OF content ON memories BEGIN
642
+ INSERT INTO memories_fts(memories_fts, rowid, content) VALUES ('delete', old.seq, old.content);
643
+ INSERT INTO memories_fts(rowid, content) VALUES (new.seq, new.content);
644
+ END
645
+ `);
646
+ return true;
647
+ } catch (err) {
648
+ logWarning("db", `FTS5 unavailable — memory queries will use LIKE fallback: ${(err as Error).message}`);
649
+ return false;
650
+ }
651
+ }
652
+
653
+ export function isMemoriesFtsAvailable(db: DbAdapter): boolean {
654
+ try {
655
+ const row = db
656
+ .prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='memories_fts'")
657
+ .get();
658
+ return !!row;
659
+ } catch {
660
+ return false;
661
+ }
662
+ }
663
+
557
664
  function ensureColumn(db: DbAdapter, table: string, column: string, ddl: string): void {
558
665
  if (!columnExists(db, table, column)) db.exec(ddl);
559
666
  }
@@ -951,6 +1058,105 @@ function migrateSchema(db: DbAdapter): void {
951
1058
  });
952
1059
  }
953
1060
 
1061
+ if (currentVersion < 16) {
1062
+ // ADR-011 Phase 1: sketch-then-refine progressive planning — sketch columns on slices.
1063
+ ensureColumn(db, "slices", "is_sketch", `ALTER TABLE slices ADD COLUMN is_sketch INTEGER NOT NULL DEFAULT 0`);
1064
+ ensureColumn(db, "slices", "sketch_scope", `ALTER TABLE slices ADD COLUMN sketch_scope TEXT NOT NULL DEFAULT ''`);
1065
+ // ADR-011 Phase 2: decisions can now be sourced from escalation resolutions.
1066
+ ensureColumn(db, "decisions", "source", `ALTER TABLE decisions ADD COLUMN source TEXT NOT NULL DEFAULT 'discussion'`);
1067
+ db.prepare("INSERT INTO schema_version (version, applied_at) VALUES (:version, :applied_at)").run({
1068
+ ":version": 16,
1069
+ ":applied_at": new Date().toISOString(),
1070
+ });
1071
+ }
1072
+
1073
+ if (currentVersion < 17) {
1074
+ // ADR-011 Phase 2: mid-execution escalation — columns on the tasks table.
1075
+ ensureColumn(db, "tasks", "blocker_source", `ALTER TABLE tasks ADD COLUMN blocker_source TEXT NOT NULL DEFAULT ''`);
1076
+ ensureColumn(db, "tasks", "escalation_pending", `ALTER TABLE tasks ADD COLUMN escalation_pending INTEGER NOT NULL DEFAULT 0`);
1077
+ ensureColumn(db, "tasks", "escalation_awaiting_review", `ALTER TABLE tasks ADD COLUMN escalation_awaiting_review INTEGER NOT NULL DEFAULT 0`);
1078
+ ensureColumn(db, "tasks", "escalation_artifact_path", `ALTER TABLE tasks ADD COLUMN escalation_artifact_path TEXT DEFAULT NULL`);
1079
+ ensureColumn(db, "tasks", "escalation_override_applied_at", `ALTER TABLE tasks ADD COLUMN escalation_override_applied_at TEXT DEFAULT NULL`);
1080
+ db.exec("CREATE INDEX IF NOT EXISTS idx_tasks_escalation_pending ON tasks(milestone_id, slice_id, escalation_pending)");
1081
+ db.prepare("INSERT INTO schema_version (version, applied_at) VALUES (:version, :applied_at)").run({
1082
+ ":version": 17,
1083
+ ":applied_at": new Date().toISOString(),
1084
+ });
1085
+ }
1086
+
1087
+ if (currentVersion < 18) {
1088
+ // Memory system Phase 2: scope + tags on memories, plus memory_sources
1089
+ // table for raw ingested content (notes, files, URLs, artifacts).
1090
+ ensureColumn(db, "memories", "scope", `ALTER TABLE memories ADD COLUMN scope TEXT NOT NULL DEFAULT 'project'`);
1091
+ ensureColumn(db, "memories", "tags", `ALTER TABLE memories ADD COLUMN tags TEXT NOT NULL DEFAULT '[]'`);
1092
+ db.exec(`
1093
+ CREATE TABLE IF NOT EXISTS memory_sources (
1094
+ id TEXT PRIMARY KEY,
1095
+ kind TEXT NOT NULL,
1096
+ uri TEXT,
1097
+ title TEXT,
1098
+ content TEXT NOT NULL,
1099
+ content_hash TEXT NOT NULL UNIQUE,
1100
+ imported_at TEXT NOT NULL,
1101
+ scope TEXT NOT NULL DEFAULT 'project',
1102
+ tags TEXT NOT NULL DEFAULT '[]'
1103
+ )
1104
+ `);
1105
+ db.exec("CREATE INDEX IF NOT EXISTS idx_memories_scope ON memories(scope)");
1106
+ db.exec("CREATE INDEX IF NOT EXISTS idx_memory_sources_kind ON memory_sources(kind)");
1107
+ db.exec("CREATE INDEX IF NOT EXISTS idx_memory_sources_scope ON memory_sources(scope)");
1108
+ db.prepare("INSERT INTO schema_version (version, applied_at) VALUES (:version, :applied_at)").run({
1109
+ ":version": 18,
1110
+ ":applied_at": new Date().toISOString(),
1111
+ });
1112
+ }
1113
+
1114
+ if (currentVersion < 19) {
1115
+ // Memory system Phase 3: embeddings + FTS5 for hybrid retrieval.
1116
+ db.exec(`
1117
+ CREATE TABLE IF NOT EXISTS memory_embeddings (
1118
+ memory_id TEXT PRIMARY KEY,
1119
+ model TEXT NOT NULL,
1120
+ dim INTEGER NOT NULL,
1121
+ vector BLOB NOT NULL,
1122
+ updated_at TEXT NOT NULL
1123
+ )
1124
+ `);
1125
+ tryCreateMemoriesFts(db);
1126
+ // Backfill FTS5 with any existing memories (triggers only cover future writes).
1127
+ if (isMemoriesFtsAvailable(db)) {
1128
+ try {
1129
+ db.exec(`INSERT INTO memories_fts(rowid, content) SELECT seq, content FROM memories`);
1130
+ } catch (err) {
1131
+ logWarning("db", `FTS5 backfill failed: ${(err as Error).message}`);
1132
+ }
1133
+ }
1134
+ db.prepare("INSERT INTO schema_version (version, applied_at) VALUES (:version, :applied_at)").run({
1135
+ ":version": 19,
1136
+ ":applied_at": new Date().toISOString(),
1137
+ });
1138
+ }
1139
+
1140
+ if (currentVersion < 20) {
1141
+ // Memory system Phase 4: knowledge-graph relations between memories.
1142
+ db.exec(`
1143
+ CREATE TABLE IF NOT EXISTS memory_relations (
1144
+ from_id TEXT NOT NULL,
1145
+ to_id TEXT NOT NULL,
1146
+ rel TEXT NOT NULL,
1147
+ confidence REAL NOT NULL DEFAULT 0.8,
1148
+ created_at TEXT NOT NULL,
1149
+ PRIMARY KEY (from_id, to_id, rel)
1150
+ )
1151
+ `);
1152
+ db.exec("CREATE INDEX IF NOT EXISTS idx_memory_relations_from ON memory_relations(from_id)");
1153
+ db.exec("CREATE INDEX IF NOT EXISTS idx_memory_relations_to ON memory_relations(to_id)");
1154
+ db.prepare("INSERT INTO schema_version (version, applied_at) VALUES (:version, :applied_at)").run({
1155
+ ":version": 20,
1156
+ ":applied_at": new Date().toISOString(),
1157
+ });
1158
+ }
1159
+
954
1160
  db.exec("COMMIT");
955
1161
  } catch (err) {
956
1162
  db.exec("ROLLBACK");
@@ -1052,6 +1258,14 @@ export function vacuumDatabase(): void {
1052
1258
  } catch (e) { logWarning("db", `VACUUM failed: ${(e as Error).message}`); }
1053
1259
  }
1054
1260
 
1261
+ /** Flush WAL into gsd.db so `git add .gsd/gsd.db` stages current state — safe while DB is open. */
1262
+ export function checkpointDatabase(): void {
1263
+ if (!currentDb) return;
1264
+ try {
1265
+ currentDb.exec('PRAGMA wal_checkpoint(TRUNCATE)');
1266
+ } catch (e) { logWarning("db", `WAL checkpoint failed: ${(e as Error).message}`); }
1267
+ }
1268
+
1055
1269
  let _txDepth = 0;
1056
1270
 
1057
1271
  export function transaction<T>(fn: () => T): T {
@@ -1127,8 +1341,8 @@ export function readTransaction<T>(fn: () => T): T {
1127
1341
  export function insertDecision(d: Omit<Decision, "seq">): void {
1128
1342
  if (!currentDb) throw new GSDError(GSD_STALE_STATE, "gsd-db: No database open");
1129
1343
  currentDb.prepare(
1130
- `INSERT INTO decisions (id, when_context, scope, decision, choice, rationale, revisable, made_by, superseded_by)
1131
- VALUES (:id, :when_context, :scope, :decision, :choice, :rationale, :revisable, :made_by, :superseded_by)`,
1344
+ `INSERT INTO decisions (id, when_context, scope, decision, choice, rationale, revisable, made_by, source, superseded_by)
1345
+ VALUES (:id, :when_context, :scope, :decision, :choice, :rationale, :revisable, :made_by, :source, :superseded_by)`,
1132
1346
  ).run({
1133
1347
  ":id": d.id,
1134
1348
  ":when_context": d.when_context,
@@ -1138,6 +1352,7 @@ export function insertDecision(d: Omit<Decision, "seq">): void {
1138
1352
  ":rationale": d.rationale,
1139
1353
  ":revisable": d.revisable,
1140
1354
  ":made_by": d.made_by ?? "agent",
1355
+ ":source": d.source ?? "discussion",
1141
1356
  ":superseded_by": d.superseded_by,
1142
1357
  });
1143
1358
  }
@@ -1156,6 +1371,7 @@ export function getDecisionById(id: string): Decision | null {
1156
1371
  rationale: row["rationale"] as string,
1157
1372
  revisable: row["revisable"] as string,
1158
1373
  made_by: (row["made_by"] as string as import("./types.js").DecisionMadeBy) ?? "agent",
1374
+ source: (row["source"] as string) ?? "discussion",
1159
1375
  superseded_by: (row["superseded_by"] as string) ?? null,
1160
1376
  };
1161
1377
  }
@@ -1173,6 +1389,7 @@ export function getActiveDecisions(): Decision[] {
1173
1389
  rationale: row["rationale"] as string,
1174
1390
  revisable: row["revisable"] as string,
1175
1391
  made_by: (row["made_by"] as string as import("./types.js").DecisionMadeBy) ?? "agent",
1392
+ source: (row["source"] as string) ?? "discussion",
1176
1393
  superseded_by: null,
1177
1394
  }));
1178
1395
  }
@@ -1261,8 +1478,8 @@ export function upsertDecision(d: Omit<Decision, "seq">): void {
1261
1478
  // seq column. INSERT OR REPLACE deletes then reinserts, resetting seq and
1262
1479
  // corrupting decision ordering in DECISIONS.md after reconcile replay.
1263
1480
  currentDb.prepare(
1264
- `INSERT INTO decisions (id, when_context, scope, decision, choice, rationale, revisable, made_by, superseded_by)
1265
- VALUES (:id, :when_context, :scope, :decision, :choice, :rationale, :revisable, :made_by, :superseded_by)
1481
+ `INSERT INTO decisions (id, when_context, scope, decision, choice, rationale, revisable, made_by, source, superseded_by)
1482
+ VALUES (:id, :when_context, :scope, :decision, :choice, :rationale, :revisable, :made_by, :source, :superseded_by)
1266
1483
  ON CONFLICT(id) DO UPDATE SET
1267
1484
  when_context = excluded.when_context,
1268
1485
  scope = excluded.scope,
@@ -1271,6 +1488,7 @@ export function upsertDecision(d: Omit<Decision, "seq">): void {
1271
1488
  rationale = excluded.rationale,
1272
1489
  revisable = excluded.revisable,
1273
1490
  made_by = excluded.made_by,
1491
+ source = excluded.source,
1274
1492
  superseded_by = excluded.superseded_by`,
1275
1493
  ).run({
1276
1494
  ":id": d.id,
@@ -1281,6 +1499,7 @@ export function upsertDecision(d: Omit<Decision, "seq">): void {
1281
1499
  ":rationale": d.rationale,
1282
1500
  ":revisable": d.revisable,
1283
1501
  ":made_by": d.made_by ?? "agent",
1502
+ ":source": d.source ?? "discussion",
1284
1503
  ":superseded_by": d.superseded_by ?? null,
1285
1504
  });
1286
1505
  }
@@ -1455,16 +1674,20 @@ export function insertSlice(s: {
1455
1674
  depends?: string[];
1456
1675
  demo?: string;
1457
1676
  sequence?: number;
1677
+ isSketch?: boolean;
1678
+ sketchScope?: string;
1458
1679
  planning?: Partial<SlicePlanningRecord>;
1459
1680
  }): void {
1460
1681
  if (!currentDb) throw new GSDError(GSD_STALE_STATE, "gsd-db: No database open");
1461
1682
  currentDb.prepare(
1462
1683
  `INSERT INTO slices (
1463
1684
  milestone_id, id, title, status, risk, depends, demo, created_at,
1464
- goal, success_criteria, proof_level, integration_closure, observability_impact, sequence
1685
+ goal, success_criteria, proof_level, integration_closure, observability_impact, sequence,
1686
+ is_sketch, sketch_scope
1465
1687
  ) VALUES (
1466
1688
  :milestone_id, :id, :title, :status, :risk, :depends, :demo, :created_at,
1467
- :goal, :success_criteria, :proof_level, :integration_closure, :observability_impact, :sequence
1689
+ :goal, :success_criteria, :proof_level, :integration_closure, :observability_impact, :sequence,
1690
+ :is_sketch, :sketch_scope
1468
1691
  )
1469
1692
  ON CONFLICT (milestone_id, id) DO UPDATE SET
1470
1693
  title = CASE WHEN :raw_title IS NOT NULL THEN excluded.title ELSE slices.title END,
@@ -1477,7 +1700,9 @@ export function insertSlice(s: {
1477
1700
  proof_level = CASE WHEN :raw_proof_level IS NOT NULL THEN excluded.proof_level ELSE slices.proof_level END,
1478
1701
  integration_closure = CASE WHEN :raw_integration_closure IS NOT NULL THEN excluded.integration_closure ELSE slices.integration_closure END,
1479
1702
  observability_impact = CASE WHEN :raw_observability_impact IS NOT NULL THEN excluded.observability_impact ELSE slices.observability_impact END,
1480
- sequence = CASE WHEN :raw_sequence IS NOT NULL THEN excluded.sequence ELSE slices.sequence END`,
1703
+ sequence = CASE WHEN :raw_sequence IS NOT NULL THEN excluded.sequence ELSE slices.sequence END,
1704
+ is_sketch = CASE WHEN :raw_is_sketch IS NOT NULL THEN excluded.is_sketch ELSE slices.is_sketch END,
1705
+ sketch_scope = CASE WHEN :raw_sketch_scope IS NOT NULL THEN excluded.sketch_scope ELSE slices.sketch_scope END`,
1481
1706
  ).run({
1482
1707
  ":milestone_id": s.milestoneId,
1483
1708
  ":id": s.id,
@@ -1493,6 +1718,8 @@ export function insertSlice(s: {
1493
1718
  ":integration_closure": s.planning?.integrationClosure ?? "",
1494
1719
  ":observability_impact": s.planning?.observabilityImpact ?? "",
1495
1720
  ":sequence": s.sequence ?? 0,
1721
+ ":is_sketch": s.isSketch ? 1 : 0,
1722
+ ":sketch_scope": s.sketchScope ?? "",
1496
1723
  // Raw sentinel params: NULL when caller omitted the field, used in ON CONFLICT guards
1497
1724
  ":raw_title": s.title ?? null,
1498
1725
  ":raw_risk": s.risk ?? null,
@@ -1503,9 +1730,52 @@ export function insertSlice(s: {
1503
1730
  ":raw_integration_closure": s.planning?.integrationClosure ?? null,
1504
1731
  ":raw_observability_impact": s.planning?.observabilityImpact ?? null,
1505
1732
  ":raw_sequence": s.sequence ?? null,
1733
+ ":raw_is_sketch": s.isSketch === undefined ? null : (s.isSketch ? 1 : 0),
1734
+ // NOTE: use !== undefined (not ??) so an explicit empty string "" is treated
1735
+ // as a present value and correctly clears the existing sketch_scope on
1736
+ // CONFLICT. ?? would incorrectly preserve the stale value.
1737
+ ":raw_sketch_scope": s.sketchScope !== undefined ? s.sketchScope : null,
1506
1738
  });
1507
1739
  }
1508
1740
 
1741
+ // ADR-011: sketch-then-refine helpers
1742
+ export function setSliceSketchFlag(milestoneId: string, sliceId: string, isSketch: boolean): void {
1743
+ if (!currentDb) throw new GSDError(GSD_STALE_STATE, "gsd-db: No database open");
1744
+ currentDb.prepare(
1745
+ `UPDATE slices SET is_sketch = :is_sketch WHERE milestone_id = :mid AND id = :sid`,
1746
+ ).run({ ":is_sketch": isSketch ? 1 : 0, ":mid": milestoneId, ":sid": sliceId });
1747
+ }
1748
+
1749
+ /**
1750
+ * ADR-011 auto-heal: reconcile stale is_sketch=1 rows whose PLAN already exists.
1751
+ *
1752
+ * Callers pass a predicate that resolves whether a plan file exists for a slice.
1753
+ * The predicate MUST use the canonical path resolver (`resolveSliceFile`, etc.)
1754
+ * to keep path logic in one place — do not hand-roll the path inside the callback.
1755
+ *
1756
+ * Recovers from two scenarios:
1757
+ * 1. Crash between `gsd_plan_slice` write and the sketch flag flip.
1758
+ * 2. Flag-OFF downgrade path: when `progressive_planning` is off, the dispatch
1759
+ * rule routes sketch slices to plan-slice, which writes PLAN.md but leaves
1760
+ * `is_sketch=1` — the next state derivation auto-heals it to 0 here.
1761
+ *
1762
+ * Not aggressive in practice: PLAN.md is only written via the DB-backed
1763
+ * `gsd_plan_slice` tool (which also inserts tasks), so a "stale PLAN.md with
1764
+ * is_sketch=1" is extremely unlikely to indicate anything other than the two
1765
+ * recovery scenarios above.
1766
+ */
1767
+ export function autoHealSketchFlags(milestoneId: string, hasPlanFile: (sliceId: string) => boolean): void {
1768
+ if (!currentDb) return;
1769
+ const rows = currentDb.prepare(
1770
+ `SELECT id FROM slices WHERE milestone_id = :mid AND is_sketch = 1`,
1771
+ ).all({ ":mid": milestoneId }) as Array<{ id: string }>;
1772
+ for (const row of rows) {
1773
+ if (hasPlanFile(row.id)) {
1774
+ setSliceSketchFlag(milestoneId, row.id, false);
1775
+ }
1776
+ }
1777
+ }
1778
+
1509
1779
  export function upsertSlicePlanning(milestoneId: string, sliceId: string, planning: Partial<SlicePlanningRecord>): void {
1510
1780
  if (!currentDb) throw new GSDError(GSD_STALE_STATE, "gsd-db: No database open");
1511
1781
  currentDb.prepare(
@@ -1679,6 +1949,8 @@ export interface SliceRow {
1679
1949
  observability_impact: string;
1680
1950
  sequence: number;
1681
1951
  replan_triggered_at: string | null;
1952
+ is_sketch: number;
1953
+ sketch_scope: string;
1682
1954
  }
1683
1955
 
1684
1956
  function rowToSlice(row: Record<string, unknown>): SliceRow {
@@ -1701,6 +1973,8 @@ function rowToSlice(row: Record<string, unknown>): SliceRow {
1701
1973
  observability_impact: (row["observability_impact"] as string) ?? "",
1702
1974
  sequence: (row["sequence"] as number) ?? 0,
1703
1975
  replan_triggered_at: (row["replan_triggered_at"] as string) ?? null,
1976
+ is_sketch: (row["is_sketch"] as number) ?? 0,
1977
+ sketch_scope: (row["sketch_scope"] as string) ?? "",
1704
1978
  };
1705
1979
  }
1706
1980
 
@@ -1764,6 +2038,12 @@ export interface TaskRow {
1764
2038
  observability_impact: string;
1765
2039
  full_plan_md: string;
1766
2040
  sequence: number;
2041
+ // ADR-011 Phase 2 escalation fields
2042
+ blocker_source: string;
2043
+ escalation_pending: number;
2044
+ escalation_awaiting_review: number;
2045
+ escalation_artifact_path: string | null;
2046
+ escalation_override_applied_at: string | null;
1767
2047
  }
1768
2048
 
1769
2049
  function parseTaskArrayColumn(raw: unknown): string[] {
@@ -1834,6 +2114,11 @@ function rowToTask(row: Record<string, unknown>): TaskRow {
1834
2114
  observability_impact: (row["observability_impact"] as string) ?? "",
1835
2115
  full_plan_md: (row["full_plan_md"] as string) ?? "",
1836
2116
  sequence: (row["sequence"] as number) ?? 0,
2117
+ blocker_source: (row["blocker_source"] as string) ?? "",
2118
+ escalation_pending: (row["escalation_pending"] as number) ?? 0,
2119
+ escalation_awaiting_review: (row["escalation_awaiting_review"] as number) ?? 0,
2120
+ escalation_artifact_path: (row["escalation_artifact_path"] as string) ?? null,
2121
+ escalation_override_applied_at: (row["escalation_override_applied_at"] as string) ?? null,
1837
2122
  };
1838
2123
  }
1839
2124
 
@@ -1854,6 +2139,125 @@ export function getSliceTasks(milestoneId: string, sliceId: string): TaskRow[] {
1854
2139
  return rows.map(rowToTask);
1855
2140
  }
1856
2141
 
2142
+ // ─── ADR-011 Phase 2 escalation helpers ──────────────────────────────────
2143
+
2144
+ /** Set pause-on-escalation state on a completed task. Mutually exclusive with awaiting_review. */
2145
+ export function setTaskEscalationPending(
2146
+ milestoneId: string, sliceId: string, taskId: string,
2147
+ artifactPath: string,
2148
+ ): void {
2149
+ if (!currentDb) throw new GSDError(GSD_STALE_STATE, "gsd-db: No database open");
2150
+ currentDb.prepare(
2151
+ `UPDATE tasks
2152
+ SET escalation_pending = 1,
2153
+ escalation_awaiting_review = 0,
2154
+ escalation_artifact_path = :path
2155
+ WHERE milestone_id = :mid AND slice_id = :sid AND id = :tid`,
2156
+ ).run({ ":path": artifactPath, ":mid": milestoneId, ":sid": sliceId, ":tid": taskId });
2157
+ }
2158
+
2159
+ /** Set awaiting-review state (artifact exists but continueWithDefault=true, no pause). Mutually exclusive with pending. */
2160
+ export function setTaskEscalationAwaitingReview(
2161
+ milestoneId: string, sliceId: string, taskId: string,
2162
+ artifactPath: string,
2163
+ ): void {
2164
+ if (!currentDb) throw new GSDError(GSD_STALE_STATE, "gsd-db: No database open");
2165
+ currentDb.prepare(
2166
+ `UPDATE tasks
2167
+ SET escalation_awaiting_review = 1,
2168
+ escalation_pending = 0,
2169
+ escalation_artifact_path = :path
2170
+ WHERE milestone_id = :mid AND slice_id = :sid AND id = :tid`,
2171
+ ).run({ ":path": artifactPath, ":mid": milestoneId, ":sid": sliceId, ":tid": taskId });
2172
+ }
2173
+
2174
+ /** Clear escalation-pending and awaiting-review flags once the user has resolved it. */
2175
+ export function clearTaskEscalationFlags(
2176
+ milestoneId: string, sliceId: string, taskId: string,
2177
+ ): void {
2178
+ if (!currentDb) throw new GSDError(GSD_STALE_STATE, "gsd-db: No database open");
2179
+ currentDb.prepare(
2180
+ `UPDATE tasks
2181
+ SET escalation_pending = 0,
2182
+ escalation_awaiting_review = 0
2183
+ WHERE milestone_id = :mid AND slice_id = :sid AND id = :tid`,
2184
+ ).run({ ":mid": milestoneId, ":sid": sliceId, ":tid": taskId });
2185
+ }
2186
+
2187
+ /**
2188
+ * Atomically claim a resolved escalation override for injection into a downstream
2189
+ * task's prompt. Returns true if this caller claimed it (must inject), false if
2190
+ * another caller already claimed it (must skip).
2191
+ */
2192
+ export function claimEscalationOverride(
2193
+ milestoneId: string, sliceId: string, sourceTaskId: string,
2194
+ ): boolean {
2195
+ if (!currentDb) return false;
2196
+ const now = new Date().toISOString();
2197
+ const result = currentDb.prepare(
2198
+ `UPDATE tasks
2199
+ SET escalation_override_applied_at = :now
2200
+ WHERE milestone_id = :mid AND slice_id = :sid AND id = :tid
2201
+ AND escalation_override_applied_at IS NULL
2202
+ AND escalation_artifact_path IS NOT NULL`,
2203
+ ).run({ ":now": now, ":mid": milestoneId, ":sid": sliceId, ":tid": sourceTaskId });
2204
+ // node:sqlite + better-sqlite3 both surface `changes` on the run result.
2205
+ const changes = (result as { changes?: number }).changes ?? 0;
2206
+ return changes > 0;
2207
+ }
2208
+
2209
+ /** Find the most recent resolved-but-unapplied escalation override in a slice. */
2210
+ export function findUnappliedEscalationOverride(
2211
+ milestoneId: string, sliceId: string,
2212
+ ): { taskId: string; artifactPath: string } | null {
2213
+ if (!currentDb) return null;
2214
+ // Filter BOTH flags: escalation_pending=0 AND escalation_awaiting_review=0
2215
+ // ensures we only claim overrides the user has explicitly resolved.
2216
+ // Without the awaiting_review filter, continueWithDefault=true artifacts
2217
+ // (not yet responded to) would be prematurely claimed, causing the override
2218
+ // to be lost when the user later resolves (#ADR-011 Phase 2 peer-review Bug 2).
2219
+ const row = currentDb.prepare(
2220
+ `SELECT id, escalation_artifact_path AS path
2221
+ FROM tasks
2222
+ WHERE milestone_id = :mid AND slice_id = :sid
2223
+ AND escalation_artifact_path IS NOT NULL
2224
+ AND escalation_override_applied_at IS NULL
2225
+ AND escalation_pending = 0
2226
+ AND escalation_awaiting_review = 0
2227
+ ORDER BY sequence DESC, id DESC
2228
+ LIMIT 1`,
2229
+ ).get({ ":mid": milestoneId, ":sid": sliceId }) as
2230
+ | { id: string; path: string | null }
2231
+ | undefined;
2232
+ if (!row || !row.path) return null;
2233
+ return { taskId: row.id, artifactPath: row.path };
2234
+ }
2235
+
2236
+ /** Set the blocker_source provenance field (used when rejecting an escalation). */
2237
+ export function setTaskBlockerSource(
2238
+ milestoneId: string, sliceId: string, taskId: string, source: string,
2239
+ ): void {
2240
+ if (!currentDb) throw new GSDError(GSD_STALE_STATE, "gsd-db: No database open");
2241
+ currentDb.prepare(
2242
+ `UPDATE tasks
2243
+ SET blocker_discovered = 1,
2244
+ blocker_source = :src
2245
+ WHERE milestone_id = :mid AND slice_id = :sid AND id = :tid`,
2246
+ ).run({ ":src": source, ":mid": milestoneId, ":sid": sliceId, ":tid": taskId });
2247
+ }
2248
+
2249
+ /** List tasks with active escalation artifacts across a milestone (for /gsd escalate list). */
2250
+ export function listEscalationArtifacts(milestoneId: string, includeResolved: boolean = false): TaskRow[] {
2251
+ if (!currentDb) return [];
2252
+ const filter = includeResolved
2253
+ ? "escalation_artifact_path IS NOT NULL"
2254
+ : "(escalation_pending = 1 OR escalation_awaiting_review = 1) AND escalation_artifact_path IS NOT NULL";
2255
+ const rows = currentDb.prepare(
2256
+ `SELECT * FROM tasks WHERE milestone_id = :mid AND ${filter} ORDER BY slice_id, sequence, id`,
2257
+ ).all({ ":mid": milestoneId });
2258
+ return rows.map(rowToTask);
2259
+ }
2260
+
1857
2261
  export function insertVerificationEvidence(e: {
1858
2262
  taskId: string;
1859
2263
  sliceId: string;
@@ -2167,6 +2571,19 @@ export function reconcileWorktreeDb(
2167
2571
  try {
2168
2572
  const wtInfo = adapter.prepare("PRAGMA wt.table_info('decisions')").all();
2169
2573
  const hasMadeBy = wtInfo.some((col) => col["name"] === "made_by");
2574
+ // ADR-011: worktree may predate schema v16/v17. For missing columns we
2575
+ // fall through to the main DB's existing value (not a literal default)
2576
+ // so reconcile never silently clears state the main tree has recorded.
2577
+ const hasDecisionSource = wtInfo.some((col) => col["name"] === "source");
2578
+ const wtSliceInfo = adapter.prepare("PRAGMA wt.table_info('slices')").all();
2579
+ const hasIsSketch = wtSliceInfo.some((col) => col["name"] === "is_sketch");
2580
+ const hasSketchScope = wtSliceInfo.some((col) => col["name"] === "sketch_scope");
2581
+ const wtTaskInfo = adapter.prepare("PRAGMA wt.table_info('tasks')").all();
2582
+ const hasBlockerSource = wtTaskInfo.some((col) => col["name"] === "blocker_source");
2583
+ const hasEscalationPending = wtTaskInfo.some((col) => col["name"] === "escalation_pending");
2584
+ const hasEscalationAwaiting = wtTaskInfo.some((col) => col["name"] === "escalation_awaiting_review");
2585
+ const hasEscalationArtifact = wtTaskInfo.some((col) => col["name"] === "escalation_artifact_path");
2586
+ const hasEscalationOverride = wtTaskInfo.some((col) => col["name"] === "escalation_override_applied_at");
2170
2587
 
2171
2588
  const decConf = adapter.prepare(
2172
2589
  `SELECT m.id FROM decisions m INNER JOIN wt.decisions w ON m.id = w.id WHERE m.decision != w.decision OR m.choice != w.choice OR m.rationale != w.rationale OR ${
@@ -2188,13 +2605,20 @@ export function reconcileWorktreeDb(
2188
2605
 
2189
2606
  adapter.exec("BEGIN");
2190
2607
  try {
2608
+ // Join the target decisions so we can prefer an existing main.source
2609
+ // when the worktree predates v16 — otherwise a write-through reconcile
2610
+ // would clobber 'escalation'-sourced decisions with the literal default.
2191
2611
  merged.decisions = countChanges(adapter.prepare(`
2192
2612
  INSERT OR REPLACE INTO decisions (
2193
- id, when_context, scope, decision, choice, rationale, revisable, made_by, superseded_by
2613
+ id, when_context, scope, decision, choice, rationale, revisable, made_by, source, superseded_by
2194
2614
  )
2195
- SELECT id, when_context, scope, decision, choice, rationale, revisable, ${
2196
- hasMadeBy ? "made_by" : "'agent'"
2197
- }, superseded_by FROM wt.decisions
2615
+ SELECT w.id, w.when_context, w.scope, w.decision, w.choice, w.rationale, w.revisable, ${
2616
+ hasMadeBy ? "w.made_by" : "COALESCE(m.made_by, 'agent')"
2617
+ }, ${
2618
+ hasDecisionSource ? "w.source" : "COALESCE(m.source, 'discussion')"
2619
+ }, w.superseded_by
2620
+ FROM wt.decisions w
2621
+ LEFT JOIN decisions m ON m.id = w.id
2198
2622
  `).run());
2199
2623
 
2200
2624
  merged.requirements = countChanges(adapter.prepare(`
@@ -2231,13 +2655,15 @@ export function reconcileWorktreeDb(
2231
2655
  `).run());
2232
2656
 
2233
2657
  // Merge slices — preserve worktree progress but never downgrade completed status (#2558).
2234
- // Uses INSERT OR REPLACE with a subquery that picks the best status — if the main DB
2235
- // already has a completed slice, keep that status even if the worktree copy is stale.
2658
+ // ADR-011 Phase 1: carry is_sketch + sketch_scope so reconcile doesn't
2659
+ // silently clear sketch metadata. When the worktree predates v16,
2660
+ // fall back to the main DB's existing value rather than a literal 0/''.
2236
2661
  merged.slices = countChanges(adapter.prepare(`
2237
2662
  INSERT OR REPLACE INTO slices (
2238
2663
  milestone_id, id, title, status, risk, depends, demo, created_at, completed_at,
2239
2664
  full_summary_md, full_uat_md, goal, success_criteria, proof_level,
2240
- integration_closure, observability_impact, sequence, replan_triggered_at
2665
+ integration_closure, observability_impact, sequence, replan_triggered_at,
2666
+ is_sketch, sketch_scope
2241
2667
  )
2242
2668
  SELECT w.milestone_id, w.id, w.title,
2243
2669
  CASE
@@ -2250,19 +2676,25 @@ export function reconcileWorktreeDb(
2250
2676
  THEN m.completed_at ELSE w.completed_at
2251
2677
  END,
2252
2678
  w.full_summary_md, w.full_uat_md, w.goal, w.success_criteria, w.proof_level,
2253
- w.integration_closure, w.observability_impact, w.sequence, w.replan_triggered_at
2679
+ w.integration_closure, w.observability_impact, w.sequence, w.replan_triggered_at,
2680
+ ${hasIsSketch ? "w.is_sketch" : "COALESCE(m.is_sketch, 0)"},
2681
+ ${hasSketchScope ? "w.sketch_scope" : "COALESCE(m.sketch_scope, '')"}
2254
2682
  FROM wt.slices w
2255
2683
  LEFT JOIN slices m ON m.milestone_id = w.milestone_id AND m.id = w.id
2256
2684
  `).run());
2257
2685
 
2258
- // Merge tasks — preserve execution results, never downgrade completed status (#2558)
2686
+ // Merge tasks — preserve execution results, never downgrade completed status (#2558).
2687
+ // ADR-011 P2: carry blocker_source + escalation_* columns so worktree reconcile
2688
+ // doesn't silently clear escalation state back to defaults.
2259
2689
  merged.tasks = countChanges(adapter.prepare(`
2260
2690
  INSERT OR REPLACE INTO tasks (
2261
2691
  milestone_id, slice_id, id, title, status, one_liner, narrative,
2262
2692
  verification_result, duration, completed_at, blocker_discovered,
2263
2693
  deviations, known_issues, key_files, key_decisions, full_summary_md,
2264
2694
  description, estimate, files, verify, inputs, expected_output,
2265
- observability_impact, full_plan_md, sequence
2695
+ observability_impact, full_plan_md, sequence,
2696
+ blocker_source, escalation_pending, escalation_awaiting_review,
2697
+ escalation_artifact_path, escalation_override_applied_at
2266
2698
  )
2267
2699
  SELECT w.milestone_id, w.slice_id, w.id, w.title,
2268
2700
  CASE
@@ -2278,7 +2710,12 @@ export function reconcileWorktreeDb(
2278
2710
  w.blocker_discovered,
2279
2711
  w.deviations, w.known_issues, w.key_files, w.key_decisions, w.full_summary_md,
2280
2712
  w.description, w.estimate, w.files, w.verify, w.inputs, w.expected_output,
2281
- w.observability_impact, w.full_plan_md, w.sequence
2713
+ w.observability_impact, w.full_plan_md, w.sequence,
2714
+ ${hasBlockerSource ? "w.blocker_source" : "COALESCE(m.blocker_source, '')"},
2715
+ ${hasEscalationPending ? "w.escalation_pending" : "COALESCE(m.escalation_pending, 0)"},
2716
+ ${hasEscalationAwaiting ? "w.escalation_awaiting_review" : "COALESCE(m.escalation_awaiting_review, 0)"},
2717
+ ${hasEscalationArtifact ? "w.escalation_artifact_path" : "m.escalation_artifact_path"},
2718
+ ${hasEscalationOverride ? "w.escalation_override_applied_at" : "m.escalation_override_applied_at"}
2282
2719
  FROM wt.tasks w
2283
2720
  LEFT JOIN tasks m ON m.milestone_id = w.milestone_id AND m.slice_id = w.slice_id AND m.id = w.id
2284
2721
  `).run());
@@ -3000,13 +3437,13 @@ export function restoreManifest(manifest: StateManifest): void {
3000
3437
  );
3001
3438
  }
3002
3439
 
3003
- // Restore slices
3440
+ // Restore slices (ADR-011 Phase 1: includes is_sketch + sketch_scope)
3004
3441
  const slStmt = db.prepare(
3005
3442
  `INSERT INTO slices (milestone_id, id, title, status, risk, depends, demo,
3006
3443
  created_at, completed_at, full_summary_md, full_uat_md,
3007
3444
  goal, success_criteria, proof_level, integration_closure, observability_impact,
3008
- sequence, replan_triggered_at)
3009
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
3445
+ sequence, replan_triggered_at, is_sketch, sketch_scope)
3446
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
3010
3447
  );
3011
3448
  for (const s of manifest.slices) {
3012
3449
  slStmt.run(
@@ -3015,17 +3452,21 @@ export function restoreManifest(manifest: StateManifest): void {
3015
3452
  s.created_at, s.completed_at, s.full_summary_md, s.full_uat_md,
3016
3453
  s.goal, s.success_criteria, s.proof_level, s.integration_closure, s.observability_impact,
3017
3454
  s.sequence, s.replan_triggered_at,
3455
+ s.is_sketch ?? 0,
3456
+ s.sketch_scope ?? "",
3018
3457
  );
3019
3458
  }
3020
3459
 
3021
- // Restore tasks
3460
+ // Restore tasks (ADR-011 P2: includes blocker_source + escalation_* columns)
3022
3461
  const tkStmt = db.prepare(
3023
3462
  `INSERT INTO tasks (milestone_id, slice_id, id, title, status,
3024
3463
  one_liner, narrative, verification_result, duration, completed_at,
3025
3464
  blocker_discovered, deviations, known_issues, key_files, key_decisions,
3026
3465
  full_summary_md, description, estimate, files, verify,
3027
- inputs, expected_output, observability_impact, sequence)
3028
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
3466
+ inputs, expected_output, observability_impact, sequence,
3467
+ blocker_source, escalation_pending, escalation_awaiting_review,
3468
+ escalation_artifact_path, escalation_override_applied_at)
3469
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
3029
3470
  );
3030
3471
  for (const t of manifest.tasks) {
3031
3472
  tkStmt.run(
@@ -3036,16 +3477,21 @@ export function restoreManifest(manifest: StateManifest): void {
3036
3477
  t.full_summary_md, t.description, t.estimate, JSON.stringify(t.files), t.verify,
3037
3478
  JSON.stringify(t.inputs), JSON.stringify(t.expected_output),
3038
3479
  t.observability_impact, t.sequence,
3480
+ t.blocker_source ?? "",
3481
+ t.escalation_pending ?? 0,
3482
+ t.escalation_awaiting_review ?? 0,
3483
+ t.escalation_artifact_path ?? null,
3484
+ t.escalation_override_applied_at ?? null,
3039
3485
  );
3040
3486
  }
3041
3487
 
3042
- // Restore decisions
3488
+ // Restore decisions (ADR-011 P2: include source so escalation decisions survive)
3043
3489
  const dcStmt = db.prepare(
3044
- `INSERT INTO decisions (seq, id, when_context, scope, decision, choice, rationale, revisable, made_by, superseded_by)
3045
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
3490
+ `INSERT INTO decisions (seq, id, when_context, scope, decision, choice, rationale, revisable, made_by, source, superseded_by)
3491
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
3046
3492
  );
3047
3493
  for (const d of manifest.decisions) {
3048
- dcStmt.run(d.seq, d.id, d.when_context, d.scope, d.decision, d.choice, d.rationale, d.revisable, d.made_by, d.superseded_by);
3494
+ dcStmt.run(d.seq, d.id, d.when_context, d.scope, d.decision, d.choice, d.rationale, d.revisable, d.made_by, d.source ?? "discussion", d.superseded_by);
3049
3495
  }
3050
3496
 
3051
3497
  // Restore verification evidence
@@ -3146,11 +3592,13 @@ export function insertMemoryRow(args: {
3146
3592
  sourceUnitId: string | null;
3147
3593
  createdAt: string;
3148
3594
  updatedAt: string;
3595
+ scope?: string;
3596
+ tags?: string[];
3149
3597
  }): void {
3150
3598
  if (!currentDb) throw new GSDError(GSD_STALE_STATE, "gsd-db: No database open");
3151
3599
  currentDb.prepare(
3152
- `INSERT INTO memories (id, category, content, confidence, source_unit_type, source_unit_id, created_at, updated_at)
3153
- VALUES (:id, :category, :content, :confidence, :source_unit_type, :source_unit_id, :created_at, :updated_at)`,
3600
+ `INSERT INTO memories (id, category, content, confidence, source_unit_type, source_unit_id, created_at, updated_at, scope, tags)
3601
+ VALUES (:id, :category, :content, :confidence, :source_unit_type, :source_unit_id, :created_at, :updated_at, :scope, :tags)`,
3154
3602
  ).run({
3155
3603
  ":id": args.id,
3156
3604
  ":category": args.category,
@@ -3160,9 +3608,107 @@ export function insertMemoryRow(args: {
3160
3608
  ":source_unit_id": args.sourceUnitId,
3161
3609
  ":created_at": args.createdAt,
3162
3610
  ":updated_at": args.updatedAt,
3611
+ ":scope": args.scope ?? "project",
3612
+ ":tags": JSON.stringify(args.tags ?? []),
3613
+ });
3614
+ }
3615
+
3616
+ export function insertMemorySourceRow(args: {
3617
+ id: string;
3618
+ kind: string;
3619
+ uri: string | null;
3620
+ title: string | null;
3621
+ content: string;
3622
+ contentHash: string;
3623
+ importedAt: string;
3624
+ scope?: string;
3625
+ tags?: string[];
3626
+ }): void {
3627
+ if (!currentDb) throw new GSDError(GSD_STALE_STATE, "gsd-db: No database open");
3628
+ currentDb.prepare(
3629
+ `INSERT OR IGNORE INTO memory_sources (id, kind, uri, title, content, content_hash, imported_at, scope, tags)
3630
+ VALUES (:id, :kind, :uri, :title, :content, :content_hash, :imported_at, :scope, :tags)`,
3631
+ ).run({
3632
+ ":id": args.id,
3633
+ ":kind": args.kind,
3634
+ ":uri": args.uri,
3635
+ ":title": args.title,
3636
+ ":content": args.content,
3637
+ ":content_hash": args.contentHash,
3638
+ ":imported_at": args.importedAt,
3639
+ ":scope": args.scope ?? "project",
3640
+ ":tags": JSON.stringify(args.tags ?? []),
3641
+ });
3642
+ }
3643
+
3644
+ export function deleteMemorySourceRow(id: string): boolean {
3645
+ if (!currentDb) throw new GSDError(GSD_STALE_STATE, "gsd-db: No database open");
3646
+ const res = currentDb
3647
+ .prepare("DELETE FROM memory_sources WHERE id = :id")
3648
+ .run({ ":id": id }) as { changes?: number };
3649
+ return (res?.changes ?? 0) > 0;
3650
+ }
3651
+
3652
+ export function upsertMemoryEmbedding(args: {
3653
+ memoryId: string;
3654
+ model: string;
3655
+ dim: number;
3656
+ vector: Uint8Array;
3657
+ updatedAt: string;
3658
+ }): void {
3659
+ if (!currentDb) throw new GSDError(GSD_STALE_STATE, "gsd-db: No database open");
3660
+ currentDb.prepare(
3661
+ `INSERT INTO memory_embeddings (memory_id, model, dim, vector, updated_at)
3662
+ VALUES (:memory_id, :model, :dim, :vector, :updated_at)
3663
+ ON CONFLICT(memory_id) DO UPDATE SET
3664
+ model = excluded.model,
3665
+ dim = excluded.dim,
3666
+ vector = excluded.vector,
3667
+ updated_at = excluded.updated_at`,
3668
+ ).run({
3669
+ ":memory_id": args.memoryId,
3670
+ ":model": args.model,
3671
+ ":dim": args.dim,
3672
+ ":vector": args.vector,
3673
+ ":updated_at": args.updatedAt,
3163
3674
  });
3164
3675
  }
3165
3676
 
3677
+ export function deleteMemoryEmbedding(memoryId: string): boolean {
3678
+ if (!currentDb) throw new GSDError(GSD_STALE_STATE, "gsd-db: No database open");
3679
+ const res = currentDb
3680
+ .prepare("DELETE FROM memory_embeddings WHERE memory_id = :id")
3681
+ .run({ ":id": memoryId }) as { changes?: number };
3682
+ return (res?.changes ?? 0) > 0;
3683
+ }
3684
+
3685
+ export function insertMemoryRelationRow(args: {
3686
+ fromId: string;
3687
+ toId: string;
3688
+ rel: string;
3689
+ confidence: number;
3690
+ createdAt: string;
3691
+ }): void {
3692
+ if (!currentDb) throw new GSDError(GSD_STALE_STATE, "gsd-db: No database open");
3693
+ currentDb.prepare(
3694
+ `INSERT OR REPLACE INTO memory_relations (from_id, to_id, rel, confidence, created_at)
3695
+ VALUES (:from_id, :to_id, :rel, :confidence, :created_at)`,
3696
+ ).run({
3697
+ ":from_id": args.fromId,
3698
+ ":to_id": args.toId,
3699
+ ":rel": args.rel,
3700
+ ":confidence": args.confidence,
3701
+ ":created_at": args.createdAt,
3702
+ });
3703
+ }
3704
+
3705
+ export function deleteMemoryRelationsFor(memoryId: string): void {
3706
+ if (!currentDb) throw new GSDError(GSD_STALE_STATE, "gsd-db: No database open");
3707
+ currentDb
3708
+ .prepare("DELETE FROM memory_relations WHERE from_id = :id OR to_id = :id")
3709
+ .run({ ":id": memoryId });
3710
+ }
3711
+
3166
3712
  export function rewriteMemoryId(placeholderId: string, realId: string): void {
3167
3713
  if (!currentDb) throw new GSDError(GSD_STALE_STATE, "gsd-db: No database open");
3168
3714
  currentDb.prepare("UPDATE memories SET id = :real_id WHERE id = :placeholder").run({