@opengsd/gsd-pi 1.2.0-dev.0b870afa → 1.2.0-dev.23d85b63

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 (579) hide show
  1. package/dist/cli-model-override.d.ts +15 -0
  2. package/dist/cli-model-override.js +21 -0
  3. package/dist/cli.js +14 -19
  4. package/dist/headless-events.d.ts +16 -1
  5. package/dist/headless-events.js +19 -2
  6. package/dist/headless.js +8 -1
  7. package/dist/loader.js +6 -4
  8. package/dist/onboarding.js +9 -4
  9. package/dist/provider-migrations.d.ts +23 -0
  10. package/dist/provider-migrations.js +41 -0
  11. package/dist/register-agent-bundles.d.ts +11 -2
  12. package/dist/register-agent-bundles.js +18 -4
  13. package/dist/resource-loader.d.ts +10 -5
  14. package/dist/resource-loader.js +121 -6
  15. package/dist/resources/.managed-resources-content-hash +1 -1
  16. package/dist/resources/extensions/ask-user-questions.js +3 -2
  17. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +447 -215
  18. package/dist/resources/extensions/claude-code-cli/turn-assembler.js +33 -1
  19. package/dist/resources/extensions/google-cli/stream-adapter.js +16 -1
  20. package/dist/resources/extensions/gsd/auto/closeout.js +215 -0
  21. package/dist/resources/extensions/gsd/auto/dispatch-history.js +21 -6
  22. package/dist/resources/extensions/gsd/auto/dispatch.js +365 -0
  23. package/dist/resources/extensions/gsd/auto/finalize.js +347 -0
  24. package/dist/resources/extensions/gsd/auto/loop.js +4 -1
  25. package/dist/resources/extensions/gsd/auto/milestone-lease-reclaim.js +56 -0
  26. package/dist/resources/extensions/gsd/auto/orchestrator.js +119 -18
  27. package/dist/resources/extensions/gsd/auto/phase-helpers.js +146 -0
  28. package/dist/resources/extensions/gsd/auto/phases.js +17 -2372
  29. package/dist/resources/extensions/gsd/auto/pre-dispatch.js +542 -0
  30. package/dist/resources/extensions/gsd/auto/unit-phase.js +694 -0
  31. package/dist/resources/extensions/gsd/auto/workflow-unit-dispatch.js +1 -1
  32. package/dist/resources/extensions/gsd/auto/worktree-safety-phase.js +125 -0
  33. package/dist/resources/extensions/gsd/auto-closeout-messaging.js +90 -0
  34. package/dist/resources/extensions/gsd/auto-dashboard.js +255 -431
  35. package/dist/resources/extensions/gsd/auto-direct-dispatch.js +15 -3
  36. package/dist/resources/extensions/gsd/auto-dispatch.js +19 -1
  37. package/dist/resources/extensions/gsd/auto-model-selection.js +9 -6
  38. package/dist/resources/extensions/gsd/auto-post-unit.js +12 -8
  39. package/dist/resources/extensions/gsd/auto-prompts.js +5 -1
  40. package/dist/resources/extensions/gsd/auto-recovery.js +52 -6
  41. package/dist/resources/extensions/gsd/auto-start.js +28 -7
  42. package/dist/resources/extensions/gsd/auto-worktree.js +48 -3
  43. package/dist/resources/extensions/gsd/auto.js +83 -19
  44. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +4 -2
  45. package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +37 -7
  46. package/dist/resources/extensions/gsd/bootstrap/register-extension.js +3 -1
  47. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +32 -3
  48. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +56 -16
  49. package/dist/resources/extensions/gsd/closeout-wizard.js +8 -3
  50. package/dist/resources/extensions/gsd/commands/handlers/core.js +22 -8
  51. package/dist/resources/extensions/gsd/commands/handlers/ops.js +2 -2
  52. package/dist/resources/extensions/gsd/commands-mcp-status.js +2 -2
  53. package/dist/resources/extensions/gsd/commands-prefs-wizard.js +8 -0
  54. package/dist/resources/extensions/gsd/commands-workflow-templates.js +9 -2
  55. package/dist/resources/extensions/gsd/config-overlay.js +11 -8
  56. package/dist/resources/extensions/gsd/db/engine.js +24 -6
  57. package/dist/resources/extensions/gsd/db/queries.js +30 -0
  58. package/dist/resources/extensions/gsd/db/writers/reconcile.js +19 -1
  59. package/dist/resources/extensions/gsd/db-migration-backup.js +51 -8
  60. package/dist/resources/extensions/gsd/db-transaction.js +27 -23
  61. package/dist/resources/extensions/gsd/db-writer.js +8 -17
  62. package/dist/resources/extensions/gsd/doctor-environment.js +256 -125
  63. package/dist/resources/extensions/gsd/doctor-git-checks.js +5 -1
  64. package/dist/resources/extensions/gsd/doctor-providers.js +1 -1
  65. package/dist/resources/extensions/gsd/doctor-runtime-checks.js +11 -9
  66. package/dist/resources/extensions/gsd/gsd-db.js +15 -20
  67. package/dist/resources/extensions/gsd/guided-flow.js +88 -2
  68. package/dist/resources/extensions/gsd/health-widget.js +87 -28
  69. package/dist/resources/extensions/gsd/mcp-bridge.js +10 -0
  70. package/dist/resources/extensions/gsd/memory-relations.js +1 -1
  71. package/dist/resources/extensions/gsd/milestone-settlement.js +2 -2
  72. package/dist/resources/extensions/gsd/notifications.js +12 -7
  73. package/dist/resources/extensions/gsd/preferences-models.js +17 -9
  74. package/dist/resources/extensions/gsd/preferences.js +91 -5
  75. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +8 -2
  76. package/dist/resources/extensions/gsd/prompts/complete-slice.md +6 -2
  77. package/dist/resources/extensions/gsd/prompts/execute-task.md +7 -2
  78. package/dist/resources/extensions/gsd/prompts/quick-task.md +1 -1
  79. package/dist/resources/extensions/gsd/prompts/reactive-execute.md +2 -2
  80. package/dist/resources/extensions/gsd/prompts/run-uat.md +7 -1
  81. package/dist/resources/extensions/gsd/prompts/triage-captures.md +1 -1
  82. package/dist/resources/extensions/gsd/prompts/workflow-start.md +2 -1
  83. package/dist/resources/extensions/gsd/provider-error-guidance.js +24 -0
  84. package/dist/resources/extensions/gsd/session-lock.js +4 -3
  85. package/dist/resources/extensions/gsd/skill-activation.js +3 -6
  86. package/dist/resources/extensions/gsd/state-reconciliation/drift/artifact-db.js +13 -6
  87. package/dist/resources/extensions/gsd/state.js +6 -2
  88. package/dist/resources/extensions/gsd/tool-surface-readiness.js +83 -31
  89. package/dist/resources/extensions/gsd/tools/complete-task.js +62 -0
  90. package/dist/resources/extensions/gsd/tools/exec-tool.js +2 -109
  91. package/dist/resources/extensions/gsd/tui/render-kit.js +38 -13
  92. package/dist/resources/extensions/gsd/unit-context-composer.js +1 -1
  93. package/dist/resources/extensions/gsd/unit-registry.js +34 -4
  94. package/dist/resources/extensions/gsd/workflow-logger.js +4 -0
  95. package/dist/resources/extensions/gsd/workflow-mcp-auto-prep.js +2 -0
  96. package/dist/resources/extensions/gsd/workflow-mcp-readiness-cache.js +105 -0
  97. package/dist/resources/extensions/gsd/worktree-manager.js +101 -2
  98. package/dist/resources/extensions/gsd/worktree-safety.js +28 -26
  99. package/dist/resources/extensions/gsd/worktree-shell-guard.js +113 -0
  100. package/dist/resources/extensions/gsd/worktree.js +8 -1
  101. package/dist/resources/extensions/mcp-client/manager.js +6 -1
  102. package/dist/resources/extensions/search-the-web/index.js +41 -9
  103. package/dist/resources/extensions/search-the-web/native-search.js +18 -4
  104. package/dist/resources/extensions/shared/gsd-browser-cli.js +40 -2
  105. package/dist/resources/extensions/subagent/index.js +20 -15
  106. package/dist/resources/extensions/subagent/worktree-cwd.js +31 -0
  107. package/dist/resources/skills/create-skill/SKILL.md +3 -0
  108. package/dist/resources/skills/create-skill/references/skill-structure.md +1 -0
  109. package/dist/runtime-checks.d.ts +10 -0
  110. package/dist/runtime-checks.js +27 -0
  111. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  112. package/dist/web/standalone/.next/BUILD_ID +1 -1
  113. package/dist/web/standalone/.next/app-path-routes-manifest.json +10 -10
  114. package/dist/web/standalone/.next/build-manifest.json +2 -2
  115. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  116. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  117. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  118. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  119. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  120. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  121. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  122. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  123. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  124. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  125. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  126. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  127. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  128. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  129. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  130. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  131. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  132. package/dist/web/standalone/.next/server/app/api/boot/route.js.nft.json +1 -1
  133. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js.nft.json +1 -1
  134. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js.nft.json +1 -1
  135. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js.nft.json +1 -1
  136. package/dist/web/standalone/.next/server/app/api/captures/route.js.nft.json +1 -1
  137. package/dist/web/standalone/.next/server/app/api/cleanup/route.js.nft.json +1 -1
  138. package/dist/web/standalone/.next/server/app/api/doctor/route.js.nft.json +1 -1
  139. package/dist/web/standalone/.next/server/app/api/export-data/route.js.nft.json +1 -1
  140. package/dist/web/standalone/.next/server/app/api/files/route.js.nft.json +1 -1
  141. package/dist/web/standalone/.next/server/app/api/forensics/route.js.nft.json +1 -1
  142. package/dist/web/standalone/.next/server/app/api/git/route.js.nft.json +1 -1
  143. package/dist/web/standalone/.next/server/app/api/history/route.js.nft.json +1 -1
  144. package/dist/web/standalone/.next/server/app/api/hooks/route.js.nft.json +1 -1
  145. package/dist/web/standalone/.next/server/app/api/inspect/route.js.nft.json +1 -1
  146. package/dist/web/standalone/.next/server/app/api/knowledge/route.js.nft.json +1 -1
  147. package/dist/web/standalone/.next/server/app/api/live-state/route.js.nft.json +1 -1
  148. package/dist/web/standalone/.next/server/app/api/mcp-connections/route.js.nft.json +1 -1
  149. package/dist/web/standalone/.next/server/app/api/notifications/route.js.nft.json +1 -1
  150. package/dist/web/standalone/.next/server/app/api/onboarding/route.js.nft.json +1 -1
  151. package/dist/web/standalone/.next/server/app/api/projects/route.js.nft.json +1 -1
  152. package/dist/web/standalone/.next/server/app/api/recovery/route.js.nft.json +1 -1
  153. package/dist/web/standalone/.next/server/app/api/session/browser/route.js.nft.json +1 -1
  154. package/dist/web/standalone/.next/server/app/api/session/command/route.js.nft.json +1 -1
  155. package/dist/web/standalone/.next/server/app/api/session/events/route.js.nft.json +1 -1
  156. package/dist/web/standalone/.next/server/app/api/session/manage/route.js.nft.json +1 -1
  157. package/dist/web/standalone/.next/server/app/api/settings-data/route.js.nft.json +1 -1
  158. package/dist/web/standalone/.next/server/app/api/shutdown/route.js.nft.json +1 -1
  159. package/dist/web/standalone/.next/server/app/api/skill-health/route.js.nft.json +1 -1
  160. package/dist/web/standalone/.next/server/app/api/steer/route.js.nft.json +1 -1
  161. package/dist/web/standalone/.next/server/app/api/switch-root/route.js.nft.json +1 -1
  162. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js.nft.json +1 -1
  163. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js.nft.json +1 -1
  164. package/dist/web/standalone/.next/server/app/api/undo/route.js.nft.json +1 -1
  165. package/dist/web/standalone/.next/server/app/api/visualizer/route.js.nft.json +1 -1
  166. package/dist/web/standalone/.next/server/app/index.html +1 -1
  167. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  168. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  169. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  170. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  171. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  172. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  173. package/dist/web/standalone/.next/server/app-paths-manifest.json +10 -10
  174. package/dist/web/standalone/.next/server/chunks/{5942.js → 1128.js} +1 -1
  175. package/dist/web/standalone/.next/server/chunks/8357.js +1 -1
  176. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  177. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  178. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  179. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  180. package/dist/web/standalone/node_modules/node-pty/build/Makefile +1 -1
  181. package/package.json +4 -4
  182. package/packages/cloud-mcp-gateway/package.json +2 -2
  183. package/packages/contracts/package.json +1 -1
  184. package/packages/daemon/package.json +4 -4
  185. package/packages/gsd-agent-core/dist/sdk.d.ts.map +1 -1
  186. package/packages/gsd-agent-core/dist/sdk.js +12 -6
  187. package/packages/gsd-agent-core/dist/sdk.js.map +1 -1
  188. package/packages/gsd-agent-core/package.json +5 -5
  189. package/packages/gsd-agent-modes/dist/modes/interactive/components/assistant-message.d.ts +5 -5
  190. package/packages/gsd-agent-modes/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  191. package/packages/gsd-agent-modes/dist/modes/interactive/components/assistant-message.js +12 -24
  192. package/packages/gsd-agent-modes/dist/modes/interactive/components/assistant-message.js.map +1 -1
  193. package/packages/gsd-agent-modes/dist/modes/interactive/components/bash-execution.js +5 -5
  194. package/packages/gsd-agent-modes/dist/modes/interactive/components/bash-execution.js.map +1 -1
  195. package/packages/gsd-agent-modes/dist/modes/interactive/components/branch-summary-message.d.ts +3 -3
  196. package/packages/gsd-agent-modes/dist/modes/interactive/components/branch-summary-message.d.ts.map +1 -1
  197. package/packages/gsd-agent-modes/dist/modes/interactive/components/branch-summary-message.js +20 -11
  198. package/packages/gsd-agent-modes/dist/modes/interactive/components/branch-summary-message.js.map +1 -1
  199. package/packages/gsd-agent-modes/dist/modes/interactive/components/chat-turn-connect.d.ts +4 -3
  200. package/packages/gsd-agent-modes/dist/modes/interactive/components/chat-turn-connect.d.ts.map +1 -1
  201. package/packages/gsd-agent-modes/dist/modes/interactive/components/chat-turn-connect.js +5 -54
  202. package/packages/gsd-agent-modes/dist/modes/interactive/components/chat-turn-connect.js.map +1 -1
  203. package/packages/gsd-agent-modes/dist/modes/interactive/components/compaction-summary-message.d.ts +2 -4
  204. package/packages/gsd-agent-modes/dist/modes/interactive/components/compaction-summary-message.d.ts.map +1 -1
  205. package/packages/gsd-agent-modes/dist/modes/interactive/components/compaction-summary-message.js +2 -4
  206. package/packages/gsd-agent-modes/dist/modes/interactive/components/compaction-summary-message.js.map +1 -1
  207. package/packages/gsd-agent-modes/dist/modes/interactive/components/custom-editor.d.ts +2 -0
  208. package/packages/gsd-agent-modes/dist/modes/interactive/components/custom-editor.d.ts.map +1 -1
  209. package/packages/gsd-agent-modes/dist/modes/interactive/components/custom-editor.js +4 -0
  210. package/packages/gsd-agent-modes/dist/modes/interactive/components/custom-editor.js.map +1 -1
  211. package/packages/gsd-agent-modes/dist/modes/interactive/components/footer.d.ts +9 -12
  212. package/packages/gsd-agent-modes/dist/modes/interactive/components/footer.d.ts.map +1 -1
  213. package/packages/gsd-agent-modes/dist/modes/interactive/components/footer.js +100 -166
  214. package/packages/gsd-agent-modes/dist/modes/interactive/components/footer.js.map +1 -1
  215. package/packages/gsd-agent-modes/dist/modes/interactive/components/gsd-progress-state.d.ts +2 -0
  216. package/packages/gsd-agent-modes/dist/modes/interactive/components/gsd-progress-state.d.ts.map +1 -0
  217. package/packages/gsd-agent-modes/dist/modes/interactive/components/gsd-progress-state.js +4 -0
  218. package/packages/gsd-agent-modes/dist/modes/interactive/components/gsd-progress-state.js.map +1 -0
  219. package/packages/gsd-agent-modes/dist/modes/interactive/components/gsd-status-widget.d.ts +23 -0
  220. package/packages/gsd-agent-modes/dist/modes/interactive/components/gsd-status-widget.d.ts.map +1 -0
  221. package/packages/gsd-agent-modes/dist/modes/interactive/components/gsd-status-widget.js +178 -0
  222. package/packages/gsd-agent-modes/dist/modes/interactive/components/gsd-status-widget.js.map +1 -0
  223. package/packages/gsd-agent-modes/dist/modes/interactive/components/login-dialog.d.ts +8 -0
  224. package/packages/gsd-agent-modes/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
  225. package/packages/gsd-agent-modes/dist/modes/interactive/components/login-dialog.js +21 -9
  226. package/packages/gsd-agent-modes/dist/modes/interactive/components/login-dialog.js.map +1 -1
  227. package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.d.ts +2 -0
  228. package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  229. package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.js +10 -0
  230. package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.js.map +1 -1
  231. package/packages/gsd-agent-modes/dist/modes/interactive/components/skill-invocation-message.d.ts +2 -3
  232. package/packages/gsd-agent-modes/dist/modes/interactive/components/skill-invocation-message.d.ts.map +1 -1
  233. package/packages/gsd-agent-modes/dist/modes/interactive/components/skill-invocation-message.js +2 -3
  234. package/packages/gsd-agent-modes/dist/modes/interactive/components/skill-invocation-message.js.map +1 -1
  235. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts +11 -0
  236. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  237. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js +85 -19
  238. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js.map +1 -1
  239. package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.d.ts +71 -3
  240. package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.d.ts.map +1 -1
  241. package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.js +257 -37
  242. package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.js.map +1 -1
  243. package/packages/gsd-agent-modes/dist/modes/interactive/components/user-message.d.ts +3 -3
  244. package/packages/gsd-agent-modes/dist/modes/interactive/components/user-message.d.ts.map +1 -1
  245. package/packages/gsd-agent-modes/dist/modes/interactive/components/user-message.js +19 -19
  246. package/packages/gsd-agent-modes/dist/modes/interactive/components/user-message.js.map +1 -1
  247. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts +3 -0
  248. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  249. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js +26 -10
  250. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  251. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/extension-ui-controller.d.ts.map +1 -1
  252. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/extension-ui-controller.js +12 -1
  253. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/extension-ui-controller.js.map +1 -1
  254. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.d.ts.map +1 -1
  255. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.js +5 -0
  256. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.js.map +1 -1
  257. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-autocomplete.d.ts.map +1 -1
  258. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-autocomplete.js +3 -1
  259. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-autocomplete.js.map +1 -1
  260. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-chat-render.d.ts.map +1 -1
  261. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-chat-render.js +3 -5
  262. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-chat-render.js.map +1 -1
  263. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-extension-dialogs.js +2 -2
  264. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-extension-dialogs.js.map +1 -1
  265. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-extension-widgets.d.ts +1 -0
  266. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-extension-widgets.d.ts.map +1 -1
  267. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-extension-widgets.js +25 -0
  268. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-extension-widgets.js.map +1 -1
  269. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-key-handlers.d.ts.map +1 -1
  270. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-key-handlers.js +1 -0
  271. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-key-handlers.js.map +1 -1
  272. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-init.d.ts +1 -0
  273. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-init.d.ts.map +1 -1
  274. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-init.js +20 -49
  275. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-init.js.map +1 -1
  276. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-state.d.ts +4 -0
  277. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-state.d.ts.map +1 -1
  278. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-state.js.map +1 -1
  279. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.d.ts +10 -2
  280. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  281. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js +48 -6
  282. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js.map +1 -1
  283. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-settings.d.ts.map +1 -1
  284. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-settings.js +4 -0
  285. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-settings.js.map +1 -1
  286. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-ui-messaging.d.ts.map +1 -1
  287. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-ui-messaging.js +0 -1
  288. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-ui-messaging.js.map +1 -1
  289. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  290. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.js +3 -0
  291. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.js.map +1 -1
  292. package/packages/gsd-agent-modes/package.json +7 -7
  293. package/packages/mcp-server/README.md +12 -3
  294. package/packages/mcp-server/dist/cli-runner.d.ts +40 -0
  295. package/packages/mcp-server/dist/cli-runner.d.ts.map +1 -0
  296. package/packages/mcp-server/dist/cli-runner.js +137 -0
  297. package/packages/mcp-server/dist/cli-runner.js.map +1 -0
  298. package/packages/mcp-server/dist/cli.js +2 -58
  299. package/packages/mcp-server/dist/cli.js.map +1 -1
  300. package/packages/mcp-server/dist/pid-registry.d.ts +46 -0
  301. package/packages/mcp-server/dist/pid-registry.d.ts.map +1 -0
  302. package/packages/mcp-server/dist/pid-registry.js +459 -0
  303. package/packages/mcp-server/dist/pid-registry.js.map +1 -0
  304. package/packages/mcp-server/dist/probe-mode.d.ts +4 -0
  305. package/packages/mcp-server/dist/probe-mode.d.ts.map +1 -0
  306. package/packages/mcp-server/dist/probe-mode.js +10 -0
  307. package/packages/mcp-server/dist/probe-mode.js.map +1 -0
  308. package/packages/mcp-server/dist/stdio-watchdog.d.ts +8 -0
  309. package/packages/mcp-server/dist/stdio-watchdog.d.ts.map +1 -0
  310. package/packages/mcp-server/dist/stdio-watchdog.js +40 -0
  311. package/packages/mcp-server/dist/stdio-watchdog.js.map +1 -0
  312. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  313. package/packages/mcp-server/dist/workflow-tools.js +62 -43
  314. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  315. package/packages/mcp-server/package.json +5 -5
  316. package/packages/native/package.json +1 -1
  317. package/packages/pi-agent-core/dist/agent-loop.js +52 -2
  318. package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
  319. package/packages/pi-agent-core/package.json +1 -1
  320. package/packages/pi-ai/package.json +1 -1
  321. package/packages/pi-coding-agent/dist/core/extensions/extension-upstream-types.d.ts +28 -2
  322. package/packages/pi-coding-agent/dist/core/extensions/extension-upstream-types.d.ts.map +1 -1
  323. package/packages/pi-coding-agent/dist/core/extensions/extension-upstream-types.js.map +1 -1
  324. package/packages/pi-coding-agent/dist/core/extensions/index.d.ts +1 -1
  325. package/packages/pi-coding-agent/dist/core/extensions/index.d.ts.map +1 -1
  326. package/packages/pi-coding-agent/dist/core/extensions/index.js.map +1 -1
  327. package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts +5 -1
  328. package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts.map +1 -1
  329. package/packages/pi-coding-agent/dist/core/extensions/runner.js +3 -1
  330. package/packages/pi-coding-agent/dist/core/extensions/runner.js.map +1 -1
  331. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +3 -0
  332. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
  333. package/packages/pi-coding-agent/dist/core/settings-manager.js +11 -0
  334. package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
  335. package/packages/pi-coding-agent/dist/index.d.ts +1 -1
  336. package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
  337. package/packages/pi-coding-agent/dist/index.js.map +1 -1
  338. package/packages/pi-coding-agent/dist/theme/theme.d.ts.map +1 -1
  339. package/packages/pi-coding-agent/dist/theme/theme.js +45 -17
  340. package/packages/pi-coding-agent/dist/theme/theme.js.map +1 -1
  341. package/packages/pi-coding-agent/package.json +8 -8
  342. package/packages/pi-tui/README.md +15 -0
  343. package/packages/pi-tui/dist/autocomplete.d.ts.map +1 -1
  344. package/packages/pi-tui/dist/autocomplete.js +6 -1
  345. package/packages/pi-tui/dist/autocomplete.js.map +1 -1
  346. package/packages/pi-tui/dist/components/input.js +1 -1
  347. package/packages/pi-tui/dist/components/input.js.map +1 -1
  348. package/packages/pi-tui/dist/components/loader.d.ts.map +1 -1
  349. package/packages/pi-tui/dist/components/loader.js +1 -0
  350. package/packages/pi-tui/dist/components/loader.js.map +1 -1
  351. package/packages/pi-tui/dist/components/select-list.d.ts.map +1 -1
  352. package/packages/pi-tui/dist/components/select-list.js +8 -2
  353. package/packages/pi-tui/dist/components/select-list.js.map +1 -1
  354. package/packages/pi-tui/dist/index.d.ts +2 -2
  355. package/packages/pi-tui/dist/index.d.ts.map +1 -1
  356. package/packages/pi-tui/dist/index.js +2 -2
  357. package/packages/pi-tui/dist/index.js.map +1 -1
  358. package/packages/pi-tui/dist/terminal-image.d.ts +33 -0
  359. package/packages/pi-tui/dist/terminal-image.d.ts.map +1 -1
  360. package/packages/pi-tui/dist/terminal-image.js +54 -2
  361. package/packages/pi-tui/dist/terminal-image.js.map +1 -1
  362. package/packages/pi-tui/dist/terminal.d.ts +12 -0
  363. package/packages/pi-tui/dist/terminal.d.ts.map +1 -1
  364. package/packages/pi-tui/dist/terminal.js +70 -25
  365. package/packages/pi-tui/dist/terminal.js.map +1 -1
  366. package/packages/pi-tui/dist/tui.d.ts +15 -0
  367. package/packages/pi-tui/dist/tui.d.ts.map +1 -1
  368. package/packages/pi-tui/dist/tui.js +106 -21
  369. package/packages/pi-tui/dist/tui.js.map +1 -1
  370. package/packages/pi-tui/dist/utils.d.ts.map +1 -1
  371. package/packages/pi-tui/dist/utils.js +110 -36
  372. package/packages/pi-tui/dist/utils.js.map +1 -1
  373. package/packages/pi-tui/package.json +2 -2
  374. package/packages/rpc-client/package.json +2 -2
  375. package/pkg/dist/theme/theme.d.ts.map +1 -1
  376. package/pkg/dist/theme/theme.js +45 -17
  377. package/pkg/dist/theme/theme.js.map +1 -1
  378. package/pkg/package.json +1 -1
  379. package/src/resources/extensions/ask-user-questions.ts +7 -2
  380. package/src/resources/extensions/browser-tools/tests/gsd-browser-launch-config.test.mjs +80 -0
  381. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +531 -226
  382. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +672 -7
  383. package/src/resources/extensions/claude-code-cli/turn-assembler.ts +38 -1
  384. package/src/resources/extensions/google-cli/stream-adapter.ts +22 -1
  385. package/src/resources/extensions/gsd/auto/closeout.ts +309 -0
  386. package/src/resources/extensions/gsd/auto/dispatch-history.ts +22 -6
  387. package/src/resources/extensions/gsd/auto/dispatch.ts +449 -0
  388. package/src/resources/extensions/gsd/auto/finalize.ts +445 -0
  389. package/src/resources/extensions/gsd/auto/loop.ts +4 -1
  390. package/src/resources/extensions/gsd/auto/milestone-lease-reclaim.ts +74 -0
  391. package/src/resources/extensions/gsd/auto/orchestrator.ts +140 -18
  392. package/src/resources/extensions/gsd/auto/phase-helpers.ts +199 -0
  393. package/src/resources/extensions/gsd/auto/phases.ts +58 -3061
  394. package/src/resources/extensions/gsd/auto/pre-dispatch.ts +716 -0
  395. package/src/resources/extensions/gsd/auto/unit-phase.ts +910 -0
  396. package/src/resources/extensions/gsd/auto/workflow-unit-dispatch.ts +1 -1
  397. package/src/resources/extensions/gsd/auto/worktree-safety-phase.ts +149 -0
  398. package/src/resources/extensions/gsd/auto-closeout-messaging.ts +90 -0
  399. package/src/resources/extensions/gsd/auto-dashboard.ts +310 -454
  400. package/src/resources/extensions/gsd/auto-direct-dispatch.ts +15 -2
  401. package/src/resources/extensions/gsd/auto-dispatch.ts +24 -2
  402. package/src/resources/extensions/gsd/auto-model-selection.ts +20 -5
  403. package/src/resources/extensions/gsd/auto-post-unit.ts +16 -9
  404. package/src/resources/extensions/gsd/auto-prompts.ts +5 -1
  405. package/src/resources/extensions/gsd/auto-recovery.ts +62 -8
  406. package/src/resources/extensions/gsd/auto-start.ts +44 -7
  407. package/src/resources/extensions/gsd/auto-worktree.ts +51 -3
  408. package/src/resources/extensions/gsd/auto.ts +118 -18
  409. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +6 -2
  410. package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +56 -6
  411. package/src/resources/extensions/gsd/bootstrap/register-extension.ts +2 -1
  412. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +36 -3
  413. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +69 -16
  414. package/src/resources/extensions/gsd/closeout-wizard.ts +11 -2
  415. package/src/resources/extensions/gsd/commands/handlers/core.ts +27 -8
  416. package/src/resources/extensions/gsd/commands/handlers/ops.ts +5 -2
  417. package/src/resources/extensions/gsd/commands-mcp-status.ts +2 -2
  418. package/src/resources/extensions/gsd/commands-prefs-wizard.ts +7 -0
  419. package/src/resources/extensions/gsd/commands-workflow-templates.ts +11 -4
  420. package/src/resources/extensions/gsd/config-overlay.ts +22 -9
  421. package/src/resources/extensions/gsd/db/engine.ts +26 -6
  422. package/src/resources/extensions/gsd/db/queries.ts +29 -0
  423. package/src/resources/extensions/gsd/db/writers/reconcile.ts +24 -1
  424. package/src/resources/extensions/gsd/db-migration-backup.ts +56 -7
  425. package/src/resources/extensions/gsd/db-transaction.ts +37 -20
  426. package/src/resources/extensions/gsd/db-writer.ts +11 -19
  427. package/src/resources/extensions/gsd/doctor-environment.ts +267 -142
  428. package/src/resources/extensions/gsd/doctor-git-checks.ts +4 -1
  429. package/src/resources/extensions/gsd/doctor-providers.ts +1 -1
  430. package/src/resources/extensions/gsd/doctor-runtime-checks.ts +10 -10
  431. package/src/resources/extensions/gsd/gsd-db.ts +15 -19
  432. package/src/resources/extensions/gsd/guided-flow.ts +128 -2
  433. package/src/resources/extensions/gsd/health-widget.ts +91 -27
  434. package/src/resources/extensions/gsd/mcp-bridge.ts +39 -0
  435. package/src/resources/extensions/gsd/memory-relations.ts +1 -1
  436. package/src/resources/extensions/gsd/milestone-settlement.ts +2 -2
  437. package/src/resources/extensions/gsd/notifications.ts +13 -6
  438. package/src/resources/extensions/gsd/preferences-models.ts +26 -8
  439. package/src/resources/extensions/gsd/preferences.ts +111 -5
  440. package/src/resources/extensions/gsd/prompts/complete-milestone.md +8 -2
  441. package/src/resources/extensions/gsd/prompts/complete-slice.md +6 -2
  442. package/src/resources/extensions/gsd/prompts/execute-task.md +7 -2
  443. package/src/resources/extensions/gsd/prompts/quick-task.md +1 -1
  444. package/src/resources/extensions/gsd/prompts/reactive-execute.md +2 -2
  445. package/src/resources/extensions/gsd/prompts/run-uat.md +7 -1
  446. package/src/resources/extensions/gsd/prompts/triage-captures.md +1 -1
  447. package/src/resources/extensions/gsd/prompts/workflow-start.md +2 -1
  448. package/src/resources/extensions/gsd/provider-error-guidance.ts +32 -0
  449. package/src/resources/extensions/gsd/session-lock.ts +8 -7
  450. package/src/resources/extensions/gsd/skill-activation.ts +3 -6
  451. package/src/resources/extensions/gsd/state-reconciliation/drift/artifact-db.ts +23 -10
  452. package/src/resources/extensions/gsd/state.ts +7 -1
  453. package/src/resources/extensions/gsd/tests/auto-abort-pause-regression.test.ts +1 -1
  454. package/src/resources/extensions/gsd/tests/auto-blocked-remediation-message.test.ts +1 -1
  455. package/src/resources/extensions/gsd/tests/auto-closeout-messaging.test.ts +71 -0
  456. package/src/resources/extensions/gsd/tests/auto-dashboard.test.ts +68 -116
  457. package/src/resources/extensions/gsd/tests/auto-direct-dispatch-parse.test.ts +33 -0
  458. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +206 -22
  459. package/src/resources/extensions/gsd/tests/auto-model-selection-tool-poisoning.test.ts +7 -2
  460. package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +16 -1
  461. package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +89 -22
  462. package/src/resources/extensions/gsd/tests/auto-pause-double-entry-guard.test.ts +1 -1
  463. package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +97 -4
  464. package/src/resources/extensions/gsd/tests/auto-phases-lifecycle.test.ts +2 -1
  465. package/src/resources/extensions/gsd/tests/auto-start-orphan-bootstrap.test.ts +236 -0
  466. package/src/resources/extensions/gsd/tests/auto-unit-closeout.test.ts +169 -1
  467. package/src/resources/extensions/gsd/tests/auto-verification.test.ts +36 -0
  468. package/src/resources/extensions/gsd/tests/blocker-placeholder-logs.test.ts +218 -0
  469. package/src/resources/extensions/gsd/tests/complete-milestone-prompt-rendering.test.ts +6 -2
  470. package/src/resources/extensions/gsd/tests/complete-task.test.ts +141 -5
  471. package/src/resources/extensions/gsd/tests/core-overlay-fallback.test.ts +1 -0
  472. package/src/resources/extensions/gsd/tests/db-engine-logs.test.ts +207 -0
  473. package/src/resources/extensions/gsd/tests/db-migration-backup.test.ts +68 -19
  474. package/src/resources/extensions/gsd/tests/db-transaction.test.ts +59 -0
  475. package/src/resources/extensions/gsd/tests/db-writer.test.ts +15 -4
  476. package/src/resources/extensions/gsd/tests/deep-project-auto-loop.test.ts +2 -1
  477. package/src/resources/extensions/gsd/tests/derive-state-helpers.test.ts +62 -0
  478. package/src/resources/extensions/gsd/tests/discuss-routing-fixes.test.ts +12 -2
  479. package/src/resources/extensions/gsd/tests/dispatch-db-degradation-logs.test.ts +98 -0
  480. package/src/resources/extensions/gsd/tests/dispatch-history.test.ts +55 -0
  481. package/src/resources/extensions/gsd/tests/dispatch-logs.test.ts +103 -0
  482. package/src/resources/extensions/gsd/tests/dispatch-reactive-logs.test.ts +98 -0
  483. package/src/resources/extensions/gsd/tests/dist-redirect.mjs +8 -0
  484. package/src/resources/extensions/gsd/tests/doctor-providers.test.ts +6 -4
  485. package/src/resources/extensions/gsd/tests/engine-interfaces-contract.test.ts +117 -91
  486. package/src/resources/extensions/gsd/tests/ensure-db-open.test.ts +113 -0
  487. package/src/resources/extensions/gsd/tests/flat-rate-routing-guard.test.ts +2 -1
  488. package/src/resources/extensions/gsd/tests/gsd-command-home.test.ts +40 -7
  489. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +19 -0
  490. package/src/resources/extensions/gsd/tests/guided-dispatch-root.test.ts +16 -0
  491. package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +75 -0
  492. package/src/resources/extensions/gsd/tests/integration/auto-worktree.test.ts +15 -0
  493. package/src/resources/extensions/gsd/tests/integration/doctor-environment-async.test.ts +104 -0
  494. package/src/resources/extensions/gsd/tests/integration/run-uat.test.ts +18 -0
  495. package/src/resources/extensions/gsd/tests/interactive-routing-bypass.test.ts +1 -0
  496. package/src/resources/extensions/gsd/tests/journal-integration.test.ts +47 -16
  497. package/src/resources/extensions/gsd/tests/loop.test.ts +60 -0
  498. package/src/resources/extensions/gsd/tests/mcp-readiness-preflight.test.ts +205 -0
  499. package/src/resources/extensions/gsd/tests/mcp-status.test.ts +6 -5
  500. package/src/resources/extensions/gsd/tests/milestone-merge-stash-restore.test.ts +1 -1
  501. package/src/resources/extensions/gsd/tests/milestone-report-path.test.ts +1 -1
  502. package/src/resources/extensions/gsd/tests/milestone-settlement.test.ts +92 -0
  503. package/src/resources/extensions/gsd/tests/milestone-transition-state-rebuild.test.ts +1 -1
  504. package/src/resources/extensions/gsd/tests/model-router.test.ts +139 -0
  505. package/src/resources/extensions/gsd/tests/notifications.test.ts +64 -9
  506. package/src/resources/extensions/gsd/tests/oauth-api-model-routing.test.ts +13 -1
  507. package/src/resources/extensions/gsd/tests/orchestrator-legacy-parity.test.ts +1 -1
  508. package/src/resources/extensions/gsd/tests/orchestrator-logs.test.ts +335 -0
  509. package/src/resources/extensions/gsd/tests/parallel-skill-prompt-integration.test.ts +2 -2
  510. package/src/resources/extensions/gsd/tests/parsers-legacy-importers.test.ts +5 -0
  511. package/src/resources/extensions/gsd/tests/phases-merge-error-stops-auto.test.ts +1 -1
  512. package/src/resources/extensions/gsd/tests/phases-terminal-complete-idempotent.test.ts +1 -1
  513. package/src/resources/extensions/gsd/tests/plan-gate-failed-doctor-heal-hint.test.ts +3 -3
  514. package/src/resources/extensions/gsd/tests/prefs-missing-models-crash.test.ts +35 -4
  515. package/src/resources/extensions/gsd/tests/progress-strip-test-helpers.ts +79 -0
  516. package/src/resources/extensions/gsd/tests/prompt-budget-enforcement.test.ts +2 -0
  517. package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +11 -2
  518. package/src/resources/extensions/gsd/tests/provider-error-guidance.test.ts +15 -0
  519. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +2 -4
  520. package/src/resources/extensions/gsd/tests/reconcile-logs.test.ts +244 -0
  521. package/src/resources/extensions/gsd/tests/recovery-finalize-logs.test.ts +119 -0
  522. package/src/resources/extensions/gsd/tests/recovery-verify-logs.test.ts +428 -0
  523. package/src/resources/extensions/gsd/tests/register-extension-guard.test.ts +25 -0
  524. package/src/resources/extensions/gsd/tests/remote-notification-from-desktop.test.ts +31 -81
  525. package/src/resources/extensions/gsd/tests/resume-missing-worktree-warning.test.ts +5 -5
  526. package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +7 -1
  527. package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +68 -0
  528. package/src/resources/extensions/gsd/tests/show-config-command.test.ts +3 -0
  529. package/src/resources/extensions/gsd/tests/single-writer-invariant.test.ts +170 -48
  530. package/src/resources/extensions/gsd/tests/skill-activation.test.ts +20 -17
  531. package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +7 -3
  532. package/src/resources/extensions/gsd/tests/state-reconciliation-drift.test.ts +17 -1
  533. package/src/resources/extensions/gsd/tests/stop-auto-race-null-unit.test.ts +1 -1
  534. package/src/resources/extensions/gsd/tests/teardown-chdir-failure-clears-registry.test.ts +17 -0
  535. package/src/resources/extensions/gsd/tests/thinking-level-resolution.test.ts +1 -1
  536. package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +4 -2
  537. package/src/resources/extensions/gsd/tests/tool-surface-readiness.test.ts +184 -10
  538. package/src/resources/extensions/gsd/tests/tui-header-lifecycle.test.ts +40 -86
  539. package/src/resources/extensions/gsd/tests/tui-render-kit.test.ts +44 -6
  540. package/src/resources/extensions/gsd/tests/uok-audit.test.ts +194 -0
  541. package/src/resources/extensions/gsd/tests/uok-plan-v2-wiring.test.ts +1 -1
  542. package/src/resources/extensions/gsd/tests/workflow-mcp-readiness-cache.test.ts +119 -0
  543. package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +65 -2
  544. package/src/resources/extensions/gsd/tests/workflow-phase-contract-matrix.test.ts +332 -0
  545. package/src/resources/extensions/gsd/tests/workflow-templates.test.ts +92 -0
  546. package/src/resources/extensions/gsd/tests/worktree-health-dispatch.test.ts +1 -1
  547. package/src/resources/extensions/gsd/tests/worktree-manager.test.ts +36 -0
  548. package/src/resources/extensions/gsd/tests/worktree-project-root-degrade.test.ts +1 -1
  549. package/src/resources/extensions/gsd/tests/worktree-safety-phase.test.ts +100 -0
  550. package/src/resources/extensions/gsd/tests/worktree-safety.test.ts +72 -0
  551. package/src/resources/extensions/gsd/tests/worktree-teardown-safety.test.ts +22 -0
  552. package/src/resources/extensions/gsd/tests/worktree-write-gate.test.ts +75 -3
  553. package/src/resources/extensions/gsd/tests/worktree.test.ts +18 -0
  554. package/src/resources/extensions/gsd/tool-surface-readiness.ts +126 -19
  555. package/src/resources/extensions/gsd/tools/complete-task.ts +87 -0
  556. package/src/resources/extensions/gsd/tools/exec-tool.ts +2 -118
  557. package/src/resources/extensions/gsd/tui/render-kit.ts +56 -13
  558. package/src/resources/extensions/gsd/unit-context-composer.ts +1 -1
  559. package/src/resources/extensions/gsd/unit-registry.ts +34 -4
  560. package/src/resources/extensions/gsd/workflow-logger.ts +5 -0
  561. package/src/resources/extensions/gsd/workflow-mcp-auto-prep.ts +2 -0
  562. package/src/resources/extensions/gsd/workflow-mcp-readiness-cache.ts +150 -0
  563. package/src/resources/extensions/gsd/worktree-manager.ts +97 -2
  564. package/src/resources/extensions/gsd/worktree-safety.ts +41 -39
  565. package/src/resources/extensions/gsd/worktree-shell-guard.ts +123 -0
  566. package/src/resources/extensions/gsd/worktree.ts +7 -1
  567. package/src/resources/extensions/mcp-client/manager.ts +7 -1
  568. package/src/resources/extensions/search-the-web/index.ts +45 -9
  569. package/src/resources/extensions/search-the-web/native-search.ts +16 -4
  570. package/src/resources/extensions/shared/gsd-browser-cli.ts +41 -2
  571. package/src/resources/extensions/subagent/index.ts +20 -15
  572. package/src/resources/extensions/subagent/tests/worktree-cwd.test.ts +57 -0
  573. package/src/resources/extensions/subagent/worktree-cwd.ts +35 -0
  574. package/src/resources/skills/create-skill/SKILL.md +3 -0
  575. package/src/resources/skills/create-skill/references/skill-structure.md +1 -0
  576. package/dist/resources/skills/gsd-browser/SKILL.md +0 -41
  577. package/src/resources/skills/gsd-browser/SKILL.md +0 -41
  578. /package/dist/web/standalone/.next/static/{T-LTxEw5wir5Lm5T3qEVd → Wn9u2NYq0cyUigB_3Z0_N}/_buildManifest.js +0 -0
  579. /package/dist/web/standalone/.next/static/{T-LTxEw5wir5Lm5T3qEVd → Wn9u2NYq0cyUigB_3Z0_N}/_ssgManifest.js +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"assistant-message.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/assistant-message.ts"],"names":[],"mappings":"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","sourcesContent":["// Project/App: gsd-pi\n// File Purpose: Assistant message rail renderer for interactive terminal sessions.\nimport type { AssistantMessage } from \"@gsd/pi-ai\";\nimport { Container, Markdown, type MarkdownTheme, Spacer, Text } from \"@gsd/pi-tui\";\nimport { getMarkdownTheme, theme } from \"@gsd/pi-coding-agent/theme/theme.js\";\nimport { type TimestampFormat } from \"./timestamp.js\";\nimport { formatTimestamp } from \"./timestamp.js\";\nimport { RenderCache } from \"./render-cache.js\";\nimport { renderAssistantRail } from \"./transcript-design.js\";\nimport { asServerToolUse, asWebSearchResult, isToolContentBlock } from \"../gsd-content-blocks.js\";\n\nexport interface ContentRange {\n\tstartIndex: number;\n\tendIndex: number;\n}\n\n/**\n * Component that renders a complete assistant message, or a sub-range of its content[].\n * When `range` is provided, only content[startIndex..endIndex] (inclusive) is rendered.\n * Non-text/thinking blocks within the range are silently skipped.\n */\nexport class AssistantMessageComponent extends Container {\n\tprivate contentContainer: Container;\n\tprivate hideThinkingBlock: boolean;\n\tprivate markdownTheme: MarkdownTheme;\n\tprivate lastMessage?: AssistantMessage;\n\tprivate timestampFormat: TimestampFormat;\n\tprivate range?: ContentRange;\n\tprivate showMetadata: boolean;\n\tprivate connectedToUser: boolean;\n\tprivate continuesToUser = false;\n\tprivate renderCache = new RenderCache();\n\tprivate renderVersion = 0;\n\n\tconstructor(\n\t\tmessage?: AssistantMessage,\n\t\thideThinkingBlock = true,\n\t\tmarkdownTheme: MarkdownTheme = getMarkdownTheme(),\n\t\ttimestampFormat: TimestampFormat = \"date-time-iso\",\n\t\trange?: ContentRange,\n\t\tconnectedToUser = false,\n\t) {\n\t\tsuper();\n\n\t\tthis.hideThinkingBlock = hideThinkingBlock;\n\t\tthis.markdownTheme = markdownTheme;\n\t\tthis.timestampFormat = timestampFormat;\n\t\tthis.range = range;\n\t\tthis.connectedToUser = connectedToUser;\n\t\t// No range = legacy full-message rendering; show metadata by default.\n\t\t// Ranged (interleaved) instances start with metadata hidden; chat-controller\n\t\t// calls setShowMetadata(true) on the last segment at message_end.\n\t\tthis.showMetadata = !range;\n\n\t\t// Container for text/thinking content\n\t\tthis.contentContainer = new Container();\n\t\tthis.addChild(this.contentContainer);\n\n\t\tif (message) {\n\t\t\tthis.updateContent(message);\n\t\t}\n\t}\n\n\tsetRange(range: ContentRange | undefined): void {\n\t\tthis.range = range;\n\t\tif (this.lastMessage) {\n\t\t\tthis.updateContent(this.lastMessage);\n\t\t}\n\t}\n\n\tsetShowMetadata(show: boolean): void {\n\t\tthis.showMetadata = show;\n\t\tif (this.lastMessage) {\n\t\t\tthis.updateContent(this.lastMessage);\n\t\t}\n\t}\n\n\toverride invalidate(): void {\n\t\tsuper.invalidate();\n\t\tthis.clearRenderCache();\n\t\tif (this.lastMessage) {\n\t\t\tthis.updateContent(this.lastMessage);\n\t\t}\n\t}\n\n\tsetHideThinkingBlock(hide: boolean): void {\n\t\tif (this.hideThinkingBlock === hide) return;\n\t\tthis.hideThinkingBlock = hide;\n\t\tif (this.lastMessage) {\n\t\t\tthis.updateContent(this.lastMessage);\n\t\t} else {\n\t\t\tthis.clearRenderCache();\n\t\t}\n\t}\n\n\tsetContinuesToUser(value: boolean): void {\n\t\tif (this.continuesToUser === value) return;\n\t\tthis.continuesToUser = value;\n\t\tthis.clearRenderCache();\n\t}\n\n\tsetConnectedToUser(value: boolean): void {\n\t\tif (this.connectedToUser === value) return;\n\t\tthis.connectedToUser = value;\n\t\tthis.clearRenderCache();\n\t}\n\n\tupdateContent(message: AssistantMessage): void {\n\t\tthis.lastMessage = message;\n\t\tthis.clearRenderCache();\n\n\t\t// Clear content container\n\t\tthis.contentContainer.clear();\n\n\t\tconst start = this.range?.startIndex ?? 0;\n\t\tconst end = this.range?.endIndex ?? message.content.length - 1;\n\t\tconst slice = message.content.slice(start, end + 1);\n\n\t\tconst hasVisibleContent = slice.some((content) => {\n\t\t\tif (content.type === \"text\") return content.text.trim().length > 0;\n\t\t\treturn !this.hideThinkingBlock && content.type === \"thinking\" && content.thinking.trim().length > 0;\n\t\t});\n\t\tconst hasTextContent = message.content.some((c) => c.type === \"text\" && c.text.trim().length > 0);\n\t\tconst hasToolContent = message.content.some((c) => isToolContentBlock(c));\n\t\t// Claude Code often emits long reasoning blocks ahead of user-visible text/tool\n\t\t// output in the same lifecycle. Keep chat output visible without requiring a\n\t\t// manual thinking toggle every turn.\n\t\tconst shouldCapThinking = hasTextContent || hasToolContent || message.provider === \"claude-code\";\n\n\t\t// Render content in order; non-text/thinking blocks are silently skipped\n\t\tfor (let i = 0; i < slice.length; i++) {\n\t\t\tconst content = slice[i];\n\t\t\tif (content.type === \"text\" && content.text.trim()) {\n\t\t\t\t// Assistant text messages with no background - trim the text\n\t\t\t\t// Set paddingY=0 to avoid extra spacing before tool executions\n\t\t\t\tthis.contentContainer.addChild(new Markdown(content.text.trim(), 1, 0, this.markdownTheme));\n\t\t\t} else if (content.type === \"thinking\" && content.thinking.trim()) {\n\t\t\t\tif (this.hideThinkingBlock) continue;\n\t\t\t\t// Add spacing only when another visible assistant content block follows.\n\t\t\t\t// This avoids a superfluous blank line before separately-rendered tool execution blocks.\n\t\t\t\tconst hasVisibleContentAfter = slice\n\t\t\t\t\t.slice(i + 1)\n\t\t\t\t\t.some((c) => (c.type === \"text\" && c.text.trim()) || (c.type === \"thinking\" && c.thinking.trim()));\n\n\t\t\t\tconst thinkingMarkdown = new Markdown(content.thinking.trim(), 1, 0, this.markdownTheme, {\n\t\t\t\t\tcolor: (text: string) => theme.fg(\"thinkingText\", text),\n\t\t\t\t\titalic: true,\n\t\t\t\t});\n\t\t\t\t// Keep visible chat output readable when thinking traces are long.\n\t\t\t\t// Tool-bearing turns can stream text in a later assistant message.\n\t\t\t\tif (shouldCapThinking) {\n\t\t\t\t\tthinkingMarkdown.maxLines = 8;\n\t\t\t\t}\n\t\t\t\tthis.contentContainer.addChild(thinkingMarkdown);\n\t\t\t\tif (hasVisibleContentAfter) {\n\t\t\t\t\tthis.contentContainer.addChild(new Spacer(1));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Metadata (errors, timestamp): gated on showMetadata so ranged instances stay clean\n\t\t// until chat-controller explicitly enables it on the last segment at message_end.\n\t\tif (this.showMetadata) {\n\t\t\t// Check if aborted - show after partial content\n\t\t\t// But only if there are no tool calls (tool execution components will show the error)\n\t\t\tconst hasToolCalls = message.content.some((c) => c.type === \"toolCall\");\n\t\t\tif (!hasToolCalls) {\n\t\t\t\tif (message.stopReason === \"aborted\") {\n\t\t\t\t\tconst abortMessage =\n\t\t\t\t\t\tmessage.errorMessage && message.errorMessage !== \"Request was aborted\"\n\t\t\t\t\t\t\t? message.errorMessage\n\t\t\t\t\t\t\t: \"Operation aborted\";\n\t\t\t\t\tif (hasVisibleContent) {\n\t\t\t\t\t\tthis.contentContainer.addChild(new Spacer(1));\n\t\t\t\t\t}\n\t\t\t\t\tthis.contentContainer.addChild(new Text(theme.fg(\"error\", abortMessage), 1, 0));\n\t\t\t\t} else if (message.stopReason === \"error\") {\n\t\t\t\t\tconst errorMsg = message.errorMessage || \"Unknown error\";\n\t\t\t\t\tthis.contentContainer.addChild(new Spacer(1));\n\t\t\t\t\tthis.contentContainer.addChild(new Text(theme.fg(\"error\", `Error: ${errorMsg}`), 1, 0));\n\t\t\t\t}\n\t\t\t}\n\n\t\t}\n\t}\n\n\toverride render(width: number): string[] {\n\t\tconst cached = this.renderCache.get(\n\t\t\t`${width}:${this.renderVersion}:${this.connectedToUser ? 1 : 0}:${this.continuesToUser ? 1 : 0}`,\n\t\t);\n\t\tif (cached) return cached;\n\n\t\tconst frameWidth = Math.max(20, width);\n\t\tconst contentWidth = Math.max(1, frameWidth - 3);\n\t\tconst lines = super.render(contentWidth);\n\t\tif (lines.length === 0) return [];\n\t\tconst metaParts = [];\n\t\tif (this.lastMessage?.model) metaParts.push(this.lastMessage.model);\n\t\tif (this.showMetadata && this.lastMessage?.timestamp != null) {\n\t\t\tmetaParts.push(formatTimestamp(this.lastMessage.timestamp, this.timestampFormat));\n\t\t}\n\t\tconst rendered = renderAssistantRail(lines, frameWidth, {\n\t\t\tlabel: \"GSD\",\n\t\t\tmeta: metaParts.length > 0 ? `· ${metaParts.join(\" · \")}` : undefined,\n\t\t\tconnected: this.connectedToUser,\n\t\t\tcontinuesToUser: this.continuesToUser,\n\t\t});\n\t\treturn this.renderCache.set(\n\t\t\t`${width}:${this.renderVersion}:${this.connectedToUser ? 1 : 0}:${this.continuesToUser ? 1 : 0}`,\n\t\t\tthis.connectedToUser || rendered.length === 0 ? rendered : [\"\", ...rendered],\n\t\t);\n\t}\n\n\tprivate clearRenderCache(): void {\n\t\tthis.renderVersion++;\n\t\tthis.renderCache.clear();\n\t}\n}\n"]}
