@iowarp/clio-coder 0.4.5 → 0.4.6

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 (188) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/CONTRIBUTING.md +14 -9
  3. package/NOTICE +16 -0
  4. package/README.md +312 -685
  5. package/dist/{acp-H3CU2HBQ.js → acp-UVEVWSDL.js} +6 -6
  6. package/dist/{agents-IXQQZ7BD.js → agents-VWY37DTK.js} +31 -30
  7. package/dist/assets/codewiki.json +1 -1
  8. package/dist/{auth-R7KYF7N3.js → auth-PCV2XQDV.js} +6 -6
  9. package/dist/{builtins-CRFDQUVP.js → builtins-PD652MTK.js} +3 -3
  10. package/dist/{chunk-SDWNDICN.js → chunk-24T2YZ7A.js} +58 -56
  11. package/dist/{chunk-FSTIBAGM.js → chunk-2AKYFREM.js} +7 -7
  12. package/dist/{chunk-SE4ZKILO.js → chunk-3BJGMT2D.js} +30 -9
  13. package/dist/{chunk-GVYWZNRK.js → chunk-3HQVBIKD.js} +2 -2
  14. package/dist/{chunk-EWD5P3GK.js → chunk-3JLFK5MW.js} +4 -4
  15. package/dist/{chunk-O2RQ7LCK.js → chunk-3O2ZAUGQ.js} +2 -2
  16. package/dist/{chunk-GXCCHKN6.js → chunk-3QKXHCGS.js} +4 -4
  17. package/dist/{chunk-YEJIG7LN.js → chunk-3WBALRQH.js} +7 -7
  18. package/dist/{chunk-I7VLWRK2.js → chunk-4DU2TVI4.js} +5 -5
  19. package/dist/{chunk-TEG3RYVZ.js → chunk-4U4TKZFR.js} +3 -3
  20. package/dist/{chunk-EHCPSZJF.js → chunk-4VMV6OS6.js} +2 -2
  21. package/dist/{chunk-T7FDXNRU.js → chunk-536HXRFE.js} +4 -4
  22. package/dist/{chunk-ZMZQEBKI.js → chunk-5QRX7SLS.js} +8 -8
  23. package/dist/{chunk-RXIOCVBZ.js → chunk-6HAO6X5B.js} +4 -4
  24. package/dist/{chunk-HGSLRG33.js → chunk-6OII3LOK.js} +2 -2
  25. package/dist/{chunk-U2JOLB7O.js → chunk-6RYDAVQT.js} +32 -32
  26. package/dist/{chunk-T53XI6I7.js → chunk-6VRRJT7L.js} +2 -2
  27. package/dist/{chunk-RLTT5GVY.js → chunk-7JSSKXG2.js} +4 -4
  28. package/dist/{chunk-633EXGZA.js → chunk-ACCKVSHU.js} +3 -3
  29. package/dist/{chunk-6SYEGZI3.js → chunk-B3MOMLJ4.js} +2 -2
  30. package/dist/{chunk-UXAC2FX4.js → chunk-BLTEAUCB.js} +3 -3
  31. package/dist/{chunk-DRD2A54W.js → chunk-BT7HGDOX.js} +15 -15
  32. package/dist/{chunk-F34AR6O3.js → chunk-DXLUVUD4.js} +5 -5
  33. package/dist/{chunk-HR3HPQ76.js → chunk-E7RF4KBO.js} +2 -2
  34. package/dist/chunk-EM2WNQS2.js +93 -0
  35. package/dist/{chunk-KYKNBD4Y.js → chunk-F5Z7EWMN.js} +953 -233
  36. package/dist/{chunk-VLPTKCKT.js → chunk-GLYBJ4RQ.js} +3 -3
  37. package/dist/{chunk-KDWLXVMN.js → chunk-HPTJF6DG.js} +16 -39
  38. package/dist/{chunk-6CDNRHWH.js → chunk-HZ2T2YED.js} +2 -2
  39. package/dist/{chunk-UTUNT5QL.js → chunk-HZFBVU5X.js} +7 -7
  40. package/dist/{chunk-KF6GFW6O.js → chunk-I2K2NCZQ.js} +7 -7
  41. package/dist/{chunk-5DDOTTG4.js → chunk-IGLVVNEG.js} +2 -2
  42. package/dist/{chunk-4SVIVOMC.js → chunk-IKRWLEDA.js} +5 -5
  43. package/dist/{chunk-R6MAYTMS.js → chunk-JMPL7NUB.js} +3 -3
  44. package/dist/{chunk-5ZMXGW7P.js → chunk-KAFMW7WM.js} +4 -85
  45. package/dist/{chunk-R6MICQYU.js → chunk-LIN2K3EL.js} +4 -4
  46. package/dist/{chunk-QEQISF75.js → chunk-LK2FN5JY.js} +1 -1
  47. package/dist/{chunk-YYB3MC65.js → chunk-N2OKBREN.js} +2 -2
  48. package/dist/{chunk-XXBQKW32.js → chunk-NNWJYUNO.js} +4 -4
  49. package/dist/{chunk-TZ7MFRG4.js → chunk-P5JMBPDJ.js} +22 -20
  50. package/dist/{chunk-WFKDPU7U.js → chunk-P6M7RKMI.js} +2 -2
  51. package/dist/{chunk-MDU3C27C.js → chunk-PZN2LQY6.js} +5 -5
  52. package/dist/{chunk-S32UQ5GL.js → chunk-Q7NNUHQV.js} +15 -15
  53. package/dist/{chunk-U7VQ4NI4.js → chunk-QCOV5DFY.js} +5 -5
  54. package/dist/{chunk-MC3JSVR6.js → chunk-QJMRYTCX.js} +7 -7
  55. package/dist/{chunk-DIMRLNIC.js → chunk-QNWRHOMF.js} +3 -3
  56. package/dist/{chunk-ILJ7DWGE.js → chunk-QXFBABFJ.js} +4 -4
  57. package/dist/chunk-R2CT5YDO.js +66 -0
  58. package/dist/{chunk-E3BQTQUP.js → chunk-RGZNQ5CT.js} +3 -3
  59. package/dist/{chunk-SBZX6ARC.js → chunk-SXQKNKRA.js} +7 -7
  60. package/dist/{chunk-WLMSOT73.js → chunk-TJFDL26W.js} +3 -3
  61. package/dist/{chunk-EQEJJ53P.js → chunk-VAHLPXPY.js} +2 -2
  62. package/dist/{chunk-7TKWWPD7.js → chunk-VANN3GDP.js} +3 -23
  63. package/dist/{chunk-GNQRWTMY.js → chunk-VHMX7SXF.js} +2 -2
  64. package/dist/{chunk-UL36QJX6.js → chunk-WKUYQBCG.js} +6 -6
  65. package/dist/{chunk-FKIOX6DS.js → chunk-WNGF5AJX.js} +9 -4
  66. package/dist/{chunk-ICO4TQ2F.js → chunk-WV6TDAPN.js} +36 -20
  67. package/dist/{chunk-K6RDB7IA.js → chunk-X3BI7HTV.js} +9 -9
  68. package/dist/{chunk-NY6IWDVU.js → chunk-XWMSPJYN.js} +2 -2
  69. package/dist/{chunk-7HBHHVCK.js → chunk-YPRSNUTC.js} +2 -2
  70. package/dist/{chunk-ONRTXOZY.js → chunk-ZS43Y2FT.js} +2 -2
  71. package/dist/cli/index.js +27 -27
  72. package/dist/{clio-5I2IBFYL.js → clio-QQCMTUZE.js} +6 -6
  73. package/dist/{code-nav-YXIAEZVS.js → code-nav-GUPM6766.js} +8 -8
  74. package/dist/{config-Y2JDJ3JJ.js → config-IIM7YOD3.js} +42 -41
  75. package/dist/{configure-SML6UBZ5.js → configure-4ZM5HWJX.js} +28 -10
  76. package/dist/{context-S2EEC3EJ.js → context-44BZLJ3J.js} +12 -12
  77. package/dist/{context-P5YSEO55.js → context-AIDVQKMW.js} +34 -33
  78. package/dist/{context-QQ53HSGJ.js → context-OL5P3HEP.js} +25 -24
  79. package/dist/{context-clear-TMEQCOTH.js → context-clear-OQV76MYP.js} +34 -33
  80. package/dist/{context-working-set-CNLSQN5K.js → context-working-set-ZUW3EGLS.js} +10 -9
  81. package/dist/{detail-5572VLBO.js → detail-UXPWRANG.js} +35 -34
  82. package/dist/{dispatch-runner-FRHD6P2O.js → dispatch-runner-P3ZW6G77.js} +38 -37
  83. package/dist/{doctor-N3LCM2LG.js → doctor-JJVGPZWT.js} +18 -17
  84. package/dist/{eval-BUU3ZOUZ.js → eval-V2RTN3UH.js} +26 -25
  85. package/dist/{evidence-DTGEN456.js → evidence-35PYWGSO.js} +34 -33
  86. package/dist/{evidence-SQ5DNFEN.js → evidence-CIGGKI6J.js} +36 -35
  87. package/dist/{evolve-IJNUFZDS.js → evolve-33SM3NJP.js} +34 -33
  88. package/dist/{fleet-ZNNVSYFO.js → fleet-LFO7SIPC.js} +62 -61
  89. package/dist/{fleet-commands-5YE7NPJL.js → fleet-commands-RLK72GU3.js} +9 -9
  90. package/dist/fleet-decisions-3SBSCTCW.js +1 -1
  91. package/dist/{fleet-graph-6HHPWF5T.js → fleet-graph-JZIBCGMW.js} +11 -11
  92. package/dist/{fleet-inspect-JEYMGCGC.js → fleet-inspect-2L5YGGZJ.js} +35 -34
  93. package/dist/{fleet-validate-4PM4GDDL.js → fleet-validate-LIAVKDUU.js} +12 -12
  94. package/dist/{fleet-verify-NJDTHTO3.js → fleet-verify-JIK3OQZR.js} +34 -33
  95. package/dist/{fleet-view-UP2BWQQY.js → fleet-view-IWHYGQKK.js} +35 -34
  96. package/dist/{init-S3GZQ5ZF.js → init-NJEDOTQW.js} +46 -45
  97. package/dist/{interop-YOTGXFJM.js → interop-RVCAYECG.js} +4 -4
  98. package/dist/{inventory-K2OZ36YJ.js → inventory-74UL7UHU.js} +35 -34
  99. package/dist/{library-GJI6W6OK.js → library-CTKZA7K3.js} +10 -10
  100. package/dist/{memory-OQOXQGYD.js → memory-I76I5VUH.js} +34 -33
  101. package/dist/{models-3IK2Y5WE.js → models-D4YDIQZQ.js} +19 -18
  102. package/dist/{monitor-FTJLTKCQ.js → monitor-NKVD55HX.js} +40 -39
  103. package/dist/{orchestrator-N47O7SFD.js → orchestrator-I6OATVPK.js} +658 -1092
  104. package/dist/{preload-65U34NG6.js → preload-EJAWJEIO.js} +34 -33
  105. package/dist/{reset-MUVQDLNL.js → reset-4XMQKDNZ.js} +5 -3
  106. package/dist/{resources-LM76COAO.js → resources-TVYVXK3Q.js} +10 -10
  107. package/dist/{run-3VFZQ33N.js → run-OWQNNSJU.js} +61 -60
  108. package/dist/{share-4JUB4BL7.js → share-NPZZMUXG.js} +11 -11
  109. package/dist/{skills-S36AAJHU.js → skills-OXFEAWMT.js} +12 -12
  110. package/dist/{skills-eval-G6T57L7M.js → skills-eval-J5TCKSJA.js} +38 -37
  111. package/dist/{skills-inventory-WLM46PJH.js → skills-inventory-7II4DM57.js} +10 -10
  112. package/dist/{slash-commands-GBARG3Y7.js → slash-commands-MDSDSWYF.js} +26 -25
  113. package/dist/{targets-N5REUETU.js → targets-KILZEOCE.js} +36 -20
  114. package/dist/{tasks-6BVY5YZF.js → tasks-R6P6OV22.js} +7 -7
  115. package/dist/{terminal-lease-57UEOJKS.js → terminal-lease-LZCG2KN3.js} +2 -2
  116. package/dist/{upgrade-4HD5HAIV.js → upgrade-D2OZH6IQ.js} +9 -9
  117. package/dist/{usage-4GWM2WWP.js → usage-PIASNUS4.js} +40 -39
  118. package/dist/{verifiers-GSKWKWVG.js → verifiers-LTHUY2PX.js} +9 -9
  119. package/dist/{verify-3AS3ULCY.js → verify-HYF7KBVE.js} +7 -7
  120. package/dist/{wiki-generate-7BV7XWIY.js → wiki-generate-RK7JQ5NP.js} +51 -50
  121. package/dist/worker/entry.js +41 -39
  122. package/docs/architecture/context-engine.md +1 -1
  123. package/docs/architecture/tui-design.md +45 -30
  124. package/docs/guide/commands-and-modes.md +26 -25
  125. package/docs/guide/configuration-and-targets.md +122 -27
  126. package/docs/guide/configuration-reference.md +9 -4
  127. package/docs/guide/fleet-dispatch.md +1 -6
  128. package/docs/guide/glossary.md +1 -1
  129. package/docs/guide/installation-and-lifecycle.md +44 -11
  130. package/docs/process/development-pipeline.md +1 -1
  131. package/docs/process/documentation-coverage.md +1 -1
  132. package/docs/process/release-cut-checklist.md +18 -6
  133. package/package.json +1 -1
  134. package/src/cli/ask.ts +10 -10
  135. package/src/cli/configure-editor.ts +51 -0
  136. package/src/cli/configure-interop.ts +1 -1
  137. package/src/cli/configure-oauth.ts +1 -1
  138. package/src/cli/configure-onboarding.ts +232 -96
  139. package/src/cli/configure-prompts.ts +76 -0
  140. package/src/cli/configure-quick.ts +274 -0
  141. package/src/cli/configure-target.ts +14 -2
  142. package/src/cli/configure.ts +413 -174
  143. package/src/cli/oauth-manual-input.ts +1 -1
  144. package/src/cli/reset.ts +2 -0
  145. package/src/cli/select.ts +35 -4
  146. package/src/cli/upgrade.ts +2 -2
  147. package/src/core/config.ts +6 -1
  148. package/src/core/defaults.ts +33 -11
  149. package/src/{interactive → core}/external-editor.ts +4 -4
  150. package/src/domains/config/classify.ts +1 -1
  151. package/src/domains/config/keybindings.ts +3 -31
  152. package/src/domains/providers/probe/fingerprint.ts +13 -6
  153. package/src/domains/providers/probe/reasoning.ts +2 -0
  154. package/src/domains/providers/runtimes/common/probe-helpers.ts +23 -7
  155. package/src/domains/providers/runtimes/protocol/anthropic-compat.ts +7 -2
  156. package/src/domains/providers/runtimes/protocol/openai-compat.ts +10 -4
  157. package/src/interactive/application-controller.ts +1 -31
  158. package/src/interactive/chat-panel.ts +163 -637
  159. package/src/interactive/chat-renderer.ts +13 -30
  160. package/src/interactive/dispatch-board.ts +1 -3
  161. package/src/interactive/editor-submit.ts +8 -31
  162. package/src/interactive/footer/dashboard.ts +8 -3
  163. package/src/interactive/footer/widgets.ts +50 -91
  164. package/src/interactive/interactive-application.ts +16 -42
  165. package/src/interactive/interactive-event-projection.ts +2 -44
  166. package/src/interactive/interactive-input-runtime.ts +3 -28
  167. package/src/interactive/interactive-presentation.ts +30 -9
  168. package/src/interactive/interactive-slash-runtime.ts +3 -40
  169. package/src/interactive/layout.ts +29 -4
  170. package/src/interactive/overlay-general-openers.ts +2 -0
  171. package/src/interactive/overlay-lifecycle.ts +1 -0
  172. package/src/interactive/overlay-session-lifecycle.ts +1 -1
  173. package/src/interactive/overlays/settings.ts +9 -8
  174. package/src/interactive/renderers/preview.ts +16 -0
  175. package/src/interactive/renderers/tool-execution.ts +67 -160
  176. package/src/interactive/renderers/worker-entry.ts +57 -41
  177. package/src/interactive/slash-autocomplete.ts +1 -6
  178. package/src/interactive/slash-commands.ts +7 -39
  179. package/src/interactive/status/controller.ts +0 -5
  180. package/src/interactive/status/state-machine.ts +44 -26
  181. package/src/interactive/status/types.ts +3 -0
  182. package/src/interactive/status/verbs.ts +13 -12
  183. package/src/interactive/transcript-detail.ts +50 -112
  184. package/src/interactive/view/artifacts.ts +4 -0
  185. package/src/interactive/view/view-overlay.ts +44 -34
  186. package/src/tools/presentation.ts +1 -1
  187. package/src/tools/registry.ts +1 -1
  188. package/src/tools/verify/numeric.ts +4 -4
@@ -33,15 +33,15 @@ import {
33
33
  toolNamesFromAgentState,
34
34
  toolResultSummary,
35
35
  toolSignatureFromState
36
- } from "./chunk-UTUNT5QL.js";
36
+ } from "./chunk-HZFBVU5X.js";
37
37
  import {
38
38
  ShareDomainModule
39
- } from "./chunk-UL36QJX6.js";
39
+ } from "./chunk-WKUYQBCG.js";
40
40
  import {
41
41
  bootstrapInputFromInitOptions,
42
42
  modelBootstrapGenerate,
43
43
  resolveBootstrapRoute
44
- } from "./chunk-S32UQ5GL.js";
44
+ } from "./chunk-Q7NNUHQV.js";
45
45
  import {
46
46
  DEFAULT_KEEP_RECENT_TOKENS,
47
47
  DEFAULT_RESERVE_TOKENS,
@@ -58,7 +58,7 @@ import {
58
58
  SchedulingDomainModule,
59
59
  createPromptsDomainModule,
60
60
  renderAgentCatalogSectionsFromSpecs
61
- } from "./chunk-DIMRLNIC.js";
61
+ } from "./chunk-QNWRHOMF.js";
62
62
  import {
63
63
  PROMPT_MANIFEST_VERSION,
64
64
  appendPromptCompileRecord,
@@ -68,7 +68,7 @@ import {
68
68
  } from "./chunk-5ZSZEYJK.js";
69
69
  import {
70
70
  recordFailedCompactionCalls
71
- } from "./chunk-EHCPSZJF.js";
71
+ } from "./chunk-4VMV6OS6.js";
72
72
  import {
73
73
  describePanesLeftBehind,
74
74
  paneWatchDecision
@@ -83,15 +83,15 @@ import {
83
83
  import {
84
84
  LifecycleDomainModule,
85
85
  describeUpgradeNotice
86
- } from "./chunk-R6MICQYU.js";
87
- import "./chunk-EWD5P3GK.js";
88
- import "./chunk-GVYWZNRK.js";
86
+ } from "./chunk-LIN2K3EL.js";
87
+ import "./chunk-3JLFK5MW.js";
88
+ import "./chunk-3HQVBIKD.js";
89
89
  import {
90
90
  ConfigDomainModule,
91
91
  createConfigDomainModule,
92
92
  loadDomains
93
- } from "./chunk-ILJ7DWGE.js";
94
- import "./chunk-YYB3MC65.js";
93
+ } from "./chunk-QXFBABFJ.js";
94
+ import "./chunk-N2OKBREN.js";
95
95
  import {
96
96
  buildRecallFields,
97
97
  recallErrorMessage,
@@ -107,18 +107,18 @@ import {
107
107
  } from "./chunk-DBREN25X.js";
108
108
  import {
109
109
  compileScoutTransition
110
- } from "./chunk-WFKDPU7U.js";
110
+ } from "./chunk-P6M7RKMI.js";
111
111
  import {
112
112
  monitorToolSurface
113
113
  } from "./chunk-NF3BK5WR.js";
114
114
  import {
115
115
  ObservabilityDomainModule,
116
116
  recordBackgroundMemoryStep
117
- } from "./chunk-FSTIBAGM.js";
117
+ } from "./chunk-2AKYFREM.js";
118
118
  import {
119
119
  appendOutOfTurnUsageRow,
120
120
  readAccountabilitySummary
121
- } from "./chunk-HR3HPQ76.js";
121
+ } from "./chunk-E7RF4KBO.js";
122
122
  import {
123
123
  steerToolSurface
124
124
  } from "./chunk-URBGEOH3.js";
@@ -142,10 +142,10 @@ import {
142
142
  workerAskedByModel,
143
143
  workerReceiptSummary,
144
144
  workerTargetLabel
145
- } from "./chunk-KDWLXVMN.js";
145
+ } from "./chunk-HPTJF6DG.js";
146
146
  import {
147
147
  boundSettledText
148
- } from "./chunk-O2RQ7LCK.js";
148
+ } from "./chunk-3O2ZAUGQ.js";
149
149
  import "./chunk-QUIJZSDW.js";
150
150
  import {
151
151
  classifyLibraryRequirements,
@@ -157,25 +157,25 @@ import {
157
157
  libraryEntryRef,
158
158
  libraryInstallPath,
159
159
  planLibraryInstall
160
- } from "./chunk-U7VQ4NI4.js";
160
+ } from "./chunk-QCOV5DFY.js";
161
161
  import {
162
162
  AgentsDomainModule
163
- } from "./chunk-NY6IWDVU.js";
164
- import "./chunk-EQEJJ53P.js";
163
+ } from "./chunk-XWMSPJYN.js";
164
+ import "./chunk-VAHLPXPY.js";
165
165
  import "./chunk-3UW3KU4A.js";
166
166
  import {
167
167
  createUserTasksStore,
168
168
  formatUserTaskHandoff
169
- } from "./chunk-VLPTKCKT.js";
169
+ } from "./chunk-GLYBJ4RQ.js";
170
170
  import "./chunk-QRFXEO6Y.js";
171
171
  import {
172
172
  ToolchainDomainModule
173
173
  } from "./chunk-32KJPXAM.js";
174
- import "./chunk-K6RDB7IA.js";
174
+ import "./chunk-X3BI7HTV.js";
175
175
  import {
176
176
  ensureClioState,
177
177
  takeUpgradeNotice
178
- } from "./chunk-E3BQTQUP.js";
178
+ } from "./chunk-RGZNQ5CT.js";
179
179
  import "./chunk-T334FW2H.js";
180
180
  import "./chunk-LZBMXNLP.js";
181
181
  import {
@@ -183,18 +183,22 @@ import {
183
183
  discoverMarketplaceSkills,
184
184
  installSkill,
185
185
  modelVisibleSkills
186
- } from "./chunk-T7FDXNRU.js";
186
+ } from "./chunk-536HXRFE.js";
187
187
  import "./chunk-DNCE23JJ.js";
188
188
  import "./chunk-U7H5WRG5.js";
189
189
  import "./chunk-5GZICIYO.js";
190
- import "./chunk-MC3JSVR6.js";
190
+ import {
191
+ editTextExternally,
192
+ resolveExternalEditor
193
+ } from "./chunk-R2CT5YDO.js";
194
+ import "./chunk-QJMRYTCX.js";
191
195
  import {
192
196
  INHERITED_PROJECT_CONTEXT,
193
197
  InteropDomainModule,
194
198
  delegationEntryForKind,
195
199
  renderProposalEntry
196
- } from "./chunk-6SYEGZI3.js";
197
- import "./chunk-T53XI6I7.js";
200
+ } from "./chunk-B3MOMLJ4.js";
201
+ import "./chunk-6VRRJT7L.js";
198
202
  import {
199
203
  ClioEditor,
200
204
  CombinedAutocompleteProvider,
@@ -267,7 +271,7 @@ import {
267
271
  visibleWidth,
268
272
  wrapTextWithAnsi,
269
273
  writeInputWedgeDump
270
- } from "./chunk-7TKWWPD7.js";
274
+ } from "./chunk-VANN3GDP.js";
271
275
  import {
272
276
  getTerminationCoordinator
273
277
  } from "./chunk-BS4GAMUB.js";
@@ -318,7 +322,7 @@ import {
318
322
  taskMemoryBankSize,
319
323
  taskMemoryHandoffSeedOffer,
320
324
  taskMemoryTracePath
321
- } from "./chunk-SDWNDICN.js";
325
+ } from "./chunk-24T2YZ7A.js";
322
326
  import "./chunk-PECBKCDK.js";
323
327
  import {
324
328
  readGateDecisionArtifacts,
@@ -331,17 +335,12 @@ import {
331
335
  isGitRepository,
332
336
  preflightWriteBoundaries,
333
337
  recoverCleanupReadyCompeteGroups
334
- } from "./chunk-GNQRWTMY.js";
338
+ } from "./chunk-VHMX7SXF.js";
335
339
  import {
336
340
  bindExecutionPlanEndpoints,
337
341
  compileFleetExecutionPlan,
338
342
  requireAgentSteps
339
- } from "./chunk-ONRTXOZY.js";
340
- import {
341
- SafetyDomainModule,
342
- parseRigorOverride,
343
- resolveRigor
344
- } from "./chunk-WLMSOT73.js";
343
+ } from "./chunk-ZS43Y2FT.js";
345
344
  import {
346
345
  TRUST_STATUS_AXES,
347
346
  formatTrustSummaryLine,
@@ -352,7 +351,7 @@ import {
352
351
  retiredReceiptIntegrityReason,
353
352
  trustStateWord,
354
353
  verifyReceiptIntegrity
355
- } from "./chunk-6CDNRHWH.js";
354
+ } from "./chunk-HZ2T2YED.js";
356
355
  import {
357
356
  SessionDomainModule,
358
357
  addResponseModelIdObservationCount,
@@ -366,7 +365,7 @@ import {
366
365
  readAuditRows,
367
366
  responseModelIdObservationCountsLabel,
368
367
  responseModelIdObservationFromRecord
369
- } from "./chunk-F34AR6O3.js";
368
+ } from "./chunk-DXLUVUD4.js";
370
369
  import "./chunk-U44YYLVV.js";
