gsd-pi 2.81.0 → 2.82.0-dev.2841a1e44

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 (572) hide show
  1. package/README.md +63 -32
  2. package/dist/resources/.managed-resources-content-hash +1 -1
  3. package/dist/resources/GSD-WORKFLOW.md +3 -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/cmux/index.js +5 -0
  7. package/dist/resources/extensions/gsd/auto/loop.js +111 -8
  8. package/dist/resources/extensions/gsd/auto/orchestrator.js +113 -6
  9. package/dist/resources/extensions/gsd/auto/phases.js +199 -97
  10. package/dist/resources/extensions/gsd/auto/run-unit.js +66 -3
  11. package/dist/resources/extensions/gsd/auto/session.js +9 -0
  12. package/dist/resources/extensions/gsd/auto/verification-retry-policy.js +43 -0
  13. package/dist/resources/extensions/gsd/auto-dashboard.js +182 -178
  14. package/dist/resources/extensions/gsd/auto-dispatch.js +14 -11
  15. package/dist/resources/extensions/gsd/auto-post-unit.js +176 -125
  16. package/dist/resources/extensions/gsd/auto-prompts.js +13 -5
  17. package/dist/resources/extensions/gsd/auto-recovery.js +6 -181
  18. package/dist/resources/extensions/gsd/auto-runtime-state.js +5 -0
  19. package/dist/resources/extensions/gsd/auto-start.js +20 -23
  20. package/dist/resources/extensions/gsd/auto-unit-closeout.js +33 -5
  21. package/dist/resources/extensions/gsd/auto-verification.js +38 -26
  22. package/dist/resources/extensions/gsd/auto-worktree.js +8 -0
  23. package/dist/resources/extensions/gsd/auto.js +371 -106
  24. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +13 -6
  25. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +13 -2
  26. package/dist/resources/extensions/gsd/bootstrap/register-shortcuts.js +4 -8
  27. package/dist/resources/extensions/gsd/bootstrap/subagent-input.js +16 -7
  28. package/dist/resources/extensions/gsd/bootstrap/system-context.js +55 -12
  29. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +3 -1
  30. package/dist/resources/extensions/gsd/clean-root-preflight.js +170 -8
  31. package/dist/resources/extensions/gsd/commands/catalog.js +4 -1
  32. package/dist/resources/extensions/gsd/commands/handlers/core.js +22 -1
  33. package/dist/resources/extensions/gsd/commands/handlers/notifications-handler.js +4 -10
  34. package/dist/resources/extensions/gsd/commands/handlers/parallel.js +9 -0
  35. package/dist/resources/extensions/gsd/commands-bootstrap.js +5 -0
  36. package/dist/resources/extensions/gsd/commands-handlers.js +15 -2
  37. package/dist/resources/extensions/gsd/context-store.js +112 -0
  38. package/dist/resources/extensions/gsd/db-writer.js +150 -84
  39. package/dist/resources/extensions/gsd/docs/preferences-reference.md +1 -1
  40. package/dist/resources/extensions/gsd/doctor-git-checks.js +41 -6
  41. package/dist/resources/extensions/gsd/git-service.js +2 -1
  42. package/dist/resources/extensions/gsd/gsd-db.js +7 -23
  43. package/dist/resources/extensions/gsd/health-widget-core.js +1 -1
  44. package/dist/resources/extensions/gsd/health-widget.js +4 -10
  45. package/dist/resources/extensions/gsd/knowledge-backfill.js +144 -0
  46. package/dist/resources/extensions/gsd/knowledge-capture.js +136 -0
  47. package/dist/resources/extensions/gsd/knowledge-parser.js +154 -0
  48. package/dist/resources/extensions/gsd/knowledge-projection.js +210 -0
  49. package/dist/resources/extensions/gsd/markdown-renderer.js +6 -96
  50. package/dist/resources/extensions/gsd/md-importer.js +1 -1
  51. package/dist/resources/extensions/gsd/memory-backfill.js +73 -17
  52. package/dist/resources/extensions/gsd/memory-consolidation-scanner.js +222 -0
  53. package/dist/resources/extensions/gsd/migrate/command.js +5 -0
  54. package/dist/resources/extensions/gsd/migrate/preview.js +9 -0
  55. package/dist/resources/extensions/gsd/migrate/transformer.js +51 -4
  56. package/dist/resources/extensions/gsd/migrate/writer.js +11 -1
  57. package/dist/resources/extensions/gsd/native-git-bridge.js +14 -14
  58. package/dist/resources/extensions/gsd/notification-overlay.js +35 -40
  59. package/dist/resources/extensions/gsd/parallel-merge.js +53 -30
  60. package/dist/resources/extensions/gsd/parallel-monitor-overlay.js +25 -33
  61. package/dist/resources/extensions/gsd/prompts/complete-slice.md +14 -12
  62. package/dist/resources/extensions/gsd/prompts/discuss-headless.md +20 -2
  63. package/dist/resources/extensions/gsd/prompts/discuss.md +20 -2
  64. package/dist/resources/extensions/gsd/prompts/system.md +2 -2
  65. package/dist/resources/extensions/gsd/provider-switch-observer.js +146 -0
  66. package/dist/resources/extensions/gsd/recovery-classification.js +15 -1
  67. package/dist/resources/extensions/gsd/session-lock.js +40 -0
  68. package/dist/resources/extensions/gsd/state-reconciliation/drift/completion.js +131 -0
  69. package/dist/resources/extensions/gsd/state-reconciliation/drift/merge-state.js +247 -0
  70. package/dist/resources/extensions/gsd/state-reconciliation/drift/project-md.js +50 -0
  71. package/dist/resources/extensions/gsd/state-reconciliation/drift/roadmap.js +87 -0
  72. package/dist/resources/extensions/gsd/state-reconciliation/drift/sketch-flag.js +50 -0
  73. package/dist/resources/extensions/gsd/state-reconciliation/drift/stale-render.js +124 -0
  74. package/dist/resources/extensions/gsd/state-reconciliation/drift/stale-worker.js +32 -0
  75. package/dist/resources/extensions/gsd/state-reconciliation/errors.js +41 -0
  76. package/dist/resources/extensions/gsd/state-reconciliation/index.js +99 -0
  77. package/dist/resources/extensions/gsd/state-reconciliation/registry.js +24 -0
  78. package/dist/resources/extensions/gsd/state-reconciliation/spawn-gate.js +43 -0
  79. package/dist/resources/extensions/gsd/state-reconciliation/types.js +3 -0
  80. package/dist/resources/extensions/gsd/state-reconciliation.js +5 -26
  81. package/dist/resources/extensions/gsd/templates/knowledge.md +2 -2
  82. package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +119 -0
  83. package/dist/resources/extensions/gsd/tui/render-kit.js +74 -0
  84. package/dist/resources/extensions/gsd/unit-context-manifest.js +25 -2
  85. package/dist/resources/extensions/gsd/verification-verdict.js +26 -0
  86. package/dist/resources/extensions/gsd/watch/header-renderer.js +92 -69
  87. package/dist/resources/extensions/gsd/watch/splash-palette.js +10 -0
  88. package/dist/resources/extensions/gsd/workflow-mcp.js +2 -2
  89. package/dist/resources/extensions/gsd/worktree-lifecycle.js +743 -318
  90. package/dist/resources/extensions/gsd/worktree-telemetry.js +3 -1
  91. package/dist/resources/extensions/subagent/index.js +448 -78
  92. package/dist/resources/extensions/subagent/launch.js +77 -0
  93. package/dist/resources/extensions/subagent/run-store.js +148 -0
  94. package/dist/resources/extensions/visual-brief/artifact-policy.js +29 -0
  95. package/dist/resources/extensions/visual-brief/extension-manifest.json +8 -0
  96. package/dist/resources/extensions/visual-brief/index.js +5 -0
  97. package/dist/resources/extensions/visual-brief/page-contract.js +122 -0
  98. package/dist/resources/extensions/visual-brief/prompts.js +111 -0
  99. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  100. package/dist/web/standalone/.next/BUILD_ID +1 -1
  101. package/dist/web/standalone/.next/app-path-routes-manifest.json +11 -11
  102. package/dist/web/standalone/.next/build-manifest.json +4 -4
  103. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  104. package/dist/web/standalone/.next/react-loadable-manifest.json +3 -3
  105. package/dist/web/standalone/.next/required-server-files.json +3 -3
  106. package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
  107. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  108. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  109. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  110. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  111. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  112. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  113. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  114. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  115. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  116. package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
  117. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  118. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  119. package/dist/web/standalone/.next/server/app/_not-found.rsc +4 -4
  120. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +4 -4
  121. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  122. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +4 -4
  123. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  124. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  125. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  126. package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
  127. package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
  128. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
  129. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
  130. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
  131. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
  132. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
  133. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
  134. package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
  135. package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
  136. package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
  137. package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
  138. package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
  139. package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
  140. package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
  141. package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
  142. package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
  143. package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
  144. package/dist/web/standalone/.next/server/app/api/experimental/route.js +2 -2
  145. package/dist/web/standalone/.next/server/app/api/experimental/route_client-reference-manifest.js +1 -1
  146. package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
  147. package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
  148. package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
  149. package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
  150. package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
  151. package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
  152. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  153. package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  154. package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
  155. package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
  156. package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
  157. package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
  158. package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
  159. package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
  160. package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
  161. package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
  162. package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
  163. package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
  164. package/dist/web/standalone/.next/server/app/api/notifications/route.js +2 -2
  165. package/dist/web/standalone/.next/server/app/api/notifications/route_client-reference-manifest.js +1 -1
  166. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  167. package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
  168. package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
  169. package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
  170. package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
  171. package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  172. package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
  173. package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
  174. package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +2 -2
  175. package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
  176. package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
  177. package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
  178. package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
  179. package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
  180. package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
  181. package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
  182. package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
  183. package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
  184. package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
  185. package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
  186. package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
  187. package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
  188. package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
  189. package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
  190. package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
  191. package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
  192. package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
  193. package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
  194. package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +1 -1
  195. package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
  196. package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
  197. package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
  198. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +1 -1
  199. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
  200. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +2 -2
  201. package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
  202. package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
  203. package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
  204. package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
  205. package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
  206. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  207. package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  208. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  209. package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
  210. package/dist/web/standalone/.next/server/app/index.html +1 -1
  211. package/dist/web/standalone/.next/server/app/index.rsc +5 -5
  212. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  213. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +5 -5
  214. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  215. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +4 -4
  216. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  217. package/dist/web/standalone/.next/server/app/page.js +2 -2
  218. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  219. package/dist/web/standalone/.next/server/app-paths-manifest.json +11 -11
  220. package/dist/web/standalone/.next/server/chunks/63.js +3 -3
  221. package/dist/web/standalone/.next/server/chunks/6897.js +1 -1
  222. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  223. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  224. package/dist/web/standalone/.next/server/middleware.js +2 -2
  225. package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
  226. package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
  227. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  228. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  229. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  230. package/dist/web/standalone/.next/static/chunks/2973.33f26573894b6153.js +2 -0
  231. package/dist/web/standalone/.next/static/chunks/{8359.e059d86b255fce1c.js → 8359.7eb3bb8f8ecf4c01.js} +2 -2
  232. package/dist/web/standalone/.next/static/chunks/app/_not-found/{page-2f24283c162b6ab3.js → page-f2a7482d42a5614b.js} +1 -1
  233. package/dist/web/standalone/.next/static/chunks/app/{layout-9ecfd95f343793f0.js → layout-a16c7a7ecdf0c2cf.js} +1 -1
  234. package/dist/web/standalone/.next/static/chunks/app/page-752f1e2ebdaa3e45.js +1 -0
  235. package/dist/web/standalone/.next/static/chunks/main-app-fdab67f7802d7832.js +1 -0
  236. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +1 -0
  237. package/dist/web/standalone/.next/static/chunks/{webpack-de742b64187e13fe.js → webpack-6a95bc41e0f7ec89.js} +1 -1
  238. package/dist/web/standalone/.next/static/css/0262768ec1b89d34.css +1 -0
  239. package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
  240. package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
  241. package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
  242. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api.target.mk +14 -14
  243. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_except.target.mk +14 -14
  244. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_maybe.target.mk +14 -14
  245. package/dist/web/standalone/server.js +1 -1
  246. package/dist/welcome-screen.d.ts +0 -7
  247. package/dist/welcome-screen.js +60 -69
  248. package/package.json +5 -4
  249. package/packages/contracts/dist/rpc.test.js +7 -0
  250. package/packages/contracts/dist/rpc.test.js.map +1 -1
  251. package/packages/contracts/dist/workflow.d.ts +21 -0
  252. package/packages/contracts/dist/workflow.d.ts.map +1 -1
  253. package/packages/contracts/dist/workflow.js +24 -0
  254. package/packages/contracts/dist/workflow.js.map +1 -1
  255. package/packages/contracts/src/rpc.test.ts +8 -0
  256. package/packages/contracts/src/workflow.ts +24 -0
  257. package/packages/daemon/package.json +2 -2
  258. package/packages/mcp-server/README.md +14 -3
  259. package/packages/mcp-server/dist/workflow-tools.d.ts +0 -3
  260. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  261. package/packages/mcp-server/dist/workflow-tools.js +80 -0
  262. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  263. package/packages/mcp-server/package.json +2 -2
  264. package/packages/mcp-server/src/workflow-tools-parity.test.ts +244 -0
  265. package/packages/mcp-server/src/workflow-tools.test.ts +22 -0
  266. package/packages/mcp-server/src/workflow-tools.ts +168 -0
  267. package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
  268. package/packages/native/package.json +1 -1
  269. package/packages/pi-agent-core/package.json +1 -1
  270. package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -1
  271. package/packages/pi-ai/dist/index.d.ts +2 -2
  272. package/packages/pi-ai/dist/index.d.ts.map +1 -1
  273. package/packages/pi-ai/dist/index.js +1 -1
  274. package/packages/pi-ai/dist/index.js.map +1 -1
  275. package/packages/pi-ai/dist/providers/transform-messages.d.ts +11 -0
  276. package/packages/pi-ai/dist/providers/transform-messages.d.ts.map +1 -1
  277. package/packages/pi-ai/dist/providers/transform-messages.js +20 -0
  278. package/packages/pi-ai/dist/providers/transform-messages.js.map +1 -1
  279. package/packages/pi-ai/package.json +1 -1
  280. package/packages/pi-ai/src/index.ts +7 -2
  281. package/packages/pi-ai/src/providers/transform-messages.ts +24 -0
  282. package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
  283. package/packages/pi-coding-agent/dist/core/system-prompt.js +4 -4
  284. package/packages/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
  285. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/assistant-message-design.test.d.ts +2 -0
  286. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/assistant-message-design.test.d.ts.map +1 -0
  287. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/assistant-message-design.test.js +47 -0
  288. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/assistant-message-design.test.js.map +1 -0
  289. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js +76 -9
  290. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js.map +1 -1
  291. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/user-message-design.test.d.ts +2 -0
  292. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/user-message-design.test.d.ts.map +1 -0
  293. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/user-message-design.test.js +40 -0
  294. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/user-message-design.test.js.map +1 -0
  295. package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.d.ts +0 -1
  296. package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.d.ts.map +1 -1
  297. package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.js +30 -29
  298. package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.js.map +1 -1
  299. package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.test.js +10 -3
  300. package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.test.js.map +1 -1
  301. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  302. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js +13 -13
  303. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js.map +1 -1
  304. package/packages/pi-coding-agent/dist/modes/interactive/components/bash-execution.d.ts +1 -3
  305. package/packages/pi-coding-agent/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
  306. package/packages/pi-coding-agent/dist/modes/interactive/components/bash-execution.js +58 -3
  307. package/packages/pi-coding-agent/dist/modes/interactive/components/bash-execution.js.map +1 -1
  308. package/packages/pi-coding-agent/dist/modes/interactive/components/diff.d.ts +2 -2
  309. package/packages/pi-coding-agent/dist/modes/interactive/components/diff.d.ts.map +1 -1
  310. package/packages/pi-coding-agent/dist/modes/interactive/components/diff.js +12 -6
  311. package/packages/pi-coding-agent/dist/modes/interactive/components/diff.js.map +1 -1
  312. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.d.ts.map +1 -1
  313. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js +14 -41
  314. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js.map +1 -1
  315. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts +0 -1
  316. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  317. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +86 -82
  318. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
  319. package/packages/pi-coding-agent/dist/modes/interactive/components/transcript-design.d.ts +35 -0
  320. package/packages/pi-coding-agent/dist/modes/interactive/components/transcript-design.d.ts.map +1 -0
  321. package/packages/pi-coding-agent/dist/modes/interactive/components/transcript-design.js +152 -0
  322. package/packages/pi-coding-agent/dist/modes/interactive/components/transcript-design.js.map +1 -0
  323. package/packages/pi-coding-agent/dist/modes/interactive/components/tui-style-kit.d.ts +16 -0
  324. package/packages/pi-coding-agent/dist/modes/interactive/components/tui-style-kit.d.ts.map +1 -0
  325. package/packages/pi-coding-agent/dist/modes/interactive/components/tui-style-kit.js +73 -0
  326. package/packages/pi-coding-agent/dist/modes/interactive/components/tui-style-kit.js.map +1 -0
  327. package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.d.ts +1 -1
  328. package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.d.ts.map +1 -1
  329. package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.js +12 -8
  330. package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.js.map +1 -1
  331. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-highlight.test.d.ts +2 -0
  332. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-highlight.test.d.ts.map +1 -0
  333. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-highlight.test.js +17 -0
  334. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-highlight.test.js.map +1 -0
  335. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  336. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.js +105 -1
  337. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.js.map +1 -1
  338. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.d.ts.map +1 -1
  339. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js +27 -26
  340. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js.map +1 -1
  341. package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.test.js +9 -6
  342. package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.test.js.map +1 -1
  343. package/packages/pi-coding-agent/dist/tests/system-prompt-file-safety.test.d.ts +2 -0
  344. package/packages/pi-coding-agent/dist/tests/system-prompt-file-safety.test.d.ts.map +1 -0
  345. package/packages/pi-coding-agent/dist/tests/system-prompt-file-safety.test.js +17 -0
  346. package/packages/pi-coding-agent/dist/tests/system-prompt-file-safety.test.js.map +1 -0
  347. package/packages/pi-coding-agent/package.json +1 -1
  348. package/packages/pi-coding-agent/src/core/system-prompt.ts +4 -4
  349. package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/assistant-message-design.test.ts +56 -0
  350. package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/tool-execution.test.ts +113 -9
  351. package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/user-message-design.test.ts +48 -0
  352. package/packages/pi-coding-agent/src/modes/interactive/components/adaptive-layout.test.ts +10 -3
  353. package/packages/pi-coding-agent/src/modes/interactive/components/adaptive-layout.ts +43 -42
  354. package/packages/pi-coding-agent/src/modes/interactive/components/assistant-message.ts +14 -14
  355. package/packages/pi-coding-agent/src/modes/interactive/components/bash-execution.ts +64 -3
  356. package/packages/pi-coding-agent/src/modes/interactive/components/diff.ts +13 -7
  357. package/packages/pi-coding-agent/src/modes/interactive/components/footer.ts +15 -42
  358. package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +84 -104
  359. package/packages/pi-coding-agent/src/modes/interactive/components/transcript-design.ts +196 -0
  360. package/packages/pi-coding-agent/src/modes/interactive/components/tui-style-kit.ts +94 -0
  361. package/packages/pi-coding-agent/src/modes/interactive/components/user-message.ts +14 -9
  362. package/packages/pi-coding-agent/src/modes/interactive/theme/theme-highlight.test.ts +23 -0
  363. package/packages/pi-coding-agent/src/modes/interactive/theme/theme.ts +106 -1
  364. package/packages/pi-coding-agent/src/modes/interactive/theme/themes.ts +27 -26
  365. package/packages/pi-coding-agent/src/modes/interactive/tui-mode.test.ts +9 -6
  366. package/packages/pi-coding-agent/src/tests/system-prompt-file-safety.test.ts +22 -0
  367. package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
  368. package/packages/pi-tui/dist/__tests__/overlay-layout.test.js +14 -1
  369. package/packages/pi-tui/dist/__tests__/overlay-layout.test.js.map +1 -1
  370. package/packages/pi-tui/dist/overlay-layout.d.ts.map +1 -1
  371. package/packages/pi-tui/dist/overlay-layout.js +9 -6
  372. package/packages/pi-tui/dist/overlay-layout.js.map +1 -1
  373. package/packages/pi-tui/dist/tui.d.ts.map +1 -1
  374. package/packages/pi-tui/dist/tui.js +5 -0
  375. package/packages/pi-tui/dist/tui.js.map +1 -1
  376. package/packages/pi-tui/package.json +1 -1
  377. package/packages/pi-tui/src/__tests__/overlay-layout.test.ts +20 -1
  378. package/packages/pi-tui/src/overlay-layout.ts +10 -7
  379. package/packages/pi-tui/src/tui.ts +6 -0
  380. package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
  381. package/packages/rpc-client/package.json +1 -1
  382. package/packages/rpc-client/tsconfig.tsbuildinfo +1 -1
  383. package/pkg/dist/modes/interactive/theme/theme-highlight.test.d.ts +2 -0
  384. package/pkg/dist/modes/interactive/theme/theme-highlight.test.d.ts.map +1 -0
  385. package/pkg/dist/modes/interactive/theme/theme-highlight.test.js +17 -0
  386. package/pkg/dist/modes/interactive/theme/theme-highlight.test.js.map +1 -0
  387. package/pkg/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  388. package/pkg/dist/modes/interactive/theme/theme.js +105 -1
  389. package/pkg/dist/modes/interactive/theme/theme.js.map +1 -1
  390. package/pkg/dist/modes/interactive/theme/themes.d.ts.map +1 -1
  391. package/pkg/dist/modes/interactive/theme/themes.js +27 -26
  392. package/pkg/dist/modes/interactive/theme/themes.js.map +1 -1
  393. package/pkg/package.json +1 -1
  394. package/src/resources/GSD-WORKFLOW.md +3 -1
  395. package/src/resources/extensions/browser-tools/tools/screenshot.ts +1 -0
  396. package/src/resources/extensions/browser-tools/tools/zoom.ts +1 -0
  397. package/src/resources/extensions/cmux/index.ts +6 -0
  398. package/src/resources/extensions/gsd/auto/contracts.ts +46 -11
  399. package/src/resources/extensions/gsd/auto/loop-deps.ts +9 -5
  400. package/src/resources/extensions/gsd/auto/loop.ts +113 -9
  401. package/src/resources/extensions/gsd/auto/orchestrator.ts +118 -6
  402. package/src/resources/extensions/gsd/auto/phases.ts +158 -19
  403. package/src/resources/extensions/gsd/auto/run-unit.ts +69 -4
  404. package/src/resources/extensions/gsd/auto/session.ts +10 -0
  405. package/src/resources/extensions/gsd/auto/verification-retry-policy.ts +82 -0
  406. package/src/resources/extensions/gsd/auto-dashboard.ts +230 -183
  407. package/src/resources/extensions/gsd/auto-dispatch.ts +15 -1
  408. package/src/resources/extensions/gsd/auto-post-unit.ts +201 -138
  409. package/src/resources/extensions/gsd/auto-prompts.ts +13 -5
  410. package/src/resources/extensions/gsd/auto-recovery.ts +7 -209
  411. package/src/resources/extensions/gsd/auto-runtime-state.ts +5 -0
  412. package/src/resources/extensions/gsd/auto-start.ts +22 -22
  413. package/src/resources/extensions/gsd/auto-unit-closeout.ts +51 -0
  414. package/src/resources/extensions/gsd/auto-verification.ts +46 -38
  415. package/src/resources/extensions/gsd/auto-worktree.ts +8 -0
  416. package/src/resources/extensions/gsd/auto.ts +411 -106
  417. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +21 -6
  418. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +12 -2
  419. package/src/resources/extensions/gsd/bootstrap/register-shortcuts.ts +5 -8
  420. package/src/resources/extensions/gsd/bootstrap/subagent-input.ts +16 -6
  421. package/src/resources/extensions/gsd/bootstrap/system-context.ts +58 -15
  422. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +3 -2
  423. package/src/resources/extensions/gsd/clean-root-preflight.ts +174 -8
  424. package/src/resources/extensions/gsd/commands/catalog.ts +4 -1
  425. package/src/resources/extensions/gsd/commands/handlers/core.ts +25 -1
  426. package/src/resources/extensions/gsd/commands/handlers/notifications-handler.ts +4 -10
  427. package/src/resources/extensions/gsd/commands/handlers/parallel.ts +12 -0
  428. package/src/resources/extensions/gsd/commands-bootstrap.ts +10 -0
  429. package/src/resources/extensions/gsd/commands-handlers.ts +19 -2
  430. package/src/resources/extensions/gsd/context-store.ts +120 -1
  431. package/src/resources/extensions/gsd/db-writer.ts +167 -84
  432. package/src/resources/extensions/gsd/docs/preferences-reference.md +1 -1
  433. package/src/resources/extensions/gsd/doctor-git-checks.ts +44 -6
  434. package/src/resources/extensions/gsd/doctor-types.ts +2 -0
  435. package/src/resources/extensions/gsd/git-service.ts +2 -0
  436. package/src/resources/extensions/gsd/gsd-db.ts +7 -23
  437. package/src/resources/extensions/gsd/health-widget-core.ts +1 -1
  438. package/src/resources/extensions/gsd/health-widget.ts +6 -10
  439. package/src/resources/extensions/gsd/journal.ts +2 -0
  440. package/src/resources/extensions/gsd/knowledge-backfill.ts +164 -0
  441. package/src/resources/extensions/gsd/knowledge-capture.ts +160 -0
  442. package/src/resources/extensions/gsd/knowledge-parser.ts +174 -0
  443. package/src/resources/extensions/gsd/knowledge-projection.ts +241 -0
  444. package/src/resources/extensions/gsd/markdown-renderer.ts +10 -96
  445. package/src/resources/extensions/gsd/md-importer.ts +1 -1
  446. package/src/resources/extensions/gsd/memory-backfill.ts +89 -17
  447. package/src/resources/extensions/gsd/memory-consolidation-scanner.ts +277 -0
  448. package/src/resources/extensions/gsd/migrate/command.ts +5 -0
  449. package/src/resources/extensions/gsd/migrate/preview.ts +10 -0
  450. package/src/resources/extensions/gsd/migrate/transformer.ts +58 -4
  451. package/src/resources/extensions/gsd/migrate/writer.ts +14 -1
  452. package/src/resources/extensions/gsd/native-git-bridge.ts +14 -13
  453. package/src/resources/extensions/gsd/notification-overlay.ts +50 -46
  454. package/src/resources/extensions/gsd/parallel-merge.ts +61 -34
  455. package/src/resources/extensions/gsd/parallel-monitor-overlay.ts +33 -35
  456. package/src/resources/extensions/gsd/prompts/complete-slice.md +14 -12
  457. package/src/resources/extensions/gsd/prompts/discuss-headless.md +20 -2
  458. package/src/resources/extensions/gsd/prompts/discuss.md +20 -2
  459. package/src/resources/extensions/gsd/prompts/system.md +2 -2
  460. package/src/resources/extensions/gsd/provider-switch-observer.ts +185 -0
  461. package/src/resources/extensions/gsd/recovery-classification.ts +18 -1
  462. package/src/resources/extensions/gsd/session-lock.ts +41 -0
  463. package/src/resources/extensions/gsd/state-reconciliation/drift/completion.ts +172 -0
  464. package/src/resources/extensions/gsd/state-reconciliation/drift/merge-state.ts +337 -0
  465. package/src/resources/extensions/gsd/state-reconciliation/drift/project-md.ts +69 -0
  466. package/src/resources/extensions/gsd/state-reconciliation/drift/roadmap.ts +109 -0
  467. package/src/resources/extensions/gsd/state-reconciliation/drift/sketch-flag.ts +68 -0
  468. package/src/resources/extensions/gsd/state-reconciliation/drift/stale-render.ts +185 -0
  469. package/src/resources/extensions/gsd/state-reconciliation/drift/stale-worker.ts +46 -0
  470. package/src/resources/extensions/gsd/state-reconciliation/errors.ts +67 -0
  471. package/src/resources/extensions/gsd/state-reconciliation/index.ts +142 -0
  472. package/src/resources/extensions/gsd/state-reconciliation/registry.ts +27 -0
  473. package/src/resources/extensions/gsd/state-reconciliation/spawn-gate.ts +60 -0
  474. package/src/resources/extensions/gsd/state-reconciliation/types.ts +83 -0
  475. package/src/resources/extensions/gsd/state-reconciliation.ts +21 -53
  476. package/src/resources/extensions/gsd/templates/knowledge.md +2 -2
  477. package/src/resources/extensions/gsd/tests/artifact-retry-cap.test.ts +1 -1
  478. package/src/resources/extensions/gsd/tests/auto-dashboard.test.ts +99 -0
  479. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +729 -176
  480. package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +408 -4
  481. package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +292 -4
  482. package/src/resources/extensions/gsd/tests/auto-runtime-state.test.ts +20 -5
  483. package/src/resources/extensions/gsd/tests/auto-start-orphan-bootstrap.test.ts +18 -0
  484. package/src/resources/extensions/gsd/tests/auto-unit-closeout.test.ts +68 -0
  485. package/src/resources/extensions/gsd/tests/brief-command.test.ts +89 -0
  486. package/src/resources/extensions/gsd/tests/browser-tools-compatibility-declarations.test.ts +62 -0
  487. package/src/resources/extensions/gsd/tests/clean-root-preflight.test.ts +107 -2
  488. package/src/resources/extensions/gsd/tests/closeout-git-deferral.test.ts +16 -0
  489. package/src/resources/extensions/gsd/tests/context-store-decisions-from-memories.test.ts +312 -0
  490. package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +28 -1
  491. package/src/resources/extensions/gsd/tests/db-writer.test.ts +13 -8
  492. package/src/resources/extensions/gsd/tests/decisions-projection-from-memories.test.ts +453 -0
  493. package/src/resources/extensions/gsd/tests/decisions-stop-table-writes.test.ts +348 -0
  494. package/src/resources/extensions/gsd/tests/deep-project-auto-loop.test.ts +20 -2
  495. package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +44 -0
  496. package/src/resources/extensions/gsd/tests/evidence-cross-ref.test.ts +38 -0
  497. package/src/resources/extensions/gsd/tests/freeform-decisions.test.ts +8 -4
  498. package/src/resources/extensions/gsd/tests/gsd-tools.test.ts +11 -7
  499. package/src/resources/extensions/gsd/tests/header-renderer.test.ts +40 -0
  500. package/src/resources/extensions/gsd/tests/headless-milestone-parity.test.ts +10 -0
  501. package/src/resources/extensions/gsd/tests/health-widget.test.ts +14 -4
  502. package/src/resources/extensions/gsd/tests/integration/doctor-git.test.ts +44 -0
  503. package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +26 -0
  504. package/src/resources/extensions/gsd/tests/integration/integration-lifecycle.test.ts +13 -5
  505. package/src/resources/extensions/gsd/tests/integration/integration-proof.test.ts +1 -1
  506. package/src/resources/extensions/gsd/tests/integration/migrate-command.test.ts +48 -3
  507. package/src/resources/extensions/gsd/tests/integration/parallel-merge.test.ts +116 -24
  508. package/src/resources/extensions/gsd/tests/journal-integration.test.ts +0 -1
  509. package/src/resources/extensions/gsd/tests/knowledge-backfill-projection.test.ts +323 -0
  510. package/src/resources/extensions/gsd/tests/knowledge-capture.test.ts +242 -0
  511. package/src/resources/extensions/gsd/tests/knowledge.test.ts +47 -2
  512. package/src/resources/extensions/gsd/tests/load-knowledge-block-rules-only.test.ts +209 -0
  513. package/src/resources/extensions/gsd/tests/markdown-renderer.test.ts +1 -1
  514. package/src/resources/extensions/gsd/tests/memory-consolidation-scanner.test.ts +316 -0
  515. package/src/resources/extensions/gsd/tests/merge-conflict-stops-loop.test.ts +46 -11
  516. package/src/resources/extensions/gsd/tests/migrate-transformer.test.ts +5 -1
  517. package/src/resources/extensions/gsd/tests/migrate-writer-integration.test.ts +6 -1
  518. package/src/resources/extensions/gsd/tests/notification-overlay.test.ts +78 -41
  519. package/src/resources/extensions/gsd/tests/notifications-handler.test.ts +44 -0
  520. package/src/resources/extensions/gsd/tests/originalbase-path-comparison.test.ts +12 -217
  521. package/src/resources/extensions/gsd/tests/parallel-monitor-overlay.test.ts +38 -6
  522. package/src/resources/extensions/gsd/tests/plan-milestone-sketch-render.test.ts +157 -0
  523. package/src/resources/extensions/gsd/tests/post-exec-retry-bypass.test.ts +81 -3
  524. package/src/resources/extensions/gsd/tests/progressive-planning.test.ts +1 -1
  525. package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +32 -1
  526. package/src/resources/extensions/gsd/tests/provider-switch-observer.test.ts +252 -0
  527. package/src/resources/extensions/gsd/tests/resume-dispatch-worktree.test.ts +7 -3
  528. package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +6 -3
  529. package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +16 -4
  530. package/src/resources/extensions/gsd/tests/session-switch-abort-misclassification.test.ts +24 -0
  531. package/src/resources/extensions/gsd/tests/state-corruption-2945.test.ts +71 -58
  532. package/src/resources/extensions/gsd/tests/state-reconciliation-drift.test.ts +952 -0
  533. package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +4 -0
  534. package/src/resources/extensions/gsd/tests/tui-header-lifecycle.test.ts +121 -1
  535. package/src/resources/extensions/gsd/tests/tui-render-kit.test.ts +66 -0
  536. package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +21 -0
  537. package/src/resources/extensions/gsd/tests/verification-retry-policy.test.ts +83 -0
  538. package/src/resources/extensions/gsd/tests/verification-verdict.test.ts +78 -0
  539. package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +6 -0
  540. package/src/resources/extensions/gsd/tests/worktree-journal-events.test.ts +158 -58
  541. package/src/resources/extensions/gsd/tests/worktree-lifecycle.test.ts +597 -118
  542. package/src/resources/extensions/gsd/tests/worktree-telemetry.test.ts +59 -2
  543. package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +34 -0
  544. package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +135 -0
  545. package/src/resources/extensions/gsd/tui/render-kit.ts +109 -0
  546. package/src/resources/extensions/gsd/unit-context-manifest.ts +35 -2
  547. package/src/resources/extensions/gsd/verification-verdict.ts +47 -0
  548. package/src/resources/extensions/gsd/watch/header-renderer.ts +121 -79
  549. package/src/resources/extensions/gsd/watch/splash-palette.ts +11 -0
  550. package/src/resources/extensions/gsd/workflow-logger.ts +4 -0
  551. package/src/resources/extensions/gsd/workflow-mcp.ts +2 -2
  552. package/src/resources/extensions/gsd/worktree-lifecycle.ts +1171 -526
  553. package/src/resources/extensions/gsd/worktree-telemetry.ts +7 -2
  554. package/src/resources/extensions/subagent/index.ts +567 -103
  555. package/src/resources/extensions/subagent/launch.ts +131 -0
  556. package/src/resources/extensions/subagent/run-store.ts +218 -0
  557. package/src/resources/extensions/subagent/tests/launch.test.ts +115 -0
  558. package/src/resources/extensions/subagent/tests/run-store.test.ts +111 -0
  559. package/src/resources/extensions/visual-brief/artifact-policy.ts +41 -0
  560. package/src/resources/extensions/visual-brief/extension-manifest.json +8 -0
  561. package/src/resources/extensions/visual-brief/index.ts +8 -0
  562. package/src/resources/extensions/visual-brief/page-contract.ts +134 -0
  563. package/src/resources/extensions/visual-brief/prompts.ts +147 -0
  564. package/src/resources/extensions/visual-brief/tests/visual-brief.test.ts +172 -0
  565. package/dist/web/standalone/.next/static/chunks/2556.0527fea66e123b7f.js +0 -1
  566. package/dist/web/standalone/.next/static/chunks/app/page-200592a7f3baf579.js +0 -1
  567. package/dist/web/standalone/.next/static/chunks/main-app-d3d4c336195465f9.js +0 -1
  568. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ab5a8926e07ec673.js +0 -1
  569. package/dist/web/standalone/.next/static/css/54ec2745c1da488b.css +0 -1
  570. package/src/resources/extensions/gsd/tests/worktree-resolver.test.ts +0 -1544
  571. /package/dist/web/standalone/.next/static/{drLMkgfHQ8lzS229_HWYR → Qgr2B_MRhPxC0z8fwv4vT}/_buildManifest.js +0 -0
  572. /package/dist/web/standalone/.next/static/{drLMkgfHQ8lzS229_HWYR → Qgr2B_MRhPxC0z8fwv4vT}/_ssgManifest.js +0 -0