1
+ {"version":3,"file":"assistant-message.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/assistant-message.ts"],"names":[],"mappings":"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","sourcesContent":["// Project/App: gsd-pi\n// File Purpose: Assistant message rail renderer for interactive terminal sessions.\nimport type { AssistantMessage } from \"@gsd/pi-ai\";\nimport { Container, Markdown, type MarkdownTheme, Spacer, Text } from \"@gsd/pi-tui\";\nimport { getMarkdownTheme, theme } from \"@gsd/pi-coding-agent/theme/theme.js\";\nimport { type TimestampFormat } from \"./timestamp.js\";\nimport { formatTimestamp } from \"./timestamp.js\";\nimport { RenderCache } from \"./render-cache.js\";\nimport { renderPlainSpeakerMessage } from \"./transcript-design.js\";\nimport { asServerToolUse, asWebSearchResult, isToolContentBlock } from \"../gsd-content-blocks.js\";\n\nexport interface ContentRange {\n\tstartIndex: number;\n\tendIndex: number;\n}\n\n/**\n * Component that renders a complete assistant message, or a sub-range of its content[].\n * When `range` is provided, only content[startIndex..endIndex] (inclusive) is rendered.\n * Non-text/thinking blocks within the range are silently skipped.\n */\nexport class AssistantMessageComponent extends Container {\n\tprivate contentContainer: Container;\n\tprivate hideThinkingBlock: boolean;\n\tprivate markdownTheme: MarkdownTheme;\n\tprivate lastMessage?: AssistantMessage;\n\tprivate timestampFormat: TimestampFormat;\n\tprivate range?: ContentRange;\n\tprivate showMetadata: boolean;\n\tprivate renderCache = new RenderCache();\n\tprivate renderVersion = 0;\n\n\tconstructor(\n\t\tmessage?: AssistantMessage,\n\t\thideThinkingBlock = true,\n\t\tmarkdownTheme: MarkdownTheme = getMarkdownTheme(),\n\t\ttimestampFormat: TimestampFormat = \"date-time-iso\",\n\t\trange?: ContentRange,\n\t) {\n\t\tsuper();\n\n\t\tthis.hideThinkingBlock = hideThinkingBlock;\n\t\tthis.markdownTheme = markdownTheme;\n\t\tthis.timestampFormat = timestampFormat;\n\t\tthis.range = range;\n\t\t// No range = legacy full-message rendering; show metadata by default.\n\t\t// Ranged (interleaved) instances start with metadata hidden; chat-controller\n\t\t// calls setShowMetadata(true) on the last segment at message_end.\n\t\tthis.showMetadata = !range;\n\n\t\t// Container for text/thinking content\n\t\tthis.contentContainer = new Container();\n\t\tthis.addChild(this.contentContainer);\n\n\t\tif (message) {\n\t\t\tthis.updateContent(message);\n\t\t}\n\t}\n\n\tsetRange(range: ContentRange | undefined): void {\n\t\tthis.range = range;\n\t\tif (this.lastMessage) {\n\t\t\tthis.updateContent(this.lastMessage);\n\t\t}\n\t}\n\n\tsetShowMetadata(show: boolean): void {\n\t\tthis.showMetadata = show;\n\t\tif (this.lastMessage) {\n\t\t\tthis.updateContent(this.lastMessage);\n\t\t}\n\t}\n\n\toverride invalidate(): void {\n\t\tsuper.invalidate();\n\t\tthis.clearRenderCache();\n\t\tif (this.lastMessage) {\n\t\t\tthis.updateContent(this.lastMessage);\n\t\t}\n\t}\n\n\tsetHideThinkingBlock(hide: boolean): void {\n\t\tif (this.hideThinkingBlock === hide) return;\n\t\tthis.hideThinkingBlock = hide;\n\t\tif (this.lastMessage) {\n\t\t\tthis.updateContent(this.lastMessage);\n\t\t} else {\n\t\t\tthis.clearRenderCache();\n\t\t}\n\t}\n\n\t/** @deprecated Plain transcript has no connected rails. */\n\tsetContinuesToUser(_value: boolean): void {}\n\n\t/** @deprecated Plain transcript has no connected rails. */\n\tsetConnectedToUser(_value: boolean): void {}\n\n\tupdateContent(message: AssistantMessage): void {\n\t\tthis.lastMessage = message;\n\t\tthis.clearRenderCache();\n\n\t\t// Clear content container\n\t\tthis.contentContainer.clear();\n\n\t\tconst start = this.range?.startIndex ?? 0;\n\t\tconst end = this.range?.endIndex ?? message.content.length - 1;\n\t\tconst slice = message.content.slice(start, end + 1);\n\n\t\tconst hasVisibleContent = slice.some((content) => {\n\t\t\tif (content.type === \"text\") return content.text.trim().length > 0;\n\t\t\treturn !this.hideThinkingBlock && content.type === \"thinking\" && content.thinking.trim().length > 0;\n\t\t});\n\t\tconst hasTextContent = message.content.some((c) => c.type === \"text\" && c.text.trim().length > 0);\n\t\tconst hasToolContent = message.content.some((c) => isToolContentBlock(c));\n\t\t// Claude Code often emits long reasoning blocks ahead of user-visible text/tool\n\t\t// output in the same lifecycle. Keep chat output visible without requiring a\n\t\t// manual thinking toggle every turn.\n\t\tconst shouldCapThinking = hasTextContent || hasToolContent || message.provider === \"claude-code\";\n\n\t\t// Render content in order; non-text/thinking blocks are silently skipped\n\t\tfor (let i = 0; i < slice.length; i++) {\n\t\t\tconst content = slice[i];\n\t\t\tif (content.type === \"text\" && content.text.trim()) {\n\t\t\t\t// Assistant text messages with no background - trim the text\n\t\t\t\t// Set paddingY=0 to avoid extra spacing before tool executions\n\t\t\t\tthis.contentContainer.addChild(new Markdown(content.text.trim(), 1, 0, this.markdownTheme));\n\t\t\t} else if (content.type === \"thinking\" && content.thinking.trim()) {\n\t\t\t\tif (this.hideThinkingBlock) continue;\n\t\t\t\t// Add spacing only when another visible assistant content block follows.\n\t\t\t\t// This avoids a superfluous blank line before separately-rendered tool execution blocks.\n\t\t\t\tconst hasVisibleContentAfter = slice\n\t\t\t\t\t.slice(i + 1)\n\t\t\t\t\t.some((c) => (c.type === \"text\" && c.text.trim()) || (c.type === \"thinking\" && c.thinking.trim()));\n\n\t\t\t\tconst thinkingMarkdown = new Markdown(content.thinking.trim(), 1, 0, this.markdownTheme, {\n\t\t\t\t\tcolor: (text: string) => theme.fg(\"thinkingText\", text),\n\t\t\t\t\titalic: true,\n\t\t\t\t});\n\t\t\t\t// Keep visible chat output readable when thinking traces are long.\n\t\t\t\t// Tool-bearing turns can stream text in a later assistant message.\n\t\t\t\tif (shouldCapThinking) {\n\t\t\t\t\tthinkingMarkdown.maxLines = 8;\n\t\t\t\t}\n\t\t\t\tthis.contentContainer.addChild(thinkingMarkdown);\n\t\t\t\tif (hasVisibleContentAfter) {\n\t\t\t\t\tthis.contentContainer.addChild(new Spacer(1));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Metadata (errors, timestamp): gated on showMetadata so ranged instances stay clean\n\t\t// until chat-controller explicitly enables it on the last segment at message_end.\n\t\tif (this.showMetadata) {\n\t\t\t// Check if aborted - show after partial content\n\t\t\t// But only if there are no tool calls (tool execution components will show the error)\n\t\t\tconst hasToolCalls = message.content.some((c) => c.type === \"toolCall\");\n\t\t\tif (!hasToolCalls) {\n\t\t\t\tif (message.stopReason === \"aborted\") {\n\t\t\t\t\tconst abortMessage =\n\t\t\t\t\t\tmessage.errorMessage && message.errorMessage !== \"Request was aborted\"\n\t\t\t\t\t\t\t? message.errorMessage\n\t\t\t\t\t\t\t: \"Operation aborted\";\n\t\t\t\t\tif (hasVisibleContent) {\n\t\t\t\t\t\tthis.contentContainer.addChild(new Spacer(1));\n\t\t\t\t\t}\n\t\t\t\t\tthis.contentContainer.addChild(new Text(theme.fg(\"error\", abortMessage), 1, 0));\n\t\t\t\t} else if (message.stopReason === \"error\") {\n\t\t\t\t\tconst errorMsg = message.errorMessage || \"Unknown error\";\n\t\t\t\t\tthis.contentContainer.addChild(new Spacer(1));\n\t\t\t\t\tthis.contentContainer.addChild(new Text(theme.fg(\"error\", `Error: ${errorMsg}`), 1, 0));\n\t\t\t\t}\n\t\t\t}\n\n\t\t}\n\t}\n\n\toverride render(width: number): string[] {\n\t\tconst cached = this.renderCache.get(`${width}:${this.renderVersion}`);\n\t\tif (cached) return cached;\n\n\t\tconst frameWidth = Math.max(20, width);\n\t\tconst lines = super.render(frameWidth);\n\t\tif (lines.length === 0) return [];\n\t\tconst metaParts = [];\n\t\tif (this.lastMessage?.model) metaParts.push(this.lastMessage.model);\n\t\tif (this.showMetadata && this.lastMessage?.timestamp != null) {\n\t\t\tmetaParts.push(formatTimestamp(this.lastMessage.timestamp, this.timestampFormat));\n\t\t}\n\t\tconst rendered = renderPlainSpeakerMessage(lines, frameWidth, {\n\t\t\tlabel: \"GSD\",\n\t\t\tmeta: metaParts.length > 0 ? metaParts.join(\" · \") : undefined,\n\t\t\ttone: \"assistant\",\n\t\t});\n\t\treturn this.renderCache.set(`${width}:${this.renderVersion}`, rendered);\n\t}\n\n\tprivate clearRenderCache(): void {\n\t\tthis.renderVersion++;\n\t\tthis.renderCache.clear();\n\t}\n}\n"]}
@@ -6,7 +6,7 @@ import { DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES, truncateTail, } from "@gsd/pi-cod
6
6
  import { theme } from "@gsd/pi-coding-agent/theme/theme.js";