371
370
  import {
372
371
  configureRunEventJournal
@@ -389,7 +388,7 @@ import {
389
388
  createDecisionBoardStore,
390
389
  decisionRationale,
391
390
  foldDecisionBoard
392
- } from "./chunk-5DDOTTG4.js";
391
+ } from "./chunk-IGLVVNEG.js";
393
392
  import {
394
393
  FLEET_COMMANDS_REMEDY,
395
394
  FleetCommandRegistryMissingError,
@@ -399,16 +398,12 @@ import {
399
398
  renderFleetPrompt,
400
399
  validateFleetCommands,
401
400
  validateFleetGraph
402
- } from "./chunk-YEJIG7LN.js";
401
+ } from "./chunk-3WBALRQH.js";
403
402
  import "./chunk-CXQ37WJH.js";
404
403
  import {
405
404
  discoverDeclaredChecks
406
- } from "./chunk-HGSLRG33.js";
405
+ } from "./chunk-6OII3LOK.js";
407
406
  import "./chunk-7YJWEF2L.js";
408
- import {
409
- shellQuote
410
- } from "./chunk-SD7SHNDW.js";
411
- import "./chunk-T52TPHYC.js";
412
407
  import {
413
408
  foldPromptCacheTelemetry,
414
409
  hasPromptCacheTelemetry,
@@ -420,6 +415,13 @@ import {
420
415
  ExtensionsDomainModule
421
416
  } from "./chunk-22PQ4TX4.js";
422
417
  import "./chunk-DZK63TZJ.js";
418
+ import {
419
+ SafetyDomainModule,
420
+ parseRigorOverride,
421
+ resolveRigor
422
+ } from "./chunk-TJFDL26W.js";
423
+ import "./chunk-SD7SHNDW.js";
424
+ import "./chunk-T52TPHYC.js";
423
425
  import {
424
426
  emptyWorkspaceSnapshot,
425
427
  probeGitStatusAsync,
@@ -452,7 +454,7 @@ import {
452
454
  resolveSessionTools,
453
455
  sanitizeLockedSynthesisMessage,
454
456
  stripBom
455
- } from "./chunk-U2JOLB7O.js";
457
+ } from "./chunk-6RYDAVQT.js";
456
458
  import {
457
459
  resolveFdBinary
458
460
  } from "./chunk-JABWPKFY.js";
@@ -477,9 +479,9 @@ import {
477
479
  openDetachedBatchViews,
478
480
  watchdogBriefing,
479
481
  writeMiddlewareDiagnosticToStderr
480
- } from "./chunk-DRD2A54W.js";
482
+ } from "./chunk-BT7HGDOX.js";
481
483
  import "./chunk-BBV5TKE6.js";
482
- import "./chunk-GXCCHKN6.js";
484
+ import "./chunk-3QKXHCGS.js";
483
485
  import "./chunk-PWWSIB2A.js";
484
486
  import "./chunk-KTFSFCVN.js";
485
487
  import "./chunk-XCUDZQLX.js";
@@ -529,12 +531,7 @@ import {
529
531
  timeoutMsArg,
530
532
  toolPresentationPolicy,
531
533
  withResolvedDispatchPlan
532
- } from "./chunk-TZ7MFRG4.js";
533
- import {
534
- DEFAULT_RECENT_ENTRY_LIMIT,
535
- assessFinishContract,
536
- recentEntries
537
- } from "./chunk-KF6GFW6O.js";
534
+ } from "./chunk-P5JMBPDJ.js";
538
535
  import {
539
536
  defaultRoutingIntent
540
537
  } from "./chunk-K2HL3GBL.js";
@@ -543,7 +540,7 @@ import {
543
540
  foldSessionTaskHistory,
544
541
  foldTaskBoard,
545
542
  taskBoardCounts
546
- } from "./chunk-7HBHHVCK.js";
543
+ } from "./chunk-YPRSNUTC.js";
547
544
  import {
548
545
  describeCallTarget,
549
546
  sanitizeCallTargetText,
@@ -561,15 +558,10 @@ import {
561
558
  sweepExpiredToolOffloads,
562
559
  toolResultPresentationPolicy,
563
560
  toolResultPresentationText
564
- } from "./chunk-RLTT5GVY.js";
561
+ } from "./chunk-7JSSKXG2.js";
565
562
  import {
566
563
  formatSize
567
564
  } from "./chunk-KECNXMDE.js";
568
- import "./chunk-4SVIVOMC.js";
569
- import {
570
- captureProjectSurface,
571
- projectSurfaceTrustNotice
572
- } from "./chunk-NTK3WTHM.js";
573
565
  import "./chunk-WXA2CFJO.js";
574
566
  import {
575
567
  TOOL_PROFILE_NAMES
@@ -588,31 +580,17 @@ import {
588
580
  parseVerifierResult,
589
581
  resultContractSourceId
590
582
  } from "./chunk-OQM5IVJY.js";
591
- import "./chunk-LUL5Z66S.js";
592
- import {
593
- toolMutationPaths
594
- } from "./chunk-M6TAYK66.js";
595
- import {
596
- canonicalizeExistingPath
597
- } from "./chunk-KQ6IDQIB.js";
598
583
  import {
599
584
  narrowDispatchIntentToReadOnly,
600
585
  normalizeDispatchIntent
601
586
  } from "./chunk-L4N3DWNW.js";
602
587
  import "./chunk-WJIMKGD6.js";
603
- import "./chunk-MDU3C27C.js";
604
- import "./chunk-R2P2U3ZS.js";
605
- import "./chunk-NTTS3O53.js";
606
- import {
607
- VERIFICATION_SCRIPT_FAMILY_HINT
608
- } from "./chunk-M4KFUXS7.js";
609
588
  import {
610
589
  typebox_exports
611
590
  } from "./chunk-GH5ZR6JP.js";
612
591
  import "./chunk-VQD7NH7Z.js";
613
592
  import "./chunk-O3VV6IVK.js";
614
593
  import {
615
- DEFAULT_AUTONOMY_LEVEL,
616
594
  SKILL_CONTEXT_STATE,
617
595
  SKILL_SUGGESTION_PREFIX,
618
596
  armedSkillSurface,
@@ -620,19 +598,23 @@ import {
620
598
  isSkillActivation,
621
599
  latestSkillContextState,
622
600
  mainSkillContextState,
623
- modelMayActivateSkills,
624
601
  skillActivationFromToolDetails,
625
602
  skillContextContentHash,
626
603
  skillSurfaceLabels,
627
604
  skillSurfaceNames,
628
605
  verifiedSkillContextCheckpoint,
629
606
  withModelSkillActivation
630
- } from "./chunk-5ZMXGW7P.js";
631
- import "./chunk-B6UM3OZC.js";
632
- import "./chunk-MYI32N4R.js";
607
+ } from "./chunk-KAFMW7WM.js";
633
608
  import {
634
- ToolNames
635
- } from "./chunk-EHOSNVVM.js";
609
+ DEFAULT_RECENT_ENTRY_LIMIT,
610
+ assessFinishContract,
611
+ recentEntries
612
+ } from "./chunk-I2K2NCZQ.js";
613
+ import "./chunk-IKRWLEDA.js";
614
+ import {
615
+ captureProjectSurface,
616
+ projectSurfaceTrustNotice
617
+ } from "./chunk-NTK3WTHM.js";
636
618
  import {
637
619
  ProvidersDomainModule,
638
620
  applyModelCapabilityPatch,
@@ -666,7 +648,7 @@ import {
666
648
  thinkingLevelChoiceLabel,
667
649
  thinkingLevelFromChoiceLabel,
668
650
  withRunOverrides
669
- } from "./chunk-TEG3RYVZ.js";
651
+ } from "./chunk-4U4TKZFR.js";
670
652
  import "./chunk-MCJKEGHO.js";
