gsd-pi 2.81.0 → 2.82.0-dev.c22380fc3

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 (521) 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/orchestrator.js +113 -6
  7. package/dist/resources/extensions/gsd/auto/phases.js +199 -97
  8. package/dist/resources/extensions/gsd/auto/run-unit.js +66 -3
  9. package/dist/resources/extensions/gsd/auto/session.js +9 -0
  10. package/dist/resources/extensions/gsd/auto/verification-retry-policy.js +43 -0
  11. package/dist/resources/extensions/gsd/auto-dashboard.js +182 -178
  12. package/dist/resources/extensions/gsd/auto-dispatch.js +14 -11
  13. package/dist/resources/extensions/gsd/auto-post-unit.js +7 -1
  14. package/dist/resources/extensions/gsd/auto-prompts.js +11 -3
  15. package/dist/resources/extensions/gsd/auto-recovery.js +6 -181
  16. package/dist/resources/extensions/gsd/auto-runtime-state.js +5 -0
  17. package/dist/resources/extensions/gsd/auto-start.js +20 -23
  18. package/dist/resources/extensions/gsd/auto-unit-closeout.js +33 -5
  19. package/dist/resources/extensions/gsd/auto-verification.js +12 -6
  20. package/dist/resources/extensions/gsd/auto-worktree.js +8 -0
  21. package/dist/resources/extensions/gsd/auto.js +371 -106
  22. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +13 -6
  23. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +13 -2
  24. package/dist/resources/extensions/gsd/bootstrap/register-shortcuts.js +4 -8
  25. package/dist/resources/extensions/gsd/bootstrap/system-context.js +55 -12
  26. package/dist/resources/extensions/gsd/commands/handlers/core.js +1 -1
  27. package/dist/resources/extensions/gsd/commands/handlers/notifications-handler.js +4 -10
  28. package/dist/resources/extensions/gsd/commands/handlers/parallel.js +9 -0
  29. package/dist/resources/extensions/gsd/commands-handlers.js +15 -2
  30. package/dist/resources/extensions/gsd/context-store.js +112 -0
  31. package/dist/resources/extensions/gsd/db-writer.js +150 -84
  32. package/dist/resources/extensions/gsd/docs/preferences-reference.md +1 -1
  33. package/dist/resources/extensions/gsd/doctor-git-checks.js +41 -6
  34. package/dist/resources/extensions/gsd/git-service.js +2 -1
  35. package/dist/resources/extensions/gsd/gsd-db.js +7 -23
  36. package/dist/resources/extensions/gsd/health-widget-core.js +1 -1
  37. package/dist/resources/extensions/gsd/health-widget.js +4 -10
  38. package/dist/resources/extensions/gsd/knowledge-backfill.js +144 -0
  39. package/dist/resources/extensions/gsd/knowledge-capture.js +136 -0
  40. package/dist/resources/extensions/gsd/knowledge-parser.js +154 -0
  41. package/dist/resources/extensions/gsd/knowledge-projection.js +210 -0
  42. package/dist/resources/extensions/gsd/markdown-renderer.js +6 -96
  43. package/dist/resources/extensions/gsd/md-importer.js +1 -1
  44. package/dist/resources/extensions/gsd/memory-backfill.js +73 -17
  45. package/dist/resources/extensions/gsd/memory-consolidation-scanner.js +222 -0
  46. package/dist/resources/extensions/gsd/migrate/command.js +5 -0
  47. package/dist/resources/extensions/gsd/migrate/preview.js +9 -0
  48. package/dist/resources/extensions/gsd/migrate/transformer.js +51 -4
  49. package/dist/resources/extensions/gsd/migrate/writer.js +11 -1
  50. package/dist/resources/extensions/gsd/native-git-bridge.js +14 -14
  51. package/dist/resources/extensions/gsd/notification-overlay.js +35 -40
  52. package/dist/resources/extensions/gsd/parallel-merge.js +53 -30
  53. package/dist/resources/extensions/gsd/parallel-monitor-overlay.js +25 -33
  54. package/dist/resources/extensions/gsd/prompts/complete-slice.md +14 -12
  55. package/dist/resources/extensions/gsd/prompts/discuss-headless.md +20 -2
  56. package/dist/resources/extensions/gsd/prompts/discuss.md +20 -2
  57. package/dist/resources/extensions/gsd/prompts/system.md +2 -2
  58. package/dist/resources/extensions/gsd/provider-switch-observer.js +146 -0
  59. package/dist/resources/extensions/gsd/recovery-classification.js +15 -1
  60. package/dist/resources/extensions/gsd/session-lock.js +40 -0
  61. package/dist/resources/extensions/gsd/state-reconciliation/drift/completion.js +131 -0
  62. package/dist/resources/extensions/gsd/state-reconciliation/drift/merge-state.js +247 -0
  63. package/dist/resources/extensions/gsd/state-reconciliation/drift/project-md.js +50 -0
  64. package/dist/resources/extensions/gsd/state-reconciliation/drift/roadmap.js +87 -0
  65. package/dist/resources/extensions/gsd/state-reconciliation/drift/sketch-flag.js +50 -0
  66. package/dist/resources/extensions/gsd/state-reconciliation/drift/stale-render.js +124 -0
  67. package/dist/resources/extensions/gsd/state-reconciliation/drift/stale-worker.js +32 -0
  68. package/dist/resources/extensions/gsd/state-reconciliation/errors.js +41 -0
  69. package/dist/resources/extensions/gsd/state-reconciliation/index.js +99 -0
  70. package/dist/resources/extensions/gsd/state-reconciliation/registry.js +24 -0
  71. package/dist/resources/extensions/gsd/state-reconciliation/spawn-gate.js +43 -0
  72. package/dist/resources/extensions/gsd/state-reconciliation/types.js +3 -0
  73. package/dist/resources/extensions/gsd/state-reconciliation.js +5 -26
  74. package/dist/resources/extensions/gsd/templates/knowledge.md +2 -2
  75. package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +119 -0
  76. package/dist/resources/extensions/gsd/tui/render-kit.js +74 -0
  77. package/dist/resources/extensions/gsd/watch/header-renderer.js +92 -69
  78. package/dist/resources/extensions/gsd/watch/splash-palette.js +10 -0
  79. package/dist/resources/extensions/gsd/workflow-mcp.js +2 -2
  80. package/dist/resources/extensions/gsd/worktree-lifecycle.js +743 -318
  81. package/dist/resources/extensions/gsd/worktree-telemetry.js +3 -1
  82. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  83. package/dist/web/standalone/.next/BUILD_ID +1 -1
  84. package/dist/web/standalone/.next/app-path-routes-manifest.json +12 -12
  85. package/dist/web/standalone/.next/build-manifest.json +3 -3
  86. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  87. package/dist/web/standalone/.next/required-server-files.json +3 -3
  88. package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
  89. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  90. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  91. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  92. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  93. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  94. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  95. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  96. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  97. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  98. package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
  99. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  100. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  101. package/dist/web/standalone/.next/server/app/_not-found.rsc +3 -3
  102. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
  103. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  104. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +3 -3
  105. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  106. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  107. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  108. package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
  109. package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
  110. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
  111. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
  112. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
  113. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
  114. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
  115. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
  116. package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
  117. package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
  118. package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
  119. package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
  120. package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
  121. package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
  122. package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
  123. package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
  124. package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
  125. package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
  126. package/dist/web/standalone/.next/server/app/api/experimental/route.js +2 -2
  127. package/dist/web/standalone/.next/server/app/api/experimental/route_client-reference-manifest.js +1 -1
  128. package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
  129. package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
  130. package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
  131. package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
  132. package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
  133. package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
  134. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  135. package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  136. package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
  137. package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
  138. package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
  139. package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
  140. package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
  141. package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
  142. package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
  143. package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
  144. package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
  145. package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
  146. package/dist/web/standalone/.next/server/app/api/notifications/route.js +2 -2
  147. package/dist/web/standalone/.next/server/app/api/notifications/route_client-reference-manifest.js +1 -1
  148. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  149. package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
  150. package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
  151. package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
  152. package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
  153. package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  154. package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
  155. package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
  156. package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +2 -2
  157. package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
  158. package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
  159. package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
  160. package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
  161. package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
  162. package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
  163. package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
  164. package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
  165. package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
  166. package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
  167. package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
  168. package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
  169. package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
  170. package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
  171. package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
  172. package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
  173. package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
  174. package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
  175. package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
  176. package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +1 -1
  177. package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
  178. package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
  179. package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
  180. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +1 -1
  181. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
  182. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +2 -2
  183. package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
  184. package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
  185. package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
  186. package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
  187. package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
  188. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  189. package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  190. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  191. package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
  192. package/dist/web/standalone/.next/server/app/index.html +1 -1
  193. package/dist/web/standalone/.next/server/app/index.rsc +4 -4
  194. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  195. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +4 -4
  196. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  197. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +3 -3
  198. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  199. package/dist/web/standalone/.next/server/app/page.js +2 -2
  200. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  201. package/dist/web/standalone/.next/server/app-paths-manifest.json +12 -12
  202. package/dist/web/standalone/.next/server/chunks/63.js +3 -3
  203. package/dist/web/standalone/.next/server/chunks/6897.js +1 -1
  204. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  205. package/dist/web/standalone/.next/server/middleware.js +2 -2
  206. package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
  207. package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
  208. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  209. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  210. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  211. package/dist/web/standalone/.next/static/chunks/app/_not-found/{page-2f24283c162b6ab3.js → page-f2a7482d42a5614b.js} +1 -1
  212. package/dist/web/standalone/.next/static/chunks/app/{layout-9ecfd95f343793f0.js → layout-a16c7a7ecdf0c2cf.js} +1 -1
  213. package/dist/web/standalone/.next/static/chunks/app/page-752f1e2ebdaa3e45.js +1 -0
  214. package/dist/web/standalone/.next/static/chunks/main-app-fdab67f7802d7832.js +1 -0
  215. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +1 -0
  216. package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
  217. package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
  218. package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
  219. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api.target.mk +14 -14
  220. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_except.target.mk +14 -14
  221. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_maybe.target.mk +14 -14
  222. package/dist/web/standalone/server.js +1 -1
  223. package/dist/welcome-screen.d.ts +0 -7
  224. package/dist/welcome-screen.js +60 -69
  225. package/package.json +3 -2
  226. package/packages/contracts/dist/rpc.test.js +7 -0
  227. package/packages/contracts/dist/rpc.test.js.map +1 -1
  228. package/packages/contracts/dist/workflow.d.ts +21 -0
  229. package/packages/contracts/dist/workflow.d.ts.map +1 -1
  230. package/packages/contracts/dist/workflow.js +24 -0
  231. package/packages/contracts/dist/workflow.js.map +1 -1
  232. package/packages/contracts/src/rpc.test.ts +8 -0
  233. package/packages/contracts/src/workflow.ts +24 -0
  234. package/packages/daemon/package.json +2 -2
  235. package/packages/mcp-server/README.md +14 -3
  236. package/packages/mcp-server/dist/workflow-tools.d.ts +0 -3
  237. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  238. package/packages/mcp-server/dist/workflow-tools.js +80 -0
  239. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  240. package/packages/mcp-server/package.json +2 -2
  241. package/packages/mcp-server/src/workflow-tools-parity.test.ts +244 -0
  242. package/packages/mcp-server/src/workflow-tools.test.ts +22 -0
  243. package/packages/mcp-server/src/workflow-tools.ts +168 -0
  244. package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
  245. package/packages/native/package.json +1 -1
  246. package/packages/pi-agent-core/package.json +1 -1
  247. package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -1
  248. package/packages/pi-ai/dist/index.d.ts +2 -2
  249. package/packages/pi-ai/dist/index.d.ts.map +1 -1
  250. package/packages/pi-ai/dist/index.js +1 -1
  251. package/packages/pi-ai/dist/index.js.map +1 -1
  252. package/packages/pi-ai/dist/providers/transform-messages.d.ts +11 -0
  253. package/packages/pi-ai/dist/providers/transform-messages.d.ts.map +1 -1
  254. package/packages/pi-ai/dist/providers/transform-messages.js +20 -0
  255. package/packages/pi-ai/dist/providers/transform-messages.js.map +1 -1
  256. package/packages/pi-ai/package.json +1 -1
  257. package/packages/pi-ai/src/index.ts +7 -2
  258. package/packages/pi-ai/src/providers/transform-messages.ts +24 -0
  259. package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
  260. package/packages/pi-coding-agent/dist/core/system-prompt.js +4 -4
  261. package/packages/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
  262. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/assistant-message-design.test.d.ts +2 -0
  263. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/assistant-message-design.test.d.ts.map +1 -0
  264. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/assistant-message-design.test.js +47 -0
  265. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/assistant-message-design.test.js.map +1 -0
  266. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js +76 -9
  267. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js.map +1 -1
  268. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/user-message-design.test.d.ts +2 -0
  269. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/user-message-design.test.d.ts.map +1 -0
  270. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/user-message-design.test.js +40 -0
  271. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/user-message-design.test.js.map +1 -0
  272. package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.d.ts +0 -1
  273. package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.d.ts.map +1 -1
  274. package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.js +30 -29
  275. package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.js.map +1 -1
  276. package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.test.js +10 -3
  277. package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.test.js.map +1 -1
  278. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  279. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js +13 -13
  280. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js.map +1 -1
  281. package/packages/pi-coding-agent/dist/modes/interactive/components/bash-execution.d.ts +1 -3
  282. package/packages/pi-coding-agent/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
  283. package/packages/pi-coding-agent/dist/modes/interactive/components/bash-execution.js +58 -3
  284. package/packages/pi-coding-agent/dist/modes/interactive/components/bash-execution.js.map +1 -1
  285. package/packages/pi-coding-agent/dist/modes/interactive/components/diff.d.ts +2 -2
  286. package/packages/pi-coding-agent/dist/modes/interactive/components/diff.d.ts.map +1 -1
  287. package/packages/pi-coding-agent/dist/modes/interactive/components/diff.js +12 -6
  288. package/packages/pi-coding-agent/dist/modes/interactive/components/diff.js.map +1 -1
  289. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.d.ts.map +1 -1
  290. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js +14 -41
  291. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js.map +1 -1
  292. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts +0 -1
  293. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  294. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +86 -82
  295. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
  296. package/packages/pi-coding-agent/dist/modes/interactive/components/transcript-design.d.ts +35 -0
  297. package/packages/pi-coding-agent/dist/modes/interactive/components/transcript-design.d.ts.map +1 -0
  298. package/packages/pi-coding-agent/dist/modes/interactive/components/transcript-design.js +152 -0
  299. package/packages/pi-coding-agent/dist/modes/interactive/components/transcript-design.js.map +1 -0
  300. package/packages/pi-coding-agent/dist/modes/interactive/components/tui-style-kit.d.ts +16 -0
  301. package/packages/pi-coding-agent/dist/modes/interactive/components/tui-style-kit.d.ts.map +1 -0
  302. package/packages/pi-coding-agent/dist/modes/interactive/components/tui-style-kit.js +73 -0
  303. package/packages/pi-coding-agent/dist/modes/interactive/components/tui-style-kit.js.map +1 -0
  304. package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.d.ts +1 -1
  305. package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.d.ts.map +1 -1
  306. package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.js +12 -8
  307. package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.js.map +1 -1
  308. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-highlight.test.d.ts +2 -0
  309. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-highlight.test.d.ts.map +1 -0
  310. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-highlight.test.js +17 -0
  311. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-highlight.test.js.map +1 -0
  312. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  313. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.js +105 -1
  314. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.js.map +1 -1
  315. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.d.ts.map +1 -1
  316. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js +27 -26
  317. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js.map +1 -1
  318. package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.test.js +9 -6
  319. package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.test.js.map +1 -1
  320. package/packages/pi-coding-agent/dist/tests/system-prompt-file-safety.test.d.ts +2 -0
  321. package/packages/pi-coding-agent/dist/tests/system-prompt-file-safety.test.d.ts.map +1 -0
  322. package/packages/pi-coding-agent/dist/tests/system-prompt-file-safety.test.js +17 -0
  323. package/packages/pi-coding-agent/dist/tests/system-prompt-file-safety.test.js.map +1 -0
  324. package/packages/pi-coding-agent/package.json +1 -1
  325. package/packages/pi-coding-agent/src/core/system-prompt.ts +4 -4
  326. package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/assistant-message-design.test.ts +56 -0
  327. package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/tool-execution.test.ts +113 -9
  328. package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/user-message-design.test.ts +48 -0
  329. package/packages/pi-coding-agent/src/modes/interactive/components/adaptive-layout.test.ts +10 -3
  330. package/packages/pi-coding-agent/src/modes/interactive/components/adaptive-layout.ts +43 -42
  331. package/packages/pi-coding-agent/src/modes/interactive/components/assistant-message.ts +14 -14
  332. package/packages/pi-coding-agent/src/modes/interactive/components/bash-execution.ts +64 -3
  333. package/packages/pi-coding-agent/src/modes/interactive/components/diff.ts +13 -7
  334. package/packages/pi-coding-agent/src/modes/interactive/components/footer.ts +15 -42
  335. package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +84 -104
  336. package/packages/pi-coding-agent/src/modes/interactive/components/transcript-design.ts +196 -0
  337. package/packages/pi-coding-agent/src/modes/interactive/components/tui-style-kit.ts +94 -0
  338. package/packages/pi-coding-agent/src/modes/interactive/components/user-message.ts +14 -9
  339. package/packages/pi-coding-agent/src/modes/interactive/theme/theme-highlight.test.ts +23 -0
  340. package/packages/pi-coding-agent/src/modes/interactive/theme/theme.ts +106 -1
  341. package/packages/pi-coding-agent/src/modes/interactive/theme/themes.ts +27 -26
  342. package/packages/pi-coding-agent/src/modes/interactive/tui-mode.test.ts +9 -6
  343. package/packages/pi-coding-agent/src/tests/system-prompt-file-safety.test.ts +22 -0
  344. package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
  345. package/packages/pi-tui/dist/__tests__/overlay-layout.test.js +14 -1
  346. package/packages/pi-tui/dist/__tests__/overlay-layout.test.js.map +1 -1
  347. package/packages/pi-tui/dist/overlay-layout.d.ts.map +1 -1
  348. package/packages/pi-tui/dist/overlay-layout.js +9 -6
  349. package/packages/pi-tui/dist/overlay-layout.js.map +1 -1
  350. package/packages/pi-tui/dist/tui.d.ts.map +1 -1
  351. package/packages/pi-tui/dist/tui.js +5 -0
  352. package/packages/pi-tui/dist/tui.js.map +1 -1
  353. package/packages/pi-tui/package.json +1 -1
  354. package/packages/pi-tui/src/__tests__/overlay-layout.test.ts +20 -1
  355. package/packages/pi-tui/src/overlay-layout.ts +10 -7
  356. package/packages/pi-tui/src/tui.ts +6 -0
  357. package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
  358. package/packages/rpc-client/package.json +1 -1
  359. package/packages/rpc-client/tsconfig.tsbuildinfo +1 -1
  360. package/pkg/dist/modes/interactive/theme/theme-highlight.test.d.ts +2 -0
  361. package/pkg/dist/modes/interactive/theme/theme-highlight.test.d.ts.map +1 -0
  362. package/pkg/dist/modes/interactive/theme/theme-highlight.test.js +17 -0
  363. package/pkg/dist/modes/interactive/theme/theme-highlight.test.js.map +1 -0
  364. package/pkg/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  365. package/pkg/dist/modes/interactive/theme/theme.js +105 -1
  366. package/pkg/dist/modes/interactive/theme/theme.js.map +1 -1
  367. package/pkg/dist/modes/interactive/theme/themes.d.ts.map +1 -1
  368. package/pkg/dist/modes/interactive/theme/themes.js +27 -26
  369. package/pkg/dist/modes/interactive/theme/themes.js.map +1 -1
  370. package/pkg/package.json +1 -1
  371. package/src/resources/extensions/browser-tools/tools/screenshot.ts +1 -0
  372. package/src/resources/extensions/browser-tools/tools/zoom.ts +1 -0
  373. package/src/resources/extensions/gsd/auto/contracts.ts +46 -11
  374. package/src/resources/extensions/gsd/auto/loop-deps.ts +9 -5
  375. package/src/resources/extensions/gsd/auto/loop.ts +113 -9
  376. package/src/resources/extensions/gsd/auto/orchestrator.ts +118 -6
  377. package/src/resources/extensions/gsd/auto/phases.ts +158 -19
  378. package/src/resources/extensions/gsd/auto/run-unit.ts +69 -4
  379. package/src/resources/extensions/gsd/auto/session.ts +10 -0
  380. package/src/resources/extensions/gsd/auto/verification-retry-policy.ts +82 -0
  381. package/src/resources/extensions/gsd/auto-dashboard.ts +230 -183
  382. package/src/resources/extensions/gsd/auto-dispatch.ts +15 -1
  383. package/src/resources/extensions/gsd/auto-post-unit.ts +7 -1
  384. package/src/resources/extensions/gsd/auto-prompts.ts +11 -3
  385. package/src/resources/extensions/gsd/auto-recovery.ts +7 -209
  386. package/src/resources/extensions/gsd/auto-runtime-state.ts +5 -0
  387. package/src/resources/extensions/gsd/auto-start.ts +22 -22
  388. package/src/resources/extensions/gsd/auto-unit-closeout.ts +51 -0
  389. package/src/resources/extensions/gsd/auto-verification.ts +12 -6
  390. package/src/resources/extensions/gsd/auto-worktree.ts +8 -0
  391. package/src/resources/extensions/gsd/auto.ts +411 -106
  392. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +21 -6
  393. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +12 -2
  394. package/src/resources/extensions/gsd/bootstrap/register-shortcuts.ts +5 -8
  395. package/src/resources/extensions/gsd/bootstrap/system-context.ts +58 -15
  396. package/src/resources/extensions/gsd/commands/handlers/core.ts +1 -1
  397. package/src/resources/extensions/gsd/commands/handlers/notifications-handler.ts +4 -10
  398. package/src/resources/extensions/gsd/commands/handlers/parallel.ts +12 -0
  399. package/src/resources/extensions/gsd/commands-handlers.ts +19 -2
  400. package/src/resources/extensions/gsd/context-store.ts +120 -1
  401. package/src/resources/extensions/gsd/db-writer.ts +167 -84
  402. package/src/resources/extensions/gsd/docs/preferences-reference.md +1 -1
  403. package/src/resources/extensions/gsd/doctor-git-checks.ts +44 -6
  404. package/src/resources/extensions/gsd/doctor-types.ts +2 -0
  405. package/src/resources/extensions/gsd/git-service.ts +2 -0
  406. package/src/resources/extensions/gsd/gsd-db.ts +7 -23
  407. package/src/resources/extensions/gsd/health-widget-core.ts +1 -1
  408. package/src/resources/extensions/gsd/health-widget.ts +6 -10
  409. package/src/resources/extensions/gsd/journal.ts +2 -0
  410. package/src/resources/extensions/gsd/knowledge-backfill.ts +164 -0
  411. package/src/resources/extensions/gsd/knowledge-capture.ts +160 -0
  412. package/src/resources/extensions/gsd/knowledge-parser.ts +174 -0
  413. package/src/resources/extensions/gsd/knowledge-projection.ts +241 -0
  414. package/src/resources/extensions/gsd/markdown-renderer.ts +10 -96
  415. package/src/resources/extensions/gsd/md-importer.ts +1 -1
  416. package/src/resources/extensions/gsd/memory-backfill.ts +89 -17
  417. package/src/resources/extensions/gsd/memory-consolidation-scanner.ts +277 -0
  418. package/src/resources/extensions/gsd/migrate/command.ts +5 -0
  419. package/src/resources/extensions/gsd/migrate/preview.ts +10 -0
  420. package/src/resources/extensions/gsd/migrate/transformer.ts +58 -4
  421. package/src/resources/extensions/gsd/migrate/writer.ts +14 -1
  422. package/src/resources/extensions/gsd/native-git-bridge.ts +14 -13
  423. package/src/resources/extensions/gsd/notification-overlay.ts +50 -46
  424. package/src/resources/extensions/gsd/parallel-merge.ts +61 -34
  425. package/src/resources/extensions/gsd/parallel-monitor-overlay.ts +33 -35
  426. package/src/resources/extensions/gsd/prompts/complete-slice.md +14 -12
  427. package/src/resources/extensions/gsd/prompts/discuss-headless.md +20 -2
  428. package/src/resources/extensions/gsd/prompts/discuss.md +20 -2
  429. package/src/resources/extensions/gsd/prompts/system.md +2 -2
  430. package/src/resources/extensions/gsd/provider-switch-observer.ts +185 -0
  431. package/src/resources/extensions/gsd/recovery-classification.ts +18 -1
  432. package/src/resources/extensions/gsd/session-lock.ts +41 -0
  433. package/src/resources/extensions/gsd/state-reconciliation/drift/completion.ts +172 -0
  434. package/src/resources/extensions/gsd/state-reconciliation/drift/merge-state.ts +337 -0
  435. package/src/resources/extensions/gsd/state-reconciliation/drift/project-md.ts +69 -0
  436. package/src/resources/extensions/gsd/state-reconciliation/drift/roadmap.ts +109 -0
  437. package/src/resources/extensions/gsd/state-reconciliation/drift/sketch-flag.ts +68 -0
  438. package/src/resources/extensions/gsd/state-reconciliation/drift/stale-render.ts +185 -0
  439. package/src/resources/extensions/gsd/state-reconciliation/drift/stale-worker.ts +46 -0
  440. package/src/resources/extensions/gsd/state-reconciliation/errors.ts +67 -0
  441. package/src/resources/extensions/gsd/state-reconciliation/index.ts +142 -0
  442. package/src/resources/extensions/gsd/state-reconciliation/registry.ts +27 -0
  443. package/src/resources/extensions/gsd/state-reconciliation/spawn-gate.ts +60 -0
  444. package/src/resources/extensions/gsd/state-reconciliation/types.ts +83 -0
  445. package/src/resources/extensions/gsd/state-reconciliation.ts +21 -53
  446. package/src/resources/extensions/gsd/templates/knowledge.md +2 -2
  447. package/src/resources/extensions/gsd/tests/artifact-retry-cap.test.ts +1 -1
  448. package/src/resources/extensions/gsd/tests/auto-dashboard.test.ts +99 -0
  449. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +729 -176
  450. package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +408 -4
  451. package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +292 -4
  452. package/src/resources/extensions/gsd/tests/auto-runtime-state.test.ts +20 -5
  453. package/src/resources/extensions/gsd/tests/auto-start-orphan-bootstrap.test.ts +18 -0
  454. package/src/resources/extensions/gsd/tests/auto-unit-closeout.test.ts +68 -0
  455. package/src/resources/extensions/gsd/tests/browser-tools-compatibility-declarations.test.ts +62 -0
  456. package/src/resources/extensions/gsd/tests/context-store-decisions-from-memories.test.ts +312 -0
  457. package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +28 -1
  458. package/src/resources/extensions/gsd/tests/db-writer.test.ts +13 -8
  459. package/src/resources/extensions/gsd/tests/decisions-projection-from-memories.test.ts +453 -0
  460. package/src/resources/extensions/gsd/tests/decisions-stop-table-writes.test.ts +348 -0
  461. package/src/resources/extensions/gsd/tests/deep-project-auto-loop.test.ts +20 -2
  462. package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +44 -0
  463. package/src/resources/extensions/gsd/tests/freeform-decisions.test.ts +8 -4
  464. package/src/resources/extensions/gsd/tests/gsd-tools.test.ts +11 -7
  465. package/src/resources/extensions/gsd/tests/header-renderer.test.ts +40 -0
  466. package/src/resources/extensions/gsd/tests/headless-milestone-parity.test.ts +10 -0
  467. package/src/resources/extensions/gsd/tests/health-widget.test.ts +14 -4
  468. package/src/resources/extensions/gsd/tests/integration/doctor-git.test.ts +44 -0
  469. package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +26 -0
  470. package/src/resources/extensions/gsd/tests/integration/integration-lifecycle.test.ts +13 -5
  471. package/src/resources/extensions/gsd/tests/integration/integration-proof.test.ts +1 -1
  472. package/src/resources/extensions/gsd/tests/integration/migrate-command.test.ts +48 -3
  473. package/src/resources/extensions/gsd/tests/integration/parallel-merge.test.ts +116 -24
  474. package/src/resources/extensions/gsd/tests/journal-integration.test.ts +0 -1
  475. package/src/resources/extensions/gsd/tests/knowledge-backfill-projection.test.ts +323 -0
  476. package/src/resources/extensions/gsd/tests/knowledge-capture.test.ts +242 -0
  477. package/src/resources/extensions/gsd/tests/knowledge.test.ts +47 -2
  478. package/src/resources/extensions/gsd/tests/load-knowledge-block-rules-only.test.ts +209 -0
  479. package/src/resources/extensions/gsd/tests/markdown-renderer.test.ts +1 -1
  480. package/src/resources/extensions/gsd/tests/memory-consolidation-scanner.test.ts +316 -0
  481. package/src/resources/extensions/gsd/tests/merge-conflict-stops-loop.test.ts +46 -11
  482. package/src/resources/extensions/gsd/tests/migrate-transformer.test.ts +5 -1
  483. package/src/resources/extensions/gsd/tests/migrate-writer-integration.test.ts +6 -1
  484. package/src/resources/extensions/gsd/tests/notification-overlay.test.ts +78 -41
  485. package/src/resources/extensions/gsd/tests/notifications-handler.test.ts +44 -0
  486. package/src/resources/extensions/gsd/tests/originalbase-path-comparison.test.ts +12 -217
  487. package/src/resources/extensions/gsd/tests/parallel-monitor-overlay.test.ts +38 -6
  488. package/src/resources/extensions/gsd/tests/plan-milestone-sketch-render.test.ts +157 -0
  489. package/src/resources/extensions/gsd/tests/post-exec-retry-bypass.test.ts +2 -2
  490. package/src/resources/extensions/gsd/tests/progressive-planning.test.ts +1 -1
  491. package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +32 -1
  492. package/src/resources/extensions/gsd/tests/provider-switch-observer.test.ts +252 -0
  493. package/src/resources/extensions/gsd/tests/resume-dispatch-worktree.test.ts +7 -3
  494. package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +6 -3
  495. package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +16 -4
  496. package/src/resources/extensions/gsd/tests/session-switch-abort-misclassification.test.ts +24 -0
  497. package/src/resources/extensions/gsd/tests/state-corruption-2945.test.ts +71 -58
  498. package/src/resources/extensions/gsd/tests/state-reconciliation-drift.test.ts +952 -0
  499. package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +4 -0
  500. package/src/resources/extensions/gsd/tests/tui-header-lifecycle.test.ts +121 -1
  501. package/src/resources/extensions/gsd/tests/tui-render-kit.test.ts +66 -0
  502. package/src/resources/extensions/gsd/tests/verification-retry-policy.test.ts +83 -0
  503. package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +6 -0
  504. package/src/resources/extensions/gsd/tests/worktree-journal-events.test.ts +158 -58
  505. package/src/resources/extensions/gsd/tests/worktree-lifecycle.test.ts +597 -118
  506. package/src/resources/extensions/gsd/tests/worktree-telemetry.test.ts +59 -2
  507. package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +18 -0
  508. package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +135 -0
  509. package/src/resources/extensions/gsd/tui/render-kit.ts +109 -0
  510. package/src/resources/extensions/gsd/watch/header-renderer.ts +121 -79
  511. package/src/resources/extensions/gsd/watch/splash-palette.ts +11 -0
  512. package/src/resources/extensions/gsd/workflow-logger.ts +4 -0
  513. package/src/resources/extensions/gsd/workflow-mcp.ts +2 -2
  514. package/src/resources/extensions/gsd/worktree-lifecycle.ts +1171 -526
  515. package/src/resources/extensions/gsd/worktree-telemetry.ts +7 -2
  516. package/dist/web/standalone/.next/static/chunks/app/page-200592a7f3baf579.js +0 -1
  517. package/dist/web/standalone/.next/static/chunks/main-app-d3d4c336195465f9.js +0 -1
  518. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ab5a8926e07ec673.js +0 -1
  519. package/src/resources/extensions/gsd/tests/worktree-resolver.test.ts +0 -1544
  520. /package/dist/web/standalone/.next/static/{drLMkgfHQ8lzS229_HWYR → Wop3A7KRGyR06H3rla_1-}/_buildManifest.js +0 -0
  521. /package/dist/web/standalone/.next/static/{drLMkgfHQ8lzS229_HWYR → Wop3A7KRGyR06H3rla_1-}/_ssgManifest.js +0 -0
