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,252 @@
1
+ // GSD-2 — ADR-005 Phase 3b: ProviderSwitchObserver Tests
2
+ import test from "node:test";
3
+ import assert from "node:assert/strict";
4
+ import { mkdtempSync, readFileSync, rmSync, existsSync } from "node:fs";
5
+ import { join } from "node:path";
6
+ import { tmpdir } from "node:os";
7
+
8
+ import { setProviderSwitchObserver, type ProviderSwitchReport } from "@gsd/pi-ai";
9
+
10
+ import { autoSession } from "../auto-runtime-state.ts";
11
+ import {
12
+ initNotificationStore,
13
+ readNotifications,
14
+ _resetNotificationStore,
15
+ } from "../notification-store.ts";
16
+ import {
17
+ _resetProviderSwitchStats,
18
+ getProviderSwitchStats,
19
+ installProviderSwitchObserver,
20
+ uninstallProviderSwitchObserver,
21
+ } from "../provider-switch-observer.ts";
22
+
23
+ function makeReport(overrides: Partial<ProviderSwitchReport> = {}): ProviderSwitchReport {
24
+ return {
25
+ fromApi: "anthropic-messages",
26
+ toApi: "openai-responses",
27
+ thinkingBlocksDropped: 0,
28
+ thinkingBlocksDowngraded: 0,
29
+ toolCallIdsRemapped: 0,
30
+ syntheticToolResultsInserted: 0,
31
+ thoughtSignaturesDropped: 0,
32
+ ...overrides,
33
+ };
34
+ }
35
+
36
+ function withTempBasePath(): { basePath: string; cleanup: () => void } {
37
+ const basePath = mkdtempSync(join(tmpdir(), "gsd-provider-switch-"));
38
+ return {
39
+ basePath,
40
+ cleanup: () => rmSync(basePath, { recursive: true, force: true }),
41
+ };
42
+ }
43
+
44
+ test.beforeEach(() => {
45
+ _resetProviderSwitchStats();
46
+ _resetNotificationStore();
47
+ autoSession.currentTraceId = null;
48
+ autoSession.basePath = "";
49
+ });
50
+
51
+ test.afterEach(() => {
52
+ uninstallProviderSwitchObserver();
53
+ _resetNotificationStore();
54
+ autoSession.currentTraceId = null;
55
+ autoSession.basePath = "";
56
+ });
57
+
58
+ test("installProviderSwitchObserver wires the pi-ai observer hook", () => {
59
+ installProviderSwitchObserver();
60
+ // Indirect: a second install is a no-op. We verify by checking the counter
61
+ // increments exactly once when we fire a single report directly into pi-ai's
62
+ // observer slot.
63
+ installProviderSwitchObserver();
64
+
65
+ // Drive the pi-ai observer directly. The install above pointed it at our
66
+ // handler; firing here exercises the same code path as a real transform.
67
+ // We can't reach the installed handler reference from here, so we re-install
68
+ // a sentinel and confirm setProviderSwitchObserver accepts undefined.
69
+ setProviderSwitchObserver(undefined);
70
+ assert.ok(true); // install/uninstall did not throw
71
+ });
72
+
73
+ test("non-empty report increments the in-memory counter", () => {
74
+ installProviderSwitchObserver();
75
+
76
+ // Reach into the installed handler via setProviderSwitchObserver re-binding.
77
+ // We snapshot the handler by re-installing, capturing nothing — instead we
78
+ // use the public API: drive a report through the observer hook directly by
79
+ // calling setProviderSwitchObserver with a wrapper that proxies into the
80
+ // installed handler. This is awkward without a separate seam, so we test
81
+ // the recordReport path end-to-end by firing through pi-ai's transform helper
82
+ // pattern in a sibling test below. Here we exercise install idempotency only.
83
+
84
+ // Fire by setting our own observer that forwards to the module API isn't
85
+ // possible without exporting handleReport. Instead, verify install state
86
+ // doesn't crash; the real fire path is covered by the integration test
87
+ // below that exercises transformMessagesWithReport.
88
+ assert.deepEqual(getProviderSwitchStats().totalSwitches, 0);
89
+ });
90
+
91
+ test("end-to-end: transformMessagesWithReport fires the observer and updates stats + notifications", async () => {
92
+ const { transformMessagesWithReport } = await import("@gsd/pi-ai");
93
+
94
+ const { basePath, cleanup } = withTempBasePath();
95
+ try {
96
+ initNotificationStore(basePath);
97
+ installProviderSwitchObserver();
98
+
99
+ // Construct a cross-API transform that will drop a redacted thinking block.
100
+ const targetModel = {
101
+ id: "gpt-5",
102
+ name: "GPT-5",
103
+ api: "openai-responses",
104
+ provider: "openai",
105
+ baseUrl: "",
106
+ reasoning: false,
107
+ input: ["text"],
108
+ cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
109
+ contextWindow: 128000,
110
+ maxTokens: 8192,
111
+ } as Parameters<typeof transformMessagesWithReport>[1];
112
+
113
+ const messages = [
114
+ {
115
+ role: "assistant" as const,
116
+ content: [
117
+ { type: "thinking" as const, thinking: "", redacted: true },
118
+ { type: "text" as const, text: "hi" },
119
+ ],
120
+ api: "anthropic-messages",
121
+ provider: "anthropic",
122
+ model: "claude-sonnet-4-6",
123
+ usage: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, totalTokens: 0, cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 } },
124
+ stopReason: "stop" as const,
125
+ timestamp: Date.now(),
126
+ },
127
+ ];
128
+
129
+ transformMessagesWithReport(messages as Parameters<typeof transformMessagesWithReport>[0], targetModel, undefined, "anthropic-messages");
130
+
131
+ const stats = getProviderSwitchStats();
132
+ assert.equal(stats.totalSwitches, 1, "non-empty report should bump the counter");
133
+ assert.ok(stats.totals.thinkingBlocksDropped >= 1, "thinking block drop should be tallied");
134
+ assert.ok(stats.lastReport, "last report should be retained");
135
+ assert.equal(stats.lastReport?.fromApi, "anthropic-messages");
136
+ assert.equal(stats.lastReport?.toApi, "openai-responses");
137
+
138
+ // Notification persistence — the observer is interactive (no traceId), so
139
+ // the byTrace key falls back to "interactive".
140
+ assert.ok("interactive" in stats.byTrace, "interactive trace bucket should exist");
141
+ assert.equal(stats.byTrace.interactive?.switches, 1);
142
+
143
+ const notifications = readNotifications(basePath);
144
+ const switchNotifs = notifications.filter((n) => n.message.includes("Provider switch"));
145
+ assert.ok(switchNotifs.length >= 1, "a provider-switch notification should be persisted");
146
+ assert.equal(switchNotifs[0]?.severity, "warning");
147
+ } finally {
148
+ cleanup();
149
+ }
150
+ });
151
+
152
+ test("end-to-end: audit event is emitted when an auto trace is active", async () => {
153
+ const { transformMessagesWithReport } = await import("@gsd/pi-ai");
154
+
155
+ const { basePath, cleanup } = withTempBasePath();
156
+ try {
157
+ initNotificationStore(basePath);
158
+ installProviderSwitchObserver();
159
+ autoSession.basePath = basePath;
160
+ autoSession.currentTraceId = "trace-provider-switch-1";
161
+
162
+ const targetModel = {
163
+ id: "gpt-5",
164
+ name: "GPT-5",
165
+ api: "openai-responses",
166
+ provider: "openai",
167
+ baseUrl: "",
168
+ reasoning: false,
169
+ input: ["text"],
170
+ cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
171
+ contextWindow: 128000,
172
+ maxTokens: 8192,
173
+ } as Parameters<typeof transformMessagesWithReport>[1];
174
+
175
+ const messages = [
176
+ {
177
+ role: "assistant" as const,
178
+ content: [
179
+ { type: "thinking" as const, thinking: "", redacted: true },
180
+ { type: "text" as const, text: "hi" },
181
+ ],
182
+ api: "anthropic-messages",
183
+ provider: "anthropic",
184
+ model: "claude-sonnet-4-6",
185
+ usage: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, totalTokens: 0, cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 } },
186
+ stopReason: "stop" as const,
187
+ timestamp: Date.now(),
188
+ },
189
+ ];
190
+
191
+ transformMessagesWithReport(messages as Parameters<typeof transformMessagesWithReport>[0], targetModel, undefined, "anthropic-messages");
192
+
193
+ const auditLogPath = join(basePath, ".gsd", "audit", "events.jsonl");
194
+ assert.ok(existsSync(auditLogPath), "audit events file should be created");
195
+ const auditLines = readFileSync(auditLogPath, "utf-8")
196
+ .trim()
197
+ .split("\n")
198
+ .map((line) => JSON.parse(line) as { category: string; type: string; traceId: string; payload: Record<string, unknown> });
199
+ const switchEvent = auditLines.find((e) => e.category === "model-policy" && e.type === "provider-switch");
200
+ assert.ok(switchEvent, "a model-policy/provider-switch audit event should be present");
201
+ assert.equal(switchEvent?.traceId, "trace-provider-switch-1");
202
+ assert.equal(switchEvent?.payload.fromApi, "anthropic-messages");
203
+ assert.equal(switchEvent?.payload.toApi, "openai-responses");
204
+
205
+ const stats = getProviderSwitchStats();
206
+ assert.ok("trace-provider-switch-1" in stats.byTrace, "trace-keyed bucket should be populated");
207
+ assert.equal(stats.byTrace["trace-provider-switch-1"]?.switches, 1);
208
+ } finally {
209
+ cleanup();
210
+ }
211
+ });
212
+
213
+ test("empty report does not bump counter or emit a notification", async () => {
214
+ const { transformMessagesWithReport } = await import("@gsd/pi-ai");
215
+
216
+ const { basePath, cleanup } = withTempBasePath();
217
+ try {
218
+ initNotificationStore(basePath);
219
+ installProviderSwitchObserver();
220
+
221
+ // Same-API transform → no transformations → empty report.
222
+ const sameApiModel = {
223
+ id: "claude-sonnet-4-6",
224
+ name: "Claude Sonnet 4.6",
225
+ api: "anthropic-messages",
226
+ provider: "anthropic",
227
+ baseUrl: "",
228
+ reasoning: false,
229
+ input: ["text"],
230
+ cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
231
+ contextWindow: 200000,
232
+ maxTokens: 8192,
233
+ } as Parameters<typeof transformMessagesWithReport>[1];
234
+
235
+ transformMessagesWithReport(
236
+ [
237
+ {
238
+ role: "user" as const,
239
+ content: "plain text — no transforms triggered",
240
+ },
241
+ ] as Parameters<typeof transformMessagesWithReport>[0],
242
+ sameApiModel,
243
+ undefined,
244
+ "anthropic-messages",
245
+ );
246
+
247
+ assert.equal(getProviderSwitchStats().totalSwitches, 0);
248
+ assert.equal(readNotifications(basePath).length, 0);
249
+ } finally {
250
+ cleanup();
251
+ }
252
+ });
@@ -10,7 +10,11 @@ import { join } from "node:path";
10
10
  import { tmpdir } from "node:os";
