gsd-pi 2.81.0 → 2.82.0-dev.725028083

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 (482) hide show
  1. package/README.md +60 -30
  2. package/dist/resources/.managed-resources-content-hash +1 -1
  3. package/dist/resources/extensions/browser-tools/tools/screenshot.js +1 -0
  4. package/dist/resources/extensions/browser-tools/tools/zoom.js +1 -0
  5. package/dist/resources/extensions/gsd/auto/loop.js +111 -8
  6. package/dist/resources/extensions/gsd/auto/phases.js +199 -97
  7. package/dist/resources/extensions/gsd/auto/run-unit.js +66 -3
  8. package/dist/resources/extensions/gsd/auto/session.js +9 -0
  9. package/dist/resources/extensions/gsd/auto/verification-retry-policy.js +43 -0
  10. package/dist/resources/extensions/gsd/auto-dashboard.js +182 -178
  11. package/dist/resources/extensions/gsd/auto-dispatch.js +14 -11
  12. package/dist/resources/extensions/gsd/auto-post-unit.js +7 -1
  13. package/dist/resources/extensions/gsd/auto-prompts.js +11 -3
  14. package/dist/resources/extensions/gsd/auto-recovery.js +6 -181
  15. package/dist/resources/extensions/gsd/auto-runtime-state.js +5 -0
  16. package/dist/resources/extensions/gsd/auto-start.js +20 -23
  17. package/dist/resources/extensions/gsd/auto-unit-closeout.js +33 -5
  18. package/dist/resources/extensions/gsd/auto-verification.js +12 -6
  19. package/dist/resources/extensions/gsd/auto-worktree.js +8 -0
  20. package/dist/resources/extensions/gsd/auto.js +265 -76
  21. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +13 -6
  22. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +13 -2
  23. package/dist/resources/extensions/gsd/bootstrap/register-shortcuts.js +4 -8
  24. package/dist/resources/extensions/gsd/bootstrap/system-context.js +55 -12
  25. package/dist/resources/extensions/gsd/commands/handlers/core.js +1 -1
  26. package/dist/resources/extensions/gsd/commands/handlers/notifications-handler.js +4 -10
  27. package/dist/resources/extensions/gsd/commands/handlers/parallel.js +9 -0
  28. package/dist/resources/extensions/gsd/commands-handlers.js +15 -2
  29. package/dist/resources/extensions/gsd/context-store.js +112 -0
  30. package/dist/resources/extensions/gsd/db-writer.js +150 -84
  31. package/dist/resources/extensions/gsd/docs/preferences-reference.md +1 -1
  32. package/dist/resources/extensions/gsd/doctor-git-checks.js +41 -6
  33. package/dist/resources/extensions/gsd/git-service.js +2 -1
  34. package/dist/resources/extensions/gsd/gsd-db.js +7 -23
  35. package/dist/resources/extensions/gsd/health-widget-core.js +1 -1
  36. package/dist/resources/extensions/gsd/health-widget.js +4 -10
  37. package/dist/resources/extensions/gsd/knowledge-backfill.js +144 -0
  38. package/dist/resources/extensions/gsd/knowledge-capture.js +136 -0
  39. package/dist/resources/extensions/gsd/knowledge-parser.js +154 -0
  40. package/dist/resources/extensions/gsd/knowledge-projection.js +210 -0
  41. package/dist/resources/extensions/gsd/markdown-renderer.js +6 -96
  42. package/dist/resources/extensions/gsd/memory-backfill.js +73 -17
  43. package/dist/resources/extensions/gsd/memory-consolidation-scanner.js +222 -0
  44. package/dist/resources/extensions/gsd/native-git-bridge.js +14 -14
  45. package/dist/resources/extensions/gsd/notification-overlay.js +35 -40
  46. package/dist/resources/extensions/gsd/parallel-merge.js +53 -30
  47. package/dist/resources/extensions/gsd/parallel-monitor-overlay.js +25 -33
  48. package/dist/resources/extensions/gsd/prompts/complete-slice.md +14 -12
  49. package/dist/resources/extensions/gsd/prompts/discuss-headless.md +20 -2
  50. package/dist/resources/extensions/gsd/prompts/discuss.md +20 -2
  51. package/dist/resources/extensions/gsd/prompts/system.md +2 -2
  52. package/dist/resources/extensions/gsd/provider-switch-observer.js +146 -0
  53. package/dist/resources/extensions/gsd/recovery-classification.js +15 -1
  54. package/dist/resources/extensions/gsd/session-lock.js +40 -0
  55. package/dist/resources/extensions/gsd/state-reconciliation/drift/completion.js +131 -0
  56. package/dist/resources/extensions/gsd/state-reconciliation/drift/merge-state.js +247 -0
  57. package/dist/resources/extensions/gsd/state-reconciliation/drift/project-md.js +50 -0
  58. package/dist/resources/extensions/gsd/state-reconciliation/drift/roadmap.js +87 -0
  59. package/dist/resources/extensions/gsd/state-reconciliation/drift/sketch-flag.js +50 -0
  60. package/dist/resources/extensions/gsd/state-reconciliation/drift/stale-render.js +124 -0
  61. package/dist/resources/extensions/gsd/state-reconciliation/drift/stale-worker.js +32 -0
  62. package/dist/resources/extensions/gsd/state-reconciliation/errors.js +41 -0
  63. package/dist/resources/extensions/gsd/state-reconciliation/index.js +99 -0
  64. package/dist/resources/extensions/gsd/state-reconciliation/registry.js +24 -0
  65. package/dist/resources/extensions/gsd/state-reconciliation/spawn-gate.js +43 -0
  66. package/dist/resources/extensions/gsd/state-reconciliation/types.js +3 -0
  67. package/dist/resources/extensions/gsd/state-reconciliation.js +5 -26
  68. package/dist/resources/extensions/gsd/templates/knowledge.md +2 -2
  69. package/dist/resources/extensions/gsd/tui/render-kit.js +74 -0
  70. package/dist/resources/extensions/gsd/watch/header-renderer.js +92 -69
  71. package/dist/resources/extensions/gsd/watch/splash-palette.js +10 -0
  72. package/dist/resources/extensions/gsd/workflow-mcp.js +2 -2
  73. package/dist/resources/extensions/gsd/worktree-lifecycle.js +722 -316
  74. package/dist/resources/extensions/gsd/worktree-telemetry.js +3 -1
  75. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  76. package/dist/web/standalone/.next/BUILD_ID +1 -1
  77. package/dist/web/standalone/.next/app-path-routes-manifest.json +15 -15
  78. package/dist/web/standalone/.next/build-manifest.json +3 -3
  79. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  80. package/dist/web/standalone/.next/required-server-files.json +3 -3
  81. package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
  82. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  83. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  84. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  85. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  86. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  87. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  88. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  89. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  90. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  91. package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
  92. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  93. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  94. package/dist/web/standalone/.next/server/app/_not-found.rsc +3 -3
  95. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
  96. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  97. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +3 -3
  98. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  99. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  100. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  101. package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
  102. package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
  103. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
  104. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
  105. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
  106. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
  107. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
  108. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
  109. package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
  110. package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
  111. package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
  112. package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
  113. package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
  114. package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
  115. package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
  116. package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
  117. package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
  118. package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
  119. package/dist/web/standalone/.next/server/app/api/experimental/route.js +2 -2
  120. package/dist/web/standalone/.next/server/app/api/experimental/route_client-reference-manifest.js +1 -1
  121. package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
  122. package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
  123. package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
  124. package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
  125. package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
  126. package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
  127. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  128. package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  129. package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
  130. package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
  131. package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
  132. package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
  133. package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
  134. package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
  135. package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
  136. package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
  137. package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
  138. package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
  139. package/dist/web/standalone/.next/server/app/api/notifications/route.js +2 -2
  140. package/dist/web/standalone/.next/server/app/api/notifications/route_client-reference-manifest.js +1 -1
  141. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  142. package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
  143. package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
  144. package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
  145. package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
  146. package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  147. package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
  148. package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
  149. package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +2 -2
  150. package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
  151. package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
  152. package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
  153. package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
  154. package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
  155. package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
  156. package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
  157. package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
  158. package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
  159. package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
  160. package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
  161. package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
  162. package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
  163. package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
  164. package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
  165. package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
  166. package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
  167. package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
  168. package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
  169. package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +1 -1
  170. package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
  171. package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
  172. package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
  173. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +1 -1
  174. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
  175. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +2 -2
  176. package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
  177. package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
  178. package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
  179. package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
  180. package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
  181. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  182. package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  183. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  184. package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
  185. package/dist/web/standalone/.next/server/app/index.html +1 -1
  186. package/dist/web/standalone/.next/server/app/index.rsc +4 -4
  187. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  188. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +4 -4
  189. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  190. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +3 -3
  191. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  192. package/dist/web/standalone/.next/server/app/page.js +2 -2
  193. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  194. package/dist/web/standalone/.next/server/app-paths-manifest.json +15 -15
  195. package/dist/web/standalone/.next/server/chunks/63.js +3 -3
  196. package/dist/web/standalone/.next/server/chunks/6897.js +1 -1
  197. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  198. package/dist/web/standalone/.next/server/middleware.js +2 -2
  199. package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
  200. package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
  201. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  202. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  203. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  204. package/dist/web/standalone/.next/static/chunks/app/_not-found/{page-2f24283c162b6ab3.js → page-f2a7482d42a5614b.js} +1 -1
  205. package/dist/web/standalone/.next/static/chunks/app/{layout-9ecfd95f343793f0.js → layout-a16c7a7ecdf0c2cf.js} +1 -1
  206. package/dist/web/standalone/.next/static/chunks/app/page-752f1e2ebdaa3e45.js +1 -0
  207. package/dist/web/standalone/.next/static/chunks/main-app-fdab67f7802d7832.js +1 -0
  208. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +1 -0
  209. package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
  210. package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
  211. package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
  212. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api.target.mk +14 -14
  213. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_except.target.mk +14 -14
  214. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_maybe.target.mk +14 -14
  215. package/dist/web/standalone/server.js +1 -1
  216. package/dist/welcome-screen.d.ts +0 -7
  217. package/dist/welcome-screen.js +60 -69
  218. package/package.json +3 -2
  219. package/packages/daemon/package.json +2 -2
  220. package/packages/mcp-server/README.md +2 -0
  221. package/packages/mcp-server/package.json +2 -2
  222. package/packages/mcp-server/src/workflow-tools-parity.test.ts +244 -0
  223. package/packages/native/package.json +1 -1
  224. package/packages/pi-agent-core/package.json +1 -1
  225. package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -1
  226. package/packages/pi-ai/dist/index.d.ts +2 -2
  227. package/packages/pi-ai/dist/index.d.ts.map +1 -1
  228. package/packages/pi-ai/dist/index.js +1 -1
  229. package/packages/pi-ai/dist/index.js.map +1 -1
  230. package/packages/pi-ai/dist/providers/transform-messages.d.ts +11 -0
  231. package/packages/pi-ai/dist/providers/transform-messages.d.ts.map +1 -1
  232. package/packages/pi-ai/dist/providers/transform-messages.js +20 -0
  233. package/packages/pi-ai/dist/providers/transform-messages.js.map +1 -1
  234. package/packages/pi-ai/package.json +1 -1
  235. package/packages/pi-ai/src/index.ts +7 -2
  236. package/packages/pi-ai/src/providers/transform-messages.ts +24 -0
  237. package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
  238. package/packages/pi-coding-agent/dist/core/system-prompt.js +4 -4
  239. package/packages/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
  240. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/assistant-message-design.test.d.ts +2 -0
  241. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/assistant-message-design.test.d.ts.map +1 -0
  242. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/assistant-message-design.test.js +47 -0
  243. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/assistant-message-design.test.js.map +1 -0
  244. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js +76 -9
  245. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js.map +1 -1
  246. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/user-message-design.test.d.ts +2 -0
  247. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/user-message-design.test.d.ts.map +1 -0
  248. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/user-message-design.test.js +40 -0
  249. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/user-message-design.test.js.map +1 -0
  250. package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.d.ts +0 -1
  251. package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.d.ts.map +1 -1
  252. package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.js +30 -29
  253. package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.js.map +1 -1
  254. package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.test.js +10 -3
  255. package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.test.js.map +1 -1
  256. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  257. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js +13 -13
  258. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js.map +1 -1
  259. package/packages/pi-coding-agent/dist/modes/interactive/components/bash-execution.d.ts +1 -3
  260. package/packages/pi-coding-agent/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
  261. package/packages/pi-coding-agent/dist/modes/interactive/components/bash-execution.js +58 -3
  262. package/packages/pi-coding-agent/dist/modes/interactive/components/bash-execution.js.map +1 -1
  263. package/packages/pi-coding-agent/dist/modes/interactive/components/diff.d.ts +2 -2
  264. package/packages/pi-coding-agent/dist/modes/interactive/components/diff.d.ts.map +1 -1
  265. package/packages/pi-coding-agent/dist/modes/interactive/components/diff.js +12 -6
  266. package/packages/pi-coding-agent/dist/modes/interactive/components/diff.js.map +1 -1
  267. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.d.ts.map +1 -1
  268. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js +14 -41
  269. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js.map +1 -1
  270. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts +0 -1
  271. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  272. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +86 -82
  273. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
  274. package/packages/pi-coding-agent/dist/modes/interactive/components/transcript-design.d.ts +35 -0
  275. package/packages/pi-coding-agent/dist/modes/interactive/components/transcript-design.d.ts.map +1 -0
  276. package/packages/pi-coding-agent/dist/modes/interactive/components/transcript-design.js +152 -0
  277. package/packages/pi-coding-agent/dist/modes/interactive/components/transcript-design.js.map +1 -0
  278. package/packages/pi-coding-agent/dist/modes/interactive/components/tui-style-kit.d.ts +16 -0
  279. package/packages/pi-coding-agent/dist/modes/interactive/components/tui-style-kit.d.ts.map +1 -0
  280. package/packages/pi-coding-agent/dist/modes/interactive/components/tui-style-kit.js +73 -0
  281. package/packages/pi-coding-agent/dist/modes/interactive/components/tui-style-kit.js.map +1 -0
  282. package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.d.ts +1 -1
  283. package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.d.ts.map +1 -1
  284. package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.js +12 -8
  285. package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.js.map +1 -1
  286. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-highlight.test.d.ts +2 -0
  287. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-highlight.test.d.ts.map +1 -0
  288. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-highlight.test.js +17 -0
  289. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-highlight.test.js.map +1 -0
  290. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  291. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.js +105 -1
  292. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.js.map +1 -1
  293. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.d.ts.map +1 -1
  294. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js +27 -26
  295. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js.map +1 -1
  296. package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.test.js +9 -6
  297. package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.test.js.map +1 -1
  298. package/packages/pi-coding-agent/dist/tests/system-prompt-file-safety.test.d.ts +2 -0
  299. package/packages/pi-coding-agent/dist/tests/system-prompt-file-safety.test.d.ts.map +1 -0
  300. package/packages/pi-coding-agent/dist/tests/system-prompt-file-safety.test.js +17 -0
  301. package/packages/pi-coding-agent/dist/tests/system-prompt-file-safety.test.js.map +1 -0
  302. package/packages/pi-coding-agent/package.json +1 -1
  303. package/packages/pi-coding-agent/src/core/system-prompt.ts +4 -4
  304. package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/assistant-message-design.test.ts +56 -0
  305. package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/tool-execution.test.ts +113 -9
  306. package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/user-message-design.test.ts +48 -0
  307. package/packages/pi-coding-agent/src/modes/interactive/components/adaptive-layout.test.ts +10 -3
  308. package/packages/pi-coding-agent/src/modes/interactive/components/adaptive-layout.ts +43 -42
  309. package/packages/pi-coding-agent/src/modes/interactive/components/assistant-message.ts +14 -14
  310. package/packages/pi-coding-agent/src/modes/interactive/components/bash-execution.ts +64 -3
  311. package/packages/pi-coding-agent/src/modes/interactive/components/diff.ts +13 -7
  312. package/packages/pi-coding-agent/src/modes/interactive/components/footer.ts +15 -42
  313. package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +84 -104
  314. package/packages/pi-coding-agent/src/modes/interactive/components/transcript-design.ts +196 -0
  315. package/packages/pi-coding-agent/src/modes/interactive/components/tui-style-kit.ts +94 -0
  316. package/packages/pi-coding-agent/src/modes/interactive/components/user-message.ts +14 -9
  317. package/packages/pi-coding-agent/src/modes/interactive/theme/theme-highlight.test.ts +23 -0
  318. package/packages/pi-coding-agent/src/modes/interactive/theme/theme.ts +106 -1
  319. package/packages/pi-coding-agent/src/modes/interactive/theme/themes.ts +27 -26
  320. package/packages/pi-coding-agent/src/modes/interactive/tui-mode.test.ts +9 -6
  321. package/packages/pi-coding-agent/src/tests/system-prompt-file-safety.test.ts +22 -0
  322. package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
  323. package/packages/pi-tui/dist/__tests__/overlay-layout.test.js +14 -1
  324. package/packages/pi-tui/dist/__tests__/overlay-layout.test.js.map +1 -1
  325. package/packages/pi-tui/dist/overlay-layout.d.ts.map +1 -1
  326. package/packages/pi-tui/dist/overlay-layout.js +9 -6
  327. package/packages/pi-tui/dist/overlay-layout.js.map +1 -1
  328. package/packages/pi-tui/package.json +1 -1
  329. package/packages/pi-tui/src/__tests__/overlay-layout.test.ts +20 -1
  330. package/packages/pi-tui/src/overlay-layout.ts +10 -7
  331. package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
  332. package/packages/rpc-client/package.json +1 -1
  333. package/pkg/dist/modes/interactive/theme/theme-highlight.test.d.ts +2 -0
  334. package/pkg/dist/modes/interactive/theme/theme-highlight.test.d.ts.map +1 -0
  335. package/pkg/dist/modes/interactive/theme/theme-highlight.test.js +17 -0
  336. package/pkg/dist/modes/interactive/theme/theme-highlight.test.js.map +1 -0
  337. package/pkg/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  338. package/pkg/dist/modes/interactive/theme/theme.js +105 -1
  339. package/pkg/dist/modes/interactive/theme/theme.js.map +1 -1
  340. package/pkg/dist/modes/interactive/theme/themes.d.ts.map +1 -1
  341. package/pkg/dist/modes/interactive/theme/themes.js +27 -26
  342. package/pkg/dist/modes/interactive/theme/themes.js.map +1 -1
  343. package/pkg/package.json +1 -1
  344. package/src/resources/extensions/browser-tools/tools/screenshot.ts +1 -0
  345. package/src/resources/extensions/browser-tools/tools/zoom.ts +1 -0
  346. package/src/resources/extensions/gsd/auto/loop-deps.ts +9 -5
  347. package/src/resources/extensions/gsd/auto/loop.ts +113 -9
  348. package/src/resources/extensions/gsd/auto/phases.ts +158 -19
  349. package/src/resources/extensions/gsd/auto/run-unit.ts +69 -4
  350. package/src/resources/extensions/gsd/auto/session.ts +10 -0
  351. package/src/resources/extensions/gsd/auto/verification-retry-policy.ts +82 -0
  352. package/src/resources/extensions/gsd/auto-dashboard.ts +230 -183
  353. package/src/resources/extensions/gsd/auto-dispatch.ts +15 -1
  354. package/src/resources/extensions/gsd/auto-post-unit.ts +7 -1
  355. package/src/resources/extensions/gsd/auto-prompts.ts +11 -3
  356. package/src/resources/extensions/gsd/auto-recovery.ts +7 -209
  357. package/src/resources/extensions/gsd/auto-runtime-state.ts +5 -0
  358. package/src/resources/extensions/gsd/auto-start.ts +22 -22
  359. package/src/resources/extensions/gsd/auto-unit-closeout.ts +51 -0
  360. package/src/resources/extensions/gsd/auto-verification.ts +12 -6
  361. package/src/resources/extensions/gsd/auto-worktree.ts +8 -0
  362. package/src/resources/extensions/gsd/auto.ts +295 -75
  363. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +21 -6
  364. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +12 -2
  365. package/src/resources/extensions/gsd/bootstrap/register-shortcuts.ts +5 -8
  366. package/src/resources/extensions/gsd/bootstrap/system-context.ts +58 -15
  367. package/src/resources/extensions/gsd/commands/handlers/core.ts +1 -1
  368. package/src/resources/extensions/gsd/commands/handlers/notifications-handler.ts +4 -10
  369. package/src/resources/extensions/gsd/commands/handlers/parallel.ts +12 -0
  370. package/src/resources/extensions/gsd/commands-handlers.ts +19 -2
  371. package/src/resources/extensions/gsd/context-store.ts +120 -1
  372. package/src/resources/extensions/gsd/db-writer.ts +167 -84
  373. package/src/resources/extensions/gsd/docs/preferences-reference.md +1 -1
  374. package/src/resources/extensions/gsd/doctor-git-checks.ts +44 -6
  375. package/src/resources/extensions/gsd/doctor-types.ts +2 -0
  376. package/src/resources/extensions/gsd/git-service.ts +2 -0
  377. package/src/resources/extensions/gsd/gsd-db.ts +7 -23
  378. package/src/resources/extensions/gsd/health-widget-core.ts +1 -1
  379. package/src/resources/extensions/gsd/health-widget.ts +6 -10
  380. package/src/resources/extensions/gsd/journal.ts +2 -0
  381. package/src/resources/extensions/gsd/knowledge-backfill.ts +164 -0
  382. package/src/resources/extensions/gsd/knowledge-capture.ts +160 -0
  383. package/src/resources/extensions/gsd/knowledge-parser.ts +174 -0
  384. package/src/resources/extensions/gsd/knowledge-projection.ts +241 -0
  385. package/src/resources/extensions/gsd/markdown-renderer.ts +10 -96
  386. package/src/resources/extensions/gsd/memory-backfill.ts +89 -17
  387. package/src/resources/extensions/gsd/memory-consolidation-scanner.ts +277 -0
  388. package/src/resources/extensions/gsd/native-git-bridge.ts +14 -13
  389. package/src/resources/extensions/gsd/notification-overlay.ts +50 -46
  390. package/src/resources/extensions/gsd/parallel-merge.ts +61 -34
  391. package/src/resources/extensions/gsd/parallel-monitor-overlay.ts +33 -35
  392. package/src/resources/extensions/gsd/prompts/complete-slice.md +14 -12
  393. package/src/resources/extensions/gsd/prompts/discuss-headless.md +20 -2
  394. package/src/resources/extensions/gsd/prompts/discuss.md +20 -2
  395. package/src/resources/extensions/gsd/prompts/system.md +2 -2
  396. package/src/resources/extensions/gsd/provider-switch-observer.ts +185 -0
  397. package/src/resources/extensions/gsd/recovery-classification.ts +18 -1
  398. package/src/resources/extensions/gsd/session-lock.ts +41 -0
  399. package/src/resources/extensions/gsd/state-reconciliation/drift/completion.ts +172 -0
  400. package/src/resources/extensions/gsd/state-reconciliation/drift/merge-state.ts +337 -0
  401. package/src/resources/extensions/gsd/state-reconciliation/drift/project-md.ts +69 -0
  402. package/src/resources/extensions/gsd/state-reconciliation/drift/roadmap.ts +109 -0
  403. package/src/resources/extensions/gsd/state-reconciliation/drift/sketch-flag.ts +68 -0
  404. package/src/resources/extensions/gsd/state-reconciliation/drift/stale-render.ts +185 -0
  405. package/src/resources/extensions/gsd/state-reconciliation/drift/stale-worker.ts +46 -0
  406. package/src/resources/extensions/gsd/state-reconciliation/errors.ts +67 -0
  407. package/src/resources/extensions/gsd/state-reconciliation/index.ts +142 -0
  408. package/src/resources/extensions/gsd/state-reconciliation/registry.ts +27 -0
  409. package/src/resources/extensions/gsd/state-reconciliation/spawn-gate.ts +60 -0
  410. package/src/resources/extensions/gsd/state-reconciliation/types.ts +83 -0
  411. package/src/resources/extensions/gsd/state-reconciliation.ts +21 -53
  412. package/src/resources/extensions/gsd/templates/knowledge.md +2 -2
  413. package/src/resources/extensions/gsd/tests/artifact-retry-cap.test.ts +1 -1
  414. package/src/resources/extensions/gsd/tests/auto-dashboard.test.ts +99 -0
  415. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +729 -176
  416. package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +291 -4
  417. package/src/resources/extensions/gsd/tests/auto-runtime-state.test.ts +16 -1
  418. package/src/resources/extensions/gsd/tests/auto-start-orphan-bootstrap.test.ts +18 -0
  419. package/src/resources/extensions/gsd/tests/auto-unit-closeout.test.ts +68 -0
  420. package/src/resources/extensions/gsd/tests/browser-tools-compatibility-declarations.test.ts +62 -0
  421. package/src/resources/extensions/gsd/tests/context-store-decisions-from-memories.test.ts +312 -0
  422. package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +28 -1
  423. package/src/resources/extensions/gsd/tests/db-writer.test.ts +13 -8
  424. package/src/resources/extensions/gsd/tests/decisions-projection-from-memories.test.ts +453 -0
  425. package/src/resources/extensions/gsd/tests/decisions-stop-table-writes.test.ts +348 -0
  426. package/src/resources/extensions/gsd/tests/deep-project-auto-loop.test.ts +20 -2
  427. package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +44 -0
  428. package/src/resources/extensions/gsd/tests/freeform-decisions.test.ts +8 -4
  429. package/src/resources/extensions/gsd/tests/gsd-tools.test.ts +11 -7
  430. package/src/resources/extensions/gsd/tests/header-renderer.test.ts +40 -0
  431. package/src/resources/extensions/gsd/tests/headless-milestone-parity.test.ts +10 -0
  432. package/src/resources/extensions/gsd/tests/health-widget.test.ts +14 -4
  433. package/src/resources/extensions/gsd/tests/integration/doctor-git.test.ts +44 -0
  434. package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +26 -0
  435. package/src/resources/extensions/gsd/tests/integration/integration-lifecycle.test.ts +13 -5
  436. package/src/resources/extensions/gsd/tests/integration/integration-proof.test.ts +1 -1
  437. package/src/resources/extensions/gsd/tests/integration/parallel-merge.test.ts +116 -24
  438. package/src/resources/extensions/gsd/tests/journal-integration.test.ts +0 -1
  439. package/src/resources/extensions/gsd/tests/knowledge-backfill-projection.test.ts +323 -0
  440. package/src/resources/extensions/gsd/tests/knowledge-capture.test.ts +242 -0
  441. package/src/resources/extensions/gsd/tests/knowledge.test.ts +47 -2
  442. package/src/resources/extensions/gsd/tests/load-knowledge-block-rules-only.test.ts +209 -0
  443. package/src/resources/extensions/gsd/tests/markdown-renderer.test.ts +1 -1
  444. package/src/resources/extensions/gsd/tests/memory-consolidation-scanner.test.ts +316 -0
  445. package/src/resources/extensions/gsd/tests/merge-conflict-stops-loop.test.ts +46 -11
  446. package/src/resources/extensions/gsd/tests/notification-overlay.test.ts +78 -41
  447. package/src/resources/extensions/gsd/tests/notifications-handler.test.ts +44 -0
  448. package/src/resources/extensions/gsd/tests/originalbase-path-comparison.test.ts +12 -217
  449. package/src/resources/extensions/gsd/tests/parallel-monitor-overlay.test.ts +38 -6
  450. package/src/resources/extensions/gsd/tests/plan-milestone-sketch-render.test.ts +157 -0
  451. package/src/resources/extensions/gsd/tests/post-exec-retry-bypass.test.ts +2 -2
  452. package/src/resources/extensions/gsd/tests/progressive-planning.test.ts +1 -1
  453. package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +32 -1
  454. package/src/resources/extensions/gsd/tests/provider-switch-observer.test.ts +252 -0
  455. package/src/resources/extensions/gsd/tests/resume-dispatch-worktree.test.ts +7 -3
  456. package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +6 -3
  457. package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +16 -4
  458. package/src/resources/extensions/gsd/tests/session-switch-abort-misclassification.test.ts +24 -0
  459. package/src/resources/extensions/gsd/tests/state-corruption-2945.test.ts +65 -58
  460. package/src/resources/extensions/gsd/tests/state-reconciliation-drift.test.ts +952 -0
  461. package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +4 -0
  462. package/src/resources/extensions/gsd/tests/tui-header-lifecycle.test.ts +121 -1
  463. package/src/resources/extensions/gsd/tests/tui-render-kit.test.ts +66 -0
  464. package/src/resources/extensions/gsd/tests/verification-retry-policy.test.ts +83 -0
  465. package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +6 -0
  466. package/src/resources/extensions/gsd/tests/worktree-journal-events.test.ts +158 -58
  467. package/src/resources/extensions/gsd/tests/worktree-lifecycle.test.ts +572 -118
  468. package/src/resources/extensions/gsd/tests/worktree-telemetry.test.ts +59 -2
  469. package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +18 -0
  470. package/src/resources/extensions/gsd/tui/render-kit.ts +109 -0
  471. package/src/resources/extensions/gsd/watch/header-renderer.ts +121 -79
  472. package/src/resources/extensions/gsd/watch/splash-palette.ts +11 -0
  473. package/src/resources/extensions/gsd/workflow-logger.ts +4 -0
  474. package/src/resources/extensions/gsd/workflow-mcp.ts +2 -2
  475. package/src/resources/extensions/gsd/worktree-lifecycle.ts +1151 -524
  476. package/src/resources/extensions/gsd/worktree-telemetry.ts +7 -2
  477. package/dist/web/standalone/.next/static/chunks/app/page-200592a7f3baf579.js +0 -1
  478. package/dist/web/standalone/.next/static/chunks/main-app-d3d4c336195465f9.js +0 -1
  479. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ab5a8926e07ec673.js +0 -1
  480. package/src/resources/extensions/gsd/tests/worktree-resolver.test.ts +0 -1544
  481. /package/dist/web/standalone/.next/static/{drLMkgfHQ8lzS229_HWYR → KDRTXR-22LPCsa80X9dey}/_buildManifest.js +0 -0
  482. /package/dist/web/standalone/.next/static/{drLMkgfHQ8lzS229_HWYR → KDRTXR-22LPCsa80X9dey}/_ssgManifest.js +0 -0