@@ -0,0 +1,17 @@
1
+ // GSD-2 pi-coding-agent system prompt file-safety regression tests.
2
+ import test from "node:test";
3
+ import assert from "node:assert/strict";
4
+ import { buildSystemPrompt } from "../core/system-prompt.js";
5
+ test("buildSystemPrompt: read and write tools require reading before overwrite", () => {
6
+ const prompt = buildSystemPrompt({ selectedTools: ["read", "write"] });
7
+ assert.match(prompt, /before editing or overwriting/i);
8
+ assert.match(prompt, /Before write creates or replaces a file, verify the target path/i);
9
+ assert.match(prompt, /if it exists, read it first/i);
10
+ assert.match(prompt, /Use write only for new files or complete rewrites after verifying the target path/i);
11
+ });
12
+ test("buildSystemPrompt: write-only tool guidance does not reference unavailable read tool", () => {
13
+ const prompt = buildSystemPrompt({ selectedTools: ["write"] });
14
+ assert.doesNotMatch(prompt, /read it first/i);
15
+ assert.match(prompt, /Use write only for new files or complete rewrites after verifying the target path/i);
16
+ });
17
+ //# sourceMappingURL=system-prompt-file-safety.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"system-prompt-file-safety.test.js","sourceRoot":"","sources":["../../src/tests/system-prompt-file-safety.test.ts"],"names":[],"mappings":"AAAA,oEAAoE;AAEpE,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,MAAM,MAAM,oBAAoB,CAAC;AAExC,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAE7D,IAAI,CAAC,0EAA0E,EAAE,GAAG,EAAE;IACrF,MAAM,MAAM,GAAG,iBAAiB,CAAC,EAAE,aAAa,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC;IAEvE,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,gCAAgC,CAAC,CAAC;IACvD,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,kEAAkE,CAAC,CAAC;IACzF,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,8BAA8B,CAAC,CAAC;IACrD,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,oFAAoF,CAAC,CAAC;AAC5G,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,sFAAsF,EAAE,GAAG,EAAE;IACjG,MAAM,MAAM,GAAG,iBAAiB,CAAC,EAAE,aAAa,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAE/D,MAAM,CAAC,YAAY,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IAC9C,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,oFAAoF,CAAC,CAAC;AAC5G,CAAC,CAAC,CAAC","sourcesContent":["// GSD-2 pi-coding-agent system prompt file-safety regression tests.\n\nimport test from \"node:test\";\nimport assert from \"node:assert/strict\";\n\nimport { buildSystemPrompt } from \"../core/system-prompt.js\";\n\ntest(\"buildSystemPrompt: read and write tools require reading before overwrite\", () => {\n\tconst prompt = buildSystemPrompt({ selectedTools: [\"read\", \"write\"] });\n\n\tassert.match(prompt, /before editing or overwriting/i);\n\tassert.match(prompt, /Before write creates or replaces a file, verify the target path/i);\n\tassert.match(prompt, /if it exists, read it first/i);\n\tassert.match(prompt, /Use write only for new files or complete rewrites after verifying the target path/i);\n});\n\ntest(\"buildSystemPrompt: write-only tool guidance does not reference unavailable read tool\", () => {\n\tconst prompt = buildSystemPrompt({ selectedTools: [\"write\"] });\n\n\tassert.doesNotMatch(prompt, /read it first/i);\n\tassert.match(prompt, /Use write only for new files or complete rewrites after verifying the target path/i);\n});\n"]}
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gsd/pi-coding-agent",
3
- "version": "2.81.0",
3
+ "version": "2.82.0",
4
4
  "description": "Coding agent CLI (vendored from pi-mono)",
