gsd-pi 2.82.0 → 3.0.0

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 (555) hide show
  1. package/README.md +51 -32
  2. package/dist/resources/.managed-resources-content-hash +1 -1
  3. package/dist/resources/GSD-WORKFLOW.md +10 -1
  4. package/dist/resources/extensions/browser-tools/tools/screenshot.js +1 -0
  5. package/dist/resources/extensions/browser-tools/tools/zoom.js +1 -0
  6. package/dist/resources/extensions/claude-code-cli/partial-builder.js +2 -1
  7. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +1 -1
  8. package/dist/resources/extensions/cmux/index.js +5 -0
  9. package/dist/resources/extensions/gsd/auto/infra-errors.js +9 -3
  10. package/dist/resources/extensions/gsd/auto/loop.js +19 -6
  11. package/dist/resources/extensions/gsd/auto/orchestrator.js +124 -6
  12. package/dist/resources/extensions/gsd/auto/phases.js +90 -31
  13. package/dist/resources/extensions/gsd/auto/session.js +4 -0
  14. package/dist/resources/extensions/gsd/auto/workflow-kernel.js +3 -0
  15. package/dist/resources/extensions/gsd/auto/workflow-memory-pressure.js +12 -0
  16. package/dist/resources/extensions/gsd/auto-dashboard.js +66 -1
  17. package/dist/resources/extensions/gsd/auto-direct-dispatch.js +1 -0
  18. package/dist/resources/extensions/gsd/auto-dispatch.js +20 -19
  19. package/dist/resources/extensions/gsd/auto-model-selection.js +2 -0
  20. package/dist/resources/extensions/gsd/auto-post-unit.js +246 -133
  21. package/dist/resources/extensions/gsd/auto-prompts.js +13 -5
  22. package/dist/resources/extensions/gsd/auto-recovery.js +71 -14
  23. package/dist/resources/extensions/gsd/auto-start.js +87 -14
  24. package/dist/resources/extensions/gsd/auto-verification.js +45 -26
  25. package/dist/resources/extensions/gsd/auto-worktree.js +176 -10
  26. package/dist/resources/extensions/gsd/auto.js +178 -63
  27. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +31 -7
  28. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +10 -9
  29. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +9 -2
  30. package/dist/resources/extensions/gsd/bootstrap/subagent-input.js +21 -9
  31. package/dist/resources/extensions/gsd/bootstrap/system-context.js +55 -12
  32. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +17 -3
  33. package/dist/resources/extensions/gsd/clean-root-preflight.js +170 -8
  34. package/dist/resources/extensions/gsd/commands/catalog.js +10 -1
  35. package/dist/resources/extensions/gsd/commands/handlers/core.js +39 -1
  36. package/dist/resources/extensions/gsd/commands/handlers/ops.js +5 -0
  37. package/dist/resources/extensions/gsd/commands-bootstrap.js +5 -0
  38. package/dist/resources/extensions/gsd/commands-handlers.js +15 -2
  39. package/dist/resources/extensions/gsd/commands-prefs-wizard.js +7 -2
  40. package/dist/resources/extensions/gsd/commands-verdict.js +139 -0
  41. package/dist/resources/extensions/gsd/context-store.js +112 -0
  42. package/dist/resources/extensions/gsd/crash-recovery.js +43 -5
  43. package/dist/resources/extensions/gsd/db/milestone-leases.js +24 -0
  44. package/dist/resources/extensions/gsd/db/unit-dispatches.js +3 -2
  45. package/dist/resources/extensions/gsd/db-writer.js +150 -84
  46. package/dist/resources/extensions/gsd/dispatch-guard.js +2 -2
  47. package/dist/resources/extensions/gsd/docs/preferences-reference.md +1 -1
  48. package/dist/resources/extensions/gsd/doctor-git-checks.js +87 -7
  49. package/dist/resources/extensions/gsd/doctor-runtime-checks.js +28 -11
  50. package/dist/resources/extensions/gsd/doctor.js +2 -28
  51. package/dist/resources/extensions/gsd/export-html.js +27 -425
  52. package/dist/resources/extensions/gsd/forensics.js +3 -3
  53. package/dist/resources/extensions/gsd/git-service.js +45 -3
  54. package/dist/resources/extensions/gsd/gsd-db.js +21 -6
  55. package/dist/resources/extensions/gsd/guided-flow-queue.js +4 -3
  56. package/dist/resources/extensions/gsd/guided-flow.js +101 -116
  57. package/dist/resources/extensions/gsd/guided-unit-context.js +23 -0
  58. package/dist/resources/extensions/gsd/knowledge-backfill.js +144 -0
  59. package/dist/resources/extensions/gsd/knowledge-capture.js +136 -0
  60. package/dist/resources/extensions/gsd/knowledge-parser.js +154 -0
  61. package/dist/resources/extensions/gsd/knowledge-projection.js +210 -0
  62. package/dist/resources/extensions/gsd/markdown-renderer.js +16 -9
  63. package/dist/resources/extensions/gsd/md-importer.js +1 -1
  64. package/dist/resources/extensions/gsd/memory-backfill.js +73 -17
  65. package/dist/resources/extensions/gsd/memory-consolidation-scanner.js +222 -0
  66. package/dist/resources/extensions/gsd/migrate/command.js +5 -0
  67. package/dist/resources/extensions/gsd/migrate/parsers.js +10 -0
  68. package/dist/resources/extensions/gsd/migrate/preview.js +9 -0
  69. package/dist/resources/extensions/gsd/migrate/transformer.js +51 -4
  70. package/dist/resources/extensions/gsd/migrate/writer.js +11 -1
  71. package/dist/resources/extensions/gsd/migration-auto-check.js +12 -17
  72. package/dist/resources/extensions/gsd/milestone-actions.js +11 -4
  73. package/dist/resources/extensions/gsd/native-git-bridge.js +48 -12
  74. package/dist/resources/extensions/gsd/paths.js +4 -0
  75. package/dist/resources/extensions/gsd/pending-auto-start.js +52 -0
  76. package/dist/resources/extensions/gsd/post-execution-checks.js +73 -2
  77. package/dist/resources/extensions/gsd/pre-execution-checks.js +28 -1
  78. package/dist/resources/extensions/gsd/prompt-loader.js +1 -1
  79. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
  80. package/dist/resources/extensions/gsd/prompts/complete-slice.md +1 -1
  81. package/dist/resources/extensions/gsd/prompts/discuss-headless.md +8 -8
  82. package/dist/resources/extensions/gsd/prompts/discuss.md +9 -9
  83. package/dist/resources/extensions/gsd/prompts/guided-discuss-project.md +4 -4
  84. package/dist/resources/extensions/gsd/prompts/guided-discuss-requirements.md +3 -3
  85. package/dist/resources/extensions/gsd/prompts/plan-slice.md +4 -4
  86. package/dist/resources/extensions/gsd/prompts/queue.md +4 -4
  87. package/dist/resources/extensions/gsd/prompts/refine-slice.md +2 -2
  88. package/dist/resources/extensions/gsd/prompts/rewrite-docs.md +1 -1
  89. package/dist/resources/extensions/gsd/prompts/system.md +2 -2
  90. package/dist/resources/extensions/gsd/provider-switch-observer.js +146 -0
  91. package/dist/resources/extensions/gsd/queue-reorder-ui.js +30 -13
  92. package/dist/resources/extensions/gsd/smart-entry-routing.js +36 -0
  93. package/dist/resources/extensions/gsd/state-reconciliation/drift/merge-state.js +6 -1
  94. package/dist/resources/extensions/gsd/state-reconciliation/drift/project-md.js +9 -14
  95. package/dist/resources/extensions/gsd/state-reconciliation/drift/roadmap.js +19 -24
  96. package/dist/resources/extensions/gsd/state.js +3 -3
  97. package/dist/resources/extensions/gsd/status-guards.js +11 -0
  98. package/dist/resources/extensions/gsd/templates/knowledge.md +2 -2
  99. package/dist/resources/extensions/gsd/templates/plan.md +9 -5
  100. package/dist/resources/extensions/gsd/templates/task-plan.md +10 -2
  101. package/dist/resources/extensions/gsd/tools/complete-milestone.js +6 -8
  102. package/dist/resources/extensions/gsd/tools/complete-slice.js +6 -8
  103. package/dist/resources/extensions/gsd/tools/plan-milestone.js +7 -1
  104. package/dist/resources/extensions/gsd/tools/plan-slice.js +87 -14
  105. package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +119 -0
  106. package/dist/resources/extensions/gsd/unit-context-manifest.js +32 -10
  107. package/dist/resources/extensions/gsd/validation.js +23 -1
  108. package/dist/resources/extensions/gsd/verification-gate.js +68 -7
  109. package/dist/resources/extensions/gsd/verification-verdict.js +26 -0
  110. package/dist/resources/extensions/gsd/workflow-mcp.js +17 -1
  111. package/dist/resources/extensions/gsd/workflow-projections.js +6 -8
  112. package/dist/resources/extensions/gsd/worktree-lifecycle.js +54 -10
  113. package/dist/resources/extensions/gsd/worktree-manager.js +1 -1
  114. package/dist/resources/extensions/shared/html-shell.js +388 -0
  115. package/dist/resources/extensions/subagent/index.js +448 -78
  116. package/dist/resources/extensions/subagent/launch.js +77 -0
  117. package/dist/resources/extensions/subagent/run-store.js +148 -0
  118. package/dist/resources/extensions/ttsr/ttsr-manager.js +3 -1
  119. package/dist/resources/extensions/visual-brief/artifact-policy.js +29 -0
  120. package/dist/resources/extensions/visual-brief/extension-manifest.json +8 -0
  121. package/dist/resources/extensions/visual-brief/index.js +5 -0
  122. package/dist/resources/extensions/visual-brief/page-contract.js +124 -0
  123. package/dist/resources/extensions/visual-brief/prompts.js +140 -0
  124. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  125. package/dist/web/standalone/.next/BUILD_ID +1 -1
  126. package/dist/web/standalone/.next/app-path-routes-manifest.json +9 -9
  127. package/dist/web/standalone/.next/build-manifest.json +3 -3
  128. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  129. package/dist/web/standalone/.next/react-loadable-manifest.json +5 -5
  130. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  131. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  132. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  133. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  134. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  135. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  136. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  137. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  138. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  139. package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
  140. package/dist/web/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
  141. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  142. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  143. package/dist/web/standalone/.next/server/app/_not-found.rsc +4 -7
  144. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +4 -7
  145. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  146. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +4 -5
  147. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  148. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  149. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -5
  150. package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
  151. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  152. package/dist/web/standalone/.next/server/app/index.html +1 -1
  153. package/dist/web/standalone/.next/server/app/index.rsc +4 -7
  154. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  155. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +4 -7
  156. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  157. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +4 -5
  158. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -5
  159. package/dist/web/standalone/.next/server/app/page.js +2 -2
  160. package/dist/web/standalone/.next/server/app/page.js.nft.json +1 -1
  161. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  162. package/dist/web/standalone/.next/server/app-paths-manifest.json +9 -9
  163. package/dist/web/standalone/.next/server/chunks/4266.js +2 -0
  164. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  165. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  166. package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
  167. package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
  168. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  169. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  170. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  171. package/dist/web/standalone/.next/static/chunks/2973.33f26573894b6153.js +2 -0
  172. package/dist/web/standalone/.next/static/chunks/8359.65b24fac92188a6b.js +10 -0
  173. package/dist/web/standalone/.next/static/chunks/9441.ff70bb53f6835771.js +1 -0
  174. package/dist/web/standalone/.next/static/chunks/app/layout-b23b3f6858dc6dc8.js +1 -0
  175. package/dist/web/standalone/.next/static/chunks/{webpack-de742b64187e13fe.js → webpack-855d616060cb6e59.js} +1 -1
  176. package/dist/web/standalone/.next/static/css/746ee28c929d1880.css +1 -0
  177. package/package.json +6 -5
  178. package/packages/contracts/dist/rpc.test.js +7 -0
  179. package/packages/contracts/dist/rpc.test.js.map +1 -1
  180. package/packages/contracts/dist/workflow.d.ts +21 -0
  181. package/packages/contracts/dist/workflow.d.ts.map +1 -1
  182. package/packages/contracts/dist/workflow.js +24 -0
  183. package/packages/contracts/dist/workflow.js.map +1 -1
  184. package/packages/contracts/src/rpc.test.ts +8 -0
  185. package/packages/contracts/src/workflow.ts +24 -0
  186. package/packages/daemon/package.json +2 -2
  187. package/packages/mcp-server/README.md +14 -3
  188. package/packages/mcp-server/dist/workflow-tools.d.ts +0 -3
  189. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  190. package/packages/mcp-server/dist/workflow-tools.js +80 -0
  191. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  192. package/packages/mcp-server/package.json +2 -2
  193. package/packages/mcp-server/src/workflow-tools-parity.test.ts +244 -0
  194. package/packages/mcp-server/src/workflow-tools.test.ts +23 -1
  195. package/packages/mcp-server/src/workflow-tools.ts +168 -0
  196. package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
  197. package/packages/native/package.json +1 -1
  198. package/packages/native/tsconfig.json +2 -1
  199. package/packages/native/tsconfig.tsbuildinfo +1 -1
  200. package/packages/pi-agent-core/package.json +1 -1
  201. package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -1
  202. package/packages/pi-ai/dist/index.d.ts +2 -2
  203. package/packages/pi-ai/dist/index.d.ts.map +1 -1
  204. package/packages/pi-ai/dist/index.js +1 -1
  205. package/packages/pi-ai/dist/index.js.map +1 -1
  206. package/packages/pi-ai/dist/providers/google-gemini-cli.d.ts.map +1 -1
  207. package/packages/pi-ai/dist/providers/google-gemini-cli.js +5 -0
  208. package/packages/pi-ai/dist/providers/google-gemini-cli.js.map +1 -1
  209. package/packages/pi-ai/dist/providers/google-gemini-cli.test.d.ts +2 -0
  210. package/packages/pi-ai/dist/providers/google-gemini-cli.test.d.ts.map +1 -0
  211. package/packages/pi-ai/dist/providers/google-gemini-cli.test.js +41 -0
  212. package/packages/pi-ai/dist/providers/google-gemini-cli.test.js.map +1 -0
  213. package/packages/pi-ai/dist/providers/openai-codex-responses.d.ts.map +1 -1
  214. package/packages/pi-ai/dist/providers/openai-codex-responses.js +82 -1
  215. package/packages/pi-ai/dist/providers/openai-codex-responses.js.map +1 -1
  216. package/packages/pi-ai/dist/providers/openai-codex-responses.test.d.ts +2 -0
  217. package/packages/pi-ai/dist/providers/openai-codex-responses.test.d.ts.map +1 -0
  218. package/packages/pi-ai/dist/providers/openai-codex-responses.test.js +52 -0
  219. package/packages/pi-ai/dist/providers/openai-codex-responses.test.js.map +1 -0
  220. package/packages/pi-ai/dist/providers/simple-options.d.ts +2 -4
  221. package/packages/pi-ai/dist/providers/simple-options.d.ts.map +1 -1
  222. package/packages/pi-ai/dist/providers/simple-options.js +5 -6
  223. package/packages/pi-ai/dist/providers/simple-options.js.map +1 -1
  224. package/packages/pi-ai/dist/providers/simple-options.test.d.ts +2 -0
  225. package/packages/pi-ai/dist/providers/simple-options.test.d.ts.map +1 -0
  226. package/packages/pi-ai/dist/providers/simple-options.test.js +50 -0
  227. package/packages/pi-ai/dist/providers/simple-options.test.js.map +1 -0
  228. package/packages/pi-ai/dist/providers/transform-messages.d.ts +11 -0
  229. package/packages/pi-ai/dist/providers/transform-messages.d.ts.map +1 -1
  230. package/packages/pi-ai/dist/providers/transform-messages.js +20 -0
  231. package/packages/pi-ai/dist/providers/transform-messages.js.map +1 -1
  232. package/packages/pi-ai/package.json +1 -1
  233. package/packages/pi-ai/src/index.ts +7 -2
  234. package/packages/pi-ai/src/providers/google-gemini-cli.test.ts +49 -0
  235. package/packages/pi-ai/src/providers/google-gemini-cli.ts +7 -0
  236. package/packages/pi-ai/src/providers/openai-codex-responses.test.ts +63 -0
  237. package/packages/pi-ai/src/providers/openai-codex-responses.ts +91 -1
  238. package/packages/pi-ai/src/providers/simple-options.test.ts +60 -0
  239. package/packages/pi-ai/src/providers/simple-options.ts +5 -6
  240. package/packages/pi-ai/src/providers/transform-messages.ts +24 -0
  241. package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
  242. package/packages/pi-coding-agent/dist/core/agent-session-thinking-level.test.d.ts +2 -0
  243. package/packages/pi-coding-agent/dist/core/agent-session-thinking-level.test.d.ts.map +1 -0
  244. package/packages/pi-coding-agent/dist/core/agent-session-thinking-level.test.js +66 -0
  245. package/packages/pi-coding-agent/dist/core/agent-session-thinking-level.test.js.map +1 -0
  246. package/packages/pi-coding-agent/dist/core/agent-session.js +1 -1
  247. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  248. package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js +44 -3
  249. package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js.map +1 -1
  250. package/packages/pi-coding-agent/dist/core/sdk.js +1 -1
  251. package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
  252. package/packages/pi-coding-agent/dist/core/system-prompt.js +4 -4
  253. package/packages/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
  254. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.d.ts.map +1 -1
  255. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js +24 -6
  256. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js.map +1 -1
  257. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  258. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +71 -97
  259. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  260. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-ordering.test.js +25 -1
  261. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-ordering.test.js.map +1 -1
  262. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +2 -0
  263. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  264. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +24 -10
  265. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  266. package/packages/pi-coding-agent/dist/tests/system-prompt-file-safety.test.d.ts +2 -0
  267. package/packages/pi-coding-agent/dist/tests/system-prompt-file-safety.test.d.ts.map +1 -0
  268. package/packages/pi-coding-agent/dist/tests/system-prompt-file-safety.test.js +17 -0
  269. package/packages/pi-coding-agent/dist/tests/system-prompt-file-safety.test.js.map +1 -0
  270. package/packages/pi-coding-agent/package.json +1 -1
  271. package/packages/pi-coding-agent/src/core/agent-session-thinking-level.test.ts +79 -0
  272. package/packages/pi-coding-agent/src/core/agent-session.ts +1 -1
  273. package/packages/pi-coding-agent/src/core/chat-controller-ordering.test.ts +53 -3
  274. package/packages/pi-coding-agent/src/core/sdk.ts +1 -1
  275. package/packages/pi-coding-agent/src/core/system-prompt.ts +4 -4
  276. package/packages/pi-coding-agent/src/modes/interactive/components/footer.ts +23 -7
  277. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +75 -102
  278. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode-ordering.test.ts +30 -1
  279. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +29 -10
  280. package/packages/pi-coding-agent/src/tests/system-prompt-file-safety.test.ts +22 -0
  281. package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
  282. package/packages/pi-tui/dist/__tests__/terminal.test.d.ts +2 -0
  283. package/packages/pi-tui/dist/__tests__/terminal.test.d.ts.map +1 -0
  284. package/packages/pi-tui/dist/__tests__/terminal.test.js +103 -0
  285. package/packages/pi-tui/dist/__tests__/terminal.test.js.map +1 -0
  286. package/packages/pi-tui/dist/terminal.d.ts +2 -0
  287. package/packages/pi-tui/dist/terminal.d.ts.map +1 -1
  288. package/packages/pi-tui/dist/terminal.js +12 -0
  289. package/packages/pi-tui/dist/terminal.js.map +1 -1
  290. package/packages/pi-tui/dist/tui.d.ts.map +1 -1
  291. package/packages/pi-tui/dist/tui.js +5 -0
  292. package/packages/pi-tui/dist/tui.js.map +1 -1
  293. package/packages/pi-tui/package.json +1 -1
  294. package/packages/pi-tui/src/__tests__/terminal.test.ts +121 -0
  295. package/packages/pi-tui/src/terminal.ts +11 -0
  296. package/packages/pi-tui/src/tui.ts +6 -0
  297. package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
  298. package/packages/rpc-client/package.json +1 -1
  299. package/packages/rpc-client/tsconfig.tsbuildinfo +1 -1
  300. package/pkg/package.json +1 -1
  301. package/src/resources/GSD-WORKFLOW.md +10 -1
  302. package/src/resources/extensions/browser-tools/tools/screenshot.ts +1 -0
  303. package/src/resources/extensions/browser-tools/tools/zoom.ts +1 -0
  304. package/src/resources/extensions/claude-code-cli/partial-builder.ts +2 -1
  305. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +1 -1
  306. package/src/resources/extensions/claude-code-cli/tests/partial-builder.test.ts +19 -2
  307. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +9 -0
  308. package/src/resources/extensions/cmux/index.ts +6 -0
  309. package/src/resources/extensions/gsd/auto/contracts.ts +59 -16
  310. package/src/resources/extensions/gsd/auto/infra-errors.ts +9 -3
  311. package/src/resources/extensions/gsd/auto/loop.ts +22 -6
  312. package/src/resources/extensions/gsd/auto/orchestrator.ts +129 -6
  313. package/src/resources/extensions/gsd/auto/phases.ts +104 -38
  314. package/src/resources/extensions/gsd/auto/session.ts +4 -0
  315. package/src/resources/extensions/gsd/auto/workflow-kernel.ts +5 -1
  316. package/src/resources/extensions/gsd/auto/workflow-memory-pressure.ts +13 -0
  317. package/src/resources/extensions/gsd/auto-dashboard.ts +72 -1
  318. package/src/resources/extensions/gsd/auto-direct-dispatch.ts +1 -0
  319. package/src/resources/extensions/gsd/auto-dispatch.ts +21 -19
  320. package/src/resources/extensions/gsd/auto-model-selection.ts +2 -1
  321. package/src/resources/extensions/gsd/auto-post-unit.ts +279 -144
  322. package/src/resources/extensions/gsd/auto-prompts.ts +13 -5
  323. package/src/resources/extensions/gsd/auto-recovery.ts +74 -11
  324. package/src/resources/extensions/gsd/auto-start.ts +94 -12
  325. package/src/resources/extensions/gsd/auto-verification.ts +58 -36
  326. package/src/resources/extensions/gsd/auto-worktree.ts +193 -10
  327. package/src/resources/extensions/gsd/auto.ts +187 -61
  328. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +42 -7
  329. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +10 -9
  330. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +10 -2
  331. package/src/resources/extensions/gsd/bootstrap/subagent-input.ts +19 -7
  332. package/src/resources/extensions/gsd/bootstrap/system-context.ts +58 -15
  333. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +20 -4
  334. package/src/resources/extensions/gsd/clean-root-preflight.ts +174 -8
  335. package/src/resources/extensions/gsd/commands/catalog.ts +10 -1
  336. package/src/resources/extensions/gsd/commands/handlers/core.ts +42 -1
  337. package/src/resources/extensions/gsd/commands/handlers/ops.ts +5 -0
  338. package/src/resources/extensions/gsd/commands-bootstrap.ts +10 -0
  339. package/src/resources/extensions/gsd/commands-handlers.ts +19 -2
  340. package/src/resources/extensions/gsd/commands-prefs-wizard.ts +8 -3
  341. package/src/resources/extensions/gsd/commands-verdict.ts +202 -0
  342. package/src/resources/extensions/gsd/context-store.ts +120 -1
  343. package/src/resources/extensions/gsd/crash-recovery.ts +44 -4
  344. package/src/resources/extensions/gsd/db/milestone-leases.ts +26 -0
  345. package/src/resources/extensions/gsd/db/unit-dispatches.ts +4 -3
  346. package/src/resources/extensions/gsd/db-writer.ts +167 -84
  347. package/src/resources/extensions/gsd/dispatch-guard.ts +2 -2
  348. package/src/resources/extensions/gsd/docs/preferences-reference.md +1 -1
  349. package/src/resources/extensions/gsd/doctor-git-checks.ts +89 -7
  350. package/src/resources/extensions/gsd/doctor-runtime-checks.ts +25 -13
  351. package/src/resources/extensions/gsd/doctor-types.ts +3 -0
  352. package/src/resources/extensions/gsd/doctor.ts +2 -27
  353. package/src/resources/extensions/gsd/export-html.ts +27 -427
  354. package/src/resources/extensions/gsd/forensics.ts +3 -3
  355. package/src/resources/extensions/gsd/git-service.ts +51 -4
  356. package/src/resources/extensions/gsd/gsd-db.ts +21 -6
  357. package/src/resources/extensions/gsd/guided-flow-queue.ts +4 -3
  358. package/src/resources/extensions/gsd/guided-flow.ts +134 -133
  359. package/src/resources/extensions/gsd/guided-unit-context.ts +30 -0
  360. package/src/resources/extensions/gsd/knowledge-backfill.ts +164 -0
  361. package/src/resources/extensions/gsd/knowledge-capture.ts +160 -0
  362. package/src/resources/extensions/gsd/knowledge-parser.ts +174 -0
  363. package/src/resources/extensions/gsd/knowledge-projection.ts +241 -0
  364. package/src/resources/extensions/gsd/markdown-renderer.ts +16 -9
  365. package/src/resources/extensions/gsd/md-importer.ts +1 -1
  366. package/src/resources/extensions/gsd/memory-backfill.ts +89 -17
  367. package/src/resources/extensions/gsd/memory-consolidation-scanner.ts +277 -0
  368. package/src/resources/extensions/gsd/migrate/command.ts +5 -0
  369. package/src/resources/extensions/gsd/migrate/parsers.ts +11 -0
  370. package/src/resources/extensions/gsd/migrate/preview.ts +10 -0
  371. package/src/resources/extensions/gsd/migrate/transformer.ts +58 -4
  372. package/src/resources/extensions/gsd/migrate/writer.ts +14 -1
  373. package/src/resources/extensions/gsd/migration-auto-check.ts +15 -23
  374. package/src/resources/extensions/gsd/milestone-actions.ts +10 -4
  375. package/src/resources/extensions/gsd/native-git-bridge.ts +54 -12
  376. package/src/resources/extensions/gsd/paths.ts +5 -0
  377. package/src/resources/extensions/gsd/pending-auto-start.ts +79 -0
  378. package/src/resources/extensions/gsd/post-execution-checks.ts +87 -2
  379. package/src/resources/extensions/gsd/pre-execution-checks.ts +32 -1
  380. package/src/resources/extensions/gsd/prompt-loader.ts +1 -1
  381. package/src/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
  382. package/src/resources/extensions/gsd/prompts/complete-slice.md +1 -1
  383. package/src/resources/extensions/gsd/prompts/discuss-headless.md +8 -8
  384. package/src/resources/extensions/gsd/prompts/discuss.md +9 -9
  385. package/src/resources/extensions/gsd/prompts/guided-discuss-project.md +4 -4
  386. package/src/resources/extensions/gsd/prompts/guided-discuss-requirements.md +3 -3
  387. package/src/resources/extensions/gsd/prompts/plan-slice.md +4 -4
  388. package/src/resources/extensions/gsd/prompts/queue.md +4 -4
  389. package/src/resources/extensions/gsd/prompts/refine-slice.md +2 -2
  390. package/src/resources/extensions/gsd/prompts/rewrite-docs.md +1 -1
  391. package/src/resources/extensions/gsd/prompts/system.md +2 -2
  392. package/src/resources/extensions/gsd/provider-switch-observer.ts +185 -0
  393. package/src/resources/extensions/gsd/queue-reorder-ui.ts +31 -13
  394. package/src/resources/extensions/gsd/smart-entry-routing.ts +77 -0
  395. package/src/resources/extensions/gsd/state-reconciliation/drift/merge-state.ts +8 -1
  396. package/src/resources/extensions/gsd/state-reconciliation/drift/project-md.ts +12 -15
  397. package/src/resources/extensions/gsd/state-reconciliation/drift/roadmap.ts +17 -25
  398. package/src/resources/extensions/gsd/state.ts +3 -3
  399. package/src/resources/extensions/gsd/status-guards.ts +13 -0
  400. package/src/resources/extensions/gsd/templates/knowledge.md +2 -2
  401. package/src/resources/extensions/gsd/templates/plan.md +9 -5
  402. package/src/resources/extensions/gsd/templates/task-plan.md +10 -2
  403. package/src/resources/extensions/gsd/tests/auto-dashboard.test.ts +71 -0
  404. package/src/resources/extensions/gsd/tests/auto-deterministic-error-classification-4973.test.ts +116 -0
  405. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +131 -0
  406. package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +487 -4
  407. package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +151 -12
  408. package/src/resources/extensions/gsd/tests/auto-phases-lifecycle.test.ts +53 -2
  409. package/src/resources/extensions/gsd/tests/auto-post-unit-step-message.test.ts +18 -6
  410. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +91 -6
  411. package/src/resources/extensions/gsd/tests/auto-runtime-state.test.ts +4 -4
  412. package/src/resources/extensions/gsd/tests/auto-start-orphan-bootstrap.test.ts +1 -0
  413. package/src/resources/extensions/gsd/tests/auto-stop-notification.test.ts +20 -0
  414. package/src/resources/extensions/gsd/tests/auto-worktree-registry.test.ts +69 -1
  415. package/src/resources/extensions/gsd/tests/brief-command.test.ts +89 -0
  416. package/src/resources/extensions/gsd/tests/browser-tools-compatibility-declarations.test.ts +62 -0
  417. package/src/resources/extensions/gsd/tests/checkout-branch-stash-guard.test.ts +87 -0
  418. package/src/resources/extensions/gsd/tests/clean-root-preflight.test.ts +107 -2
  419. package/src/resources/extensions/gsd/tests/clear-stale-autostart.test.ts +11 -2
  420. package/src/resources/extensions/gsd/tests/closeout-git-deferral.test.ts +16 -0
  421. package/src/resources/extensions/gsd/tests/commands-verdict.test.ts +378 -0
  422. package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +4 -1
  423. package/src/resources/extensions/gsd/tests/complete-slice.test.ts +5 -9
  424. package/src/resources/extensions/gsd/tests/complete-task.test.ts +3 -1
  425. package/src/resources/extensions/gsd/tests/context-store-decisions-from-memories.test.ts +312 -0
  426. package/src/resources/extensions/gsd/tests/crash-recovery-via-db.test.ts +86 -2
  427. package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +2 -0
  428. package/src/resources/extensions/gsd/tests/db-authority-regression.test.ts +208 -0
  429. package/src/resources/extensions/gsd/tests/db-writer.test.ts +13 -8
  430. package/src/resources/extensions/gsd/tests/decisions-projection-from-memories.test.ts +453 -0
  431. package/src/resources/extensions/gsd/tests/decisions-stop-table-writes.test.ts +348 -0
  432. package/src/resources/extensions/gsd/tests/deep-project-auto-loop.test.ts +59 -2
  433. package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +66 -0
  434. package/src/resources/extensions/gsd/tests/dispatch-guard.test.ts +27 -0
  435. package/src/resources/extensions/gsd/tests/doctor-empty-worktree.test.ts +65 -0
  436. package/src/resources/extensions/gsd/tests/evidence-cross-ref.test.ts +38 -0
  437. package/src/resources/extensions/gsd/tests/export-html-enhancements.test.ts +8 -0
  438. package/src/resources/extensions/gsd/tests/freeform-decisions.test.ts +8 -4
  439. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +11 -0
  440. package/src/resources/extensions/gsd/tests/gsd-tools.test.ts +11 -7
  441. package/src/resources/extensions/gsd/tests/gsdroot-worktree-detection.test.ts +5 -2
  442. package/src/resources/extensions/gsd/tests/guided-discuss-project-prompt-rendering.test.ts +2 -0
  443. package/src/resources/extensions/gsd/tests/guided-dispatch-root.test.ts +106 -0
  444. package/src/resources/extensions/gsd/tests/guided-flow-session-isolation.test.ts +59 -11
  445. package/src/resources/extensions/gsd/tests/guided-flow.test.ts +21 -0
  446. package/src/resources/extensions/gsd/tests/guided-tool-contract.test.ts +65 -0
  447. package/src/resources/extensions/gsd/tests/headless-milestone-parity.test.ts +7 -7
  448. package/src/resources/extensions/gsd/tests/hook-model-resolution.test.ts +5 -0
  449. package/src/resources/extensions/gsd/tests/infra-error.test.ts +2 -2
  450. package/src/resources/extensions/gsd/tests/infra-errors-cooldown.test.ts +9 -0
  451. package/src/resources/extensions/gsd/tests/integration/doctor-git.test.ts +44 -0
  452. package/src/resources/extensions/gsd/tests/integration/doctor-runtime.test.ts +20 -0
  453. package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +112 -1
  454. package/src/resources/extensions/gsd/tests/integration/integration-lifecycle.test.ts +13 -5
  455. package/src/resources/extensions/gsd/tests/integration/migrate-command.test.ts +48 -3
  456. package/src/resources/extensions/gsd/tests/integration/state-machine-runtime-failures.test.ts +6 -1
  457. package/src/resources/extensions/gsd/tests/journal-integration.test.ts +46 -0
  458. package/src/resources/extensions/gsd/tests/knowledge-backfill-projection.test.ts +323 -0
  459. package/src/resources/extensions/gsd/tests/knowledge-capture.test.ts +242 -0
  460. package/src/resources/extensions/gsd/tests/knowledge.test.ts +47 -2
  461. package/src/resources/extensions/gsd/tests/load-knowledge-block-rules-only.test.ts +209 -0
  462. package/src/resources/extensions/gsd/tests/memory-consolidation-scanner.test.ts +316 -0
  463. package/src/resources/extensions/gsd/tests/merge-db-cycle.test.ts +179 -0
  464. package/src/resources/extensions/gsd/tests/migrate-transformer.test.ts +5 -1
  465. package/src/resources/extensions/gsd/tests/migrate-validator-parsers.test.ts +24 -1
  466. package/src/resources/extensions/gsd/tests/migrate-writer-integration.test.ts +6 -1
  467. package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +26 -18
  468. package/src/resources/extensions/gsd/tests/native-git-bridge-exec-fallback.test.ts +63 -2
  469. package/src/resources/extensions/gsd/tests/orphaned-worktree-audit.test.ts +121 -1
  470. package/src/resources/extensions/gsd/tests/park-db-sync.test.ts +55 -1
  471. package/src/resources/extensions/gsd/tests/pending-autostart-scope.test.ts +29 -5
  472. package/src/resources/extensions/gsd/tests/pipeline-variant-dispatch.test.ts +2 -1
  473. package/src/resources/extensions/gsd/tests/plan-milestone-sketch-render.test.ts +157 -0
  474. package/src/resources/extensions/gsd/tests/plan-milestone.test.ts +26 -0
  475. package/src/resources/extensions/gsd/tests/plan-slice-prompt.test.ts +2 -0
  476. package/src/resources/extensions/gsd/tests/plan-slice.test.ts +251 -2
  477. package/src/resources/extensions/gsd/tests/plan-task.test.ts +17 -0
  478. package/src/resources/extensions/gsd/tests/post-exec-retry-bypass.test.ts +79 -1
  479. package/src/resources/extensions/gsd/tests/post-execution-checks.test.ts +86 -0
  480. package/src/resources/extensions/gsd/tests/post-unit-git-failure.test.ts +1 -1
  481. package/src/resources/extensions/gsd/tests/post-unit-state-rebuild.test.ts +84 -0
  482. package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +53 -0
  483. package/src/resources/extensions/gsd/tests/prefs-wizard-coverage.test.ts +59 -0
  484. package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +8 -0
  485. package/src/resources/extensions/gsd/tests/prompt-loader.test.ts +23 -0
  486. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +37 -1
  487. package/src/resources/extensions/gsd/tests/provider-switch-observer.test.ts +252 -0
  488. package/src/resources/extensions/gsd/tests/quality-gates.test.ts +6 -0
  489. package/src/resources/extensions/gsd/tests/queue-reorder-ui.test.ts +54 -0
  490. package/src/resources/extensions/gsd/tests/remediation-completion-guard.test.ts +89 -2
  491. package/src/resources/extensions/gsd/tests/run-uat-replay-cap.test.ts +2 -3
  492. package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +16 -4
  493. package/src/resources/extensions/gsd/tests/session-switch-abort-misclassification.test.ts +10 -0
  494. package/src/resources/extensions/gsd/tests/smart-entry-routing.test.ts +113 -0
  495. package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +53 -2
  496. package/src/resources/extensions/gsd/tests/state-corruption-2945.test.ts +6 -0
  497. package/src/resources/extensions/gsd/tests/state-reconciliation-drift.test.ts +119 -23
  498. package/src/resources/extensions/gsd/tests/status-guards.test.ts +13 -1
  499. package/src/resources/extensions/gsd/tests/stuck-state-via-db.test.ts +64 -1
  500. package/src/resources/extensions/gsd/tests/summary-render-parity.test.ts +7 -3
  501. package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +103 -7
  502. package/src/resources/extensions/gsd/tests/validate-milestone-stuck-guard.test.ts +29 -2
  503. package/src/resources/extensions/gsd/tests/verification-gate.test.ts +110 -1
  504. package/src/resources/extensions/gsd/tests/verification-verdict.test.ts +78 -0
  505. package/src/resources/extensions/gsd/tests/workflow-kernel.test.ts +7 -0
  506. package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +19 -1
  507. package/src/resources/extensions/gsd/tests/workflow-memory-pressure.test.ts +21 -1
  508. package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +1 -1
  509. package/src/resources/extensions/gsd/tests/worktree-git-pathspec.test.ts +39 -0
  510. package/src/resources/extensions/gsd/tests/worktree-journal-events.test.ts +64 -12
  511. package/src/resources/extensions/gsd/tests/worktree-lifecycle.test.ts +25 -0
  512. package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +54 -0
  513. package/src/resources/extensions/gsd/tools/complete-milestone.ts +8 -10
  514. package/src/resources/extensions/gsd/tools/complete-slice.ts +6 -8
  515. package/src/resources/extensions/gsd/tools/plan-milestone.ts +5 -1
  516. package/src/resources/extensions/gsd/tools/plan-slice.ts +97 -12
  517. package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +135 -0
  518. package/src/resources/extensions/gsd/types.ts +1 -1
  519. package/src/resources/extensions/gsd/unit-context-manifest.ts +47 -11
  520. package/src/resources/extensions/gsd/validation.ts +23 -1
  521. package/src/resources/extensions/gsd/verification-gate.ts +78 -6
  522. package/src/resources/extensions/gsd/verification-verdict.ts +47 -0
  523. package/src/resources/extensions/gsd/workflow-logger.ts +4 -0
  524. package/src/resources/extensions/gsd/workflow-mcp.ts +18 -1
  525. package/src/resources/extensions/gsd/workflow-projections.ts +6 -8
  526. package/src/resources/extensions/gsd/worktree-lifecycle.ts +61 -10
  527. package/src/resources/extensions/gsd/worktree-manager.ts +1 -1
  528. package/src/resources/extensions/shared/html-shell.ts +412 -0
  529. package/src/resources/extensions/subagent/index.ts +567 -103
  530. package/src/resources/extensions/subagent/launch.ts +131 -0
  531. package/src/resources/extensions/subagent/run-store.ts +218 -0
  532. package/src/resources/extensions/subagent/tests/launch.test.ts +115 -0
  533. package/src/resources/extensions/subagent/tests/run-store.test.ts +111 -0
  534. package/src/resources/extensions/ttsr/ttsr-manager.ts +5 -1
  535. package/src/resources/extensions/visual-brief/artifact-policy.ts +41 -0
  536. package/src/resources/extensions/visual-brief/extension-manifest.json +8 -0
  537. package/src/resources/extensions/visual-brief/index.ts +8 -0
  538. package/src/resources/extensions/visual-brief/page-contract.ts +136 -0
  539. package/src/resources/extensions/visual-brief/prompts.ts +183 -0
  540. package/src/resources/extensions/visual-brief/tests/visual-brief.test.ts +212 -0
  541. package/dist/web/standalone/.next/server/chunks/5822.js +0 -2
  542. package/dist/web/standalone/.next/static/chunks/2556.0527fea66e123b7f.js +0 -1
  543. package/dist/web/standalone/.next/static/chunks/8359.e059d86b255fce1c.js +0 -10
  544. package/dist/web/standalone/.next/static/chunks/9441.1081da1125d1764f.js +0 -1
  545. package/dist/web/standalone/.next/static/chunks/app/layout-9ecfd95f343793f0.js +0 -1
  546. package/dist/web/standalone/.next/static/css/54ec2745c1da488b.css +0 -1
  547. package/dist/web/standalone/.next/static/css/de70bee13400563f.css +0 -1
  548. package/dist/web/standalone/.next/static/media/4cf2300e9c8272f7-s.p.woff2 +0 -0
  549. package/dist/web/standalone/.next/static/media/747892c23ea88013-s.woff2 +0 -0
  550. package/dist/web/standalone/.next/static/media/8d697b304b401681-s.woff2 +0 -0
  551. package/dist/web/standalone/.next/static/media/93f479601ee12b01-s.p.woff2 +0 -0
  552. package/dist/web/standalone/.next/static/media/9610d9e46709d722-s.woff2 +0 -0
  553. package/dist/web/standalone/.next/static/media/ba015fad6dcf6784-s.woff2 +0 -0
  554. /package/dist/web/standalone/.next/static/{S44UQTFCUdA44dkjfYt6S → qoMxZh-xuwuvpFW0x0k01}/_buildManifest.js +0 -0
  555. /package/dist/web/standalone/.next/static/{S44UQTFCUdA44dkjfYt6S → qoMxZh-xuwuvpFW0x0k01}/_ssgManifest.js +0 -0