671
653
  import {
672
654
  AutoCompactionTrigger,
@@ -688,7 +670,24 @@ import {
688
670
  shouldCompact,
689
671
  snapshotInputTokens
690
672
  } from "./chunk-77CZRFTE.js";
673
+ import "./chunk-LUL5Z66S.js";
674
+ import {
675
+ toolMutationPaths
676
+ } from "./chunk-M6TAYK66.js";
677
+ import {
678
+ canonicalizeExistingPath
679
+ } from "./chunk-KQ6IDQIB.js";
680
+ import "./chunk-PZN2LQY6.js";
681
+ import "./chunk-R2P2U3ZS.js";
682
+ import "./chunk-NTTS3O53.js";
683
+ import {
684
+ VERIFICATION_SCRIPT_FAMILY_HINT
685
+ } from "./chunk-M4KFUXS7.js";
691
686
  import "./chunk-J2FYEQ5L.js";
687
+ import {
688
+ DEFAULT_AUTONOMY_LEVEL,
689
+ modelMayActivateSkills
690
+ } from "./chunk-EM2WNQS2.js";
692
691
  import {
693
692
  SETTINGS_V1_PATH_MOVES,
694
693
  bindAgentProfileInSettings,
@@ -698,7 +697,7 @@ import {
698
697
  setFleetProfileInSettings,
699
698
  updateSettings,
700
699
  useTargetInSettings
701
- } from "./chunk-FKIOX6DS.js";
700
+ } from "./chunk-WNGF5AJX.js";
702
701
  import "./chunk-DVNAPPXU.js";
703
702
  import {
704
703
  interopAgentKind
@@ -712,6 +711,11 @@ import {
712
711
  sessionPaths
713
712
  } from "./chunk-FQOOGXBH.js";
714
713
  import "./chunk-UHW5V7HC.js";
714
+ import "./chunk-B6UM3OZC.js";
715
+ import "./chunk-MYI32N4R.js";
716
+ import {
717
+ ToolNames
718
+ } from "./chunk-EHOSNVVM.js";
715
719
  import "./chunk-KMF54VH3.js";
716
720
  import {
717
721
  combineBashOutput,
@@ -753,14 +757,15 @@ import {
753
757
  VALID_THINKING_LEVELS,
754
758
  formatContextWindowSlots,
755
759
  registerBuiltinRuntimes
756
- } from "./chunk-ICO4TQ2F.js";
760
+ } from "./chunk-WV6TDAPN.js";
757
761
  import {
758
762
  ACTIVE_ROUTING_POSTURES,
759
763
  ACTIVE_ROUTING_ROLES,
760
764
  DEFAULT_DELEGATION_PERMISSION_TIMEOUT_MS,
761
765
  DEFAULT_SETTINGS,
762
- THINKING_LEVELS
763
- } from "./chunk-SE4ZKILO.js";
766
+ THINKING_LEVELS,
767
+ nextOutputStyle
768
+ } from "./chunk-3BJGMT2D.js";
764
769
  import "./chunk-U2MSJ57E.js";
765
770
  import {
766
771
  configureGuardrails,
@@ -818,9 +823,9 @@ import {
818
823
 
819
824
  // src/entry/orchestrator.ts
820
825
  init_esm_shims();
821
- import { randomUUID as randomUUID3 } from "node:crypto";
822
- import { readFileSync as readFileSync8 } from "node:fs";
823
- import { join as join10 } from "node:path";
826
+ import { randomUUID as randomUUID2 } from "node:crypto";
827
+ import { readFileSync as readFileSync7 } from "node:fs";
828
+ import { join as join9 } from "node:path";
824
829
 
825
830
  // src/cli/modes/print.ts
826
831
  init_esm_shims();
@@ -2024,18 +2029,18 @@ function captureSkillContext(entries, selection) {
2024
2029
  const payload = payloadObject2(resultEntry.payload);
2025
2030
  const result = payloadObject2(payload?.result);
2026
2031
  const details = payloadObject2(result?.details);
2027
- const observation = payloadObject2(details?.observation);
2032
+ const observation2 = payloadObject2(details?.observation);
2028
2033
  const resultSummary = payloadObject2(payload?.resultSummary);
2029
2034
  const summaryObservation = payloadObject2(resultSummary?.observation);
2030
2035
  const sourceInfo = payloadObject2(details?.sourceInfo);
2031
- if (payload?.toolName !== "context" || payload.isError !== false || payload.outcome !== "ok" || details?.kind !== "ok" || observation?.truncated !== false || details.workingSet !== void 0 || details.contextCompaction !== void 0 || resultSummary?.truncated !== false || summaryObservation?.truncated === true || details.name !== activation.name || details.path !== activation.filePath || details.hash !== activation.hash || details.source !== activation.source || details.sourceOrigin !== activation.sourceOrigin || sourceInfo?.path !== activation.filePath || sourceInfo.scope !== details.scope || sourceInfo.source !== activation.sourceOrigin || details.drift !== void 0 && details.drift !== "match" || details.drift !== activation.drift || !Array.isArray(result?.content) || !result.content.every((block) => {
2036
+ if (payload?.toolName !== "context" || payload.isError !== false || payload.outcome !== "ok" || details?.kind !== "ok" || observation2?.truncated !== false || details.workingSet !== void 0 || details.contextCompaction !== void 0 || resultSummary?.truncated !== false || summaryObservation?.truncated === true || details.name !== activation.name || details.path !== activation.filePath || details.hash !== activation.hash || details.source !== activation.source || details.sourceOrigin !== activation.sourceOrigin || sourceInfo?.path !== activation.filePath || sourceInfo.scope !== details.scope || sourceInfo.source !== activation.sourceOrigin || details.drift !== void 0 && details.drift !== "match" || details.drift !== activation.drift || !Array.isArray(result?.content) || !result.content.every((block) => {
2032
2037
  const obj = payloadObject2(block);
2033
2038
  return obj?.type === "text" && typeof obj.text === "string";
2034
2039
  }))
2035
2040
  return void 0;
2036
2041
  const content = result.content;
2037
2042
  const text = content.map((block) => block.text).join("\n");
2038
- if (observation.shownBytes !== Buffer.byteLength(text, "utf8") || observation.totalBytes !== observation.shownBytes || resultSummary?.bytes !== observation.shownBytes)
2043
+ if (observation2.shownBytes !== Buffer.byteLength(text, "utf8") || observation2.totalBytes !== observation2.shownBytes || resultSummary?.bytes !== observation2.shownBytes)
2039
2044
  return void 0;
2040
2045
  const requestPayload = payloadObject2(request.payload);
2041
2046
  const operatorText = requestPayload?.operatorText;
@@ -5407,6 +5412,63 @@ function formatRetryStatus(status) {
5407
5412
  // src/interactive/renderers/tool-execution.ts
5408
5413
  init_esm_shims();
5409
5414
 
5415
+ // src/interactive/transcript-detail.ts
5416
+ init_esm_shims();
5417
+ var POLICIES = {
5418
+ compact: {
5419
+ style: "compact",
5420
+ reasoningRows: 0,
5421
+ resultRows: 0,
5422
+ bashRows: 0,
5423
+ operatorBashRows: 3,
5424
+ diffRows: 0,
5425
+ workerRows: 0,
5426
+ workerActivity: false,
5427
+ errorRows: 4,
5428
+ receipt: "none"
5429
+ },
5430
+ standard: {
5431
+ style: "standard",
5432
+ reasoningRows: 3,
5433
+ resultRows: 0,
5434
+ bashRows: 0,
5435
+ operatorBashRows: 6,
5436
+ diffRows: 8,
5437
+ workerRows: 3,
5438
+ workerActivity: false,
5439
+ errorRows: 4,
5440
+ receipt: "compact"
5441
+ },
5442
+ detailed: {
5443
+ style: "detailed",
5444
+ reasoningRows: 12,
5445
+ resultRows: 8,
5446
+ bashRows: 12,
5447
+ operatorBashRows: 12,
5448
+ diffRows: 20,
5449
+ workerRows: 8,
5450
+ workerActivity: true,
5451
+ errorRows: 12,
5452
+ receipt: "full"
5453
+ }
5454
+ };
5455
+ function transcriptDetail(style = "standard") {
5456
+ return POLICIES[style];
5457
+ }
5458
+
5459
+ // src/interactive/renderers/preview.ts
5460
+ init_esm_shims();
5461
+ function previewRows(rows, limit, width, tail = false) {
5462
+ if (rows.length <= limit) return [...rows];
5463
+ if (limit <= 0) return [];
5464
+ const count2 = Math.max(0, limit - 1);
5465
+ const hint = clioTheme().fg("dim", truncateToWidth(`\u2026 ${rows.length - count2} rows \xB7 /view`, Math.max(1, width)));
5466
+ return tail ? [hint, ...rows.slice(rows.length - count2)] : [...rows.slice(0, count2), hint];
5467
+ }
5468
+ function previewBudget(limit, terminalRows = 40) {
5469
+ return Math.min(limit, Math.max(2, Math.floor((terminalRows - 8) / 2)));
5470
+ }
5471
+
5410
5472
  // src/interactive/mutation-preview.ts
5411
5473
  init_esm_shims();
5412
5474
  import { createHash as createHash2 } from "node:crypto";
@@ -5755,9 +5817,7 @@ var ARG_PREVIEW_LIMIT = 60;
5755
5817
  var WEB_FETCH_ARG_PREVIEW_LIMIT = 140;
5756
5818
  var FULL_RESULT_PREVIEW_LIMIT = 6e4;
5757
5819
  var FULL_RESULT_ROW_LIMIT = 120;
5758
- var STREAMING_RESULT_ROW_LIMIT = 20;
5759
5820
  var ARGS_BODY_LINE_LIMIT = 24;
5760
- var FOLDED_DIFF_ROW_LIMIT = 24;
5761
5821
  var STATUS_OK_GLYPH = GLYPH.ok;
5762
5822
  var STATUS_ERROR_GLYPH = GLYPH.error;
5763
5823
  var RAIL_DIM = dim(BODY_INDENT_PLAIN);
@@ -5879,28 +5939,28 @@ function stringField2(record2, key) {
5879
5939
  const value = record2?.[key];
5880
5940
  return typeof value === "string" && value.length > 0 ? value : null;
5881
5941
  }
5882
- function countSummary(observation) {
5883
- const unit = stringField2(observation, "unit") ?? "results";
5884
- const shown = numberField(observation, "shownCount");
5942
+ function countSummary(observation2) {
5943
+ const unit = stringField2(observation2, "unit") ?? "results";
5944
+ const shown = numberField(observation2, "shownCount");
5885
5945
  if (shown === null) return null;
5886
- const total = numberField(observation, "totalCount");
5946
+ const total = numberField(observation2, "totalCount");
5887
5947
  if (total === null) return `${shown}+ ${unit}`;
5888
5948
  if (total === shown) return `${shown} ${unit}`;
5889
5949
  return `${shown}/${total} ${unit}`;
5890
5950
  }
5891
5951
  function outcomeSummary(finished) {
5892
- const observation = observationOf(finished);
5893
- if (observation !== null) {
5952
+ const observation2 = observationOf(finished);
5953
+ if (observation2 !== null) {
5894
5954
  if (finished.toolName === "read") {
5895
- const shown = numberField(observation, "shownCount");
5896
- const total = numberField(observation, "totalCount");
5955
+ const shown = numberField(observation2, "shownCount");
5956
+ const total = numberField(observation2, "totalCount");
5897
5957
  if (shown !== null && total !== null) {
5898
5958
  const offsetRaw = isPlainObject(finished.args) ? finished.args.offset : void 0;
5899
5959
  const start = typeof offsetRaw === "number" && offsetRaw > 0 ? Math.floor(offsetRaw) : 1;
5900
5960
  return shown > 0 ? `lines ${start}-${start + shown - 1} of ${total}` : `0 of ${total} lines`;
5901
5961
  }
5902
5962
  }
5903
- return countSummary(observation);
5963
+ return countSummary(observation2);
5904
5964
  }
5905
5965
  const details = detailsOf(finished.result);
5906
5966
  if (finished.toolName === "git" || finished.toolName === "verify") {
@@ -5945,8 +6005,8 @@ function outcomeSummary(finished) {
5945
6005
  return null;
5946
6006
  }
5947
6007
  function offloadPathOf(finished) {
5948
- const observation = observationOf(finished);
5949
- const fromObservation = stringField2(observation, "offloadPath");
6008
+ const observation2 = observationOf(finished);
6009
+ const fromObservation = stringField2(observation2, "offloadPath");
5950
6010
  if (fromObservation !== null) return fromObservation;
5951
6011
  const summary = finished.resultSummary ?? null;
5952
6012
  const fromSummary = stringField2(summary, "offloadPath");
@@ -5958,8 +6018,8 @@ function offloadFileMissing(finished) {
5958
6018
  return finished.resultSummary?.offloadFileMissing === true;
5959
6019
  }
5960
6020
  function shownBytesOf(finished) {
5961
- const observation = observationOf(finished);
5962
- const fromObservation = numberField(observation, "shownBytes");
6021
+ const observation2 = observationOf(finished);
6022
+ const fromObservation = numberField(observation2, "shownBytes");
5963
6023
  if (fromObservation !== null) return fromObservation;
5964
6024
  const resultSize = detailsOf(finished.result)?.resultSize;
5965
6025
  const fromResultSize = isPlainObject(resultSize) ? numberField(resultSize, "shownBytes") : null;
@@ -5967,8 +6027,8 @@ function shownBytesOf(finished) {
5967
6027
  return numberField(finished.resultSummary ?? null, "bytes");
5968
6028
  }
5969
6029
  function totalBytesOf(finished) {
5970
- const observation = observationOf(finished);
5971
- const fromObservation = numberField(observation, "totalBytes");
6030
+ const observation2 = observationOf(finished);
6031
+ const fromObservation = numberField(observation2, "totalBytes");
5972
6032
  if (fromObservation !== null) return fromObservation;
5973
6033
  const resultSize = detailsOf(finished.result)?.resultSize;
5974
6034
  if (isPlainObject(resultSize)) {
@@ -5982,8 +6042,8 @@ function resultSizeOf(finished) {
5982
6042
  return isPlainObject(value) ? value : null;
5983
6043
  }
5984
6044
  function isTruncatedResult(finished) {
5985
- const observation = observationOf(finished);
5986
- if (observation?.truncated === true) return true;
6045
+ const observation2 = observationOf(finished);
6046
+ if (observation2?.truncated === true) return true;
5987
6047
  if (resultSizeOf(finished)?.truncated === true) return true;
5988
6048
  const truncation = detailsOf(finished.result)?.truncation;
5989
6049
  if (isPlainObject(truncation) && truncation.truncated === true) return true;
@@ -6398,8 +6458,8 @@ function outputFacts(finished) {
6398
6458
  }
6399
6459
  const exitCode = structuredExitCode(finished) ?? (finished.toolName === "bash" && !finished.isError ? "0" : null);
6400
6460
  if (exitCode !== null) parts.push(`exit ${exitCode}`);
6401
- const observation = observationOf(finished);
6402
- const count2 = observation === null ? null : countSummary(observation);
6461
+ const observation2 = observationOf(finished);
6462
+ const count2 = observation2 === null ? null : countSummary(observation2);
6403
6463
  if (count2 !== null) parts.push(count2);
6404
6464
  const lines = resultLineCount(finished.result);
6405
6465
  if (count2 === null && lines > 0) parts.push(`${lines} line${lines === 1 ? "" : "s"}`);
@@ -6462,39 +6522,11 @@ function renderResultBlock(result, isError, width, opts = {}) {
6462
6522
  if (structured) return structured;
6463
6523
  return renderOutputRows(resultText2(unwrapped, resultCharLimit(opts)), width, isError, resultRowLimit(opts));
6464
6524
  }
6465
- function renderToolCallHeader(call, width) {
6466
- return wrap(
6467
- headerLine(call.toolName, call.args, call.phase ?? "running", {
6468
- elapsedMs: call.elapsedMs
6469
- }),
6470
- width
6471
- );
6472
- }
6473
- function renderToolRunningStatus(call, width) {
6474
- const elapsed = optionalCompactMs(call.elapsedMs);
6475
- return [
6476
- ...renderToolCallHeader(call, width),
6477
- ...indentAndWrap(dim(elapsed ? `live output paused \xB7 ${elapsed}` : "live output paused"), width, false)
6478
- ];
6479
- }
6480
6525
  function sublineStatus(call) {
6481
6526
  if (!("result" in call)) return call.phase ?? "running";
6482
6527
  return call.isError ? "error" : "ok";
6483
6528
  }
6484
- function foldedDiffRows(finished, width, opts) {
6485
- if (opts.foldedExtras === "none") return [];
6486
- if (finished.isError || isNonExecutedOutcome(finished.outcome)) return [];
6487
- const presentation = toolResultPresentationPolicy(finished.result) ?? toolPresentationPolicy(finished.toolName, finished.args);
6488
- if (!presentation.showDiffWhenFolded) return [];
6489
- const diff = resultDiff(finished.result);
6490
- if (diff === null) return [];
6491
- return truncateRowsMiddle(
6492
- renderMutationDiffBlock(diff, width, opts.diffStyle !== "plain"),
6493
- FOLDED_DIFF_ROW_LIMIT,
6494
- false
6495
- );
6496
- }
6497
- function renderToolSubline(call, width, expandKey, opts = {}) {
6529
+ function renderToolSubline(call, width) {
6498
6530
  const status = sublineStatus(call);
6499
6531
  const meta = "result" in call ? {
6500
6532
  durationMs: call.durationMs,
@@ -6504,11 +6536,7 @@ function renderToolSubline(call, width, expandKey, opts = {}) {
6504
6536
  } : { elapsedMs: call.elapsedMs };
6505
6537
  const parts = sublineParts(call, status, meta);
6506
6538
  const excerpt = "result" in call ? failureExcerpt(call, width) : "";
6507
- const showHint = "result" in call && expandKey !== void 0 && expandKey.length > 0;
6508
- const tail = showHint ? `${parts.tail}${dim(` (${expandKey})`)}` : parts.tail;
6509
- const lines = wrapSublineWithTail(`${parts.lead}${excerpt}`, tail, width);
6510
- if ("result" in call) lines.push(...foldedDiffRows(call, width, opts));
6511
- return lines;
6539
+ return wrapSublineWithTail(`${parts.lead}${excerpt}`, parts.tail, width);
6512
6540
  }
6513
6541
  function renderToolExecution(finished, width, opts = {}) {
6514
6542
  const status = finished.isError ? "error" : "ok";
@@ -6560,6 +6588,7 @@ function renderToolExecution(finished, width, opts = {}) {
6560
6588
  return out;
6561
6589
  }
6562
6590
  function renderToolResultOnly(finished, width, opts = {}) {
6591
+ if (!opts.unbounded && opts.detail) return renderToolPreview(finished, width, opts.detail, opts);
6563
6592
  const status = finished.isError ? "error" : "ok";
6564
6593
  const statusMeta = {
6565
6594
  durationMs: finished.durationMs,
@@ -6574,36 +6603,7 @@ function renderToolResultOnly(finished, width, opts = {}) {
6574
6603
  out.push(...renderOutputFooter(finished, width, finished.isError));
6575
6604
  return out;
6576
6605
  }
6577
- function renderToolStreamingExecution(call, width, partialResult) {
6578
- const out = [];
6579
- out.push(...renderToolCallHeader({ ...call, phase: "running" }, width));
6580
- out.push(...renderArgsBody(call.toolName, call.args, width, false));
6581
- const partial = {
6582
- toolCallId: call.toolCallId,
6583
- toolName: call.toolName,
6584
- args: call.args,
6585
- result: partialResult,
6586
- isError: false
6587
- };
6588
- out.push(...renderOutputMeta(partial, width, false, "live output"));
6589
- const partialOutput = unwrapResultEnvelope(partialResult);
6590
- if (isEmptyResult(partialOutput)) {
6591
- out.push(...indentAndWrap(dim("(no output yet)"), width, false));
6592
- } else {
6593
- if (call.toolName === "bash") {
6594
- const bashArgs = asBashArgs(redactToolArgs(call.args));
6595
- if (bashArgs !== null) {
6596
- const commandLine = `${cyanBold("$")} ${highlightBashCommand(stripShellWrapperForDisplay(bashArgs.command))}`;
6597
- out.push(...indentAndWrap(commandLine, width, false));
6598
- }
6599
- }
6600
- out.push(
6601
- ...renderOutputRows(resultText2(partialOutput, FULL_RESULT_PREVIEW_LIMIT), width, false, STREAMING_RESULT_ROW_LIMIT)
6602
- );
6603
- }
6604
- return out;
6605
- }
6606
- function renderBashTranscriptExecution(execution, width, expandKey, bodyOptions = {}) {
6606
+ function renderBashTranscriptExecution(execution, width, _expandKey, bodyOptions = {}) {
6607
6607
  const shownBytes = Buffer.byteLength(execution.output, "utf8");
6608
6608
  const totalBytes = execution.totalBytes ?? shownBytes;
6609
6609
  const args = { command: execution.command };
@@ -6621,30 +6621,12 @@ function renderBashTranscriptExecution(execution, width, expandKey, bodyOptions
6621
6621
  content: [{ type: "text", text: execution.output }],
6622
6622
  details
6623
6623
  };
6624
- const folded = execution.folded !== false;
6625
6624
  if (execution.running) {
6626
- if (folded) {
6627
- return renderToolSubline(
6628
- {
6629
- toolCallId: "local-bash",
6630
- toolName: "bash",
6631
- args,
6632
- elapsedMs: execution.elapsedMs,
6633
- phase: "running"
6634
- },
6635
- width
6636
- );
6637
- }
6638
- return renderToolStreamingExecution(
6639
- {
6640
- toolCallId: "local-bash",
6641
- toolName: "bash",
6642
- args,
6643
- elapsedMs: execution.elapsedMs,
6644
- phase: "running"
6645
- },
6625
+ return renderToolPreview(
6626
+ { toolCallId: "local-bash", toolName: "bash", args, phase: "running", elapsedMs: execution.elapsedMs },
6646
6627
  width,
6647
- result
6628
+ bodyOptions.detail ?? transcriptDetail(),
6629
+ { ...bodyOptions, operator: true, partialResult: result }
6648
6630
  );
6649
6631
  }
6650
6632
  const message = execution.error?.trim();
@@ -6664,7 +6646,35 @@ function renderBashTranscriptExecution(execution, width, expandKey, bodyOptions
6664
6646
  ...execution.fullOutputPath !== void 0 ? { offloadPath: execution.fullOutputPath } : {}
6665
6647
  }
6666
6648
  };
6667
- return folded ? renderToolSubline(finished, width, expandKey) : renderToolExecution(finished, width, bodyOptions);
6649
+ return bodyOptions.unbounded ? renderToolExecution(finished, width, bodyOptions) : renderToolPreview(finished, width, bodyOptions.detail ?? transcriptDetail(), { ...bodyOptions, operator: true });
6650
+ }
6651
+ function renderToolPreview(call, width, detail, options = {}) {
6652
+ const finished = "result" in call ? call : void 0;
6653
+ const failure2 = finished?.isError === true || finished?.outcome !== void 0;
6654
+ const limit = previewBudget(
6655
+ failure2 ? detail.errorRows : options.operator ? detail.operatorBashRows : call.toolName === "bash" ? detail.bashRows : detail.resultRows,
6656
+ options.terminalRows
6657
+ );
6658
+ const rows = renderToolSubline(call, width);
6659
+ const result = finished?.result ?? options.partialResult;
6660
+ const diff = finished && !failure2 ? resultDiff(result) : null;
6661
+ if (diff !== null && detail.diffRows > 0) {
6662
+ rows.push(
6663
+ ...previewRows(
6664
+ renderMutationDiffBlock(redactSecretString(diff), width, options.diffStyle !== "plain"),
6665
+ previewBudget(detail.diffRows, options.terminalRows),
6666
+ width
6667
+ )
6668
+ );
6669
+ } else if (limit > 0 && result !== void 0) {
6670
+ const text = resultText2(unwrapResultEnvelope(result), Number.POSITIVE_INFINITY);
6671
+ const body = indentAndWrap(redactSecretString(text), width, failure2);
6672
+ rows.push(...previewRows(body, limit, width, call.toolName === "bash" || !finished));
6673
+ }
6674
+ return rows;
6675
+ }
6676
+ function canGroupObservation(call) {
6677
+ return ["read", "grep", "find", "ls"].includes(call.toolName) && !call.isError && !call.outcome && !call.evictedReason && !isTruncatedResult(call) && offloadPathOf(call) === null;
6668
6678
  }
6669
6679
 
6670
6680
  // src/interactive/stream-pacer.ts
@@ -7030,63 +7040,6 @@ function createStreamPacer(options) {
7030
7040
  return api;
7031
7041
  }
7032
7042
 
7033
- // src/interactive/transcript-detail.ts
7034
- init_esm_shims();
7035
- var MINIMAL = {
7036
- toolBody: "folded",
7037
- runningTool: "row",
7038
- thinking: "marker",
7039
- worker: "folded",
7040
- receipt: "none",
7041
- errors: "excerpt"
7042
- };
7043
- var DEFAULT = {
7044
- toolBody: "per-tool",
7045
- runningTool: "row",
7046
- thinking: "folded",
7047
- worker: "origin",
7048
- receipt: "compact",
7049
- errors: "excerpt"
7050
- };
7051
- var VERBOSE = {
7052
- toolBody: "expanded",
7053
- runningTool: "body",
7054
- thinking: "rail",
7055
- worker: "expanded",
7056
- receipt: "full",
7057
- errors: "body"
7058
- };
7059
- function transcriptDetail(verbosity) {
7060
- switch (verbosity) {
7061
- case "minimal":
7062
- return MINIMAL;
7063
- case "verbose":
7064
- return VERBOSE;
7065
- default:
7066
- return DEFAULT;
7067
- }
7068
- }
7069
- function resolveFold(override, policyFold) {
7070
- return override ?? policyFold;
7071
- }
7072
- function policyToolFold(detail, presentation) {
7073
- if (detail.toolBody === "per-tool") return presentation.foldDefault;
7074
- return detail.toolBody;
7075
- }
7076
- function policyRunningToolFold(detail) {
7077
- return detail.runningTool === "body" ? "expanded" : "folded";
7078
- }
7079
- function policyThinkingFold(detail) {
7080
- return detail.thinking === "rail" ? "expanded" : "folded";
7081
- }
7082
- function policyWorkerFold(detail, askedByModel) {
7083
- if (detail.worker === "origin") return askedByModel ? "folded" : "expanded";
7084
- return detail.worker;
7085
- }
7086
- function toggledFold(effective) {
7087
- return effective === "expanded" ? "folded" : "expanded";
7088
- }
7089
-
7090
7043
  // src/interactive/worker-receipts.ts
7091
7044
  init_esm_shims();
7092
7045
  import { existsSync as existsSync3, readFileSync as readFileSync5 } from "node:fs";
@@ -8551,6 +8504,7 @@ function activePhaseAfterStuck(prev) {
8551
8504
  return prev.resumePhase ?? "thinking";
8552
8505
  }
8553
8506
  function isAwaitingDispatch(prev) {
8507
+ if (activePhaseAfterStuck(prev) === "tool_running" && prev.tool?.toolName === ToolNames.Dispatch) return true;
8554
8508
  if (prev.phase === "dispatching") return true;
8555
8509
  if (prev.activePhases?.has("dispatching")) return true;
8556
8510
  return (prev.overlayStack ?? []).some((frame2) => frame2.phase === "dispatching");
@@ -8641,23 +8595,9 @@ function reduceStatus(prev, event, ctx) {
8641
8595
  if (base === "preparing") return { ...next, phase: "waiting_model", resumePhase: void 0 };
8642
8596
  return next;
8643
8597
  }
8644
- case "message_start": {
8645
- const next = refreshMeaningful(prev, ctx);
8646
- const role = event.message.role;
8647
- if (role === "assistant" && prev.phase === "tool_running") return { ...next, phase: "writing" };
8648
- if (role === "assistant" && (prev.phase === "preparing" || prev.phase === "waiting_model" || prev.phase === "thinking"))
8649
- return { ...next, phase: "writing", resumePhase: void 0 };
8650
- return next;
8651
- }
8652
- case "message_update": {
8653
- const base = activePhaseAfterStuck(prev);
8654
- const next = refreshMeaningful({ ...prev, phase: base }, ctx);
8655
- if (base === "preparing" || base === "waiting_model" || base === "thinking") {
8656
- return { ...next, phase: "writing", resumePhase: void 0 };
8657
- }
8658
- if (CORE_ACTIVE_PHASES.has(base)) return { ...next, resumePhase: void 0 };
8659
- return next;
8660
- }
8598
+ case "message_start":
8599
+ case "message_update":
8600
+ return refreshMeaningful(prev, ctx);
8661
8601
  case "tool_execution_update":
8662
8602
  return refreshMeaningful(prev, ctx);
8663
8603
  case "message_end":
@@ -8666,10 +8606,22 @@ function reduceStatus(prev, event, ctx) {
8666
8606
  runTally: foldMessageIntoRunTally(prev.runTally ?? emptyRunTally(), event.message)
8667
8607
  };
8668
8608
  case "tool_execution_end": {
8669
- const next = refreshMeaningful(prev, ctx);
8670
- if (prev.phase === "tool_running") return { ...next, phase: "preparing", tool: void 0, toolStartedAt: void 0 };
8609
+ const activeTools = (prev.activeTools ?? []).filter((tool) => tool.toolCallId !== event.toolCallId);
8610
+ const next = { ...refreshMeaningful(prev, ctx), activeTools };
8611
+ const remaining = activeTools.at(-1);
8612
+ if (remaining && prev.phase === "tool_running")
8613
+ return { ...next, tool: remaining, toolStartedAt: remaining.startedAt };
8614
+ if (prev.phase === "tool_running")
8615
+ return { ...next, phase: "preparing", tool: void 0, toolStartedAt: void 0, activeTools: [] };
8671
8616
  if (prev.phase === "stuck" && prev.resumePhase === "tool_running") {
8672
- return { ...next, phase: "preparing", resumePhase: void 0, tool: void 0, toolStartedAt: void 0 };
8617
+ return {
8618
+ ...next,
8619
+ phase: "preparing",
8620
+ resumePhase: void 0,
8621
+ tool: void 0,
8622
+ toolStartedAt: void 0,
8623
+ activeTools: []
8624
+ };
8673
8625
  }
8674
8626
  if (isOverlayPhase(prev.phase)) {
8675
8627
  return {
@@ -8690,7 +8642,14 @@ function reduceStatus(prev, event, ctx) {
8690
8642
  const base = activePhaseAfterStuck(prev);
8691
8643
  const next = refreshMeaningful({ ...prev, phase: base }, ctx);
8692
8644
  if (base === "preparing" || base === "waiting_model" || base === "writing" || base === "tool_running") {
8693
- return { ...next, phase: "thinking", resumePhase: void 0, tool: void 0, toolStartedAt: void 0 };
8645
+ return {
8646
+ ...next,
8647
+ phase: "thinking",
8648
+ resumePhase: void 0,
8649
+ tool: void 0,
8650
+ toolStartedAt: void 0,
8651
+ activeTools: []
8652
+ };
8694
8653
  }
8695
8654
  if (CORE_ACTIVE_PHASES.has(base)) return { ...next, resumePhase: void 0 };
8696
8655
  return next;
@@ -8699,17 +8658,32 @@ function reduceStatus(prev, event, ctx) {
8699
8658
  const base = activePhaseAfterStuck(prev);
8700
8659
  const next = refreshMeaningful({ ...prev, phase: base }, ctx);
8701
8660
  if (base === "preparing" || base === "waiting_model" || base === "thinking" || base === "tool_running") {
8702
- return { ...next, phase: "writing", resumePhase: void 0, tool: void 0, toolStartedAt: void 0 };
8661
+ return {
8662
+ ...next,
8663
+ phase: "writing",
8664
+ resumePhase: void 0,
8665
+ tool: void 0,
8666
+ toolStartedAt: void 0,
8667
+ activeTools: []
8668
+ };
8703
8669
  }
8704
8670
  if (CORE_ACTIVE_PHASES.has(base)) return { ...next, resumePhase: void 0 };
8705
8671
  return next;
8706
8672
  }
8707
8673
  case "tool_execution_start": {
8708
8674
  const tool = {
8675
+ toolCallId: event.toolCallId,
8676
+ startedAt: ctx.now,
8709
8677
  toolName: event.toolName,
8710
8678
  toolPreview: compactPreview(event.args)
8711
8679
  };
8712
- return { ...refreshMeaningful(prev, ctx), phase: "tool_running", tool, toolStartedAt: ctx.now };
8680
+ return {
8681
+ ...refreshMeaningful(prev, ctx),
8682
+ phase: "tool_running",
8683
+ tool,
8684
+ toolStartedAt: ctx.now,
8685
+ activeTools: [...(prev.activeTools ?? []).filter((active) => active.toolCallId !== event.toolCallId), tool]
8686
+ };
8713
8687
  }
8714
8688
  case "retry_status": {
8715
8689
  const phase = event.status.phase;
@@ -8965,10 +8939,6 @@ function createStatusController(deps) {
8965
8939
  deps.bus.on(BusChannels.PermissionResolved, () => apply({ type: "overlay_pop", overlay: "tool_blocked" }, true)),
8966
8940
  deps.bus.on(BusChannels.CompactionBegin, () => apply({ type: "overlay_push", overlay: "compacting" }, true)),
8967
8941
  deps.bus.on(BusChannels.CompactionEnd, () => apply({ type: "overlay_pop", overlay: "compacting" }, true)),
8968
- deps.bus.on(
8969
- BusChannels.DispatchStarted,
8970
- (payload) => apply({ type: "overlay_push", overlay: "dispatching", data: payload }, true)
8971
- ),
8972
8942
  deps.bus.on(BusChannels.DispatchProgress, (payload) => {
8973
8943
  if (!isWorkerStreamEvidence(payload)) return;
8974
8944
  const at = now();
@@ -8976,8 +8946,6 @@ function createStatusController(deps) {
8976
8946
  lastDispatchProgressAt = at;
8977
8947
  apply({ type: "dispatch_progress" });
8978
8948
  }),
8979
- deps.bus.on(BusChannels.DispatchCompleted, () => apply({ type: "overlay_pop", overlay: "dispatching" }, true)),
8980
- deps.bus.on(BusChannels.DispatchFailed, () => apply({ type: "overlay_pop", overlay: "dispatching" }, true)),
8981
8949
  deps.bus.on(BusChannels.RunAborted, (payload) => {
8982
8950
  scheduleAbortCeiling();
8983
8951
  if (isRunAbortedPayload(payload)) {
@@ -9027,7 +8995,6 @@ function createStatusController(deps) {
9027
8995
 
9028
8996
  // src/interactive/status/verbs.ts
9029
8997
  init_esm_shims();
9030
- var INLINE_STATUS_INDENT_COLS = 2;
9031
8998
  function spinnerFrame2(frameIndex) {
9032
8999
  return spinnerFrame(frameIndex);
9033
9000
  }
@@ -9038,39 +9005,37 @@ function elapsedSince(status, now) {
9038
9005
  const from = status.phase === "tool_running" && status.toolStartedAt !== void 0 ? status.toolStartedAt : status.since;
9039
9006
  return formatStatusElapsed(Math.max(0, now - from));
9040
9007
  }
9041
- function noProgressSince(status, now) {
9042
- return formatStatusElapsed(Math.max(0, now - status.lastMeaningfulAt));
9043
- }
9044
9008
  function coreVerb(status) {
9045
9009
  const tier = status.watchdogTier;
9046
9010
  switch (status.phase) {
9047
9011
  case "idle":
9048
9012
  return null;
9049
9013
  case "preparing":
9050
- return { text: tier >= 2 ? "still preparing harness" : "preparing harness", toneHint: "normal" };
9014
+ return { text: "Preparing", toneHint: "normal" };
9051
9015
  case "waiting_model":
9052
9016
  return {
9053
- text: tier >= 2 ? "still waiting on model" : status.localRuntime ? "waiting on local model" : "waiting on model",
9017
+ text: tier >= 2 ? "Waiting for model" : status.localRuntime ? "Waiting for local model" : "Waiting for model",
9054
9018
  toneHint: "normal"
9055
9019
  };
9056
9020
  case "thinking":
9057
- return { text: tier >= 2 ? "still receiving thinking" : "receiving thinking", toneHint: "normal" };
9021
+ return { text: "Thinking", toneHint: "normal" };
9058
9022
  case "writing":
9059
- return { text: "streaming response", toneHint: "normal" };
9023
+ return { text: "Writing", toneHint: "normal" };
9060
9024
  case "tool_running": {
9061
9025
  const name = status.tool?.toolName ?? "tool";
9062
- if (name === ToolNames.AskUser) return { text: "waiting for user input", toneHint: "normal" };
9063
- return { text: tier >= 2 ? `still running tool: ${name}` : `running tool: ${name}`, toneHint: "normal" };
9026
+ if (name === ToolNames.Dispatch) return { text: "Waiting for worker", toneHint: "normal" };
9027
+ if (name === ToolNames.AskUser) return { text: "Needs input", toneHint: "normal" };
9028
+ return { text: `Running ${name}`, toneHint: "normal" };
9064
9029
  }
9065
9030
  case "tool_blocked":
9066
- return { text: "awaiting confirmation", toneHint: "warn" };
9031
+ return { text: "Needs approval", toneHint: "warn" };
9067
9032
  case "retrying": {
9068
9033
  const retry = status.retry;
9069
9034
  const wait = retry && retry.waitMs > 0 ? ` \xB7 ${formatStatusElapsed(retry.waitMs)}` : "";
9070
9035
  return { text: `retrying ${retry?.attempt ?? 0}/${retry?.maxAttempts ?? 0}${wait}`, toneHint: "warn" };
9071
9036
  }
9072
9037
  case "compacting":
9073
- return { text: "compacting context", toneHint: "normal" };
9038
+ return { text: "Compacting context", toneHint: "normal" };
9074
9039
  case "dispatching": {
9075
9040
  const agent = status.dispatch?.agentName;
9076
9041
  if (tier >= 2)
@@ -9078,7 +9043,7 @@ function coreVerb(status) {
9078
9043
  return { text: agent ? `dispatching agent: ${agent}` : "dispatching agent", toneHint: "normal" };
9079
9044
  }
9080
9045
  case "stuck":
9081
- return { text: "stuck", toneHint: "error" };
9046
+ return { text: "No output", toneHint: "error" };
9082
9047
  case "ended": {
9083
9048
  const stop = status.summary?.stopReason ?? "stop";
9084
9049
  const elapsed = status.summary ? ` \xB7 ${formatStatusElapsed(status.summary.elapsedMs)}` : "";
@@ -9099,7 +9064,7 @@ function resolveFooterVerb(status, now, terminalCols) {
9099
9064
  if (status.phase === "stuck") {
9100
9065
  const elapsed2 = elapsedSince(status, now);
9101
9066
  return {
9102
- text: terminalCols < 60 ? "stuck" : `stuck \xB7 ${elapsed2} \xB7 Esc to cancel`,
9067
+ text: terminalCols < 60 ? "No output" : `No output \xB7 ${elapsed2} \xB7 Esc to cancel`,
9103
9068
  toneHint: "error"
9104
9069
  };
9105
9070
  }
@@ -9108,34 +9073,6 @@ function resolveFooterVerb(status, now, terminalCols) {
9108
9073
  const elapsed = elapsedSince(status, now);
9109
9074
  return { text: `${core.text} \xB7 ${elapsed}`, toneHint: core.toneHint };
9110
9075
  }
9111
- function inlineParts(status, now, terminalCols) {
9112
- if (status.phase === "stuck")
9113
- return { text: `Stuck for ${elapsedSince(status, now)}.`, hint: "Press Esc to cancel.", toneHint: "error" };
9114
- const core = coreVerb(status);
9115
- if (!core) return null;
9116
- const text = core.text.replace(/^[a-z]/, (c) => c.toUpperCase());
9117
- if (status.watchdogTier >= 3) {
9118
- const hint = terminalCols < 50 ? null : `(no progress for ${noProgressSince(status, now)}; press Esc to cancel)`;
9119
- return { text, hint, toneHint: core.toneHint };
9120
- }
9121
- if (terminalCols < 50 || status.phase === "tool_blocked") return { text, hint: null, toneHint: core.toneHint };
9122
- return { text, hint: `\xB7 ${elapsedSince(status, now)}`, toneHint: core.toneHint };
9123
- }
9124
- function fitInlineVerb(text, hint, budget) {
9125
- if (budget <= 0) return "";
9126
- const composed = hint === null ? text : `${text} ${hint}`;
9127
- if (visibleWidth(composed) <= budget) return composed;
9128
- if (visibleWidth(text) <= budget) return text;
9129
- return truncateToWidth(text, budget, GLYPH.ellipsis, false);
9130
- }
9131
- function resolveInlineVerb(status, now, terminalCols, prefixCols = 0) {
9132
- if (status.phase === "idle" || status.phase === "ended") return null;
9133
- const parts = inlineParts(status, now, terminalCols);
9134
- if (!parts) return null;
9135
- const budget = Math.max(0, Math.floor(terminalCols) - Math.max(0, Math.floor(prefixCols)));
9136
- const text = fitInlineVerb(parts.text, parts.hint, budget);
9137
- return text.length === 0 ? null : { text, toneHint: parts.toneHint };
9138
- }
9139
9076
 
9140
9077
  // src/interactive/footer/widgets.ts
9141
9078
  var EXPANDED_WIDE = 80;
@@ -9307,7 +9244,7 @@ function compactSecondaryLine(context, agent, width, theme6 = clioTheme(), statu
9307
9244
  watchdogTier: 0,
9308
9245
  watchdogPeak: 0,
9309
9246
  localRuntime: false
9310
- }, throughput = null, sessionTokens = null, sessionCost = null, outputVerbosity, leaderArmed = false, shutdownArmed = false) {
9247
+ }, throughput = null, sessionTokens = null, sessionCost = null, outputStyle, leaderArmed = false, shutdownArmed = false) {
9311
9248
  const safeWidth = Math.max(1, Math.floor(width));
9312
9249
  const barCells = compactContextBarWidth(safeWidth);
9313
9250
  let left = "";
@@ -9333,12 +9270,12 @@ function compactSecondaryLine(context, agent, width, theme6 = clioTheme(), statu
9333
9270
  context.used ?? void 0,
9334
9271
  maxRightWidth,
9335
9272
  compactMetricChipLimit(safeWidth),
9336
- outputVerbosity,
9273
+ outputStyle,
9337
9274
  leaderArmed,
9338
9275
  shutdownArmed
9339
9276
  );
9340
- if (outputVerbosity && outputVerbosity !== "default" && visibleWidth(right) === 0) {
9341
- const marker = outputVerbosity === "minimal" ? "m" : outputVerbosity === "verbose" ? "v" : "d";
9277
+ if (outputStyle && outputStyle !== "standard" && visibleWidth(right) === 0) {
9278
+ const marker = outputStyle === "compact" ? "C" : outputStyle === "detailed" ? "D" : "S";
9342
9279
  left = `${left}${theme6.fg("dim", ` out:${marker}`)}`;
9343
9280
  }
9344
9281
  return joinColumns(left, right, safeWidth);
@@ -9418,8 +9355,8 @@ function sessionQuadrant(facts, options = {}) {
9418
9355
  kv("profile", facts.toolProfile),
9419
9356
  kv(
9420
9357
  "output",
9421
- facts.outputVerbosity && facts.outputVerbosity !== "default" ? facts.outputVerbosity : null,
9422
- facts.outputVerbosity === "verbose" ? "accent" : "muted"
9358
+ facts.outputStyle && facts.outputStyle !== "standard" ? facts.outputStyle : null,
9359
+ facts.outputStyle === "detailed" ? "accent" : "muted"
9423
9360
  ),
9424
9361
  styledKv("memory", memoryValue)
9425
9362
  ]);
@@ -9721,28 +9658,34 @@ function zipColumnBlocks(blocks, widths, sep4) {
9721
9658
  }
9722
9659
  function shortToolLabel(status, width) {
9723
9660
  const name = status.tool?.toolName?.trim();
9724
- if (name === ToolNames.AskUser) return width < 72 ? "ask" : "waiting for user";
9725
- if (!name || width < 72) return "tool";
9661
+ if (name === ToolNames.AskUser) return "Needs input";
9662
+ if (name === ToolNames.Dispatch) return "Waiting for worker";
9663
+ if (!name || width < 72) return "Running tool";
9726
9664
  const nameWidth = width >= 100 ? 18 : 12;
9727
- return `tool ${truncateToWidth(name, nameWidth, "\u2026", false)}`;
9665
+ return `Running ${truncateToWidth(name, nameWidth, "\u2026", false)}`;
9728
9666
  }
9729
9667
  function harnessPhasePresentation(status, width, now) {
9730
9668
  const ultraNarrow = width < 48;
9731
9669
  switch (status.phase) {
9732
9670
  case "idle":
9733
- return { glyph: GLYPH.queued, label: "idle", token: "muted", live: false };
9671
+ return { glyph: GLYPH.queued, label: "Ready", token: "muted", live: false };
9734
9672
  case "preparing":
9735
- return { glyph: GLYPH.phaseWaiting, label: "prep", token: "info", live: true };
9673
+ return { glyph: GLYPH.phaseWaiting, label: "Preparing", token: "info", live: true };
9736
9674
  case "waiting_model":
9737
- return { glyph: GLYPH.phaseWaiting, label: "waiting", token: "info", live: true };
9675
+ return { glyph: GLYPH.phaseWaiting, label: "Waiting for model", token: "info", live: true };
9738
9676
  case "thinking":
9739
- return { glyph: GLYPH.phaseThinking, label: "thinking", token: "reason", live: true };
9677
+ return { glyph: GLYPH.phaseThinking, label: "Thinking", token: "reason", live: true };
9740
9678
  case "writing":
9741
- return { glyph: GLYPH.phaseWriting, label: "writing", token: "accent", live: true };
9679
+ return { glyph: GLYPH.phaseWriting, label: "Writing", token: "accent", live: true };
9742
9680
  case "tool_running":
9743
- return { glyph: GLYPH.phaseTool, label: shortToolLabel(status, width), token: "accent", live: true };
9681
+ return {
9682
+ glyph: GLYPH.phaseTool,
9683
+ label: shortToolLabel(status, width),
9684
+ token: "accent",
9685
+ live: status.tool?.toolName !== ToolNames.AskUser
9686
+ };
9744
9687
  case "tool_blocked":
9745
- return { glyph: GLYPH.phaseBlocked, label: "confirm", token: "warning", live: false };
9688
+ return { glyph: GLYPH.phaseBlocked, label: "Needs approval", token: "warning", live: false };
9746
9689
  case "retrying": {
9747
9690
  const attempt = status.retry?.attempt ?? 0;
9748
9691
  const maxAttempts = status.retry?.maxAttempts ?? 0;
@@ -9754,31 +9697,34 @@ function harnessPhasePresentation(status, width, now) {
9754
9697
  };
9755
9698
  }
9756
9699
  case "compacting":
9757
- return { glyph: GLYPH.phaseCompact, label: "compacting", token: "reason", live: true };
9700
+ return { glyph: GLYPH.phaseCompact, label: "Compacting context", token: "reason", live: true };
9758
9701
  case "dispatching":
9759
- return { glyph: GLYPH.phaseDispatch, label: "dispatch", token: "action", live: true };
9702
+ return { glyph: GLYPH.phaseDispatch, label: "Waiting for worker", token: "action", live: true };
9760
9703
  case "stuck": {
9761
- const seconds = Math.max(0, Math.floor((now - status.since) / 1e3));
9762
- return { glyph: GLYPH.warn, label: ultraNarrow ? "stuck" : `stuck ${seconds}s`, token: "error", live: false };
9704
+ const seconds = Math.max(0, Math.floor((now - status.lastMeaningfulAt) / 1e3));
9705
+ return {
9706
+ glyph: GLYPH.warn,
9707
+ label: ultraNarrow ? "No output" : `No output \xB7 ${seconds}s`,
9708
+ token: "warning",
9709
+ live: false
9710
+ };
9711
+ }
9712
+ case "ended": {
9713
+ const stop = status.summary?.stopReason;
9714
+ if (stop === "error") return { glyph: GLYPH.error, label: "Failed", token: "error", live: false };
9715
+ if (stop === "aborted" || stop === "cancelled")
9716
+ return { glyph: GLYPH.cancelled, label: "Cancelled", token: "muted", live: false };
9717
+ if (stop === "length") return { glyph: GLYPH.warn, label: "Output limit", token: "warning", live: false };
9718
+ return { glyph: GLYPH.ok, label: "Ready", token: "success", live: false };
9763
9719
  }
9764
- case "ended":
9765
- return { glyph: GLYPH.ok, label: "done", token: "success", live: false };
9766
9720
  }
9767
9721
  }
9768
9722
  function activeWorkerRows(rows) {
9769
9723
  return rows.filter((row2) => row2.status === "running" || row2.status === "stale" || row2.status === "enqueued");
9770
9724
  }
9771
9725
  function activeWorkerChip(rows) {
9772
- const active = activeWorkerRows(rows);
9773
- const counts = /* @__PURE__ */ new Map();
9774
- for (const row2 of active) {
9775
- const glyph = dispatchOriginPresentation(row2)?.glyph;
9776
- if (glyph === void 0) return `fleet ${active.length}`;
9777
- counts.set(glyph, (counts.get(glyph) ?? 0) + 1);
9778
- }
9779
- if (counts.size < 2) return `fleet ${active.length}`;
9780
- const order = [GLYPH.workerHuman, GLYPH.workerAgent, GLYPH.workerInternal];
9781
- return order.filter((glyph) => counts.has(glyph)).map((glyph) => `${glyph}${counts.get(glyph)}`).join(" ");
9726
+ const count2 = activeWorkerRows(rows).length;
9727
+ return `${count2} worker${count2 === 1 ? "" : "s"}`;
9782
9728
  }
9783
9729
  function harnessBadge(theme6, status, toolCounts, dispatchRows, fleetSummaryIsAction = false) {
9784
9730
  const workers = activeWorkerRows(dispatchRows).length;
@@ -9790,8 +9736,8 @@ function harnessBadge(theme6, status, toolCounts, dispatchRows, fleetSummaryIsAc
9790
9736
  const badgeText = activeTools > 0 ? `tools ${activeTools}` : null;
9791
9737
  return badgeText ? theme6.fg("muted", badgeText) : "";
9792
9738
  }
9793
- function outputVerbosityLabel(verbosity) {
9794
- return verbosity === "minimal" ? "min" : verbosity === "verbose" ? "verbose" : "default";
9739
+ function outputStyleLabel(verbosity) {
9740
+ return verbosity.charAt(0).toUpperCase() + verbosity.slice(1);
9795
9741
  }
9796
9742
  function buildHarnessStatePill(theme6, status, toolCounts, dispatchRows, tick, now, width, showBadge = true, fleetSummaryIsAction = false) {
9797
9743
  const safeWidth = Math.max(1, Math.floor(width));
@@ -9806,7 +9752,6 @@ var CHIP_RANK_SHUTDOWN = -2;
9806
9752
  var CHIP_RANK_LEADER = -1;
9807
9753
  var CHIP_RANK_TOTALS = 0;
9808
9754
  var CHIP_RANK_DETAIL = 1;
9809
- var CHIP_RANK_DEFERRED = 2;
9810
9755
  function pushChip(chips, text, rank) {
9811
9756
  if (typeof text === "string" && text.length > 0) chips.push({ text, rank });
9812
9757
  }
@@ -9820,15 +9765,13 @@ function selectChips(theme6, chips, chipLimit, maxWidth) {
9820
9765
  }
9821
9766
  return surviving();
9822
9767
  }
9823
- function buildMetricStrip(theme6, status, throughput, lastTurn, sessionTokens, sessionCost, liveInputTokens, maxWidth, maxChipsCount = 6, outputVerbosity, leaderArmed = false, shutdownArmed = false) {
9768
+ function buildMetricStrip(theme6, status, throughput, lastTurn, sessionTokens, sessionCost, liveInputTokens, maxWidth, maxChipsCount = 6, outputStyle, leaderArmed = false, shutdownArmed = false) {
9824
9769
  const safeMaxWidth = Math.max(0, Math.floor(maxWidth));
9825
9770
  if (safeMaxWidth <= 0) return "";
9826
9771
  const isStreaming = status.phase !== "idle" && status.phase !== "ended";
9827
- const meaningfulVerbosity = outputVerbosity && outputVerbosity !== "default" ? outputVerbosity : null;
9828
- if (!isStreaming && !lastTurn && !meaningfulVerbosity && !leaderArmed && !shutdownArmed) return "";
9772
+ const style = outputStyle ?? "standard";
9829
9773
  const candidates = [];
9830
- const deferred = [];
9831
- if (isStreaming) {
9774
+ if (isStreaming && outputStyle === "detailed") {
9832
9775
  const tps = finiteNonNegative2(throughput?.tokensPerSecond);
9833
9776
  const rounded = tps > 0 ? tps >= 10 ? Math.round(tps) : Math.round(tps * 10) / 10 : null;
9834
9777
  candidates.push(rounded !== null ? theme6.fg("success", `${GLYPH.speed}${rounded}/s`) : null);
@@ -9838,31 +9781,7 @@ function buildMetricStrip(theme6, status, throughput, lastTurn, sessionTokens, s
9838
9781
  candidates.push(ttftMs > 0 ? theme6.fg("muted", `ttft ${formatCompactMs(ttftMs)}`) : null);
9839
9782
  const inputTokens = finiteNonNegative2(liveInputTokens) || finiteNonNegative2(status.summary?.inputTokens) || finiteNonNegative2(lastTurn?.inputTokens) || finiteNonNegative2(sessionTokens?.input);
9840
9783
  candidates.push(inputTokens > 0 ? theme6.fg("muted", `${GLYPH.up}${formatFooterTokens(inputTokens)}`) : null);
9841
- } else if (lastTurn) {
9842
- const stop = stopReasonStyle(lastTurn.stopReason);
9843
- candidates.push(theme6.fg(stop.token, `${stop.glyph} ${formatCompactMs(lastTurn.elapsedMs)}`));
9844
- candidates.push(
9845
- theme6.fg(
9846
- "muted",
9847
- `${GLYPH.up}${formatFooterTokens(lastTurn.inputTokens)} ${GLYPH.down}${formatFooterTokens(lastTurn.outputTokens)}`
9848
- )
9849
- );
9850
- candidates.push(reasoningChip(theme6, lastTurn));
9851
- deferred.push(
9852
- lastTurn.cacheReadTokens > 0 || lastTurn.cacheWriteTokens > 0 ? theme6.fg(
9853
- "dim",
9854
- `cache ${formatFooterTokens(lastTurn.cacheReadTokens)}/${formatFooterTokens(lastTurn.cacheWriteTokens)}`
9855
- ) : null
9856
- );
9857
- if (lastTurn.toolCount > 0) {
9858
- const label = `${lastTurn.toolCount} tool${lastTurn.toolCount === 1 ? "" : "s"}`;
9859
- const errors = lastTurn.toolErrorCount > 0 ? theme6.fg("error", ` ${lastTurn.toolErrorCount}${GLYPH.error}`) : "";
9860
- deferred.push(`${theme6.fg("muted", label)}${errors}`);
9861
- } else {
9862
- deferred.push(null);
9863
- }
9864
9784
  }
9865
- if (meaningfulVerbosity) deferred.push(theme6.fg("muted", `out ${outputVerbosityLabel(meaningfulVerbosity)}`));
9866
9785
  const fallbackTotal = finiteNonNegative2(sessionTokens?.input) + finiteNonNegative2(sessionTokens?.output);
9867
9786
  const cumulativeTotal = finiteNonNegative2(sessionTokens?.totalTokens) || fallbackTotal;
9868
9787
  const totalChip = cumulativeTotal > 0 ? theme6.fg("muted", `\u03A3${formatFooterTokens(cumulativeTotal)}`) : null;
@@ -9870,13 +9789,13 @@ function buildMetricStrip(theme6, status, throughput, lastTurn, sessionTokens, s
9870
9789
  const costChip = cost === null ? null : theme6.fg("muted", cost);
9871
9790
  const chipLimit = Math.max(0, Math.floor(maxChipsCount));
9872
9791
  const chips = [];
9792
+ pushChip(chips, theme6.fg("muted", outputStyleLabel(style)), CHIP_RANK_LEADER);
9873
9793
  const shutdownHint = safeMaxWidth >= 20 ? "Ctrl+C again to quit" : "Ctrl+C again";
9874
9794
  pushChip(chips, shutdownArmed ? theme6.fg("warning", shutdownHint) : null, CHIP_RANK_SHUTDOWN);
9875
9795
  pushChip(chips, leaderArmed ? theme6.fg("accent", "leader armed") : null, CHIP_RANK_LEADER);
9876
9796
  for (const chip of candidates) pushChip(chips, chip, CHIP_RANK_DETAIL);
9877
9797
  pushChip(chips, totalChip, CHIP_RANK_TOTALS);
9878
9798
  pushChip(chips, costChip, CHIP_RANK_DETAIL);
9879
- for (const chip of deferred) pushChip(chips, chip, CHIP_RANK_DEFERRED);
9880
9799
  return joinChips(theme6, selectChips(theme6, chips, chipLimit, safeMaxWidth));
9881
9800
  }
9882
9801
 
@@ -9935,6 +9854,7 @@ function relative3(instant, now = Date.now()) {
9935
9854
 
9936
9855
  // src/interactive/view/artifacts.ts
9937
9856
  var VIEW_ARTIFACT_CATEGORIES = [
9857
+ "transcript",
9938
9858
  "accountability",
9939
9859
  "evidence",
9940
9860
  "receipt",
@@ -11241,6 +11161,7 @@ var SafetyAuditArtifactProvider = class {
11241
11161
  };
11242
11162
  function createDefaultArtifactProviders(deps) {
11243
11163
  return [
11164
+ { category: "transcript", list: async () => deps.readTranscript?.() ?? [] },
11244
11165
  new AccountabilityArtifactProvider(deps),
11245
11166
  new EvidenceArtifactProvider(deps),
11246
11167
  new ReceiptArtifactProvider(deps),
@@ -11934,23 +11855,22 @@ function renderReplayLine(text, width) {
11934
11855
  function appendReplayLine(chatPanel, text) {
11935
11856
  chatPanel.appendReplayBlock((width) => renderReplayLine(truncateReplayText(text), width));
11936
11857
  }
11937
- function renderBashExecutionEntry(entry, width, folded, unbounded) {
11858
+ function renderBashExecutionEntry(entry, width, detail, unbounded) {
11938
11859
  const normalizedOutput = entry.output.replace(/\r\n/g, "\n").replace(/\r/g, "\n").replace(/\s+$/g, "");
11939
11860
  return renderBashTranscriptExecution(
11940
11861
  {
11941
11862
  command: entry.command,
11942
- output: unbounded ? normalizedOutput : truncateReplayText(normalizedOutput),
11863
+ output: normalizedOutput,
11943
11864
  running: false,
11944
11865
  exitCode: entry.exitCode,
11945
11866
  cancelled: entry.cancelled,
11946
11867
  truncated: entry.truncated,
11947
11868
  fullOutputPath: entry.fullOutputPath,
11948
- excludeFromContext: entry.excludeFromContext,
11949
- folded
11869
+ excludeFromContext: entry.excludeFromContext
11950
11870
  },
11951
11871
  width,
11952
11872
  void 0,
11953
- { unbounded, diffStyle: "plain" }
11873
+ { unbounded, diffStyle: "plain", detail }
11954
11874
  );
11955
11875
  }
11956
11876
  function renderRetryStatusEntry(entry, width) {
@@ -12260,16 +12180,16 @@ function rehydrateChatPanelFromTurns(chatPanel, turns, options = {}) {
12260
12180
  case "message": {
12261
12181
  if (entry.role === "user") {
12262
12182
  runAssistantMessages = [];
12263
- const text = truncateReplayText(replayedUserText(entry));
12183
+ const text = replayedUserText(entry);
12264
12184
  if (text.length > 0) chatPanel.appendUser(text);
12265
12185
  break;
12266
12186
  }
12267
12187
  if (entry.role === "assistant") {
12268
12188
  const text = chatMessageText(entry);
12269
12189
  const failure2 = messageFailure(entry);
12270
- const richMessage = richMessageFromEntry(entry, MAX_REPLAY_TEXT_CHARS);
12190
+ const richMessage = richMessageFromEntry(entry, Number.POSITIVE_INFINITY);
12271
12191
  if (richMessage || text.length > 0 || failure2) {
12272
- const message = richMessage ?? makeTextMessage("assistant", truncateReplayText(text), entry.timestamp);
12192
+ const message = richMessage ?? makeTextMessage("assistant", text, entry.timestamp);
12273
12193
  if (failure2) {
12274
12194
  message.stopReason = failure2.stopReason;
12275
12195
  message.errorMessage = failure2.errorMessage;
@@ -12304,7 +12224,7 @@ function rehydrateChatPanelFromTurns(chatPanel, turns, options = {}) {
12304
12224
  type: "tool_execution_end",
12305
12225
  toolCallId: fallbackId,
12306
12226
  toolName: result.name,
12307
- result: displayReplayToolResult(result.result, options.unboundedToolBodies === true),
12227
+ result: displayReplayToolResult(result.result, true),
12308
12228
  isError: result.isError,
12309
12229
  ...result.durationMs !== void 0 ? { durationMs: result.durationMs } : {},
12310
12230
  ...resultSummary !== void 0 ? { resultSummary } : {},
@@ -12314,11 +12234,11 @@ function rehydrateChatPanelFromTurns(chatPanel, turns, options = {}) {
12314
12234
  });
12315
12235
  } else {
12316
12236
  chatPanel.appendReplayBlock(
12317
- (width) => renderToolResultOnly(
12237
+ (width, detail, unbounded) => renderToolResultOnly(
12318
12238
  {
12319
12239
  toolCallId: result.id ?? "",
12320
12240
  toolName: result.name,
12321
- result: displayReplayToolResult(result.result, options.unboundedToolBodies === true),
12241
+ result: displayReplayToolResult(result.result, true),
12322
12242
  isError: result.isError,
12323
12243
  ...result.durationMs !== void 0 ? { durationMs: result.durationMs } : {},
12324
12244
  ...resultSummary !== void 0 ? { resultSummary } : {},
@@ -12327,7 +12247,7 @@ function rehydrateChatPanelFromTurns(chatPanel, turns, options = {}) {
12327
12247
  ...evictedReason !== void 0 ? { evictedReason } : {}
12328
12248
  },
12329
12249
  width,
12330
- { unbounded: options.unboundedToolBodies === true }
12250
+ { unbounded: unbounded || options.unboundedToolBodies === true, detail }
12331
12251
  )
12332
12252
  );
12333
12253
  }
@@ -12346,20 +12266,8 @@ function rehydrateChatPanelFromTurns(chatPanel, turns, options = {}) {
12346
12266
  break;
12347
12267
  }
12348
12268
  case "bashExecution": {
12349
- let fold;
12350
- const presentation = toolPresentationPolicy(ToolNames.Bash, void 0);
12351
- const policyFold = (detail) => policyToolFold(detail, presentation);
12352
- const unbounded = options.unboundedToolBodies === true;
12353
12269
  chatPanel.appendReplayBlock(
12354
- (width, detail) => renderBashExecutionEntry(entry, width, resolveFold(fold, policyFold(detail)) === "folded", unbounded),
12355
- void 0,
12356
- {
12357
- policyFold,
12358
- fold: () => fold,
12359
- setFold: (next) => {
12360
- fold = next;
12361
- }
12362
- }
12270
+ (width, detail, unbounded) => renderBashExecutionEntry(entry, width, detail, unbounded || options.unboundedToolBodies === true)
12363
12271
  );
12364
12272
  break;
12365
12273
  }
@@ -12423,7 +12331,6 @@ function rehydrateChatPanelFromTurns(chatPanel, turns, options = {}) {
12423
12331
  isError: true
12424
12332
  });
12425
12333
  }
12426
- chatPanel.clearFoldOverrides();
12427
12334
  }
12428
12335
 
12429
12336
  // src/interactive/model-session-replay.ts
@@ -16079,6 +15986,8 @@ function artifactKey(artifact) {
16079
15986
  }
16080
15987
  function categoryLabel(category) {
16081
15988
  switch (category) {
15989
+ case "transcript":
15990
+ return "Transcript details";
16082
15991
  case "accountability":
16083
15992
  return "Accountability";
16084
15993
  case "evidence":
@@ -16105,6 +16014,7 @@ function categoryLabel(category) {
16105
16014
  }
16106
16015
  var VIEW_ARTIFACT_CATEGORY_SET = new Set(VIEW_ARTIFACT_CATEGORIES);
16107
16016
  var BARE_CATEGORY_FILTERS = /* @__PURE__ */ new Set([
16017
+ "transcript",
16108
16018
  "task-ledger",
16109
16019
  "workspace",
16110
16020
  "protected-artifact",
@@ -16231,11 +16141,8 @@ function groupedViewRows(artifacts) {
16231
16141
  const rows = [];
16232
16142
  for (const category of VIEW_ARTIFACT_CATEGORIES) {
16233
16143
  const items = artifacts.filter((artifact) => artifact.category === category);
16144
+ if (items.length === 0) continue;
16234
16145
  rows.push({ type: "group", category });
16235
- if (items.length === 0) {
16236
- rows.push({ type: "empty", category });
16237
- continue;
16238
- }
16239
16146
  for (const item of items) {
16240
16147
  rows.push({ type: "item", category, item, itemIndex: artifacts.indexOf(item) });
16241
16148
  }
@@ -16311,10 +16218,10 @@ function viewFooterHint(focus, canVerify, innerWidth) {
16311
16218
  if (innerWidth !== void 0 && viewUsesSinglePane(innerWidth - 2)) {
16312
16219
  const budget = innerWidth - 3;
16313
16220
  const tiers = focus === "list" ? [
16314
- "[\u2191\u2193] select \xB7 [type] filter \xB7 [Tab] detail \xB7 [Esc] close",
16315
- "[\u2191\u2193] select \xB7 [Tab] detail \xB7 [Esc] close",
16316
- "[\u2191\u2193] select \xB7 [Tab] detail"
16317
- ] : ["[\u2191\u2193] scroll \xB7 [Tab] list \xB7 [Esc] close", "[\u2191\u2193] scroll \xB7 [Tab] list"];
16221
+ "[\u2191\u2193] select \xB7 [type] filter \xB7 [Enter] detail \xB7 [Esc] close",
16222
+ "[\u2191\u2193] select \xB7 [Enter] detail \xB7 [Esc] close",
16223
+ "[\u2191\u2193] select \xB7 [Enter] detail"
16224
+ ] : ["[\u2191\u2193] scroll \xB7 [Esc] back", "[\u2191\u2193] scroll \xB7 [Tab] list"];
16318
16225
  return tiers.find((tier) => visibleWidth(tier) <= budget) ?? tiers.at(-1);
16319
16226
  }
16320
16227
  if (focus === "list") {
@@ -16322,20 +16229,21 @@ function viewFooterHint(focus, canVerify, innerWidth) {
16322
16229
  { key: "\u2191\u2193", verb: "select" },
16323
16230
  { key: "\u2190\u2192", verb: "category" },
16324
16231
  { key: "type", verb: "filter" },
16325
- { key: "Tab", verb: "content" },
16326
- ...canVerify ? [{ key: "v", verb: "verify" }] : [],
16327
- { key: "o", verb: "path" }
16232
+ { key: "Enter", verb: "content" },
16233
+ { key: "Ctrl+U", verb: "clear filter" }
16328
16234
  ]);
16329
16235
  }
16330
- return buildHint([
16331
- { key: "\u2191\u2193", verb: "scroll" },
16332
- { key: "\u2190\u2192", verb: "category" },
16333
- { key: "PgUp/PgDn", verb: "page" },
16334
- { key: "g/G", verb: "top/bottom" },
16335
- { key: "Tab", verb: "list" },
16336
- ...canVerify ? [{ key: "v", verb: "verify" }] : [],
16337
- { key: "o", verb: "path" }
16338
- ]);
16236
+ return buildHint(
16237
+ [
16238
+ { key: "\u2191\u2193", verb: "scroll" },
16239
+ { key: "\u2190\u2192", verb: "category" },
16240
+ { key: "PgUp/PgDn", verb: "page" },
16241
+ { key: "g/G", verb: "top/bottom" },
16242
+ ...canVerify ? [{ key: "v", verb: "verify" }] : [],
16243
+ { key: "o", verb: "path" }
16244
+ ],
16245
+ "back"
16246
+ );
16339
16247
  }
16340
16248
  var ViewOverlayView = class {
16341
16249
  constructor(options) {
@@ -16436,10 +16344,8 @@ var ViewOverlayView = class {
16436
16344
  const content = this.content;
16437
16345
  if (!content) return [];
16438
16346
  if (content.status === "error") return content.lines.flatMap((line) => wrapTextWithAnsi(line, Math.max(1, width)));
16439
- if (content.format !== "markdown") return content.lines;
16440
16347
  if (content.renderedLines && content.renderWidth === width) return content.renderedLines;
16441
- const md = new Markdown(content.lines.join("\n"), 0, 0, markdownTheme(clioTheme()));
16442
- const rendered = md.render(width);
16348
+ const rendered = content.format === "markdown" ? new Markdown(content.lines.join("\n"), 0, 0, markdownTheme(clioTheme())).render(width) : content.lines.flatMap((line) => wrapTextWithAnsi(line, Math.max(1, width)));
16443
16349
  content.renderWidth = width;
16444
16350
  content.renderedLines = rendered;
16445
16351
  return rendered;
@@ -16461,6 +16367,7 @@ var ViewOverlayView = class {
16461
16367
  return this.fixedLines(lines, width, height);
16462
16368
  }
16463
16369
  const filtered = this.filteredArtifacts();
16370
+ if (filtered.length === 0) return this.fixedLines([...lines, theme6.fg("dim", "No matching details.")], width, height);
16464
16371
  const rows = groupedViewRows(filtered);
16465
16372
  const selectedRow = rows.findIndex((row2) => row2.type === "item" && row2.itemIndex === this.selectedIndex);
16466
16373
  const rowHeight = Math.max(1, height - 1);
@@ -16531,7 +16438,7 @@ var ViewOverlayView = class {
16531
16438
  return Array.from({ length: bodyHeight }, (_, index) => `${list[index] ?? ""}${separator}${content[index] ?? ""}`);
16532
16439
  }
16533
16440
  handleInput(data) {
16534
- if (matchesKey(data, "tab") || matchesKey(data, "shift+tab")) {
16441
+ if (matchesKey(data, "tab") || matchesKey(data, "shift+tab") || this.focus === "list" && matchesKey(data, "enter")) {
16535
16442
  this.focus = this.focus === "list" ? "content" : "list";
16536
16443
  this.options.requestRender?.();
16537
16444
  return;
@@ -16544,21 +16451,19 @@ var ViewOverlayView = class {
16544
16451
  this.selectCategory(1);
16545
16452
  return;
16546
16453
  }
16547
- if (data === "v") {
16454
+ if (this.focus === "content" && data === "v") {
16548
16455
  this.verifySelected();
16549
16456
  return;
16550
16457
  }
16551
- if (data === "o") {
16458
+ if (this.focus === "content" && data === "o") {
16552
16459
  this.openPathNotice();
16553
16460
  return;
16554
16461
  }
16555
16462
  if (matchesKey(data, "esc")) {
16556
- if (this.focus === "list" && this.filterText.length > 0) {
16557
- this.filterText = "";
16558
- this.selectInitialFilterMatch();
16559
- return;
16560
- }
16561
- this.options.onClose();
16463
+ if (this.focus === "content") {
16464
+ this.focus = "list";
16465
+ this.options.requestRender?.();
16466
+ } else this.options.onClose();
16562
16467
  return;
16563
16468
  }
16564
16469
  if (this.focus === "content") {
@@ -16571,14 +16476,19 @@ var ViewOverlayView = class {
16571
16476
  }
16572
16477
  handleListInput(data) {
16573
16478
  const filtered = this.filteredArtifacts();
16574
- if (matchesKey(data, "up") || data === "k") {
16479
+ if (matchesKey(data, "up")) {
16575
16480
  if (filtered.length > 0) this.selectIndex(this.selectedIndex - 1);
16576
16481
  return true;
16577
16482
  }
16578
- if (matchesKey(data, "down") || data === "j") {
16483
+ if (matchesKey(data, "down")) {
16579
16484
  if (filtered.length > 0) this.selectIndex(this.selectedIndex + 1);
16580
16485
  return true;
16581
16486
  }
16487
+ if (matchesKey(data, "ctrl+u")) {
16488
+ this.filterText = "";
16489
+ this.selectInitialFilterMatch();
16490
+ return true;
16491
+ }
16582
16492
  if (matchesKey(data, "backspace")) {
16583
16493
  if (this.filterText.length > 0) {
16584
16494
  this.filterText = this.filterText.slice(0, -1);
@@ -20779,7 +20689,8 @@ function createOverlayGeneralOpeners(deps) {
20779
20689
  dataDir: deps.dataDir,
20780
20690
  dispatch: deps.dispatch,
20781
20691
  sessionMeta: deps.getSessionMeta(),
20782
- readSessionEntries: deps.readSessionEntries
20692
+ readSessionEntries: deps.readSessionEntries,
20693
+ readTranscript: deps.readTranscript
20783
20694
  }),
20784
20695
  ...initialFilter ? { initialFilter } : {},
20785
20696
  notice: deps.notify,
@@ -21959,7 +21870,7 @@ var SETTINGS_LABELS_BY_ID = {
21959
21870
  "retry.maxDelayMs": "Max delay (ms)",
21960
21871
  "retry.streamStallMs": "Stream stall timeout (ms)",
21961
21872
  "terminal.showTerminalProgress": "Terminal progress badges",
21962
- "terminal.outputVerbosity": "Output detail",
21873
+ "terminal.outputVerbosity": "Output style",
21963
21874
  "terminal.tuiMode": "TUI mode",
21964
21875
  "terminal.fullscreenScrollbar": "Fullscreen scrollbar",
21965
21876
  "terminal.smoothStreaming": "Smooth streaming",
@@ -22189,7 +22100,7 @@ var SETTINGS_HELP_BY_ID = {
22189
22100
  "library.remote": "A Git remote URL, or blank to keep the library local. Setting it is not enough to sync: the remote must also be confirmed, and library.sync must be true. Default: blank.",
22190
22101
  "library.confirmedRemote": "Written by the confirm flow, not by hand, because confirming a remote here would be the record confirming itself. Sync refuses with library_remote_unconfirmed until this equals library.remote. Default: blank.",
22191
22102
  "library.sync": "Off means `clio-coder library sync` and `push` refuse before touching the network, whatever the remote says. Legal values: true, false \xB7 default: false.",
22192
- "budget.concurrency": "auto sizes to your machine. A fixed number caps how many workers run at once.",
22103
+ "budget.concurrency": "auto allows four local workers. A fixed number caps how many workers run at once; the default is one.",
22193
22104
  "skills.trustProjectCompatRoots": "Project roots like .claude/skills and .codex/skills are untrusted by default; enabling exposes them to the model.",
22194
22105
  "attribution.gitCommits": "Role trailers are added only when Clio has trusted evidence for that role. Disabling leaves subsequent commit messages entirely unchanged.",
22195
22106
  "workers.onPermission": "deny turns the ask into a tool denial and the run continues; fail stops the run as permission_required; escalate forwards the ask to you and falls back per workers.escalation on timeout.",
@@ -22208,7 +22119,7 @@ var SETTINGS_HELP_BY_ID = {
22208
22119
  "watchdog.enabled": "The verifier run is briefed with the turn's coalesced diff and the task board's current scope; its blockers become one transcript notice and nothing else. Headless and ACP runs never fire it.",
22209
22120
  "watchdog.target": "A watchdog run costs a worker run per mutating turn, so routing it at a local target keeps the review cheap. Leave blank to reuse whatever the session is already talking to.",
22210
22121
  "watchdog.cadenceToolCalls": "Mid-turn firing is how scope drift becomes visible before the turn ends. Leave blank and the watchdog fires at turn end only.",
22211
- keybindings: "Renderer controls: Alt+O newest tool or worker details, Ctrl+Alt+O or Alt+Shift+O all of them, Alt+P live tool output, Alt+R latest reasoning, Ctrl+Alt+R or Alt+Shift+R all reasoning. Override these in settings.yaml or use /help."
22122
+ keybindings: "Alt+O cycles Output style: Compact, Standard, Detailed. Use /view for full reasoning and action details. Shift+Tab changes model thinking effort."
22212
22123
  };
22213
22124
  var SETTINGS_VALUE_HELP_BY_ID = {
22214
22125
  autonomy: {
@@ -22275,9 +22186,9 @@ var SETTINGS_VALUE_HELP_BY_ID = {
22275
22186
  false: "no terminal progress badges"
22276
22187
  },
22277
22188
  "terminal.outputVerbosity": {
22278
- minimal: "quiet transcript; tools stay to one-line outcomes and reasoning stays folded",
22279
- default: "balanced transcript; unfold the latest tool, worker, or reasoning block on demand",
22280
- verbose: "transparent transcript; reasoning, arguments, and live tool output stay visible"
22189
+ compact: "quiet action summaries, answers, and visible failures",
22190
+ standard: "short reasoning and change previews, clear action outcomes",
22191
+ detailed: "larger bounded previews; full content is available in /view"
22281
22192
  },
22282
22193
  "terminal.tuiMode": {
22283
22194
  regular: "preserve terminal scrollback and render the composer below the transcript",
@@ -22743,12 +22654,12 @@ function scopedModelsSubmenu(selectedRefs, providers) {
22743
22654
  "Target entries cycle by target, using its default model when switching targets. Model entries pin one exact target/model reference."
22744
22655
  );
22745
22656
  }
22746
- function chainSubmenus(first, second, join11) {
22657
+ function chainSubmenus(first, second, join10) {
22747
22658
  return (_currentValue, done) => {
22748
22659
  let active = first("", (head) => {
22749
22660
  const trimmed = head?.trim() ?? "";
22750
22661
  if (!trimmed) return done();
22751
- active = second(trimmed)("", (tail) => done(tail?.trim() ? join11(trimmed, tail.trim()) : void 0));
22662
+ active = second(trimmed)("", (tail) => done(tail?.trim() ? join10(trimmed, tail.trim()) : void 0));
22752
22663
  });
22753
22664
  return {
22754
22665
  render: (width) => active.render(width),
@@ -23252,7 +23163,7 @@ function buildSettingItems(settings, options) {
23252
23163
  values: ["false", "true"]
23253
23164
  }),
23254
23165
  settingItem("terminal.outputVerbosity", terminal.outputDetail, {
23255
- values: ["minimal", "default", "verbose"]
23166
+ values: ["compact", "standard", "detailed"]
23256
23167
  }),
23257
23168
  settingItem("terminal.tuiMode", terminal.mode, {
23258
23169
  values: ["regular", "fullscreen"]
@@ -23822,7 +23733,7 @@ function applySettingChange(settings, id, value) {
23822
23733
  if (value === "true" || value === "false") settings.interface.terminalProgress = value === "true";
23823
23734
  return;
23824
23735
  case "terminal.outputVerbosity":
23825
- if (value === "minimal" || value === "default" || value === "verbose") settings.interface.outputDetail = value;
23736
+ if (value === "compact" || value === "standard" || value === "detailed") settings.interface.outputDetail = value;
23826
23737
  return;
23827
23738
  case "terminal.tuiMode":
23828
23739
  if (value === "regular" || value === "fullscreen") settings.interface.mode = value;
@@ -27069,59 +26980,6 @@ function runCompactWithNotice(onCompact, notice, instructions) {
27069
26980
  });
27070
26981
  }
27071
26982
 
27072
- // src/interactive/external-editor.ts
27073
- init_esm_shims();
27074
- import { spawnSync } from "node:child_process";
27075
- import { randomUUID as randomUUID2 } from "node:crypto";
27076
- import { readFileSync as readFileSync6, unlinkSync, writeFileSync } from "node:fs";
27077
- import { tmpdir } from "node:os";
27078
- import { join as join5 } from "node:path";
27079
- function defaultProbe(candidates) {
27080
- for (const candidate of candidates) {
27081
- const result = spawnSync("sh", ["-lc", `command -v ${candidate}`], {
27082
- encoding: "utf8",
27083
- stdio: ["ignore", "pipe", "ignore"]
27084
- });
27085
- const resolved = typeof result.stdout === "string" ? result.stdout.trim() : "";
27086
- if (result.status === 0 && resolved.length > 0) return resolved;
27087
- }
27088
- return null;
27089
- }
27090
- function runEditor(command, filePath) {
27091
- if (process.platform === "win32") {
27092
- return spawnSync(command, [filePath], {
27093
- stdio: "inherit",
27094
- shell: true
27095
- });
27096
- }
27097
- return spawnSync(process.env.SHELL || "/bin/sh", ["-lc", `${command} ${shellQuote(filePath)}`], {
27098
- stdio: "inherit"
27099
- });
27100
- }
27101
- function resolveExternalEditor(env = process.env, probe = defaultProbe) {
27102
- const visual = env.VISUAL?.trim();
27103
- if (visual) return visual;
27104
- const editor = env.EDITOR?.trim();
27105
- if (editor) return editor;
27106
- return probe(["nano", "vi"]);
27107
- }
27108
- function editTextExternally(initialText, command) {
27109
- if (!command) return { ok: false, error: "no external editor configured; set VISUAL or EDITOR" };
27110
- const tmpFile = join5(tmpdir(), `clio-coder-editor-${process.pid}-${randomUUID2()}.md`);
27111
- try {
27112
- writeFileSync(tmpFile, initialText, "utf8");
27113
- const result = runEditor(command, tmpFile);
27114
- if (result.error) return { ok: false, error: result.error.message };
27115
- if (result.status !== 0) return { ok: false, error: `external editor exited with code ${result.status ?? "?"}` };
27116
- return { ok: true, text: readFileSync6(tmpFile, "utf8").replace(/\n$/, "") };
27117
- } finally {
27118
- try {
27119
- unlinkSync(tmpFile);
27120
- } catch {
27121
- }
27122
- }
27123
- }
27124
-
27125
26983
  // src/interactive/overlays/cwd-fallback.ts
27126
26984
  init_esm_shims();
27127
26985
  var CWD_FALLBACK_OVERLAY_WIDTH = 88;
@@ -27757,11 +27615,11 @@ function formatTreeRow(row2, opts) {
27757
27615
  const labelText = row2.node.label ? ` \xB7 label:"${row2.node.label}"` : "";
27758
27616
  const inertText = row2.switchable ? "" : " (fixed)";
27759
27617
  const plainPrefix = `${indent}${glyph} ${row2.node.kind.padEnd(12)} ${turnId} `;
27760
- const previewBudget = Math.min(
27618
+ const previewBudget2 = Math.min(
27761
27619
  ROW_PREVIEW_BUDGET,
27762
27620
  Math.max(1, opts.width - visibleWidth(plainPrefix) - visibleWidth(labelText) - visibleWidth(inertText))
27763
27621
  );
27764
- const preview = clampPreview(rawPreview, previewBudget);
27622
+ const preview = clampPreview(rawPreview, previewBudget2);
27765
27623
  const glyphStyled = row2.isActiveTip ? theme6.fg("accent", glyph) : theme6.fg("dim", glyph);
27766
27624
  const styledPrefix = `${indent}${glyphStyled}${theme6.fg("dim", ` ${row2.node.kind.padEnd(12)}`)} ${theme6.fg("muted", turnId)} `;
27767
27625
  const styledLabel = labelText ? `${theme6.fg("dim", " \xB7 label:")}${theme6.fg("muted", `"${row2.node.label}"`)}` : "";
@@ -29004,6 +28862,7 @@ function createOverlayLifecycle(deps) {
29004
28862
  });
29005
28863
  const scheduling = deps.app.scheduling;
29006
28864
  const overlayGeneralOpeners = createOverlayGeneralOpeners({
28865
+ readTranscript: () => chatPanel.inspectionArtifacts(),
29007
28866
  tui,
29008
28867
  transitions: overlayTransitions,
29009
28868
  observability: deps.app.observability,
@@ -29127,16 +28986,12 @@ function createOverlayLifecycle(deps) {
29127
28986
  // src/interactive/application-controller.ts
29128
28987
  var APPLICATION_DOUBLE_TAP_MS = 500;
29129
28988
  var CLOSED_ACTION_ORDER = [
28989
+ "clio-coder.output.cycle",
29130
28990
  "clio-coder.notifications.dismiss",
29131
- "clio-coder.tool.expand",
29132
- "clio-coder.tool.expandAll",
29133
- "clio-coder.tool.liveOutput",
29134
28991
  "clio-coder.editor.external",
29135
28992
  "clio-coder.message.followUp",
29136
28993
  "clio-coder.message.interrupt",
29137
- "clio-coder.message.dequeue",
29138
- "clio-coder.thinking.expand",
29139
- "clio-coder.thinking.expandAll"
28994
+ "clio-coder.message.dequeue"
29140
28995
  ];
29141
28996
  var GLOBAL_ACTION_ORDER = [
29142
28997
  "clio-coder.status.toggle",
@@ -29172,8 +29027,6 @@ function createApplicationController(deps) {
29172
29027
  let shuttingDown = false;
29173
29028
  let lastCtrlCAt = 0;
29174
29029
  let lastNotificationDismissAt = 0;
29175
- let lastToolExpandAt = 0;
29176
- let lastThinkingExpandAt = 0;
29177
29030
  const isDoubleTap = (lastAt, now) => lastAt > 0 && now - lastAt <= APPLICATION_DOUBLE_TAP_MS;
29178
29031
  let shutdownArmed = false;
29179
29032
  let armedIndicator = null;
@@ -29292,20 +29145,6 @@ function createApplicationController(deps) {
29292
29145
  const first = deps.listNotifications()[0];
29293
29146
  if (first) deps.dismissNotification(first.id);
29294
29147
  };
29295
- const toggleToolExpansion = () => {
29296
- const now = deps.clock.now();
29297
- const doubleTap = isDoubleTap(lastToolExpandAt, now);
29298
- lastToolExpandAt = now;
29299
- const changed = doubleTap ? deps.toggleAllToolsExpanded() : deps.toggleLastToolExpanded();
29300
- if (changed) deps.requestRender();
29301
- };
29302
- const toggleThinkingExpansion = () => {
29303
- const now = deps.clock.now();
29304
- const doubleTap = isDoubleTap(lastThinkingExpandAt, now);
29305
- lastThinkingExpandAt = now;
29306
- const changed = doubleTap ? deps.toggleAllThinking() : deps.toggleLastThinking();
29307
- if (changed) deps.requestRender();
29308
- };
29309
29148
  const handleInput = (data) => {
29310
29149
  const initialOverlayState = deps.getOverlayState();
29311
29150
  if (overlayOwnsInput(initialOverlayState) && deps.leaderKeys.isPending()) deps.leaderKeys.reset();
@@ -29356,8 +29195,6 @@ function createApplicationController(deps) {
29356
29195
  handleInput,
29357
29196
  handleCtrlC,
29358
29197
  dismissNotifications,
29359
- toggleToolExpansion,
29360
- toggleThinkingExpansion,
29361
29198
  shutdown
29362
29199
  };
29363
29200
  }
@@ -29507,29 +29344,17 @@ function createEditorSubmitController(deps) {
29507
29344
  totalBytes: 0,
29508
29345
  excludeFromContext: parsed.excludeFromContext
29509
29346
  };
29510
- let fold;
29511
- const bashPresentation = toolPresentationPolicy(ToolNames.Bash, void 0);
29512
- const policyFold = (detail) => execution.running ? policyRunningToolFold(detail) : policyToolFold(detail, bashPresentation);
29513
29347
  deps.chatPanel.appendReplayBlock(
29514
- (width, detail) => renderBashTranscriptExecution(
29515
- {
29516
- ...execution,
29517
- folded: resolveFold(fold, policyFold(detail)) === "folded",
29518
- ...execution.running ? { elapsedMs: Math.max(0, performance.now() - startedAt) } : {}
29519
- },
29520
- width
29348
+ (width, detail, unbounded) => renderBashTranscriptExecution(
29349
+ { ...execution, ...execution.running ? { elapsedMs: Math.max(0, performance.now() - startedAt) } : {} },
29350
+ width,
29351
+ void 0,
29352
+ { detail, ...unbounded ? { unbounded } : {} }
29521
29353
  ),
29522
- () => execution.running,
29523
- {
29524
- policyFold,
29525
- fold: () => fold,
29526
- setFold: (next) => {
29527
- fold = next;
29528
- deps.ui.requestRender();
29529
- }
29530
- }
29354
+ () => execution.running
29531
29355
  );
29532
29356
  deps.ui.requestRender();
29357
+ deps.onLocalBashRunning?.(true);
29533
29358
  let settlement;
29534
29359
  settlement = (async () => {
29535
29360
  try {
@@ -29572,6 +29397,7 @@ function createEditorSubmitController(deps) {
29572
29397
  deps.io.stderr(`[bash] ${msg}
29573
29398
  `);
29574
29399
  } finally {
29400
+ deps.onLocalBashRunning?.(false);
29575
29401
  if (activeEditorBash === abort) activeEditorBash = null;
29576
29402
  if (activeEditorBashSettlement === settlement) activeEditorBashSettlement = null;
29577
29403
  deps.ui.requestRender();
@@ -30195,7 +30021,6 @@ function askUserInterviewClosedByToolResult(event) {
30195
30021
  return interview?.status === "complete" || interview?.status === "cancelled";
30196
30022
  }
30197
30023
  function createInteractiveEventProjection(deps) {
30198
- const now = deps.now ?? Date.now;
30199
30024
  for (const notice of deps.initialNotices ?? []) {
30200
30025
  const text = notice.trim();
30201
30026
  if (text.length === 0) continue;
@@ -30253,28 +30078,9 @@ function createInteractiveEventProjection(deps) {
30253
30078
  deps.applyChatEvent(event);
30254
30079
  })
30255
30080
  );
30256
- let statusInlineFrame = 0;
30257
30081
  primaryUnsubscribers.push(
30258
30082
  deps.status.subscribe((status) => {
30259
- deps.setLiveReasoning?.(
30260
- status.phase === "idle" || status.phase === "ended" ? null : reasoningFromTally(status.runTally)
30261
- );
30262
- if (status.phase === "idle") {
30263
- deps.setStatusLine(null);
30264
- } else if (status.phase === "ended") {
30265
- deps.setStatusLine(null);
30266
- if (status.summary) deps.setLastTurnSummary(status.summary);
30267
- } else {
30268
- const cols = deps.getTerminalColumns();
30269
- const frame2 = cols < 30 ? "" : `${spinnerFrame2(statusInlineFrame)} `;
30270
- const verb = resolveInlineVerb(status, now(), cols, INLINE_STATUS_INDENT_COLS + visibleWidth(frame2));
30271
- if (verb) {
30272
- deps.setStatusLine({ phase: status.phase, verb: `${frame2}${verb.text}`, toneHint: verb.toneHint });
30273
- statusInlineFrame = (statusInlineFrame + 1) % 10;
30274
- } else {
30275
- deps.setStatusLine(null);
30276
- }
30277
- }
30083
+ if (status.phase === "ended" && status.summary) deps.setLastTurnSummary(status.summary);
30278
30084
  deps.refreshFooter();
30279
30085
  deps.requestRender();
30280
30086
  })
@@ -30585,18 +30391,7 @@ function createInteractiveInputRuntime(deps) {
30585
30391
  deps.requestRender();
30586
30392
  },
30587
30393
  dismissNotifications: () => controller.dismissNotifications(),
30588
- toggleToolExpansion: () => controller.toggleToolExpansion(),
30589
- toggleAllToolExpansion: () => {
30590
- if (deps.chatPanel.toggleAllToolsExpanded()) deps.requestRender();
30591
- },
30592
- toggleLiveToolOutput: () => {
30593
- deps.chatPanel.toggleLiveToolOutput();
30594
- deps.requestRender();
30595
- },
30596
- toggleThinkingExpansion: () => controller.toggleThinkingExpansion(),
30597
- toggleAllThinkingExpansion: () => {
30598
- if (deps.chatPanel.toggleAllThinking()) deps.requestRender();
30599
- },
30394
+ cycleOutputStyle: deps.actions.cycleOutputStyle,
30600
30395
  openExternalEditor: deps.editorSubmit.openExternalEditorForInput,
30601
30396
  queueFollowUp: deps.editorSubmit.queueFollowUpFromEditor,
30602
30397
  interruptWithMessage: deps.editorSubmit.interruptFromEditor,
@@ -30687,10 +30482,6 @@ function createInteractiveInputRuntime(deps) {
30687
30482
  listNotifications: () => deps.notifications.list(),
30688
30483
  dismissNotification: (id) => deps.notifications.dismiss(id),
30689
30484
  dismissAllNotifications: () => deps.notifications.dismissAll(),
30690
- toggleLastToolExpanded: () => deps.chatPanel.toggleLastToolExpanded(),
30691
- toggleAllToolsExpanded: () => deps.chatPanel.toggleAllToolsExpanded(),
30692
- toggleLastThinking: () => deps.chatPanel.toggleLastThinking(),
30693
- toggleAllThinking: () => deps.chatPanel.toggleAllThinking(),
30694
30485
  shutdownDisposers: [
30695
30486
  () => deps.shutdown.stopTickers(),
30696
30487
  () => leaderKeys.dispose(),
@@ -31365,13 +31156,12 @@ function footerLine(entry, width) {
31365
31156
  const units = isPending(entry) || entry.receipt === void 0 ? [pendingUnit(entry)] : footerUnits(entry, entry.receipt);
31366
31157
  return fitUnits(theme5, dim3(FOOTER), units, width);
31367
31158
  }
31368
- function foldedLine(entry, width, expandKey) {
31159
+ function actionLine(entry, width) {
31369
31160
  const identity = `${originGlyph(entry)} ${identityUnits(entry).join(dim3(SEPARATOR2))}`;
31370
31161
  const status = isPending(entry) || entry.receipt === void 0 ? pendingUnit(entry) : outcomeUnit(entry.receipt, false);
31371
31162
  const elapsed = entry.receipt?.durationMs === void 0 ? "" : dim3(`${SEPARATOR2}${formatCompactMs(entry.receipt.durationMs)}`);
31372
- const hint = expandKey === void 0 || expandKey.length === 0 ? "" : dim3(` (${expandKey})`);
31373
- const full = ` ${status}${elapsed}${hint}`;
31374
- let tail = visibleWidth(identity) + visibleWidth(full) <= width ? full : ` ${status}${hint}`;
31163
+ const full = ` ${status}${elapsed}`;
31164
+ let tail = visibleWidth(identity) + visibleWidth(full) <= width ? full : ` ${status}`;
31375
31165
  if (visibleWidth(tail) >= width) tail = ` ${status}`;
31376
31166
  const header = `${truncateToWidth(identity, Math.max(1, width - visibleWidth(tail)), GLYPH.ellipsis, false)}${tail}`;
31377
31167
  return truncateToWidth(header, width, GLYPH.ellipsis, false);
@@ -31383,17 +31173,49 @@ function renderWorkerEntryLines(entry, width, options) {
31383
31173
  "muted",
31384
31174
  safeWidth
31385
31175
  );
31386
- if (options.folded) return [foldedLine(entry, safeWidth, options.expandKey), ...quality];
31387
- const tools = toolLine(entry, safeWidth);
31176
+ const detail = options.detail ?? transcriptDetail();
31177
+ if (options.unbounded) {
31178
+ const tools2 = toolLine(entry, safeWidth);
31179
+ return [
31180
+ headerLine2(entry, safeWidth),
31181
+ ...bodyLines(entry, safeWidth, true),
31182
+ ...attemptLines(entry, safeWidth),
31183
+ ...tools2 ? [tools2] : [],
31184
+ ...failureLines(entry, safeWidth),
31185
+ footerLine(entry, safeWidth),
31186
+ ...quality
31187
+ ].map(redactSecretString);
31188
+ }
31189
+ const budget = (limit) => previewBudget(limit, options.terminalRows);
31190
+ const summary = bodySourceLines(entry).flatMap((line) => railLines(redactSecretString(line), "muted", safeWidth));
31191
+ const actions = entry.progress ? [...entry.progress.recentActions].reverse().concat(entry.progress.currentAction ? [entry.progress.currentAction] : []) : [];
31192
+ const trail = actions.flatMap(
31193
+ (action) => railLines(
31194
+ `${GLYPH.phaseTool} ${action.descriptor ? `${action.descriptor.verb} ${action.descriptor.object}` : action.tool}`,
31195
+ "muted",
31196
+ safeWidth
31197
+ )
31198
+ );
31199
+ const tools = detail.workerActivity && trail.length === 0 ? toolLine(entry, safeWidth) : null;
31200
+ const failure2 = previewRows(failureLines(entry, safeWidth), budget(detail.errorRows), safeWidth);
31201
+ const presented = presentedContractAnswer(entry)?.footer;
31388
31202
  return [
31389
- headerLine2(entry, safeWidth),
31390
- ...bodyLines(entry, safeWidth, options.unbounded === true),
31391
- ...attemptLines(entry, safeWidth),
31392
- ...tools === null ? [] : [tools],
31393
- ...failureLines(entry, safeWidth),
31394
- footerLine(entry, safeWidth),
31203
+ actionLine(entry, safeWidth),
31204
+ ...detail.workerRows > 0 ? previewRows(summary, budget(detail.workerRows), safeWidth, entry.pending) : [],
31205
+ ...previewRows(attemptLines(entry, safeWidth), budget(detail.errorRows), safeWidth, true),
31206
+ ...tools ? [tools] : [],
31207
+ ...detail.workerActivity ? previewRows(trail, budget(4), safeWidth, true) : [],
31208
+ ...failure2,
31209
+ ...presented ? railLines(presented, "muted", safeWidth) : [],
31210
+ ...entry.receipt?.abandonedDetail ? railLines(entry.receipt.abandonedDetail, "warning", safeWidth) : [],
31211
+ ...entry.receipt?.receiptUnavailable ? railLines("receipt unavailable", "warning", safeWidth) : [],
31212
+ ...entry.droppedLines ? railLines(
31213
+ `\u2026 ${entry.droppedLines} earlier lines unavailable here \xB7 /view dispatch:${entry.runId}`,
31214
+ "muted",
31215
+ safeWidth
31216
+ ) : [],
31395
31217
  ...quality
31396
- ];
31218
+ ].map(redactSecretString);
31397
31219
  }
31398
31220
 
31399
31221
  // src/interactive/chat-panel.ts
@@ -31407,8 +31229,6 @@ var RESET = SGR_RESET;
31407
31229
  var DIM = SGR_DIM;
31408
31230
  var TEAL = fgSequence("accent");
31409
31231
  var BLUE_REASON = fgSequence("reason");
31410
- var GREEN_OK = fgSequence("success");
31411
- var AMBER = fgSequence("warning");
31412
31232
  var RED_CRIT = fgSequence("error");
31413
31233
  var AGENT_GLYPH = GLYPH.agent;
31414
31234
  var USER_GLYPH = GLYPH.user;
@@ -31507,9 +31327,6 @@ function scopeTerminalErrorAfterSuccessfulTool(entry, terminalError) {
31507
31327
  );
31508
31328
  return `[error] ${modelFailure}${detachedDispatchSucceeded ? "; detached runs continue" : ""}`;
31509
31329
  }
31510
- function hasThinking(entry) {
31511
- return entry.segments.some((seg) => seg.kind === "thinking" && seg.text.length > 0);
31512
- }
31513
31330
  function openThinkingSegment(entry) {
31514
31331
  const tail = entry.segments[entry.segments.length - 1];
31515
31332
  return tail?.kind === "thinking" && !tail.finalized ? tail : null;
@@ -31537,10 +31354,6 @@ function lastAssistantIndex(transcript, options = {}) {
31537
31354
  }
31538
31355
  return null;
31539
31356
  }
31540
- function hasStreamingText(entry) {
31541
- const tail = entry.segments[entry.segments.length - 1];
31542
- return tail?.kind === "text" && !tail.finalized && tail.text.trim().length > 0;
31543
- }
31544
31357
  function findSkillSuggestionLine(seg) {
31545
31358
  const text = seg.text;
31546
31359
  let at = text.startsWith(SKILL_SUGGESTION_PREFIX) ? 0 : text.indexOf(`
@@ -31623,8 +31436,7 @@ function appendUserRowTail(rendered, tail, width) {
31623
31436
  }
31624
31437
  rendered.push(`${PROSE_GUTTER}${dimLine(tail.trimStart(), Math.max(1, width - PROSE_GUTTER_WIDTH))}`);
31625
31438
  }
31626
- var THINKING_HIDDEN_LABEL = `Thinking${GLYPH.ellipsis}`;
31627
- var THINKING_LINE_LIMIT = 12;
31439
+ var THINKING_HIDDEN_LABEL = "Thinking \xB7 /view";
31628
31440
  function dimLine(text, width) {
31629
31441
  return `${DIM}${truncateToWidth(text, Math.max(1, width), GLYPH.ellipsis, false)}${RESET}`;
31630
31442
  }
@@ -31635,43 +31447,17 @@ function renderSettledThinkingMarker(view, width) {
31635
31447
  width
31636
31448
  );
31637
31449
  }
31638
- function renderLiveReasoningLine(view, elapsedMs, width) {
31639
- const chip = formatReasoningChip(view, compactReasoningTokens);
31640
- const head = chip === null ? THINKING_HIDDEN_LABEL : `Thinking \xB7 ${chip} ${formatReasoningLabel(view)}`;
31641
- const seconds = elapsedMs === void 0 ? 0 : Math.floor(Math.max(0, elapsedMs) / 1e3);
31642
- return dimLine(seconds > 0 ? `${head} \xB7 ${seconds}s` : head, width);
31643
- }
31644
- function renderThinkingRail(thinking, width, streaming, unbounded = false) {
31645
- if (thinking.length === 0) return [];
31646
- const splitLines = thinking.split("\n");
31647
- let visible;
31648
- if (unbounded) {
31649
- visible = splitLines;
31650
- } else if (streaming) {
31651
- if (splitLines.length > THINKING_LINE_LIMIT) {
31652
- const hiddenCount = splitLines.length - THINKING_LINE_LIMIT;
31653
- visible = [`\u2026 ${hiddenCount} earlier lines hidden`, ...splitLines.slice(-THINKING_LINE_LIMIT)];
31654
- } else {
31655
- visible = splitLines;
31656
- }
31657
- } else {
31658
- visible = splitLines.length > THINKING_LINE_LIMIT ? [...splitLines.slice(0, THINKING_LINE_LIMIT), `... ${splitLines.length - THINKING_LINE_LIMIT} more lines hidden`] : splitLines;
31659
- }
31660
- const out = [];
31661
- const bodyWidth = Math.max(1, width - 2);
31662
- for (const raw of visible) {
31663
- const wrappedLines = raw.length === 0 ? [""] : wrapTextWithAnsi(raw, bodyWidth);
31664
- for (const wrapped of wrappedLines) {
31665
- out.push(`${BLUE_REASON}\u2502 ${RESET}${DIM}${wrapped}${RESET}`);
31666
- }
31667
- }
31668
- return out;
31450
+ function renderThinkingRail(thinking, width, limit, unbounded = false) {
31451
+ const rows = wrapTextWithAnsi(redactSecretString(thinking), Math.max(1, width - 2)).map(
31452
+ (row2) => `${BLUE_REASON}\u2502 ${RESET}${DIM}${row2}${RESET}`
31453
+ );
31454
+ return unbounded ? rows : previewRows(rows, limit, width, true);
31669
31455
  }
31670
31456
  function renderTurnUsageLine(usage, width, receipt) {
31671
31457
  if (receipt === "none") return [];
31672
31458
  if (receipt === "compact") {
31673
31459
  const receipt2 = truncateToWidth(
31674
- ` turn \xB7 in ${usage.inputTokens} \xB7 out ${usage.outputTokens}`,
31460
+ ` ${usage.outcome ?? "Done"}${usage.elapsedMs === void 0 ? "" : ` \xB7 ${Math.round(usage.elapsedMs / 1e3)}s`}`,
31675
31461
  width,
31676
31462
  GLYPH.ellipsis,
31677
31463
  false
@@ -31688,90 +31474,47 @@ function renderTurnUsageLine(usage, width, receipt) {
31688
31474
  width
31689
31475
  );
31690
31476
  }
31691
- var STATUS_INDENT = " ".repeat(INLINE_STATUS_INDENT_COLS);
31692
- function styleStatusVerb(text, toneHint) {
31693
- if (toneHint === "error") return `${RED_CRIT}${text}${RESET}`;
31694
- if (toneHint === "warn") return `${AMBER}${text}${RESET}`;
31695
- if (toneHint === "ok") return `${GREEN_OK}${text}${RESET}`;
31696
- return `${DIM}${text}${RESET}`;
31697
- }
31698
- function policySegmentFold(seg, detail) {
31699
- if (!seg.finished) return policyRunningToolFold(detail);
31700
- if (seg.isError && detail.errors === "body") return "expanded";
31701
- return policyToolFold(detail, toolResultPresentationPolicy(seg.result) ?? toolPresentationPolicy(seg.name, seg.args));
31702
- }
31703
- function toolSegmentExpanded(seg, detail) {
31704
- return resolveFold(seg.fold, policySegmentFold(seg, detail)) === "expanded";
31705
- }
31706
- function renderToolSegmentLines(seg, width, expandKey, latestHintToolId, nowMs, unboundedToolBodies, detail, liveToolOutput) {
31707
- const hintKey = seg.id === latestHintToolId ? expandKey : void 0;
31708
- const expanded = toolSegmentExpanded(seg, detail);
31709
- const elapsedMs = seg.startedAtMs !== void 0 ? Math.max(0, rawDurationMs(seg.startedAtMs, nowMs)) : void 0;
31710
- const phase = seg.executionStarted ? "running" : seg.argsComplete ? "ready" : "forming";
31711
- if (!seg.finished && seg.awaitingApproval === true) {
31712
- return renderToolAwaitingApproval(
31713
- { toolCallId: seg.id, toolName: seg.name, args: seg.args },
31714
- width,
31715
- seg.approvalView
31716
- );
31717
- }
31718
- if (!expanded) {
31719
- return renderToolSubline(
31720
- seg.finished ? {
31721
- toolCallId: seg.id,
31722
- toolName: seg.name,
31723
- args: seg.args,
31724
- result: seg.result,
31725
- isError: seg.isError,
31726
- durationMs: seg.durationMs,
31727
- resultSummary: seg.resultSummary,
31728
- outcome: seg.settlement,
31729
- blockReason: seg.blockReason,
31730
- evictedReason: seg.evictedReason
31731
- } : { toolCallId: seg.id, toolName: seg.name, args: seg.args, elapsedMs, phase },
31732
- width,
31733
- hintKey,
31734
- {
31735
- diffStyle: seg.replayed === true ? "plain" : "color",
31736
- foldedExtras: detail.toolBody === "folded" ? "none" : "per-tool"
31737
- }
31738
- );
31739
- }
31740
- if (!seg.finished) {
31741
- if (liveToolOutput && seg.partialResult !== void 0) {
31742
- return renderToolStreamingExecution(
31743
- { toolCallId: seg.id, toolName: seg.name, args: seg.args, elapsedMs, phase },
31744
- width,
31745
- seg.partialResult
31746
- );
31747
- }
31748
- const call = { toolCallId: seg.id, toolName: seg.name, args: seg.args, elapsedMs, phase };
31749
- return liveToolOutput ? renderToolCallHeader(call, width) : renderToolRunningStatus(call, width);
31750
- }
31751
- return renderToolExecution(
31752
- {
31753
- toolCallId: seg.id,
31754
- toolName: seg.name,
31755
- args: seg.args,
31756
- result: seg.result,
31757
- isError: seg.isError,
31758
- durationMs: seg.durationMs,
31759
- resultSummary: seg.resultSummary,
31760
- outcome: seg.settlement,
31761
- blockReason: seg.blockReason,
31762
- evictedReason: seg.evictedReason
31763
- },
31764
- width,
31765
- { unbounded: unboundedToolBodies, diffStyle: seg.replayed === true ? "plain" : "color" }
31766
- );
31767
- }
31768
- function workerEntryFolded(entry, detail) {
31769
- return resolveFold(entry.fold, policyWorkerFold(detail, workerAskedByModel(entry.state))) === "folded";
31770
- }
31771
- function thinkingExpanded(segment, detail) {
31772
- return resolveFold(segment.fold, policyThinkingFold(detail)) === "expanded";
31477
+ function renderToolSegmentLines(seg, width, nowMs, unbounded, detail, terminalRows) {
31478
+ const call = {
31479
+ toolCallId: seg.id,
31480
+ toolName: seg.name,
31481
+ args: seg.args,
31482
+ elapsedMs: seg.startedAtMs === void 0 ? void 0 : Math.max(0, rawDurationMs(seg.startedAtMs, nowMs)),
31483
+ phase: seg.executionStarted ? "running" : seg.argsComplete ? "ready" : "forming"
31484
+ };
31485
+ if (!seg.finished && seg.awaitingApproval) return renderToolAwaitingApproval(call, width, seg.approvalView);
31486
+ if (!seg.finished && !seg.argsComplete && !seg.executionStarted) return [];
31487
+ const finished = {
31488
+ ...call,
31489
+ result: seg.result,
31490
+ isError: seg.isError,
31491
+ durationMs: seg.durationMs,
31492
+ resultSummary: seg.resultSummary,
31493
+ outcome: seg.settlement,
31494
+ blockReason: seg.blockReason,
31495
+ evictedReason: seg.evictedReason
31496
+ };
31497
+ const options = { unbounded, diffStyle: seg.replayed ? "plain" : "color" };
31498
+ if (unbounded && seg.finished) return renderToolExecution(finished, width, options);
31499
+ return renderToolPreview(seg.finished ? finished : call, width, detail, {
31500
+ ...options,
31501
+ terminalRows,
31502
+ partialResult: seg.partialResult
31503
+ });
31773
31504
  }
31774
- function renderEntryLines(entry, width, expandKey, latestHintToolId, latestFoldedWorkerId, nowMs, unboundedToolBodies, detail, liveToolOutput, liveReasoning) {
31505
+ function observation(seg) {
31506
+ if (seg?.kind !== "tool" || !seg.finished) return null;
31507
+ return canGroupObservation({
31508
+ toolCallId: seg.id,
31509
+ toolName: seg.name,
31510
+ result: seg.result,
31511
+ isError: seg.isError,
31512
+ outcome: seg.settlement,
31513
+ evictedReason: seg.evictedReason,
31514
+ resultSummary: seg.resultSummary
31515
+ }) ? seg.name : null;
31516
+ }
31517
+ function renderEntryLines(entry, width, nowMs, unboundedToolBodies, detail, terminalRows) {
31775
31518
  if (entry.role === "replayBlock") {
31776
31519
  return entry.renderBlock(width, detail);
31777
31520
  }
@@ -31790,11 +31533,7 @@ function renderEntryLines(entry, width, expandKey, latestHintToolId, latestFolde
31790
31533
  return wrapTextWithAnsi(formatRetryStatus(entry.status), width);
31791
31534
  }
31792
31535
  if (entry.role === "worker") {
31793
- return renderWorkerEntryLines(entry.state, width, {
31794
- folded: workerEntryFolded(entry, detail),
31795
- ...expandKey !== void 0 && entry.state.assignmentId === latestFoldedWorkerId ? { expandKey } : {},
31796
- unbounded: unboundedToolBodies
31797
- });
31536
+ return renderWorkerEntryLines(entry.state, width, { detail, terminalRows, unbounded: unboundedToolBodies });
31798
31537
  }
31799
31538
  if (!entry.pending && entry.turnUsage === void 0 && !hasVisibleOutput(entry) && entry.segments.length === 0) {
31800
31539
  return [];
@@ -31804,45 +31543,31 @@ function renderEntryLines(entry, width, expandKey, latestHintToolId, latestFolde
31804
31543
  const clioPrefix = entry.isError ? CLIO_PREFIX_ERROR : CLIO_PREFIX;
31805
31544
  const proseWidth = Math.max(1, width - PROSE_GUTTER_WIDTH);
31806
31545
  let labeled = false;
31807
- let liveIndicatorShown = false;
31808
- let latestThinkingExpanded = policyThinkingFold(detail) === "expanded";
31809
31546
  for (let segIndex = 0; segIndex < entry.segments.length; segIndex += 1) {
31810
31547
  const seg = entry.segments[segIndex];
31811
31548
  if (seg === void 0) continue;
31812
31549
  if (seg.kind === "thinking") {
31813
31550
  if (seg.text.length === 0) continue;
31814
- const thinkingExpandedNow = thinkingExpanded(seg, detail);
31815
- latestThinkingExpanded = thinkingExpandedNow;
31816
- const live = entry.pending && !seg.finalized;
31817
- if (thinkingExpandedNow) lines.push(...renderThinkingRail(seg.text, width, live, unboundedToolBodies));
31818
- if (live) {
31819
- liveIndicatorShown = true;
31551
+ if (detail.reasoningRows > 0 || unboundedToolBodies) {
31820
31552
  lines.push(
31821
- detail.thinking === "marker" && !thinkingExpandedNow ? dimLine(THINKING_HIDDEN_LABEL, width) : renderLiveReasoningLine(
31822
- liveReasoning,
31823
- seg.startedAtMs === void 0 ? void 0 : Math.max(0, nowMs - seg.startedAtMs),
31824
- width
31825
- )
31553
+ ...renderThinkingRail(seg.text, width, previewBudget(detail.reasoningRows, terminalRows), unboundedToolBodies)
31826
31554
  );
31827
- } else if (!thinkingExpandedNow) {
31555
+ } else {
31828
31556
  const view = segIndex === chipIndex ? reasoningFromTurnUsage(entry.turnUsage) : UNMEASURED_REASONING;
31829
31557
  lines.push(renderSettledThinkingMarker(view, width));
31830
31558
  }
31831
31559
  continue;
31832
31560
  }
31833
31561
  if (seg.kind === "tool") {
31834
- lines.push(
31835
- ...renderToolSegmentLines(
31836
- seg,
31837
- width,
31838
- expandKey,
31839
- latestHintToolId,
31840
- nowMs,
31841
- unboundedToolBodies,
31842
- detail,
31843
- liveToolOutput
31844
- )
31845
- );
31562
+ const kind = detail.style === "compact" && !unboundedToolBodies ? observation(seg) : null;
31563
+ let count2 = 1;
31564
+ if (kind) {
31565
+ while (entry.segments[segIndex + count2] && observation(entry.segments[segIndex + count2]) === kind) count2++;
31566
+ }
31567
+ if (count2 > 1) {
31568
+ lines.push(dimLine(`\u2713 ${kind === "read" ? `Read ${count2} files` : `${count2} ${kind} actions`} \xB7 /view`, width));
31569
+ segIndex += count2 - 1;
31570
+ } else lines.push(...renderToolSegmentLines(seg, width, nowMs, unboundedToolBodies, detail, terminalRows));
31846
31571
  continue;
31847
31572
  }
31848
31573
  if (seg.kind === "text" && seg.text.length === 0) continue;
@@ -31865,39 +31590,25 @@ function renderEntryLines(entry, width, expandKey, latestHintToolId, latestFolde
31865
31590
  lines.push(...hangProseLines(rendered));
31866
31591
  }
31867
31592
  }
31868
- if (entry.pending && hasThinking(entry) && !liveIndicatorShown) {
31869
- lines.push(
31870
- detail.thinking === "marker" && !latestThinkingExpanded ? dimLine(THINKING_HIDDEN_LABEL, width) : renderLiveReasoningLine(liveReasoning, void 0, width)
31871
- );
31872
- liveIndicatorShown = true;
31873
- }
31874
31593
  if (entry.turnUsage && !entry.pending) lines.push(...renderTurnUsageLine(entry.turnUsage, width, detail.receipt));
31875
- const shouldRenderStatus = entry.pending && entry.statusLine !== null && entry.statusLine !== void 0 && !(entry.statusLine.phase === "writing" && hasStreamingText(entry)) && !(entry.statusLine.phase === "thinking" && liveIndicatorShown);
31876
- if (!labeled && !hasVisibleOutput(entry)) lines.push(clioPrefix.trimEnd());
31877
- if (shouldRenderStatus) {
31878
- lines.push(`${STATUS_INDENT}${styleStatusVerb(entry.statusLine?.verb ?? "", entry.statusLine?.toneHint ?? "muted")}`);
31879
- }
31880
31594
  return lines;
31881
31595
  }
31882
31596
  function createChatPanel(options = {}) {
31883
31597
  const transcript = [];
31884
31598
  const workerEntries = /* @__PURE__ */ new Map();
31885
31599
  let dirty = true;
31600
+ let runStartedAt;
31886
31601
  let cachedWidth;
31887
31602
  let cachedLines = [];
31888
- let cachedExpandKey;
31889
31603
  let cachedDetail;
31890
- let cachedLiveToolOutput;
31891
- let lastVerbosity = null;
31892
31604
  let cachedTick = 0;
31605
+ let cachedTerminalRows = 0;
31893
31606
  let renderedRunningTool = false;
31894
31607
  const entryRenderCache = /* @__PURE__ */ new Map();
31895
31608
  const MIN_ENTRY_RENDER_CACHE = 256;
31896
31609
  const MAX_ENTRY_RENDER_CACHE = 4096;
31897
31610
  const entryCacheCapacity = () => Math.max(MIN_ENTRY_RENDER_CACHE, Math.min(MAX_ENTRY_RENDER_CACHE, transcript.length));
31898
31611
  let frozen = null;
31899
- let liveToolOutput = true;
31900
- let liveReasoning = UNMEASURED_REASONING;
31901
31612
  const unboundedToolBodies = options.unboundedToolBodies === true;
31902
31613
  const markDirty = () => {
31903
31614
  dirty = true;
@@ -31913,31 +31624,8 @@ function createChatPanel(options = {}) {
31913
31624
  const unfreezeTail = () => {
31914
31625
  if (frozen !== null && frozen.through >= transcript.length) frozen = null;
31915
31626
  };
31916
- const resolveExpandKey = () => {
31917
- const key = options.getToolExpandKey?.();
31918
- if (typeof key !== "string" || key.length === 0) return void 0;
31919
- return key;
31920
- };
31921
31627
  const now = () => options.now?.() ?? Date.now();
31922
- const currentDetail = () => transcriptDetail(options.getOutputVerbosity?.());
31923
- const dropFoldOverrides = () => {
31924
- for (const entry of transcript) {
31925
- if (entry.role === "replayBlock") {
31926
- entry.fold?.setFold(void 0);
31927
- continue;
31928
- }
31929
- if (entry.role === "worker") {
31930
- entry.fold = void 0;
31931
- continue;
31932
- }
31933
- if (entry.role !== "assistant") continue;
31934
- for (const seg of entry.segments) {
31935
- if (seg.kind === "tool" || seg.kind === "thinking") seg.fold = void 0;
31936
- }
31937
- }
31938
- clearRenderCaches();
31939
- markDirty();
31940
- };
31628
+ const currentDetail = () => transcriptDetail(options.getOutputStyle?.());
31941
31629
  const settleUnfinishedToolSegment = (seg, settlement = "orphaned") => {
31942
31630
  if (seg.finished) return;
31943
31631
  seg.finished = true;
@@ -32047,26 +31735,6 @@ function createChatPanel(options = {}) {
32047
31735
  if (tail?.kind === "error" && tail.text === text) return;
32048
31736
  entry.segments.push({ kind: "error", text });
32049
31737
  };
32050
- const expandHintOwner = (detail) => {
32051
- let workerMayOwn = true;
32052
- for (let entryIndex = transcript.length - 1; entryIndex >= 0; entryIndex -= 1) {
32053
- const entry = transcript[entryIndex];
32054
- if (entry?.role === "worker") {
32055
- return {
32056
- toolId: null,
32057
- workerId: workerMayOwn && workerEntryFolded(entry, detail) ? entry.state.assignmentId : null
32058
- };
32059
- }
32060
- if (entry?.role !== "assistant") continue;
32061
- for (let segIndex = entry.segments.length - 1; segIndex >= 0; segIndex -= 1) {
32062
- const seg = entry.segments[segIndex];
32063
- if (seg?.kind !== "tool") continue;
32064
- if (seg.finished && !toolSegmentExpanded(seg, detail)) return { toolId: seg.id, workerId: null };
32065
- workerMayOwn = false;
32066
- }
32067
- }
32068
- return { toolId: null, workerId: null };
32069
- };
32070
31738
  const workerInsertionIndex = (state) => {
32071
31739
  const parentToolCallId = state.parentToolCallId;
32072
31740
  if (parentToolCallId === void 0) return null;
@@ -32078,7 +31746,6 @@ function createChatPanel(options = {}) {
32078
31746
  while (transcript[index]?.role === "worker") index += 1;
32079
31747
  return index >= transcript.length ? null : index;
32080
31748
  };
32081
- const entryContainsHint = (entry, latestHintToolId) => latestHintToolId !== null && entry.role === "assistant" && entry.segments.some((segment) => segment.kind === "tool" && segment.id === latestHintToolId);
32082
31749
  const entryHasRunningTool = (entry) => entry.role === "assistant" && (entry.segments.some(
32083
31750
  (segment) => segment.kind === "tool" && !segment.finished && segment.startedAtMs !== void 0
32084
31751
  // The live reasoning line counts its own elapsed, so a turn that is
@@ -32087,19 +31754,15 @@ function createChatPanel(options = {}) {
32087
31754
  const entryIsStable = (entry) => entry.role === "user" && (entry.status?.() ?? "committed") === "committed" || entry.role === "replayBlock" && entry.isLive?.() !== true || entry.role === "worker" && !entry.state.pending || entry.role === "assistant" && !entry.pending && !entry.segments.some((segment) => segment.kind === "tool" && !segment.finished);
32088
31755
  const render2 = (width) => {
32089
31756
  const startedAt = performance4.now();
32090
- const expandKey = resolveExpandKey();
32091
- const verbosity = options.getOutputVerbosity?.();
32092
- if (lastVerbosity !== null && verbosity !== lastVerbosity) dropFoldOverrides();
32093
- lastVerbosity = verbosity;
32094
- const detail = transcriptDetail(verbosity);
31757
+ const detail = currentDetail();
31758
+ const terminalRows = options.getTerminalRows?.() ?? 40;
32095
31759
  const nowMs = now();
32096
31760
  const tick = renderedRunningTool ? Math.floor(nowMs / 100) : 0;
32097
- if (!dirty && cachedWidth === width && cachedExpandKey === expandKey && cachedDetail === detail && cachedLiveToolOutput === liveToolOutput && cachedTick === tick) {
31761
+ if (!dirty && cachedWidth === width && cachedTerminalRows === terminalRows && cachedDetail === detail && cachedTick === tick) {
32098
31762
  options.onRenderMetrics?.({ durationMs: performance4.now() - startedAt, cacheHit: true, entriesRendered: 0 });
32099
31763
  return cachedLines;
32100
31764
  }
32101
- const { toolId: latestHintToolId, workerId: latestFoldedWorkerId } = expandHintOwner(detail);
32102
- const baseKey = `${width}|${expandKey ?? ""}|${detail.toolBody}:${detail.runningTool}:${detail.thinking}:${detail.worker}:${detail.receipt}:${detail.errors}|${liveToolOutput}`;
31765
+ const baseKey = `${width}|${terminalRows}|${detail.style}`;
32103
31766
  const capacity = entryCacheCapacity();
32104
31767
  if (frozen !== null && frozen.key !== baseKey) frozen = null;
32105
31768
  const out = frozen === null ? [] : frozen.lines.slice();
@@ -32114,28 +31777,16 @@ function createChatPanel(options = {}) {
32114
31777
  if (!entry) continue;
32115
31778
  if (!sawRunningTool && entryHasRunningTool(entry)) sawRunningTool = true;
32116
31779
  const previous = i > 0 ? transcript[i - 1] : void 0;
32117
- const stacksOnPrevious = entry.role === "worker" && previous?.role === "worker" && workerEntryFolded(entry, detail) && workerEntryFolded(previous, detail);
31780
+ const stacksOnPrevious = entry.role === "worker" && previous?.role === "worker" && detail.style === "compact";
32118
31781
  if (i > 0 && !stacksOnPrevious) out.push("");
32119
- const containsHint = entryContainsHint(entry, latestHintToolId) || entry.role === "worker" && entry.state.assignmentId === latestFoldedWorkerId;
32120
- const entryKey = containsHint ? `${baseKey}|hint:${latestHintToolId}|${latestFoldedWorkerId}` : baseKey;
31782
+ const entryKey = baseKey;
32121
31783
  const cached = entryRenderCache.get(entry);
32122
31784
  const cacheable = i >= transcript.length - capacity && entry.role !== "replayBlock" && entryIsStable(entry);
32123
31785
  if (cacheable && cached?.key === entryKey) {
32124
31786
  for (const line of cached.lines) out.push(line);
32125
31787
  } else {
32126
31788
  entriesRendered += 1;
32127
- const renderedEntry = renderEntryLines(
32128
- entry,
32129
- width,
32130
- expandKey,
32131
- latestHintToolId,
32132
- latestFoldedWorkerId,
32133
- nowMs,
32134
- unboundedToolBodies,
32135
- detail,
32136
- liveToolOutput,
32137
- liveReasoning
32138
- );
31789
+ const renderedEntry = renderEntryLines(entry, width, nowMs, unboundedToolBodies, detail, terminalRows);
32139
31790
  for (const line of renderedEntry) out.push(line);
32140
31791
  if (cacheable) {
32141
31792
  entryRenderCache.set(entry, { key: entryKey, lines: renderedEntry });
@@ -32146,7 +31797,7 @@ function createChatPanel(options = {}) {
32146
31797
  }
32147
31798
  }
32148
31799
  }
32149
- if (freezeOpen && i === freezeThrough && entryIsStable(entry) && !containsHint) {
31800
+ if (freezeOpen && i === freezeThrough && entryIsStable(entry)) {
32150
31801
  freezeThrough = i + 1;
32151
31802
  freezeLineCount = out.length;
32152
31803
  } else {
@@ -32156,9 +31807,8 @@ function createChatPanel(options = {}) {
32156
31807
  frozen = freezeThrough > 0 ? { lines: out.slice(0, freezeLineCount), through: freezeThrough, key: baseKey } : null;
32157
31808
  cachedLines = out;
32158
31809
  cachedWidth = width;
32159
- cachedExpandKey = expandKey;
32160
31810
  cachedDetail = detail;
32161
- cachedLiveToolOutput = liveToolOutput;
31811
+ cachedTerminalRows = terminalRows;
32162
31812
  cachedTick = tick;
32163
31813
  renderedRunningTool = sawRunningTool;
32164
31814
  dirty = false;
@@ -32170,8 +31820,8 @@ function createChatPanel(options = {}) {
32170
31820
  transcript.push({ role: "user", text, ...status ? { status } : {} });
32171
31821
  markDirty();
32172
31822
  },
32173
- appendReplayBlock(renderBlock, isLive2, fold) {
32174
- transcript.push({ role: "replayBlock", renderBlock, isLive: isLive2, fold });
31823
+ appendReplayBlock(renderBlock, isLive2) {
31824
+ transcript.push({ role: "replayBlock", renderBlock, isLive: isLive2 });
32175
31825
  markDirty();
32176
31826
  },
32177
31827
  applyWorkerState(state) {
@@ -32195,119 +31845,60 @@ function createChatPanel(options = {}) {
32195
31845
  workerStates() {
32196
31846
  return [...workerEntries.values()].map((entry) => entry.state);
32197
31847
  },
32198
- toggleLastToolExpanded() {
32199
- const detail = currentDetail();
32200
- for (let entryIndex = transcript.length - 1; entryIndex >= 0; entryIndex -= 1) {
32201
- const entry = transcript[entryIndex];
32202
- if (entry?.role === "replayBlock" && entry.fold !== void 0) {
32203
- entry.fold.setFold(toggledFold(resolveFold(entry.fold.fold(), entry.fold.policyFold(detail))));
32204
- clearRenderCaches();
32205
- markDirty();
32206
- return true;
32207
- }
32208
- if (entry?.role === "worker") {
32209
- entry.fold = workerEntryFolded(entry, detail) ? "expanded" : "folded";
32210
- clearRenderCaches();
32211
- markDirty();
32212
- return true;
32213
- }
32214
- if (entry?.role !== "assistant") continue;
32215
- for (let segIndex = entry.segments.length - 1; segIndex >= 0; segIndex -= 1) {
32216
- const seg = entry.segments[segIndex];
32217
- if (seg?.kind !== "tool") continue;
32218
- seg.fold = toolSegmentExpanded(seg, detail) ? "folded" : "expanded";
32219
- clearRenderCaches();
32220
- markDirty();
32221
- return true;
32222
- }
32223
- }
32224
- return false;
32225
- },
32226
- toggleAllToolsExpanded() {
32227
- const detail = currentDetail();
32228
- const tools = [];
32229
- const workers = [];
32230
- const blocks = [];
32231
- for (const entry of transcript) {
32232
- if (entry.role === "replayBlock") {
32233
- if (entry.fold !== void 0) blocks.push(entry.fold);
32234
- continue;
32235
- }
32236
- if (entry.role === "worker") {
32237
- workers.push(entry);
32238
- continue;
32239
- }
32240
- if (entry.role !== "assistant") continue;
32241
- for (const seg of entry.segments) {
32242
- if (seg.kind === "tool") tools.push(seg);
32243
- }
32244
- }
32245
- if (tools.length === 0 && workers.length === 0 && blocks.length === 0) return false;
32246
- const expand = tools.some((seg) => !toolSegmentExpanded(seg, detail)) || workers.some((entry) => workerEntryFolded(entry, detail)) || blocks.some((fold) => resolveFold(fold.fold(), fold.policyFold(detail)) === "folded");
32247
- const next = expand ? "expanded" : "folded";
32248
- for (const seg of tools) seg.fold = next;
32249
- for (const entry of workers) entry.fold = next;
32250
- for (const fold of blocks) fold.setFold(next);
32251
- clearRenderCaches();
32252
- markDirty();
32253
- return true;
32254
- },
32255
- clearFoldOverrides() {
32256
- dropFoldOverrides();
32257
- },
32258
- toggleLastThinking() {
32259
- const detail = currentDetail();
32260
- for (let entryIndex = transcript.length - 1; entryIndex >= 0; entryIndex -= 1) {
32261
- const entry = transcript[entryIndex];
32262
- if (entry?.role !== "assistant") continue;
32263
- for (let segIndex = entry.segments.length - 1; segIndex >= 0; segIndex -= 1) {
32264
- const segment = entry.segments[segIndex];
32265
- if (segment?.kind !== "thinking" || segment.text.length === 0) continue;
32266
- segment.fold = thinkingExpanded(segment, detail) ? "folded" : "expanded";
32267
- clearRenderCaches();
32268
- markDirty();
32269
- return true;
32270
- }
32271
- }
32272
- return false;
32273
- },
32274
- toggleAllThinking() {
32275
- const detail = currentDetail();
32276
- const segments = [];
31848
+ inspectionArtifacts() {
31849
+ const artifacts = [];
31850
+ const add = (title, render3) => {
31851
+ const index = artifacts.length;
31852
+ artifacts.push({
31853
+ id: `transcript:${index + 1}`,
31854
+ category: "transcript",
31855
+ title,
31856
+ timestamp: now() + index,
31857
+ searchText: [title],
31858
+ load: async () => ({ format: "text", lines: render3().map(redactSecretString) })
31859
+ });
31860
+ };
32277
31861
  for (const entry of transcript) {
32278
- if (entry.role !== "assistant") continue;
32279
- for (const segment of entry.segments) {
32280
- if (segment.kind === "thinking" && segment.text.length > 0) segments.push(segment);
31862
+ if (entry.role === "assistant") {
31863
+ for (const seg of entry.segments) {
31864
+ if (seg.kind === "thinking" && seg.text) add("Thinking \xB7 supplied reasoning", () => seg.text.split("\n"));
31865
+ if (seg.kind === "tool")
31866
+ add(
31867
+ `${seg.name} \xB7 ${seg.id}`,
31868
+ () => renderToolExecution(
31869
+ {
31870
+ toolCallId: seg.id,
31871
+ toolName: seg.name,
31872
+ args: seg.args,
31873
+ result: seg.result ?? seg.partialResult,
31874
+ isError: seg.isError,
31875
+ outcome: seg.settlement,
31876
+ blockReason: seg.blockReason,
31877
+ resultSummary: seg.resultSummary
31878
+ },
31879
+ 120,
31880
+ { unbounded: true, diffStyle: "plain" }
31881
+ )
31882
+ );
31883
+ }
31884
+ } else if (entry.role === "worker") {
31885
+ add(
31886
+ `${entry.state.agentId} \xB7 worker ${entry.state.runId}`,
31887
+ () => renderWorkerEntryLines(entry.state, 120, { unbounded: true })
31888
+ );
31889
+ } else if (entry.role === "replayBlock") {
31890
+ add("Session action", () => entry.renderBlock(120, transcriptDetail("detailed"), true));
32281
31891
  }
32282
31892
  }
32283
- if (segments.length === 0) return false;
32284
- const expand = segments.some((segment) => !thinkingExpanded(segment, detail));
32285
- for (const segment of segments) segment.fold = expand ? "expanded" : "folded";
32286
- clearRenderCaches();
32287
- markDirty();
32288
- return true;
31893
+ return artifacts;
32289
31894
  },
32290
31895
  isThinkingExpanded() {
32291
- const detail = currentDetail();
32292
- const index = lastAssistantIndex(transcript);
32293
- const entry = index === null ? void 0 : transcript[index];
32294
- if (entry?.role === "assistant") {
32295
- for (let segIndex = entry.segments.length - 1; segIndex >= 0; segIndex -= 1) {
32296
- const segment = entry.segments[segIndex];
32297
- if (segment?.kind === "thinking" && segment.text.length > 0) return thinkingExpanded(segment, detail);
32298
- }
32299
- }
32300
- return policyThinkingFold(detail) === "expanded";
32301
- },
32302
- toggleLiveToolOutput() {
32303
- liveToolOutput = !liveToolOutput;
32304
- markDirty();
32305
- return liveToolOutput;
31896
+ return currentDetail().reasoningRows > 0;
32306
31897
  },
32307
31898
  reset() {
32308
31899
  transcript.length = 0;
31900
+ runStartedAt = void 0;
32309
31901
  workerEntries.clear();
32310
- liveReasoning = UNMEASURED_REASONING;
32311
31902
  clearRenderCaches();
32312
31903
  markDirty();
32313
31904
  },
@@ -32319,6 +31910,10 @@ function createChatPanel(options = {}) {
32319
31910
  markDirty();
32320
31911
  },
32321
31912
  applyEvent(event) {
31913
+ if (event.type === "agent_start") {
31914
+ runStartedAt = now();
31915
+ return;
31916
+ }
32322
31917
  if (event.type === "agent_status") {
32323
31918
  return;
32324
31919
  }
@@ -32537,7 +32132,12 @@ function createChatPanel(options = {}) {
32537
32132
  const target = index === null ? void 0 : transcript[index];
32538
32133
  if (target?.role === "assistant") {
32539
32134
  invalidateEntryCache(target);
32540
- target.turnUsage = runUsage;
32135
+ const stop = event.messages.filter((message) => message.role === "assistant").at(-1);
32136
+ target.turnUsage = {
32137
+ ...runUsage,
32138
+ ...runStartedAt === void 0 ? {} : { elapsedMs: Math.max(0, now() - runStartedAt) },
32139
+ outcome: stop?.stopReason === "error" ? "Failed" : stop?.stopReason === "aborted" ? "Cancelled" : stop?.stopReason === "length" ? "Output limit" : "Done"
32140
+ };
32541
32141
  }
32542
32142
  for (let after = (index ?? -1) + 1; after < transcript.length; after += 1) {
32543
32143
  const later = transcript[after];
@@ -32561,37 +32161,12 @@ function createChatPanel(options = {}) {
32561
32161
  invalidateEntryCache(entry);
32562
32162
  closeOpenThinking(entry);
32563
32163
  entry.pending = false;
32564
- entry.statusLine = null;
32565
32164
  entry.messageStartSegmentIndex = void 0;
32566
32165
  }
32567
32166
  }
32568
32167
  markDirty();
32569
32168
  }
32570
32169
  },
32571
- setLiveReasoning(view) {
32572
- const next = view ?? UNMEASURED_REASONING;
32573
- if (next.tokens === liveReasoning.tokens && next.provenance === liveReasoning.provenance) return;
32574
- liveReasoning = next;
32575
- unfreezeTail();
32576
- const last = transcript[transcript.length - 1];
32577
- if (last !== void 0) invalidateEntryCache(last);
32578
- markDirty();
32579
- },
32580
- setStatusLine(line) {
32581
- if (line) {
32582
- const assistant = ensureAssistant();
32583
- assistant.pending = true;
32584
- assistant.statusLine = line;
32585
- markDirty();
32586
- return;
32587
- }
32588
- const last = transcript[transcript.length - 1];
32589
- if (last && last.role === "assistant") {
32590
- unfreezeTail();
32591
- last.statusLine = null;
32592
- markDirty();
32593
- }
32594
- },
32595
32170
  render: render2,
32596
32171
  invalidate() {
32597
32172
  markDirty();
@@ -32820,7 +32395,7 @@ function statusText(status, now, width, frame2) {
32820
32395
  if (!status || status.phase === "idle") return null;
32821
32396
  const verb = resolveFooterVerb(status, now, width);
32822
32397
  if (!verb) return status.phase.replace(/_/g, " ");
32823
- return status.phase === "ended" ? verb.text : `${spinnerFrame2(frame2)} ${verb.text}`;
32398
+ return status.phase === "ended" || status.phase === "tool_blocked" || status.phase === "stuck" || status.tool?.toolName === "ask_user" ? verb.text : `${spinnerFrame2(frame2)} ${verb.text}`;
32824
32399
  }
32825
32400
  function costSegment(value) {
32826
32401
  const cost = formatCostAggregate(value);
@@ -32851,7 +32426,7 @@ function renderFooterCompactLines(state, width) {
32851
32426
  state.throughput,
32852
32427
  state.sessionTokens,
32853
32428
  state.sessionCost,
32854
- state.session.outputVerbosity,
32429
+ state.session.outputStyle,
32855
32430
  state.session.leaderArmed ?? false,
32856
32431
  state.session.shutdownArmed ?? false
32857
32432
  )
@@ -33058,7 +32633,7 @@ function buildFooterDashboard(deps) {
33058
32633
  capabilities,
33059
32634
  safety,
33060
32635
  toolProfile,
33061
- outputVerbosity: settings?.interface.outputDetail ?? "default",
32636
+ outputStyle: settings?.interface.outputDetail ?? "standard",
33062
32637
  leaderArmed: deps.getLeaderArmed?.() ?? false,
33063
32638
  shutdownArmed: deps.getShutdownArmed?.() ?? false,
33064
32639
  memoryIntervention: taskMemory ? {
@@ -33170,6 +32745,7 @@ function buildFullscreenLayout(parts, options = {}) {
33170
32745
  scrollbarTrackStyle: (text) => theme6.fg("frame", text),
33171
32746
  scrollbarThumbStyle: () => theme6.fg("frameStrong", GLYPH.barFull)
33172
32747
  });
32748
+ options.onTranscript?.(transcript);
33173
32749
  const dock = new VStack();
33174
32750
  if (parts.pending) dock.addChild(parts.pending, { shrink: 1, minSize: 0 });
33175
32751
  dock.addChild(parts.editor, { shrink: 1, minSize: 3 });
@@ -33189,6 +32765,31 @@ function buildLayout(parts, options = {}) {
33189
32765
  root.addChild(parts.footer);
33190
32766
  return root;
33191
32767
  }
32768
+ function preserveTranscriptScroll(view, width, mutation) {
32769
+ if (!view || view.isFollowingEnd) {
32770
+ mutation();
32771
+ return;
32772
+ }
32773
+ const top = view.scrollTop;
32774
+ const before = view.render(width);
32775
+ mutation();
32776
+ const after = view.render(width);
32777
+ for (let row2 = top; row2 < Math.min(before.length, top + view.viewportHeight); row2++) {
32778
+ const anchor = before[row2];
32779
+ if (!anchor?.trim()) continue;
32780
+ let match = -1;
32781
+ for (let index = 0; index < after.length; index++) {
32782
+ if (after[index] === anchor && (match < 0 || Math.abs(index - row2) < Math.abs(match - row2))) match = index;
32783
+ }
32784
+ if (match >= 0) {
32785
+ view.updateLayout(after.length, view.viewportHeight, () => {
32786
+ });
32787
+ view.scrollTo(Math.max(0, match - (row2 - top)), { disableFollow: true });
32788
+ return;
32789
+ }
32790
+ }
32791
+ view.scrollTo(top, { disableFollow: true });
32792
+ }
33192
32793
 
33193
32794
  // src/interactive/slash-autocomplete.ts
33194
32795
  init_esm_shims();
@@ -33198,7 +32799,7 @@ init_esm_shims();
33198
32799
  import { execFile as execFile2 } from "node:child_process";
33199
32800
  import { open, readdir, stat as stat2 } from "node:fs/promises";
33200
32801
  import { homedir as homedir2 } from "node:os";
33201
- import { basename as basename3, dirname, join as join6, relative as relative7, resolve as resolve5, sep as sep2 } from "node:path";
32802
+ import { basename as basename3, dirname, join as join5, relative as relative7, resolve as resolve5, sep as sep2 } from "node:path";
33202
32803
  var MAX_COMPLETION_ROWS = 40;
33203
32804
  var PREVIEW_BYTES = 2048;
33204
32805
  var PREVIEW_CHARS = 120;
@@ -33246,7 +32847,7 @@ function buildWorkspaceSnapshot(basePath, visibleFiles, trackedFiles) {
33246
32847
  const tracked = trackedFiles.has(path2);
33247
32848
  files.push({
33248
32849
  path: path2,
33249
- absolutePath: join6(basePath, path2),
32850
+ absolutePath: join5(basePath, path2),
33250
32851
  isDirectory: false,
33251
32852
  tracked,
33252
32853
  descendantFiles: 0,
@@ -33264,7 +32865,7 @@ function buildWorkspaceSnapshot(basePath, visibleFiles, trackedFiles) {
33264
32865
  const directories = [...directoryFacts].map(
33265
32866
  ([path2, facts]) => ({
33266
32867
  path: path2,
33267
- absolutePath: join6(basePath, path2),
32868
+ absolutePath: join5(basePath, path2),
33268
32869
  isDirectory: true,
33269
32870
  tracked: facts.tracked,
33270
32871
  descendantFiles: facts.descendantFiles,
@@ -33339,7 +32940,7 @@ async function explicitCandidates(basePath, query, trackedFiles) {
33339
32940
  const candidates = [];
33340
32941
  for (const entry of await readdir(directory, { withFileTypes: true })) {
33341
32942
  if (entry.name === ".git" || /[\r\n\0]/u.test(entry.name)) continue;
33342
- const absolutePath = join6(directory, entry.name);
32943
+ const absolutePath = join5(directory, entry.name);
33343
32944
  let isDirectory = entry.isDirectory();
33344
32945
  let isFile = entry.isFile();
33345
32946
  if (!isDirectory && !isFile && entry.isSymbolicLink()) {
@@ -33533,7 +33134,7 @@ function completionGrammar(command, args) {
33533
33134
  ...spec.positionals ? {
33534
33135
  positionals: spec.positionals.map((pos) => {
33535
33136
  const completionSlot = COMPLETION_SLOT_MANIFEST[`${path2}:pos:${pos.name}`];
33536
- const values = command === "output" && pos.name === "verbosity" ? ["minimal", "default", "verbose"] : command === "settings" && pos.name === "area" ? SETTINGS_AREA_IDS : void 0;
33137
+ const values = command === "settings" && pos.name === "area" ? SETTINGS_AREA_IDS : void 0;
33537
33138
  return { ...pos, ...completionSlot ? { completionSlot } : {}, ...values ? { values } : {} };
33538
33139
  })
33539
33140
  } : {},
@@ -33886,7 +33487,7 @@ function processAutoPacingAllowed(backpressureObserved, env = process.env) {
33886
33487
  // src/interactive/welcome-dashboard.ts
33887
33488
  init_esm_shims();
33888
33489
  import { existsSync as existsSync6, readdirSync as readdirSync2, statSync as statSync3 } from "node:fs";
33889
- import { basename as basename4, join as join7 } from "node:path";
33490
+ import { basename as basename4, join as join6 } from "node:path";
33890
33491
  function activeStatus(status) {
33891
33492
  return status.available && status.health.status !== "down";
33892
33493
  }
@@ -33952,14 +33553,14 @@ function wikiFactsFrom(cwd, staleness) {
33952
33553
  };
33953
33554
  }
33954
33555
  function handoffFacts(cwd) {
33955
- const handoffsDir = join7(cwd, ".clio-coder", "handoffs");
33556
+ const handoffsDir = join6(cwd, ".clio-coder", "handoffs");
33956
33557
  if (!existsSync6(handoffsDir)) return { handoffCount: 0, handoffFreshness: "none" };
33957
33558
  try {
33958
33559
  const files = readdirSync2(handoffsDir).filter((f) => f.startsWith("handoff-") && f.endsWith(".md"));
33959
33560
  if (files.length === 0) return { handoffCount: 0, handoffFreshness: "none" };
33960
33561
  let newestMtime = 0;
33961
33562
  for (const file of files) {
33962
- const mtime = statSync3(join7(handoffsDir, file)).mtimeMs;
33563
+ const mtime = statSync3(join6(handoffsDir, file)).mtimeMs;
33963
33564
  if (mtime > newestMtime) newestMtime = mtime;
33964
33565
  }
33965
33566
  return {
@@ -33997,7 +33598,7 @@ async function readWelcomeRepositoryFactsAsync(cwd) {
33997
33598
  function placeholderRepositoryFacts(cwd) {
33998
33599
  return {
33999
33600
  clioMdStatus: clioMdStatusFor(cwd),
34000
- hasCodewiki: existsSync6(join7(cwd, ".clio-coder", "codewiki.json")),
33601
+ hasCodewiki: existsSync6(join6(cwd, ".clio-coder", "codewiki.json")),
34001
33602
  codewikiCount: 0,
34002
33603
  wikiPageCount: 0,
34003
33604
  wikiStatus: NO_WIKI_STATUS,
@@ -34268,11 +33869,8 @@ function createInteractivePresentation(deps) {
34268
33869
  });
34269
33870
  const renderTrace = getActiveRenderTrace();
34270
33871
  const chatPanel = factories.createChatPanel({
34271
- getToolExpandKey: () => {
34272
- const first = keybindings.getKeys("clio-coder.tool.expand")[0];
34273
- return typeof first === "string" && first.length > 0 ? first : void 0;
34274
- },
34275
- getOutputVerbosity: () => deps.getSettings?.().interface.outputDetail ?? "default",
33872
+ getOutputStyle: () => deps.getSettings?.().interface.outputDetail ?? "standard",
33873
+ getTerminalRows: () => process.stdout.rows ?? 40,
34276
33874
  ...renderTrace ? { onRenderMetrics: (metrics) => renderTrace.recordPanelRender(metrics) } : {}
34277
33875
  });
34278
33876
  const followUpQueuePanel = factories.createFollowUpQueuePanel({
@@ -34380,10 +33978,21 @@ function createInteractivePresentation(deps) {
34380
33978
  "memory:seed-offer"
34381
33979
  );
34382
33980
  };
33981
+ let localBashStartedAt = null;
34383
33982
  const footerDeps = {
34384
33983
  providers: deps.providers,
34385
33984
  ...deps.getSettings ? { getSettings: deps.getSettings } : {},
34386
- getAgentStatus: () => statusController.current(),
33985
+ getAgentStatus: () => {
33986
+ const status = statusController.current();
33987
+ if (localBashStartedAt === null || status.phase !== "idle" && status.phase !== "ended") return status;
33988
+ return {
33989
+ ...status,
33990
+ phase: "tool_running",
33991
+ since: localBashStartedAt,
33992
+ toolStartedAt: localBashStartedAt,
33993
+ tool: { toolName: "bash", toolPreview: "local shell" }
33994
+ };
33995
+ },
34387
33996
  getTerminalColumns: () => deps.terminal.columns,
34388
33997
  getSessionTokens: () => observabilitySnapshot.session.tokens,
34389
33998
  getTokenThroughput: () => liveThroughput === null ? observabilitySnapshot.session.latestThroughput : currentLiveThroughput(),
@@ -34529,6 +34138,7 @@ function createInteractivePresentation(deps) {
34529
34138
  followUpQueuePanel.invalidate();
34530
34139
  }
34531
34140
  } : followUpQueuePanel;
34141
+ let transcriptView;
34532
34142
  const root = factories.buildLayout(
34533
34143
  {
34534
34144
  banner,
@@ -34539,14 +34149,17 @@ function createInteractivePresentation(deps) {
34539
34149
  },
34540
34150
  {
34541
34151
  mode: settings.interface?.mode ?? "regular",
34542
- fullscreenScrollbar: settings.interface?.fullscreenScrollbar ?? "auto"
34152
+ fullscreenScrollbar: settings.interface?.fullscreenScrollbar ?? "auto",
34153
+ onTranscript: (view) => {
34154
+ transcriptView = view;
34155
+ }
34543
34156
  }
34544
34157
  );
34545
34158
  deps.mount?.(root, editor);
34546
34159
  const scheduleInterval = deps.scheduleInterval ?? ((callback, intervalMs) => setInterval(callback, intervalMs));
34547
34160
  const clearScheduledInterval = deps.clearScheduledInterval ?? ((handle) => clearInterval(handle));
34548
34161
  const footerTicker = scheduleInterval(() => {
34549
- const statusActive = statusController.current().phase !== "idle";
34162
+ const statusActive = statusController.current().phase !== "idle" || localBashStartedAt !== null;
34550
34163
  if (!deps.chat.isStreaming() && !statusActive && !footer.isExpanded()) return;
34551
34164
  footer.refresh();
34552
34165
  requestRender();
@@ -34610,6 +34223,12 @@ function createInteractivePresentation(deps) {
34610
34223
  chatRenderer,
34611
34224
  io,
34612
34225
  root,
34226
+ setLocalBashRunning(running) {
34227
+ localBashStartedAt = running ? Date.now() : null;
34228
+ footer.refresh();
34229
+ requestRender();
34230
+ },
34231
+ changeOutputStyle: (mutation) => chatRenderer.mutate(() => preserveTranscriptScroll(transcriptView, deps.terminal.columns, mutation), "output-style"),
34613
34232
  getObservabilitySnapshot: () => observabilitySnapshot,
34614
34233
  recordChatEvent,
34615
34234
  recordToolStart: (toolCallId, toolName) => {
@@ -34647,8 +34266,8 @@ function createInteractivePresentation(deps) {
34647
34266
 
34648
34267
  // src/interactive/interactive-slash-runtime.ts
34649
34268
  init_esm_shims();
34650
- import { mkdirSync as mkdirSync2, writeFileSync as writeFileSync2 } from "node:fs";
34651
- import { join as join8, resolve as resolve6 } from "node:path";
34269
+ import { mkdirSync as mkdirSync2, writeFileSync } from "node:fs";
34270
+ import { join as join7, resolve as resolve6 } from "node:path";
34652
34271
 
34653
34272
  // src/interactive/context-recall-command.ts
34654
34273
  init_esm_shims();
@@ -34944,7 +34563,6 @@ function renderSessionHtml(input) {
34944
34563
 
34945
34564
  // src/interactive/interactive-slash-runtime.ts
34946
34565
  var EXPORT_RENDER_WIDTH = 100;
34947
- var OUTPUT_VERBOSITIES = ["minimal", "default", "verbose"];
34948
34566
  function resolveThinkingCapability(providers, settings) {
34949
34567
  const resolved = resolveModelRuntimeCapabilitiesForProviders(
34950
34568
  providers,
@@ -35222,35 +34840,6 @@ function createInteractiveSlashRuntime(deps) {
35222
34840
  if (selected) dispatchSlashCommand({ kind: "thinking-set", level: selected.value }, context);
35223
34841
  });
35224
34842
  },
35225
- setOutputVerbosity: (verbosity) => {
35226
- if (!deps.getSettings || !(deps.commitSetting || deps.writeSettings)) return { status: "unavailable" };
35227
- const requested = verbosity.trim().toLowerCase();
35228
- const match = OUTPUT_VERBOSITIES.find((candidate) => candidate === requested);
35229
- if (!match) return { status: "unsupported", verbosity, supported: OUTPUT_VERBOSITIES };
35230
- const next = structuredClone(deps.getSettings());
35231
- next.interface.outputDetail = match;
35232
- if (deps.commitSetting) deps.commitSetting("interface.outputDetail", next, "session");
35233
- else deps.writeSettings?.(next);
35234
- deps.chatPanel.clearFoldOverrides();
35235
- deps.refreshFooter();
35236
- return { status: "applied", verbosity: match };
35237
- },
35238
- openOutputPicker: () => {
35239
- void deps.openAskUser([
35240
- {
35241
- question: "Choose transcript detail for this session.",
35242
- header: "Output",
35243
- options: OUTPUT_VERBOSITIES.map((value) => ({
35244
- label: `${value[0]?.toUpperCase()}${value.slice(1)}`
35245
- }))
35246
- }
35247
- ]).then((result) => {
35248
- if (result.cancelled) return;
35249
- const answer = result.answers[0]?.answer.toLowerCase();
35250
- const selected = OUTPUT_VERBOSITIES.find((value) => value === answer);
35251
- if (selected) dispatchSlashCommand({ kind: "output-set", verbosity: selected }, context);
35252
- });
35253
- },
35254
34843
  openModel: deps.openModel,
35255
34844
  providers: deps.providers,
35256
34845
  applyModelRef: (ref) => {
@@ -35290,7 +34879,7 @@ function createInteractiveSlashRuntime(deps) {
35290
34879
  }
35291
34880
  try {
35292
34881
  const turns = deps.readStructuredEntries(sessionId);
35293
- const exportPanel = createChatPanel({ unboundedToolBodies: true, getOutputVerbosity: () => "verbose" });
34882
+ const exportPanel = createChatPanel({ unboundedToolBodies: true, getOutputStyle: () => "detailed" });
35294
34883
  const leafTurnId = deps.session?.tree(sessionId).leafId ?? null;
35295
34884
  rehydrateChatPanelFromTurns(exportPanel, turns, {
35296
34885
  unboundedToolBodies: true,
@@ -35302,15 +34891,15 @@ function createInteractiveSlashRuntime(deps) {
35302
34891
  const requestedPath = pathArg?.trim() ?? "";
35303
34892
  const markdown = requestedPath.toLowerCase().endsWith(".md");
35304
34893
  const target = resolve6(
35305
- requestedPath.length > 0 ? requestedPath : join8(".clio-coder", "exports", `${sessionId}-${date}.html`)
34894
+ requestedPath.length > 0 ? requestedPath : join7(".clio-coder", "exports", `${sessionId}-${date}.html`)
35306
34895
  );
35307
34896
  mkdirSync2(resolve6(target, ".."), { recursive: true });
35308
34897
  if (markdown) {
35309
34898
  const lines = ansiLines.map(stripTerminalSequences);
35310
34899
  const header = [`# Clio session ${sessionId}`, "", `Exported ${exportedAt.toISOString()}`, "", "```text"];
35311
- writeFileSync2(target, `${[...header, ...lines, "```", ""].join("\n")}`, "utf8");
34900
+ writeFileSync(target, `${[...header, ...lines, "```", ""].join("\n")}`, "utf8");
35312
34901
  } else {
35313
- writeFileSync2(target, renderSessionHtml({ sessionId, exportedAt: exportedAt.toISOString(), ansiLines }), "utf8");
34902
+ writeFileSync(target, renderSessionHtml({ sessionId, exportedAt: exportedAt.toISOString(), ansiLines }), "utf8");
35314
34903
  }
35315
34904
  appendCommandNotice("success", `[/export] wrote ${ansiLines.length} lines to ${target}`);
35316
34905
  } catch (err) {
@@ -35758,18 +35347,12 @@ function availableInteractiveThinkingLevels(deps) {
35758
35347
  }
35759
35348
  function dispatchInteractiveAction(id, deps) {
35760
35349
  switch (id) {
35350
+ case "clio-coder.output.cycle":
35351
+ deps.cycleOutputStyle();
35352
+ return true;
35761
35353
  case "clio-coder.notifications.dismiss":
35762
35354
  deps.dismissNotifications();
35763
35355
  return true;
35764
- case "clio-coder.tool.expand":
35765
- deps.toggleToolExpansion();
35766
- return true;
35767
- case "clio-coder.tool.expandAll":
35768
- deps.toggleAllToolExpansion();
35769
- return true;
35770
- case "clio-coder.tool.liveOutput":
35771
- deps.toggleLiveToolOutput();
35772
- return true;
35773
35356
  case "clio-coder.editor.external":
35774
35357
  deps.openExternalEditor();
35775
35358
  return true;
@@ -35782,12 +35365,6 @@ function dispatchInteractiveAction(id, deps) {
35782
35365
  case "clio-coder.message.dequeue":
35783
35366
  deps.restoreQueuedFollowUps();
35784
35367
  return true;
35785
- case "clio-coder.thinking.expand":
35786
- deps.toggleThinkingExpansion();
35787
- return true;
35788
- case "clio-coder.thinking.expandAll":
35789
- deps.toggleAllThinkingExpansion();
35790
- return true;
35791
35368
  case "clio-coder.status.toggle":
35792
35369
  deps.toggleStatus();
35793
35370
  return true;
@@ -36004,8 +35581,6 @@ async function createInteractiveApplication(deps) {
36004
35581
  resetAskUserCancellation: () => overlayLifecycle.resetAskUserCancellation(),
36005
35582
  recordToolStart: (toolName, toolCallId) => presentation.recordToolStart(toolCallId, toolName),
36006
35583
  recordToolEnd: (_toolName, toolCallId, isError, truncated) => presentation.recordToolEnd({ toolCallId, isError, truncated }),
36007
- setStatusLine: (line) => chatPanel.setStatusLine(line),
36008
- setLiveReasoning: (view) => chatPanel.setLiveReasoning(view),
36009
35584
  setLastTurnSummary: (summary) => presentation.setLastTurnSummary(summary),
36010
35585
  startTerminalProgress: () => agentProgress.start(),
36011
35586
  stopTerminalProgress: () => agentProgress.stop(),
@@ -36037,8 +35612,7 @@ async function createInteractiveApplication(deps) {
36037
35612
  chat: deps.chat,
36038
35613
  chatPanel: {
36039
35614
  appendReplayBlock: (...args) => chatRenderer.mutate(() => chatPanel.appendReplayBlock(...args), "slash-output"),
36040
- appendUser: (text, status) => chatRenderer.mutate(() => chatPanel.appendUser(text, status), "user-submit"),
36041
- clearFoldOverrides: () => chatRenderer.mutate(() => chatPanel.clearFoldOverrides(), "output-detail")
35615
+ appendUser: (text, status) => chatRenderer.mutate(() => chatPanel.appendUser(text, status), "user-submit")
36042
35616
  },
36043
35617
  beforeSemanticSubmit: () => chatRenderer.flush(),
36044
35618
  settleVisibleFrame: (reason) => chatRenderer.flushAndCommit(reason),
@@ -36113,6 +35687,7 @@ async function createInteractiveApplication(deps) {
36113
35687
  listWorkerRuns: () => chatPanel.workerStates()
36114
35688
  });
36115
35689
  const editorSubmit = createEditorSubmitController({
35690
+ onLocalBashRunning: presentation.setLocalBashRunning,
36116
35691
  editor,
36117
35692
  ui: tui,
36118
35693
  io,
@@ -36334,6 +35909,16 @@ async function createInteractiveApplication(deps) {
36334
35909
  dispatchAction: dispatchInteractiveAction,
36335
35910
  actions: {
36336
35911
  canExit: () => editor.getText().length === 0,
35912
+ cycleOutputStyle: () => {
35913
+ const settings = deps.getSettings?.();
35914
+ if (!settings || !deps.commitSetting) return;
35915
+ presentation.changeOutputStyle(() => {
35916
+ const next = structuredClone(settings);
35917
+ next.interface.outputDetail = nextOutputStyle(next.interface.outputDetail);
35918
+ deps.commitSetting?.("interface.outputDetail", next, "session");
35919
+ });
35920
+ footer.refresh();
35921
+ },
36337
35922
  availableThinkingLevels: () => availableInteractiveThinkingLevels(deps),
36338
35923
  onCycleThinking: () => deps.onCycleThinking?.(),
36339
35924
  cycleScopedModelForward: () => {
@@ -36392,25 +35977,6 @@ async function createInteractiveApplication(deps) {
36392
35977
  editorSubmit,
36393
35978
  requestRender: () => tui.requestRender(),
36394
35979
  notifications,
36395
- chatPanel: {
36396
- toggleLastToolExpanded: () => chatPanel.toggleLastToolExpanded(),
36397
- toggleAllToolsExpanded: () => chatPanel.toggleAllToolsExpanded(),
36398
- toggleLiveToolOutput: () => chatPanel.toggleLiveToolOutput(),
36399
- toggleLastThinking: () => {
36400
- let changed = false;
36401
- chatRenderer.mutate(() => {
36402
- changed = chatPanel.toggleLastThinking();
36403
- }, "thinking-visibility");
36404
- return changed;
36405
- },
36406
- toggleAllThinking: () => {
36407
- let changed = false;
36408
- chatRenderer.mutate(() => {
36409
- changed = chatPanel.toggleAllThinking();
36410
- }, "thinking-visibility");
36411
- return changed;
36412
- }
36413
- },
36414
35980
  shutdown: {
36415
35981
  stopTickers: presentation.stopTickers,
36416
35982
  disposeInteractiveTickers: interactiveTickers.dispose,
@@ -36885,8 +36451,8 @@ function parallelWriterConflict(requests, specs) {
36885
36451
 
36886
36452
  // src/tools/dispatch-scout-admission.ts
36887
36453
  init_esm_shims();
36888
- import { existsSync as existsSync7, readFileSync as readFileSync7 } from "node:fs";
36889
- import { join as join9 } from "node:path";
36454
+ import { existsSync as existsSync7, readFileSync as readFileSync6 } from "node:fs";
36455
+ import { join as join8 } from "node:path";
36890
36456
  function record(value) {
36891
36457
  return typeof value === "object" && value !== null && !Array.isArray(value);
36892
36458
  }
@@ -36932,11 +36498,11 @@ function validateScoutSource(receipt, envelope, agentSpecs) {
36932
36498
  function loadVerifiedScoutSource(input) {
36933
36499
  const envelope = input.dispatch.getRun(input.ref.runId);
36934
36500
  if (envelope === null) throw new Error(`dispatch: Scout source run '${input.ref.runId}' is unavailable`);
36935
- const receiptPath = envelope.receiptPath ?? join9(clioStateDir(), "receipts", `${input.ref.runId}.json`);
36501
+ const receiptPath = envelope.receiptPath ?? join8(clioStateDir(), "receipts", `${input.ref.runId}.json`);
36936
36502
  if (!existsSync7(receiptPath)) throw new Error(`dispatch: Scout source receipt '${input.ref.runId}' is unavailable`);
36937
36503
  let receipt;
36938
36504
  try {
36939
- receipt = JSON.parse(readFileSync7(receiptPath, "utf8"));
36505
+ receipt = JSON.parse(readFileSync6(receiptPath, "utf8"));
36940
36506
  } catch (error) {
36941
36507
  throw new Error(
36942
36508
  `dispatch: Scout source receipt is unreadable: ${error instanceof Error ? error.message : String(error)}`
@@ -38015,7 +37581,7 @@ function createDispatchTool(inputDeps, surfaceOptions = {}) {
38015
37581
  const admission = createDispatchAdmissionController(deps);
38016
37582
  let runnerPromise = null;
38017
37583
  const loadRunner = () => {
38018
- runnerPromise ??= (surfaceOptions.loadRunner ?? (() => import("./dispatch-runner-FRHD6P2O.js")))();
37584
+ runnerPromise ??= (surfaceOptions.loadRunner ?? (() => import("./dispatch-runner-P3ZW6G77.js")))();
38019
37585
  return runnerPromise;
38020
37586
  };
38021
37587
  return {
@@ -38083,7 +37649,7 @@ function registerAllTools(registry, deps = {}) {
38083
37649
  ...builtin(
38084
37650
  lazyTool(
38085
37651
  monitorToolSurface,
38086
- async () => (await import("./monitor-FTJLTKCQ.js")).createMonitorTool({ dispatch, runEvents: dispatchRunEvents })
37652
+ async () => (await import("./monitor-NKVD55HX.js")).createMonitorTool({ dispatch, runEvents: dispatchRunEvents })
38087
37653
  ),
38088
37654
  {
38089
37655
  path: "src/tools/monitor.ts",
@@ -38358,8 +37924,8 @@ function prepareBackgroundMemoryRoute(providers, targetId, wireModelId, timeoutM
38358
37924
  thinkingLevel: "off",
38359
37925
  signal: request.signal,
38360
37926
  timeoutMs,
38361
- onUsage: (observation) => {
38362
- observedUsage = mapUsage(observation);
37927
+ onUsage: (observation2) => {
37928
+ observedUsage = mapUsage(observation2);
38363
37929
  request.onUsage?.(observedUsage);
38364
37930
  },
38365
37931
  ...apiKey === void 0 ? {} : { apiKey },
@@ -38648,7 +38214,7 @@ async function runCompactionFlow(session, settings, providers, instructions, tri
38648
38214
  }
38649
38215
  const entry = {
38650
38216
  kind: "compactionSummary",
38651
- turnId: randomUUID3(),
38217
+ turnId: randomUUID2(),
38652
38218
  parentTurnId: result.firstKeptTurnId ?? null,
38653
38219
  summary: result.summary,
38654
38220
  ...result.skillContext ? { skillContext: result.skillContext } : {},
@@ -38681,7 +38247,7 @@ async function runCompactionFlow(session, settings, providers, instructions, tri
38681
38247
  }
38682
38248
  function compactionCheckpointWasWritten(path2, turnId) {
38683
38249
  let malformed = false;
38684
- for (const line of readFileSync8(path2, "utf8").split("\n")) {
38250
+ for (const line of readFileSync7(path2, "utf8").split("\n")) {
38685
38251
  if (line.trim().length === 0) continue;
38686
38252
  try {
38687
38253
  const entry = JSON.parse(line);
@@ -39132,7 +38698,7 @@ async function bootOrchestrator(options = {}) {
39132
38698
  if (contextDomain) {
39133
38699
  middleware.registerHook(createFileMutationObserver(({ paths }) => contextDomain.noteFileChanges(paths)));
39134
38700
  }
39135
- const hookReceiptLog = createHookReceiptLog({ persistPath: join10(clioStateDir(), "hook-receipts.json") });
38701
+ const hookReceiptLog = createHookReceiptLog({ persistPath: join9(clioStateDir(), "hook-receipts.json") });
39136
38702
  let bootHookNotices = true;
39137
38703
  const extensionReload = createExtensionReloadCoordinator({
39138
38704
  extensions,
@@ -39949,4 +39515,4 @@ export {
39949
39515
  createBackgroundMemoryRouting,
39950
39516
  createProductionAutoCompact
39951
39517
  };
39952
- //# sourceMappingURL=orchestrator-N47O7SFD.js.map
39518
+ //# sourceMappingURL=orchestrator-I6OATVPK.js.map