5
5
  "type": "module",
6
6
  "gsd": {
@@ -203,9 +203,9 @@ export function buildSystemPrompt(options: BuildSystemPromptOptions = {}): strin
203
203
  addGuideline("Prefer grep/find/ls tools over bash for file exploration (faster, respects .gitignore)");
204
204
  }
205
205
 
206
- // Read before edit guideline
207
- if (hasRead && hasEdit) {
208
- addGuideline("Use read to examine files before editing. You must use this tool instead of cat or sed.");
206
+ // Read before file mutation guideline
207
+ if (hasRead && (hasEdit || hasWrite)) {
208
+ addGuideline("Use read to examine relevant existing files before editing or overwriting. Before write creates or replaces a file, verify the target path; if it exists, read it first. Use read instead of cat or sed for file inspection.");
209
209
  }
210
210
 
211
211
  // Edit guideline
@@ -215,7 +215,7 @@ export function buildSystemPrompt(options: BuildSystemPromptOptions = {}): strin
215
215
 
216
216
  // Write guideline
217
217
  if (hasWrite) {
218
- addGuideline("Use write only for new files or complete rewrites");
218
+ addGuideline("Use write only for new files or complete rewrites after verifying the target path");
219
219
  }
220
220
 
221
221
  // LSP guideline
@@ -0,0 +1,56 @@
1
+ // Project/App: GSD-2
2
+ // File Purpose: Visual contract tests for the recommended indented assistant message rail design.
3
+
4
+ import { describe, test } from "node:test";
5
+ import assert from "node:assert/strict";
6
+ import stripAnsi from "strip-ansi";
7
+ import type { AssistantMessage } from "@gsd/pi-ai";
8
+
9
+ import { initTheme } from "../../theme/theme.js";
10
+ import { AssistantMessageComponent } from "../assistant-message.js";
11
+ import { formatTimestamp } from "../timestamp.js";
12
+
13
+ initTheme("dark", false);
14
+
15
+ describe("AssistantMessageComponent recommended rail design", () => {
16
+ test("renders assistant content with a lightly indented left rail", () => {
17
+ const message = {
18
+ id: "m1",
19
+ role: "assistant",
20
+ provider: "test",
21
+ model: "gpt-test",
22
+ timestamp: 1,
23
+ content: [{ type: "text", text: "I will update the renderer and run verification." }],
24
+ } as unknown as AssistantMessage;
25
+
26
+ const component = new AssistantMessageComponent(message, true);
27
+ const raw = component.render(80);
28
+ const plain = raw.map((line) => stripAnsi(line));
29
+ const joined = plain.join("\n");
30
+
31
+ assert.ok(plain.some((line) => line.startsWith(" ┃ ")), `expected indented rail-prefixed lines:\n${joined}`);
32
+ assert.ok(raw.some((line) => line.includes("\x1b[48;")), `expected faint assistant block background:\n${raw.join("\n")}`);
33
+ assert.match(joined, /^\s*┃\s*$/m, "assistant block should include vertical padding rows");
34
+ assert.match(joined, /GSD/);
35
+ assert.match(joined, /gpt-test/);
36
+ assert.match(joined, /update the renderer/);
37
+ assert.doesNotMatch(joined, /^┃/m, "assistant rail should be slightly indented from the left edge");
38
+ assert.doesNotMatch(joined, /^╭/m, "assistant messages should not use rounded card borders");
39
+ });
40
+
41
+ test("renders metadata for a zero timestamp", () => {
42
+ const message = {
43
+ id: "m1",
44
+ role: "assistant",
45
+ provider: "test",
46
+ model: "gpt-test",
47
+ timestamp: 0,
48
+ content: [{ type: "text", text: "Finished." }],
49
+ } as unknown as AssistantMessage;
50
+
51
+ const component = new AssistantMessageComponent(message, true);
52
+ const joined = component.render(80).map((line) => stripAnsi(line)).join("\n");
53
+
54
+ assert.match(joined, new RegExp(formatTimestamp(0)));
55
+ });
56
+ });
@@ -1,4 +1,5 @@
1
- // GSD-2 Interactive Tool Execution Rendering Tests
1
+ // Project/App: GSD-2
2
+ // File Purpose: Tests for interactive terminal tool execution rendering.
2
3
  import { describe, test } from "node:test";
3
4
  import assert from "node:assert/strict";
4
5
  import stripAnsi from "strip-ansi";
@@ -60,6 +61,23 @@ describe("ToolExecutionComponent", () => {
60
61
  assert.match(rendered, /running · \d+(ms|s)/);
61
62
  });
62
63
 
64
+ test("does not duplicate running generic tool labels before args", () => {
65
+ const rendered = renderToolCollapsed(
66
+ "Agent",
67
+ {
68
+ description: "Scout habit tracker codebase",
69
+ subagent_type: "Explore",
70
+ prompt: "Read these files and give me a concise summary of each.",
71
+ },
72
+ );
73
+
74
+ const labelMatches = rendered.match(/Agent/g) ?? [];
75
+ assert.equal(labelMatches.length, 1, `expected only the card title to contain Agent:\n${rendered}`);
76
+ assert.doesNotMatch(rendered, /description="Scout habit tracker codebase"/);
77
+ assert.doesNotMatch(rendered, /subagent_type="Explore"/);
78
+ assert.match(rendered, /running · \d+(ms|s)/);
79
+ });
80
+
63
81
  test("renders framed header with failed status for failed tool result", () => {
64
82
  const rendered = renderTool(
65
83
  "mcp__demo__do_thing",
@@ -87,6 +105,19 @@ describe("ToolExecutionComponent", () => {
87
105
  assert.doesNotMatch(rendered, /ok=true/);
88
106
  });
89
107
 
108
+ test("does not duplicate generic tool labels in collapsed cards", () => {
109
+ const rendered = renderToolCollapsed(
110
+ "TodoWrite",
111
+ { todos: [{ content: "Ship it", status: "pending" }] },
112
+ { content: [{ type: "text", text: "TodoWrite" }], isError: false },
113
+ );
114
+
115
+ const labelMatches = rendered.match(/TodoWrite/g) ?? [];
116
+ assert.equal(labelMatches.length, 1, `expected only the card title to contain TodoWrite:\n${rendered}`);
117
+ assert.match(rendered, /output hidden/);
118
+ assert.match(rendered, /ctrl\+o expand/);
119
+ });
120
+
90
121
  test("exposes phase metadata for successful low-signal tool rows", () => {
91
122
  const component = new ToolExecutionComponent(
92
123
  "gsd_requirement_update",
@@ -132,8 +163,41 @@ describe("ToolExecutionComponent", () => {
132
163
  },
133
164
  );
134
165
 
135
- assert.match(rendered, /read .*src\/Inspector\.tsx:4-12/);
166
+ assert.match(rendered, /Read/);
167
+ assert.match(rendered, /src\/Inspector\.tsx:4-12/);
136
168
  assert.doesNotMatch(rendered, /source/);
169
+ assert.doesNotMatch(rendered, /output hidden\n\s*│\s*ctrl\+o expand/);
170
+ });
171
+
172
+ test("renders compact capitalized read rows from file_path args", () => {
173
+ const rendered = renderToolCollapsed(
174
+ "Read",
175
+ { file_path: "~/Github/gsd-2/src/resources/extensions/gsd/health-widget-core.ts" },
176
+ { content: [{ type: "text", text: "hidden body output" }], isError: false },
177
+ );
178
+
179
+ assert.match(rendered, /Read/);
180
+ assert.match(rendered, /health-widget-core\.ts/);
181
+ assert.doesNotMatch(rendered, /hidden body output/);
182
+ });
183
+
184
+ test("renders compact read rows from direct result details path", () => {
185
+ const rendered = renderToolCollapsed(
186
+ "read",
187
+ {},
188
+ {
189
+ content: [{ type: "text", text: "hidden body output" }],
190
+ isError: false,
191
+ details: {
192
+ path: "/tmp/project/src/resources/extensions/gsd/health-widget-core.ts",
193
+ range: { start: 1, end: 12 },
194
+ },
195
+ },
196
+ );
197
+
198
+ assert.match(rendered, /Read/);
199
+ assert.match(rendered, /health-widget-core\.ts:1-12/);
200
+ assert.doesNotMatch(rendered, /hidden body output/);
137
201
  });
138
202
 
139
203
  test("renders compact edit rows with target metadata", () => {
@@ -155,10 +219,21 @@ describe("ToolExecutionComponent", () => {
155
219
  },
156
220
  );
157
221
 
158
- assert.match(rendered, /edit .*src\/Inspector\.tsx:42/);
222
+ assert.match(rendered, /Edit/);
223
+ assert.match(rendered, /src\/Inspector\.tsx:42/);
159
224
  assert.doesNotMatch(rendered, /Updated src\/Inspector\.tsx/);
160
225
  });
161
226
 
227
+ test("renders running edit rows with title and target on the top line", () => {
228
+ const rendered = renderToolCollapsed("edit", { path: "src/Inspector.tsx" });
229
+
230
+ const labelMatches = rendered.match(/Edit/g) ?? [];
231
+ assert.equal(labelMatches.length, 1, `expected tool name only in the card title:\n${rendered}`);
232
+ assert.match(rendered, /src\/Inspector\.tsx/);
233
+ assert.match(rendered, /Edit src\/Inspector\.tsx/);
234
+ assert.match(rendered, /running · \d+(ms|s)/);
235
+ });
236
+
162
237
  test("renders compact write rows with target metadata", () => {
163
238
  const rendered = renderToolCollapsed(
164
239
  "write",
@@ -177,10 +252,36 @@ describe("ToolExecutionComponent", () => {
177
252
  },
178
253
  );
179
254
 
180
- assert.match(rendered, /write .*src\/output\.ts/);
255
+ assert.match(rendered, /Write/);
256
+ assert.match(rendered, /src\/output\.ts/);
181
257
  assert.doesNotMatch(rendered, /Successfully wrote/);
182
258
  });
183
259
 
260
+ test("omits default cwd placeholders for collapsed search tools", () => {
261
+ const rendered = renderToolCollapsed(
262
+ "Grep",
263
+ {},
264
+ { content: [{ type: "text", text: "hidden body output" }], isError: false },
265
+ );
266
+
267
+ assert.match(rendered, /Grep/);
268
+ assert.doesNotMatch(rendered, /^│\.\s+│/m, `expected no placeholder cwd body:\n${rendered}`);
269
+ assert.match(rendered, /output hidden/);
270
+ assert.doesNotMatch(rendered, /hidden body output/);
271
+ assert.doesNotMatch(rendered, /^│\s+output hidden/m, `expected compact footer text on the top row:\n${rendered}`);
272
+ });
273
+
274
+ test("keeps meaningful collapsed search targets", () => {
275
+ const rendered = renderToolCollapsed(
276
+ "Grep",
277
+ { pattern: "Project Initialized", path: "src/resources/extensions/gsd", glob: "*.ts" },
278
+ { content: [{ type: "text", text: "hidden body output" }], isError: false },
279
+ );
280
+
281
+ assert.match(rendered, /Project Initialized in src\/resources\/extensions\/gsd \(\*\.ts\)/);
282
+ assert.doesNotMatch(rendered, /hidden body output/);
283
+ });
284
+
184
285
  test("renders compact bash rows with command preview", () => {
185
286
  const rendered = renderToolCollapsed(
186
287
  "bash",
@@ -188,7 +289,8 @@ describe("ToolExecutionComponent", () => {
188
289
  { content: [{ type: "text", text: "ok" }], isError: false, details: { cwd: "/tmp/project" } },
189
290
  );
190
291
 
191
- assert.match(rendered, /bash npm run typecheck -- --watch false/);
292
+ assert.match(rendered, /\$ npm run typecheck -- --watch false/);
293
+ assert.doesNotMatch(rendered, /├/, "collapsed command cards should not include internal divider lines");
192
294
  assert.doesNotMatch(rendered, /\bok\b/);
193
295
  });
194
296
 
@@ -339,7 +441,7 @@ describe("ToolExecutionComponent", () => {
339
441
  assert.doesNotMatch(rendered, /gsd_requirement_update/);
340
442
  });
341
443
 
342
- test("formatCompactArgs truncates long string values inline instead of dumping JSON", () => {
444
+ test("collapsed generic running tools hide primitive args", () => {
343
445
  const longPath = "/Users/alice/.gsd/projects/4dce7b775013/worktrees/slice-S03-some-long-path-that-exceeds-limit";
344
446
  const rendered = renderToolCollapsed("gsd_slice_complete", {
345
447
  sliceId: "S03",
@@ -347,9 +449,11 @@ describe("ToolExecutionComponent", () => {
347
449
  worktree: longPath,
348
450
  });
349
451
 
350
- assert.match(rendered, /sliceId="S03"/);
351
- assert.match(rendered, /milestoneId="M001"/);
352
- assert.match(rendered, /worktree=".*…"/);
452
+ assert.match(rendered, /Slice Complete/);
453
+ assert.match(rendered, /running · \d+(ms|s)/);
454
+ assert.doesNotMatch(rendered, /sliceId="S03"/);
455
+ assert.doesNotMatch(rendered, /milestoneId="M001"/);
456
+ assert.doesNotMatch(rendered, /worktree=/);
353
457
  assert.doesNotMatch(rendered, /"sliceId":\s*"S03"/);
354
458
  });
355
459
 
@@ -0,0 +1,48 @@
1
+ // Project/App: GSD-2
2
+ // File Purpose: Visual contract tests for left-edge user chat rails.
3
+
4
+ import { describe, test } from "node:test";
5
+ import assert from "node:assert/strict";
6
+ import { stripVTControlCharacters } from "node:util";
7
+ import type { AssistantMessage } from "@gsd/pi-ai";
8
+
9
+ import { initTheme } from "../../theme/theme.js";
10
+ import { AssistantMessageComponent } from "../assistant-message.js";
11
+ import { UserMessageComponent } from "../user-message.js";
12
+
13
+ initTheme("dark", false);
14
+
15
+ describe("UserMessageComponent chat rail design", () => {
16
+ test("renders user messages against the left edge", () => {
17
+ const component = new UserMessageComponent("Can we make the transcript feel like chat?", undefined, 1, "date-time-iso");
18
+ const raw = component.render(100);
19
+ const plain = raw.map((line) => stripVTControlCharacters(line));
20
+ const joined = plain.join("\n");
21
+
22
+ assert.ok(plain.some((line) => /^┃ You/.test(line)), `expected left-edge user rail header:\n${joined}`);
23
+ assert.ok(plain.some((line) => /^┃ Can we make the transcript feel like chat\?/.test(line)), `expected left-edge user rail body:\n${joined}`);
24
+ assert.ok(raw.some((line) => line.includes("\x1b[48;")), `expected faint user block background:\n${raw.join("\n")}`);
25
+ assert.match(joined, /^┃\s*$/m, "user block should include vertical padding rows");
26
+ assert.match(joined, /feel like chat/);
27
+ assert.doesNotMatch(joined, /[╭╮╰╯]/, "user rail should not use boxed bubble corners");
28
+ assert.doesNotMatch(joined, /^ ┃ You/m, "user rail should not be indented like GSD messages");
29
+ });
30
+
31
+ test("uses a different faint background than GSD messages", () => {
32
+ const user = new UserMessageComponent("Use a distinct user color.");
33
+ const assistant = new AssistantMessageComponent({
34
+ id: "m1",
35
+ role: "assistant",
36
+ provider: "test",
37
+ model: "gpt-test",
38
+ content: [{ type: "text", text: "GSD message." }],
39
+ } as unknown as AssistantMessage);
40
+
41
+ const userBg = user.render(100).join("\n").match(/\x1b\[48;[^m]+m/)?.[0];
42
+ const assistantBg = assistant.render(100).join("\n").match(/\x1b\[48;[^m]+m/)?.[0];
43
+
44
+ assert.ok(userBg, "expected user message background color");
45
+ assert.ok(assistantBg, "expected assistant message background color");
46
+ assert.notEqual(userBg, assistantBg, "user and GSD message backgrounds should be distinct");
47
+ });
48
+ });
@@ -1,4 +1,5 @@
1
- // GSD2 - Runtime tests for adaptive terminal layout rendering
1
+ // Project/App: GSD-2
2
+ // File Purpose: Runtime tests for adaptive command-center terminal layout rendering.
2
3
 
3
4
  import assert from "node:assert/strict";
4
5
  import { describe, it, before } from "node:test";
@@ -15,7 +16,7 @@ function render(component: AdaptiveLayoutComponent, width: number): string {
15
16
  }
16
17
 
17
18
  describe("AdaptiveLayoutComponent", () => {
18
- it("renders workflow command center and inspector on wide terminals", () => {
19
+ it("renders a rounded workflow command center on wide terminals", () => {
19
20
  const component = new AdaptiveLayoutComponent(() => ({
20
21
  override: "workflow",
21
22
  activeToolCount: 2,
@@ -26,8 +27,13 @@ describe("AdaptiveLayoutComponent", () => {
26
27
 
27
28
  const output = render(component, 132);
28
29
  assert.match(output, /GSD Command Center/);
29
- assert.match(output, /signals/);
30
+ assert.match(output, /workflow · ready/);
30
31
  assert.match(output, /2 running/);
32
+ assert.match(output, /watch tool output/);
33
+ assert.doesNotMatch(output, /signals/);
34
+ assert.doesNotMatch(output, /inspector/);
35
+ assert.doesNotMatch(output, /\bauto\b/i);
36
+ assert.match(output, /^╭─+╮/m);
31
37
  });
32
38
 
33
39
  it("falls back to a single compact row for narrow workflow terminals", () => {
@@ -41,6 +47,7 @@ describe("AdaptiveLayoutComponent", () => {
41
47
  const output = render(component, 68);
42
48
  assert.match(output, /GSD compact/);
43
49
  assert.doesNotMatch(output, /signals/);
50
+ assert.doesNotMatch(output, /\bauto\b/i);
44
51
  });
45
52
 
46
53
  it("renders blocking failure context in debug mode", () => {
@@ -1,9 +1,11 @@
1
- // GSD2 - Adaptive terminal mode dashboard for the interactive TUI
1
+ // Project/App: GSD-2
2
+ // File Purpose: Adaptive command-center dashboard for the interactive TUI.
2
3
 
3
- import { style, truncateToWidth, visibleWidth, type Component } from "@gsd/pi-tui";
4
+ import { style, truncateToWidth, type Component } from "@gsd/pi-tui";
4
5
  import type { TuiAdaptiveMode, TuiMode } from "../tui-mode.js";
5
6
  import { resolveTuiMode } from "../tui-mode.js";
6
7
  import { theme, type ThemeColor } from "../theme/theme.js";
8
+ import { alignRight, breakpoint, keyValue, roundedPanel } from "./tui-style-kit.js";
7
9
 
8
10
  export interface AdaptiveLayoutState {
9
11
  override: TuiAdaptiveMode;
@@ -41,34 +43,44 @@ export class AdaptiveLayoutComponent implements Component {
41
43
  }
42
44
 
43
45
  private renderWorkflow(width: number, state: AdaptiveLayoutState): string[] {
44
- if (width < 112) return this.renderCompact(width, "workflow", state);
46
+ if (width < 72) return this.renderCompact(width, "workflow", state);
45
47
 
46
- const leftWidth = Math.max(44, Math.floor(width * 0.56));
47
- const rightWidth = Math.max(32, width - leftWidth - 2);
48
48
  const phase = state.gsdPhase ?? "Ready";
49
- const left = this.frame(
50
- [
51
- this.metric("Active", phase, "modeWorkflow"),
52
- this.metric("Tools", state.activeToolCount > 0 ? `${state.activeToolCount} running` : "idle", "toolRunning"),
53
- this.metric("Mode", state.override === "auto" ? "auto workflow" : state.override, "modeWorkflow"),
54
- ],
55
- leftWidth,
56
- "GSD Command Center",
57
- "workflow",
58
- "modeWorkflow",
59
- );
60
- const right = this.frame(
61
- [
62
- `Session ${state.sessionName ?? "current"}`,
63
- `Path ${this.basename(state.cwd)}`,
64
- `Next ${state.activeToolCount > 0 ? "watch tool output" : "continue from prompt"}`,
65
- ],
66
- rightWidth,
67
- "signals",
68
- "inspector",
69
- "surfaceAccent",
70
- );
71
- return this.columns(left, right, leftWidth);
49
+ const tools = state.activeToolCount > 0 ? `${state.activeToolCount} running` : "idle";
50
+ const next = state.activeToolCount > 0 ? "watch tool output" : "continue from prompt";
51
+ const modeLabel = state.override === "auto" ? "workflow" : state.override;
52
+ const bp = breakpoint(width);
53
+
54
+ const rows = bp === "regular"
55
+ ? [
56
+ keyValue("Status", phase, "modeWorkflow"),
57
+ keyValue("Tools", tools, state.activeToolCount > 0 ? "toolRunning" : "toolMuted"),
58
+ keyValue("Session", state.sessionName ?? "current", "text"),
59
+ keyValue("Next", next, "surfaceAccent"),
60
+ ]
61
+ : [
62
+ alignRight(
63
+ keyValue("Status", phase, "modeWorkflow"),
64
+ keyValue("Tools", tools, state.activeToolCount > 0 ? "toolRunning" : "toolMuted"),
65
+ Math.max(1, width - 2),
66
+ ),
67
+ alignRight(
68
+ keyValue("Session", state.sessionName ?? "current", "text"),
69
+ keyValue("Path", this.basename(state.cwd), "text"),
70
+ Math.max(1, width - 2),
71
+ ),
72
+ alignRight(
73
+ keyValue("Next", next, "surfaceAccent"),
74
+ keyValue("Mode", modeLabel, "modeWorkflow"),
75
+ Math.max(1, width - 2),
76
+ ),
77
+ ];
78
+
79
+ return roundedPanel(rows, width, {
80
+ title: "GSD Command Center",
81
+ rightTitle: `${modeLabel} · ${state.lastError ? "blocked" : "ready"}`,
82
+ tone: state.lastError ? "error" : "default",
83
+ });
72
84
  }
73
85
 
74
86
  private renderValidation(width: number, state: AdaptiveLayoutState): string[] {
@@ -140,21 +152,10 @@ export class AdaptiveLayoutComponent implements Component {
140
152
  return `${theme.fg("surfaceMuted", `${label.padEnd(8)} `)}${theme.fg(color, value)}`;
141
153
  }
142
154
 
143
- private columns(left: string[], right: string[], leftWidth: number): string[] {
144
- const rows = Math.max(left.length, right.length);
145
- const output: string[] = [];
146
- for (let i = 0; i < rows; i++) {
147
- const leftLine = left[i] ?? "";
148
- const rightLine = right[i] ?? "";
149
- const gap = " ".repeat(Math.max(2, leftWidth - visibleWidth(leftLine) + 2));
150
- output.push(`${leftLine}${gap}${rightLine}`);
151
- }
152
- return output;
153
- }
154
-
155
155
  private basename(cwd: string): string {
156
- const trimmed = cwd.replace(/\/+$/, "");
157
- const slash = trimmed.lastIndexOf("/");
156
+ const trimmed = cwd.replace(/[\\/]+$/, "");
157
+ if (!trimmed) return cwd.includes("\\") ? "\\" : "/";
158
+ const slash = Math.max(trimmed.lastIndexOf("/"), trimmed.lastIndexOf("\\"));
158
159
  return slash === -1 ? trimmed : trimmed.slice(slash + 1);
159
160
  }
160
161
  }
@@ -1,9 +1,11 @@
1
- // GSD2 TUI - Assistant message card renderer for interactive terminal sessions.
1
+ // Project/App: GSD-2
2
+ // File Purpose: Assistant message rail renderer for interactive terminal sessions.
2
3
  import type { AssistantMessage } from "@gsd/pi-ai";
3
4
  import { Container, Markdown, type MarkdownTheme, Spacer, Text } from "@gsd/pi-tui";
4
5
  import { getMarkdownTheme, theme } from "../theme/theme.js";
5
6
  import { type TimestampFormat } from "./timestamp.js";
6
- import { renderChatFrame } from "./chat-frame.js";
7
+ import { formatTimestamp } from "./timestamp.js";
8
+ import { renderAssistantRail } from "./transcript-design.js";
7
9
 
8
10
  export interface ContentRange {
9
11
  startIndex: number;
@@ -163,19 +165,17 @@ export class AssistantMessageComponent extends Container {
163
165
 
164
166
  override render(width: number): string[] {
165
167
  const frameWidth = Math.max(20, width);
166
- const contentWidth = Math.max(1, frameWidth - 4);
168
+ const contentWidth = Math.max(1, frameWidth - 2);
167
169
  const lines = super.render(contentWidth);
168
- const headerLabel = this.lastMessage?.model ? `GSD - ${this.lastMessage.model}` : "GSD";
169
- const framed = renderChatFrame(lines, frameWidth, {
170
- label: headerLabel,
171
- tone: "assistant",
172
- timestamp: this.lastMessage?.timestamp,
173
- timestampFormat: this.timestampFormat,
174
- showTimestamp: this.showMetadata,
175
- });
176
- if (framed.length === 0) {
177
- return framed;
170
+ const metaParts = [];
171
+ if (this.lastMessage?.model) metaParts.push(this.lastMessage.model);
172
+ if (this.showMetadata && this.lastMessage?.timestamp != null) {
173
+ metaParts.push(formatTimestamp(this.lastMessage.timestamp, this.timestampFormat));
178
174
  }
179
- return ["", ...framed];
175
+ const rendered = renderAssistantRail(lines, frameWidth, {
176
+ label: "GSD",
177
+ meta: metaParts.length > 0 ? `· ${metaParts.join(" · ")}` : undefined,
178
+ });
179
+ return rendered.length > 0 ? ["", ...rendered] : rendered;
180
180
  }
181
181
  }
@@ -1,6 +1,5 @@
1
- /**
2
- * Component for displaying bash command execution with streaming output.
3
- */
1
+ // Project/App: GSD-2
2
+ // File Purpose: Interactive terminal bash execution renderer with streaming output and recommended command cards.
4
3
 
5
4
  import { Container, Loader, Spacer, Text, type TUI } from "@gsd/pi-tui";
6
5
  import stripAnsi from "strip-ansi";
@@ -13,6 +12,7 @@ import {
13
12
  import { theme } from "../theme/theme.js";
14
13
  import { DynamicBorder } from "./dynamic-border.js";
15
14
  import { editorKey, keyHint } from "./keybinding-hints.js";
15
+ import { renderCommandCard, renderTranscriptCard, type StatusTone } from "./transcript-design.js";
16
16
  import { truncateToVisualLines } from "./visual-truncate.js";
17
17
 
18
18
  // Preview line limit when not expanded (matches tool execution behavior)
@@ -120,6 +120,67 @@ export class BashExecutionComponent extends Container {
120
120
  this.updateDisplay();
121
121
  }
122
122
 
123
+ override render(width: number): string[] {
124
+ const frameWidth = Math.max(20, width);
125
+ const elapsedStatus =
126
+ this.status === "running"
127
+ ? "running"
128
+ : this.status === "complete"
129
+ ? "success"
130
+ : this.status === "cancelled"
131
+ ? "cancelled"
132
+ : `failed${this.exitCode !== undefined ? ` · exit ${this.exitCode}` : ""}`;
133
+ const tone: StatusTone =
134
+ this.status === "running"
135
+ ? "running"
136
+ : this.status === "complete"
137
+ ? "success"
138
+ : this.status === "cancelled"
139
+ ? "warning"
140
+ : "error";
141
+
142
+ if (!this.expanded && this.status !== "error") {
143
+ return [
144
+ "",
145
+ ...renderCommandCard(this.command.replace(/\s+/g, " ").trim(), frameWidth, {
146
+ status: elapsedStatus,
147
+ tone,
148
+ }),
149
+ ];
150
+ }
151
+
152
+ const output = this.outputLines.join("\n");
153
+ const contextTruncation = truncateTail(output, {
154
+ maxLines: DEFAULT_MAX_LINES,
155
+ maxBytes: DEFAULT_MAX_BYTES,
156
+ });
157
+ const truncationResult = this.truncationResult ?? contextTruncation;
158
+ const fullOutputPath = this.fullOutputPath;
159
+ const availableLines = contextTruncation.content ? contextTruncation.content.split("\n") : [];
160
+ const preview = this.expanded ? availableLines : availableLines.slice(-PREVIEW_LINES);
161
+ const hidden = Math.max(0, availableLines.length - preview.length);
162
+ const truncationWarning =
163
+ (truncationResult.truncated || contextTruncation.truncated) && fullOutputPath
164
+ ? [theme.fg("warning", `Output truncated. Full output: ${fullOutputPath}`)]
165
+ : [];
166
+ const body = [
167
+ theme.fg("toolTitle", `$ ${this.command}`),
168
+ ...preview.map((line) => theme.fg("toolOutput", line)),
169
+ ...(hidden > 0 ? [theme.fg("muted", `... ${hidden} earlier lines`)] : []),
170
+ ...truncationWarning,
171
+ ];
172
+ return [
173
+ "",
174
+ ...renderTranscriptCard(body, frameWidth, {
175
+ title: "command",
176
+ right: elapsedStatus,
177
+ tone,
178
+ footerLeft: this.expanded ? "output expanded" : "output preview",
179
+ footerRight: this.expanded ? "ctrl+o collapse" : "ctrl+o expand",
180
+ }),
181
+ ];
182
+ }
183
+
123
184
  private updateDisplay(): void {
124
185
  // Apply truncation for LLM context limits (same limits as bash tool)
125
186
  const fullOutput = this.outputLines.join("\n");