@@ -0,0 +1,241 @@
1
+ // GSD2 — KNOWLEDGE.md hybrid projection renderer (ADR-013 Stage 2b).
2
+ //
3
+ // Renders `.gsd/KNOWLEDGE.md` as a hybrid file:
4
+ // - Rules section: read directly from the existing KNOWLEDGE.md (manual,
5
+ // per ADR-013 line 39 — Rules are not migrated to memories).
6
+ // - Patterns section: read from `memories` where `category = "pattern"`
7
+ // AND `structured_fields.sourceKnowledgeId` is set (matches the marker
8
+ // written by knowledge-backfill.ts).
9
+ // - Lessons Learned section: read from `memories` where
10
+ // `category = "gotcha"` AND `structured_fields.sourceKnowledgeId` is set.
11
+ //
12
+ // Triggered opportunistically by `buildBeforeAgentStartResult` after the
13
+ // knowledge backfill runs. Output is byte-stable when nothing has changed
14
+ // (atomic write). The Rules section is preserved verbatim — including
15
+ // indentation, trailing whitespace, and comments — so manual edits to that
16
+ // section continue to round-trip through `/gsd knowledge`.
17
+ //
18
+ // Memories captured directly via `capture_thought` (without a
19
+ // `sourceKnowledgeId` marker) are intentionally NOT rendered into
20
+ // KNOWLEDGE.md. They remain accessible via the loadMemoryBlock auto-injection
21
+ // surface; KNOWLEDGE.md projects only the KNOWLEDGE.md-originating subset.
22
+
23
+ import { atomicWriteSync } from "./atomic-write.js";
24
+ import { _getAdapter, isDbAvailable } from "./gsd-db.js";
25
+ import {
26
+ KNOWLEDGE_SECTIONS,
27
+ knowledgeMdPath,
28
+ readKnowledgeMd,
29
+ } from "./knowledge-parser.js";
30
+ import { logWarning } from "./workflow-logger.js";
31
+
32
+ const RULES_HEADING = "## Rules";
33
+ const PATTERNS_HEADING = "## Patterns";
34
+ const LESSONS_HEADING = "## Lessons Learned";
35
+
36
+ const PATTERNS_HEADER = "| # | Pattern | Where | Notes |";
37
+ const PATTERNS_SEPARATOR = "|---|---------|-------|-------|";
38
+
39
+ const LESSONS_HEADER = "| # | What Happened | Root Cause | Fix | Scope |";
40
+ const LESSONS_SEPARATOR = "|---|--------------|------------|-----|-------|";
41
+
42
+ const DEFAULT_INTRO = [
43
+ "# Project Knowledge",
44
+ "",
45
+ "Append-only register of project-specific rules, patterns, and lessons learned.",
46
+ "Agents read this before every unit. Add entries when you discover something worth remembering.",
47
+ "",
48
+ ].join("\n");
49
+
50
+ interface KnowledgeMemoryRow {
51
+ sourceId: string;
52
+ structured: Record<string, unknown>;
53
+ }
54
+
55
+ interface KnowledgeMemoryReadResult {
56
+ ok: boolean;
57
+ rows: KnowledgeMemoryRow[];
58
+ }
59
+
60
+ export interface KnowledgeProjectionResult {
61
+ written: boolean;
62
+ content: string;
63
+ }
64
+
65
+ /**
66
+ * Read pattern memories that originated from KNOWLEDGE.md, ordered by
67
+ * `sourceKnowledgeId` (lexicographic — P001 < P002 < P010). Memories whose
68
+ * structuredFields fail to parse are skipped silently; they are diagnosed
69
+ * separately by the memory-consolidation scanner.
70
+ */
71
+ function readKnowledgeMemories(category: "pattern" | "gotcha"): KnowledgeMemoryReadResult {
72
+ if (!isDbAvailable()) return { ok: false, rows: [] };
73
+ const adapter = _getAdapter();
74
+ if (!adapter) return { ok: false, rows: [] };
75
+ try {
76
+ const rows = adapter
77
+ .prepare(
78
+ "SELECT structured_fields FROM memories WHERE category = :cat AND structured_fields IS NOT NULL",
79
+ )
80
+ .all({ ":cat": category }) as Array<{ structured_fields: string | null }>;
81
+
82
+ const out: KnowledgeMemoryRow[] = [];
83
+ for (const row of rows) {
84
+ if (!row.structured_fields) continue;
85
+ let sf: Record<string, unknown>;
86
+ try {
87
+ sf = JSON.parse(row.structured_fields) as Record<string, unknown>;
88
+ } catch {
89
+ continue;
90
+ }
91
+ const sourceId = sf["sourceKnowledgeId"];
92
+ if (typeof sourceId !== "string" || sourceId.length === 0) continue;
93
+ out.push({ sourceId, structured: sf });
94
+ }
95
+ // Lexicographic sort matches the docstring contract (P001 < P002 < P010).
96
+ // DB seq order is creation-time; sorting by sourceId stabilizes the
97
+ // rendered output across reruns.
98
+ out.sort((a, b) => a.sourceId.localeCompare(b.sourceId));
99
+ return { ok: true, rows: out };
100
+ } catch {
101
+ return { ok: false, rows: [] };
102
+ }
103
+ }
104
+
105
+ function escapeCell(value: string | undefined): string {
106
+ return (value ?? "")
107
+ .replace(/\s+/g, " ")
108
+ .replace(/\|/g, "\\|")
109
+ .trim();
110
+ }
111
+
112
+ function renderPatternsSection(memories: KnowledgeMemoryRow[]): string[] {
113
+ const lines = [PATTERNS_HEADING, "", PATTERNS_HEADER, PATTERNS_SEPARATOR];
114
+ for (const m of memories) {
115
+ const pattern = escapeCell(typeof m.structured["pattern"] === "string" ? (m.structured["pattern"] as string) : "");
116
+ const where = escapeCell(typeof m.structured["where"] === "string" ? (m.structured["where"] as string) : "");
117
+ const notes = escapeCell(typeof m.structured["notes"] === "string" ? (m.structured["notes"] as string) : "");
118
+ lines.push(`| ${m.sourceId} | ${pattern} | ${where || "—"} | ${notes || "—"} |`);
119
+ }
120
+ lines.push("");
121
+ return lines;
122
+ }
123
+
124
+ function renderLessonsSection(memories: KnowledgeMemoryRow[]): string[] {
125
+ const lines = [LESSONS_HEADING, "", LESSONS_HEADER, LESSONS_SEPARATOR];
126
+ for (const m of memories) {
127
+ const what = escapeCell(typeof m.structured["whatHappened"] === "string" ? (m.structured["whatHappened"] as string) : "");
128
+ const rootCause = escapeCell(typeof m.structured["rootCause"] === "string" ? (m.structured["rootCause"] as string) : "");
129
+ const fix = escapeCell(typeof m.structured["fix"] === "string" ? (m.structured["fix"] as string) : "");
130
+ const scope = escapeCell(typeof m.structured["scopeText"] === "string" ? (m.structured["scopeText"] as string) : "");
131
+ lines.push(`| ${m.sourceId} | ${what} | ${rootCause || "—"} | ${fix || "—"} | ${scope || "project"} |`);
132
+ }
133
+ lines.push("");
134
+ return lines;
135
+ }
136
+
137
+ /**
138
+ * Extract the Rules section (heading + table) from the existing
139
+ * `KNOWLEDGE.md` content, verbatim. Returns an empty default section
140
+ * (heading + empty table) when the source has no `## Rules` heading.
141
+ */
142
+ function extractRulesSection(existing: string): string[] {
143
+ const lines = existing.split("\n");
144
+ const startIdx = lines.findIndex((l) => l.trim() === RULES_HEADING);
145
+ if (startIdx === -1) {
146
+ return [
147
+ RULES_HEADING,
148
+ "",
149
+ "| # | Scope | Rule | Why | Added |",
150
+ "|---|-------|------|-----|-------|",
151
+ "",
152
+ ];
153
+ }
154
+
155
+ // Find the next H2 heading that ends the Rules section.
156
+ let endIdx = lines.length;
157
+ for (let i = startIdx + 1; i < lines.length; i++) {
158
+ if (lines[i]!.startsWith("## ")) {
159
+ endIdx = i;
160
+ break;
161
+ }
162
+ }
163
+
164
+ // Strip trailing blank lines from the captured slice — the assembled
165
+ // output adds its own separator blank line between sections.
166
+ const slice = lines.slice(startIdx, endIdx);
167
+ while (slice.length > 0 && slice[slice.length - 1]!.trim() === "") {
168
+ slice.pop();
169
+ }
170
+ slice.push("");
171
+ return slice;
172
+ }
173
+
174
+ /**
175
+ * Extract the intro prose (anything before `## Rules`) verbatim, preserving
176
+ * any title (`# Project Knowledge`), comments, and description text. Falls
177
+ * back to the `DEFAULT_INTRO` template when the source has no Rules heading
178
+ * yet.
179
+ */
180
+ function extractIntro(existing: string): string {
181
+ if (!existing.trim()) return DEFAULT_INTRO;
182
+ const lines = existing.split("\n");
183
+ const rulesIdx = lines.findIndex((l) => l.trim() === RULES_HEADING);
184
+ if (rulesIdx === -1) return DEFAULT_INTRO;
185
+ // Trim trailing blank lines so the assembly adds its own separator.
186
+ const slice = lines.slice(0, rulesIdx);
187
+ while (slice.length > 0 && slice[slice.length - 1]!.trim() === "") {
188
+ slice.pop();
189
+ }
190
+ slice.push("");
191
+ return slice.join("\n");
192
+ }
193
+
194
+ /**
195
+ * Render the hybrid `KNOWLEDGE.md`: manual Rules + projected Patterns +
196
+ * projected Lessons. Returns the rendered content and a flag indicating
197
+ * whether the file was written (skipped when content is byte-identical to
198
+ * what's on disk).
199
+ *
200
+ * Best-effort: catches all errors and returns `{ written: false, content: "" }`.
201
+ */
202
+ export function renderKnowledgeProjection(basePath: string): KnowledgeProjectionResult {
203
+ try {
204
+ const existing = readKnowledgeMd(basePath);
205
+ const intro = extractIntro(existing);
206
+ const rules = extractRulesSection(existing);
207
+ const patternMemories = readKnowledgeMemories("pattern");
208
+ const lessonMemories = readKnowledgeMemories("gotcha");
209
+ if (!patternMemories.ok || !lessonMemories.ok) {
210
+ return { written: false, content: existing };
211
+ }
212
+ const patterns = renderPatternsSection(patternMemories.rows);
213
+ const lessons = renderLessonsSection(lessonMemories.rows);
214
+
215
+ const introText = intro
216
+ .replace(/\n{3,}/g, "\n\n")
217
+ .replace(/\s+$/g, "");
218
+ const projectedText = [...patterns, ...lessons]
219
+ .join("\n")
220
+ .replace(/\n{3,}/g, "\n\n")
221
+ .replace(/\s+$/g, "");
222
+ const content = [introText, rules.join("\n"), projectedText]
223
+ .join("\n")
224
+ .replace(/\s+$/g, "")
225
+ + "\n";
226
+
227
+ if (content === existing) {
228
+ return { written: false, content };
229
+ }
230
+
231
+ atomicWriteSync(knowledgeMdPath(basePath), content, "utf-8");
232
+ return { written: true, content };
233
+ } catch (e) {
234
+ logWarning("renderer", `KNOWLEDGE.md projection render failed: ${(e as Error).message}`);
235
+ return { written: false, content: "" };
236
+ }
237
+ }
238
+
239
+ // Re-export the section headings so tests can assert on the canonical
240
+ // structure without re-defining the strings.
241
+ export { KNOWLEDGE_SECTIONS };
@@ -32,7 +32,7 @@ import {
32
32
  resolveMilestoneFile,
33
33
  resolveSliceFile,
34
34
  resolveSlicePath,
35
- resolveTasksDir,
35
+ gsdProjectionRoot,
36
36
  gsdRoot,
37
37
  buildTaskFileName,
38
38
  buildSliceFileName,
@@ -48,7 +48,11 @@ import { clearPathCache } from "./paths.js";
48
48
  * E.g. "/project/.gsd/milestones/M001/M001-ROADMAP.md" → "milestones/M001/M001-ROADMAP.md"
49
49
  */
50
50
  function toArtifactPath(absPath: string, basePath: string): string {
51
- const root = gsdRoot(basePath);
51
+ const projectionRoot = gsdProjectionRoot(basePath);
52
+ const projectionRel = relative(projectionRoot, absPath);
53
+ const root = projectionRel && !projectionRel.startsWith("..") && !projectionRel.startsWith("/")
54
+ ? projectionRoot
55
+ : gsdRoot(basePath);
52
56
  const rel = relative(root, absPath);
53
57
  // Normalize to forward slashes for consistent DB keys
54
58
  return rel.replace(/\\/g, "/");
@@ -157,7 +161,12 @@ function renderRoadmapMarkdown(milestone: MilestoneRow, slices: SliceRow[]): str
157
161
  for (const slice of slices) {
158
162
  const done = isClosedStatus(slice.status) ? "x" : " ";
159
163
  const depends = `[${(slice.depends ?? []).join(",")}]`;
160
- lines.push(`- [${done}] **${slice.id}: ${slice.title}** \`risk:${slice.risk}\` \`depends:${depends}\``);
164
+ // ADR-011: sketch slices get a `[sketch]` badge so the roadmap shows at a
165
+ // glance which slices are still pending refine-slice expansion. The badge
166
+ // sits in front of `risk:` so it's visible in narrow terminals that may
167
+ // truncate the line.
168
+ const sketchBadge = slice.is_sketch === 1 ? "`[sketch]` " : "";
169
+ lines.push(`- [${done}] **${slice.id}: ${slice.title}** ${sketchBadge}\`risk:${slice.risk}\` \`depends:${depends}\``);
161
170
  lines.push(` > After this: ${slice.demo}`);
162
171
  lines.push("");
163
172
  }
@@ -369,10 +378,9 @@ export async function renderPlanFromDb(
369
378
  throw new Error(`no tasks found for ${milestoneId}/${sliceId}`);
370
379
  }
371
380
 
372
- const slicePath = resolveSlicePath(basePath, milestoneId, sliceId)
373
- ?? join(gsdRoot(basePath), "milestones", milestoneId, "slices", sliceId);
374
- const absPath = resolveSliceFile(basePath, milestoneId, sliceId, "PLAN")
375
- ?? join(slicePath, `${sliceId}-PLAN.md`);
381
+ const slicePath = join(gsdProjectionRoot(basePath), "milestones", milestoneId, "slices", sliceId);
382
+ mkdirSync(slicePath, { recursive: true });
383
+ const absPath = join(slicePath, `${sliceId}-PLAN.md`);
376
384
  const artifactPath = toArtifactPath(absPath, basePath);
377
385
  const sliceGates = getGateResults(milestoneId, sliceId, "slice");
378
386
  const content = renderSlicePlanMarkdown(slice, tasks, sliceGates);
@@ -403,8 +411,7 @@ export async function renderTaskPlanFromDb(
403
411
  throw new Error(`task ${milestoneId}/${sliceId}/${taskId} not found`);
404
412
  }
405
413
 
406
- const tasksDir = resolveTasksDir(basePath, milestoneId, sliceId)
407
- ?? join(gsdRoot(basePath), "milestones", milestoneId, "slices", sliceId, "tasks");
414
+ const tasksDir = join(gsdProjectionRoot(basePath), "milestones", milestoneId, "slices", sliceId, "tasks");
408
415
  mkdirSync(tasksDir, { recursive: true });
409
416
  const absPath = join(tasksDir, buildTaskFileName(taskId, "PLAN"));
410
417
  const artifactPath = toArtifactPath(absPath, basePath);
@@ -306,7 +306,7 @@ function importRequirements(gsdDir: string): number {
306
306
  // ─── Hierarchy Artifact Walker ─────────────────────────────────────────────
307
307
 
308
308
  /** Artifact suffixes to look for at each hierarchy level */
309
- const MILESTONE_SUFFIXES = ['ROADMAP', 'CONTEXT', 'RESEARCH', 'ASSESSMENT'];
309
+ const MILESTONE_SUFFIXES = ['ROADMAP', 'CONTEXT', 'RESEARCH', 'ASSESSMENT', 'SUMMARY', 'VALIDATION'];
310
310
  const SLICE_SUFFIXES = ['PLAN', 'SUMMARY', 'RESEARCH', 'CONTEXT', 'ASSESSMENT', 'UAT'];
311
311
  const TASK_SUFFIXES = ['PLAN', 'SUMMARY', 'CONTINUE', 'CONTEXT', 'RESEARCH'];
312
312
 
@@ -1,9 +1,10 @@
1
1
  // GSD2 — Decisions -> memories backfill (ADR-013 step 5)
2
2
  //
3
- // Idempotent one-shot migration that copies every active decisions row into
4
- // the memories table with category="architecture" and a structured_fields
5
- // payload preserving the original gsd_save_decision schema (when_context,
6
- // scope, decision, choice, rationale, made_by, revisable, sourceDecisionId).
3
+ // Idempotent migration that copies every decisions row (active and
4
+ // superseded — see Stage 2a note below) into the memories table with
5
+ // category="architecture" and a structured_fields payload preserving the
6
+ // original gsd_save_decision schema (when_context, scope, decision, choice,
7
+ // rationale, made_by, revisable, superseded_by, sourceDecisionId).
7
8
  //
8
9
  // The backfill exists so the cutover in ADR-013 step 6 can drop the
9
10
  // decisions table without losing schema fidelity. Idempotency is enforced
@@ -14,6 +15,13 @@
14
15
  // only ever fires once per project. Costs O(N) inserts on first run where
15
16
  // N is the active-decisions count; subsequent runs are an O(N) lookup that
16
17
  // finds existing markers and exits.
18
+ //
19
+ // ADR-013 Stage 2a (PR #5755): backfill now includes superseded rows so the
20
+ // DECISIONS.md projection regen can source from memories without losing
21
+ // historical entries. An auto-heal pass runs after the initial migration to
22
+ // pick up superseded_by changes that occurred after the source decision was
23
+ // already migrated (e.g. a fresh md-importer run that introduced a new
24
+ // supersedes-chain).
17
25
 
18
26
  import { isDbAvailable, _getAdapter } from "./gsd-db.js";
19
27
  import { createMemory } from "./memory-store.js";
@@ -31,8 +39,10 @@ interface DecisionRow {
31
39
  superseded_by: string | null;
32
40
  }
33
41
 
42
+ type DecisionContentFields = Pick<DecisionRow, "decision" | "choice" | "rationale">;
43
+
34
44
  /**
35
- * Backfill active decisions rows into the memories table.
45
+ * Backfill decisions rows into the memories table.
36
46
  *
37
47
  * - Idempotent (per-row): every row written carries
38
48
  * `structured_fields.sourceDecisionId = "<decisionId>"`. Each candidate
@@ -41,13 +51,18 @@ interface DecisionRow {
41
51
  * their own `sourceDecisionId` does NOT abort the backfill.
42
52
  * - Best-effort: never throws. Logs and returns 0 on failure so a broken
43
53
  * backfill cannot block agent startup.
44
- * - Active-only: skips rows where `superseded_by IS NOT NULL`. Superseded
45
- * decisions are historical record; the memory store is for active
46
- * knowledge.
54
+ * - Full migration (ADR-013 Stage 2a): both active and superseded rows are
55
+ * migrated. `structured_fields.superseded_by` preserves the supersedes
56
+ * chain so the DECISIONS.md projection regen can source from memories
57
+ * without losing historical entries.
58
+ * - Drift auto-heal: after the initial insert pass, the function updates
59
+ * any pre-existing memory whose `structured_fields.superseded_by` drifted
60
+ * from the source decision (e.g. a fresh md-importer run introduced a
61
+ * new supersedes annotation after the initial migration).
47
62
  *
48
63
  * Returns the number of memories written (0 when already backfilled or
49
- * when the DB has no decisions). Callers can log the result or surface it
50
- * to the user.
64
+ * when the DB has no decisions). Drift-heal updates are not counted in
65
+ * this return — they are logged separately.
51
66
  */
52
67
  export function backfillDecisionsToMemories(): number {
53
68
  if (!isDbAvailable()) return 0;
@@ -56,7 +71,7 @@ export function backfillDecisionsToMemories(): number {
56
71
 
57
72
  try {
58
73
  const decisions = adapter
59
- .prepare("SELECT id, when_context, scope, decision, choice, rationale, made_by, revisable, superseded_by FROM decisions WHERE superseded_by IS NULL")
74
+ .prepare("SELECT id, when_context, scope, decision, choice, rationale, made_by, revisable, superseded_by FROM decisions ORDER BY seq")
60
75
  .all() as Array<Record<string, unknown>>;
61
76
 
62
77
  if (decisions.length === 0) return 0;
@@ -67,10 +82,14 @@ export function backfillDecisionsToMemories(): number {
67
82
  // sentinel would silently abort the backfill if a user manually called
68
83
  // capture_thought with their own structuredFields.sourceDecisionId.
69
84
  const checkExisting = adapter.prepare(
70
- "SELECT 1 FROM memories WHERE structured_fields LIKE :pattern LIMIT 1",
85
+ "SELECT id, structured_fields FROM memories WHERE structured_fields LIKE :pattern LIMIT 1",
86
+ );
87
+ const updateStructuredFields = adapter.prepare(
88
+ "UPDATE memories SET structured_fields = :sf, updated_at = :ts WHERE id = :id",
71
89
  );
72
90
 
73
91
  let written = 0;
92
+ let healed = 0;
74
93
  for (const raw of decisions) {
75
94
  const row: DecisionRow = {
76
95
  id: String(raw["id"] ?? ""),
@@ -85,11 +104,48 @@ export function backfillDecisionsToMemories(): number {
85
104
  };
86
105
  if (!row.id) continue;
87
106
 
88
- // Pattern is anchored to the JSON-stringified shape and the exact
89
- // decision id to avoid prefix collisions (e.g. "D1" vs "D10").
90
- if (checkExisting.get({ ":pattern": `%"sourceDecisionId":"${row.id}"%` })) continue;
107
+ const pattern = `%"sourceDecisionId":"${row.id}"%`;
108
+ const existing = checkExisting.get({ ":pattern": pattern }) as
109
+ | { id: string; structured_fields: string | null }
110
+ | undefined;
91
111
 
92
- const content = synthesizeContent(row);
112
+ if (existing) {
113
+ // Drift auto-heal: if the source decision's superseded_by has changed
114
+ // since the original migration, update the memory in place. Read-side
115
+ // queries reconstruct Decision.superseded_by from this field, so the
116
+ // DECISIONS.md projection stays accurate without us having to track
117
+ // supersedes events at the write site.
118
+ const parsedSf = existing.structured_fields
119
+ ? safeParse(existing.structured_fields)
120
+ : {};
121
+ if (existing.structured_fields && !parsedSf) {
122
+ logWarning(
123
+ "memory-backfill",
124
+ `decisions->memories drift heal skipped for ${row.id}: invalid structured_fields JSON`,
125
+ );
126
+ continue;
127
+ }
128
+ const currentSf = parsedSf ?? {};
129
+ const memorySuperseded =
130
+ typeof currentSf["superseded_by"] === "string" || currentSf["superseded_by"] === null
131
+ ? (currentSf["superseded_by"] as string | null | undefined)
132
+ : null;
133
+ if (memorySuperseded !== row.superseded_by) {
134
+ const merged = {
135
+ ...currentSf,
136
+ superseded_by: row.superseded_by,
137
+ };
138
+ updateStructuredFields.run({
139
+ ":id": existing.id,
140
+ ":sf": JSON.stringify(merged),
141
+ ":ts": new Date().toISOString(),
142
+ });
143
+ healed += 1;
144
+ }
145
+ continue;
146
+ }
147
+
148
+ const content = synthesizeDecisionMemoryContent(row);
93
149
  const id = createMemory({
94
150
  category: "architecture",
95
151
  content,
@@ -104,11 +160,19 @@ export function backfillDecisionsToMemories(): number {
104
160
  rationale: row.rationale,
105
161
  made_by: row.made_by,
106
162
  revisable: row.revisable,
163
+ superseded_by: row.superseded_by,
107
164
  },
108
165
  });
109
166
  if (id) written += 1;
110
167
  }
111
168
 
169
+ if (healed > 0) {
170
+ logWarning(
171
+ "memory-backfill",
172
+ `decisions->memories drift healed: ${healed} row${healed === 1 ? "" : "s"} updated superseded_by`,
173
+ );
174
+ }
175
+
112
176
  return written;
113
177
  } catch (e) {
114
178
  logWarning("memory-backfill", `decisions->memories backfill failed: ${(e as Error).message}`);
@@ -116,6 +180,14 @@ export function backfillDecisionsToMemories(): number {
116
180
  }
117
181
  }
118
182
 
183
+ function safeParse(raw: string): Record<string, unknown> | null {
184
+ try {
185
+ return JSON.parse(raw) as Record<string, unknown>;
186
+ } catch {
187
+ return null;
188
+ }
189
+ }
190
+
119
191
  /**
120
192
  * Combine the decision's structured fields into a 1-3 sentence content
121
193
  * string suitable for keyword retrieval and human review.
@@ -124,7 +196,7 @@ export function backfillDecisionsToMemories(): number {
124
196
  * Truncates each field to keep the synthesized line under ~600 chars so
125
197
  * memory_query rendering stays readable.
126
198
  */
127
- function synthesizeContent(row: DecisionRow): string {
199
+ export function synthesizeDecisionMemoryContent(row: DecisionContentFields): string {
128
200
  const trim = (value: string, max: number): string => {
129
201
  const cleaned = value.replace(/\s+/g, " ").trim();
130
202
  return cleaned.length > max ? cleaned.slice(0, max - 1) + "\u2026" : cleaned;