7
7
  import { DynamicBorder } from "./dynamic-border.js";
8
8
  import { editorKey, keyHint } from "./keybinding-hints.js";
9
- import { renderCommandCard, renderTranscriptCard } from "./transcript-design.js";
9
+ import { renderCommandCard, renderPlainToolMessage } from "./transcript-design.js";
10
10
  import { truncateToVisualLines } from "./visual-truncate.js";
11
11
  // Preview line limit when not expanded (matches tool execution behavior)
12
12
  const PREVIEW_LINES = 20;
@@ -120,12 +120,12 @@ export class BashExecutionComponent extends Container {
120
120
  ...(hidden > 0 ? [theme.fg("muted", `... ${hidden} earlier lines`)] : []),
121
121
  ...truncationWarning,
122
122
  ];
123
- return renderTranscriptCard(body, frameWidth, {
123
+ const rightParts = [elapsedStatus];
124
+ rightParts.push(this.expanded ? "ctrl+o collapse" : "ctrl+o expand");
125
+ return renderPlainToolMessage(body, frameWidth, {
124
126
  title: "command",
125
- right: elapsedStatus,
127
+ meta: rightParts.join(" · "),
126
128
  tone,
127
- footerLeft: this.expanded ? "output expanded" : "output preview",
128
- footerRight: this.expanded ? "ctrl+o collapse" : "ctrl+o expand",
129
129
  });
130
130
  }
131
131
  updateDisplay() {
@@ -1 +1 @@
1
- {"version":3,"file":"bash-execution.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/bash-execution.ts"],"names":[],"mappings":"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","sourcesContent":["// Project/App: gsd-pi\n// File Purpose: Interactive terminal bash execution renderer with streaming output and recommended command cards.\n\nimport { Container, Loader, Spacer, Text, type TUI } from \"@gsd/pi-tui\";\nimport stripAnsi from \"strip-ansi\";\nimport {\n\tDEFAULT_MAX_BYTES,\n\tDEFAULT_MAX_LINES,\n\ttype TruncationResult,\n\ttruncateTail,\n} from \"@gsd/pi-coding-agent/core/tools/truncate.js\";\nimport { theme } from \"@gsd/pi-coding-agent/theme/theme.js\";\nimport { DynamicBorder } from \"./dynamic-border.js\";\nimport { editorKey, keyHint } from \"./keybinding-hints.js\";\nimport { renderCommandCard, renderTranscriptCard, type StatusTone } from \"./transcript-design.js\";\nimport { truncateToVisualLines } from \"./visual-truncate.js\";\n\n// Preview line limit when not expanded (matches tool execution behavior)\nconst PREVIEW_LINES = 20;\n\nexport class BashExecutionComponent extends Container {\n\tprivate command: string;\n\tprivate outputLines: string[] = [];\n\tprivate status: \"running\" | \"complete\" | \"cancelled\" | \"error\" = \"running\";\n\tprivate exitCode: number | undefined = undefined;\n\tprivate loader: Loader;\n\tprivate truncationResult?: TruncationResult;\n\tprivate fullOutputPath?: string;\n\tprivate expanded = false;\n\tprivate contentContainer: Container;\n\tprivate ui: TUI;\n\tprivate _borderColorKey: \"dim\" | \"bashMode\";\n\n\tconstructor(command: string, ui: TUI, excludeFromContext = false) {\n\t\tsuper();\n\t\tthis.command = command;\n\t\tthis.ui = ui;\n\n\t\t// Use dim border for excluded-from-context commands (!! prefix)\n\t\tconst colorKey = excludeFromContext ? \"dim\" : \"bashMode\";\n\t\tthis._borderColorKey = colorKey;\n\t\tconst borderColor = (str: string) => theme.fg(colorKey, str);\n\n\t\t// Add spacer\n\t\tthis.addChild(new Spacer(1));\n\n\t\t// Top border\n\t\tthis.addChild(new DynamicBorder(borderColor));\n\n\t\t// Content container (holds dynamic content between borders)\n\t\tthis.contentContainer = new Container();\n\t\tthis.addChild(this.contentContainer);\n\n\t\t// Command header\n\t\tconst header = new Text(theme.fg(colorKey, theme.bold(`$ ${command}`)), 1, 0);\n\t\tthis.contentContainer.addChild(header);\n\n\t\t// Loader\n\t\tthis.loader = new Loader(\n\t\t\tui,\n\t\t\t(spinner) => theme.fg(colorKey, spinner),\n\t\t\t(text) => theme.fg(\"muted\", text),\n\t\t\t`Running... (${editorKey(\"selectCancel\")} to cancel)`, // Plain text for loader\n\t\t);\n\t\tthis.contentContainer.addChild(this.loader);\n\n\t\t// Bottom border\n\t\tthis.addChild(new DynamicBorder(borderColor));\n\t}\n\n\t/**\n\t * Set whether the output is expanded (shows full output) or collapsed (preview only).\n\t */\n\tsetExpanded(expanded: boolean): void {\n\t\tthis.expanded = expanded;\n\t\tthis.updateDisplay();\n\t}\n\n\toverride invalidate(): void {\n\t\tsuper.invalidate();\n\t\tthis.updateDisplay();\n\t}\n\n\tappendOutput(chunk: string): void {\n\t\t// Strip ANSI codes and normalize line endings\n\t\t// Note: binary data is already sanitized in tui-renderer.ts executeBashCommand\n\t\tconst clean = stripAnsi(chunk).replace(/\\r\\n/g, \"\\n\").replace(/\\r/g, \"\\n\");\n\n\t\t// Append to output lines\n\t\tconst newLines = clean.split(\"\\n\");\n\t\tif (this.outputLines.length > 0 && newLines.length > 0) {\n\t\t\t// Append first chunk to last line (incomplete line continuation)\n\t\t\tthis.outputLines[this.outputLines.length - 1] += newLines[0];\n\t\t\tthis.outputLines.push(...newLines.slice(1));\n\t\t} else {\n\t\t\tthis.outputLines.push(...newLines);\n\t\t}\n\n\t\tthis.updateDisplay();\n\t}\n\n\tsetComplete(\n\t\texitCode: number | undefined,\n\t\tcancelled: boolean,\n\t\ttruncationResult?: TruncationResult,\n\t\tfullOutputPath?: string,\n\t): void {\n\t\tthis.exitCode = exitCode;\n\t\tthis.status = cancelled\n\t\t\t? \"cancelled\"\n\t\t\t: exitCode !== 0 && exitCode !== undefined && exitCode !== null\n\t\t\t\t? \"error\"\n\t\t\t\t: \"complete\";\n\t\tthis.truncationResult = truncationResult;\n\t\tthis.fullOutputPath = fullOutputPath;\n\n\t\t// Stop loader\n\t\tthis.loader.stop();\n\n\t\tthis.updateDisplay();\n\t}\n\n\toverride render(width: number): string[] {\n\t\tconst frameWidth = Math.max(20, width);\n\t\tconst elapsedStatus =\n\t\t\tthis.status === \"running\"\n\t\t\t\t? \"running\"\n\t\t\t\t: this.status === \"complete\"\n\t\t\t\t\t? \"success\"\n\t\t\t\t\t: this.status === \"cancelled\"\n\t\t\t\t\t\t? \"cancelled\"\n\t\t\t\t\t\t: `failed${this.exitCode !== undefined ? ` · exit ${this.exitCode}` : \"\"}`;\n\t\tconst tone: StatusTone =\n\t\t\tthis.status === \"running\"\n\t\t\t\t? \"running\"\n\t\t\t\t: this.status === \"complete\"\n\t\t\t\t\t? \"success\"\n\t\t\t\t\t: this.status === \"cancelled\"\n\t\t\t\t\t\t? \"warning\"\n\t\t\t\t\t\t: \"error\";\n\n\t\tif (!this.expanded && this.status !== \"error\") {\n\t\t\treturn renderCommandCard(this.command.replace(/\\s+/g, \" \").trim(), frameWidth, {\n\t\t\t\tstatus: elapsedStatus,\n\t\t\t\ttone,\n\t\t\t});\n\t\t}\n\n\t\tconst output = this.outputLines.join(\"\\n\");\n\t\tconst contextTruncation = truncateTail(output, {\n\t\t\tmaxLines: DEFAULT_MAX_LINES,\n\t\t\tmaxBytes: DEFAULT_MAX_BYTES,\n\t\t});\n\t\tconst truncationResult = this.truncationResult ?? contextTruncation;\n\t\tconst fullOutputPath = this.fullOutputPath;\n\t\tconst availableLines = contextTruncation.content ? contextTruncation.content.split(\"\\n\") : [];\n\t\tconst preview = this.expanded ? availableLines : availableLines.slice(-PREVIEW_LINES);\n\t\tconst hidden = Math.max(0, availableLines.length - preview.length);\n\t\tconst truncationWarning =\n\t\t\t(truncationResult.truncated || contextTruncation.truncated) && fullOutputPath\n\t\t\t\t? [theme.fg(\"warning\", `Output truncated. Full output: ${fullOutputPath}`)]\n\t\t\t\t: [];\n\t\tconst body = [\n\t\t\ttheme.fg(\"toolTitle\", `$ ${this.command}`),\n\t\t\t...preview.map((line) => theme.fg(\"toolOutput\", line)),\n\t\t\t...(hidden > 0 ? [theme.fg(\"muted\", `... ${hidden} earlier lines`)] : []),\n\t\t\t...truncationWarning,\n\t\t];\n\t\treturn renderTranscriptCard(body, frameWidth, {\n\t\t\ttitle: \"command\",\n\t\t\tright: elapsedStatus,\n\t\t\ttone,\n\t\t\tfooterLeft: this.expanded ? \"output expanded\" : \"output preview\",\n\t\t\tfooterRight: this.expanded ? \"ctrl+o collapse\" : \"ctrl+o expand\",\n\t\t});\n\t}\n\n\tprivate updateDisplay(): void {\n\t\t// Apply truncation for LLM context limits (same limits as bash tool)\n\t\tconst fullOutput = this.outputLines.join(\"\\n\");\n\t\tconst contextTruncation = truncateTail(fullOutput, {\n\t\t\tmaxLines: DEFAULT_MAX_LINES,\n\t\t\tmaxBytes: DEFAULT_MAX_BYTES,\n\t\t});\n\n\t\t// Get the lines to potentially display (after context truncation)\n\t\tconst availableLines = contextTruncation.content ? contextTruncation.content.split(\"\\n\") : [];\n\n\t\t// Apply preview truncation based on expanded state\n\t\tconst previewLogicalLines = availableLines.slice(-PREVIEW_LINES);\n\t\tconst hiddenLineCount = availableLines.length - previewLogicalLines.length;\n\n\t\t// Rebuild content container\n\t\tthis.contentContainer.clear();\n\n\t\t// Command header\n\t\tconst header = new Text(theme.fg(this._borderColorKey, theme.bold(`$ ${this.command}`)), 1, 0);\n\t\tthis.contentContainer.addChild(header);\n\n\t\t// Output\n\t\tif (availableLines.length > 0) {\n\t\t\tif (this.expanded) {\n\t\t\t\t// Show all lines\n\t\t\t\tconst displayText = availableLines.map((line) => theme.fg(\"muted\", line)).join(\"\\n\");\n\t\t\t\tthis.contentContainer.addChild(new Text(`\\n${displayText}`, 1, 0));\n\t\t\t} else {\n\t\t\t\t// Use shared visual truncation utility\n\t\t\t\tconst styledOutput = previewLogicalLines.map((line) => theme.fg(\"muted\", line)).join(\"\\n\");\n\t\t\t\tlet cachedWidth: number | undefined;\n\t\t\t\tlet cachedLines: string[] | undefined;\n\t\t\t\tthis.contentContainer.addChild({\n\t\t\t\t\trender: (width: number) => {\n\t\t\t\t\t\tif (cachedLines === undefined || cachedWidth !== width) {\n\t\t\t\t\t\t\tconst result = truncateToVisualLines(\n\t\t\t\t\t\t\t\t`\\n${styledOutput}`,\n\t\t\t\t\t\t\t\tPREVIEW_LINES,\n\t\t\t\t\t\t\t\twidth,\n\t\t\t\t\t\t\t\t1, // padding\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tcachedLines = result.visualLines;\n\t\t\t\t\t\t\tcachedWidth = width;\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn cachedLines;\n\t\t\t\t\t},\n\t\t\t\t\tinvalidate: () => {\n\t\t\t\t\t\tcachedWidth = undefined;\n\t\t\t\t\t\tcachedLines = undefined;\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\t// Loader or status\n\t\tif (this.status === \"running\") {\n\t\t\tthis.contentContainer.addChild(this.loader);\n\t\t} else {\n\t\t\tconst statusParts: string[] = [];\n\n\t\t\t// Show how many lines are hidden (collapsed preview)\n\t\t\tif (hiddenLineCount > 0) {\n\t\t\t\tif (this.expanded) {\n\t\t\t\t\tstatusParts.push(`(${keyHint(\"expandTools\", \"to collapse\")})`);\n\t\t\t\t} else {\n\t\t\t\t\tstatusParts.push(\n\t\t\t\t\t\t`${theme.fg(\"muted\", `... ${hiddenLineCount} more lines`)} (${keyHint(\"expandTools\", \"to expand\")})`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (this.status === \"cancelled\") {\n\t\t\t\tstatusParts.push(theme.fg(\"warning\", \"(cancelled)\"));\n\t\t\t} else if (this.status === \"error\") {\n\t\t\t\tstatusParts.push(theme.fg(\"error\", `(exit ${this.exitCode})`));\n\t\t\t}\n\n\t\t\t// Add truncation warning (context truncation, not preview truncation)\n\t\t\tconst wasTruncated = this.truncationResult?.truncated || contextTruncation.truncated;\n\t\t\tif (wasTruncated && this.fullOutputPath) {\n\t\t\t\tstatusParts.push(theme.fg(\"warning\", `Output truncated. Full output: ${this.fullOutputPath}`));\n\t\t\t}\n\n\t\t\tif (statusParts.length > 0) {\n\t\t\t\tthis.contentContainer.addChild(new Text(`\\n${statusParts.join(\"\\n\")}`, 1, 0));\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Get the raw output for creating BashExecutionMessage.\n\t */\n\tgetOutput(): string {\n\t\treturn this.outputLines.join(\"\\n\");\n\t}\n\n\t/**\n\t * Get the command that was executed.\n\t */\n\tgetCommand(): string {\n\t\treturn this.command;\n\t}\n}\n"]}
1
+ {"version":3,"file":"bash-execution.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/bash-execution.ts"],"names":[],"mappings":"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","sourcesContent":["// Project/App: gsd-pi\n// File Purpose: Interactive terminal bash execution renderer with streaming output and recommended command cards.\n\nimport { Container, Loader, Spacer, Text, type TUI } from \"@gsd/pi-tui\";\nimport stripAnsi from \"strip-ansi\";\nimport {\n\tDEFAULT_MAX_BYTES,\n\tDEFAULT_MAX_LINES,\n\ttype TruncationResult,\n\ttruncateTail,\n} from \"@gsd/pi-coding-agent/core/tools/truncate.js\";\nimport { theme } from \"@gsd/pi-coding-agent/theme/theme.js\";\nimport { DynamicBorder } from \"./dynamic-border.js\";\nimport { editorKey, keyHint } from \"./keybinding-hints.js\";\nimport { renderCommandCard, renderPlainToolMessage, type StatusTone } from \"./transcript-design.js\";\nimport { truncateToVisualLines } from \"./visual-truncate.js\";\n\n// Preview line limit when not expanded (matches tool execution behavior)\nconst PREVIEW_LINES = 20;\n\nexport class BashExecutionComponent extends Container {\n\tprivate command: string;\n\tprivate outputLines: string[] = [];\n\tprivate status: \"running\" | \"complete\" | \"cancelled\" | \"error\" = \"running\";\n\tprivate exitCode: number | undefined = undefined;\n\tprivate loader: Loader;\n\tprivate truncationResult?: TruncationResult;\n\tprivate fullOutputPath?: string;\n\tprivate expanded = false;\n\tprivate contentContainer: Container;\n\tprivate ui: TUI;\n\tprivate _borderColorKey: \"dim\" | \"bashMode\";\n\n\tconstructor(command: string, ui: TUI, excludeFromContext = false) {\n\t\tsuper();\n\t\tthis.command = command;\n\t\tthis.ui = ui;\n\n\t\t// Use dim border for excluded-from-context commands (!! prefix)\n\t\tconst colorKey = excludeFromContext ? \"dim\" : \"bashMode\";\n\t\tthis._borderColorKey = colorKey;\n\t\tconst borderColor = (str: string) => theme.fg(colorKey, str);\n\n\t\t// Add spacer\n\t\tthis.addChild(new Spacer(1));\n\n\t\t// Top border\n\t\tthis.addChild(new DynamicBorder(borderColor));\n\n\t\t// Content container (holds dynamic content between borders)\n\t\tthis.contentContainer = new Container();\n\t\tthis.addChild(this.contentContainer);\n\n\t\t// Command header\n\t\tconst header = new Text(theme.fg(colorKey, theme.bold(`$ ${command}`)), 1, 0);\n\t\tthis.contentContainer.addChild(header);\n\n\t\t// Loader\n\t\tthis.loader = new Loader(\n\t\t\tui,\n\t\t\t(spinner) => theme.fg(colorKey, spinner),\n\t\t\t(text) => theme.fg(\"muted\", text),\n\t\t\t`Running... (${editorKey(\"selectCancel\")} to cancel)`, // Plain text for loader\n\t\t);\n\t\tthis.contentContainer.addChild(this.loader);\n\n\t\t// Bottom border\n\t\tthis.addChild(new DynamicBorder(borderColor));\n\t}\n\n\t/**\n\t * Set whether the output is expanded (shows full output) or collapsed (preview only).\n\t */\n\tsetExpanded(expanded: boolean): void {\n\t\tthis.expanded = expanded;\n\t\tthis.updateDisplay();\n\t}\n\n\toverride invalidate(): void {\n\t\tsuper.invalidate();\n\t\tthis.updateDisplay();\n\t}\n\n\tappendOutput(chunk: string): void {\n\t\t// Strip ANSI codes and normalize line endings\n\t\t// Note: binary data is already sanitized in tui-renderer.ts executeBashCommand\n\t\tconst clean = stripAnsi(chunk).replace(/\\r\\n/g, \"\\n\").replace(/\\r/g, \"\\n\");\n\n\t\t// Append to output lines\n\t\tconst newLines = clean.split(\"\\n\");\n\t\tif (this.outputLines.length > 0 && newLines.length > 0) {\n\t\t\t// Append first chunk to last line (incomplete line continuation)\n\t\t\tthis.outputLines[this.outputLines.length - 1] += newLines[0];\n\t\t\tthis.outputLines.push(...newLines.slice(1));\n\t\t} else {\n\t\t\tthis.outputLines.push(...newLines);\n\t\t}\n\n\t\tthis.updateDisplay();\n\t}\n\n\tsetComplete(\n\t\texitCode: number | undefined,\n\t\tcancelled: boolean,\n\t\ttruncationResult?: TruncationResult,\n\t\tfullOutputPath?: string,\n\t): void {\n\t\tthis.exitCode = exitCode;\n\t\tthis.status = cancelled\n\t\t\t? \"cancelled\"\n\t\t\t: exitCode !== 0 && exitCode !== undefined && exitCode !== null\n\t\t\t\t? \"error\"\n\t\t\t\t: \"complete\";\n\t\tthis.truncationResult = truncationResult;\n\t\tthis.fullOutputPath = fullOutputPath;\n\n\t\t// Stop loader\n\t\tthis.loader.stop();\n\n\t\tthis.updateDisplay();\n\t}\n\n\toverride render(width: number): string[] {\n\t\tconst frameWidth = Math.max(20, width);\n\t\tconst elapsedStatus =\n\t\t\tthis.status === \"running\"\n\t\t\t\t? \"running\"\n\t\t\t\t: this.status === \"complete\"\n\t\t\t\t\t? \"success\"\n\t\t\t\t\t: this.status === \"cancelled\"\n\t\t\t\t\t\t? \"cancelled\"\n\t\t\t\t\t\t: `failed${this.exitCode !== undefined ? ` · exit ${this.exitCode}` : \"\"}`;\n\t\tconst tone: StatusTone =\n\t\t\tthis.status === \"running\"\n\t\t\t\t? \"running\"\n\t\t\t\t: this.status === \"complete\"\n\t\t\t\t\t? \"success\"\n\t\t\t\t\t: this.status === \"cancelled\"\n\t\t\t\t\t\t? \"warning\"\n\t\t\t\t\t\t: \"error\";\n\n\t\tif (!this.expanded && this.status !== \"error\") {\n\t\t\treturn renderCommandCard(this.command.replace(/\\s+/g, \" \").trim(), frameWidth, {\n\t\t\t\tstatus: elapsedStatus,\n\t\t\t\ttone,\n\t\t\t});\n\t\t}\n\n\t\tconst output = this.outputLines.join(\"\\n\");\n\t\tconst contextTruncation = truncateTail(output, {\n\t\t\tmaxLines: DEFAULT_MAX_LINES,\n\t\t\tmaxBytes: DEFAULT_MAX_BYTES,\n\t\t});\n\t\tconst truncationResult = this.truncationResult ?? contextTruncation;\n\t\tconst fullOutputPath = this.fullOutputPath;\n\t\tconst availableLines = contextTruncation.content ? contextTruncation.content.split(\"\\n\") : [];\n\t\tconst preview = this.expanded ? availableLines : availableLines.slice(-PREVIEW_LINES);\n\t\tconst hidden = Math.max(0, availableLines.length - preview.length);\n\t\tconst truncationWarning =\n\t\t\t(truncationResult.truncated || contextTruncation.truncated) && fullOutputPath\n\t\t\t\t? [theme.fg(\"warning\", `Output truncated. Full output: ${fullOutputPath}`)]\n\t\t\t\t: [];\n\t\tconst body = [\n\t\t\ttheme.fg(\"toolTitle\", `$ ${this.command}`),\n\t\t\t...preview.map((line) => theme.fg(\"toolOutput\", line)),\n\t\t\t...(hidden > 0 ? [theme.fg(\"muted\", `... ${hidden} earlier lines`)] : []),\n\t\t\t...truncationWarning,\n\t\t];\n\t\tconst rightParts = [elapsedStatus];\n\t\trightParts.push(this.expanded ? \"ctrl+o collapse\" : \"ctrl+o expand\");\n\t\treturn renderPlainToolMessage(body, frameWidth, {\n\t\t\ttitle: \"command\",\n\t\t\tmeta: rightParts.join(\" · \"),\n\t\t\ttone,\n\t\t});\n\t}\n\n\tprivate updateDisplay(): void {\n\t\t// Apply truncation for LLM context limits (same limits as bash tool)\n\t\tconst fullOutput = this.outputLines.join(\"\\n\");\n\t\tconst contextTruncation = truncateTail(fullOutput, {\n\t\t\tmaxLines: DEFAULT_MAX_LINES,\n\t\t\tmaxBytes: DEFAULT_MAX_BYTES,\n\t\t});\n\n\t\t// Get the lines to potentially display (after context truncation)\n\t\tconst availableLines = contextTruncation.content ? contextTruncation.content.split(\"\\n\") : [];\n\n\t\t// Apply preview truncation based on expanded state\n\t\tconst previewLogicalLines = availableLines.slice(-PREVIEW_LINES);\n\t\tconst hiddenLineCount = availableLines.length - previewLogicalLines.length;\n\n\t\t// Rebuild content container\n\t\tthis.contentContainer.clear();\n\n\t\t// Command header\n\t\tconst header = new Text(theme.fg(this._borderColorKey, theme.bold(`$ ${this.command}`)), 1, 0);\n\t\tthis.contentContainer.addChild(header);\n\n\t\t// Output\n\t\tif (availableLines.length > 0) {\n\t\t\tif (this.expanded) {\n\t\t\t\t// Show all lines\n\t\t\t\tconst displayText = availableLines.map((line) => theme.fg(\"muted\", line)).join(\"\\n\");\n\t\t\t\tthis.contentContainer.addChild(new Text(`\\n${displayText}`, 1, 0));\n\t\t\t} else {\n\t\t\t\t// Use shared visual truncation utility\n\t\t\t\tconst styledOutput = previewLogicalLines.map((line) => theme.fg(\"muted\", line)).join(\"\\n\");\n\t\t\t\tlet cachedWidth: number | undefined;\n\t\t\t\tlet cachedLines: string[] | undefined;\n\t\t\t\tthis.contentContainer.addChild({\n\t\t\t\t\trender: (width: number) => {\n\t\t\t\t\t\tif (cachedLines === undefined || cachedWidth !== width) {\n\t\t\t\t\t\t\tconst result = truncateToVisualLines(\n\t\t\t\t\t\t\t\t`\\n${styledOutput}`,\n\t\t\t\t\t\t\t\tPREVIEW_LINES,\n\t\t\t\t\t\t\t\twidth,\n\t\t\t\t\t\t\t\t1, // padding\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tcachedLines = result.visualLines;\n\t\t\t\t\t\t\tcachedWidth = width;\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn cachedLines;\n\t\t\t\t\t},\n\t\t\t\t\tinvalidate: () => {\n\t\t\t\t\t\tcachedWidth = undefined;\n\t\t\t\t\t\tcachedLines = undefined;\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\t// Loader or status\n\t\tif (this.status === \"running\") {\n\t\t\tthis.contentContainer.addChild(this.loader);\n\t\t} else {\n\t\t\tconst statusParts: string[] = [];\n\n\t\t\t// Show how many lines are hidden (collapsed preview)\n\t\t\tif (hiddenLineCount > 0) {\n\t\t\t\tif (this.expanded) {\n\t\t\t\t\tstatusParts.push(`(${keyHint(\"expandTools\", \"to collapse\")})`);\n\t\t\t\t} else {\n\t\t\t\t\tstatusParts.push(\n\t\t\t\t\t\t`${theme.fg(\"muted\", `... ${hiddenLineCount} more lines`)} (${keyHint(\"expandTools\", \"to expand\")})`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (this.status === \"cancelled\") {\n\t\t\t\tstatusParts.push(theme.fg(\"warning\", \"(cancelled)\"));\n\t\t\t} else if (this.status === \"error\") {\n\t\t\t\tstatusParts.push(theme.fg(\"error\", `(exit ${this.exitCode})`));\n\t\t\t}\n\n\t\t\t// Add truncation warning (context truncation, not preview truncation)\n\t\t\tconst wasTruncated = this.truncationResult?.truncated || contextTruncation.truncated;\n\t\t\tif (wasTruncated && this.fullOutputPath) {\n\t\t\t\tstatusParts.push(theme.fg(\"warning\", `Output truncated. Full output: ${this.fullOutputPath}`));\n\t\t\t}\n\n\t\t\tif (statusParts.length > 0) {\n\t\t\t\tthis.contentContainer.addChild(new Text(`\\n${statusParts.join(\"\\n\")}`, 1, 0));\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Get the raw output for creating BashExecutionMessage.\n\t */\n\tgetOutput(): string {\n\t\treturn this.outputLines.join(\"\\n\");\n\t}\n\n\t/**\n\t * Get the command that was executed.\n\t */\n\tgetCommand(): string {\n\t\treturn this.command;\n\t}\n}\n"]}
@@ -2,14 +2,14 @@ import { type MarkdownTheme } from "@gsd/pi-tui";
2
2
  import type { BranchSummaryMessage } from "@gsd/pi-coding-agent/core/messages.js";