11
11
  import { randomUUID } from "node:crypto";
12
12
 
13
- import { _resolvePausedResumeBasePathForTest } from "../auto.ts";
13
+ // ADR-016 phase 2 / B3 (#5621): the legacy `resolvePausedResumeBasePath`
14
+ // helper was retired and folded into `WorktreeLifecycle.resumeFromPausedSession`.
15
+ // The pure path-resolution function lives in `worktree-lifecycle.ts` for tests
16
+ // that exercise the path-resolution invariant without constructing a session.
17
+ import { resolvePausedResumeBasePath } from "../worktree-lifecycle.ts";
14
18
 
15
19
  function makeTmpBase(): string {
16
20
  const base = join(tmpdir(), `gsd-resume-wt-${randomUUID()}`);
@@ -59,7 +63,7 @@ test("resume base path uses paused-session worktreePath when the worktree exists
59
63
  try {
60
64
  setupWorktreeOnDisk(wt);
61
65
  assert.equal(
62
- _resolvePausedResumeBasePathForTest(base, wt),
66
+ resolvePausedResumeBasePath(base, wt),
63
67
  wt,
64
68
  );
65
69
  } finally {
@@ -72,7 +76,7 @@ test("resume base path falls back to project root when paused worktree is missin
72
76
  const wt = makeWorktreePath(base, "M001-test");
73
77
  try {
74
78
  assert.equal(
75
- _resolvePausedResumeBasePathForTest(base, wt),
79
+ resolvePausedResumeBasePath(base, wt),
76
80
  base,
77
81
  );
78
82
  } finally {
@@ -42,16 +42,19 @@ test("State Reconciliation invalidates cache and returns reconciled state", asyn
42
42
  assert.equal(result.ok && result.stateSnapshot, state);
43
43
  });
44
44
 
45
- test("State Reconciliation blocks when derived state carries blockers", async () => {
45
+ test("State Reconciliation surfaces terminal blockers in result (ADR-017)", async () => {
46
+ // Under ADR-017, blockers are terminal but do not throw — they ride along
47
+ // in the result so the orchestrator adapter can map them to ok=false.
46
48
  const result = await reconcileBeforeDispatch("/project", {
47
49
  invalidateStateCache() {},
48
50
  async deriveState() {
49
51
  return makeState({ phase: "blocked", blockers: ["slice lock missing"] });
50
52
  },
53
+ registry: [],
51
54
  });
52
55
 
53
- assert.equal(result.ok, false);
54
- assert.equal(!result.ok && result.reason, "slice lock missing");
56
+ assert.equal(result.ok, true);
57
+ assert.deepEqual(result.blockers, ["slice lock missing"]);
55
58
  });
56
59
 
57
60
  test("Tool Contract compiles known Unit prompt and tool policy", () => {
@@ -1,9 +1,11 @@
1
+ // Project/App: GSD-2
2
+ // File Purpose: Verifies GSD session hook widget and footer lifecycle behavior.
3
+
1
4
  /**
2
- * session-start-footer.test.ts
3
- *
4
5
  * Verifies that register-hooks.ts suppresses the gsd-health widget (not the
5
- * built-in footer) when isAutoActive() is true, and that setFooter is never
6
- * called by the extension in either session_start or session_switch.
6
+ * built-in footer) when isAutoActive() is true, clears stale completion widgets
7
+ * on inactive session switches, and that setFooter is never called by the
8
+ * extension in either session_start or session_switch.
7
9
  *
8
10
  * Testing strategy:
9
11
  * 1. Source-code regression guards: structural checks on register-hooks.ts.
@@ -139,6 +141,16 @@ test("session_switch toggles gsd-health from runtime auto state without touching
139
141
  widgetCalls.length = 0;
140
142
  autoSession.active = false;
141
143
  await sessionSwitch!({ reason: "resume" }, ctx);
144
+ assert.deepEqual(
145
+ widgetCalls
146
+ .filter((call) => call.key === "gsd-progress" || call.key === "gsd-outcome")
147
+ .map((call) => [call.key, call.value]),
148
+ [
149
+ ["gsd-progress", undefined],
150
+ ["gsd-outcome", undefined],
151
+ ],
152
+ "session_switch should clear stale GSD completion widgets when auto is inactive",
153
+ );
142
154
  const healthWidgetValues = widgetCalls
143
155
  .filter((call) => call.key === "gsd-health")
144
156
  .map((call) => call.value);
@@ -188,6 +188,30 @@ test("empty-content aborted during session-switch is silently ignored", () => {
188
188
  assert.equal(cancelledWith, null);
189
189
  });
190
190
 
191
+ test("completed assistant content with aborted stopReason during session-switch is ignored", () => {
192
+ // newSession() can abort the just-finished provider stream while the last
193
+ // assistant message still carries the completed unit summary. That is a
194
+ // session-transition artifact, not a cancellation for the next unit.
195
+ let cancelledWith: unknown = null;
196
+ const resolveCancelled = (ctx: ErrorContext) => {
197
+ cancelledWith = ctx;
198
+ return true;
199
+ };
200
+
201
+ _handleSessionSwitchAgentEnd(
202
+ {
203
+ stopReason: "aborted",
204
+ content: [{
205
+ type: "text",
206
+ text: "Implemented T01 and verified the slice task is complete.",
207
+ }],
208
+ },
209
+ resolveCancelled,
210
+ );
211
+
212
+ assert.equal(cancelledWith, null);
213
+ });
214
+
191
215
  test("non-abort errors during session-switch are not propagated through this helper", () => {
192
216
  // Real provider errors (rate-limit, network, unsupported-model) are handled
193
217
  // by the post-switch retry pipeline — not by the in-flight switch handler.
@@ -10,9 +10,10 @@
10
10
 
11
11
  import { describe, test, beforeEach, afterEach } from "node:test";
12
12
  import assert from "node:assert/strict";
13
- import { mkdtempSync, mkdirSync, readFileSync, rmSync, writeFileSync, existsSync } from "node:fs";
13
+ import { mkdtempSync, mkdirSync, readFileSync, rmSync, writeFileSync, existsSync, realpathSync } from "node:fs";
14
14
  import { join } from "node:path";
15
15
  import { tmpdir } from "node:os";
16
+ import { execFileSync } from "node:child_process";
16
17
  import {
17
18
  openDatabase,
18
19
  closeDatabase,
@@ -263,63 +264,69 @@ describe("#2945 Bug 2: workflow-reconcile bypasses task validation for complete_
263
264
 
264
265
  describe("#2945 Bug 3: mergeAndExit must teardown worktree after successful merge", () => {
265
266
 
266
- test("_mergeWorktreeMode calls teardownAutoWorktree after successful merge", async () => {
267
- // Test the WorktreeResolver to verify teardown is called after merge.
268
- // We use a mock-based approach since actual worktrees require a git repo.
269
- let teardownCalled = false;
270
- let teardownMilestoneId = "";
271
-
272
- const mockSession = {
273
- basePath: "/mock/worktree/M001",
274
- originalBasePath: "/mock/project",
275
- isolationDegraded: false,
276
- gitService: {} as unknown,
277
- } as unknown as AutoSession;
278
-
279
- const { WorktreeStateProjection } = await import("../worktree-state-projection.ts");
280
- const mockDeps = {
281
- isInAutoWorktree: () => true,
282
- shouldUseWorktreeIsolation: () => true,
283
- getIsolationMode: () => "worktree" as const,
284
- mergeMilestoneToMain: () => ({ pushed: false, codeFilesChanged: true }),
285
- syncWorktreeStateBack: () => ({ synced: [] }),
286
- teardownAutoWorktree: (basePath: string, mid: string) => {
287
- teardownCalled = true;
288
- teardownMilestoneId = mid;
289
- },
290
- createAutoWorktree: () => "",
291
- enterAutoWorktree: () => "",
292
- getAutoWorktreePath: () => null,
293
- autoCommitCurrentBranch: () => {},
294
- getCurrentBranch: () => "main",
295
- checkoutBranch: () => {},
296
- autoWorktreeBranch: () => "gsd/M001",
297
- resolveMilestoneFile: () => "/mock/roadmap.md",
298
- readFileSync: () => "# Roadmap content",
299
- GitServiceImpl: class {} as unknown as new (p: string, c: unknown) => unknown,
300
- loadEffectiveGSDPreferences: () => undefined,
301
- invalidateAllCaches: () => {},
302
- captureIntegrationBranch: () => {},
303
- enterBranchModeForMilestone: () => {},
304
- worktreeProjection: new WorktreeStateProjection(),
305
- };
306
-
307
- // We test the behavior contract: after a successful merge, teardown must be called
308
- const { WorktreeLifecycle } = await import("../worktree-lifecycle.ts");
309
- const lifecycle = new WorktreeLifecycle(mockSession, mockDeps as never);
310
-
311
- const ctx = { notify: () => {} };
312
- lifecycle.exitMilestone("M001", { merge: true }, ctx);
313
-
314
- assert.ok(
315
- teardownCalled,
316
- "teardownAutoWorktree must be called after successful merge in worktree mode",
317
- );
318
- assert.strictEqual(
319
- teardownMilestoneId,
320
- "M001",
321
- "teardown must be called with the correct milestone ID",
322
- );
267
+ test("_mergeWorktreeMode tears down worktree directory after successful merge", async () => {
268
+ // ADR-016 phase 2 / C2 (#5625): the worktree-manager primitives
269
+ // including `teardownAutoWorktree` are inlined into Lifecycle, so
270
+ // this test can no longer assert via a deps mock. Rewritten to use
271
+ // a real git fixture and verify the worktree directory is removed
272
+ // from disk after the merge.
273
+ const tmpBase = realpathSync(mkdtempSync(join(tmpdir(), "gsd-2945-bug3-")));
274
+ try {
275
+ const git = (args: string[]): void => {
276
+ execFileSync("git", args, { cwd: tmpBase, stdio: "pipe" });
277
+ };
278
+ git(["init", "-b", "main"]);
279
+ git(["config", "user.email", "test@test.com"]);
280
+ git(["config", "user.name", "Test"]);
281
+ writeFileSync(join(tmpBase, "README.md"), "# test\n");
282
+ writeFileSync(join(tmpBase, ".gitignore"), ".gsd/worktrees/\n");
283
+ mkdirSync(join(tmpBase, ".gsd"), { recursive: true });
284
+ writeFileSync(
285
+ join(tmpBase, ".gsd", "preferences.md"),
286
+ "## Git\n- isolation: worktree\n",
287
+ );
288
+ git(["add", "."]);
289
+ git(["commit", "-m", "init"]);
290
+ git(["checkout", "-b", "milestone/M001"]);
291
+ git(["checkout", "main"]);
292
+ const wt = join(tmpBase, ".gsd", "worktrees", "M001");
293
+ git(["worktree", "add", wt, "milestone/M001"]);
294
+ mkdirSync(join(tmpBase, ".gsd", "milestones", "M001"), { recursive: true });
295
+ writeFileSync(
296
+ join(tmpBase, ".gsd", "milestones", "M001", "M001-ROADMAP.md"),
297
+ "# M001\n- [x] S01: Slice one\n",
298
+ );
299
+
300
+ const { WorktreeStateProjection } = await import("../worktree-state-projection.ts");
301
+ const session = {
302
+ basePath: wt,
303
+ originalBasePath: tmpBase,
304
+ isolationDegraded: false,
305
+ gitService: {} as unknown,
306
+ milestoneStartShas: new Map(),
307
+ } as unknown as AutoSession;
308
+
309
+ const deps = {
310
+ mergeMilestoneToMain: () => ({ pushed: false, codeFilesChanged: true }),
311
+ worktreeProjection: new WorktreeStateProjection(),
312
+ gitServiceFactory: () => ({}) as unknown as ReturnType<
313
+ import("../worktree-lifecycle.js").WorktreeLifecycleDeps["gitServiceFactory"]
314
+ >,
315
+ };
316
+
317
+ const { WorktreeLifecycle } = await import("../worktree-lifecycle.ts");
318
+ const lifecycle = new WorktreeLifecycle(session, deps as never);
319
+
320
+ const ctx = { notify: () => {} };
321
+ lifecycle.exitMilestone("M001", { merge: true }, ctx);
322
+
323
+ assert.ok(
324
+ !existsSync(wt),
325
+ `teardownAutoWorktree must be called after successful merge — worktree directory at ${wt} should be removed`,
326
+ );
327
+ } finally {
328
+ try { rmSync(tmpBase, { recursive: true, force: true }); } catch { /* noop */ }
329
+ }
323
330
  });
324
331
  });
325
332