@@ -0,0 +1,242 @@
1
+ // ADR-013 Stage 2c — /gsd knowledge write-side redirect tests.
2
+ //
3
+ // Locks in four properties of captureKnowledgeEntry / nextKnowledgeId:
4
+ // 1. Pattern entries write a memory row with category="pattern" and a
5
+ // sourceKnowledgeId marker — but do NOT touch KNOWLEDGE.md.
6
+ // 2. Lesson entries write a memory row with category="gotcha" — same
7
+ // file-vs-memory split.
8
+ // 3. Next-ID is monotonic across both surfaces: a P004 in the file plus a
9
+ // P007 in memories yields P008 next.
10
+ // 4. The legacy appendKnowledge stays the canonical path for Rules
11
+ // (covered indirectly via no-memory side effect on type="rule").
12
+
13
+ import test from "node:test";
14
+ import assert from "node:assert/strict";
15
+ import { existsSync, mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
16
+ import { join } from "node:path";
17
+ import { tmpdir } from "node:os";
18
+
19
+ import {
20
+ _getAdapter,
21
+ closeDatabase,
22
+ openDatabase,
23
+ } from "../gsd-db.ts";
24
+ import { captureKnowledgeEntry, nextKnowledgeId } from "../knowledge-capture.ts";
25
+ import { knowledgeMdPath } from "../knowledge-parser.ts";
26
+
27
+ function makeTmpBase(): string {
28
+ const base = mkdtempSync(join(tmpdir(), "gsd-knowledge-capture-"));
29
+ mkdirSync(join(base, ".gsd"), { recursive: true });
30
+ openDatabase(join(base, ".gsd", "gsd.db"));
31
+ return base;
32
+ }
33
+
34
+ function cleanup(base: string): void {
35
+ try {
36
+ closeDatabase();
37
+ } catch {
38
+ /* noop */
39
+ }
40
+ try {
41
+ rmSync(base, { recursive: true, force: true });
42
+ } catch {
43
+ /* noop */
44
+ }
45
+ }
46
+
47
+ function readMemoriesWithMarker(prefix: "P" | "L"): Array<{ category: string; sf: Record<string, unknown> }> {
48
+ const adapter = _getAdapter();
49
+ if (!adapter) return [];
50
+ const rows = adapter
51
+ .prepare(
52
+ "SELECT category, structured_fields FROM memories WHERE structured_fields LIKE :pattern ORDER BY seq",
53
+ )
54
+ .all({ ":pattern": `%"sourceKnowledgeId":"${prefix}%` }) as Array<{
55
+ category: string;
56
+ structured_fields: string;
57
+ }>;
58
+ return rows.map((r) => ({ category: r.category, sf: JSON.parse(r.structured_fields) }));
59
+ }
60
+
61
+ // ─── Pattern path ───────────────────────────────────────────────────────────
62
+
63
+ test("pattern entry creates a memory and assigns the next P### id", () => {
64
+ const base = makeTmpBase();
65
+ try {
66
+ const result = captureKnowledgeEntry(base, "pattern", "Repository pattern at the seam", "M001");
67
+ assert.equal(result.id, "P001", "first pattern on a fresh project should be P001");
68
+ assert.equal(result.written, true);
69
+
70
+ const memories = readMemoriesWithMarker("P");
71
+ assert.equal(memories.length, 1);
72
+ assert.equal(memories[0]?.category, "pattern");
73
+ assert.equal(memories[0]?.sf.sourceKnowledgeId, "P001");
74
+ assert.equal(memories[0]?.sf.pattern, "Repository pattern at the seam");
75
+ assert.equal(memories[0]?.sf.where, "");
76
+ assert.equal(memories[0]?.sf.notes, "");
77
+ } finally {
78
+ cleanup(base);
79
+ }
80
+ });
81
+
82
+ test("pattern entry does NOT write to KNOWLEDGE.md (memory-only)", () => {
83
+ const base = makeTmpBase();
84
+ try {
85
+ captureKnowledgeEntry(base, "pattern", "Adapter at the seam", "project");
86
+ assert.equal(
87
+ existsSync(knowledgeMdPath(base)),
88
+ false,
89
+ "KNOWLEDGE.md should remain untouched — projection re-renders on next session start",
90
+ );
91
+ } finally {
92
+ cleanup(base);
93
+ }
94
+ });
95
+
96
+ test("repeated pattern captures advance the ID monotonically", () => {
97
+ const base = makeTmpBase();
98
+ try {
99
+ const a = captureKnowledgeEntry(base, "pattern", "First", "project");
100
+ const b = captureKnowledgeEntry(base, "pattern", "Second", "project");
101
+ const c = captureKnowledgeEntry(base, "pattern", "Third", "project");
102
+ assert.deepEqual([a.id, b.id, c.id], ["P001", "P002", "P003"]);
103
+ } finally {
104
+ cleanup(base);
105
+ }
106
+ });
107
+
108
+ // ─── Lesson path ────────────────────────────────────────────────────────────
109
+
110
+ test("lesson entry creates a memory with category=gotcha and L### id", () => {
111
+ const base = makeTmpBase();
112
+ try {
113
+ const result = captureKnowledgeEntry(base, "lesson", "Cache poisoning via reused key", "M001/S01");
114
+ assert.equal(result.id, "L001");
115
+ assert.equal(result.written, true);
116
+
117
+ const memories = readMemoriesWithMarker("L");
118
+ assert.equal(memories.length, 1);
119
+ assert.equal(memories[0]?.category, "gotcha");
120
+ assert.equal(memories[0]?.sf.sourceKnowledgeId, "L001");
121
+ assert.equal(memories[0]?.sf.whatHappened, "Cache poisoning via reused key");
122
+ assert.equal(memories[0]?.sf.scopeText, "M001/S01");
123
+ } finally {
124
+ cleanup(base);
125
+ }
126
+ });
127
+
128
+ // ─── Empty input ────────────────────────────────────────────────────────────
129
+
130
+ test("empty entry text does NOT create a memory but still assigns an id", () => {
131
+ const base = makeTmpBase();
132
+ try {
133
+ const result = captureKnowledgeEntry(base, "pattern", " ", "project");
134
+ assert.equal(result.written, false);
135
+ assert.equal(readMemoriesWithMarker("P").length, 0);
136
+ } finally {
137
+ cleanup(base);
138
+ }
139
+ });
140
+
141
+ // ─── nextKnowledgeId — cross-surface monotonicity ───────────────────────────
142
+
143
+ test("nextKnowledgeId takes max of file and memory surfaces", () => {
144
+ const base = makeTmpBase();
145
+ try {
146
+ // Pre-existing patterns in KNOWLEDGE.md and one new pattern in memories.
147
+ // The legacy appendKnowledge format starts P at 001 — we simulate higher
148
+ // existing IDs to verify the take-max-then-+1 rule.
149
+ writeFileSync(
150
+ knowledgeMdPath(base),
151
+ `## Patterns
152
+
153
+ | # | Pattern | Where | Notes |
154
+ |---|---------|-------|-------|
155
+ | P004 | Legacy pattern | services/ | preserved |
156
+ `,
157
+ "utf-8",
158
+ );
159
+
160
+ // Capture jumps the memory ID forward.
161
+ captureKnowledgeEntry(base, "pattern", "Memory-only pattern", "project");
162
+ captureKnowledgeEntry(base, "pattern", "Another memory-only pattern", "project");
163
+ captureKnowledgeEntry(base, "pattern", "And another", "project");
164
+
165
+ // After: file has P004 (max=4); memories have P005, P006, P007 (max=7).
166
+ // Next must be P008.
167
+ assert.equal(nextKnowledgeId(base, "P"), "P008");
168
+ } finally {
169
+ cleanup(base);
170
+ }
171
+ });
172
+
173
+ test("nextKnowledgeId works per-prefix without cross-talk", () => {
174
+ const base = makeTmpBase();
175
+ try {
176
+ captureKnowledgeEntry(base, "pattern", "P entry", "project");
177
+ captureKnowledgeEntry(base, "pattern", "P entry 2", "project");
178
+ captureKnowledgeEntry(base, "lesson", "L entry", "project");
179
+
180
+ assert.equal(nextKnowledgeId(base, "P"), "P003");
181
+ assert.equal(nextKnowledgeId(base, "L"), "L002");
182
+ // K has no entries on this project — first one should be K001.
183
+ assert.equal(nextKnowledgeId(base, "K"), "K001");
184
+ } finally {
185
+ cleanup(base);
186
+ }
187
+ });
188
+
189
+ test("nextKnowledgeId pads to three digits even at the rollover", () => {
190
+ const base = makeTmpBase();
191
+ try {
192
+ writeFileSync(
193
+ knowledgeMdPath(base),
194
+ `## Patterns
195
+
196
+ | # | Pattern | Where | Notes |
197
+ |---|---------|-------|-------|
198
+ | P099 | high water mark | — | — |
199
+ `,
200
+ "utf-8",
201
+ );
202
+ assert.equal(nextKnowledgeId(base, "P"), "P100");
203
+ } finally {
204
+ cleanup(base);
205
+ }
206
+ });
207
+
208
+ // ─── Sanity: file-side reads still see existing rows after capture ─────────
209
+
210
+ test("after pattern capture, KNOWLEDGE.md untouched but next id reflects memory state", () => {
211
+ const base = makeTmpBase();
212
+ try {
213
+ captureKnowledgeEntry(base, "pattern", "First", "project");
214
+ // KNOWLEDGE.md still absent.
215
+ assert.equal(existsSync(knowledgeMdPath(base)), false);
216
+ // Next-ID logic sees the new memory.
217
+ assert.equal(nextKnowledgeId(base, "P"), "P002");
218
+ } finally {
219
+ cleanup(base);
220
+ }
221
+ });
222
+
223
+ test("rule writes still flow through appendKnowledge (file-canonical) — memory unchanged", async () => {
224
+ const base = makeTmpBase();
225
+ try {
226
+ // We invoke the legacy file path directly here; the command handler
227
+ // dispatch is verified separately at the integration level. The point
228
+ // of this test is to lock in that captureKnowledgeEntry is NOT the
229
+ // rule path — rules must go through appendKnowledge.
230
+ const { appendKnowledge } = await import("../files.ts");
231
+ await appendKnowledge(base, "rule", "Always pin SQLite version", "project");
232
+
233
+ const md = readFileSync(knowledgeMdPath(base), "utf-8");
234
+ assert.match(md, /\| K001 \| project \| Always pin SQLite version /);
235
+
236
+ // No pattern/lesson memories should exist as a side effect.
237
+ assert.equal(readMemoriesWithMarker("P").length, 0);
238
+ assert.equal(readMemoriesWithMarker("L").length, 0);
239
+ } finally {
240
+ cleanup(base);
241
+ }
242
+ });
@@ -187,7 +187,7 @@ test('loadKnowledgeBlock: uses project knowledge alone when no global file', ()
187
187
  writeFileSync(join(cwd, '.gsd', 'KNOWLEDGE.md'), 'K001: Use real DB');
188
188
 
189
189
  const result = loadKnowledgeBlock(gsdHome, cwd);
190
- assert.ok(result.block.includes('[KNOWLEDGE — Rules, patterns, and lessons learned]'));
190
+ assert.ok(result.block.includes('[KNOWLEDGE — Rules from KNOWLEDGE.md'));
191
191
  assert.ok(result.block.includes('## Project Knowledge'));
192
192
  assert.ok(result.block.includes('K001: Use real DB'));
193
193
  assert.ok(!result.block.includes('## Global Knowledge'));
@@ -205,7 +205,7 @@ test('loadKnowledgeBlock: uses global knowledge alone when no project file', ()
205
205
  writeFileSync(join(gsdHome, 'agent', 'KNOWLEDGE.md'), 'G001: Respond in English');
206
206
 
207
207
  const result = loadKnowledgeBlock(gsdHome, cwd);
208
- assert.ok(result.block.includes('[KNOWLEDGE — Rules, patterns, and lessons learned]'));
208
+ assert.ok(result.block.includes('[KNOWLEDGE — Rules from KNOWLEDGE.md'));
209
209
  assert.ok(result.block.includes('## Global Knowledge'));
210
210
  assert.ok(result.block.includes('G001: Respond in English'));
211
211
  assert.ok(!result.block.includes('## Project Knowledge'));
@@ -234,6 +234,51 @@ test('loadKnowledgeBlock: merges global before project when both exist', () => {
234
234
  rmSync(tmp, { recursive: true, force: true });
235
235
  });
236
236
 
237
+ test('loadKnowledgeBlock: strips patterns and lessons from project knowledge', () => {
238
+ const tmp = realpathSync(mkdtempSync(join(tmpdir(), 'gsd-kb-strip-')));
239
+ const gsdHome = join(tmp, 'home');
240
+ const cwd = join(tmp, 'project');
241
+ mkdirSync(join(cwd, '.gsd'), { recursive: true });
242
+ mkdirSync(join(gsdHome, 'agent'), { recursive: true });
243
+ writeFileSync(
244
+ join(cwd, '.gsd', 'KNOWLEDGE.md'),
245
+ [
246
+ '# Project Knowledge',
247
+ '',
248
+ 'Intro note that should stay with manual rules.',
249
+ '',
250
+ '## Rules',
251
+ '',
252
+ '| ID | Rule | Notes |',
253
+ '|---|---|---|',
254
+ '| K001 | Use real DB | - |',
255
+ '',
256
+ '## Patterns',
257
+ '',
258
+ '| ID | Pattern | Where | Notes |',
259
+ '|---|---|---|---|',
260
+ '| P001 | Prefer async | server | - |',
261
+ '',
262
+ '## Lessons Learned',
263
+ '',
264
+ '| ID | What Happened | Root Cause | Fix | Scope |',
265
+ '|---|---|---|---|---|',
266
+ '| L001 | Missed cache | N/A | Add TTL | project |',
267
+ ].join('\n'),
268
+ );
269
+
270
+ const result = loadKnowledgeBlock(gsdHome, cwd);
271
+ assert.ok(result.block.includes('[KNOWLEDGE — Rules from KNOWLEDGE.md'));
272
+ assert.ok(result.block.includes('Intro note that should stay with manual rules.'));
273
+ assert.ok(result.block.includes('K001'), 'rules entry should be present');
274
+ assert.ok(!result.block.includes('P001'), 'patterns should be stripped and injected via memories');
275
+ assert.ok(!result.block.includes('L001'), 'lessons should be stripped and injected via memories');
276
+ assert.ok(!result.block.includes('## Patterns'), 'Patterns heading should not appear');
277
+ assert.ok(!result.block.includes('## Lessons Learned'), 'Lessons heading should not appear');
278
+
279
+ rmSync(tmp, { recursive: true, force: true });
280
+ });
281
+
237
282
  test('loadKnowledgeBlock: reports globalSizeKb above 4KB threshold', () => {
238
283
  const tmp = realpathSync(mkdtempSync(join(tmpdir(), 'gsd-kb-')));
239
284
  const gsdHome = join(tmp, 'home');
@@ -0,0 +1,209 @@
1
+ // ADR-013 follow-up — loadKnowledgeBlock injects only Rules from project
2
+ // KNOWLEDGE.md to avoid duplicating Patterns + Lessons content already
3
+ // injected via loadMemoryBlock (Stage 2b cutover).
4
+ //
5
+ // Global KNOWLEDGE.md (~/.gsd/agent/KNOWLEDGE.md) is NOT memory-projected
6
+ // and still passes through with all three sections intact.
7
+
8
+ import test from "node:test";
9
+ import assert from "node:assert/strict";
10
+ import { mkdtempSync, mkdirSync, rmSync, writeFileSync } from "node:fs";
11
+ import { join } from "node:path";
12
+ import { tmpdir } from "node:os";
13
+
14
+ import { loadKnowledgeBlock } from "../bootstrap/system-context.ts";
15
+ import { extractIntroAndRules } from "../knowledge-parser.ts";
16
+
17
+ function makeTmpProject(): string {
18
+ const base = mkdtempSync(join(tmpdir(), "gsd-knowledge-rules-only-"));
19
+ mkdirSync(join(base, ".gsd"), { recursive: true });
20
+ return base;
21
+ }
22
+
23
+ function makeTmpHome(): string {
24
+ const home = mkdtempSync(join(tmpdir(), "gsd-knowledge-home-"));
25
+ mkdirSync(join(home, "agent"), { recursive: true });
26
+ return home;
27
+ }
28
+
29
+ function cleanup(...dirs: string[]): void {
30
+ for (const dir of dirs) {
31
+ try {
32
+ rmSync(dir, { recursive: true, force: true });
33
+ } catch {
34
+ /* noop */
35
+ }
36
+ }
37
+ }
38
+
39
+ const FULL_KNOWLEDGE = `# Project Knowledge
40
+
41
+ Append-only register of project-specific rules, patterns, and lessons learned.
42
+
43
+ ## Rules
44
+
45
+ | # | Scope | Rule | Why | Added |
46
+ |---|-------|------|-----|-------|
47
+ | K001 | project | All timestamps in UTC | clarity | 2026-01-01 |
48
+ | K002 | M001 | Never trust user input | safety | 2026-01-02 |
49
+
50
+ ## Patterns
51
+
52
+ | # | Pattern | Where | Notes |
53
+ |---|---------|-------|-------|
54
+ | P001 | Repository pattern | services/ | guards |
55
+
56
+ ## Lessons Learned
57
+
58
+ | # | What Happened | Root Cause | Fix | Scope |
59
+ |---|--------------|------------|-----|-------|
60
+ | L001 | Cache poisoning | reused key | versioned key | project |
61
+ `;
62
+
63
+ // ─── extractIntroAndRules unit tests ───────────────────────────────────────
64
+
65
+ test("extractIntroAndRules keeps intro + Rules, drops Patterns + Lessons", () => {
66
+ const out = extractIntroAndRules(FULL_KNOWLEDGE);
67
+ assert.match(out, /# Project Knowledge/);
68
+ assert.match(out, /## Rules/);
69
+ assert.match(out, /\| K001 \| project \| All timestamps in UTC/);
70
+ assert.match(out, /\| K002 \| M001 \| Never trust user input/);
71
+
72
+ assert.equal(out.includes("## Patterns"), false, "Patterns heading must be dropped");
73
+ assert.equal(out.includes("P001"), false, "Pattern rows must be dropped");
74
+ assert.equal(out.includes("## Lessons Learned"), false, "Lessons heading must be dropped");
75
+ assert.equal(out.includes("L001"), false, "Lesson rows must be dropped");
76
+ });
77
+
78
+ test("extractIntroAndRules returns content unchanged when no `## Rules` heading", () => {
79
+ const content = "# Notes\n\nfreeform content without standard sections\n";
80
+ assert.equal(extractIntroAndRules(content), content);
81
+ });
82
+
83
+ test("extractIntroAndRules returns empty for empty input", () => {
84
+ assert.equal(extractIntroAndRules(""), "");
85
+ assert.equal(extractIntroAndRules(" \n\n"), "");
86
+ });
87
+
88
+ test("extractIntroAndRules handles Rules as the only section (no Patterns/Lessons to drop)", () => {
89
+ const content = `# Project Knowledge
90
+
91
+ ## Rules
92
+
93
+ | # | Scope | Rule | Why | Added |
94
+ |---|-------|------|-----|-------|
95
+ | K001 | project | only rule | reason | 2026-01-01 |
96
+ `;
97
+ const out = extractIntroAndRules(content);
98
+ assert.match(out, /K001/);
99
+ assert.match(out, /## Rules/);
100
+ });
101
+
102
+ // ─── loadKnowledgeBlock integration ────────────────────────────────────────
103
+
104
+ test("loadKnowledgeBlock trims project KNOWLEDGE.md to intro + Rules", () => {
105
+ const base = makeTmpProject();
106
+ const home = makeTmpHome();
107
+ try {
108
+ writeFileSync(join(base, ".gsd", "KNOWLEDGE.md"), FULL_KNOWLEDGE, "utf-8");
109
+ const { block } = loadKnowledgeBlock(home, base);
110
+
111
+ assert.match(block, /## Project Knowledge/);
112
+ assert.match(block, /K001/);
113
+ assert.match(block, /K002/);
114
+ assert.equal(block.includes("P001"), false, "project Patterns must not appear in the block");
115
+ assert.equal(block.includes("L001"), false, "project Lessons must not appear in the block");
116
+ assert.equal(block.includes("## Patterns"), false);
117
+ assert.equal(block.includes("## Lessons Learned"), false);
118
+ } finally {
119
+ cleanup(base, home);
120
+ }
121
+ });
122
+
123
+ test("loadKnowledgeBlock leaves global KNOWLEDGE.md intact (no memory projection there)", () => {
124
+ const base = makeTmpProject();
125
+ const home = makeTmpHome();
126
+ try {
127
+ writeFileSync(join(home, "agent", "KNOWLEDGE.md"), FULL_KNOWLEDGE, "utf-8");
128
+ const { block, globalSizeKb } = loadKnowledgeBlock(home, base);
129
+
130
+ assert.match(block, /## Global Knowledge/);
131
+ // Global is full-fidelity: all three sections intact.
132
+ assert.match(block, /K001/);
133
+ assert.match(block, /P001/);
134
+ assert.match(block, /L001/);
135
+ assert.match(block, /## Patterns/);
136
+ assert.match(block, /## Lessons Learned/);
137
+ assert.ok(globalSizeKb > 0, "globalSizeKb should report the global file size");
138
+ } finally {
139
+ cleanup(base, home);
140
+ }
141
+ });
142
+
143
+ test("loadKnowledgeBlock with both global and project: global keeps full content, project trimmed", () => {
144
+ const base = makeTmpProject();
145
+ const home = makeTmpHome();
146
+ try {
147
+ writeFileSync(join(home, "agent", "KNOWLEDGE.md"), FULL_KNOWLEDGE, "utf-8");
148
+ writeFileSync(join(base, ".gsd", "KNOWLEDGE.md"), FULL_KNOWLEDGE, "utf-8");
149
+ const { block } = loadKnowledgeBlock(home, base);
150
+
151
+ // Both sections present.
152
+ assert.match(block, /## Global Knowledge/);
153
+ assert.match(block, /## Project Knowledge/);
154
+
155
+ // Project's Patterns/Lessons headings must be gone. But global keeps
156
+ // them, so a substring count of e.g. "## Patterns" should equal 1.
157
+ const patternsCount = (block.match(/## Patterns/g) ?? []).length;
158
+ const lessonsCount = (block.match(/## Lessons Learned/g) ?? []).length;
159
+ assert.equal(patternsCount, 1, "Patterns heading appears exactly once (in global)");
160
+ assert.equal(lessonsCount, 1, "Lessons heading appears exactly once (in global)");
161
+
162
+ // K/P/L rows: K appears twice (global + project), P/L appear once (global).
163
+ const k001Count = (block.match(/K001/g) ?? []).length;
164
+ const p001Count = (block.match(/P001/g) ?? []).length;
165
+ const l001Count = (block.match(/L001/g) ?? []).length;
166
+ assert.equal(k001Count, 2, "K001 in both global and project");
167
+ assert.equal(p001Count, 1, "P001 only in global");
168
+ assert.equal(l001Count, 1, "L001 only in global");
169
+ } finally {
170
+ cleanup(base, home);
171
+ }
172
+ });
173
+
174
+ test("loadKnowledgeBlock returns empty block when neither file exists", () => {
175
+ const base = makeTmpProject();
176
+ const home = makeTmpHome();
177
+ try {
178
+ const result = loadKnowledgeBlock(home, base);
179
+ assert.equal(result.block, "");
180
+ assert.equal(result.globalSizeKb, 0);
181
+ } finally {
182
+ cleanup(base, home);
183
+ }
184
+ });
185
+
186
+ test("loadKnowledgeBlock injects only Rules when project KNOWLEDGE.md has no Patterns/Lessons", () => {
187
+ const base = makeTmpProject();
188
+ const home = makeTmpHome();
189
+ try {
190
+ writeFileSync(
191
+ join(base, ".gsd", "KNOWLEDGE.md"),
192
+ `# Project Knowledge
193
+
194
+ ## Rules
195
+
196
+ | # | Scope | Rule | Why | Added |
197
+ |---|-------|------|-----|-------|
198
+ | K001 | project | rule one | reason | 2026-01-01 |
199
+ `,
200
+ "utf-8",
201
+ );
202
+ const { block } = loadKnowledgeBlock(home, base);
203
+ assert.match(block, /K001/);
204
+ // Block heading reflects the new contract.
205
+ assert.match(block, /Rules from KNOWLEDGE\.md/);
206
+ } finally {
207
+ cleanup(base, home);
208
+ }
209
+ });
@@ -24,8 +24,8 @@ import {
24
24
  renderPlanFromDb,
25
25
  renderTaskPlanFromDb,
26
26
  detectStaleRenders,
27
- repairStaleRenders,
28
27
  } from '../markdown-renderer.ts';
28
+ import { repairStaleRenders } from '../state-reconciliation/drift/stale-render.ts';
29
29
  import {
30
30
  parseRoadmap,
31
31
  parsePlan,