3
3
  import { CollapsibleMessageComponent } from "./collapsible-message.js";
4
4
  /**
5
- * Component that renders a branch summary message with collapsed/expanded state.
6
- * Uses same background color as custom messages for visual consistency.
5
+ * Renders a branch summary as a plain system line (◇ branch header,
6
+ * copy-clean body) matching compaction and skill notices.
7
7
  */
8
8
  export declare class BranchSummaryMessageComponent extends CollapsibleMessageComponent {
9
9
  private message;
10
10
  private markdownTheme;
11
- private box;
12
11
  constructor(message: BranchSummaryMessage, markdownTheme?: MarkdownTheme);
13
12
  protected rebuildContent(): void;
13
+ render(width: number): string[];
14
14
  }
15
15
  //# sourceMappingURL=branch-summary-message.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"branch-summary-message.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/branch-summary-message.ts"],"names":[],"mappings":"AAEA,OAAO,EAAiB,KAAK,aAAa,EAAgB,MAAM,aAAa,CAAC;AAC9E,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,uCAAuC,CAAC;AAElF,OAAO,EAAE,2BAA2B,EAAE,MAAM,0BAA0B,CAAC;AAGvE;;;GAGG;AACH,qBAAa,6BAA8B,SAAQ,2BAA2B;IAC7E,OAAO,CAAC,OAAO,CAAuB;IACtC,OAAO,CAAC,aAAa,CAAgB;IACrC,OAAO,CAAC,GAAG,CAAM;gBAEL,OAAO,EAAE,oBAAoB,EAAE,aAAa,GAAE,aAAkC;IAQ5F,SAAS,CAAC,cAAc,IAAI,IAAI;CA4BhC"}