@@ -12,7 +12,14 @@ import {
12
12
  resetEmptyTurnCounter,
13
13
  } from "../guided-flow.js";
14
14
  import { clearPathCache } from "../paths.js";
15
- import { getAutoDashboardData, getAutoModeStartModel, isAutoActive, pauseAuto, setCurrentDispatchedModelId } from "../auto.js";
15
+ import {
16
+ getAutoDashboardData,
17
+ getAutoModeStartModel,
18
+ isAutoActive,
19
+ isAutoCompletionStopInProgress,
20
+ pauseAuto,
21
+ setCurrentDispatchedModelId,
22
+ } from "../auto.js";
16
23
  import { getNextFallbackModel, resolveModelWithFallbacksForUnit } from "../preferences.js";
17
24
  import { pauseAutoForProviderError } from "../provider-error-pause.js";
18
25
  import {
@@ -146,8 +153,7 @@ export function isBareClaudeCodeStreamAbortPlaceholder(lastMsg: unknown): boolea
146
153
  * Claude Code abort markers are intentionally ignored when the abort fires
147
154
  * while the session-switch is in flight: the abort is the expected side-effect
148
155
  * of the transition, not a user signal. Other branches (genuine `stopReason
149
- * === "aborted"` with diagnostic content/errorMessage) preserve the prior
150
- * behavior.
156
+ * === "aborted"` with explicit errorMessage) preserve the prior behavior.
151
157
  */
152
158
  export function _handleSessionSwitchAgentEnd(
153
159
  lastMsg: unknown,
@@ -171,10 +177,8 @@ export function _handleSessionSwitchAgentEnd(
171
177
  }
172
178
 
173
179
  if (m.stopReason === "aborted") {
174
- const content = m.content;
175
- const hasEmptyContent = Array.isArray(content) && content.length === 0;
176
180
  const hasErrorMessage = !!m.errorMessage;
177
- if (!hasEmptyContent || hasErrorMessage) {
181
+ if (hasErrorMessage) {
178
182
  resolveCancelled(_buildAbortedPauseContext(m as { errorMessage?: unknown }));
179
183
  }
180
184
  }
@@ -295,6 +299,12 @@ export async function handleAgentEnd(
295
299
  }
296
300
 
297
301
  if (isObjectRecord(lastMsg) && "stopReason" in lastMsg && lastMsg.stopReason === "aborted") {
302
+ if (isAutoCompletionStopInProgress()) {
303
+ resetRetryState(retryState);
304
+ resolveAgentEnd(event);
305
+ return;
306
+ }
307
+
298
308
  // Empty content with aborted stopReason is a non-fatal agent stop (the LLM
299
309
  // chose to end without producing output). Only pause on genuine fatal aborts
300
310
  // that carry error context — e.g. errorMessage field or non-empty content
@@ -326,6 +336,11 @@ export async function handleAgentEnd(
326
336
  // errorMessage looks uninformative.
327
337
  const rawErrorMsg = ("errorMessage" in lastMsg && lastMsg.errorMessage) ? String(lastMsg.errorMessage) : "";
328
338
  if (isUserInitiatedAbortMessage(rawErrorMsg)) {
339
+ if (isAutoCompletionStopInProgress()) {
340
+ resetRetryState(retryState);
341
+ resolveAgentEnd(event);
342
+ return;
343
+ }
329
344
  resolveAgentEndCancelled({
330
345
  message: rawErrorMsg,
331
346
  category: "aborted",
@@ -16,7 +16,7 @@ import { canonicalToolName, clearDiscussionFlowState, isDepthConfirmationAnswer,
16
16
  import { resolveManifest } from "../unit-context-manifest.js";
17
17
  import { isBlockedStateFile, isBashWriteToStateFile, BLOCKED_WRITE_ERROR } from "../write-intercept.js";
18
18
  import { loadFile, saveFile, formatContinue } from "../files.js";
19
- import { getAutoRuntimeSnapshot, isAutoActive, isAutoPaused, markToolEnd, markToolStart, recordToolInvocationError } from "../auto-runtime-state.js";
19
+ import { clearToolInvocationError, getAutoRuntimeSnapshot, isAutoActive, isAutoPaused, markToolEnd, markToolStart, recordToolInvocationError } from "../auto-runtime-state.js";
20
20
 
21
21
  import { checkToolCallLoop, resetToolCallLoopGuard } from "./tool-call-loop-guard.js";
22
22
  import { saveActivityLog } from "../activity-log.js";
@@ -143,7 +143,7 @@ const AUTO_UNIT_SCOPED_TOOLS: Record<string, readonly string[]> = {
143
143
  "plan-slice": ["gsd_plan_slice", "gsd_plan_task", "gsd_decision_save"],
144
144
  "refine-slice": ["gsd_plan_slice", "gsd_plan_task", "gsd_decision_save"],
145
145
  "replan-slice": ["gsd_replan_slice", "gsd_plan_task", "gsd_decision_save"],
146
- "complete-slice": ["gsd_slice_complete", "gsd_decision_save", "gsd_requirement_update", "subagent"],
146
+ "complete-slice": ["gsd_slice_complete", "gsd_task_reopen", "gsd_replan_slice", "gsd_decision_save", "gsd_requirement_update", "subagent"],
147
147
  "reassess-roadmap": ["gsd_reassess_roadmap"],
148
148
  "execute-task": ["gsd_task_complete", "gsd_decision_save"],
149
149
  "execute-task-simple": ["gsd_task_complete", "gsd_decision_save"],
@@ -423,6 +423,10 @@ export function registerHooks(
423
423
  pi: ExtensionAPI,
424
424
  ecosystemHandlers: GSDEcosystemBeforeAgentStartHandler[],
425
425
  ): void {
426
+ // ADR-005 Phase 3b: surface pi-ai ProviderSwitchReport via audit, notification, and counter.
427
+ // Idempotent — only the first registerHooks call installs.
428
+ void import("../provider-switch-observer.js").then((m) => m.installProviderSwitchObserver());
429
+
426
430
  pi.on("session_start", async (_event, ctx) => {
427
431
  const basePath = contextBasePath(ctx);
428
432
  initSessionNotifications(ctx);
@@ -480,6 +484,8 @@ export function registerHooks(
480
484
  }
481
485
  await loadToolApiKeysForSession();
482
486
  if (!isAutoActive()) {
487
+ ctx.ui.setWidget("gsd-progress", undefined);
488
+ ctx.ui.setWidget("gsd-outcome", undefined);
483
489
  const { initHealthWidget } = await import("../health-widget.js");
484
490
  initHealthWidget(ctx);
485
491
  } else {
@@ -892,6 +898,8 @@ export function registerHooks(
892
898
  // Let recordToolInvocationError classify the failure so non-gsd_ harness
893
899
  // errors and deterministic policy rejections are handled consistently.
894
900
  recordToolInvocationError(event.toolName, errorText);
901
+ } else if (isAutoActive()) {
902
+ clearToolInvocationError();
895
903
  }
896
904
  const toolName = canonicalToolName(event.toolName);
897
905
  if (toolName !== "ask_user_questions") return;
@@ -1009,6 +1017,8 @@ export function registerHooks(
1009
1017
  // Let recordToolInvocationError classify the failure so non-gsd_ harness
1010
1018
  // errors and deterministic policy rejections are handled consistently.
1011
1019
  recordToolInvocationError(event.toolName, errorText);
1020
+ } else if (isAutoActive()) {
1021
+ clearToolInvocationError();
1012
1022
  }
1013
1023
  // Safety harness: record tool execution results for evidence cross-referencing
1014
1024
  if (isAutoActive()) {
@@ -1,3 +1,6 @@
1
+ // Project/App: GSD-2
2
+ // File Purpose: Registers GSD keyboard shortcuts for dashboard, notifications, and parallel overlays.
3
+
1
4
  import { existsSync } from "node:fs";
2
5
  import { join } from "node:path";
3
6
 
@@ -39,18 +42,12 @@ export function registerShortcuts(pi: ExtensionAPI): void {
39
42
  };
40
43
 
41
44
  const openNotificationsOverlay = async (ctx: ExtensionContext) => {
42
- const { GSDNotificationOverlay } = await import("../notification-overlay.js");
45
+ const { GSDNotificationOverlay, notificationOverlayOptions } = await import("../notification-overlay.js");
43
46
  await ctx.ui.custom<boolean>(
44
47
  (tui, theme, _kb, done) => new GSDNotificationOverlay(tui, theme, () => done(true)),
45
48
  {
46
49
  overlay: true,
47
- overlayOptions: {
48
- width: "80%",
49
- minWidth: 60,
50
- maxHeight: "88%",
51
- anchor: "center",
52
- backdrop: true,
53
- },
50
+ overlayOptions: notificationOverlayOptions(),
54
51
  },
55
52
  );
56
53
  };
@@ -1,20 +1,30 @@
1
1
  export function extractSubagentAgentClasses(input: unknown): string[] {
2
2
  if (!input || typeof input !== "object") return [];
3
3
 
4
- const record = input as Record<string, unknown>;
5
4
  const agentClasses: string[] = [];
5
+ const visited = new WeakSet<object>();
6
6
  const addAgentClass = (value: unknown): void => {
7
7
  if (typeof value === "string" && value.trim().length > 0) agentClasses.push(value.trim());
8
8
  };
9
- const addFromItems = (value: unknown): void => {
9
+
10
+ const visitItems = (value: unknown): void => {
10
11
  if (!Array.isArray(value)) return;
11
12
  for (const item of value) {
12
- if (item && typeof item === "object") addAgentClass((item as Record<string, unknown>).agent);
13
+ visit(item);
13
14
  }
14
15
  };
15
16
 
16
- addAgentClass(record.agent);
17
- addFromItems(record.tasks);
18
- addFromItems(record.chain);
17
+ const visit = (value: unknown): void => {
18
+ if (!value || typeof value !== "object") return;
19
+ if (visited.has(value)) return;
20
+ visited.add(value);
21
+ const record = value as Record<string, unknown>;
22
+ addAgentClass(record.agent);
23
+ visitItems(record.tasks);
24
+ visitItems(record.chain);
25
+ visitItems(record.parallel);
26
+ };
27
+
28
+ visit(input);
19
29
  return agentClasses;
20
30
  }
@@ -13,6 +13,7 @@ import { resolveAllSkillReferences, renderPreferencesForSystemPrompt, loadEffect
13
13
  import { resolveModelWithFallbacksForUnit } from "../preferences-models.js";
14
14
  import { resolveSkillReference } from "../preferences-skills.js";
15
15
  import { resolveGsdRootFile, resolveSliceFile, resolveSlicePath, resolveTaskFile, resolveTaskFiles, resolveTasksDir, relSliceFile, relSlicePath, relTaskFile } from "../paths.js";
16
+ import { extractIntroAndRules } from "../knowledge-parser.js";
16
17
  import { ensureCodebaseMapFresh, readCodebaseMap } from "../codebase-generator.js";
17
18
  import { hasSkillSnapshot, detectNewSkills, formatSkillsXml } from "../skill-discovery.js";
18
19
  import { getActiveAutoWorktreeContext } from "../auto-worktree.js";
@@ -131,9 +132,14 @@ export async function buildBeforeAgentStartResult(
131
132
  logWarning("bootstrap", `cmux prompt setup skipped: ${(e as Error).message}`);
132
133
  }
133
134
 
135
+ const ctxProjectRoot = (ctx as { projectRoot?: unknown }).projectRoot;
136
+ const basePath = typeof ctxProjectRoot === "string" && ctxProjectRoot.length > 0
137
+ ? ctxProjectRoot
138
+ : process.cwd();
139
+
134
140
  let preferenceBlock = "";
135
141
  if (loadedPreferences) {
136
- const cwd = process.cwd();
142
+ const cwd = basePath;
137
143
  const report = resolveAllSkillReferences(loadedPreferences.preferences, cwd);
138
144
  preferenceBlock = `\n\n${renderPreferencesForSystemPrompt(loadedPreferences.preferences, report.resolutions)}`;
139
145
  if (report.warnings.length > 0) {
@@ -144,14 +150,6 @@ export async function buildBeforeAgentStartResult(
144
150
  }
145
151
  }
146
152
 
147
- const { block: knowledgeBlock, globalSizeKb } = loadKnowledgeBlock(gsdHome(), process.cwd());
148
- if (globalSizeKb > 4) {
149
- ctx.ui.notify(
150
- `GSD: ~/.gsd/agent/KNOWLEDGE.md is ${globalSizeKb.toFixed(1)}KB — consider trimming to keep system prompt lean.`,
151
- "warning",
152
- );
153
- }
154
-
155
153
  // ADR-013 step 5: opportunistic decisions->memories backfill. Idempotent
156
154
  // and best-effort — first run absorbs the existing decisions table into
157
155
  // the memory store; subsequent runs are a single sentinel SELECT.
@@ -159,12 +157,50 @@ export async function buildBeforeAgentStartResult(
159
157
  const { backfillDecisionsToMemories } = await import("../memory-backfill.js");
160
158
  const written = backfillDecisionsToMemories();
161
159
  if (written > 0) {
162
- ctx.ui.notify(`GSD: backfilled ${written} decision${written === 1 ? "" : "s"} into the memory store (ADR-013).`, "info");
160
+ ctx.ui.notify(`GSD: backfilled ${written} decision${written === 1 ? "" : "s"} into the memory store.`, "info");
163
161
  }
164
162
  } catch (e) {
165
163
  logWarning("bootstrap", `decisions backfill failed: ${(e as Error).message}`);
166
164
  }
167
165
 
166
+ // ADR-013 Stage 2b: KNOWLEDGE.md Patterns + Lessons backfill, then
167
+ // re-render the hybrid projection (manual Rules + projected Patterns +
168
+ // projected Lessons). Both are idempotent and best-effort — failures here
169
+ // can't block agent startup.
170
+ try {
171
+ const { backfillKnowledgeToMemories } = await import("../knowledge-backfill.js");
172
+ const writtenK = backfillKnowledgeToMemories(basePath);
173
+ if (writtenK > 0) {
174
+ ctx.ui.notify(`GSD: backfilled ${writtenK} KNOWLEDGE.md row${writtenK === 1 ? "" : "s"} into the memory store.`, "info");
175
+ }
176
+ } catch (e) {
177
+ logWarning("bootstrap", `KNOWLEDGE.md backfill failed: ${(e as Error).message}`);
178
+ }
179
+ try {
180
+ const { renderKnowledgeProjection } = await import("../knowledge-projection.js");
181
+ renderKnowledgeProjection(basePath);
182
+ } catch (e) {
183
+ logWarning("bootstrap", `KNOWLEDGE.md projection render failed: ${(e as Error).message}`);
184
+ }
185
+
186
+ // ADR-013 step 6 preflight: warn when decisions / KNOWLEDGE.md rows are not
187
+ // yet in the memories table. Read-only; never throws. Runs after the two
188
+ // backfills above so the gap report reflects post-backfill state.
189
+ try {
190
+ const { reportConsolidationGaps } = await import("../memory-consolidation-scanner.js");
191
+ reportConsolidationGaps(basePath);
192
+ } catch (e) {
193
+ logWarning("bootstrap", `memory consolidation scan failed: ${(e as Error).message}`);
194
+ }
195
+
196
+ const { block: knowledgeBlock, globalSizeKb } = loadKnowledgeBlock(gsdHome(), basePath);
197
+ if (globalSizeKb > 4) {
198
+ ctx.ui.notify(
199
+ `GSD: ~/.gsd/agent/KNOWLEDGE.md is ${globalSizeKb.toFixed(1)}KB — consider trimming to keep system prompt lean.`,
200
+ "warning",
201
+ );
202
+ }
203
+
168
204
  let newSkillsBlock = "";
169
205
  if (hasSkillSnapshot()) {
170
206
  const newSkills = detectNewSkills();
@@ -370,7 +406,9 @@ export async function loadMemoryBlock(
370
406
  }
371
407
 
372
408
  export function loadKnowledgeBlock(gsdHomeDir: string, cwd: string): { block: string; globalSizeKb: number } {
373
- // 1. Global knowledge (~/.gsd/agent/KNOWLEDGE.md) — cross-project, user-maintained
409
+ // 1. Global knowledge (~/.gsd/agent/KNOWLEDGE.md) — cross-project,
410
+ // user-maintained. NOT migrated to memories (which are project-scoped),
411
+ // so the full file is injected unchanged.
374
412
  let globalKnowledge = "";
375
413
  let globalSizeKb = 0;
376
414
  const globalKnowledgePath = join(gsdHomeDir, "agent", "KNOWLEDGE.md");
@@ -386,13 +424,18 @@ export function loadKnowledgeBlock(gsdHomeDir: string, cwd: string): { block: st
386
424
  }
387
425
  }
388
426
 
389
- // 2. Project knowledge (.gsd/KNOWLEDGE.md) — project-specific
427
+ // 2. Project knowledge (.gsd/KNOWLEDGE.md) — project-specific.
428
+ // ADR-013 Stage 2b: Patterns and Lessons are projected from the
429
+ // memories table and already reach the LLM via loadMemoryBlock. Inject
430
+ // only the intro prose + `## Rules` section here to avoid duplicating
431
+ // Patterns/Lessons content in the prompt. Rules stay manual per
432
+ // ADR-013 line 39 and have no memory equivalent.
390
433
  let projectKnowledge = "";
391
434
  const knowledgePath = resolveGsdRootFile(cwd, "KNOWLEDGE");
392
435
  if (existsSync(knowledgePath)) {
393
436
  try {
394
- const content = readFileSync(knowledgePath, "utf-8").trim();
395
- if (content) projectKnowledge = content;
437
+ const raw = readFileSync(knowledgePath, "utf-8").trim();
438
+ if (raw) projectKnowledge = extractIntroAndRules(raw).trim();
396
439
  } catch (e) {
397
440
  logWarning("bootstrap", `project knowledge file read failed: ${(e as Error).message}`);
398
441
  }
@@ -411,7 +454,7 @@ export function loadKnowledgeBlock(gsdHomeDir: string, cwd: string): { block: st
411
454
  }
412
455
  const body = limitKnowledgeBlock(parts.join("\n\n"), getKnowledgeCharLimit());
413
456
  return {
414
- block: `\n\n[KNOWLEDGE — Rules, patterns, and lessons learned]\n\n${body}`,
457
+ block: `\n\n[KNOWLEDGE — Rules from KNOWLEDGE.md (Patterns and Lessons reach the LLM via the memory block)]\n\n${body}`,
415
458
  globalSizeKb,
416
459
  };
417
460
  }
@@ -5,7 +5,7 @@ import { isAbsolute, join, relative, resolve, sep } from "node:path";
5
5
  import { minimatch } from "minimatch";
6
6
 
7
7
  import { getIsolationMode } from "../preferences.js";
8
- import type { ToolsPolicy } from "../unit-context-manifest.js";
8
+ import { compileSubagentPermissionContract, type ToolsPolicy } from "../unit-context-manifest.js";
9
9
  import { logWarning } from "../workflow-logger.js";
10
10
  import { isGsdWorktreePath, resolveWorktreeProjectRoot } from "../worktree-root.js";
11
11
 
@@ -811,7 +811,8 @@ export function shouldBlockPlanningUnit(
811
811
  if (PLANNING_SUBAGENT_TOOLS.has(tool)) {
812
812
  if (policy.mode === "planning-dispatch") {
813
813
  const requested = (agentClasses ?? []).map(a => a.trim()).filter(Boolean);
814
- const allowedSubagents = Array.isArray(policy.allowedSubagents) ? policy.allowedSubagents : [];
814
+ const dispatchContract = compileSubagentPermissionContract(policy);
815
+ const allowedSubagents = dispatchContract.allowedSubagents;
815
816
  const allowed = new Set(allowedSubagents);
816
817
  // When agentClasses is undefined, the caller has not been updated to extract
817
818
  // agent identities yet. Block and warn so stale callers surface in telemetry
@@ -8,12 +8,14 @@
8
8
  *
9
9
  * Design constraints (from Trek-e approval):
10
10
  * - Warn the user before stashing (no silent surprises)
11
- * - git stash push / git stash pop only no custom stash management layer
12
- * - Stash/pop errors are logged but MUST NOT block the merge itself
11
+ * - git stash push / git stash apply+drop for targeted restore
12
+ * - Stash/apply errors are logged but MUST NOT block the merge itself
13
13
  * - Fast-path status check — clean trees pay no extra cost
14
14
  */
15
15
 
16
16
  import { execFileSync } from "node:child_process";
17
+ import { existsSync, readFileSync } from "node:fs";
18
+ import { join } from "node:path";
17
19
  import { GIT_NO_PROMPT_ENV } from "./git-constants.js";
18
20
  import { logWarning } from "./workflow-logger.js";
19
21
  import { nativeHasChanges } from "./native-git-bridge.js";
@@ -32,6 +34,148 @@ export interface PostflightResult {
32
34
  needsManualRecovery: boolean;
33
35
  message: string;
34
36
  stashRef?: string;
37
+ resolution?: "applied" | "already-present-dropped" | "already-present-preserved" | "manual-recovery";
38
+ collidedPaths?: string[];
39
+ }
40
+
41
+ function gitText(basePath: string, args: string[]): string {
42
+ return execFileSync("git", args, {
43
+ cwd: basePath,
44
+ stdio: ["ignore", "pipe", "pipe"],
45
+ encoding: "utf-8",
46
+ env: GIT_NO_PROMPT_ENV,
47
+ });
48
+ }
49
+
50
+ function gitBuffer(basePath: string, args: string[]): Buffer {
51
+ return execFileSync("git", args, {
52
+ cwd: basePath,
53
+ stdio: ["ignore", "pipe", "pipe"],
54
+ env: GIT_NO_PROMPT_ENV,
55
+ });
56
+ }
57
+
58
+ function errorText(err: unknown): string {
59
+ if (!err || typeof err !== "object") return String(err);
60
+ const parts: string[] = [];
61
+ const stderr = (err as { stderr?: unknown }).stderr;
62
+ const stdout = (err as { stdout?: unknown }).stdout;
63
+ for (const value of [stderr, stdout]) {
64
+ if (typeof value === "string") parts.push(value);
65
+ else if (value instanceof Uint8Array) parts.push(Buffer.from(value).toString("utf-8"));
66
+ }
67
+ parts.push(err instanceof Error ? err.message : String(err));
68
+ return parts.filter(Boolean).join("\n");
69
+ }
70
+
71
+ function parseAlreadyExistsNoCheckoutPaths(text: string): string[] {
72
+ const paths: string[] = [];
73
+ for (const line of text.split(/\r?\n/)) {
74
+ const match = /^(.+?) already exists, no checkout$/i.exec(line.trim());
75
+ if (match?.[1]) paths.push(match[1]);
76
+ }
77
+ return [...new Set(paths)];
78
+ }
79
+
80
+ function readZeroDelimitedPaths(output: string): string[] {
81
+ return output.split("\0").filter(Boolean);
82
+ }
83
+
84
+ function listStashUntrackedPaths(basePath: string, stashRef: string): string[] | null {
85
+ try {
86
+ const output = gitText(basePath, ["ls-tree", "-r", "-z", "--name-only", `${stashRef}^3`]);
87
+ return readZeroDelimitedPaths(output);
88
+ } catch {
89
+ return null;
90
+ }
91
+ }
92
+
93
+ function listStashTrackedPaths(basePath: string, stashRef: string): string[] | null {
94
+ try {
95
+ const output = gitText(basePath, ["diff", "--name-only", "-z", `${stashRef}^1`, stashRef]);
96
+ return readZeroDelimitedPaths(output);
97
+ } catch {
98
+ return null;
99
+ }
100
+ }
101
+
102
+ function isWorktreeClean(basePath: string): boolean | null {
103
+ try {
104
+ return gitText(basePath, ["status", "--porcelain"]).trim() === "";
105
+ } catch {
106
+ return null;
107
+ }
108
+ }
109
+
110
+ function stashBlobEqualsWorktreeFile(basePath: string, stashRef: string, path: string): boolean | null {
111
+ try {
112
+ const worktreePath = join(basePath, path);
113
+ if (!existsSync(worktreePath)) return false;
114
+ const worktreeContent = readFileSync(worktreePath);
115
+ const stashContent = gitBuffer(basePath, ["show", `${stashRef}^3:${path}`]);
116
+ return Buffer.compare(worktreeContent, stashContent) === 0;
117
+ } catch {
118
+ return null;
119
+ }
120
+ }
121
+
122
+ function reconcileAlreadyPresentUntrackedStash(
123
+ basePath: string,
124
+ milestoneId: string,
125
+ stashRef: string,
126
+ err: unknown,
127
+ ): PostflightResult | null {
128
+ const text = errorText(err);
129
+ const collidedPaths = parseAlreadyExistsNoCheckoutPaths(text);
130
+ if (collidedPaths.length === 0) return null;
131
+
132
+ const untrackedPaths = listStashUntrackedPaths(basePath, stashRef);
133
+ if (!untrackedPaths || untrackedPaths.length === 0) return null;
134
+
135
+ const trackedPaths = listStashTrackedPaths(basePath, stashRef);
136
+ if (trackedPaths === null || trackedPaths.length > 0) return null;
137
+
138
+ const untrackedPathSet = new Set(untrackedPaths);
139
+ if (!collidedPaths.every((path) => untrackedPathSet.has(path))) return null;
140
+ if (!untrackedPaths.every((path) => existsSync(join(basePath, path)))) return null;
141
+ if (isWorktreeClean(basePath) !== true) return null;
142
+
143
+ const blobComparisons = untrackedPaths.map((path) => stashBlobEqualsWorktreeFile(basePath, stashRef, path));
144
+ if (blobComparisons.some((result) => result === null)) return null;
145
+ const allIdentical = blobComparisons.every(Boolean);
146
+ if (allIdentical) {
147
+ let dropped = true;
148
+ try {
149
+ execFileSync("git", ["stash", "drop", stashRef], {
150
+ cwd: basePath,
151
+ stdio: ["ignore", "pipe", "pipe"],
152
+ encoding: "utf-8",
153
+ env: GIT_NO_PROMPT_ENV,
154
+ });
155
+ } catch (err) {
156
+ dropped = false;
157
+ logWarning("preflight", `git stash drop ${stashRef} failed after identical preflight stash reconciliation: ${err instanceof Error ? err.message : String(err)}`);
158
+ }
159
+ return {
160
+ restored: true,
161
+ needsManualRecovery: false,
162
+ message: dropped
163
+ ? `Preflight stash for milestone ${milestoneId} contained files already present after merge; identical stash dropped.`
164
+ : `Preflight stash for milestone ${milestoneId} contained files already present after merge, but ${stashRef} could not be dropped and remains as a backup.`,
165
+ stashRef,
166
+ resolution: dropped ? "already-present-dropped" : "already-present-preserved",
167
+ collidedPaths,
168
+ };
169
+ }
170
+
171
+ return {
172
+ restored: false,
173
+ needsManualRecovery: false,
174
+ message: `Preflight stash for milestone ${milestoneId} contained untracked files already present after merge. Keeping merged files and preserving ${stashRef} as a backup.`,
175
+ stashRef,
176
+ resolution: "already-present-preserved",
177
+ collidedPaths,
178
+ };
35
179
  }
36
180
 
37
181
  function findPreflightStashRef(basePath: string, milestoneId: string, stashMarker?: string): string | null {
@@ -141,27 +285,48 @@ export function postflightPopStash(
141
285
  message: msg,
142
286
  };
143
287
  }
144
- execFileSync("git", ["stash", "pop", stashRef], {
288
+ execFileSync("git", ["stash", "apply", stashRef], {
145
289
  cwd: basePath,
146
290
  stdio: ["ignore", "pipe", "pipe"],
147
291
  encoding: "utf-8",
148
292
  env: GIT_NO_PROMPT_ENV,
149
293
  });
294
+ let dropWarning: string | null = null;
295
+ try {
296
+ execFileSync("git", ["stash", "drop", stashRef], {
297
+ cwd: basePath,
298
+ stdio: ["ignore", "pipe", "pipe"],
299
+ encoding: "utf-8",
300
+ env: GIT_NO_PROMPT_ENV,
301
+ });
302
+ } catch (err) {
303
+ dropWarning = ` Stash was restored, but git stash drop ${stashRef} failed: ${err instanceof Error ? err.message : String(err)}.`;
304
+ logWarning("preflight", dropWarning.trim());
305
+ }
150
306
  const msg = `Restored stashed changes after milestone ${milestoneId} merge.`;
151
- notify(msg, "info");
307
+ notify(`${msg}${dropWarning ?? ""}`, dropWarning ? "warning" : "info");
152
308
  return {
153
309
  restored: true,
154
310
  needsManualRecovery: false,
155
- message: msg,
311
+ message: `${msg}${dropWarning ?? ""}`,
156
312
  stashRef,
313
+ resolution: "applied",
157
314
  };
158
315
  } catch (err) {
159
- // Pop conflicts mean the merged code collides with the stashed changes.
316
+ if (stashRef) {
317
+ const reconciled = reconcileAlreadyPresentUntrackedStash(basePath, milestoneId, stashRef, err);
318
+ if (reconciled) {
319
+ logWarning("preflight", reconciled.message);
320
+ notify(reconciled.message, reconciled.resolution === "already-present-preserved" ? "warning" : "info");
321
+ return reconciled;
322
+ }
323
+ }
324
+ // Apply conflicts mean the merged code collides with the stashed changes.
160
325
  // Log a warning — the user needs to resolve manually, but the merge succeeded.
161
326
  const restoreHint = stashRef
162
- ? `Run "git stash pop ${stashRef}" or "git stash apply ${stashRef}" manually to restore the correct stash.`
327
+ ? `Run "git stash apply ${stashRef}" manually to restore the correct stash, then "git stash drop ${stashRef}" after recovery.`
163
328
  : `Run "git stash list" to find the matching GSD preflight stash before restoring manually.`;
164
- const msg = `git stash pop ${stashRef ?? ""}`.trim() + ` failed after merge of milestone ${milestoneId}: ${err instanceof Error ? err.message : String(err)}. ${restoreHint}`;
329
+ const msg = `git stash apply ${stashRef ?? ""}`.trim() + ` failed after merge of milestone ${milestoneId}: ${err instanceof Error ? err.message : String(err)}. ${restoreHint}`;
165
330
  logWarning("preflight", msg);
166
331
  notify(msg, "warning");
167
332
  return {
@@ -169,6 +334,7 @@ export function postflightPopStash(
169
334
  needsManualRecovery: true,
170
335
  message: msg,
171
336
  ...(stashRef ? { stashRef } : {}),
337
+ resolution: "manual-recovery",
172
338
  };
173
339
  }
174
340
  }
@@ -3,6 +3,7 @@ import { join, resolve } from "node:path";
3
3
 
4
4
  import { loadRegistry } from "../workflow-templates.js";
5
5
  import { gsdHome } from "../gsd-home.js";
6
+ import { VISUAL_BRIEF_MODES } from "../../visual-brief/prompts.js";
6
7
 
7
8
 
8
9
  export interface GsdCommandDefinition {
@@ -13,7 +14,7 @@ export interface GsdCommandDefinition {
13
14
  type CompletionMap = Record<string, readonly GsdCommandDefinition[]>;
14
15
 
15
16
  export const GSD_COMMAND_DESCRIPTION =
16
- "GSD — Get Shit Done: /gsd help|start|templates|next|auto|stop|pause|status|widget|visualize|queue|quick|discuss|capture|triage|dispatch|history|undo|undo-task|reset-slice|rate|skip|export|cleanup|model|mode|prefs|config|keys|hooks|run-hook|skill-health|doctor|debug|logs|forensics|changelog|migrate|remote|steer|knowledge|new-milestone|new-project|parallel|cmux|park|unpark|init|setup|onboarding|inspect|extensions|update|fast|mcp|rethink|workflow|codebase|notifications|ship|do|session-report|backlog|pr-branch|add-tests|scan|language|worktree|eval-review";
17
+ "GSD — Get Shit Done: /gsd help|start|templates|next|auto|stop|pause|status|widget|visualize|brief|queue|quick|discuss|capture|triage|dispatch|history|undo|undo-task|reset-slice|rate|skip|export|cleanup|model|mode|prefs|config|keys|hooks|run-hook|skill-health|doctor|debug|logs|forensics|changelog|migrate|remote|steer|knowledge|new-milestone|new-project|parallel|cmux|park|unpark|init|setup|onboarding|inspect|extensions|update|fast|mcp|rethink|workflow|codebase|notifications|ship|do|session-report|backlog|pr-branch|add-tests|scan|language|worktree|eval-review";
17
18
 
18
19
  export const TOP_LEVEL_SUBCOMMANDS: readonly GsdCommandDefinition[] = [
19
20
  { cmd: "help", desc: "Categorized command reference with descriptions" },
@@ -24,6 +25,7 @@ export const TOP_LEVEL_SUBCOMMANDS: readonly GsdCommandDefinition[] = [
24
25
  { cmd: "status", desc: "Progress dashboard" },
25
26
  { cmd: "widget", desc: "Cycle widget: full → small → min → off" },
26
27
  { cmd: "visualize", desc: "Open 10-tab workflow visualizer (progress, timeline, deps, metrics, health, agent, changes, knowledge, captures, export)" },
28
+ { cmd: "brief", desc: "Generate a visual HTML brief: diagram, plan, diff review, recap, table, or slides" },
27
29
  { cmd: "queue", desc: "Queue and reorder future milestones" },
28
30
  { cmd: "quick", desc: "Execute a quick task without full planning overhead" },
29
31
  { cmd: "discuss", desc: "Discuss architecture and decisions" },
@@ -88,6 +90,7 @@ export const TOP_LEVEL_SUBCOMMANDS: readonly GsdCommandDefinition[] = [
88
90
  ];
89
91
 
90
92
  const NESTED_COMPLETIONS: CompletionMap = {
93
+ brief: VISUAL_BRIEF_MODES.map((mode) => ({ cmd: mode.mode, desc: mode.description })),
91
94
  auto: [
92
95
  { cmd: "--verbose", desc: "Show detailed execution output" },
93
96
  { cmd: "--debug", desc: "Enable debug logging" },
@@ -11,6 +11,8 @@ import { handleCmux } from "../../commands-cmux.js";
11
11
  import { setSessionModelOverride } from "../../session-model-override.js";
12
12
  import { projectRoot } from "../context.js";
13
13
  import { formattedShortcutPair } from "../../shortcut-defs.js";
14
+ import { getVisualBriefOutputDir } from "../../../visual-brief/artifact-policy.js";
15
+ import { buildVisualBriefPrompt, parseVisualBriefArgs, VISUAL_BRIEF_USAGE } from "../../../visual-brief/prompts.js";
14
16
 
15
17
  export function showHelp(ctx: ExtensionCommandContext, args = ""): void {
16
18
  const summaryLines = [
@@ -27,6 +29,7 @@ export function showHelp(ctx: ExtensionCommandContext, args = ""): void {
27
29
  ` /gsd parallel watch Parallel monitor (${formattedShortcutPair("parallel")})`,
28
30
  ` /gsd notifications Notification history (${formattedShortcutPair("notifications")})`,
29
31
  " /gsd visualize Interactive 10-tab TUI",
32
+ " /gsd brief <mode> Visual HTML brief (diagram, plan, diff, recap, table, slides)",
30
33
  " /gsd queue Show queued/dispatched units",
31
34
  "",
32
35
  "COURSE CORRECTION",
@@ -75,6 +78,7 @@ export function showHelp(ctx: ExtensionCommandContext, args = ""): void {
75
78
  ` /gsd parallel watch Open parallel worker monitor (${formattedShortcutPair("parallel")})`,
76
79
  " /gsd widget Cycle status widget [full|small|min|off]",
77
80
  " /gsd visualize Interactive 10-tab TUI (progress, timeline, deps, metrics, health, agent, changes, knowledge, captures, export)",
81
+ " /gsd brief <mode> Generate a visual HTML brief [diagram|plan|diff|recap|table|slides] [topic] [--slides]",
78
82
  " /gsd queue Show queued/dispatched units and execution order",
79
83
  " /gsd history View execution history [--cost] [--phase] [--model] [N]",
80
84
  " /gsd changelog Show categorized release notes [version]",
@@ -96,7 +100,7 @@ export function showHelp(ctx: ExtensionCommandContext, args = ""): void {
96
100
  " /gsd unpark [id] Reactivate a parked milestone",
97
101
  "",
98
102
  "PROJECT KNOWLEDGE",
99
- " /gsd knowledge <type> <text> Add rule, pattern, or lesson to KNOWLEDGE.md",
103
+ " /gsd knowledge <type> <text> Add a rule to KNOWLEDGE.md or capture a pattern/lesson to memories",
100
104
  " /gsd codebase [generate|update|stats] Manage the CODEBASE.md cache used in prompt context",
101
105
  "",
102
106
  "SHIPPING & BACKLOG",
@@ -203,6 +207,22 @@ export async function handleVisualize(ctx: ExtensionCommandContext): Promise<voi
203
207
  }
204
208
  }
205
209
 
210
+ export async function handleBrief(args: string, ctx: ExtensionCommandContext, pi?: ExtensionAPI): Promise<void> {
211
+ const request = parseVisualBriefArgs(args);
212
+ if (!request) {
213
+ ctx.ui.notify(VISUAL_BRIEF_USAGE, "info");
214
+ return;
215
+ }
216
+
217
+ if (!pi?.sendUserMessage) {
218
+ ctx.ui.notify("Visual brief generation is unavailable in this context.", "warning");
219
+ return;
220
+ }
221
+
222
+ const outputDir = getVisualBriefOutputDir();
223
+ pi.sendUserMessage(buildVisualBriefPrompt(request, { outputDir }));
224
+ }
225
+
206
226
  export async function handleSetup(args: string, ctx: ExtensionCommandContext, pi?: ExtensionAPI): Promise<void> {
207
227
  const { detectProjectState, hasGlobalSetup } = await import("../../detection.js");
208
228
  const { isOnboardingComplete, readOnboardingRecord } = await import("../../onboarding-state.js");
@@ -429,6 +449,10 @@ export async function handleCoreCommand(
429
449
  await handleVisualize(ctx);
430
450
  return true;
431
451
  }
452
+ if (trimmed === "brief" || trimmed.startsWith("brief ")) {
453
+ await handleBrief(trimmed.replace(/^brief\s*/, "").trim(), ctx, pi);
454
+ return true;
455
+ }
432
456
  if (trimmed === "widget" || trimmed.startsWith("widget ")) {
433
457
  const { cycleWidgetMode, setWidgetMode, getWidgetMode } = await import("../../auto-dashboard.js");
434
458
  const arg = trimmed.replace(/^widget\s*/, "").trim();