1
+ {"version":3,"file":"branch-summary-message.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/branch-summary-message.ts"],"names":[],"mappings":"AAEA,OAAO,EAAY,KAAK,aAAa,EAAQ,MAAM,aAAa,CAAC;AACjE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,uCAAuC,CAAC;AAElF,OAAO,EAAE,2BAA2B,EAAE,MAAM,0BAA0B,CAAC;AAIvE;;;GAGG;AACH,qBAAa,6BAA8B,SAAQ,2BAA2B;IAC7E,OAAO,CAAC,OAAO,CAAuB;IACtC,OAAO,CAAC,aAAa,CAAgB;gBAEzB,OAAO,EAAE,oBAAoB,EAAE,aAAa,GAAE,aAAkC;IAO5F,SAAS,CAAC,cAAc,IAAI,IAAI;IAuBvB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE;CAcxC"}
@@ -1,38 +1,47 @@
1
1
  // gsd-pi + packages/pi-coding-agent/src/modes/interactive/components/branch-summary-message.ts - Branch summary message renderer.
2
- import { Box, Markdown, Spacer, Text } from "@gsd/pi-tui";
2
+ import { Markdown, Text } from "@gsd/pi-tui";
3
3
  import { getMarkdownTheme, theme } from "@gsd/pi-coding-agent/theme/theme.js";
4
4
  import { CollapsibleMessageComponent } from "./collapsible-message.js";
5
+ import { renderChatFrame } from "./transcript-design.js";
5
6
  import { editorKey } from "./keybinding-hints.js";
6
7
  /**
7
- * Component that renders a branch summary message with collapsed/expanded state.
8
- * Uses same background color as custom messages for visual consistency.
8
+ * Renders a branch summary as a plain system line (◇ branch header,
9
+ * copy-clean body) matching compaction and skill notices.
9
10
  */
10
11
  export class BranchSummaryMessageComponent extends CollapsibleMessageComponent {
11
12
  constructor(message, markdownTheme = getMarkdownTheme()) {
12
13
  super();
13
14
  this.message = message;
14
15
  this.markdownTheme = markdownTheme;
15
- this.box = new Box(1, 1, (t) => theme.bg("customMessageBg", t));
16
16
  this.rebuildContent();
17
17
  }
18
18
  rebuildContent() {
19
19
  this.clear();
20
- this.box.clear();
21
- this.addChild(this.box);
22
- const label = theme.fg("customMessageLabel", theme.bold("[branch]"));
23
- this.box.addChild(new Text(label, 0, 0));
24
- this.box.addChild(new Spacer(1));
25
20
  if (this.expanded) {
26
21
  const header = "**Branch Summary**\n\n";
27
- this.box.addChild(new Markdown(header + this.message.summary, 0, 0, this.markdownTheme, {
22
+ this.addChild(new Markdown(header + this.message.summary, 0, 0, this.markdownTheme, {
28
23
  color: (text) => theme.fg("customMessageText", text),
29
24
  }));
30
25
  }
31
26
  else {
32
- this.box.addChild(new Text(theme.fg("customMessageText", "Branch summary (") +
27
+ this.addChild(new Text(theme.fg("customMessageText", "Branch summary (") +
33
28
  theme.fg("dim", editorKey("expandTools")) +
34
29
  theme.fg("customMessageText", " to expand)"), 0, 0));
35
30
  }
36
31
  }
32
+ render(width) {
33
+ const cached = this.getCachedRender(width);
34
+ if (cached)
35
+ return cached;
36
+ const frameWidth = Math.max(20, width);
37
+ const lines = super.render(frameWidth);
38
+ const framed = renderChatFrame(lines, frameWidth, {
39
+ label: "branch",
40
+ tone: "skill",
41
+ timestampFormat: "date-time-iso",
42
+ showTimestamp: false,
43
+ });
44
+ return this.setCachedRender(width, framed.length > 0 ? ["", ...framed] : framed);
45
+ }
37
46
  }
38
47
  //# sourceMappingURL=branch-summary-message.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"branch-summary-message.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/branch-summary-message.ts"],"names":[],"mappings":"AAAA,kIAAkI;AAElI,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAsB,MAAM,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAE9E,OAAO,EAAE,gBAAgB,EAAE,KAAK,EAAE,MAAM,qCAAqC,CAAC;AAC9E,OAAO,EAAE,2BAA2B,EAAE,MAAM,0BAA0B,CAAC;AACvE,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAElD;;;GAGG;AACH,MAAM,OAAO,6BAA8B,SAAQ,2BAA2B;IAK7E,YAAY,OAA6B,EAAE,gBAA+B,gBAAgB,EAAE;QAC3F,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,aAAa,GAAG,aAAa,CAAC;QACnC,IAAI,CAAC,GAAG,GAAG,IAAI,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,iBAAiB,EAAE,CAAC,CAAC,CAAC,CAAC;QAChE,IAAI,CAAC,cAAc,EAAE,CAAC;IACvB,CAAC;IAES,cAAc;QACvB,IAAI,CAAC,KAAK,EAAE,CAAC;QACb,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC;QACjB,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAExB,MAAM,KAAK,GAAG,KAAK,CAAC,EAAE,CAAC,oBAAoB,EAAE,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;QACrE,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QACzC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QAEjC,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YACnB,MAAM,MAAM,GAAG,wBAAwB,CAAC;YACxC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAChB,IAAI,QAAQ,CAAC,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,aAAa,EAAE;gBACrE,KAAK,EAAE,CAAC,IAAY,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,mBAAmB,EAAE,IAAI,CAAC;aAC5D,CAAC,CACF,CAAC;QACH,CAAC;aAAM,CAAC;YACP,IAAI,CAAC,GAAG,CAAC,QAAQ,CAChB,IAAI,IAAI,CACP,KAAK,CAAC,EAAE,CAAC,mBAAmB,EAAE,kBAAkB,CAAC;gBAChD,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,SAAS,CAAC,aAAa,CAAC,CAAC;gBACzC,KAAK,CAAC,EAAE,CAAC,mBAAmB,EAAE,aAAa,CAAC,EAC7C,CAAC,EACD,CAAC,CACD,CACD,CAAC;QACH,CAAC;IACF,CAAC;CACD","sourcesContent":["// gsd-pi + packages/pi-coding-agent/src/modes/interactive/components/branch-summary-message.ts - Branch summary message renderer.\n\nimport { Box, Markdown, type MarkdownTheme, Spacer, Text } from \"@gsd/pi-tui\";\nimport type { BranchSummaryMessage } from \"@gsd/pi-coding-agent/core/messages.js\";\nimport { getMarkdownTheme, theme } from \"@gsd/pi-coding-agent/theme/theme.js\";\nimport { CollapsibleMessageComponent } from \"./collapsible-message.js\";\nimport { editorKey } from \"./keybinding-hints.js\";\n\n/**\n * Component that renders a branch summary message with collapsed/expanded state.\n * Uses same background color as custom messages for visual consistency.\n */\nexport class BranchSummaryMessageComponent extends CollapsibleMessageComponent {\n\tprivate message: BranchSummaryMessage;\n\tprivate markdownTheme: MarkdownTheme;\n\tprivate box: Box;\n\n\tconstructor(message: BranchSummaryMessage, markdownTheme: MarkdownTheme = getMarkdownTheme()) {\n\t\tsuper();\n\t\tthis.message = message;\n\t\tthis.markdownTheme = markdownTheme;\n\t\tthis.box = new Box(1, 1, (t) => theme.bg(\"customMessageBg\", t));\n\t\tthis.rebuildContent();\n\t}\n\n\tprotected rebuildContent(): void {\n\t\tthis.clear();\n\t\tthis.box.clear();\n\t\tthis.addChild(this.box);\n\n\t\tconst label = theme.fg(\"customMessageLabel\", theme.bold(\"[branch]\"));\n\t\tthis.box.addChild(new Text(label, 0, 0));\n\t\tthis.box.addChild(new Spacer(1));\n\n\t\tif (this.expanded) {\n\t\t\tconst header = \"**Branch Summary**\\n\\n\";\n\t\t\tthis.box.addChild(\n\t\t\t\tnew Markdown(header + this.message.summary, 0, 0, this.markdownTheme, {\n\t\t\t\t\tcolor: (text: string) => theme.fg(\"customMessageText\", text),\n\t\t\t\t}),\n\t\t\t);\n\t\t} else {\n\t\t\tthis.box.addChild(\n\t\t\t\tnew Text(\n\t\t\t\t\ttheme.fg(\"customMessageText\", \"Branch summary (\") +\n\t\t\t\t\t\ttheme.fg(\"dim\", editorKey(\"expandTools\")) +\n\t\t\t\t\t\ttheme.fg(\"customMessageText\", \" to expand)\"),\n\t\t\t\t\t0,\n\t\t\t\t\t0,\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\t}\n}\n"]}
1
+ {"version":3,"file":"branch-summary-message.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/branch-summary-message.ts"],"names":[],"mappings":"AAAA,kIAAkI;AAElI,OAAO,EAAE,QAAQ,EAAsB,IAAI,EAAE,MAAM,aAAa,CAAC;AAEjE,OAAO,EAAE,gBAAgB,EAAE,KAAK,EAAE,MAAM,qCAAqC,CAAC;AAC9E,OAAO,EAAE,2BAA2B,EAAE,MAAM,0BAA0B,CAAC;AACvE,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAElD;;;GAGG;AACH,MAAM,OAAO,6BAA8B,SAAQ,2BAA2B;IAI7E,YAAY,OAA6B,EAAE,gBAA+B,gBAAgB,EAAE;QAC3F,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,aAAa,GAAG,aAAa,CAAC;QACnC,IAAI,CAAC,cAAc,EAAE,CAAC;IACvB,CAAC;IAES,cAAc;QACvB,IAAI,CAAC,KAAK,EAAE,CAAC;QAEb,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YACnB,MAAM,MAAM,GAAG,wBAAwB,CAAC;YACxC,IAAI,CAAC,QAAQ,CACZ,IAAI,QAAQ,CAAC,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,aAAa,EAAE;gBACrE,KAAK,EAAE,CAAC,IAAY,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,mBAAmB,EAAE,IAAI,CAAC;aAC5D,CAAC,CACF,CAAC;QACH,CAAC;aAAM,CAAC;YACP,IAAI,CAAC,QAAQ,CACZ,IAAI,IAAI,CACP,KAAK,CAAC,EAAE,CAAC,mBAAmB,EAAE,kBAAkB,CAAC;gBAChD,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,SAAS,CAAC,aAAa,CAAC,CAAC;gBACzC,KAAK,CAAC,EAAE,CAAC,mBAAmB,EAAE,aAAa,CAAC,EAC7C,CAAC,EACD,CAAC,CACD,CACD,CAAC;QACH,CAAC;IACF,CAAC;IAEQ,MAAM,CAAC,KAAa;QAC5B,MAAM,MAAM,GAAG,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;QAC3C,IAAI,MAAM;YAAE,OAAO,MAAM,CAAC;QAE1B,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;QACvC,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QACvC,MAAM,MAAM,GAAG,eAAe,CAAC,KAAK,EAAE,UAAU,EAAE;YACjD,KAAK,EAAE,QAAQ;YACf,IAAI,EAAE,OAAO;YACb,eAAe,EAAE,eAAe;YAChC,aAAa,EAAE,KAAK;SACpB,CAAC,CAAC;QACH,OAAO,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;IAClF,CAAC;CACD","sourcesContent":["// gsd-pi + packages/pi-coding-agent/src/modes/interactive/components/branch-summary-message.ts - Branch summary message renderer.\n\nimport { Markdown, type MarkdownTheme, Text } from \"@gsd/pi-tui\";\nimport type { BranchSummaryMessage } from \"@gsd/pi-coding-agent/core/messages.js\";\nimport { getMarkdownTheme, theme } from \"@gsd/pi-coding-agent/theme/theme.js\";\nimport { CollapsibleMessageComponent } from \"./collapsible-message.js\";\nimport { renderChatFrame } from \"./transcript-design.js\";\nimport { editorKey } from \"./keybinding-hints.js\";\n\n/**\n * Renders a branch summary as a plain system line (◇ branch header,\n * copy-clean body) matching compaction and skill notices.\n */\nexport class BranchSummaryMessageComponent extends CollapsibleMessageComponent {\n\tprivate message: BranchSummaryMessage;\n\tprivate markdownTheme: MarkdownTheme;\n\n\tconstructor(message: BranchSummaryMessage, markdownTheme: MarkdownTheme = getMarkdownTheme()) {\n\t\tsuper();\n\t\tthis.message = message;\n\t\tthis.markdownTheme = markdownTheme;\n\t\tthis.rebuildContent();\n\t}\n\n\tprotected rebuildContent(): void {\n\t\tthis.clear();\n\n\t\tif (this.expanded) {\n\t\t\tconst header = \"**Branch Summary**\\n\\n\";\n\t\t\tthis.addChild(\n\t\t\t\tnew Markdown(header + this.message.summary, 0, 0, this.markdownTheme, {\n\t\t\t\t\tcolor: (text: string) => theme.fg(\"customMessageText\", text),\n\t\t\t\t}),\n\t\t\t);\n\t\t} else {\n\t\t\tthis.addChild(\n\t\t\t\tnew Text(\n\t\t\t\t\ttheme.fg(\"customMessageText\", \"Branch summary (\") +\n\t\t\t\t\t\ttheme.fg(\"dim\", editorKey(\"expandTools\")) +\n\t\t\t\t\t\ttheme.fg(\"customMessageText\", \" to expand)\"),\n\t\t\t\t\t0,\n\t\t\t\t\t0,\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\t}\n\n\toverride render(width: number): string[] {\n\t\tconst cached = this.getCachedRender(width);\n\t\tif (cached) return cached;\n\n\t\tconst frameWidth = Math.max(20, width);\n\t\tconst lines = super.render(frameWidth);\n\t\tconst framed = renderChatFrame(lines, frameWidth, {\n\t\t\tlabel: \"branch\",\n\t\t\ttone: \"skill\",\n\t\t\ttimestampFormat: \"date-time-iso\",\n\t\t\tshowTimestamp: false,\n\t\t});\n\t\treturn this.setCachedRender(width, framed.length > 0 ? [\"\", ...framed] : framed);\n\t}\n}\n"]}
@@ -1,4 +1,5 @@
1
- export declare function chatTurnFollowsUser(children: readonly unknown[]): boolean;
2
- /** Recompute connected-rail flags for every user/assistant turn in the chat container. */
3
- export declare function reconcileChatTurnConnections(children: readonly unknown[]): void;
1
+ /** Plain Variant A transcript does not use connected rails. */
2
+ export declare function chatTurnFollowsUser(_children: readonly unknown[]): boolean;
3
+ /** No-op plain transcript does not use connected rails. */
4
+ export declare function reconcileChatTurnConnections(_children: readonly unknown[]): void;
4
5
  //# sourceMappingURL=chat-turn-connect.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"chat-turn-connect.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/chat-turn-connect.ts"],"names":[],"mappings":"AAgBA,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,SAAS,OAAO,EAAE,GAAG,OAAO,CAQzE;AAED,0FAA0F;AAC1F,wBAAgB,4BAA4B,CAAC,QAAQ,EAAE,SAAS,OAAO,EAAE,GAAG,IAAI,CAoC/E"}
1
+ {"version":3,"file":"chat-turn-connect.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/chat-turn-connect.ts"],"names":[],"mappings":"AAGA,+DAA+D;AAC/D,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,SAAS,OAAO,EAAE,GAAG,OAAO,CAE1E;AAED,6DAA6D;AAC7D,wBAAgB,4BAA4B,CAAC,SAAS,EAAE,SAAS,OAAO,EAAE,GAAG,IAAI,CAAG"}
@@ -1,58 +1,9 @@
1
1
  // Project/App: gsd-pi
2
- // File Purpose: Detect and apply connected transcript rails between chat turns.
3
- import { Spacer } from "@gsd/pi-tui";
4
- import { AssistantMessageComponent } from "./assistant-message.js";
5
- import { ToolExecutionComponent, ToolPhaseSummaryComponent } from "./tool-execution.js";
6
- import { UserMessageComponent } from "./user-message.js";
7
- function isChatTurnComponent(child) {
8
- return child instanceof UserMessageComponent || child instanceof AssistantMessageComponent;
9
- }
10
- export function chatTurnFollowsUser(children) {
11
- for (let i = children.length - 1; i >= 0; i--) {
12
- const child = children[i];
13
- if (child instanceof Spacer)
14
- continue;
15
- if (child instanceof ToolExecutionComponent || child instanceof ToolPhaseSummaryComponent)
16
- continue;
17
- return child instanceof UserMessageComponent;
18
- }
2
+ // File Purpose: Legacy hook for connected transcript rails (Variant B — no longer applied).
3
+ /** Plain Variant A transcript does not use connected rails. */
4
+ export function chatTurnFollowsUser(_children) {
19
5
  return false;
20
6
  }
21
- /** Recompute connected-rail flags for every user/assistant turn in the chat container. */
22
- export function reconcileChatTurnConnections(children) {
23
- const userConnections = new Map();
24
- const assistantConnections = new Map();
25
- let previousTurn;
26
- for (const child of children) {
27
- if (child instanceof Spacer)
28
- continue;
29
- if (child instanceof ToolExecutionComponent || child instanceof ToolPhaseSummaryComponent)
30
- continue;
31
- if (!isChatTurnComponent(child)) {
32
- previousTurn = undefined;
33
- continue;
34
- }
35
- if (child instanceof UserMessageComponent) {
36
- userConnections.set(child, { continuesToAssistant: false });
37
- }
38
- else {
39
- assistantConnections.set(child, { continuesToUser: false, connectedToUser: false });
40
- }
41
- if (previousTurn instanceof UserMessageComponent && child instanceof AssistantMessageComponent) {
42
- userConnections.get(previousTurn).continuesToAssistant = true;
43
- assistantConnections.get(child).connectedToUser = true;
44
- }
45
- else if (previousTurn instanceof AssistantMessageComponent && child instanceof UserMessageComponent) {
46
- assistantConnections.get(previousTurn).continuesToUser = true;
47
- }
48
- previousTurn = child;
49
- }
50
- for (const [child, connection] of userConnections) {
51
- child.setContinuesToAssistant(connection.continuesToAssistant);
52
- }
53
- for (const [child, connection] of assistantConnections) {
54
- child.setContinuesToUser(connection.continuesToUser);
55
- child.setConnectedToUser(connection.connectedToUser);
56
- }
57
- }
7
+ /** No-op plain transcript does not use connected rails. */
8
+ export function reconcileChatTurnConnections(_children) { }
58
9
  //# sourceMappingURL=chat-turn-connect.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"chat-turn-connect.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/chat-turn-connect.ts"],"names":[],"mappings":"AAAA,sBAAsB;AACtB,gFAAgF;AAEhF,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,yBAAyB,EAAE,MAAM,wBAAwB,CAAC;AACnE,OAAO,EAAE,sBAAsB,EAAE,yBAAyB,EAAE,MAAM,qBAAqB,CAAC;AACxF,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAMzD,SAAS,mBAAmB,CAAC,KAAc;IAC1C,OAAO,KAAK,YAAY,oBAAoB,IAAI,KAAK,YAAY,yBAAyB,CAAC;AAC5F,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,QAA4B;IAC/D,KAAK,IAAI,CAAC,GAAG,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC/C,MAAM,KAAK,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;QAC1B,IAAI,KAAK,YAAY,MAAM;YAAE,SAAS;QACtC,IAAI,KAAK,YAAY,sBAAsB,IAAI,KAAK,YAAY,yBAAyB;YAAE,SAAS;QACpG,OAAO,KAAK,YAAY,oBAAoB,CAAC;IAC9C,CAAC;IACD,OAAO,KAAK,CAAC;AACd,CAAC;AAED,0FAA0F;AAC1F,MAAM,UAAU,4BAA4B,CAAC,QAA4B;IACxE,MAAM,eAAe,GAAG,IAAI,GAAG,EAA4C,CAAC;IAC5E,MAAM,oBAAoB,GAAG,IAAI,GAAG,EAAsD,CAAC;IAE3F,IAAI,YAA2C,CAAC;IAChD,KAAK,MAAM,KAAK,IAAI,QAAQ,EAAE,CAAC;QAC9B,IAAI,KAAK,YAAY,MAAM;YAAE,SAAS;QACtC,IAAI,KAAK,YAAY,sBAAsB,IAAI,KAAK,YAAY,yBAAyB;YAAE,SAAS;QACpG,IAAI,CAAC,mBAAmB,CAAC,KAAK,CAAC,EAAE,CAAC;YACjC,YAAY,GAAG,SAAS,CAAC;YACzB,SAAS;QACV,CAAC;QAED,IAAI,KAAK,YAAY,oBAAoB,EAAE,CAAC;YAC3C,eAAe,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,oBAAoB,EAAE,KAAK,EAAE,CAAC,CAAC;QAC7D,CAAC;aAAM,CAAC;YACP,oBAAoB,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,eAAe,EAAE,KAAK,EAAE,eAAe,EAAE,KAAK,EAAE,CAAC,CAAC;QACrF,CAAC;QAED,IAAI,YAAY,YAAY,oBAAoB,IAAI,KAAK,YAAY,yBAAyB,EAAE,CAAC;YAChG,eAAe,CAAC,GAAG,CAAC,YAAY,CAAE,CAAC,oBAAoB,GAAG,IAAI,CAAC;YAC/D,oBAAoB,CAAC,GAAG,CAAC,KAAK,CAAE,CAAC,eAAe,GAAG,IAAI,CAAC;QACzD,CAAC;aAAM,IAAI,YAAY,YAAY,yBAAyB,IAAI,KAAK,YAAY,oBAAoB,EAAE,CAAC;YACvG,oBAAoB,CAAC,GAAG,CAAC,YAAY,CAAE,CAAC,eAAe,GAAG,IAAI,CAAC;QAChE,CAAC;QAED,YAAY,GAAG,KAAK,CAAC;IACtB,CAAC;IAED,KAAK,MAAM,CAAC,KAAK,EAAE,UAAU,CAAC,IAAI,eAAe,EAAE,CAAC;QACnD,KAAK,CAAC,uBAAuB,CAAC,UAAU,CAAC,oBAAoB,CAAC,CAAC;IAChE,CAAC;IACD,KAAK,MAAM,CAAC,KAAK,EAAE,UAAU,CAAC,IAAI,oBAAoB,EAAE,CAAC;QACxD,KAAK,CAAC,kBAAkB,CAAC,UAAU,CAAC,eAAe,CAAC,CAAC;QACrD,KAAK,CAAC,kBAAkB,CAAC,UAAU,CAAC,eAAe,CAAC,CAAC;IACtD,CAAC;AACF,CAAC","sourcesContent":["// Project/App: gsd-pi\n// File Purpose: Detect and apply connected transcript rails between chat turns.\n\nimport { Spacer } from \"@gsd/pi-tui\";\nimport { AssistantMessageComponent } from \"./assistant-message.js\";\nimport { ToolExecutionComponent, ToolPhaseSummaryComponent } from \"./tool-execution.js\";\nimport { UserMessageComponent } from \"./user-message.js\";\n\ntype ChatTurnComponent = UserMessageComponent | AssistantMessageComponent;\ntype UserTurnConnection = { continuesToAssistant: boolean };\ntype AssistantTurnConnection = { continuesToUser: boolean; connectedToUser: boolean };\n\nfunction isChatTurnComponent(child: unknown): child is ChatTurnComponent {\n\treturn child instanceof UserMessageComponent || child instanceof AssistantMessageComponent;\n}\n\nexport function chatTurnFollowsUser(children: readonly unknown[]): boolean {\n\tfor (let i = children.length - 1; i >= 0; i--) {\n\t\tconst child = children[i];\n\t\tif (child instanceof Spacer) continue;\n\t\tif (child instanceof ToolExecutionComponent || child instanceof ToolPhaseSummaryComponent) continue;\n\t\treturn child instanceof UserMessageComponent;\n\t}\n\treturn false;\n}\n\n/** Recompute connected-rail flags for every user/assistant turn in the chat container. */\nexport function reconcileChatTurnConnections(children: readonly unknown[]): void {\n\tconst userConnections = new Map<UserMessageComponent, UserTurnConnection>();\n\tconst assistantConnections = new Map<AssistantMessageComponent, AssistantTurnConnection>();\n\n\tlet previousTurn: ChatTurnComponent | undefined;\n\tfor (const child of children) {\n\t\tif (child instanceof Spacer) continue;\n\t\tif (child instanceof ToolExecutionComponent || child instanceof ToolPhaseSummaryComponent) continue;\n\t\tif (!isChatTurnComponent(child)) {\n\t\t\tpreviousTurn = undefined;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (child instanceof UserMessageComponent) {\n\t\t\tuserConnections.set(child, { continuesToAssistant: false });\n\t\t} else {\n\t\t\tassistantConnections.set(child, { continuesToUser: false, connectedToUser: false });\n\t\t}\n\n\t\tif (previousTurn instanceof UserMessageComponent && child instanceof AssistantMessageComponent) {\n\t\t\tuserConnections.get(previousTurn)!.continuesToAssistant = true;\n\t\t\tassistantConnections.get(child)!.connectedToUser = true;\n\t\t} else if (previousTurn instanceof AssistantMessageComponent && child instanceof UserMessageComponent) {\n\t\t\tassistantConnections.get(previousTurn)!.continuesToUser = true;\n\t\t}\n\n\t\tpreviousTurn = child;\n\t}\n\n\tfor (const [child, connection] of userConnections) {\n\t\tchild.setContinuesToAssistant(connection.continuesToAssistant);\n\t}\n\tfor (const [child, connection] of assistantConnections) {\n\t\tchild.setContinuesToUser(connection.continuesToUser);\n\t\tchild.setConnectedToUser(connection.connectedToUser);\n\t}\n}\n"]}
1
+ {"version":3,"file":"chat-turn-connect.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/chat-turn-connect.ts"],"names":[],"mappings":"AAAA,sBAAsB;AACtB,4FAA4F;AAE5F,+DAA+D;AAC/D,MAAM,UAAU,mBAAmB,CAAC,SAA6B;IAChE,OAAO,KAAK,CAAC;AACd,CAAC;AAED,6DAA6D;AAC7D,MAAM,UAAU,4BAA4B,CAAC,SAA6B,IAAS,CAAC","sourcesContent":["// Project/App: gsd-pi\n// File Purpose: Legacy hook for connected transcript rails (Variant B no longer applied).\n\n/** Plain Variant A transcript does not use connected rails. */\nexport function chatTurnFollowsUser(_children: readonly unknown[]): boolean {\n\treturn false;\n}\n\n/** No-op plain transcript does not use connected rails. */\nexport function reconcileChatTurnConnections(_children: readonly unknown[]): void {}\n"]}
@@ -2,10 +2,8 @@ import { type MarkdownTheme } from "@gsd/pi-tui";
2
2
  import type { CompactionSummaryMessage } from "@gsd/pi-coding-agent/core/messages.js";
3
3
  import { CollapsibleMessageComponent } from "./collapsible-message.js";
4
4
  /**
5
- * Renders a compaction notice in the shared chat-frame style (top rule,
6
- * `• compaction` header, `│ ` body margin) with purple border/label so it
7
- * visually matches the other framed messages (user / assistant / tool
8
- * execution) while standing apart from the conversation flow.
5
+ * Renders a compaction notice as a plain system line ( compaction header,
6
+ * copy-clean body) visually distinct from chat dialog without rule boxes.
9
7
  */
10
8
  export declare class CompactionSummaryMessageComponent extends CollapsibleMessageComponent {
11
9
  private message;
@@ -1 +1 @@
1
- {"version":3,"file":"compaction-summary-message.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/compaction-summary-message.ts"],"names":[],"mappings":"AAEA,OAAO,EAAY,KAAK,aAAa,EAAQ,MAAM,aAAa,CAAC;AACjE,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,uCAAuC,CAAC;AAEtF,OAAO,EAAE,2BAA2B,EAAE,MAAM,0BAA0B,CAAC;AAIvE;;;;;GAKG;AACH,qBAAa,iCAAkC,SAAQ,2BAA2B;IACjF,OAAO,CAAC,OAAO,CAA2B;IAC1C,OAAO,CAAC,aAAa,CAAgB;gBAGpC,OAAO,EAAE,wBAAwB,EACjC,aAAa,GAAE,aAAkC;IAQlD,SAAS,CAAC,cAAc,IAAI,IAAI;IA4BvB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE;CAexC"}
1
+ {"version":3,"file":"compaction-summary-message.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/compaction-summary-message.ts"],"names":[],"mappings":"AAEA,OAAO,EAAY,KAAK,aAAa,EAAQ,MAAM,aAAa,CAAC;AACjE,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,uCAAuC,CAAC;AAEtF,OAAO,EAAE,2BAA2B,EAAE,MAAM,0BAA0B,CAAC;AAIvE;;;GAGG;AACH,qBAAa,iCAAkC,SAAQ,2BAA2B;IACjF,OAAO,CAAC,OAAO,CAA2B;IAC1C,OAAO,CAAC,aAAa,CAAgB;gBAGpC,OAAO,EAAE,wBAAwB,EACjC,aAAa,GAAE,aAAkC;IAQlD,SAAS,CAAC,cAAc,IAAI,IAAI;IA4BvB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE;CAexC"}
@@ -5,10 +5,8 @@ import { CollapsibleMessageComponent } from "./collapsible-message.js";
5
5
  import { renderChatFrame } from "./transcript-design.js";
6
6
  import { editorKey } from "./keybinding-hints.js";
7
7
  /**
8
- * Renders a compaction notice in the shared chat-frame style (top rule,
9
- * `• compaction` header, `│ ` body margin) with purple border/label so it
10
- * visually matches the other framed messages (user / assistant / tool
11
- * execution) while standing apart from the conversation flow.
8
+ * Renders a compaction notice as a plain system line ( compaction header,
9
+ * copy-clean body) visually distinct from chat dialog without rule boxes.
12
10
  */
13
11
  export class CompactionSummaryMessageComponent extends CollapsibleMessageComponent {
14
12
  constructor(message, markdownTheme = getMarkdownTheme()) {
@@ -1 +1 @@
1
- {"version":3,"file":"compaction-summary-message.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/compaction-summary-message.ts"],"names":[],"mappings":"AAAA,0IAA0I;AAE1I,OAAO,EAAE,QAAQ,EAAsB,IAAI,EAAE,MAAM,aAAa,CAAC;AAEjE,OAAO,EAAE,gBAAgB,EAAE,KAAK,EAAE,MAAM,qCAAqC,CAAC;AAC9E,OAAO,EAAE,2BAA2B,EAAE,MAAM,0BAA0B,CAAC;AACvE,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAElD;;;;;GAKG;AACH,MAAM,OAAO,iCAAkC,SAAQ,2BAA2B;IAIjF,YACC,OAAiC,EACjC,gBAA+B,gBAAgB,EAAE;QAEjD,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,aAAa,GAAG,aAAa,CAAC;QACnC,IAAI,CAAC,cAAc,EAAE,CAAC;IACvB,CAAC;IAES,cAAc;QACvB,IAAI,CAAC,KAAK,EAAE,CAAC;QAEb,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,cAAc,EAAE,CAAC;QAE5D,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YACnB,MAAM,MAAM,GAAG,oBAAoB,QAAQ,eAAe,CAAC;YAC3D,IAAI,CAAC,QAAQ,CACZ,IAAI,QAAQ,CAAC,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,aAAa,EAAE;gBACrE,KAAK,EAAE,CAAC,IAAY,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,mBAAmB,EAAE,IAAI,CAAC;aAC5D,CAAC,CACF,CAAC;QACH,CAAC;aAAM,CAAC;YACP,IAAI,CAAC,QAAQ,CACZ,IAAI,IAAI,CACP,KAAK,CAAC,EAAE,CACP,mBAAmB,EACnB,kBAAkB,QAAQ,WAAW,CACrC;gBACA,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,SAAS,CAAC,aAAa,CAAC,CAAC;gBACzC,KAAK,CAAC,EAAE,CAAC,mBAAmB,EAAE,aAAa,CAAC,EAC7C,CAAC,EACD,CAAC,CACD,CACD,CAAC;QACH,CAAC;IACF,CAAC;IAEQ,MAAM,CAAC,KAAa;QAC5B,MAAM,MAAM,GAAG,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;QAC3C,IAAI,MAAM;YAAE,OAAO,MAAM,CAAC;QAE1B,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;QACvC,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,UAAU,GAAG,CAAC,CAAC,CAAC;QACjD,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;QACzC,MAAM,MAAM,GAAG,eAAe,CAAC,KAAK,EAAE,UAAU,EAAE;YACjD,KAAK,EAAE,YAAY;YACnB,IAAI,EAAE,YAAY;YAClB,eAAe,EAAE,eAAe;YAChC,aAAa,EAAE,KAAK;SACpB,CAAC,CAAC;QACH,OAAO,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;IAClF,CAAC;CACD","sourcesContent":["// gsd-pi + packages/pi-coding-agent/src/modes/interactive/components/compaction-summary-message.ts - Compaction summary message renderer.\n\nimport { Markdown, type MarkdownTheme, Text } from \"@gsd/pi-tui\";\nimport type { CompactionSummaryMessage } from \"@gsd/pi-coding-agent/core/messages.js\";\nimport { getMarkdownTheme, theme } from \"@gsd/pi-coding-agent/theme/theme.js\";\nimport { CollapsibleMessageComponent } from \"./collapsible-message.js\";\nimport { renderChatFrame } from \"./transcript-design.js\";\nimport { editorKey } from \"./keybinding-hints.js\";\n\n/**\n * Renders a compaction notice in the shared chat-frame style (top rule,\n * `• compaction` header, `│ ` body margin) with purple border/label so it\n * visually matches the other framed messages (user / assistant / tool\n * execution) while standing apart from the conversation flow.\n */\nexport class CompactionSummaryMessageComponent extends CollapsibleMessageComponent {\n\tprivate message: CompactionSummaryMessage;\n\tprivate markdownTheme: MarkdownTheme;\n\n\tconstructor(\n\t\tmessage: CompactionSummaryMessage,\n\t\tmarkdownTheme: MarkdownTheme = getMarkdownTheme(),\n\t) {\n\t\tsuper();\n\t\tthis.message = message;\n\t\tthis.markdownTheme = markdownTheme;\n\t\tthis.rebuildContent();\n\t}\n\n\tprotected rebuildContent(): void {\n\t\tthis.clear();\n\n\t\tconst tokenStr = this.message.tokensBefore.toLocaleString();\n\n\t\tif (this.expanded) {\n\t\t\tconst header = `**Compacted from ${tokenStr} tokens**\\n\\n`;\n\t\t\tthis.addChild(\n\t\t\t\tnew Markdown(header + this.message.summary, 0, 0, this.markdownTheme, {\n\t\t\t\t\tcolor: (text: string) => theme.fg(\"customMessageText\", text),\n\t\t\t\t}),\n\t\t\t);\n\t\t} else {\n\t\t\tthis.addChild(\n\t\t\t\tnew Text(\n\t\t\t\t\ttheme.fg(\n\t\t\t\t\t\t\"customMessageText\",\n\t\t\t\t\t\t`Compacted from ${tokenStr} tokens (`,\n\t\t\t\t\t) +\n\t\t\t\t\t\ttheme.fg(\"dim\", editorKey(\"expandTools\")) +\n\t\t\t\t\t\ttheme.fg(\"customMessageText\", \" to expand)\"),\n\t\t\t\t\t0,\n\t\t\t\t\t0,\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\t}\n\n\toverride render(width: number): string[] {\n\t\tconst cached = this.getCachedRender(width);\n\t\tif (cached) return cached;\n\n\t\tconst frameWidth = Math.max(20, width);\n\t\tconst contentWidth = Math.max(1, frameWidth - 4);\n\t\tconst lines = super.render(contentWidth);\n\t\tconst framed = renderChatFrame(lines, frameWidth, {\n\t\t\tlabel: \"compaction\",\n\t\t\ttone: \"compaction\",\n\t\t\ttimestampFormat: \"date-time-iso\",\n\t\t\tshowTimestamp: false,\n\t\t});\n\t\treturn this.setCachedRender(width, framed.length > 0 ? [\"\", ...framed] : framed);\n\t}\n}\n"]}
1
+ {"version":3,"file":"compaction-summary-message.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/compaction-summary-message.ts"],"names":[],"mappings":"AAAA,0IAA0I;AAE1I,OAAO,EAAE,QAAQ,EAAsB,IAAI,EAAE,MAAM,aAAa,CAAC;AAEjE,OAAO,EAAE,gBAAgB,EAAE,KAAK,EAAE,MAAM,qCAAqC,CAAC;AAC9E,OAAO,EAAE,2BAA2B,EAAE,MAAM,0BAA0B,CAAC;AACvE,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAElD;;;GAGG;AACH,MAAM,OAAO,iCAAkC,SAAQ,2BAA2B;IAIjF,YACC,OAAiC,EACjC,gBAA+B,gBAAgB,EAAE;QAEjD,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,aAAa,GAAG,aAAa,CAAC;QACnC,IAAI,CAAC,cAAc,EAAE,CAAC;IACvB,CAAC;IAES,cAAc;QACvB,IAAI,CAAC,KAAK,EAAE,CAAC;QAEb,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,cAAc,EAAE,CAAC;QAE5D,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YACnB,MAAM,MAAM,GAAG,oBAAoB,QAAQ,eAAe,CAAC;YAC3D,IAAI,CAAC,QAAQ,CACZ,IAAI,QAAQ,CAAC,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,aAAa,EAAE;gBACrE,KAAK,EAAE,CAAC,IAAY,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,mBAAmB,EAAE,IAAI,CAAC;aAC5D,CAAC,CACF,CAAC;QACH,CAAC;aAAM,CAAC;YACP,IAAI,CAAC,QAAQ,CACZ,IAAI,IAAI,CACP,KAAK,CAAC,EAAE,CACP,mBAAmB,EACnB,kBAAkB,QAAQ,WAAW,CACrC;gBACA,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,SAAS,CAAC,aAAa,CAAC,CAAC;gBACzC,KAAK,CAAC,EAAE,CAAC,mBAAmB,EAAE,aAAa,CAAC,EAC7C,CAAC,EACD,CAAC,CACD,CACD,CAAC;QACH,CAAC;IACF,CAAC;IAEQ,MAAM,CAAC,KAAa;QAC5B,MAAM,MAAM,GAAG,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;QAC3C,IAAI,MAAM;YAAE,OAAO,MAAM,CAAC;QAE1B,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;QACvC,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,UAAU,GAAG,CAAC,CAAC,CAAC;QACjD,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;QACzC,MAAM,MAAM,GAAG,eAAe,CAAC,KAAK,EAAE,UAAU,EAAE;YACjD,KAAK,EAAE,YAAY;YACnB,IAAI,EAAE,YAAY;YAClB,eAAe,EAAE,eAAe;YAChC,aAAa,EAAE,KAAK;SACpB,CAAC,CAAC;QACH,OAAO,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;IAClF,CAAC;CACD","sourcesContent":["// gsd-pi + packages/pi-coding-agent/src/modes/interactive/components/compaction-summary-message.ts - Compaction summary message renderer.\n\nimport { Markdown, type MarkdownTheme, Text } from \"@gsd/pi-tui\";\nimport type { CompactionSummaryMessage } from \"@gsd/pi-coding-agent/core/messages.js\";\nimport { getMarkdownTheme, theme } from \"@gsd/pi-coding-agent/theme/theme.js\";\nimport { CollapsibleMessageComponent } from \"./collapsible-message.js\";\nimport { renderChatFrame } from \"./transcript-design.js\";\nimport { editorKey } from \"./keybinding-hints.js\";\n\n/**\n * Renders a compaction notice as a plain system line ( compaction header,\n * copy-clean body) visually distinct from chat dialog without rule boxes.\n */\nexport class CompactionSummaryMessageComponent extends CollapsibleMessageComponent {\n\tprivate message: CompactionSummaryMessage;\n\tprivate markdownTheme: MarkdownTheme;\n\n\tconstructor(\n\t\tmessage: CompactionSummaryMessage,\n\t\tmarkdownTheme: MarkdownTheme = getMarkdownTheme(),\n\t) {\n\t\tsuper();\n\t\tthis.message = message;\n\t\tthis.markdownTheme = markdownTheme;\n\t\tthis.rebuildContent();\n\t}\n\n\tprotected rebuildContent(): void {\n\t\tthis.clear();\n\n\t\tconst tokenStr = this.message.tokensBefore.toLocaleString();\n\n\t\tif (this.expanded) {\n\t\t\tconst header = `**Compacted from ${tokenStr} tokens**\\n\\n`;\n\t\t\tthis.addChild(\n\t\t\t\tnew Markdown(header + this.message.summary, 0, 0, this.markdownTheme, {\n\t\t\t\t\tcolor: (text: string) => theme.fg(\"customMessageText\", text),\n\t\t\t\t}),\n\t\t\t);\n\t\t} else {\n\t\t\tthis.addChild(\n\t\t\t\tnew Text(\n\t\t\t\t\ttheme.fg(\n\t\t\t\t\t\t\"customMessageText\",\n\t\t\t\t\t\t`Compacted from ${tokenStr} tokens (`,\n\t\t\t\t\t) +\n\t\t\t\t\t\ttheme.fg(\"dim\", editorKey(\"expandTools\")) +\n\t\t\t\t\t\ttheme.fg(\"customMessageText\", \" to expand)\"),\n\t\t\t\t\t0,\n\t\t\t\t\t0,\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\t}\n\n\toverride render(width: number): string[] {\n\t\tconst cached = this.getCachedRender(width);\n\t\tif (cached) return cached;\n\n\t\tconst frameWidth = Math.max(20, width);\n\t\tconst contentWidth = Math.max(1, frameWidth - 4);\n\t\tconst lines = super.render(contentWidth);\n\t\tconst framed = renderChatFrame(lines, frameWidth, {\n\t\t\tlabel: \"compaction\",\n\t\t\ttone: \"compaction\",\n\t\t\ttimestampFormat: \"date-time-iso\",\n\t\t\tshowTimestamp: false,\n\t\t});\n\t\treturn this.setCachedRender(width, framed.length > 0 ? [\"\", ...framed] : framed);\n\t}\n}\n"]}
@@ -18,6 +18,8 @@ export declare class CustomEditor extends Editor {
18
18
  * Register a handler for an app action.
19
19
  */
20
20
  onAction(action: AppAction, handler: () => void): void;
21
+ /** Toggle the collapsible GSD status widget above the editor. */
22
+ onToggleGsdStatus?: () => void;
21
23
  handleInput(data: string): void;
22
24
  }
23
25
  //# sourceMappingURL=custom-editor.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"custom-editor.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/custom-editor.ts"],"names":[],"mappings":"AAEA,OAAO,EACN,MAAM,EACN,KAAK,aAAa,EAClB,KAAK,WAAW,EAEhB,KAAK,GAAG,EAGR,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,SAAS,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAErE;;GAEG;AACH,qBAAa,YAAa,SAAQ,MAAM;IACvC,OAAO,CAAC,WAAW,CAAqB;IACjC,cAAc,EAAE,GAAG,CAAC,SAAS,EAAE,MAAM,IAAI,CAAC,CAAa;IAGvD,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IACjC,4DAA4D;IACrD,gBAAgB,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IACrD,2EAA2E;IACpE,mBAAmB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;gBAE3C,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,kBAAkB,EAAE,OAAO,CAAC,EAAE,aAAa;IAKlG;;OAEG;IACH,QAAQ,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,IAAI,GAAG,IAAI;IAItD,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;CAyD/B"}
1
+ {"version":3,"file":"custom-editor.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/custom-editor.ts"],"names":[],"mappings":"AAEA,OAAO,EACN,MAAM,EACN,KAAK,aAAa,EAClB,KAAK,WAAW,EAEhB,KAAK,GAAG,EAGR,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,SAAS,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAErE;;GAEG;AACH,qBAAa,YAAa,SAAQ,MAAM;IACvC,OAAO,CAAC,WAAW,CAAqB;IACjC,cAAc,EAAE,GAAG,CAAC,SAAS,EAAE,MAAM,IAAI,CAAC,CAAa;IAGvD,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IACjC,4DAA4D;IACrD,gBAAgB,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IACrD,2EAA2E;IACpE,mBAAmB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;gBAE3C,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,kBAAkB,EAAE,OAAO,CAAC,EAAE,aAAa;IAKlG;;OAEG;IACH,QAAQ,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,IAAI,GAAG,IAAI;IAItD,iEAAiE;IAC1D,iBAAiB,CAAC,EAAE,MAAM,IAAI,CAAC;IAEtC,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;CA8D/B"}
@@ -20,6 +20,10 @@ export class CustomEditor extends Editor {
20
20
  if (this.onExtensionShortcut?.(data)) {
21
21
  return;
22
22
  }
23
+ if (matchesKey(data, "shift+ctrl+d")) {
24
+ this.onToggleGsdStatus?.();
25
+ return;
26
+ }
23
27
  // Check for paste image keybinding
24
28
  if (this.keybindings.matches(data, "pasteImage")) {
25
29
  this.onPasteImage?.();
@@ -1 +1 @@
1
- {"version":3,"file":"custom-editor.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/custom-editor.ts"],"names":[],"mappings":"AAAA,uHAAuH;AAEvH,OAAO,EACN,MAAM,EAGN,GAAG,EAEH,qBAAqB,EACrB,UAAU,GACV,MAAM,aAAa,CAAC;AAGrB;;GAEG;AACH,MAAM,OAAO,YAAa,SAAQ,MAAM;IAavC,YAAY,GAAQ,EAAE,KAAkB,EAAE,WAA+B,EAAE,OAAuB;QACjG,KAAK,CAAC,GAAG,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;QAZrB,mBAAc,GAA+B,IAAI,GAAG,EAAE,CAAC;QAa7D,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;IAChC,CAAC;IAED;;OAEG;IACH,QAAQ,CAAC,MAAiB,EAAE,OAAmB;QAC9C,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC1C,CAAC;IAED,WAAW,CAAC,IAAY;QACvB,6CAA6C;QAC7C,IAAI,IAAI,CAAC,mBAAmB,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;YACtC,OAAO;QACR,CAAC;QAED,mCAAmC;QACnC,IAAI,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,IAAI,EAAE,YAAY,CAAC,EAAE,CAAC;YAClD,IAAI,CAAC,YAAY,EAAE,EAAE,CAAC;YACtB,OAAO;QACR,CAAC;QAED,8BAA8B;QAE9B,wDAAwD;QACxD,IAAI,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,IAAI,EAAE,WAAW,CAAC,EAAE,CAAC;YACjD,IAAI,CAAC,IAAI,CAAC,qBAAqB,EAAE,EAAE,CAAC;gBACnC,4DAA4D;gBAC5D,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;gBACtE,IAAI,OAAO,EAAE,CAAC;oBACb,OAAO,EAAE,CAAC;oBACV,OAAO;gBACR,CAAC;YACF,CAAC;YACD,yDAAyD;YACzD,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;YACxB,OAAO;QACR,CAAC;QAED,4CAA4C;QAC5C,IAAI,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,CAAC;YAC5C,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACjC,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;gBAChE,IAAI,OAAO;oBAAE,OAAO,EAAE,CAAC;gBACvB,OAAO;YACR,CAAC;YACD,yEAAyE;QAC1E,CAAC;QAED,8BAA8B;QAC9B,KAAK,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;YACrD,IAAI,MAAM,KAAK,WAAW,IAAI,MAAM,KAAK,MAAM,IAAI,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,CAAC;gBAC3F,0DAA0D;gBAC1D,8EAA8E;gBAC9E,kEAAkE;gBAClE,8DAA8D;gBAC9D,IAAI,MAAM,KAAK,UAAU,IAAI,CAAC,qBAAqB,EAAE,IAAI,UAAU,CAAC,IAAI,EAAE,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC;oBAC7F,MAAM,CAAC,mDAAmD;gBAC3D,CAAC;gBACD,OAAO,EAAE,CAAC;gBACV,OAAO;YACR,CAAC;QACF,CAAC;QAED,qCAAqC;QACrC,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;IACzB,CAAC;CACD","sourcesContent":["// gsd-pi + packages/pi-coding-agent/src/modes/interactive/components/custom-editor.ts - App-level editor key handling.\n\nimport {\n\tEditor,\n\ttype EditorOptions,\n\ttype EditorTheme,\n\tKey,\n\ttype TUI,\n\tisKittyProtocolActive,\n\tmatchesKey,\n} from \"@gsd/pi-tui\";\nimport type { AppAction, KeybindingsManager } from \"@gsd/agent-core\";\n\n/**\n * Custom editor that handles app-level keybindings for coding-agent.\n */\nexport class CustomEditor extends Editor {\n\tprivate keybindings: KeybindingsManager;\n\tpublic actionHandlers: Map<AppAction, () => void> = new Map();\n\n\t// Special handlers that can be dynamically replaced\n\tpublic onEscape?: () => void;\n\tpublic onCtrlD?: () => void;\n\tpublic onPasteImage?: () => void;\n\t/** GSD compat alias for filesystem image paste handlers. */\n\tpublic onPasteImagePath?: (filePath: string) => void;\n\t/** Handler for extension-registered shortcuts. Returns true if handled. */\n\tpublic onExtensionShortcut?: (data: string) => boolean;\n\n\tconstructor(tui: TUI, theme: EditorTheme, keybindings: KeybindingsManager, options?: EditorOptions) {\n\t\tsuper(tui, theme, options);\n\t\tthis.keybindings = keybindings;\n\t}\n\n\t/**\n\t * Register a handler for an app action.\n\t */\n\tonAction(action: AppAction, handler: () => void): void {\n\t\tthis.actionHandlers.set(action, handler);\n\t}\n\n\thandleInput(data: string): void {\n\t\t// Check extension-registered shortcuts first\n\t\tif (this.onExtensionShortcut?.(data)) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Check for paste image keybinding\n\t\tif (this.keybindings.matches(data, \"pasteImage\")) {\n\t\t\tthis.onPasteImage?.();\n\t\t\treturn;\n\t\t}\n\n\t\t// Check app keybindings first\n\n\t\t// Escape/interrupt - only if autocomplete is NOT active\n\t\tif (this.keybindings.matches(data, \"interrupt\")) {\n\t\t\tif (!this.isShowingAutocomplete()) {\n\t\t\t\t// Use dynamic onEscape if set, otherwise registered handler\n\t\t\t\tconst handler = this.onEscape ?? this.actionHandlers.get(\"interrupt\");\n\t\t\t\tif (handler) {\n\t\t\t\t\thandler();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Let parent handle escape for autocomplete cancellation\n\t\t\tsuper.handleInput(data);\n\t\t\treturn;\n\t\t}\n\n\t\t// Exit (Ctrl+D) - only when editor is empty\n\t\tif (this.keybindings.matches(data, \"exit\")) {\n\t\t\tif (this.getText().length === 0) {\n\t\t\t\tconst handler = this.onCtrlD ?? this.actionHandlers.get(\"exit\");\n\t\t\t\tif (handler) handler();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// Fall through to editor handling for delete-char-forward when not empty\n\t\t}\n\n\t\t// Check all other app actions\n\t\tfor (const [action, handler] of this.actionHandlers) {\n\t\t\tif (action !== \"interrupt\" && action !== \"exit\" && this.keybindings.matches(data, action)) {\n\t\t\t\t// When kitty protocol is not active, \\x1b\\r is ambiguous:\n\t\t\t\t// it could be alt+enter (followUp) or shift+enter mapped via /terminal-setup.\n\t\t\t\t// Prioritize newLine since that's what terminal-setup configures.\n\t\t\t\t// Alt+enter followUp still works in kitty-protocol terminals.\n\t\t\t\tif (action === \"followUp\" && !isKittyProtocolActive() && matchesKey(data, Key.alt(\"enter\"))) {\n\t\t\t\t\tbreak; // Fall through to parent editor's newLine handling\n\t\t\t\t}\n\t\t\t\thandler();\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\t// Pass to parent for editor handling\n\t\tsuper.handleInput(data);\n\t}\n}\n"]}
1
+ {"version":3,"file":"custom-editor.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/custom-editor.ts"],"names":[],"mappings":"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","sourcesContent":["// gsd-pi + packages/pi-coding-agent/src/modes/interactive/components/custom-editor.ts - App-level editor key handling.\n\nimport {\n\tEditor,\n\ttype EditorOptions,\n\ttype EditorTheme,\n\tKey,\n\ttype TUI,\n\tisKittyProtocolActive,\n\tmatchesKey,\n} from \"@gsd/pi-tui\";\nimport type { AppAction, KeybindingsManager } from \"@gsd/agent-core\";\n\n/**\n * Custom editor that handles app-level keybindings for coding-agent.\n */\nexport class CustomEditor extends Editor {\n\tprivate keybindings: KeybindingsManager;\n\tpublic actionHandlers: Map<AppAction, () => void> = new Map();\n\n\t// Special handlers that can be dynamically replaced\n\tpublic onEscape?: () => void;\n\tpublic onCtrlD?: () => void;\n\tpublic onPasteImage?: () => void;\n\t/** GSD compat alias for filesystem image paste handlers. */\n\tpublic onPasteImagePath?: (filePath: string) => void;\n\t/** Handler for extension-registered shortcuts. Returns true if handled. */\n\tpublic onExtensionShortcut?: (data: string) => boolean;\n\n\tconstructor(tui: TUI, theme: EditorTheme, keybindings: KeybindingsManager, options?: EditorOptions) {\n\t\tsuper(tui, theme, options);\n\t\tthis.keybindings = keybindings;\n\t}\n\n\t/**\n\t * Register a handler for an app action.\n\t */\n\tonAction(action: AppAction, handler: () => void): void {\n\t\tthis.actionHandlers.set(action, handler);\n\t}\n\n\t/** Toggle the collapsible GSD status widget above the editor. */\n\tpublic onToggleGsdStatus?: () => void;\n\n\thandleInput(data: string): void {\n\t\t// Check extension-registered shortcuts first\n\t\tif (this.onExtensionShortcut?.(data)) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (matchesKey(data, \"shift+ctrl+d\")) {\n\t\t\tthis.onToggleGsdStatus?.();\n\t\t\treturn;\n\t\t}\n\n\t\t// Check for paste image keybinding\n\t\tif (this.keybindings.matches(data, \"pasteImage\")) {\n\t\t\tthis.onPasteImage?.();\n\t\t\treturn;\n\t\t}\n\n\t\t// Check app keybindings first\n\n\t\t// Escape/interrupt - only if autocomplete is NOT active\n\t\tif (this.keybindings.matches(data, \"interrupt\")) {\n\t\t\tif (!this.isShowingAutocomplete()) {\n\t\t\t\t// Use dynamic onEscape if set, otherwise registered handler\n\t\t\t\tconst handler = this.onEscape ?? this.actionHandlers.get(\"interrupt\");\n\t\t\t\tif (handler) {\n\t\t\t\t\thandler();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Let parent handle escape for autocomplete cancellation\n\t\t\tsuper.handleInput(data);\n\t\t\treturn;\n\t\t}\n\n\t\t// Exit (Ctrl+D) - only when editor is empty\n\t\tif (this.keybindings.matches(data, \"exit\")) {\n\t\t\tif (this.getText().length === 0) {\n\t\t\t\tconst handler = this.onCtrlD ?? this.actionHandlers.get(\"exit\");\n\t\t\t\tif (handler) handler();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// Fall through to editor handling for delete-char-forward when not empty\n\t\t}\n\n\t\t// Check all other app actions\n\t\tfor (const [action, handler] of this.actionHandlers) {\n\t\t\tif (action !== \"interrupt\" && action !== \"exit\" && this.keybindings.matches(data, action)) {\n\t\t\t\t// When kitty protocol is not active, \\x1b\\r is ambiguous:\n\t\t\t\t// it could be alt+enter (followUp) or shift+enter mapped via /terminal-setup.\n\t\t\t\t// Prioritize newLine since that's what terminal-setup configures.\n\t\t\t\t// Alt+enter followUp still works in kitty-protocol terminals.\n\t\t\t\tif (action === \"followUp\" && !isKittyProtocolActive() && matchesKey(data, Key.alt(\"enter\"))) {\n\t\t\t\t\tbreak; // Fall through to parent editor's newLine handling\n\t\t\t\t}\n\t\t\t\thandler();\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\t// Pass to parent for editor handling\n\t\tsuper.handleInput(data);\n\t}\n}\n"]}
@@ -1,31 +1,28 @@
1
1
  import { type Component } from "@gsd/pi-tui";
2
2
  import type { AgentSession } from "@gsd/agent-core";
3
3
  import type { ReadonlyFooterDataProvider } from "@gsd/pi-coding-agent/core/footer-data-provider.js";
4
+ import type { GsdStatusWidgetState } from "./gsd-status-widget.js";
5
+ /**
6
+ * Abbreviate cwd for the footer — `~` for home and descendants only.
7
+ * @internal Exported for testing only.
8
+ */
9
+ export declare function formatCwdForFooter(cwd: string, home?: string): string;
4
10
  /**
5
11
  * Format a cost value for compact display.
6
- * Uses fewer decimal places for larger amounts.
7
12
  * @internal Exported for testing only.
8
13
  */
9
14
  export declare function formatPromptCost(cost: number): string;
10
15
  /**
11
- * Footer component that shows pwd, token stats, and context usage.
12
- * Computes token/context stats from session, gets git branch and extension statuses from provider.
16
+ * Footer component one minimal status line (branch, model, context, cost).
13
17
  */
14
18
  export declare class FooterComponent implements Component {
15
19
  private session;
16
20
  private footerData;
21
+ private readonly getGsdStatus?;
17
22
  private autoCompactEnabled;
18
- constructor(session: AgentSession, footerData: ReadonlyFooterDataProvider);
23
+ constructor(session: AgentSession, footerData: ReadonlyFooterDataProvider, getGsdStatus?: (() => GsdStatusWidgetState) | undefined);
19
24
  setAutoCompactEnabled(enabled: boolean): void;
20
- /**
21
- * No-op: git branch caching now handled by provider.
22
- * Kept for compatibility with existing call sites in interactive-mode.
23
- */
24
25
  invalidate(): void;
25
- /**
26
- * Clean up resources.
27
- * Git watcher cleanup now handled by provider.
28
- */
29
26
  dispose(): void;
30
27
  render(width: number): string[];
31
28
  }
@@ -1 +1 @@
1
- {"version":3,"file":"footer.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/footer.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,SAAS,EAAiC,MAAM,aAAa,CAAC;AAC5E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,mDAAmD,CAAC;AAuCpG;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAKrD;AAED;;;GAGG;AACH,qBAAa,eAAgB,YAAW,SAAS;IAI/C,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,UAAU;IAJnB,OAAO,CAAC,kBAAkB,CAAQ;gBAGzB,OAAO,EAAE,YAAY,EACrB,UAAU,EAAE,0BAA0B;IAG/C,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAI7C;;;OAGG;IACH,UAAU,IAAI,IAAI;IAIlB;;;OAGG;IACH,OAAO,IAAI,IAAI;IAIf,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE;CAiL/B"}
1
+ {"version":3,"file":"footer.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/footer.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,SAAS,EAAmB,MAAM,aAAa,CAAC;AAC9D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,mDAAmD,CAAC;AASpG,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAuBnE;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,SAAoD,GAAG,MAAM,CAShH;AAgCD;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAKrD;AAED;;GAEG;AACH,qBAAa,eAAgB,YAAW,SAAS;IAI/C,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC;IAL/B,OAAO,CAAC,kBAAkB,CAAQ;gBAGzB,OAAO,EAAE,YAAY,EACrB,UAAU,EAAE,0BAA0B,EAC7B,YAAY,CAAC,GAAE,MAAM,oBAAoB,aAAA;IAG3D,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAI7C,UAAU,IAAI,IAAI;IAElB,OAAO,IAAI,IAAI;IAEf,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE;CAgG/B"}