@north-light/crouter 0.3.318 → 0.3.320

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 (1304) hide show
  1. package/README.md +0 -3
  2. package/dist/api/client.js +2 -912
  3. package/dist/api/dto/attach.js +0 -13
  4. package/dist/api/dto/bash-jobs.js +1 -9
  5. package/dist/api/dto/broker-ops.js +0 -6
  6. package/dist/api/dto/broker.js +0 -20
  7. package/dist/api/dto/canvas.js +0 -2
  8. package/dist/api/dto/chat-inventory.js +0 -11
  9. package/dist/api/dto/common.js +1 -15
  10. package/dist/api/dto/config.js +0 -3
  11. package/dist/api/dto/crons.js +1 -10
  12. package/dist/api/dto/files.js +0 -7
  13. package/dist/api/dto/focus.js +0 -10
  14. package/dist/api/dto/health.js +0 -2
  15. package/dist/api/dto/human-requests.js +0 -4
  16. package/dist/api/dto/human.js +0 -4
  17. package/dist/api/dto/inbox.js +0 -4
  18. package/dist/api/dto/lifecycle.js +0 -3
  19. package/dist/api/dto/mail.js +0 -1
  20. package/dist/api/dto/memory.js +0 -6
  21. package/dist/api/dto/messages.js +0 -2
  22. package/dist/api/dto/model-config.js +0 -1
  23. package/dist/api/dto/modelauth.js +0 -4
  24. package/dist/api/dto/node-outcomes.js +0 -2
  25. package/dist/api/dto/nodes.js +0 -3
  26. package/dist/api/dto/profiles.js +1 -4
  27. package/dist/api/dto/recovery.js +0 -1
  28. package/dist/api/dto/reports.js +0 -2
  29. package/dist/api/dto/review-comments.js +0 -5
  30. package/dist/api/dto/reviews.js +0 -5
  31. package/dist/api/dto/subscriptions.js +0 -2
  32. package/dist/api/dto/worktree.js +0 -6
  33. package/dist/api/errors.js +1 -40
  34. package/dist/api/index.js +1 -33
  35. package/dist/api/plugin-manifest-schema.js +0 -23
  36. package/dist/api/routes.js +1 -147
  37. package/dist/build-root.js +1 -198
  38. package/dist/cli.js +3 -99
  39. package/dist/clients/attach/ansi-cells.js +1 -137
  40. package/dist/clients/attach/chrome/bash-jobs.js +1 -31
  41. package/dist/clients/attach/chrome/canvas-panels.js +1 -194
  42. package/dist/clients/attach/chrome/completion-bell.js +1 -89
  43. package/dist/clients/attach/chrome/cron-wait.js +1 -34
  44. package/dist/clients/attach/chrome/git-info.js +2 -44
  45. package/dist/clients/attach/chrome/header.js +1 -30
  46. package/dist/clients/attach/chrome/inbox-strip.js +1 -199
  47. package/dist/clients/attach/chrome/recap.js +1 -19
  48. package/dist/clients/attach/chrome/review-wait.js +1 -22
  49. package/dist/clients/attach/chrome/roster.js +4 -275
  50. package/dist/clients/attach/chrome/status-line.js +1 -117
  51. package/dist/clients/attach/chrome/ticket-panel.js +1 -280
  52. package/dist/clients/attach/chrome/widgets.js +1 -51
  53. package/dist/clients/attach/command.js +1 -107
  54. package/dist/clients/attach/config.js +1 -274
  55. package/dist/clients/attach/input/capabilities.js +1 -104
  56. package/dist/clients/attach/input/clipboard-image.js +3 -220
  57. package/dist/clients/attach/input/completion-frecency.js +1 -141
  58. package/dist/clients/attach/input/controller.js +7 -377
  59. package/dist/clients/attach/input/overlay-owner.js +1 -199
  60. package/dist/clients/attach/input/ref-autocomplete.js +2 -176
  61. package/dist/clients/attach/input/titled-editor.js +4 -859
  62. package/dist/clients/attach/overlays/auth.js +2 -271
  63. package/dist/clients/attach/overlays/dialogs.js +2 -102
  64. package/dist/clients/attach/overlays/file-review.js +2 -128
  65. package/dist/clients/attach/overlays/graph.js +1 -661
  66. package/dist/clients/attach/overlays/help.js +1 -211
  67. package/dist/clients/attach/overlays/mcp.js +1 -302
  68. package/dist/clients/attach/overlays/pickers.js +1 -163
  69. package/dist/clients/attach/render/activity-slot.js +1 -13
  70. package/dist/clients/attach/render/assistant-message.js +1 -56
  71. package/dist/clients/attach/render/card-presentation.js +5 -218
  72. package/dist/clients/attach/render/chat-view.js +5 -1708
  73. package/dist/clients/attach/render/condensed-history.js +1 -60
  74. package/dist/clients/attach/render/context-message.js +1 -63
  75. package/dist/clients/attach/render/crtr-output.js +17 -905
  76. package/dist/clients/attach/render/diagram.js +7 -111
  77. package/dist/clients/attach/render/edit-diff.js +5 -304
  78. package/dist/clients/attach/render/glyph-codepoints.js +1 -42
  79. package/dist/clients/attach/render/group-activity.js +2 -263
  80. package/dist/clients/attach/render/group-recap.js +1 -152
  81. package/dist/clients/attach/render/markdown-source.js +5 -266
  82. package/dist/clients/attach/render/measured-container.js +1 -322
  83. package/dist/clients/attach/render/page-block.js +1 -183
  84. package/dist/clients/attach/render/scroll-animation.js +1 -80
  85. package/dist/clients/attach/render/tool-calls.js +3 -361
  86. package/dist/clients/attach/render/transcript-copy.js +2 -81
  87. package/dist/clients/attach/render/transcript-search.js +1 -152
  88. package/dist/clients/attach/render/viewport.js +1 -184
  89. package/dist/clients/attach/session/banner.js +1 -29
  90. package/dist/clients/attach/session/bindings.js +1 -71
  91. package/dist/clients/attach/session/chrome-refresh.js +1 -94
  92. package/dist/clients/attach/session/connection.js +1 -186
  93. package/dist/clients/attach/session/context.js +0 -16
  94. package/dist/clients/attach/session/editor-frame.js +1 -142
  95. package/dist/clients/attach/session/editor-inventory.js +6 -160
  96. package/dist/clients/attach/session/file-links.js +1 -68
  97. package/dist/clients/attach/session/focus-events.js +1 -12
  98. package/dist/clients/attach/session/frame.js +1 -214
  99. package/dist/clients/attach/session/frames.js +1 -188
  100. package/dist/clients/attach/session/identity.js +1 -26
  101. package/dist/clients/attach/session/input-wiring.js +1 -140
  102. package/dist/clients/attach/session/invariant.js +1 -15
  103. package/dist/clients/attach/session/keys.js +1 -77
  104. package/dist/clients/attach/session/layout.js +1 -59
  105. package/dist/clients/attach/session/mouse.js +1 -78
  106. package/dist/clients/attach/session/pane-focus.js +1 -42
  107. package/dist/clients/attach/session/pane-tag.js +1 -112
  108. package/dist/clients/attach/session/pi-assets.js +1 -24
  109. package/dist/clients/attach/session/pi-oauth-flows.js +1 -21
  110. package/dist/clients/attach/session/profile-files.js +1 -228
  111. package/dist/clients/attach/session/reconnect.js +1 -175
  112. package/dist/clients/attach/session/selection.js +3 -108
  113. package/dist/clients/attach/session/state-sync.js +1 -67
  114. package/dist/clients/attach/session/surface-frame.js +1 -73
  115. package/dist/clients/attach/session/surface-host.js +1 -255
  116. package/dist/clients/attach/session/teardown.js +5 -94
  117. package/dist/clients/attach/session/transcript-search.js +3 -151
  118. package/dist/clients/attach/session/whip-achievements.js +2 -145
  119. package/dist/clients/attach/session/whip.js +1 -362
  120. package/dist/clients/attach/slash/dispatch.js +1 -706
  121. package/dist/clients/attach/slash/prompt-preview.js +1 -121
  122. package/dist/clients/attach/viewer.js +441 -441
  123. package/dist/clients/conversation/projection.js +1 -324
  124. package/dist/clients/conversation/submit.js +1 -51
  125. package/dist/clients/inbox/controller.js +1 -701
  126. package/dist/clients/inbox/dto-adapt.js +1 -93
  127. package/dist/clients/inbox/layout.js +1 -9
  128. package/dist/clients/inbox/page-adapter.js +1 -55
  129. package/dist/clients/inbox/resolve.js +1 -35
  130. package/dist/clients/inbox/review/anchors.js +1 -89
  131. package/dist/clients/inbox/review/comments-client.js +1 -98
  132. package/dist/clients/inbox/review/companion-pane.js +1 -82
  133. package/dist/clients/inbox/review/document-surface.js +2 -1188
  134. package/dist/clients/inbox/review/frame.js +1 -216
  135. package/dist/clients/inbox/review/keys.js +1 -123
  136. package/dist/clients/inbox/review/launch.js +1 -151
  137. package/dist/clients/inbox/review/live-source.js +1 -160
  138. package/dist/clients/inbox/review/nvim.js +1 -44
  139. package/dist/clients/inbox/review/remap.js +1 -157
  140. package/dist/clients/inbox/review/review-client.js +1 -123
  141. package/dist/clients/inbox/review/roundtrip.js +3 -36
  142. package/dist/clients/inbox/review/state.js +4 -315
  143. package/dist/clients/inbox/review-adapter.js +1 -43
  144. package/dist/clients/inbox/surface.js +1 -152
  145. package/dist/clients/inbox/tui/ansi.js +3 -321
  146. package/dist/clients/inbox/tui/input.js +5 -392
  147. package/dist/clients/inbox/tui/keys.js +1 -104
  148. package/dist/clients/inbox/tui/page-body.js +1 -66
  149. package/dist/clients/inbox/tui/panel.js +1 -84
  150. package/dist/clients/inbox/tui/render.js +2 -368
  151. package/dist/clients/inbox/tui/slots.js +3 -134
  152. package/dist/clients/inbox/tui/types.js +0 -1
  153. package/dist/clients/inbox/tui.js +1 -86
  154. package/dist/clients/surfaces/host.js +0 -1
  155. package/dist/commands/api-client.js +4 -290
  156. package/dist/commands/attention.js +1 -215
  157. package/dist/commands/canvas-browse.js +1 -70
  158. package/dist/commands/canvas-config.js +2 -192
  159. package/dist/commands/canvas-history/grep.js +7 -85
  160. package/dist/commands/canvas-history/read.js +3 -50
  161. package/dist/commands/canvas-history/search.js +10 -99
  162. package/dist/commands/canvas-history/shared.js +1 -139
  163. package/dist/commands/canvas-history/stats.js +6 -68
  164. package/dist/commands/canvas-history.js +1 -32
  165. package/dist/commands/canvas-issue.js +14 -149
  166. package/dist/commands/canvas-prune.js +1 -108
  167. package/dist/commands/canvas-roster.js +1 -69
  168. package/dist/commands/canvas-snapshot.js +1 -34
  169. package/dist/commands/canvas-use.js +1 -61
  170. package/dist/commands/canvas.js +1 -49
  171. package/dist/commands/chord.js +1 -241
  172. package/dist/commands/cron.js +11 -534
  173. package/dist/commands/dashboard.js +1 -85
  174. package/dist/commands/human/components.js +3 -77
  175. package/dist/commands/human/feedback.js +1 -112
  176. package/dist/commands/human/prompts.js +1 -331
  177. package/dist/commands/human/queue.js +1 -191
  178. package/dist/commands/human/request.js +1 -266
  179. package/dist/commands/human/review.js +1 -288
  180. package/dist/commands/human/shared.js +1 -67
  181. package/dist/commands/human.js +4 -60
  182. package/dist/commands/memory/delete.js +1 -100
  183. package/dist/commands/memory/edit.js +21 -219
  184. package/dist/commands/memory/find.js +2 -244
  185. package/dist/commands/memory/history.js +5 -199
  186. package/dist/commands/memory/lint.js +1 -107
  187. package/dist/commands/memory/list.js +1 -142
  188. package/dist/commands/memory/move.js +1 -223
  189. package/dist/commands/memory/origin.js +1 -130
  190. package/dist/commands/memory/read.js +6 -232
  191. package/dist/commands/memory/shared.js +12 -802
  192. package/dist/commands/memory/write.js +13 -235
  193. package/dist/commands/memory.js +1 -30
  194. package/dist/commands/node/bash.js +5 -245
  195. package/dist/commands/node/create.js +3 -332
  196. package/dist/commands/node/inspect.js +12 -300
  197. package/dist/commands/node/lifecycle.js +2 -453
  198. package/dist/commands/node/message.js +1 -161
  199. package/dist/commands/node/outcome.js +4 -134
  200. package/dist/commands/node/pyramid.js +2 -79
  201. package/dist/commands/node/subscription.js +1 -78
  202. package/dist/commands/node/wait.js +7 -163
  203. package/dist/commands/node-context.js +2 -159
  204. package/dist/commands/node-inspect-artifacts.js +8 -109
  205. package/dist/commands/node-lifecycle-revive.js +1 -217
  206. package/dist/commands/node-snapshot.js +1 -37
  207. package/dist/commands/node-transcript.js +1 -62
  208. package/dist/commands/node-worktree.js +1 -138
  209. package/dist/commands/node.js +1 -29
  210. package/dist/commands/pkg/browse/actions.js +1 -198
  211. package/dist/commands/pkg/browse/catalog.js +1 -466
  212. package/dist/commands/pkg/browse/command-view.js +1 -191
  213. package/dist/commands/pkg/browse/detail-panel.js +1 -402
  214. package/dist/commands/pkg/browse/doc-view.js +1 -89
  215. package/dist/commands/pkg/browse/list-panel.js +2 -168
  216. package/dist/commands/pkg/browse/model.js +1 -36
  217. package/dist/commands/pkg/browse/shell.js +1 -640
  218. package/dist/commands/pkg/browse.js +1 -27
  219. package/dist/commands/pkg/market-inspect.js +1 -141
  220. package/dist/commands/pkg/market-manage.js +1 -327
  221. package/dist/commands/pkg/market.js +1 -14
  222. package/dist/commands/pkg/plugin-inspect.js +1 -168
  223. package/dist/commands/pkg/plugin-manage.js +17 -1109
  224. package/dist/commands/pkg/plugin.js +1 -14
  225. package/dist/commands/pkg/shared.js +1 -62
  226. package/dist/commands/pkg.js +1 -21
  227. package/dist/commands/profile/default.js +1 -139
  228. package/dist/commands/profile/delete.js +1 -66
  229. package/dist/commands/profile/env.js +3 -188
  230. package/dist/commands/profile/kind.js +2 -35
  231. package/dist/commands/profile/list.js +1 -43
  232. package/dist/commands/profile/meta.js +1 -67
  233. package/dist/commands/profile/new.js +1 -115
  234. package/dist/commands/profile/pause.js +1 -59
  235. package/dist/commands/profile/project.js +1 -113
  236. package/dist/commands/profile/rename.js +1 -38
  237. package/dist/commands/profile/show.js +1 -52
  238. package/dist/commands/profile.js +1 -35
  239. package/dist/commands/push.js +9 -265
  240. package/dist/commands/revive.js +10 -181
  241. package/dist/commands/surface/node/cycle.js +1 -83
  242. package/dist/commands/surface/node/focus.js +1 -81
  243. package/dist/commands/surface/node/id.js +1 -38
  244. package/dist/commands/surface/node/pin.js +1 -42
  245. package/dist/commands/surface/node/placement.js +1 -134
  246. package/dist/commands/surface-edit.js +1 -157
  247. package/dist/commands/surface-inbox.js +1 -98
  248. package/dist/commands/surface-inspect.js +1 -39
  249. package/dist/commands/surface-node.js +1 -19
  250. package/dist/commands/surface-reload.js +2 -134
  251. package/dist/commands/surface-tmux-spread.js +1 -214
  252. package/dist/commands/surface.js +1 -28
  253. package/dist/commands/sys/branch.js +1 -19
  254. package/dist/commands/sys/config.js +1 -353
  255. package/dist/commands/sys/context/admin/actions.js +2 -246
  256. package/dist/commands/sys/context/admin/detail-panel.js +1 -247
  257. package/dist/commands/sys/context/admin/docs-panel.js +1 -191
  258. package/dist/commands/sys/context/admin/list-view.js +1 -183
  259. package/dist/commands/sys/context/admin/model.js +1 -229
  260. package/dist/commands/sys/context/admin/rail-panel.js +1 -227
  261. package/dist/commands/sys/context/admin/read-view.js +2 -194
  262. package/dist/commands/sys/context/admin/shell.js +1 -910
  263. package/dist/commands/sys/context/admin.js +2 -126
  264. package/dist/commands/sys/context/doc.js +3 -197
  265. package/dist/commands/sys/context/prompt-review.js +11 -291
  266. package/dist/commands/sys/context/resolve.js +10 -489
  267. package/dist/commands/sys/context/sysprompt.js +5 -96
  268. package/dist/commands/sys/context.js +1 -20
  269. package/dist/commands/sys/daemon.js +1 -313
  270. package/dist/commands/sys/doctor.js +1 -617
  271. package/dist/commands/sys/feedback.js +7 -228
  272. package/dist/commands/sys/logs.js +3 -129
  273. package/dist/commands/sys/migrate.js +1 -94
  274. package/dist/commands/sys/panels/broker-limits-panel.js +2 -110
  275. package/dist/commands/sys/panels/dependencies-panel.js +1 -80
  276. package/dist/commands/sys/panels/keybindings-panel.js +1 -703
  277. package/dist/commands/sys/panels/models-panel.js +1 -1133
  278. package/dist/commands/sys/panels/plugins-panel.js +1 -80
  279. package/dist/commands/sys/panels/prefs-panel.js +1 -85
  280. package/dist/commands/sys/panels/profiles-panel.js +1 -601
  281. package/dist/commands/sys/panels/provider-panel.js +1 -538
  282. package/dist/commands/sys/settings-shell.js +1 -400
  283. package/dist/commands/sys/settings.js +1 -46
  284. package/dist/commands/sys/setup-core.js +6 -579
  285. package/dist/commands/sys/setup-settings-runner.js +1 -16
  286. package/dist/commands/sys/setup-wizard.js +1 -279
  287. package/dist/commands/sys/setup.js +1 -34
  288. package/dist/commands/sys/shared.js +1 -81
  289. package/dist/commands/sys/support/prepare.js +3 -239
  290. package/dist/commands/sys/support/submit.js +6 -524
  291. package/dist/commands/sys/support.js +1 -18
  292. package/dist/commands/sys/sync-deps.js +15 -498
  293. package/dist/commands/sys/sync-project-guidance.js +4 -481
  294. package/dist/commands/sys/sync-shared.js +1 -49
  295. package/dist/commands/sys/sync-skills.js +2 -311
  296. package/dist/commands/sys/sync.js +1 -18
  297. package/dist/commands/sys/update.js +1 -147
  298. package/dist/commands/sys/worktrees.js +5 -53
  299. package/dist/commands/sys.js +1 -18
  300. package/dist/core/activity-signal.js +2 -38
  301. package/dist/core/asset-root.js +1 -18
  302. package/dist/core/auth-file.js +2 -179
  303. package/dist/core/auth-interaction.js +3 -94
  304. package/dist/core/auto-update.js +4 -94
  305. package/dist/core/bash-guard.js +11 -393
  306. package/dist/core/bash-jobs.js +7 -411
  307. package/dist/core/bootstrap.js +2 -53
  308. package/dist/core/broker-client/client.js +1 -184
  309. package/dist/core/broker-client/index.js +1 -13
  310. package/dist/core/broker-client/transport-relay.js +1 -157
  311. package/dist/core/broker-client/transport-socket.js +1 -179
  312. package/dist/core/broker-client/transport.js +1 -26
  313. package/dist/core/canvas/attention.js +1 -47
  314. package/dist/core/canvas/boot-id.js +1 -26
  315. package/dist/core/canvas/boot.js +1 -186
  316. package/dist/core/canvas/browse/app.js +3 -919
  317. package/dist/core/canvas/browse/model.js +1 -477
  318. package/dist/core/canvas/browse/pins.js +1 -29
  319. package/dist/core/canvas/browse/render.js +3 -1055
  320. package/dist/core/canvas/canvas.js +15 -922
  321. package/dist/core/canvas/crons.js +11 -481
  322. package/dist/core/canvas/daemon-owner.js +2 -146
  323. package/dist/core/canvas/db.js +2 -100
  324. package/dist/core/canvas/deliveries.js +22 -283
  325. package/dist/core/canvas/delivery-contract.js +1 -8
  326. package/dist/core/canvas/executions.js +1 -68
  327. package/dist/core/canvas/extensions.js +1 -83
  328. package/dist/core/canvas/focuses.js +1 -77
  329. package/dist/core/canvas/history.js +24 -860
  330. package/dist/core/canvas/index.js +1 -15
  331. package/dist/core/canvas/install-id.js +1 -84
  332. package/dist/core/canvas/labels.js +1 -43
  333. package/dist/core/canvas/meta-file.js +1 -89
  334. package/dist/core/canvas/migrations.js +41 -1150
  335. package/dist/core/canvas/nav-model.js +1 -231
  336. package/dist/core/canvas/nav-render.js +1 -260
  337. package/dist/core/canvas/node-order.js +1 -37
  338. package/dist/core/canvas/node-recap.js +2 -67
  339. package/dist/core/canvas/node-sql-migration.js +2 -209
  340. package/dist/core/canvas/paths.js +1 -153
  341. package/dist/core/canvas/pid.js +4 -683
  342. package/dist/core/canvas/recovery.js +3 -565
  343. package/dist/core/canvas/remote-canvas-source.js +1 -288
  344. package/dist/core/canvas/remote-transport.js +1 -57
  345. package/dist/core/canvas/render-source.js +10 -635
  346. package/dist/core/canvas/sessions.js +1 -78
  347. package/dist/core/canvas/source.js +1 -47
  348. package/dist/core/canvas/status-glyph.js +1 -132
  349. package/dist/core/canvas/telemetry.js +1 -35
  350. package/dist/core/canvas/types.js +1 -6
  351. package/dist/core/canvas/waits.js +4 -68
  352. package/dist/core/canvas/worktrees.js +1 -93
  353. package/dist/core/clipboard-text.js +1 -57
  354. package/dist/core/command-hooks/artifact.js +1 -145
  355. package/dist/core/command-hooks/catalog.js +1 -38
  356. package/dist/core/command-hooks/compose.js +1 -99
  357. package/dist/core/command-hooks/discovery.js +1 -228
  358. package/dist/core/command-hooks/help.js +1 -18
  359. package/dist/core/command-hooks/index.js +1 -7
  360. package/dist/core/command-hooks/lifecycle-catalog.js +1 -9
  361. package/dist/core/command-hooks/lifecycle-create.js +1 -51
  362. package/dist/core/command-hooks/report.js +1 -28
  363. package/dist/core/command-hooks/schema.js +1 -157
  364. package/dist/core/command-hooks/transport/exec-invoke.js +1 -276
  365. package/dist/core/command-hooks/transport/exec-lifecycle.js +1 -211
  366. package/dist/core/command-manifests/manifest.js +1 -324
  367. package/dist/core/command-manifests/registry.js +1 -118
  368. package/dist/core/command-manifests/schema.js +1 -736
  369. package/dist/core/command-plugins/bundle.js +1 -261
  370. package/dist/core/command-plugins/compose.js +1 -65
  371. package/dist/core/command-plugins/discovery.js +1 -245
  372. package/dist/core/command-plugins/endpoint.js +1 -48
  373. package/dist/core/command-plugins/extensions.js +1 -166
  374. package/dist/core/command-plugins/help-addenda.js +1 -44
  375. package/dist/core/command-plugins/presence.js +1 -17
  376. package/dist/core/command-plugins/revalidate.js +2 -152
  377. package/dist/core/command-plugins/transport/exec-invoke.js +1 -215
  378. package/dist/core/command-plugins/transport/http-fetch.js +1 -68
  379. package/dist/core/command-plugins/transport/http-invoke.js +3 -546
  380. package/dist/core/command.js +10 -739
  381. package/dist/core/config.js +1 -1059
  382. package/dist/core/document-lines.js +3 -6
  383. package/dist/core/env-name.js +1 -9
  384. package/dist/core/errors.js +1 -52
  385. package/dist/core/events/emit.js +1 -17
  386. package/dist/core/events/envelope.js +1 -84
  387. package/dist/core/events/errors.js +1 -69
  388. package/dist/core/events/index.js +1 -4
  389. package/dist/core/events/operation-id.js +1 -24
  390. package/dist/core/events/read.js +1 -623
  391. package/dist/core/events/serialize.js +1 -199
  392. package/dist/core/events/source.js +1 -31
  393. package/dist/core/events/types.js +1 -11
  394. package/dist/core/exclusive-lock.js +1 -197
  395. package/dist/core/fault-classifier.js +1 -96
  396. package/dist/core/feed/feed.js +7 -202
  397. package/dist/core/feed/inbox-migrate.js +3 -135
  398. package/dist/core/feed/inbox.js +10 -122
  399. package/dist/core/feed/messages.js +6 -212
  400. package/dist/core/frontmatter.js +1 -35
  401. package/dist/core/fs-utils.js +3 -202
  402. package/dist/core/git.js +2 -103
  403. package/dist/core/help.js +9 -310
  404. package/dist/core/host-exports/builtins.js +9 -68
  405. package/dist/core/host-exports/export.js +3 -124
  406. package/dist/core/human/action-binding.js +1 -40
  407. package/dist/core/human/answer-text.js +5 -100
  408. package/dist/core/human/answer.js +1 -119
  409. package/dist/core/human/claim.js +3 -67
  410. package/dist/core/human/completion.js +1 -27
  411. package/dist/core/human/component-docs.js +78 -272
  412. package/dist/core/human/convention.js +2 -82
  413. package/dist/core/human/feedback-companion.js +1 -106
  414. package/dist/core/human/feedback.js +1 -88
  415. package/dist/core/human/page-authoring.js +1 -19
  416. package/dist/core/human/page-catalog.js +1 -172
  417. package/dist/core/human/page-errors.js +1 -7
  418. package/dist/core/human/page-eval.js +1 -125
  419. package/dist/core/human/page-html-markdown.js +8 -260
  420. package/dist/core/human/page-markdown.js +17 -295
  421. package/dist/core/human/page-schema.js +1 -373
  422. package/dist/core/human/page-synth.js +8 -27
  423. package/dist/core/human/page.js +1 -198
  424. package/dist/core/human/requests.js +15 -466
  425. package/dist/core/human/review-schema.js +1 -34
  426. package/dist/core/human/root.js +1 -11
  427. package/dist/core/human/scan.js +1 -69
  428. package/dist/core/human/summary.js +1 -5
  429. package/dist/core/human/tickets.js +1 -171
  430. package/dist/core/human/types.js +0 -1
  431. package/dist/core/human/visible-paths.js +1 -77
  432. package/dist/core/human-actions.js +1 -101
  433. package/dist/core/inspector/chrome.js +1 -14
  434. package/dist/core/inspector/contract.js +0 -1
  435. package/dist/core/inspector/core.js +2 -295
  436. package/dist/core/inspector/host.js +4 -538
  437. package/dist/core/inspector/model.js +2 -226
  438. package/dist/core/inspector/text.js +6 -45
  439. package/dist/core/inspector/transport.js +1 -36
  440. package/dist/core/inspector/tui.js +2 -295
  441. package/dist/core/installed-plugins.js +1 -78
  442. package/dist/core/io.js +7 -356
  443. package/dist/core/keybindings/attach-control.js +1 -42
  444. package/dist/core/keybindings/background-bash.js +1 -33
  445. package/dist/core/keybindings/catalog.js +1 -256
  446. package/dist/core/keybindings/inbox.js +1 -25
  447. package/dist/core/keybindings/index.js +1 -7
  448. package/dist/core/keybindings/match.js +1 -127
  449. package/dist/core/keybindings/persistence.js +1 -49
  450. package/dist/core/keybindings/resolve.js +1 -348
  451. package/dist/core/keybindings/types.js +0 -1
  452. package/dist/core/locked-file.js +1 -118
  453. package/dist/core/log.js +3 -27
  454. package/dist/core/manifest-recovery.js +1 -72
  455. package/dist/core/manifest-stale.js +1 -39
  456. package/dist/core/manifest.js +1 -20
  457. package/dist/core/memory/doc-link-grammar.js +2 -109
  458. package/dist/core/memory/extensions.js +1 -221
  459. package/dist/core/memory/history.js +6 -268
  460. package/dist/core/memory/identity.js +1 -181
  461. package/dist/core/memory/inline-ref-grammar.js +1 -98
  462. package/dist/core/memory/inline-ref-guidance.js +2 -35
  463. package/dist/core/memory/inline-ref-inventory.js +1 -59
  464. package/dist/core/memory/lint.js +2 -671
  465. package/dist/core/memory/project-namespace.js +2 -85
  466. package/dist/core/memory/repository-association.js +1 -129
  467. package/dist/core/memory/tree.js +1 -93
  468. package/dist/core/memory-resolver.js +2 -611
  469. package/dist/core/model-config.js +1 -107
  470. package/dist/core/model-routes.js +1 -201
  471. package/dist/core/nested-stores.js +2 -166
  472. package/dist/core/output.js +7 -99
  473. package/dist/core/pagination.js +1 -88
  474. package/dist/core/plugin-swap-lock.js +1 -31
  475. package/dist/core/pool-credential-store.js +1 -116
  476. package/dist/core/predicate.js +1 -191
  477. package/dist/core/preview-registry.js +2 -411
  478. package/dist/core/preview-result-path.js +1 -26
  479. package/dist/core/profiles/default-binding.js +1 -24
  480. package/dist/core/profiles/deletion-reservation.js +1 -42
  481. package/dist/core/profiles/env-store.js +2 -162
  482. package/dist/core/profiles/fuzzy-match.js +1 -92
  483. package/dist/core/profiles/manifest.js +1 -574
  484. package/dist/core/profiles/select.js +35 -741
  485. package/dist/core/profiles/state-block.js +3 -17
  486. package/dist/core/provider-error-recognition.js +1 -74
  487. package/dist/core/provider-failure.js +1 -86
  488. package/dist/core/provider-management.js +1 -22
  489. package/dist/core/remote-canvas-target.js +1 -30
  490. package/dist/core/render.js +18 -138
  491. package/dist/core/resolver.js +1 -111
  492. package/dist/core/review/birth.js +1 -52
  493. package/dist/core/review/comments.js +5 -279
  494. package/dist/core/review/companion.js +1 -215
  495. package/dist/core/review/document.js +2 -138
  496. package/dist/core/review/project.js +1 -36
  497. package/dist/core/review/realize.js +1 -71
  498. package/dist/core/review/remap.js +4 -141
  499. package/dist/core/review/signal.js +1 -12
  500. package/dist/core/review/stage.js +1 -184
  501. package/dist/core/review/store.js +1 -168
  502. package/dist/core/review/types.js +1 -23
  503. package/dist/core/runtime/advertised-command-invocation.js +1 -233
  504. package/dist/core/runtime/auth-reload.js +1 -67
  505. package/dist/core/runtime/banner.js +1 -51
  506. package/dist/core/runtime/bearings-render.js +18 -250
  507. package/dist/core/runtime/bearings.js +7 -194
  508. package/dist/core/runtime/bin-contributions.js +2 -186
  509. package/dist/core/runtime/boot-root.js +1 -107
  510. package/dist/core/runtime/branded-host.js +2 -264
  511. package/dist/core/runtime/broker/auth-reload.js +1 -157
  512. package/dist/core/runtime/broker/client-registry.js +1 -179
  513. package/dist/core/runtime/broker/daemon-ops.js +1 -88
  514. package/dist/core/runtime/broker/engine-drive.js +1 -354
  515. package/dist/core/runtime/broker/engine-routing.js +1 -211
  516. package/dist/core/runtime/broker/event-projection.js +1 -193
  517. package/dist/core/runtime/broker/extension-abort.js +1 -36
  518. package/dist/core/runtime/broker/fault-retry.js +1 -588
  519. package/dist/core/runtime/broker/frame-client.js +1 -132
  520. package/dist/core/runtime/broker/frame-dispatch.js +1 -183
  521. package/dist/core/runtime/broker/frame-engine-control.js +1 -231
  522. package/dist/core/runtime/broker/frame-memory-refs.js +1 -41
  523. package/dist/core/runtime/broker/frame-model-query.js +1 -69
  524. package/dist/core/runtime/broker/frame-read.js +1 -116
  525. package/dist/core/runtime/broker/frame-replies.js +1 -64
  526. package/dist/core/runtime/broker/frame-session.js +4 -203
  527. package/dist/core/runtime/broker/held-deferred-inbox.js +1 -13
  528. package/dist/core/runtime/broker/inbox.js +13 -163
  529. package/dist/core/runtime/broker/node-named.js +1 -27
  530. package/dist/core/runtime/broker/read-ops.js +1 -171
  531. package/dist/core/runtime/broker/rebind.js +1 -318
  532. package/dist/core/runtime/broker/tool-groups.js +1 -246
  533. package/dist/core/runtime/broker/turn-admission.js +1 -31
  534. package/dist/core/runtime/broker/turn-ignition.js +1 -84
  535. package/dist/core/runtime/broker-cli.js +3 -81
  536. package/dist/core/runtime/broker-extension-render.js +5 -135
  537. package/dist/core/runtime/broker-inventory.js +1 -116
  538. package/dist/core/runtime/broker-persona-guidance.js +4 -154
  539. package/dist/core/runtime/broker-protocol.js +3 -152
  540. package/dist/core/runtime/broker-request.js +1 -85
  541. package/dist/core/runtime/broker-sdk.js +1 -129
  542. package/dist/core/runtime/broker.js +1 -1214
  543. package/dist/core/runtime/canvas-extensions.js +1 -96
  544. package/dist/core/runtime/chat-inventory-rows.js +1 -105
  545. package/dist/core/runtime/close.js +1 -265
  546. package/dist/core/runtime/command-expansion.js +9 -104
  547. package/dist/core/runtime/command-surface.js +1 -117
  548. package/dist/core/runtime/connectivity.js +1 -73
  549. package/dist/core/runtime/deliver-live.js +1 -88
  550. package/dist/core/runtime/fault-recovery.js +1 -83
  551. package/dist/core/runtime/fault.js +1 -17
  552. package/dist/core/runtime/fleet.js +1 -58
  553. package/dist/core/runtime/front-door-env.js +1 -16
  554. package/dist/core/runtime/front-door.js +7 -183
  555. package/dist/core/runtime/headless-pi.js +1 -161
  556. package/dist/core/runtime/host.js +1 -457
  557. package/dist/core/runtime/interactive-deliver.js +1 -51
  558. package/dist/core/runtime/invocation.js +0 -10
  559. package/dist/core/runtime/kickoff.js +30 -327
  560. package/dist/core/runtime/launch-config-worker.js +1 -12
  561. package/dist/core/runtime/launch-prompt.js +4 -13
  562. package/dist/core/runtime/launch-target.js +1 -55
  563. package/dist/core/runtime/launch.js +1 -483
  564. package/dist/core/runtime/lifecycle.js +2 -213
  565. package/dist/core/runtime/managed-provider-cooling.js +1 -62
  566. package/dist/core/runtime/memory.js +1 -17
  567. package/dist/core/runtime/model-registry.js +1 -13
  568. package/dist/core/runtime/model-selection.js +1 -135
  569. package/dist/core/runtime/model-swap.js +1 -86
  570. package/dist/core/runtime/naming.js +14 -298
  571. package/dist/core/runtime/nerd-font.js +2 -127
  572. package/dist/core/runtime/node-read.js +2 -386
  573. package/dist/core/runtime/nodes.js +1 -331
  574. package/dist/core/runtime/outcome-document.js +1 -97
  575. package/dist/core/runtime/package-health.js +4 -99
  576. package/dist/core/runtime/persona.js +2 -55
  577. package/dist/core/runtime/pi-cli.js +1 -65
  578. package/dist/core/runtime/pi-vendored.js +1 -66
  579. package/dist/core/runtime/placement-tmux.js +1 -81
  580. package/dist/core/runtime/placement.js +1 -386
  581. package/dist/core/runtime/promote.js +1 -174
  582. package/dist/core/runtime/prospective-inventory-cli.js +3 -61
  583. package/dist/core/runtime/prospective-inventory.js +2 -88
  584. package/dist/core/runtime/recap.js +27 -103
  585. package/dist/core/runtime/recycle.js +1 -190
  586. package/dist/core/runtime/reopen.js +1 -138
  587. package/dist/core/runtime/reset.js +1 -245
  588. package/dist/core/runtime/resume-root.js +10 -290
  589. package/dist/core/runtime/revive-all.js +1 -107
  590. package/dist/core/runtime/revive.js +4 -544
  591. package/dist/core/runtime/roadmap.js +4 -38
  592. package/dist/core/runtime/session-branch.js +1 -46
  593. package/dist/core/runtime/session-cycles.js +1 -110
  594. package/dist/core/runtime/session-list-cache.js +1 -406
  595. package/dist/core/runtime/session-visibility.js +1 -99
  596. package/dist/core/runtime/shell-expansion.js +9 -100
  597. package/dist/core/runtime/situational-context.js +2 -67
  598. package/dist/core/runtime/situational-live.js +1 -41
  599. package/dist/core/runtime/spawn-env.js +1 -255
  600. package/dist/core/runtime/spawn.js +3 -577
  601. package/dist/core/runtime/stamp/channel.js +1 -76
  602. package/dist/core/runtime/stamp/protocol.js +1 -113
  603. package/dist/core/runtime/stop-guard.js +7 -116
  604. package/dist/core/runtime/stop-signals.js +1 -46
  605. package/dist/core/runtime/stream-watchdog.js +1 -134
  606. package/dist/core/runtime/structured-output.js +4 -156
  607. package/dist/core/runtime/surface-bg.js +1 -85
  608. package/dist/core/runtime/tmux-bindings.js +4 -730
  609. package/dist/core/runtime/tmux-chrome.js +1 -5
  610. package/dist/core/runtime/tmux-driver.js +7 -637
  611. package/dist/core/runtime/tool-group-summary.js +6 -85
  612. package/dist/core/runtime/turn-visibility.js +1 -31
  613. package/dist/core/runtime/view-socket.js +1 -83
  614. package/dist/core/runtime/warm-pool.js +1 -395
  615. package/dist/core/scope.js +1 -254
  616. package/dist/core/scoped-state/db.js +1 -135
  617. package/dist/core/scoped-state/migrate.js +3 -181
  618. package/dist/core/scoped-state/paths.js +1 -27
  619. package/dist/core/scoped-state/profiles.js +1 -62
  620. package/dist/core/scoped-state/providers.js +1 -8
  621. package/dist/core/scoped-state/schema.js +3 -16
  622. package/dist/core/scoped-state/settings.js +1 -82
  623. package/dist/core/secrets.js +2 -55
  624. package/dist/core/self-update.js +1 -71
  625. package/dist/core/session-model/session-state.js +1 -180
  626. package/dist/core/shell-segments.js +4 -169
  627. package/dist/core/spawn.js +1 -26
  628. package/dist/core/stdout-errors.js +1 -14
  629. package/dist/core/subscription-state.js +3 -193
  630. package/dist/core/substrate/frontmatter-validation.js +1 -105
  631. package/dist/core/substrate/gate-explain.js +1 -424
  632. package/dist/core/substrate/gate.js +1 -26
  633. package/dist/core/substrate/index.js +1 -30
  634. package/dist/core/substrate/injected-store.js +1 -249
  635. package/dist/core/substrate/listings.js +1 -115
  636. package/dist/core/substrate/on-read-node.js +1 -36
  637. package/dist/core/substrate/on-read.js +9 -315
  638. package/dist/core/substrate/plan.js +1 -266
  639. package/dist/core/substrate/render-node.js +1 -30
  640. package/dist/core/substrate/render.js +65 -689
  641. package/dist/core/substrate/schema.js +1 -186
  642. package/dist/core/substrate/session-cache.js +1 -83
  643. package/dist/core/substrate/subject-fields.js +1 -35
  644. package/dist/core/substrate/subject.js +1 -47
  645. package/dist/core/substrate/surface-match.js +1 -242
  646. package/dist/core/termrender/code-doc.js +5 -92
  647. package/dist/core/termrender/display.js +2 -56
  648. package/dist/core/termrender/termrender.js +14 -719
  649. package/dist/core/termrender/version.js +1 -1
  650. package/dist/core/timing.js +2 -94
  651. package/dist/core/tui/draw.js +2 -378
  652. package/dist/core/tui/fuzzy.js +1 -38
  653. package/dist/core/tui/markdown.js +3 -407
  654. package/dist/core/tui/page-host.js +1 -74
  655. package/dist/core/tui/panel.js +1 -137
  656. package/dist/core/tui/terminal.js +2 -100
  657. package/dist/core/user-settings.js +1 -454
  658. package/dist/core/wake.js +1 -296
  659. package/dist/core/worktree-close.js +6 -228
  660. package/dist/core/worktree-containment.js +3 -48
  661. package/dist/core/worktree-landing.js +4 -56
  662. package/dist/core/worktree-mutation-async.js +10 -280
  663. package/dist/core/worktree-quarantine.js +1 -54
  664. package/dist/core/worktree-sweep.js +6 -453
  665. package/dist/core/worktree.js +18 -899
  666. package/dist/daemon/api/bridge.js +8 -418
  667. package/dist/daemon/api/handlers/attach.js +1 -65
  668. package/dist/daemon/api/handlers/bash-jobs.js +2 -91
  669. package/dist/daemon/api/handlers/broker-ops.js +1 -447
  670. package/dist/daemon/api/handlers/broker-recovery.js +1 -251
  671. package/dist/daemon/api/handlers/canvas.js +6 -490
  672. package/dist/daemon/api/handlers/chat-inventory.js +1 -25
  673. package/dist/daemon/api/handlers/crons.js +1 -373
  674. package/dist/daemon/api/handlers/daemon.js +1 -76
  675. package/dist/daemon/api/handlers/feedback-comments.js +3 -199
  676. package/dist/daemon/api/handlers/files.js +1 -63
  677. package/dist/daemon/api/handlers/focus.js +1 -92
  678. package/dist/daemon/api/handlers/health.js +1 -76
  679. package/dist/daemon/api/handlers/human-requests.js +1 -379
  680. package/dist/daemon/api/handlers/human.js +1 -3
  681. package/dist/daemon/api/handlers/inbox-page.js +1 -89
  682. package/dist/daemon/api/handlers/inbox.js +1 -301
  683. package/dist/daemon/api/handlers/memory.js +1 -50
  684. package/dist/daemon/api/handlers/messages.js +2 -506
  685. package/dist/daemon/api/handlers/model-config.js +1 -44
  686. package/dist/daemon/api/handlers/modelauth.js +1 -165
  687. package/dist/daemon/api/handlers/node-outcomes.js +1 -181
  688. package/dist/daemon/api/handlers/nodes.js +1 -939
  689. package/dist/daemon/api/handlers/profiles.js +1 -140
  690. package/dist/daemon/api/handlers/prospective-chat-inventory.js +1 -59
  691. package/dist/daemon/api/handlers/reports.js +16 -332
  692. package/dist/daemon/api/handlers/review-comments.js +1 -465
  693. package/dist/daemon/api/handlers/reviews.js +1 -200
  694. package/dist/daemon/api/handlers/subscriptions.js +1 -53
  695. package/dist/daemon/api/handlers/validate.js +1 -58
  696. package/dist/daemon/api/handlers/worktree.js +1 -39
  697. package/dist/daemon/api/map.js +2 -735
  698. package/dist/daemon/api/router.js +1 -190
  699. package/dist/daemon/api/server.js +11 -408
  700. package/dist/daemon/boot-migrations.js +1 -31
  701. package/dist/daemon/companion-retire.js +1 -34
  702. package/dist/daemon/control.js +1 -22
  703. package/dist/daemon/cron/armed-context.js +1 -100
  704. package/dist/daemon/cron/capture.js +2 -45
  705. package/dist/daemon/cron/disposition.js +1 -55
  706. package/dist/daemon/cron/escalation.js +3 -124
  707. package/dist/daemon/cron/held.js +1 -20
  708. package/dist/daemon/cron/lease-recovery.js +1 -119
  709. package/dist/daemon/cron/live-runs.js +1 -23
  710. package/dist/daemon/cron/passes.js +1 -58
  711. package/dist/daemon/cron/settle.js +1 -61
  712. package/dist/daemon/cron/sinks.js +2 -59
  713. package/dist/daemon/cron-run.js +1 -405
  714. package/dist/daemon/crtrd-cli.js +1 -23
  715. package/dist/daemon/crtrd.js +8 -854
  716. package/dist/daemon/delivery/run-delivery.js +1 -164
  717. package/dist/daemon/fleet.js +17 -475
  718. package/dist/daemon/human/finish.js +10 -179
  719. package/dist/daemon/human/settle.js +1 -89
  720. package/dist/daemon/human/sweep.js +1 -66
  721. package/dist/daemon/manage.js +2 -595
  722. package/dist/daemon/messaging/node-message.js +1 -99
  723. package/dist/daemon/park-activity.js +1 -30
  724. package/dist/daemon/park-pending.js +1 -52
  725. package/dist/daemon/pidfile.js +1 -37
  726. package/dist/daemon/profile-delete.js +1 -306
  727. package/dist/daemon/reconcilers/bash-deadline.js +1 -80
  728. package/dist/daemon/reconcilers/broker-supervision.js +4 -761
  729. package/dist/daemon/reconcilers/controller-death.js +1 -14
  730. package/dist/daemon/reconcilers/cron-lane.js +1 -29
  731. package/dist/daemon/reconcilers/delivery-lane.js +1 -130
  732. package/dist/daemon/reconcilers/live-obligation.js +1 -87
  733. package/dist/daemon/reconcilers/managed-worktree-sweep.js +1 -202
  734. package/dist/daemon/reconcilers/node-deadline.js +1 -82
  735. package/dist/daemon/reconcilers/node-lifecycle/freeze-lane.js +1 -172
  736. package/dist/daemon/reconcilers/node-lifecycle/respawn-policy.js +1 -59
  737. package/dist/daemon/reconcilers/node-lifecycle/terminating.js +1 -12
  738. package/dist/daemon/reconcilers/node-lifecycle/tick.js +1 -146
  739. package/dist/daemon/reconcilers/node-lifecycle/wants-execution.js +1 -11
  740. package/dist/daemon/reconcilers/pending-review-submit.js +1 -36
  741. package/dist/daemon/reconcilers/storage-maintenance.js +1 -207
  742. package/dist/daemon/review/comment-notify.js +2 -109
  743. package/dist/daemon/review/companion.js +1 -29
  744. package/dist/daemon/review/deliver.js +3 -8
  745. package/dist/daemon/review/finish.js +1 -122
  746. package/dist/daemon/review/sweep.js +1 -18
  747. package/dist/daemon/startup-policy.js +1 -1
  748. package/dist/daemon/supervise-cadence.js +1 -6
  749. package/dist/hook-authoring.js +5 -447
  750. package/dist/hook-process.js +1 -34
  751. package/dist/index.js +1 -52
  752. package/dist/migrations/001-surfaces-frontmatter.js +1 -161
  753. package/dist/migrations/002-profile-project-memory.js +1 -72
  754. package/dist/migrations/003-repository-root-memory-identity/front-door.js +11 -231
  755. package/dist/migrations/003-repository-root-memory-identity/index.js +5 -513
  756. package/dist/migrations/003-repository-root-memory-identity/references.js +5 -469
  757. package/dist/migrations/003-repository-root-memory-identity/repository-facts.js +3 -349
  758. package/dist/migrations/activation.js +2 -89
  759. package/dist/migrations/convergent.js +2 -82
  760. package/dist/migrations/corpus.js +3 -483
  761. package/dist/migrations/frontmatter-splice.js +8 -176
  762. package/dist/migrations/profile-manifests.js +2 -70
  763. package/dist/migrations/registry.js +1 -42
  764. package/dist/migrations/runner.js +1 -85
  765. package/dist/migrations/types.js +0 -24
  766. package/dist/pi-extensions/broker-local.js +2 -106
  767. package/dist/pi-extensions/canvas-bash-valve.js +7 -461
  768. package/dist/pi-extensions/canvas-context-intro.js +2 -113
  769. package/dist/pi-extensions/canvas-doc-substrate.js +9 -178
  770. package/dist/pi-extensions/canvas-goal-capture.js +1 -83
  771. package/dist/pi-extensions/canvas-inbox-watcher.js +1 -1010
  772. package/dist/pi-extensions/canvas-passive-context.js +14 -203
  773. package/dist/pi-extensions/canvas-preview-result.js +2 -72
  774. package/dist/pi-extensions/canvas-prompt-scrub.js +2 -54
  775. package/dist/pi-extensions/canvas-recap.js +11 -405
  776. package/dist/pi-extensions/canvas-review-boundary.js +3 -63
  777. package/dist/pi-extensions/canvas-stamp.js +2 -77
  778. package/dist/pi-extensions/canvas-stophook.js +1 -643
  779. package/dist/pi-extensions/canvas-structured-output.js +13 -35
  780. package/dist/pi-extensions/canvas-tool-guide.js +9 -78
  781. package/dist/pi-extensions/envelope-merge.js +8 -29
  782. package/dist/prompts/review.js +20 -42
  783. package/dist/shared/birth-announcement.js +1 -25
  784. package/dist/shared/crtr-version.js +1 -18
  785. package/dist/shared/env.js +1 -214
  786. package/dist/shared/generated-context.js +11 -226
  787. package/dist/shared/predicates.js +1 -4
  788. package/dist/shared/shell-quote.js +1 -5
  789. package/dist/shared/tool-groups.js +1 -64
  790. package/dist/shared/working-activity.js +1 -27
  791. package/dist/suppress-experimental-warnings.js +1 -15
  792. package/dist/types.js +1 -185
  793. package/docs/public-api.md +10 -9
  794. package/package.json +6 -4
  795. package/runtime.lock.json +5 -5
  796. package/scripts/pack-minify.mjs +108 -0
  797. package/dist/api/__tests__/integration/client.test.d.ts +0 -1
  798. package/dist/api/__tests__/integration/client.test.js +0 -163
  799. package/dist/builtin-pi-packages/pi-crtr-extensions/__tests__/insights-active-init.test.ts +0 -98
  800. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/__tests__/crtr-commands.test.ts +0 -93
  801. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/__tests__/integration/provider-rotation.test.ts +0 -2530
  802. package/dist/clients/__tests__/helpers/human-daemon.d.ts +0 -11
  803. package/dist/clients/__tests__/helpers/human-daemon.js +0 -60
  804. package/dist/clients/attach/__tests__/attach-remote-readonly.test.d.ts +0 -1
  805. package/dist/clients/attach/__tests__/attach-remote-readonly.test.js +0 -97
  806. package/dist/clients/attach/__tests__/bash-call-width.test.d.ts +0 -1
  807. package/dist/clients/attach/__tests__/bash-call-width.test.js +0 -38
  808. package/dist/clients/attach/__tests__/chat-view-snapshot-ordering.test.d.ts +0 -1
  809. package/dist/clients/attach/__tests__/chat-view-snapshot-ordering.test.js +0 -175
  810. package/dist/clients/attach/__tests__/completion-frecency.test.d.ts +0 -1
  811. package/dist/clients/attach/__tests__/completion-frecency.test.js +0 -35
  812. package/dist/clients/attach/__tests__/context-message.test.d.ts +0 -1
  813. package/dist/clients/attach/__tests__/context-message.test.js +0 -130
  814. package/dist/clients/attach/__tests__/crtr-output.test.d.ts +0 -1
  815. package/dist/clients/attach/__tests__/crtr-output.test.js +0 -68
  816. package/dist/clients/attach/__tests__/diagram.test.d.ts +0 -1
  817. package/dist/clients/attach/__tests__/diagram.test.js +0 -42
  818. package/dist/clients/attach/__tests__/edit-diff.test.d.ts +0 -1
  819. package/dist/clients/attach/__tests__/edit-diff.test.js +0 -31
  820. package/dist/clients/attach/__tests__/frame-selection.test.d.ts +0 -1
  821. package/dist/clients/attach/__tests__/frame-selection.test.js +0 -84
  822. package/dist/clients/attach/__tests__/group-activity.test.d.ts +0 -1
  823. package/dist/clients/attach/__tests__/group-activity.test.js +0 -165
  824. package/dist/clients/attach/__tests__/oauth-dialog-lifecycle.test.d.ts +0 -1
  825. package/dist/clients/attach/__tests__/oauth-dialog-lifecycle.test.js +0 -83
  826. package/dist/clients/attach/__tests__/pane-tag-successor.test.d.ts +0 -1
  827. package/dist/clients/attach/__tests__/pane-tag-successor.test.js +0 -56
  828. package/dist/clients/attach/__tests__/profile-files.test.d.ts +0 -1
  829. package/dist/clients/attach/__tests__/profile-files.test.js +0 -21
  830. package/dist/clients/attach/__tests__/prompt-preview.test.d.ts +0 -1
  831. package/dist/clients/attach/__tests__/prompt-preview.test.js +0 -21
  832. package/dist/clients/attach/__tests__/ref-autocomplete.test.d.ts +0 -1
  833. package/dist/clients/attach/__tests__/ref-autocomplete.test.js +0 -64
  834. package/dist/clients/attach/__tests__/titled-editor-paste.test.d.ts +0 -1
  835. package/dist/clients/attach/__tests__/titled-editor-paste.test.js +0 -114
  836. package/dist/clients/attach/__tests__/titled-editor-preview.test.d.ts +0 -1
  837. package/dist/clients/attach/__tests__/titled-editor-preview.test.js +0 -83
  838. package/dist/clients/inbox/__tests__/integration/inbox-controller.test.d.ts +0 -1
  839. package/dist/clients/inbox/__tests__/integration/inbox-controller.test.js +0 -81
  840. package/dist/clients/inbox/__tests__/integration/mount-panel.test.d.ts +0 -1
  841. package/dist/clients/inbox/__tests__/integration/mount-panel.test.js +0 -135
  842. package/dist/clients/inbox/__tests__/integration/stale-row-activation.test.d.ts +0 -1
  843. package/dist/clients/inbox/__tests__/integration/stale-row-activation.test.js +0 -66
  844. package/dist/clients/inbox/review/__tests__/editor-roundtrip.test.d.ts +0 -1
  845. package/dist/clients/inbox/review/__tests__/editor-roundtrip.test.js +0 -35
  846. package/dist/clients/inbox/review/__tests__/review-core.test.d.ts +0 -1
  847. package/dist/clients/inbox/review/__tests__/review-core.test.js +0 -52
  848. package/dist/clients/inbox/review/__tests__/teardown-notice.test.d.ts +0 -1
  849. package/dist/clients/inbox/review/__tests__/teardown-notice.test.js +0 -100
  850. package/dist/commands/__tests__/api-client-cold-start-diagnostic.test.d.ts +0 -1
  851. package/dist/commands/__tests__/api-client-cold-start-diagnostic.test.js +0 -69
  852. package/dist/commands/__tests__/human.test.d.ts +0 -1
  853. package/dist/commands/__tests__/human.test.js +0 -172
  854. package/dist/commands/__tests__/integration/dashboard-snapshot.test.d.ts +0 -1
  855. package/dist/commands/__tests__/integration/dashboard-snapshot.test.js +0 -237
  856. package/dist/commands/__tests__/integration/migrate.test.d.ts +0 -1
  857. package/dist/commands/__tests__/integration/migrate.test.js +0 -1330
  858. package/dist/commands/__tests__/node-message.test.d.ts +0 -1
  859. package/dist/commands/__tests__/node-message.test.js +0 -112
  860. package/dist/commands/__tests__/node-new.test.d.ts +0 -1
  861. package/dist/commands/__tests__/node-new.test.js +0 -58
  862. package/dist/commands/__tests__/revive-now-gate.test.d.ts +0 -1
  863. package/dist/commands/__tests__/revive-now-gate.test.js +0 -62
  864. package/dist/commands/__tests__/seam/daemon-status.test.d.ts +0 -1
  865. package/dist/commands/__tests__/seam/daemon-status.test.js +0 -29
  866. package/dist/commands/__tests__/surface-reload-target.test.d.ts +0 -1
  867. package/dist/commands/__tests__/surface-reload-target.test.js +0 -21
  868. package/dist/commands/memory/__tests__/command-selector-and-mutation-guards.test.d.ts +0 -1
  869. package/dist/commands/memory/__tests__/command-selector-and-mutation-guards.test.js +0 -379
  870. package/dist/commands/memory/__tests__/memory-list-and-lint-ignore.test.d.ts +0 -1
  871. package/dist/commands/memory/__tests__/memory-list-and-lint-ignore.test.js +0 -124
  872. package/dist/commands/memory/__tests__/repository-root-lint.test.d.ts +0 -1
  873. package/dist/commands/memory/__tests__/repository-root-lint.test.js +0 -148
  874. package/dist/commands/sys/__tests__/config-model-ladders.test.d.ts +0 -1
  875. package/dist/commands/sys/__tests__/config-model-ladders.test.js +0 -114
  876. package/dist/commands/sys/__tests__/setup-core.test.d.ts +0 -1
  877. package/dist/commands/sys/__tests__/setup-core.test.js +0 -45
  878. package/dist/commands/sys/__tests__/sync-project-guidance.test.d.ts +0 -1
  879. package/dist/commands/sys/__tests__/sync-project-guidance.test.js +0 -244
  880. package/dist/core/__tests__/bash-guard.test.d.ts +0 -1
  881. package/dist/core/__tests__/bash-guard.test.js +0 -190
  882. package/dist/core/__tests__/boot-fault-attempt.test.d.ts +0 -1
  883. package/dist/core/__tests__/boot-fault-attempt.test.js +0 -105
  884. package/dist/core/__tests__/boot.test.d.ts +0 -1
  885. package/dist/core/__tests__/boot.test.js +0 -274
  886. package/dist/core/__tests__/branded-host-concurrency.test.d.ts +0 -1
  887. package/dist/core/__tests__/branded-host-concurrency.test.js +0 -72
  888. package/dist/core/__tests__/broker-extension-canvas-db-boundary.test.d.ts +0 -1
  889. package/dist/core/__tests__/broker-extension-canvas-db-boundary.test.js +0 -75
  890. package/dist/core/__tests__/broker-launch-candidates.test.d.ts +0 -1
  891. package/dist/core/__tests__/broker-launch-candidates.test.js +0 -311
  892. package/dist/core/__tests__/broker-preflight.test.d.ts +0 -1
  893. package/dist/core/__tests__/broker-preflight.test.js +0 -95
  894. package/dist/core/__tests__/broker-stream-watchdog-floor.test.d.ts +0 -1
  895. package/dist/core/__tests__/broker-stream-watchdog-floor.test.js +0 -82
  896. package/dist/core/__tests__/broker-turn-admission.test.d.ts +0 -1
  897. package/dist/core/__tests__/broker-turn-admission.test.js +0 -44
  898. package/dist/core/__tests__/canvas-db-boundary.test.d.ts +0 -1
  899. package/dist/core/__tests__/canvas-db-boundary.test.js +0 -46
  900. package/dist/core/__tests__/canvas-inbox-watcher-hold.test.d.ts +0 -1
  901. package/dist/core/__tests__/canvas-inbox-watcher-hold.test.js +0 -710
  902. package/dist/core/__tests__/canvas-inbox-watcher-naming.test.d.ts +0 -1
  903. package/dist/core/__tests__/canvas-inbox-watcher-naming.test.js +0 -310
  904. package/dist/core/__tests__/canvas-inbox-watcher.test.d.ts +0 -1
  905. package/dist/core/__tests__/canvas-inbox-watcher.test.js +0 -397
  906. package/dist/core/__tests__/canvas.test.d.ts +0 -1
  907. package/dist/core/__tests__/canvas.test.js +0 -138
  908. package/dist/core/__tests__/child-death-wake.test.d.ts +0 -1
  909. package/dist/core/__tests__/child-death-wake.test.js +0 -153
  910. package/dist/core/__tests__/cli-help-contract.test.d.ts +0 -1
  911. package/dist/core/__tests__/cli-help-contract.test.js +0 -152
  912. package/dist/core/__tests__/close.test.d.ts +0 -1
  913. package/dist/core/__tests__/close.test.js +0 -284
  914. package/dist/core/__tests__/collectible.test.d.ts +0 -1
  915. package/dist/core/__tests__/collectible.test.js +0 -89
  916. package/dist/core/__tests__/config-change-delta.test.d.ts +0 -1
  917. package/dist/core/__tests__/config-change-delta.test.js +0 -108
  918. package/dist/core/__tests__/context-intro.test.d.ts +0 -1
  919. package/dist/core/__tests__/context-intro.test.js +0 -123
  920. package/dist/core/__tests__/cron-armed-context-failure.test.d.ts +0 -1
  921. package/dist/core/__tests__/cron-armed-context-failure.test.js +0 -150
  922. package/dist/core/__tests__/cron-held-settlement.test.d.ts +0 -1
  923. package/dist/core/__tests__/cron-held-settlement.test.js +0 -240
  924. package/dist/core/__tests__/cron-node-sink-parked-root.test.d.ts +0 -1
  925. package/dist/core/__tests__/cron-node-sink-parked-root.test.js +0 -166
  926. package/dist/core/__tests__/cron-self-cancel-delivery.test.d.ts +0 -1
  927. package/dist/core/__tests__/cron-self-cancel-delivery.test.js +0 -84
  928. package/dist/core/__tests__/cron-timeout-descendants.test.d.ts +0 -1
  929. package/dist/core/__tests__/cron-timeout-descendants.test.js +0 -114
  930. package/dist/core/__tests__/daemon-boot.test.d.ts +0 -1
  931. package/dist/core/__tests__/daemon-boot.test.js +0 -422
  932. package/dist/core/__tests__/daemon-wedge.test.d.ts +0 -1
  933. package/dist/core/__tests__/daemon-wedge.test.js +0 -106
  934. package/dist/core/__tests__/dead-node-policy-table.test.d.ts +0 -1
  935. package/dist/core/__tests__/dead-node-policy-table.test.js +0 -77
  936. package/dist/core/__tests__/events-contract.test.d.ts +0 -1
  937. package/dist/core/__tests__/events-contract.test.js +0 -76
  938. package/dist/core/__tests__/extension-abort.test.d.ts +0 -1
  939. package/dist/core/__tests__/extension-abort.test.js +0 -21
  940. package/dist/core/__tests__/fault-classifier.test.d.ts +0 -1
  941. package/dist/core/__tests__/fault-classifier.test.js +0 -138
  942. package/dist/core/__tests__/fixtures/api-server-host.d.ts +0 -1
  943. package/dist/core/__tests__/fixtures/api-server-host.js +0 -47
  944. package/dist/core/__tests__/fixtures/c3-custom-provider-ext.d.ts +0 -2
  945. package/dist/core/__tests__/fixtures/c3-custom-provider-ext.js +0 -34
  946. package/dist/core/__tests__/fixtures/c5-command-boundary-ext.d.ts +0 -2
  947. package/dist/core/__tests__/fixtures/c5-command-boundary-ext.js +0 -32
  948. package/dist/core/__tests__/fixtures/fake-engine.d.ts +0 -347
  949. package/dist/core/__tests__/fixtures/fake-engine.js +0 -1509
  950. package/dist/core/__tests__/fixtures/fake-pi-host.d.ts +0 -2
  951. package/dist/core/__tests__/fixtures/fake-pi-host.js +0 -311
  952. package/dist/core/__tests__/fixtures/memory-slash-live-probe.d.ts +0 -1
  953. package/dist/core/__tests__/fixtures/memory-slash-live-probe.js +0 -75
  954. package/dist/core/__tests__/fixtures/metadata-migration-race.d.ts +0 -1
  955. package/dist/core/__tests__/fixtures/metadata-migration-race.js +0 -49
  956. package/dist/core/__tests__/focuses.test.d.ts +0 -1
  957. package/dist/core/__tests__/focuses.test.js +0 -113
  958. package/dist/core/__tests__/fs-utils.test.d.ts +0 -1
  959. package/dist/core/__tests__/fs-utils.test.js +0 -50
  960. package/dist/core/__tests__/helpers/broker-clients.d.ts +0 -43
  961. package/dist/core/__tests__/helpers/broker-clients.js +0 -174
  962. package/dist/core/__tests__/helpers/fleet.d.ts +0 -12
  963. package/dist/core/__tests__/helpers/fleet.js +0 -50
  964. package/dist/core/__tests__/helpers/harness.d.ts +0 -124
  965. package/dist/core/__tests__/helpers/harness.js +0 -806
  966. package/dist/core/__tests__/helpers/viewer-panes.d.ts +0 -12
  967. package/dist/core/__tests__/helpers/viewer-panes.js +0 -133
  968. package/dist/core/__tests__/history-inbox.test.d.ts +0 -1
  969. package/dist/core/__tests__/history-inbox.test.js +0 -121
  970. package/dist/core/__tests__/human-action-delivery.test.d.ts +0 -1
  971. package/dist/core/__tests__/human-action-delivery.test.js +0 -162
  972. package/dist/core/__tests__/human-actions.test.d.ts +0 -1
  973. package/dist/core/__tests__/human-actions.test.js +0 -120
  974. package/dist/core/__tests__/inline-memory-refs.test.d.ts +0 -1
  975. package/dist/core/__tests__/inline-memory-refs.test.js +0 -225
  976. package/dist/core/__tests__/integration/broker-fork-seam.test.d.ts +0 -1
  977. package/dist/core/__tests__/integration/broker-fork-seam.test.js +0 -193
  978. package/dist/core/__tests__/integration/broker-sdk-wiring.test.d.ts +0 -1
  979. package/dist/core/__tests__/integration/broker-sdk-wiring.test.js +0 -750
  980. package/dist/core/__tests__/integration/broker-snapshot-history.test.d.ts +0 -1
  981. package/dist/core/__tests__/integration/broker-snapshot-history.test.js +0 -288
  982. package/dist/core/__tests__/integration/broker-wedge-supervision.test.d.ts +0 -1
  983. package/dist/core/__tests__/integration/broker-wedge-supervision.test.js +0 -103
  984. package/dist/core/__tests__/integration/command-plugins.test.d.ts +0 -1
  985. package/dist/core/__tests__/integration/command-plugins.test.js +0 -1200
  986. package/dist/core/__tests__/integration/deferred-no-wake.test.d.ts +0 -1
  987. package/dist/core/__tests__/integration/deferred-no-wake.test.js +0 -610
  988. package/dist/core/__tests__/integration/flagship-lifecycle.test.d.ts +0 -1
  989. package/dist/core/__tests__/integration/flagship-lifecycle.test.js +0 -264
  990. package/dist/core/__tests__/integration/fresh-home-commands.test.d.ts +0 -1
  991. package/dist/core/__tests__/integration/fresh-home-commands.test.js +0 -49
  992. package/dist/core/__tests__/integration/git-optional-locks.test.d.ts +0 -1
  993. package/dist/core/__tests__/integration/git-optional-locks.test.js +0 -81
  994. package/dist/core/__tests__/integration/host-teardown-process-group.test.d.ts +0 -1
  995. package/dist/core/__tests__/integration/host-teardown-process-group.test.js +0 -480
  996. package/dist/core/__tests__/integration/lifecycle-hooks.test.d.ts +0 -1
  997. package/dist/core/__tests__/integration/lifecycle-hooks.test.js +0 -498
  998. package/dist/core/__tests__/integration/live-mutation-verbs.test.d.ts +0 -1
  999. package/dist/core/__tests__/integration/live-mutation-verbs.test.js +0 -180
  1000. package/dist/core/__tests__/integration/live-mutation.test.d.ts +0 -1
  1001. package/dist/core/__tests__/integration/live-mutation.test.js +0 -173
  1002. package/dist/core/__tests__/integration/plugin-revalidate.test.d.ts +0 -1
  1003. package/dist/core/__tests__/integration/plugin-revalidate.test.js +0 -359
  1004. package/dist/core/__tests__/integration/profile-pause.test.d.ts +0 -1
  1005. package/dist/core/__tests__/integration/profile-pause.test.js +0 -115
  1006. package/dist/core/__tests__/integration/refresh-stall-recycle.test.d.ts +0 -1
  1007. package/dist/core/__tests__/integration/refresh-stall-recycle.test.js +0 -151
  1008. package/dist/core/__tests__/integration/revive.test.d.ts +0 -1
  1009. package/dist/core/__tests__/integration/revive.test.js +0 -615
  1010. package/dist/core/__tests__/integration/spawn-root.test.d.ts +0 -1
  1011. package/dist/core/__tests__/integration/spawn-root.test.js +0 -536
  1012. package/dist/core/__tests__/integration/subscription-delivery.test.d.ts +0 -1
  1013. package/dist/core/__tests__/integration/subscription-delivery.test.js +0 -132
  1014. package/dist/core/__tests__/integration/tmux-surface.test.d.ts +0 -1
  1015. package/dist/core/__tests__/integration/tmux-surface.test.js +0 -330
  1016. package/dist/core/__tests__/integration/worktree-land.test.d.ts +0 -1
  1017. package/dist/core/__tests__/integration/worktree-land.test.js +0 -607
  1018. package/dist/core/__tests__/integration/worktree-reap.test.d.ts +0 -1
  1019. package/dist/core/__tests__/integration/worktree-reap.test.js +0 -842
  1020. package/dist/core/__tests__/kickoff.test.d.ts +0 -1
  1021. package/dist/core/__tests__/kickoff.test.js +0 -196
  1022. package/dist/core/__tests__/lifecycle-terminal-reasons.test.d.ts +0 -1
  1023. package/dist/core/__tests__/lifecycle-terminal-reasons.test.js +0 -62
  1024. package/dist/core/__tests__/lifecycle.test.d.ts +0 -1
  1025. package/dist/core/__tests__/lifecycle.test.js +0 -176
  1026. package/dist/core/__tests__/live-lifecycle-prompt.test.d.ts +0 -1
  1027. package/dist/core/__tests__/live-lifecycle-prompt.test.js +0 -63
  1028. package/dist/core/__tests__/memory-resolver-precedence.test.d.ts +0 -1
  1029. package/dist/core/__tests__/memory-resolver-precedence.test.js +0 -228
  1030. package/dist/core/__tests__/migration.test.d.ts +0 -1
  1031. package/dist/core/__tests__/migration.test.js +0 -946
  1032. package/dist/core/__tests__/model-pin-durability.test.d.ts +0 -1
  1033. package/dist/core/__tests__/model-pin-durability.test.js +0 -195
  1034. package/dist/core/__tests__/model-routes-config.test.d.ts +0 -1
  1035. package/dist/core/__tests__/model-routes-config.test.js +0 -150
  1036. package/dist/core/__tests__/nested-store-discovery.test.d.ts +0 -1
  1037. package/dist/core/__tests__/nested-store-discovery.test.js +0 -89
  1038. package/dist/core/__tests__/node-outcome.test.d.ts +0 -1
  1039. package/dist/core/__tests__/node-outcome.test.js +0 -246
  1040. package/dist/core/__tests__/on-read-crouter-home-fence.test.d.ts +0 -1
  1041. package/dist/core/__tests__/on-read-crouter-home-fence.test.js +0 -66
  1042. package/dist/core/__tests__/on-read-dedup-resume.test.d.ts +0 -1
  1043. package/dist/core/__tests__/on-read-dedup-resume.test.js +0 -132
  1044. package/dist/core/__tests__/on-read-nested-store.test.d.ts +0 -1
  1045. package/dist/core/__tests__/on-read-nested-store.test.js +0 -135
  1046. package/dist/core/__tests__/parse-argv-stdin-secret.test.d.ts +0 -1
  1047. package/dist/core/__tests__/parse-argv-stdin-secret.test.js +0 -68
  1048. package/dist/core/__tests__/passive-subscription.test.d.ts +0 -1
  1049. package/dist/core/__tests__/passive-subscription.test.js +0 -120
  1050. package/dist/core/__tests__/pid-identity-match.test.d.ts +0 -1
  1051. package/dist/core/__tests__/pid-identity-match.test.js +0 -145
  1052. package/dist/core/__tests__/pid-zombie.test.d.ts +0 -1
  1053. package/dist/core/__tests__/pid-zombie.test.js +0 -42
  1054. package/dist/core/__tests__/plugin-kinds.test.d.ts +0 -1
  1055. package/dist/core/__tests__/plugin-kinds.test.js +0 -182
  1056. package/dist/core/__tests__/plugin-link-symlinked-scope-root.test.d.ts +0 -1
  1057. package/dist/core/__tests__/plugin-link-symlinked-scope-root.test.js +0 -43
  1058. package/dist/core/__tests__/plugin-page-components.test.d.ts +0 -1
  1059. package/dist/core/__tests__/plugin-page-components.test.js +0 -159
  1060. package/dist/core/__tests__/preview-mirror-cap.test.d.ts +0 -1
  1061. package/dist/core/__tests__/preview-mirror-cap.test.js +0 -53
  1062. package/dist/core/__tests__/preview-registry-sync.test.d.ts +0 -1
  1063. package/dist/core/__tests__/preview-registry-sync.test.js +0 -107
  1064. package/dist/core/__tests__/profile-project-memory-delivery.test.d.ts +0 -1
  1065. package/dist/core/__tests__/profile-project-memory-delivery.test.js +0 -644
  1066. package/dist/core/__tests__/prospective-inventory-capability-parity.test.d.ts +0 -1
  1067. package/dist/core/__tests__/prospective-inventory-capability-parity.test.js +0 -91
  1068. package/dist/core/__tests__/prune.test.d.ts +0 -1
  1069. package/dist/core/__tests__/prune.test.js +0 -243
  1070. package/dist/core/__tests__/push-final-guard.test.d.ts +0 -1
  1071. package/dist/core/__tests__/push-final-guard.test.js +0 -191
  1072. package/dist/core/__tests__/relaunch-root.test.d.ts +0 -1
  1073. package/dist/core/__tests__/relaunch-root.test.js +0 -249
  1074. package/dist/core/__tests__/remote-canvas-target.test.d.ts +0 -1
  1075. package/dist/core/__tests__/remote-canvas-target.test.js +0 -93
  1076. package/dist/core/__tests__/repository-association.test.d.ts +0 -1
  1077. package/dist/core/__tests__/repository-association.test.js +0 -153
  1078. package/dist/core/__tests__/repository-root-identity.test.d.ts +0 -1
  1079. package/dist/core/__tests__/repository-root-identity.test.js +0 -223
  1080. package/dist/core/__tests__/respawn-throttle.test.d.ts +0 -1
  1081. package/dist/core/__tests__/respawn-throttle.test.js +0 -20
  1082. package/dist/core/__tests__/review-model-floor.test.d.ts +0 -1
  1083. package/dist/core/__tests__/review-model-floor.test.js +0 -83
  1084. package/dist/core/__tests__/revive-all.test.d.ts +0 -1
  1085. package/dist/core/__tests__/revive-all.test.js +0 -157
  1086. package/dist/core/__tests__/revive-capacity.test.d.ts +0 -1
  1087. package/dist/core/__tests__/revive-capacity.test.js +0 -184
  1088. package/dist/core/__tests__/revive-parked-fresh.test.d.ts +0 -1
  1089. package/dist/core/__tests__/revive-parked-fresh.test.js +0 -176
  1090. package/dist/core/__tests__/scope-crouter-home-fence.test.d.ts +0 -1
  1091. package/dist/core/__tests__/scope-crouter-home-fence.test.js +0 -55
  1092. package/dist/core/__tests__/seam/broker-attach-multiclient.test.d.ts +0 -1
  1093. package/dist/core/__tests__/seam/broker-attach-multiclient.test.js +0 -262
  1094. package/dist/core/__tests__/seam/broker-attach-stream.test.d.ts +0 -1
  1095. package/dist/core/__tests__/seam/broker-attach-stream.test.js +0 -176
  1096. package/dist/core/__tests__/seam/broker-cap-freeze.test.d.ts +0 -1
  1097. package/dist/core/__tests__/seam/broker-cap-freeze.test.js +0 -155
  1098. package/dist/core/__tests__/seam/broker-crash-teardown.test.d.ts +0 -1
  1099. package/dist/core/__tests__/seam/broker-crash-teardown.test.js +0 -131
  1100. package/dist/core/__tests__/seam/broker-pane-resolution.test.d.ts +0 -1
  1101. package/dist/core/__tests__/seam/broker-pane-resolution.test.js +0 -204
  1102. package/dist/core/__tests__/seam/broker-provider-retry.test.d.ts +0 -1
  1103. package/dist/core/__tests__/seam/broker-provider-retry.test.js +0 -686
  1104. package/dist/core/__tests__/seam/broker-startup-diagnostics.test.d.ts +0 -1
  1105. package/dist/core/__tests__/seam/broker-startup-diagnostics.test.js +0 -82
  1106. package/dist/core/__tests__/seam/broker-whip-interrupt.test.d.ts +0 -1
  1107. package/dist/core/__tests__/seam/broker-whip-interrupt.test.js +0 -50
  1108. package/dist/core/__tests__/seam/deadline-wake-delivery.test.d.ts +0 -1
  1109. package/dist/core/__tests__/seam/deadline-wake-delivery.test.js +0 -138
  1110. package/dist/core/__tests__/seam/dormancy-release.test.d.ts +0 -1
  1111. package/dist/core/__tests__/seam/dormancy-release.test.js +0 -516
  1112. package/dist/core/__tests__/seam/held-deferred-human-prompt.test.d.ts +0 -1
  1113. package/dist/core/__tests__/seam/held-deferred-human-prompt.test.js +0 -65
  1114. package/dist/core/__tests__/seam/inbox-reference-guidance.test.d.ts +0 -1
  1115. package/dist/core/__tests__/seam/inbox-reference-guidance.test.js +0 -84
  1116. package/dist/core/__tests__/seam/memory-slash-node-relative-inventory.test.d.ts +0 -1
  1117. package/dist/core/__tests__/seam/memory-slash-node-relative-inventory.test.js +0 -160
  1118. package/dist/core/__tests__/seam/node-outcome-delivery.test.d.ts +0 -1
  1119. package/dist/core/__tests__/seam/node-outcome-delivery.test.js +0 -177
  1120. package/dist/core/__tests__/seam/prospective-inventory-stdout.test.d.ts +0 -1
  1121. package/dist/core/__tests__/seam/prospective-inventory-stdout.test.js +0 -31
  1122. package/dist/core/__tests__/seam/reopen-invalidated-worktree.test.d.ts +0 -1
  1123. package/dist/core/__tests__/seam/reopen-invalidated-worktree.test.js +0 -60
  1124. package/dist/core/__tests__/seam/self-close-teardown.test.d.ts +0 -1
  1125. package/dist/core/__tests__/seam/self-close-teardown.test.js +0 -49
  1126. package/dist/core/__tests__/seam/yield-refresh-transaction.test.d.ts +0 -1
  1127. package/dist/core/__tests__/seam/yield-refresh-transaction.test.js +0 -100
  1128. package/dist/core/__tests__/secrets.test.d.ts +0 -1
  1129. package/dist/core/__tests__/secrets.test.js +0 -49
  1130. package/dist/core/__tests__/self-update.test.d.ts +0 -1
  1131. package/dist/core/__tests__/self-update.test.js +0 -46
  1132. package/dist/core/__tests__/session-branch.test.d.ts +0 -1
  1133. package/dist/core/__tests__/session-branch.test.js +0 -61
  1134. package/dist/core/__tests__/session-cycles.test.d.ts +0 -1
  1135. package/dist/core/__tests__/session-cycles.test.js +0 -133
  1136. package/dist/core/__tests__/session-model.test.d.ts +0 -1
  1137. package/dist/core/__tests__/session-model.test.js +0 -111
  1138. package/dist/core/__tests__/spawn-worktree-id-conflict.test.d.ts +0 -1
  1139. package/dist/core/__tests__/spawn-worktree-id-conflict.test.js +0 -71
  1140. package/dist/core/__tests__/stdin-body-no-discard.test.d.ts +0 -1
  1141. package/dist/core/__tests__/stdin-body-no-discard.test.js +0 -33
  1142. package/dist/core/__tests__/stdout-errors.test.d.ts +0 -1
  1143. package/dist/core/__tests__/stdout-errors.test.js +0 -16
  1144. package/dist/core/__tests__/stop-guard.test.d.ts +0 -1
  1145. package/dist/core/__tests__/stop-guard.test.js +0 -237
  1146. package/dist/core/__tests__/stream-watchdog.test.d.ts +0 -1
  1147. package/dist/core/__tests__/stream-watchdog.test.js +0 -154
  1148. package/dist/core/__tests__/subscription-pool-credential-guard.test.d.ts +0 -1
  1149. package/dist/core/__tests__/subscription-pool-credential-guard.test.js +0 -95
  1150. package/dist/core/__tests__/tmux-driver-boundary.test.d.ts +0 -1
  1151. package/dist/core/__tests__/tmux-driver-boundary.test.js +0 -50
  1152. package/dist/core/__tests__/warm-claim-preference-snapshot.test.d.ts +0 -1
  1153. package/dist/core/__tests__/warm-claim-preference-snapshot.test.js +0 -54
  1154. package/dist/core/__tests__/worktree-landing.test.d.ts +0 -1
  1155. package/dist/core/__tests__/worktree-landing.test.js +0 -11
  1156. package/dist/core/__tests__/yield-ensures-daemon.test.d.ts +0 -1
  1157. package/dist/core/__tests__/yield-ensures-daemon.test.js +0 -55
  1158. package/dist/core/broker-client/__tests__/transport-relay.test.d.ts +0 -1
  1159. package/dist/core/broker-client/__tests__/transport-relay.test.js +0 -214
  1160. package/dist/core/broker-client/__tests__/transport-socket.test.d.ts +0 -1
  1161. package/dist/core/broker-client/__tests__/transport-socket.test.js +0 -73
  1162. package/dist/core/canvas/__tests__/attention.test.d.ts +0 -1
  1163. package/dist/core/canvas/__tests__/attention.test.js +0 -83
  1164. package/dist/core/canvas/__tests__/history-transcript.test.d.ts +0 -1
  1165. package/dist/core/canvas/__tests__/history-transcript.test.js +0 -102
  1166. package/dist/core/canvas/__tests__/remote-canvas-source.test.d.ts +0 -1
  1167. package/dist/core/canvas/__tests__/remote-canvas-source.test.js +0 -328
  1168. package/dist/core/canvas/__tests__/remote-transport.test.d.ts +0 -1
  1169. package/dist/core/canvas/__tests__/remote-transport.test.js +0 -97
  1170. package/dist/core/canvas/__tests__/render-remote.test.d.ts +0 -1
  1171. package/dist/core/canvas/__tests__/render-remote.test.js +0 -243
  1172. package/dist/core/canvas/__tests__/session-window.test.d.ts +0 -1
  1173. package/dist/core/canvas/__tests__/session-window.test.js +0 -70
  1174. package/dist/core/feed/__tests__/inbox-migrate.test.d.ts +0 -1
  1175. package/dist/core/feed/__tests__/inbox-migrate.test.js +0 -49
  1176. package/dist/core/human/__tests__/page-catalog.test.d.ts +0 -1
  1177. package/dist/core/human/__tests__/page-catalog.test.js +0 -20
  1178. package/dist/core/human/__tests__/page-html-markdown.test.d.ts +0 -1
  1179. package/dist/core/human/__tests__/page-html-markdown.test.js +0 -48
  1180. package/dist/core/human/__tests__/page.test.d.ts +0 -1
  1181. package/dist/core/human/__tests__/page.test.js +0 -92
  1182. package/dist/core/keybindings/__tests__/resolve.test.d.ts +0 -1
  1183. package/dist/core/keybindings/__tests__/resolve.test.js +0 -171
  1184. package/dist/core/profiles/__tests__/env-store.test.d.ts +0 -1
  1185. package/dist/core/profiles/__tests__/env-store.test.js +0 -99
  1186. package/dist/core/profiles/__tests__/fuzzy-match.test.d.ts +0 -1
  1187. package/dist/core/profiles/__tests__/fuzzy-match.test.js +0 -51
  1188. package/dist/core/profiles/__tests__/root-profile.test.d.ts +0 -1
  1189. package/dist/core/profiles/__tests__/root-profile.test.js +0 -59
  1190. package/dist/core/review/__tests__/capture-origin.test.d.ts +0 -1
  1191. package/dist/core/review/__tests__/capture-origin.test.js +0 -150
  1192. package/dist/core/review/__tests__/comments.test.d.ts +0 -1
  1193. package/dist/core/review/__tests__/comments.test.js +0 -116
  1194. package/dist/core/review/__tests__/remap.test.d.ts +0 -1
  1195. package/dist/core/review/__tests__/remap.test.js +0 -177
  1196. package/dist/core/review/__tests__/stage-identity.test.d.ts +0 -1
  1197. package/dist/core/review/__tests__/stage-identity.test.js +0 -150
  1198. package/dist/core/runtime/__tests__/engine-route.test.d.ts +0 -1
  1199. package/dist/core/runtime/__tests__/engine-route.test.js +0 -36
  1200. package/dist/core/runtime/__tests__/install-id-cache-scoping.test.d.ts +0 -1
  1201. package/dist/core/runtime/__tests__/install-id-cache-scoping.test.js +0 -45
  1202. package/dist/core/runtime/__tests__/node-env.test.d.ts +0 -1
  1203. package/dist/core/runtime/__tests__/node-env.test.js +0 -73
  1204. package/dist/core/runtime/__tests__/spawn-env.test.d.ts +0 -1
  1205. package/dist/core/runtime/__tests__/spawn-env.test.js +0 -259
  1206. package/dist/core/substrate/__tests__/surface-match-command.test.d.ts +0 -1
  1207. package/dist/core/substrate/__tests__/surface-match-command.test.js +0 -89
  1208. package/dist/core/substrate/__tests__/surface-match-memory-read.test.d.ts +0 -1
  1209. package/dist/core/substrate/__tests__/surface-match-memory-read.test.js +0 -28
  1210. package/dist/core/substrate/__tests__/surface-match-pre-command.test.d.ts +0 -1
  1211. package/dist/core/substrate/__tests__/surface-match-pre-command.test.js +0 -92
  1212. package/dist/daemon/__tests__/autostart-storm.test.d.ts +0 -1
  1213. package/dist/daemon/__tests__/autostart-storm.test.js +0 -128
  1214. package/dist/daemon/__tests__/broker-ownership.test.d.ts +0 -1
  1215. package/dist/daemon/__tests__/broker-ownership.test.js +0 -25
  1216. package/dist/daemon/__tests__/daemon-ownership.test.d.ts +0 -1
  1217. package/dist/daemon/__tests__/daemon-ownership.test.js +0 -27
  1218. package/dist/daemon/__tests__/helpers/source-daemon.d.ts +0 -30
  1219. package/dist/daemon/__tests__/helpers/source-daemon.js +0 -176
  1220. package/dist/daemon/__tests__/integration/api-startup-readiness.test.d.ts +0 -1
  1221. package/dist/daemon/__tests__/integration/api-startup-readiness.test.js +0 -83
  1222. package/dist/daemon/__tests__/integration/migration-startup.test.d.ts +0 -1
  1223. package/dist/daemon/__tests__/integration/migration-startup.test.js +0 -127
  1224. package/dist/daemon/__tests__/node-deadline-lane.test.d.ts +0 -1
  1225. package/dist/daemon/__tests__/node-deadline-lane.test.js +0 -77
  1226. package/dist/daemon/__tests__/node-outcome-birth-invariants.test.d.ts +0 -1
  1227. package/dist/daemon/__tests__/node-outcome-birth-invariants.test.js +0 -146
  1228. package/dist/daemon/__tests__/node-outcome-delivery.test.d.ts +0 -1
  1229. package/dist/daemon/__tests__/node-outcome-delivery.test.js +0 -116
  1230. package/dist/daemon/__tests__/reconciler-signature.test.d.ts +0 -1
  1231. package/dist/daemon/__tests__/reconciler-signature.test.js +0 -37
  1232. package/dist/daemon/__tests__/subtree-filter-freshness.test.d.ts +0 -1
  1233. package/dist/daemon/__tests__/subtree-filter-freshness.test.js +0 -63
  1234. package/dist/daemon/__tests__/thaw-order.test.d.ts +0 -1
  1235. package/dist/daemon/__tests__/thaw-order.test.js +0 -55
  1236. package/dist/daemon/api/__tests__/bridge-heartbeat.test.d.ts +0 -1
  1237. package/dist/daemon/api/__tests__/bridge-heartbeat.test.js +0 -58
  1238. package/dist/daemon/api/__tests__/broker-settle-park.test.d.ts +0 -1
  1239. package/dist/daemon/api/__tests__/broker-settle-park.test.js +0 -175
  1240. package/dist/daemon/api/__tests__/canvas-snapshot-fields.test.d.ts +0 -1
  1241. package/dist/daemon/api/__tests__/canvas-snapshot-fields.test.js +0 -216
  1242. package/dist/daemon/api/__tests__/error-seam.test.d.ts +0 -1
  1243. package/dist/daemon/api/__tests__/error-seam.test.js +0 -83
  1244. package/dist/daemon/api/__tests__/model-config.test.d.ts +0 -1
  1245. package/dist/daemon/api/__tests__/model-config.test.js +0 -73
  1246. package/dist/daemon/api/__tests__/node-create-description.test.d.ts +0 -1
  1247. package/dist/daemon/api/__tests__/node-create-description.test.js +0 -127
  1248. package/dist/daemon/api/__tests__/node-model-validation.test.d.ts +0 -1
  1249. package/dist/daemon/api/__tests__/node-model-validation.test.js +0 -183
  1250. package/dist/daemon/api/__tests__/nodes-activity-query.test.d.ts +0 -1
  1251. package/dist/daemon/api/__tests__/nodes-activity-query.test.js +0 -99
  1252. package/dist/daemon/api/__tests__/profile-launch-gates.test.d.ts +0 -1
  1253. package/dist/daemon/api/__tests__/profile-launch-gates.test.js +0 -172
  1254. package/dist/daemon/api/__tests__/profile-metadata-route.test.d.ts +0 -1
  1255. package/dist/daemon/api/__tests__/profile-metadata-route.test.js +0 -95
  1256. package/dist/daemon/api/__tests__/reopen-delivery.test.d.ts +0 -1
  1257. package/dist/daemon/api/__tests__/reopen-delivery.test.js +0 -260
  1258. package/dist/daemon/api/__tests__/seam/api-server.test.d.ts +0 -1
  1259. package/dist/daemon/api/__tests__/seam/api-server.test.js +0 -442
  1260. package/dist/daemon/api/__tests__/seam/b10-attach-modelauth.test.d.ts +0 -1
  1261. package/dist/daemon/api/__tests__/seam/b10-attach-modelauth.test.js +0 -310
  1262. package/dist/daemon/api/__tests__/seam/leaf-api-parity.test.d.ts +0 -1
  1263. package/dist/daemon/api/__tests__/seam/leaf-api-parity.test.js +0 -351
  1264. package/dist/daemon/api/__tests__/seam/node-outcome-api.test.d.ts +0 -1
  1265. package/dist/daemon/api/__tests__/seam/node-outcome-api.test.js +0 -159
  1266. package/dist/daemon/api/__tests__/seam/profile-delete.test.d.ts +0 -1
  1267. package/dist/daemon/api/__tests__/seam/profile-delete.test.js +0 -372
  1268. package/dist/daemon/api/__tests__/submit-result.test.d.ts +0 -1
  1269. package/dist/daemon/api/__tests__/submit-result.test.js +0 -215
  1270. package/dist/migrations/__tests__/activation-concurrency.test.d.ts +0 -1
  1271. package/dist/migrations/__tests__/activation-concurrency.test.js +0 -146
  1272. package/dist/migrations/__tests__/activation.test.d.ts +0 -1
  1273. package/dist/migrations/__tests__/activation.test.js +0 -152
  1274. package/dist/migrations/__tests__/deletion-and-root-declaration.test.d.ts +0 -1
  1275. package/dist/migrations/__tests__/deletion-and-root-declaration.test.js +0 -149
  1276. package/dist/pi-extensions/__tests__/canvas-bash-valve.test.d.ts +0 -1
  1277. package/dist/pi-extensions/__tests__/canvas-bash-valve.test.js +0 -86
  1278. package/dist/pi-extensions/__tests__/canvas-context-intro.test.d.ts +0 -1
  1279. package/dist/pi-extensions/__tests__/canvas-context-intro.test.js +0 -364
  1280. package/dist/pi-extensions/__tests__/canvas-goal-capture-envelope.test.d.ts +0 -1
  1281. package/dist/pi-extensions/__tests__/canvas-goal-capture-envelope.test.js +0 -106
  1282. package/dist/pi-extensions/__tests__/canvas-recap.test.d.ts +0 -1
  1283. package/dist/pi-extensions/__tests__/canvas-recap.test.js +0 -62
  1284. package/dist/pi-extensions/__tests__/canvas-stophook-agentend.test.d.ts +0 -1
  1285. package/dist/pi-extensions/__tests__/canvas-stophook-agentend.test.js +0 -432
  1286. package/dist/pi-extensions/__tests__/canvas-stophook-context-nudge.test.d.ts +0 -1
  1287. package/dist/pi-extensions/__tests__/canvas-stophook-context-nudge.test.js +0 -152
  1288. package/dist/pi-extensions/__tests__/canvas-structured-output.test.d.ts +0 -1
  1289. package/dist/pi-extensions/__tests__/canvas-structured-output.test.js +0 -88
  1290. package/dist/pi-extensions/__tests__/canvas-tool-guide.test.d.ts +0 -1
  1291. package/dist/pi-extensions/__tests__/canvas-tool-guide.test.js +0 -96
  1292. package/dist/pi-extensions/__tests__/integration/canvas-bash-valve.test.d.ts +0 -1
  1293. package/dist/pi-extensions/__tests__/integration/canvas-bash-valve.test.js +0 -133
  1294. package/dist/pi-extensions/__tests__/pre-command-gate.test.d.ts +0 -1
  1295. package/dist/pi-extensions/__tests__/pre-command-gate.test.js +0 -232
  1296. package/dist/shared/__tests__/env-boundary.test.d.ts +0 -1
  1297. package/dist/shared/__tests__/env-boundary.test.js +0 -95
  1298. package/dist/shared/__tests__/generated-context-grammar.test.d.ts +0 -1
  1299. package/dist/shared/__tests__/generated-context-grammar.test.js +0 -80
  1300. package/docs/compat/hearth-crtr-v1.md +0 -179
  1301. package/docs/compat/hearth-crtr-v2.md +0 -177
  1302. package/docs/compat/hearth-crtr-v3.md +0 -176
  1303. package/docs/compat/hearth-crtr-v4.md +0 -182
  1304. package/docs/compat/hearth-crtr-v5.md +0 -169
@@ -1,1708 +1,5 @@
1
- // render/chat-view.ts — the render half of `crtr surface attach`.
2
- //
3
- // A direct port of pi's `InteractiveMode.handleEvent()`
4
- // (interactive-mode.js:2169-2462) + its rebuild path
5
- // (`addMessageToChat`/`renderSessionContext`, :2483-2648) that DRIVES pi's own
6
- // exported TUI components rather than reimplementing them. The viewer never
7
- // spawns pi and never opens the session — it only consumes the relayed
8
- // `AgentSessionEvent` stream + the `welcome` snapshot over `view.sock`.
9
- //
10
- // Ownership boundary: ChatView owns the chat scroll `Container` it is handed.
11
- // Its activity state (working spinner, compaction/retry indicators) is signaled
12
- // to the viewer-owned fixed slot when one is supplied. It does NOT own the
13
- // editor, the footer, or the terminal title — those are chrome laid out by the
14
- // attach command. Events that only affect that chrome
15
- // (queue_update / session_info_changed / thinking_level_changed) are forwarded
16
- // to the optional `onFooterEvent` sink instead of rendered here.
17
- //
18
- // Custom-tool rendering: extensions run in the broker, so the viewer generally
19
- // has no extension `ToolDefinition`. The viewer supplies native renderers only
20
- // for crouter-owned message/tool types it understands; other extension
21
- // `renderCall`/`renderResult` hooks degrade to the default ToolExecutionComponent
22
- // path while builtin tools, diffs, and partial-result streaming keep working.
23
- import { Container, Loader, Spacer, Text } from '@earendil-works/pi-tui';
24
- import { AssistantMessageComponent, BashExecutionComponent, BranchSummaryMessageComponent, CompactionSummaryMessageComponent, CustomMessageComponent, parseSkillBlock, SkillInvocationMessageComponent, ToolExecutionComponent, UserMessageComponent, } from '@earendil-works/pi-coding-agent';
25
- import { attachMarkdownTheme } from '../config.js';
26
- import { ContextMessageComponent } from './context-message.js';
27
- import { presentationFor } from './card-presentation.js';
28
- import { detectInlinePageResult, PageBlockComponent } from './page-block.js';
29
- import { CRTR_OUTPUT_CUSTOM_TYPE, CrtrOutputMessageComponent, createCrtrBashToolDefinition, } from './crtr-output.js';
30
- import { CRTR_CYCLE_DIVIDER_CUSTOM_TYPE, endedByAbort } from '../../../core/runtime/session-cycles.js';
31
- import { parseCard } from '../../../shared/generated-context.js';
32
- import { assistantVisibleText, isGroupBoundaryKind, isTrueUserMessage, } from '../../../shared/tool-groups.js';
33
- import { transformDiagramFences } from './diagram.js';
34
- import { styleAttachAgentMarkdown, styleAttachMarkdownSource, styleAttachMessageMarkdown, styleAttachSummaryMarkdown, } from './markdown-source.js';
35
- import { createCrtrEditToolDefinition } from './edit-diff.js';
36
- import { GroupActivityRecorder } from './group-activity.js';
37
- import { GroupRecapComponent } from './group-recap.js';
38
- import { FoldedToolCallController, bashCallBackgroundHintLines, createCrtrPlainBashToolDefinition, createCrtrReadToolDefinition, createCrtrWriteToolDefinition, } from './tool-calls.js';
39
- import { ringCompletionBell } from '../chrome/completion-bell.js';
40
- import { extractFilePaths } from '#core/human/visible-paths';
41
- import { keepWhenCondensed, liveRegionStart } from './condensed-history.js';
42
- import { ViewerAssistantMessageComponent } from './assistant-message.js';
43
- import { CompositeViewportSource, MeasuredContainer, } from './measured-container.js';
44
- import { readConfig, updateRawConfigAtomically } from '../../../core/config.js';
45
- import { DEFAULT_CONDENSED_HISTORY, DEFAULT_LIVE_CYCLES } from '../../../types.js';
46
- import { applySnapshot as projectSnapshot, applyToolGroupSummary as projectToolGroupSummary, applyWorkingActivity as projectWorkingActivity, bashEnd as projectBashEnd, bashOutput as projectBashOutput, bashStart as projectBashStart, initialConvState, reduce as projectEvent, } from '../../conversation/projection.js';
47
- /** Theme-derived chrome colors (spinner / dim / error) are supplied by the
48
- * attach command via `ChatViewOptions.palette` (built from the live theme in
49
- * config.ts). pi does not re-export the raw `theme` instance, so standalone
50
- * ChatViews receive the same semantic ANSI fallback palette. The message components
51
- * use the attach Markdown theme, which preserves the user's pi theme while making
52
- * fenced code visually distinct. */
53
- const defaultDimStyle = (s) => `\x1b[2m${s}\x1b[22m`;
54
- /** How many catch-up messages `applySnapshot` builds between event-loop yields.
55
- * Keeps large non-streaming snapshots from monopolizing the main thread so
56
- * queued keystrokes are serviced during construction. */
57
- const SNAPSHOT_YIELD_EVERY = 50;
58
- /** The user's `live_cycles` setting — how many trailing refresh-yield cycles the
59
- * transcript renders at full fidelity. Read per ChatView (i.e. per attach), so
60
- * `crtr sys config set live_cycles --value N` takes effect on the next attach
61
- * without a daemon restart. A missing/unreadable config falls back to the
62
- * shipped default. */
63
- function readLiveCycles() {
64
- try {
65
- return readConfig('user').live_cycles;
66
- }
67
- catch {
68
- return DEFAULT_LIVE_CYCLES;
69
- }
70
- }
71
- /** The user's `condensed_history` setting — which messages of an already-condensed
72
- * cycle still render (the cycle dividers always do). Read per attach, like
73
- * `live_cycles`. */
74
- function readCondensedHistory() {
75
- try {
76
- return readConfig('user').condensed_history;
77
- }
78
- catch {
79
- return DEFAULT_CONDENSED_HISTORY;
80
- }
81
- }
82
- /** The user's `fold_finished_tools` setting — the persisted starting state of the
83
- * fold view setting. Toggling it in a viewer writes it back (`persistFoldFinishedTools`),
84
- * so the choice carries into later chats and later viewers. */
85
- function readFoldFinishedTools() {
86
- try {
87
- return readConfig('user').fold_finished_tools;
88
- }
89
- catch {
90
- return false;
91
- }
92
- }
93
- /** Whether this attach should start folded tool groups on their broker-generated
94
- * summaries. The setting is deliberately attach-local: the broker remains the
95
- * single summary producer and every viewer independently chooses its display. */
96
- function readSummarizeToolCalls() {
97
- try {
98
- return readConfig('user').summarize_tool_calls;
99
- }
100
- catch {
101
- return false;
102
- }
103
- }
104
- /** Whether folded tool recaps list their actual activity or use compact counts.
105
- * The detailed form is the default; each attach reads its own presentation choice. */
106
- function readDetailedToolRecaps() {
107
- try {
108
- return readConfig('user').detailed_tool_recaps;
109
- }
110
- catch {
111
- return true;
112
- }
113
- }
114
- /** Persist the fold view setting to user config. Best-effort: a viewer must never
115
- * die because the config file is unwritable — the in-viewer toggle still applies. */
116
- function persistFoldFinishedTools(value) {
117
- try {
118
- updateRawConfigAtomically('user', (latest) => ({ ...latest, fold_finished_tools: value }));
119
- }
120
- catch {
121
- // ignored — the fold still applies to this viewer.
122
- }
123
- }
124
- /** A component supports the Ctrl+O global tool-output toggle. Mirrors pi's
125
- * `isExpandable` duck-type (interactive-mode.js): any rendered child carrying a
126
- * `setExpanded(boolean)` method — tool executions, custom/compaction/branch/skill
127
- * message components — participates; everything else (the status container, plain
128
- * text, assistant/user bubbles) is skipped. */
129
- function isExpandable(obj) {
130
- return (typeof obj === 'object' &&
131
- obj !== null &&
132
- 'setExpanded' in obj &&
133
- typeof obj.setExpanded === 'function');
134
- }
135
- /** Every SGR escape, for measuring a line's visible content. */
136
- const ANSI_RE = /\x1b\[[0-9;]*m/g;
137
- /** Same match, with the SGR parameter list captured for rewriting. */
138
- const SGR_PARAMS_RE = /\x1b\[([0-9;]*)m/g;
139
- /** Drop every background-color SGR parameter from a line, keeping foreground and
140
- * text styles. The minimized fold is a dense index of what ran, so the tool's
141
- * pending/success/error background band (pi paints it across the full pane width)
142
- * reads as noise there — one call per line, unhighlighted. `0` (full reset) is
143
- * kept: it clears the background too, and nothing follows it to re-set one. */
144
- function stripBackground(line) {
145
- return line.replace(SGR_PARAMS_RE, (_whole, params) => {
146
- const parts = params.split(';');
147
- const kept = [];
148
- for (let i = 0; i < parts.length; i++) {
149
- const code = Number(parts[i] === '' ? 0 : parts[i]);
150
- // Extended colors (`38` foreground, `48` background, `58` underline):
151
- // consume the full sequence atomically so an RGB channel in the 40-47 or
152
- // 100-107 range is not mistaken for a standalone background code.
153
- if (code === 38 || code === 48 || code === 58) {
154
- const mode = Number(parts[i + 1]);
155
- const end = i + (mode === 5 ? 2 : mode === 2 ? 4 : 1);
156
- if (code !== 48)
157
- kept.push(...parts.slice(i, end + 1));
158
- i = end;
159
- continue;
160
- }
161
- // Standard (40-47) and bright (100-107) backgrounds. `49` (reset to the
162
- // default background) is KEPT — it is the thing we want, and dropping it
163
- // would let a neighbouring row's background bleed into this line.
164
- if ((code >= 40 && code <= 47) || (code >= 100 && code <= 107))
165
- continue;
166
- kept.push(String(code));
167
- }
168
- return kept.length > 0 ? `\x1b[${kept.join(';')}m` : '';
169
- });
170
- }
171
- /** Sender sections of an inbox card body; `parseCard` already read their entries.
172
- * Whatever remains is other content riding the same digest. */
173
- const INBOX_SENDER_SECTIONS = /<from\b[^>]*>[\s\S]*?<\/from>/g;
174
- /** A tool component that can fold itself down to its CALL. pi's `ToolExecutionComponent`
175
- * only knows expanded/collapsed, so each crtr-owned definition receives a local fold
176
- * controller and captures the compact call component it renders. Folded render paints
177
- * that captured call directly, dropping result and Box chrome while letting a wrapped
178
- * path keep its natural rows. Tools without a crtr definition remain in full. */
179
- /** A one-line separator that appears only while its adjacent tool group is
180
- * folded. It stays in the transcript so toggling folded tools reflows the same
181
- * message/tool boundary without rebuilding the chat. */
182
- class FoldedToolSeparator extends Spacer {
183
- folded = false;
184
- separatesToolGroup = false;
185
- setFolded(folded) {
186
- this.folded = folded;
187
- this.refresh();
188
- }
189
- setSeparatesToolGroup(separatesToolGroup) {
190
- this.separatesToolGroup = separatesToolGroup;
191
- this.refresh();
192
- }
193
- refresh() {
194
- this.setLines(this.folded && this.separatesToolGroup ? 1 : 0);
195
- }
196
- }
197
- class MinimizableToolComponent extends ToolExecutionComponent {
198
- /** Bound by ChatView at append time; pi's base component does not expose it. */
199
- activityCallId;
200
- minimized = false;
201
- expandedState = false;
202
- foldController;
203
- resultObserver;
204
- /** A foldable definition owns its folded call component; it may also observe
205
- * results before the imported shell renders them. */
206
- setToolView(foldController, resultObserver) {
207
- this.foldController = foldController;
208
- this.resultObserver = resultObserver;
209
- }
210
- updateResult(...args) {
211
- this.resultObserver?.(args[0], args[1] ?? false);
212
- super.updateResult(...args);
213
- }
214
- setExpanded(expanded) {
215
- this.expandedState = expanded;
216
- super.setExpanded(expanded);
217
- }
218
- /** Flip the local fold state, then use the imported component's public
219
- * expansion setter to rebuild its call renderer at the current setting. */
220
- setMinimized(minimized) {
221
- if (!this.foldController || this.minimized === minimized)
222
- return;
223
- this.minimized = minimized;
224
- this.foldController.setFolded(minimized);
225
- super.setExpanded(this.expandedState);
226
- }
227
- render(width) {
228
- // The backgrounding row is appended HERE, by the component that owns the
229
- // whole tool block, so it renders after the block's highlighted band ends
230
- // instead of inside it. It is empty unless this is a bash call still running
231
- // past the threshold.
232
- if (!this.minimized) {
233
- return [...super.render(width), ...bashCallBackgroundHintLines(this.foldController?.callComponent(), width)];
234
- }
235
- const call = this.foldController?.callComponent();
236
- if (!call)
237
- return super.render(width);
238
- // trimEnd drops right-hand padding, which only existed to carry the
239
- // background band these lines no longer paint.
240
- return call.render(width)
241
- .filter((line) => line.replace(ANSI_RE, '').trim().length > 0)
242
- .map((line) => stripBackground(line).trimEnd());
243
- }
244
- }
245
- const defaultErrorStyle = (s) => `\x1b[31m${s}\x1b[39m`;
246
- const defaultAttachPalette = {
247
- accent: (s) => `\x1b[33m${s}\x1b[39m`,
248
- active: (s) => `\x1b[36m${s}\x1b[39m`,
249
- info: (s) => `\x1b[34m${s}\x1b[39m`,
250
- muted: defaultDimStyle,
251
- faint: defaultDimStyle,
252
- border: (s) => s,
253
- surface: (s) => s,
254
- bold: (s) => `\x1b[1m${s}\x1b[22m`,
255
- error: defaultErrorStyle,
256
- warning: (s) => `\x1b[33m${s}\x1b[39m`,
257
- diffAdded: (s) => `\x1b[32m${s}\x1b[39m`,
258
- diffRemoved: (s) => `\x1b[91m${s}\x1b[39m`,
259
- bashMode: (s) => `\x1b[32m${s}\x1b[39m`,
260
- bashModeAlt: (s) => `\x1b[92m${s}\x1b[39m`,
261
- };
262
- export class ChatView {
263
- tui;
264
- /** The chat scroll area handed in by the attach command. */
265
- container;
266
- /** Settled history is cached independently from the live status area so picker
267
- * navigation does not re-render a long conversation on every key repeat. */
268
- historyContainer = new MeasuredContainer();
269
- /** Standalone ChatViews render activity inline; the attach viewer supplies
270
- * `onActivityChange`, so its transcript excludes this container. */
271
- statusContainer = new MeasuredContainer();
272
- /** Optional banner, above history and status in the viewport's flat source. */
273
- bannerContainer;
274
- transcript;
275
- /** Where `append()` puts a component. Normally `historyContainer`; retargeted to
276
- * a nested container while condensed history is being built, so the same
277
- * message-rendering path serves both regions. */
278
- appendTarget = this.historyContainer;
279
- /** Inline page blocks placed in this transcript, by page id — one block per
280
- * page, so a `--replace` revision refreshes the block already on screen. */
281
- pageBlocks = new Map();
282
- inlinePageBlocks;
283
- pageOpenHint;
284
- backgroundBashHint;
285
- /** Trailing cycles kept at full fidelity (config `live_cycles`). */
286
- liveCycles;
287
- /** Messages kept from a condensed cycle (config `condensed_history`). */
288
- condensedHistory;
289
- cwd;
290
- showImages;
291
- imageWidthCells;
292
- hideThinking;
293
- hiddenThinkingLabel;
294
- /** Ctrl+O: pi's two-state tool-output expansion. */
295
- toolOutputExpanded;
296
- /** The view setting (Alt+C → z → f): fold every SETTLED tool call to its single
297
- * call line. Independent of `toolOutputExpanded` — it survives an expand/collapse
298
- * and only ever applies to tool calls that are done. */
299
- foldSettledTools = readFoldFinishedTools();
300
- /** Summary mode only changes Ctrl+O when both persistent settings are on. */
301
- summarizeToolCalls = readSummarizeToolCalls();
302
- detailedToolRecaps = readDetailedToolRecaps();
303
- showGroupSummaries = this.summarizeToolCalls && this.foldSettledTools;
304
- /** Groups exist only while building/rendering the full-fidelity live region. */
305
- groups = [];
306
- openGroup;
307
- groupSummaries = new Map();
308
- /** Node id → display name for every node spawned in this transcript, so a
309
- * later group's finish notice can name the child rather than its id. */
310
- nodeRoster = new Map();
311
- streamingWasGroupMember = false;
312
- onFooterEvent;
313
- /** Viewer hook that places activity in its fixed slot, when available. */
314
- onActivityChange;
315
- /** Theme-derived colorizers for the activity/status area. */
316
- spinnerStyle;
317
- dimStyle;
318
- errorStyle;
319
- /** Palette shared with recap rows that render outside pi tool callbacks. */
320
- recapPalette;
321
- /** Bold accent for the expanded crtr-context label. */
322
- labelStyle = (s) => `\x1b[1m${s}\x1b[22m`;
323
- /** Viewer-local Markdown projection, handed to pi's message components so
324
- * THEY apply it at render time with the exact content width. The viewer keeps
325
- * no projected copy: the components hold canonical source, and each
326
- * transformer reads live viewer state on every call. Diagrams apply only to
327
- * assistant-authored Markdown. */
328
- markdownTransformers = [
329
- (markdown, { messageType, availableWidth }) => (messageType === 'assistant' ? transformDiagramFences(markdown, availableWidth) : markdown),
330
- (markdown, { messageType }) => (messageType === 'user' ? styleAttachMarkdownSource(markdown) : styleAttachAgentMarkdown(markdown)),
331
- ];
332
- /** The assistant message component currently being streamed (between
333
- * message_start and message_end for an assistant turn). */
334
- streamingComponent;
335
- /** The separator immediately after the live assistant component. It becomes
336
- * visible when that response has visible prose or thinking and folded tools. */
337
- streamingToolSeparator;
338
- /** Content classes for each separator, so Ctrl+T can add/remove thinking gaps
339
- * without rebuilding the transcript. */
340
- foldedToolSeparatorContents = new Map();
341
- /** Tool-call id → its execution component, for the duration of the call. */
342
- pendingTools = new Map();
343
- /** The `!` bash component currently streaming (between bash_start and bash_end). */
344
- bashComponent;
345
- /** The single active activity loader (working/compaction/retry), if any. */
346
- activityLoader;
347
- /** The shared broker transcript state; this renderer projects it into pi TUI
348
- * components while retaining terminal-only folding and virtualization. */
349
- projection = initialConvState();
350
- /** Broker-selected normal label for this turn; compaction/retry temporarily
351
- * replace it and restore it when the run remains active. */
352
- workingActivity = this.projection.workingActivity;
353
- runActive = false;
354
- // -- Single-writer snapshot ordering -------------------------------------
355
- // A non-streaming catch-up yields to the event loop mid-build (so queued stdin
356
- // drains), which opens a window where later broker frames could otherwise
357
- // mutate a half-rebuilt transcript. These three fields make the ChatView a
358
- // single ordered writer: applySnapshot is the only thing that mutates the
359
- // view while a build is in flight, live frames are deferred and replayed in
360
- // wire order once it finishes, and a newer welcome always supersedes an older
361
- // build. See applySnapshot / deferIfBuilding.
362
- /** True while applySnapshot is mid-build; live broker frames defer instead of
363
- * mutating the partially-rebuilt view. */
364
- applyingSnapshot = false;
365
- /** Bumped on every applySnapshot. A build suspended at a yield compares this
366
- * after resuming and abandons itself when a newer welcome has bumped it, so
367
- * the newest welcome wins and stale state never overwrites the live view. */
368
- snapshotGeneration = 0;
369
- /** Live frames captured during an in-flight build (bound closures that re-run
370
- * the original entry point), replayed in order when the build completes and
371
- * dropped when a newer welcome supersedes the build. */
372
- deferredFrames = [];
373
- /** Text of the most recent assistant message, kept current from the welcome
374
- * snapshot AND the live event stream so `/copy` (getLastAssistantText) works
375
- * whether the message arrived before or after attach. */
376
- lastAssistantText;
377
- /** Existing file paths found anywhere in the rendered transcript, newest first. */
378
- transcriptFilePaths = [];
379
- /** Canonical copyable transcript blocks, in their rendered visual order. */
380
- copyBlockRecords = [];
381
- copyIndex = new Map();
382
- /** Registrations made while building condensed history are collapsed onto its
383
- * outer container once that container becomes a top-level viewport block. */
384
- condensedCopyBlocks = new WeakMap();
385
- constructor(tui, container, opts = {}) {
386
- this.tui = tui;
387
- this.container = container;
388
- this.cwd = opts.cwd ?? process.cwd();
389
- this.showImages = opts.showImages ?? true;
390
- this.imageWidthCells = opts.imageWidthCells ?? 60;
391
- this.hideThinking = opts.hideThinking ?? false;
392
- this.hiddenThinkingLabel = opts.hiddenThinkingLabel ?? 'Thinking...';
393
- this.toolOutputExpanded = opts.toolOutputExpanded ?? false;
394
- this.liveCycles = opts.liveCycles ?? readLiveCycles();
395
- this.condensedHistory = opts.condensedHistory ?? readCondensedHistory();
396
- this.onFooterEvent = opts.onFooterEvent;
397
- this.onActivityChange = opts.onActivityChange;
398
- this.inlinePageBlocks = opts.inlinePageBlocks ?? false;
399
- this.pageOpenHint = opts.pageOpenHint ?? (() => 'crtr human list');
400
- this.backgroundBashHint = opts.backgroundBashHint ?? (() => null);
401
- this.recapPalette = opts.palette ?? defaultAttachPalette;
402
- this.spinnerStyle = this.recapPalette.active;
403
- this.dimStyle = this.recapPalette.muted;
404
- this.errorStyle = this.recapPalette.error;
405
- // Banner sits above history and OUTSIDE it, so resetChat() (which clears only
406
- // historyContainer) never wipes it — it persists across every welcome snapshot.
407
- if (opts.banner && opts.banner.length > 0) {
408
- const banner = new MeasuredContainer();
409
- banner.addChild(new Spacer(1));
410
- for (const line of opts.banner)
411
- banner.addChild(new Text(line, 1, 0));
412
- banner.addChild(new Spacer(1));
413
- this.bannerContainer = banner;
414
- this.container.addChild(banner);
415
- }
416
- this.container.addChild(this.historyContainer);
417
- if (!this.onActivityChange)
418
- this.container.addChild(this.statusContainer);
419
- this.transcript = new CompositeViewportSource([
420
- ...(this.bannerContainer ? [this.bannerContainer] : []),
421
- this.historyContainer,
422
- ...(this.onActivityChange ? [] : [this.statusContainer]),
423
- ]);
424
- }
425
- /** The transcript as one flat ordered block list for the viewport. */
426
- transcriptSource() {
427
- return this.transcript;
428
- }
429
- // Catch-up: render the welcome snapshot, then live events resume.
430
- /** Render the full message history from a `welcome` snapshot. Ports pi's
431
- * `renderSessionContext` (interactive-mode.js:2553): assistant messages spawn
432
- * tool-execution components matched to their toolResult messages; everything
433
- * else routes through `addMessageToChat`. The TUI's differential renderer +
434
- * reflow-on-resize is automatic — no scrollback reconstruction needed. */
435
- async applySnapshot(snapshot) {
436
- // Open a new build generation. Any older build still suspended at a yield
437
- // abandons itself when it resumes (generation check below), and live frames
438
- // that were deferred against the transcript we are about to discard are
439
- // dropped — a newer welcome always wins.
440
- const generation = ++this.snapshotGeneration;
441
- this.applyingSnapshot = true;
442
- this.deferredFrames.length = 0;
443
- this.resetChat();
444
- this.projection = projectSnapshot(snapshot, this.projection);
445
- this.workingActivity = this.projection.workingActivity;
446
- this.runActive = this.projection.isStreaming;
447
- this.seedToolGroupSummaries(this.projection.toolGroupSummaryDetails);
448
- const renderedPendingTools = new Map();
449
- const messages = this.projection.messages;
450
- const lastIndex = messages.length - 1;
451
- // Cycles older than the trailing `live_cycles` are condensed into one nested
452
- // container before the live region is built. It retains only configured prose
453
- // and cycle seams, avoiding old tool components while still reflowing on pane
454
- // resize. `liveStart` is 0 until the node has yielded past the configured
455
- // window, so a fresh node renders at full fidelity.
456
- const liveStart = liveRegionStart(messages, this.liveCycles);
457
- if (liveStart > 0) {
458
- const condensed = await this.buildCondensedBlock(messages.slice(0, liveStart), generation);
459
- if (generation !== this.snapshotGeneration)
460
- return;
461
- if (condensed)
462
- this.appendCondensedBlock(condensed);
463
- }
464
- for (let i = liveStart; i < messages.length; i++) {
465
- // Yield to the event loop every SNAPSHOT_YIELD_EVERY messages so queued
466
- // stdin drains (keystrokes are handled instead of bursting after a long
467
- // catch-up) while a big transcript constructs. Skipped for a STREAMING
468
- // snapshot: its in-flight tail + pending tools must be bound before any
469
- // relayed message_update/message_end lands, so it builds synchronously
470
- // (no await → no broker frame can interleave and freeze the live bubble).
471
- if (!this.projection.isStreaming &&
472
- i > liveStart &&
473
- (i - liveStart) % SNAPSHOT_YIELD_EVERY === 0) {
474
- await new Promise((resolve) => setImmediate(resolve));
475
- // A newer welcome arrived while we were suspended — abandon this stale
476
- // build without touching the view (or the gate) it no longer owns.
477
- if (generation !== this.snapshotGeneration)
478
- return;
479
- }
480
- const message = messages[i];
481
- if (message.role === 'assistant') {
482
- // Keep the `/copy` source current from the catch-up transcript too, not
483
- // only the live stream (you usually attach AFTER the last reply landed).
484
- const text = assistantVisibleText(message);
485
- if (text.trim()) {
486
- this.lastAssistantText = text;
487
- this.pushTranscriptText(text);
488
- }
489
- // If the snapshot caught an IN-FLIGHT assistant turn (state.isStreaming
490
- // and this is the trailing, non-terminal assistant message), bind it as
491
- // the live streaming component so the relayed message_update/message_end
492
- // frames that follow `welcome` land on it. Otherwise the in-flight
493
- // message would freeze at its snapshot value until the next turn — the
494
- // common case, since you typically attach to a node that is working.
495
- const isStreamingTail = i === lastIndex &&
496
- this.projection.isStreaming &&
497
- message.stopReason !== 'aborted' &&
498
- message.stopReason !== 'error';
499
- const hasProse = assistantVisibleText(message).trim() !== '';
500
- const toolCalls = this.assistantToolCalls(message);
501
- const endedWithFailure = message.stopReason === 'aborted' || message.stopReason === 'error';
502
- const terminalErrorMessage = endedByAbort(message) ? 'Interrupted' : (message.errorMessage ?? 'Error');
503
- // A terminal assistant failure remains visible as its own boundary. Settle
504
- // any interrupted calls so the completed span before it can still recap.
505
- if (endedWithFailure) {
506
- for (const component of renderedPendingTools.values()) {
507
- const result = { content: [{ type: 'text', text: terminalErrorMessage }], isError: true };
508
- component.updateResult(result);
509
- this.registerCopyBlock(component, 'tool', terminalErrorMessage);
510
- this.settleGroupTool(component, result, true);
511
- }
512
- renderedPendingTools.clear();
513
- }
514
- if (hasProse || endedWithFailure)
515
- this.closeOpenGroup();
516
- let separator;
517
- if (isStreamingTail) {
518
- this.streamingComponent = new ViewerAssistantMessageComponent(undefined, this.hideThinking, attachMarkdownTheme(), this.hiddenThinkingLabel, this.markdownTransformers);
519
- this.appendAssistantPart(this.streamingComponent, !hasProse);
520
- this.registerCopyBlock(this.streamingComponent, 'assistant', '');
521
- this.streamingWasGroupMember = !hasProse;
522
- this.streamingComponent.updateContent(message);
523
- this.registerCopyBlock(this.streamingComponent, 'assistant', assistantVisibleText(message));
524
- separator = this.streamingToolSeparator = this.appendAssistantSeparator(!hasProse);
525
- }
526
- else {
527
- separator = this.appendAssistantMessage(message, !hasProse && !endedWithFailure);
528
- }
529
- if (separator)
530
- this.setAssistantSeparatorContent(separator, message);
531
- for (const content of toolCalls) {
532
- this.pushTranscriptValue(content.arguments);
533
- const component = this.appendToolComponent(content.name, content.id, content.arguments);
534
- // (isStreamingTail is never aborted/error, so its tools fall through to
535
- // renderedPendingTools → pendingTools, where live tool events find them.)
536
- if (message.stopReason === 'aborted' || message.stopReason === 'error') {
537
- component.updateResult({ content: [{ type: 'text', text: terminalErrorMessage }], isError: true });
538
- this.registerCopyBlock(component, 'tool', terminalErrorMessage);
539
- this.settleGroupTool(component, { content: [{ type: 'text', text: terminalErrorMessage }], isError: true }, true);
540
- }
541
- else {
542
- renderedPendingTools.set(content.id, component);
543
- }
544
- }
545
- if (endedWithFailure)
546
- this.closeOpenGroup();
547
- }
548
- else if (message.role === 'toolResult') {
549
- this.pushTranscriptText(this.userMessageText(message));
550
- const component = renderedPendingTools.get(message.toolCallId);
551
- if (component) {
552
- component.updateResult(message);
553
- this.registerCopyBlock(component, 'tool', this.toolResultText(message));
554
- this.historyContainer.markDirty(component);
555
- this.settleGroupTool(component, message, message.isError === true);
556
- renderedPendingTools.delete(message.toolCallId);
557
- this.maybeAppendPageBlock(message);
558
- }
559
- }
560
- else {
561
- this.addMessageToChat(message);
562
- }
563
- }
564
- for (const [id, component] of renderedPendingTools) {
565
- this.pendingTools.set(id, component);
566
- }
567
- // A rebuild constructs fresh components, which are born unfolded; re-apply the
568
- // setting so a reconnect/welcome does not silently unfold the transcript.
569
- this.applyToolDisplay();
570
- // If we attached mid-turn, the `agent_start` that spins up the working loader
571
- // already fired before we connected — restore it from the snapshot's streaming
572
- // state so an actively-working node shows the spinner right away.
573
- if (this.projection.isStreaming)
574
- this.setActivity(this.makeLoader(this.workingActivity));
575
- this.tui.requestRender();
576
- // Build complete and still current (a mismatch would have returned above):
577
- // open the gate and replay, in wire order, any live frames that arrived
578
- // during construction so they land on the finished transcript.
579
- this.applyingSnapshot = false;
580
- this.replayDeferredFrames();
581
- }
582
- /**
583
- * Build the condensed form of the already-finished cycles as a nested component
584
- * container, or return undefined when nothing survives condensation.
585
- *
586
- * Reuses `addMessageToChat` by retargeting `append()` at the nested container, so
587
- * condensed history uses the same renderer as live history with tool traffic
588
- * filtered out. The outer history cache keeps stable-width frames cheap, while
589
- * preserving the components lets pane-width changes reflow their content. The
590
- * build yields on the live cadence and abandons itself when a newer welcome
591
- * supersedes this generation.
592
- */
593
- async buildCondensedBlock(messages, generation) {
594
- const condensed = new Container();
595
- const previousTarget = this.appendTarget;
596
- const copyBlocks = [];
597
- this.appendTarget = condensed;
598
- this.condensedCopyBlocks.set(condensed, copyBlocks);
599
- try {
600
- let built = 0;
601
- for (const message of messages) {
602
- if (!keepWhenCondensed(message, this.condensedHistory))
603
- continue;
604
- if (built > 0 && built % SNAPSHOT_YIELD_EVERY === 0) {
605
- await new Promise((resolve) => setImmediate(resolve));
606
- if (generation !== this.snapshotGeneration)
607
- return undefined;
608
- }
609
- built++;
610
- // Condensed prose still feeds the @-path picker; `lastAssistantText` (the
611
- // `/copy` source) deliberately does not — the live region always holds the
612
- // newest reply.
613
- this.pushTranscriptText(this.userMessageText(message));
614
- this.addMessageToChat(message);
615
- }
616
- }
617
- finally {
618
- this.appendTarget = previousTarget;
619
- this.condensedCopyBlocks.delete(condensed);
620
- }
621
- return condensed.children.length > 0 ? { component: condensed, copyBlocks } : undefined;
622
- }
623
- /** Defer a live broker frame when a snapshot build is in flight. Returns true
624
- * (and enqueues the replay closure) while building so the caller returns
625
- * without mutating the half-rebuilt view; false when the caller may proceed.
626
- * This is the single-writer gate every live-frame entry point passes through. */
627
- deferIfBuilding(replay) {
628
- if (!this.applyingSnapshot)
629
- return false;
630
- this.deferredFrames.push(replay);
631
- return true;
632
- }
633
- /** Replay deferred live frames in wire order. The gate is already open, so each
634
- * closure re-enters its entry point and dispatches immediately. */
635
- replayDeferredFrames() {
636
- const frames = this.deferredFrames.splice(0);
637
- for (const replay of frames)
638
- replay();
639
- }
640
- /** Apply the broker's random choice for a newly received user message. */
641
- setWorkingActivity(activity) {
642
- if (this.deferIfBuilding(() => this.setWorkingActivity(activity)))
643
- return;
644
- const wasShowingWorkingActivity = this.projection.activity === this.workingActivity;
645
- this.projection = projectWorkingActivity(this.projection, activity);
646
- this.workingActivity = this.projection.workingActivity;
647
- if (this.runActive && wasShowingWorkingActivity)
648
- this.setActivity(this.makeLoader(this.workingActivity));
649
- }
650
- /** Clear live turn state after the broker reports completion or the viewer observes dormancy. */
651
- settleRun() {
652
- this.runActive = false;
653
- for (const component of this.pendingTools.values())
654
- this.settleGroupTool(component);
655
- if (this.streamingComponent) {
656
- this.historyContainer.removeChild(this.streamingComponent);
657
- this.unregisterCopyBlock(this.streamingComponent);
658
- this.streamingComponent = undefined;
659
- }
660
- this.streamingToolSeparator = undefined;
661
- this.pendingTools.clear();
662
- this.applyToolDisplay();
663
- this.setActivity(undefined);
664
- this.settleBashComponent();
665
- }
666
- /** Stop any spinning activity loader. A one-shot `crtr surface attach` process lets its
667
- * timers die with the process, but if T7 reuses a ChatView across reconnects in
668
- * one process it should call this on detach to avoid a leaked interval. */
669
- dispose() {
670
- this.settleRun();
671
- }
672
- // Global display toggles (Ctrl+O / Ctrl+T), driven by the input controller.
673
- // Pure client-side render state — no broker round-trip — ported from pi's
674
- // `setToolsExpanded` / `toggleThinkingBlockVisibility`.
675
- /** Ctrl+O prefers summaries when the user enabled both folding and summary
676
- * generation. */
677
- toggleToolsExpanded() {
678
- let result;
679
- if (this.summarizeToolCalls && this.foldSettledTools) {
680
- this.showGroupSummaries = !this.showGroupSummaries;
681
- this.toolOutputExpanded = !this.showGroupSummaries;
682
- result = { kind: 'summaries', shown: this.showGroupSummaries };
683
- }
684
- else {
685
- this.toolOutputExpanded = !this.toolOutputExpanded;
686
- result = { kind: 'output', expanded: this.toolOutputExpanded };
687
- }
688
- this.applyToolDisplay();
689
- return result;
690
- }
691
- /** The `fold finished tool calls` view setting (`/fold-tools`, Alt+C → z → f).
692
- * Returns the new state so the caller can surface a notice. */
693
- toggleFoldSettledTools() {
694
- this.foldSettledTools = !this.foldSettledTools;
695
- persistFoldFinishedTools(this.foldSettledTools);
696
- // Turning folding back on restores the configured default (summaries),
697
- // rather than preserving a stale Ctrl+O choice from an unfolded view.
698
- if (this.summarizeToolCalls && this.foldSettledTools)
699
- this.showGroupSummaries = true;
700
- this.applyToolDisplay();
701
- return this.foldSettledTools;
702
- }
703
- /** Push both display settings onto every rendered component. A tool call still in
704
- * flight is never hidden or minimized. Only a settled group with a broker-known
705
- * summary collapses; incomplete/failed generation leaves its folded call lines. */
706
- applyToolDisplay() {
707
- const inFlight = new Set(this.pendingTools.values());
708
- for (const group of this.groups)
709
- for (const tool of group.inFlight)
710
- inFlight.add(tool);
711
- for (const child of this.historyContainer.children) {
712
- if (child instanceof MinimizableToolComponent)
713
- child.setMinimized(this.foldSettledTools && !inFlight.has(child));
714
- if (isExpandable(child))
715
- child.setExpanded(this.toolOutputExpanded);
716
- }
717
- for (const group of this.groups)
718
- this.applyGroupDisplay(group);
719
- this.updateFoldedToolSeparators(inFlight);
720
- this.historyContainer.markDirty();
721
- this.tui.requestRender();
722
- }
723
- /** Ctrl+T / app.thinking.toggle — flip thinking-block visibility and apply it to
724
- * every assistant message (the in-flight streaming bubble is itself a child of
725
- * the container, so the loop covers it too). Returns the new HIDDEN state. */
726
- toggleThinking() {
727
- this.hideThinking = !this.hideThinking;
728
- for (const child of this.historyContainer.children) {
729
- if (child instanceof AssistantMessageComponent)
730
- child.setHideThinkingBlock(this.hideThinking);
731
- }
732
- for (const [separator, content] of this.foldedToolSeparatorContents) {
733
- separator.setSeparatesToolGroup(content.hasText || (!this.hideThinking && content.hasThinking));
734
- }
735
- this.historyContainer.markDirty();
736
- this.tui.requestRender();
737
- return this.hideThinking;
738
- }
739
- // Live stream: the 15-of-17-case handleEvent port (turn_start/turn_end no-op,
740
- // exactly as interactive pi falls through default for those two).
741
- handleEvent(event) {
742
- // Order behind an in-flight catch-up: a live turn that starts while a large
743
- // welcome is still building is replayed after it, never interleaved into it.
744
- if (this.deferIfBuilding(() => this.handleEvent(event)))
745
- return;
746
- this.projection = projectEvent(this.projection, event);
747
- switch (event.type) {
748
- case 'agent_start': {
749
- this.runActive = this.projection.isStreaming;
750
- for (const component of this.pendingTools.values())
751
- this.settleGroupTool(component);
752
- this.pendingTools.clear();
753
- this.setActivity(this.makeLoader(this.workingActivity));
754
- break;
755
- }
756
- case 'agent_end': {
757
- this.settleRun();
758
- // The node you're watching just finished its turn and handed control
759
- // back — ring the completion bell (the Claude-Code Stop-hook ding).
760
- // Best-effort/detached; gated on the `completion_bell` config setting.
761
- // Only ever reached inside a live viewer pane, so a headless/background
762
- // node (no ChatView) is always silent.
763
- ringCompletionBell();
764
- break;
765
- }
766
- // The whole run has truly settled (after any recovery/continuations). This
767
- // is the broker's canonical turn-over signal and is always relayed, so use
768
- // it as a safety net to clear a lingering activity loader: a missed or
769
- // abnormal `agent_end` would otherwise leave a dormant, between-wakes node
770
- // showing a frozen `Working…` spinner. No bell here — `agent_end` already
771
- // rang it on the normal path; this only cleans up display state.
772
- case 'agent_settled': {
773
- this.settleRun();
774
- break;
775
- }
776
- case 'message_start': {
777
- if (event.message.role === 'custom' || event.message.role === 'user') {
778
- this.addMessageToChat(event.message);
779
- }
780
- else if (event.message.role === 'assistant') {
781
- const hasProse = assistantVisibleText(event.message).trim() !== '';
782
- if (hasProse)
783
- this.closeOpenGroup();
784
- this.streamingComponent = new ViewerAssistantMessageComponent(undefined, this.hideThinking, attachMarkdownTheme(), this.hiddenThinkingLabel, this.markdownTransformers);
785
- this.streamingWasGroupMember = !hasProse;
786
- this.appendAssistantPart(this.streamingComponent, !hasProse);
787
- this.registerCopyBlock(this.streamingComponent, 'assistant', '');
788
- this.streamingComponent.updateContent(event.message);
789
- this.registerCopyBlock(this.streamingComponent, 'assistant', assistantVisibleText(event.message));
790
- this.streamingToolSeparator = this.appendAssistantSeparator(!hasProse);
791
- this.setAssistantSeparatorContent(this.streamingToolSeparator, event.message);
792
- }
793
- break;
794
- }
795
- case 'message_update': {
796
- if (this.streamingComponent && event.message.role === 'assistant') {
797
- this.promoteStreamingAssistantToBoundary(event.message);
798
- // Incomplete Mermaid fences and HTML pairs stay literal until their
799
- // closing marker arrives; the transformers upgrade them on the render
800
- // that follows, with no separate mid-stream path.
801
- this.streamingComponent.updateContent(event.message);
802
- this.registerCopyBlock(this.streamingComponent, 'assistant', assistantVisibleText(event.message));
803
- this.historyContainer.markDirty(this.streamingComponent);
804
- const toolCalls = this.assistantToolCalls(event.message);
805
- if (this.streamingToolSeparator)
806
- this.setAssistantSeparatorContent(this.streamingToolSeparator, event.message);
807
- for (const content of toolCalls) {
808
- this.pushTranscriptValue(content.arguments);
809
- const existing = this.pendingTools.get(content.id);
810
- if (existing) {
811
- existing.updateArgs(content.arguments);
812
- this.noteGroupTool(existing, content.name, content.arguments);
813
- this.historyContainer.markDirty(existing);
814
- }
815
- else {
816
- const component = this.appendToolComponent(content.name, content.id, content.arguments);
817
- this.pendingTools.set(content.id, component);
818
- }
819
- }
820
- }
821
- break;
822
- }
823
- case 'message_end': {
824
- if (event.message.role !== 'assistant')
825
- break;
826
- const endedWithFailure = event.message.stopReason === 'aborted' || event.message.stopReason === 'error';
827
- // A terminal failure is always its own visible boundary, including an
828
- // empty abort created by yield or a daemon restart.
829
- this.promoteStreamingAssistantToBoundary(event.message, endedWithFailure);
830
- // Stash the completed reply's text for `/copy` (skip aborted/error turns,
831
- // whose text is partial or absent).
832
- if (this.streamingComponent)
833
- this.registerCopyBlock(this.streamingComponent, 'assistant', assistantVisibleText(event.message));
834
- if (event.message.stopReason !== 'aborted' && event.message.stopReason !== 'error') {
835
- const text = assistantVisibleText(event.message);
836
- if (text.trim()) {
837
- this.lastAssistantText = text;
838
- this.pushTranscriptText(text);
839
- }
840
- }
841
- if (this.streamingComponent) {
842
- const stopReason = event.message.stopReason;
843
- let errorMessage = event.message.errorMessage;
844
- // An aborted turn may be a user interrupt or a lifecycle interruption
845
- // (a refresh-yield aborts its own turn). Providers spell it several
846
- // ways — including `stopReason: 'error'` carrying a bare AbortError,
847
- // which would otherwise render as a red `Error: This operation was
848
- // aborted` for a perfectly healthy yield — so override it outright
849
- // with one plain, human label.
850
- if (endedByAbort(event.message)) {
851
- errorMessage = 'Interrupted';
852
- // Surface the abort on the assistant bubble itself, mirroring pi
853
- // (interactive-mode.js:2280 sets streamingMessage.errorMessage before
854
- // updateContent) so the rendered message shows the annotation. The
855
- // stopReason moves with it: pi's component reserves its red
856
- // `Error: …` line for stopReason 'error', and an abort is not one.
857
- event.message.errorMessage = errorMessage;
858
- event.message.stopReason = 'aborted';
859
- }
860
- this.streamingComponent.updateContent(event.message);
861
- if (stopReason === 'aborted' || stopReason === 'error') {
862
- const text = errorMessage ?? 'Error';
863
- for (const component of this.pendingTools.values()) {
864
- component.updateResult({ content: [{ type: 'text', text }], isError: true });
865
- this.registerCopyBlock(component, 'tool', text);
866
- this.settleGroupTool(component, { content: [{ type: 'text', text }], isError: true }, true);
867
- this.historyContainer.markDirty(component);
868
- }
869
- this.pendingTools.clear();
870
- }
871
- else {
872
- // Finalize renderer caches now that every tool argument is complete.
873
- for (const component of this.pendingTools.values()) {
874
- component.setArgsComplete();
875
- this.historyContainer.markDirty(component);
876
- }
877
- }
878
- this.historyContainer.markDirty(this.streamingComponent);
879
- this.streamingComponent = undefined;
880
- this.streamingToolSeparator = undefined;
881
- }
882
- if (endedWithFailure) {
883
- this.closeOpenGroup();
884
- // A summary normally follows this terminal frame, but re-evaluate now
885
- // too so an early recap immediately folds the tools before this seam.
886
- this.applyToolDisplay();
887
- }
888
- break;
889
- }
890
- case 'tool_execution_start': {
891
- this.pushTranscriptValue(event.args);
892
- let component = this.pendingTools.get(event.toolCallId);
893
- if (!component) {
894
- component = this.appendToolComponent(event.toolName, event.toolCallId, event.args);
895
- this.pendingTools.set(event.toolCallId, component);
896
- }
897
- else {
898
- this.noteGroupTool(component, event.toolName, event.args);
899
- }
900
- component.markExecutionStarted();
901
- this.historyContainer.markDirty(component);
902
- break;
903
- }
904
- case 'tool_execution_update': {
905
- const result = this.projection.partialToolResults.get(event.toolCallId) ?? event.partialResult;
906
- this.pushTranscriptValue(result);
907
- const component = this.pendingTools.get(event.toolCallId);
908
- if (component) {
909
- component.updateResult(result, true);
910
- this.registerCopyBlock(component, 'tool', this.toolResultText(result));
911
- this.historyContainer.markDirty(component);
912
- }
913
- break;
914
- }
915
- case 'tool_execution_end': {
916
- const result = this.projection.partialToolResults.get(event.toolCallId) ?? event.result;
917
- this.pushTranscriptValue(result);
918
- const component = this.pendingTools.get(event.toolCallId);
919
- if (component) {
920
- component.updateResult(result);
921
- this.registerCopyBlock(component, 'tool', this.toolResultText(result));
922
- this.pendingTools.delete(event.toolCallId);
923
- this.settleGroupTool(component, result, event.isError);
924
- this.applyToolDisplay();
925
- this.historyContainer.markDirty(component);
926
- this.maybeAppendPageBlock(result);
927
- }
928
- break;
929
- }
930
- case 'compaction_start': {
931
- const label = event.reason === 'manual' ? 'Compacting context...' : 'Auto-compacting...';
932
- this.setActivity(this.makeLoader(label));
933
- break;
934
- }
935
- case 'compaction_end': {
936
- this.setActivity(this.runActive ? this.makeLoader(this.workingActivity) : undefined);
937
- if (event.aborted) {
938
- this.showStatus(event.reason === 'manual' ? 'Compaction cancelled' : 'Auto-compaction cancelled');
939
- }
940
- else if (event.result) {
941
- // 0.78.1 divergence from the §3.2 sketch: `compaction_end` carries only
942
- // the CompactionResult (summary + tokensBefore), NOT the post-compaction
943
- // message list — so the viewer cannot clear+rebuild the transcript the
944
- // way in-process pi does (it rebuilds from its own SessionManager). We
945
- // append the compaction summary marker instead and KEEP the
946
- // pre-compaction scrollback for the rest of this attach session; a fresh
947
- // re-attach gets the already-compacted history via `welcome`. (Reported
948
- // in T5's final.)
949
- this.addMessageToChat({
950
- role: 'compactionSummary',
951
- summary: event.result.summary,
952
- tokensBefore: event.result.tokensBefore,
953
- timestamp: Date.now(),
954
- });
955
- }
956
- else if (event.errorMessage) {
957
- this.showError(event.errorMessage);
958
- }
959
- break;
960
- }
961
- case 'auto_retry_start': {
962
- const seconds = Math.ceil(event.delayMs / 1000);
963
- this.setActivity(this.makeLoader(`Retrying (${event.attempt}/${event.maxAttempts}) in ${seconds}s...`));
964
- break;
965
- }
966
- case 'auto_retry_end': {
967
- this.setActivity(this.runActive ? this.makeLoader(this.workingActivity) : undefined);
968
- if (!event.success) {
969
- this.showError(`Retry failed after ${event.attempt} attempts: ${event.finalError ?? 'Unknown error'}`);
970
- }
971
- break;
972
- }
973
- // Footer/header-only — ChatView owns no footer; forward to the sink.
974
- case 'queue_update':
975
- case 'session_info_changed':
976
- case 'thinking_level_changed':
977
- this.onFooterEvent?.(event);
978
- break;
979
- // turn_start / turn_end — interactive pi ignores these (falls through
980
- // default); the viewer does too.
981
- default:
982
- break;
983
- }
984
- // No unconditional markDirty here: appends/removes invalidate through
985
- // MeasuredContainer, and branches that mutate a child in place explicitly
986
- // mark it dirty. Activity-only events leave settled history cached while the
987
- // independent status loader animates.
988
- this.tui.requestRender();
989
- }
990
- // `!` bash live stream (broker bash_start/bash_output/bash_end frames). Mirrors
991
- // pi interactive mode's `!` handling: create the component on start, stream
992
- // chunks into it, mark complete on end. The persisted `bashExecution` message
993
- // also rides the next snapshot, so this only drives the LIVE view.
994
- bashStart(command, excludeFromContext) {
995
- if (this.deferIfBuilding(() => this.bashStart(command, excludeFromContext)))
996
- return;
997
- this.projection = projectBashStart(this.projection, command, excludeFromContext);
998
- this.closeOpenGroup();
999
- this.settleBashComponent();
1000
- let component;
1001
- component = new BashExecutionComponent(command, this.componentTui(() => component), excludeFromContext);
1002
- this.bashComponent = component;
1003
- this.append(component);
1004
- this.tui.requestRender();
1005
- }
1006
- bashOutput(chunk) {
1007
- if (this.deferIfBuilding(() => this.bashOutput(chunk)))
1008
- return;
1009
- this.projection = projectBashOutput(this.projection, chunk);
1010
- this.pushTranscriptText(chunk);
1011
- if (this.bashComponent) {
1012
- this.bashComponent.appendOutput(chunk);
1013
- this.historyContainer.markDirty(this.bashComponent);
1014
- }
1015
- this.tui.requestRender();
1016
- }
1017
- bashEnd(result) {
1018
- if (this.deferIfBuilding(() => this.bashEnd(result)))
1019
- return;
1020
- this.projection = projectBashEnd(this.projection, result);
1021
- this.settleBashComponent(result);
1022
- this.tui.requestRender();
1023
- }
1024
- // Rebuild path (ports addMessageToChat, interactive-mode.js:2483).
1025
- addMessageToChat(message) {
1026
- // Crouter-generated context retains its runtime role (user vs custom) so
1027
- // delivery to the model is unchanged, but every attached view presents it
1028
- // through one compact disclosure contract. The producer's envelope is what
1029
- // classifies, so an ordinary user prompt cannot acquire this treatment and
1030
- // saved transcripts gain it too.
1031
- const card = parseCard(message);
1032
- if (card !== null &&
1033
- (message.role !== 'custom' || message.display === true)) {
1034
- this.pushTranscriptText(card.body);
1035
- // A person's inbox answer is the person speaking: their words leave the
1036
- // card and render as their own message. A digest carrying nothing else
1037
- // gets no card at all — but a passive backlog folded into the same body
1038
- // is content, so the residue check keeps it from vanishing with the card.
1039
- const answers = card.senders
1040
- .flatMap((sender) => sender.entries)
1041
- .filter((entry) => entry.disposition === 'human-answer')
1042
- .map((entry) => entry.body.trim())
1043
- .filter((text) => text !== '');
1044
- const onlyHumanWords = answers.length > 0
1045
- && card.body.replace(INBOX_SENDER_SECTIONS, '').trim() === ''
1046
- && card.senders.every((sender) => sender.entries.every((entry) => entry.disposition === 'human-answer'));
1047
- if (!onlyHumanWords) {
1048
- const presentation = presentationFor(card.kind);
1049
- const component = new ContextMessageComponent(card, presentation, this.toolOutputExpanded, this.dimStyle, (s) => this.spinnerStyle(this.labelStyle(s)));
1050
- // A boundary card is a visible seam, not a group member: the preceding
1051
- // span keeps its own recap and the next tool call begins a
1052
- // broker-aligned fresh group.
1053
- if (isGroupBoundaryKind(card.kind)) {
1054
- this.closeOpenGroup();
1055
- this.append(component);
1056
- }
1057
- else {
1058
- // A folded group hides its members, so whatever the card should leave
1059
- // behind — a child's final, a recovery — reaches the recap here.
1060
- this.appendGroupMember(component)?.activity.noteCard(card, presentation);
1061
- }
1062
- }
1063
- for (const answer of answers)
1064
- this.appendHumanAnswer(answer);
1065
- return;
1066
- }
1067
- switch (message.role) {
1068
- case 'bashExecution': {
1069
- this.closeOpenGroup();
1070
- this.pushTranscriptText(message.output ?? '');
1071
- const component = new BashExecutionComponent(message.command, this.tui, message.excludeFromContext);
1072
- if (message.output)
1073
- component.appendOutput(message.output);
1074
- component.setComplete(message.exitCode, message.cancelled,
1075
- // pi's interactive mode passes a minimal `{truncated:true}` marker here
1076
- // (interactive-mode.js:2489) where the typed param is the full
1077
- // TruncationResult; the snapshot message only carries the boolean, so we
1078
- // mirror pi and cast.
1079
- message.truncated ? { truncated: true } : undefined, message.fullOutputPath);
1080
- this.append(component);
1081
- break;
1082
- }
1083
- case 'custom': {
1084
- if (message.display) {
1085
- this.pushTranscriptText(this.userMessageText(message));
1086
- if (message.customType === CRTR_OUTPUT_CUSTOM_TYPE) {
1087
- this.appendGroupMember(new CrtrOutputMessageComponent(this.userMessageText(message), this.toolOutputExpanded, this.crtrOutputTheme()));
1088
- break;
1089
- }
1090
- // A refresh-yield cycle boundary (session-cycles.ts, synthetic — never
1091
- // persisted): render as a dim rule rather than the generic custom-
1092
- // message card, so scrolling through a multi-cycle node's full history
1093
- // reads as one conversation with clear seams between cycles.
1094
- if (message.customType === CRTR_CYCLE_DIVIDER_CUSTOM_TYPE) {
1095
- this.closeOpenGroup();
1096
- this.append(new Spacer(1));
1097
- this.append(new Text(this.dimStyle(`── ${this.userMessageText(message)} ──`), 1, 0));
1098
- this.append(new Spacer(1));
1099
- break;
1100
- }
1101
- const component = new CustomMessageComponent(styleAttachMessageMarkdown(message), undefined, attachMarkdownTheme());
1102
- component.setExpanded(this.toolOutputExpanded);
1103
- this.appendGroupMember(component);
1104
- }
1105
- break;
1106
- }
1107
- case 'compactionSummary': {
1108
- this.closeOpenGroup();
1109
- this.append(new Spacer(1));
1110
- const component = new CompactionSummaryMessageComponent(styleAttachSummaryMarkdown(message), attachMarkdownTheme());
1111
- component.setExpanded(this.toolOutputExpanded);
1112
- this.append(component);
1113
- break;
1114
- }
1115
- case 'branchSummary': {
1116
- this.closeOpenGroup();
1117
- this.append(new Spacer(1));
1118
- const component = new BranchSummaryMessageComponent(styleAttachSummaryMarkdown(message), attachMarkdownTheme());
1119
- component.setExpanded(this.toolOutputExpanded);
1120
- this.append(component);
1121
- this.registerCopyBlock(component, 'assistant', message.summary);
1122
- break;
1123
- }
1124
- case 'user': {
1125
- if (isTrueUserMessage(message))
1126
- this.closeOpenGroup();
1127
- const textContent = this.userMessageText(message);
1128
- if (!textContent)
1129
- break;
1130
- this.pushTranscriptText(textContent);
1131
- if (this.chatChildCount() > 0)
1132
- this.appendUserPart(new Spacer(1), !isTrueUserMessage(message));
1133
- const skillBlock = parseSkillBlock(textContent);
1134
- if (skillBlock) {
1135
- // SkillInvocationMessageComponent has no transformer seam, so its body
1136
- // is still styled before construction.
1137
- const component = new SkillInvocationMessageComponent({ ...skillBlock, content: styleAttachMarkdownSource(skillBlock.content) }, attachMarkdownTheme());
1138
- component.setExpanded(this.toolOutputExpanded);
1139
- this.appendUserPart(component, !isTrueUserMessage(message));
1140
- this.registerCopyBlock(component, 'user', textContent);
1141
- if (skillBlock.userMessage) {
1142
- const userMessage = new UserMessageComponent(skillBlock.userMessage, attachMarkdownTheme(), undefined, this.markdownTransformers);
1143
- this.appendUserPart(userMessage, !isTrueUserMessage(message));
1144
- this.registerCopyBlock(userMessage, 'user', skillBlock.userMessage);
1145
- }
1146
- }
1147
- else {
1148
- const component = new UserMessageComponent(textContent, attachMarkdownTheme(), undefined, this.markdownTransformers);
1149
- this.appendUserPart(component, !isTrueUserMessage(message));
1150
- this.registerCopyBlock(component, 'user', textContent);
1151
- }
1152
- break;
1153
- }
1154
- case 'assistant': {
1155
- const hasProse = assistantVisibleText(message).trim() !== '';
1156
- if (hasProse)
1157
- this.closeOpenGroup();
1158
- this.appendAssistantMessage(message, !hasProse);
1159
- break;
1160
- }
1161
- // toolResult is rendered inline with its tool call (handled in applySnapshot).
1162
- default:
1163
- break;
1164
- }
1165
- }
1166
- // Helpers
1167
- /** Render an assistant reply plus its initially-hidden boundary separator.
1168
- * A turn that ended on its own abort is rendered as the interrupt it is,
1169
- * matching the live seam above, so re-reading the transcript later never
1170
- * turns a healthy interrupt into a red `Error:` line. */
1171
- appendAssistantMessage(message, groupMember = false) {
1172
- const component = new ViewerAssistantMessageComponent(undefined, this.hideThinking, attachMarkdownTheme(), this.hiddenThinkingLabel, this.markdownTransformers);
1173
- const rendered = endedByAbort(message)
1174
- ? { ...message, stopReason: 'aborted', errorMessage: 'Interrupted' }
1175
- : message;
1176
- component.updateContent(rendered);
1177
- this.appendAssistantPart(component, groupMember);
1178
- this.registerCopyBlock(component, 'assistant', assistantVisibleText(message));
1179
- const separator = this.appendAssistantSeparator(groupMember);
1180
- this.setAssistantSeparatorContent(separator, message);
1181
- return separator;
1182
- }
1183
- /** Add a separator in transcript order now; it renders only after a following
1184
- * tool settles in the folded view. */
1185
- appendAssistantSeparator(groupMember = false) {
1186
- const separator = new FoldedToolSeparator();
1187
- if (groupMember)
1188
- this.appendGroupMember(separator);
1189
- else
1190
- this.append(separator);
1191
- return separator;
1192
- }
1193
- appendAssistantPart(component, groupMember) {
1194
- if (groupMember)
1195
- this.appendGroupMember(component);
1196
- else
1197
- this.append(component);
1198
- }
1199
- appendUserPart(component, groupMember) {
1200
- if (groupMember)
1201
- this.appendGroupMember(component);
1202
- else
1203
- this.append(component);
1204
- }
1205
- /** An answer the person typed in their inbox renders exactly like a message
1206
- * they typed here, and closes the run around it the same way. */
1207
- appendHumanAnswer(text) {
1208
- this.closeOpenGroup();
1209
- if (this.chatChildCount() > 0)
1210
- this.append(new Spacer(1));
1211
- const component = new UserMessageComponent(text, attachMarkdownTheme(), undefined, this.markdownTransformers);
1212
- this.append(component);
1213
- this.registerCopyBlock(component, 'user', text);
1214
- }
1215
- /** Only the full-fidelity trailing region gets summary groups. Condensed
1216
- * history intentionally drops tool traffic, so grouping there would create
1217
- * phantom summary rows and cross the live/condensed boundary. */
1218
- isLiveGroupRegion() {
1219
- return this.appendTarget === this.historyContainer;
1220
- }
1221
- ensureGroup() {
1222
- if (!this.isLiveGroupRegion())
1223
- return undefined;
1224
- if (this.openGroup)
1225
- return this.openGroup;
1226
- const recap = new GroupRecapComponent();
1227
- const group = {
1228
- members: [],
1229
- recap,
1230
- activity: new GroupActivityRecorder(this.cwd, this.nodeRoster),
1231
- toolCount: 0,
1232
- inFlight: new Set(),
1233
- };
1234
- this.append(recap);
1235
- // The recap is a direct history child for cache identity, but zero-row and
1236
- // hidden until a settled broker summary makes this group collapsible.
1237
- this.historyContainer.setHidden(recap, true);
1238
- this.groups.push(group);
1239
- this.openGroup = group;
1240
- return group;
1241
- }
1242
- closeOpenGroup() {
1243
- this.openGroup = undefined;
1244
- }
1245
- appendGroupMember(component) {
1246
- const group = this.ensureGroup();
1247
- this.append(component);
1248
- if (group)
1249
- group.members.push(component);
1250
- return group;
1251
- }
1252
- removeGroupMember(component) {
1253
- for (const group of this.groups) {
1254
- const index = group.members.indexOf(component);
1255
- if (index !== -1)
1256
- group.members.splice(index, 1);
1257
- }
1258
- this.historyContainer.setHidden(component, false);
1259
- }
1260
- /** Add one tool as a group member, moving the assistant's boundary separator
1261
- * behind the new summary row without changing the separator's identity. */
1262
- appendToolComponent(name, id, args) {
1263
- const trailingSeparator = this.isLiveGroupRegion() &&
1264
- !this.openGroup &&
1265
- this.historyContainer.children.at(-1) instanceof FoldedToolSeparator
1266
- ? this.historyContainer.children.at(-1)
1267
- : undefined;
1268
- if (trailingSeparator)
1269
- this.historyContainer.removeChild(trailingSeparator);
1270
- const group = this.ensureGroup();
1271
- if (trailingSeparator) {
1272
- this.append(trailingSeparator);
1273
- group?.members.push(trailingSeparator);
1274
- }
1275
- const component = this.makeToolComponent(name, id, args);
1276
- component.activityCallId = id;
1277
- this.appendGroupMember(component);
1278
- this.registerCopyBlock(component, 'tool', '');
1279
- if (group) {
1280
- group.key ??= id;
1281
- group.toolCount++;
1282
- group.inFlight.add(component);
1283
- group.activity.noteCall(id, name, args);
1284
- }
1285
- return component;
1286
- }
1287
- noteGroupTool(component, name, args) {
1288
- if (!component.activityCallId)
1289
- return;
1290
- for (const group of this.groups) {
1291
- if (group.members.includes(component))
1292
- group.activity.noteCall(component.activityCallId, name, args);
1293
- }
1294
- }
1295
- settleGroupTool(component, result, isError = false) {
1296
- for (const group of this.groups) {
1297
- group.inFlight.delete(component);
1298
- if (!component.activityCallId || !group.members.includes(component))
1299
- continue;
1300
- if (result === undefined)
1301
- group.activity.resolveWithoutResult(component.activityCallId);
1302
- else
1303
- group.activity.settle(component.activityCallId, result, isError);
1304
- }
1305
- }
1306
- /** An assistant starts as a non-boundary while its text is empty. Visible prose
1307
- * or a terminal failure turns it into a boundary without recreating either
1308
- * pi-owned component (their direct-child cache identities remain intact). */
1309
- promoteStreamingAssistantToBoundary(message, force = false) {
1310
- if (!this.streamingWasGroupMember || (!force && assistantVisibleText(message).trim() === ''))
1311
- return;
1312
- if (this.streamingComponent)
1313
- this.removeGroupMember(this.streamingComponent);
1314
- if (this.streamingToolSeparator)
1315
- this.removeGroupMember(this.streamingToolSeparator);
1316
- this.streamingWasGroupMember = false;
1317
- this.closeOpenGroup();
1318
- }
1319
- seedToolGroupSummaries(summaries) {
1320
- this.groupSummaries.clear();
1321
- for (const [key, summary] of Object.entries(summaries))
1322
- this.groupSummaries.set(key, summary);
1323
- }
1324
- /** Broker frames can arrive before or after their group's events, and snapshot
1325
- * rebuilding defers them through the single-writer gate, so this stores first
1326
- * and applies to every currently-rendered matching group. */
1327
- applyToolGroupSummary(key, summary) {
1328
- if (this.deferIfBuilding(() => this.applyToolGroupSummary(key, summary)))
1329
- return;
1330
- this.projection = projectToolGroupSummary(this.projection, key, summary);
1331
- const projected = this.projection.toolGroupSummaryDetails[key];
1332
- if (projected === undefined)
1333
- return;
1334
- this.groupSummaries.set(key, projected);
1335
- this.applyToolDisplay();
1336
- }
1337
- applyGroupDisplay(group) {
1338
- const summary = group.key === undefined ? undefined : this.groupSummaries.get(group.key);
1339
- const collapsed = this.foldSettledTools &&
1340
- this.showGroupSummaries &&
1341
- group.toolCount > 0 &&
1342
- group.inFlight.size === 0 &&
1343
- summary !== undefined;
1344
- group.recap.setRecap(collapsed ? summary : undefined, group.toolCount, group.activity.activity(), this.detailedToolRecaps, this.recapPalette);
1345
- this.historyContainer.setHidden(group.recap, !collapsed);
1346
- for (const member of group.members)
1347
- this.historyContainer.setHidden(member, collapsed);
1348
- }
1349
- /** Make each separator visible only if its immediately-following tool call is
1350
- * actually folded; in-flight calls remain flush with their live output. */
1351
- updateFoldedToolSeparators(inFlight = new Set(this.pendingTools.values())) {
1352
- const children = this.historyContainer.children;
1353
- for (let i = 0; i < children.length; i++) {
1354
- const separator = children[i];
1355
- if (!(separator instanceof FoldedToolSeparator))
1356
- continue;
1357
- const followingTool = children[i + 1];
1358
- separator.setFolded(this.foldSettledTools &&
1359
- !this.historyContainer.hiddenChildren.has(separator) &&
1360
- followingTool instanceof MinimizableToolComponent &&
1361
- !this.historyContainer.hiddenChildren.has(followingTool) &&
1362
- !inFlight.has(followingTool));
1363
- this.historyContainer.markDirty(separator);
1364
- }
1365
- }
1366
- /** Track whether an assistant response contains prose or thinking, then make
1367
- * its separator eligible only for content the current Ctrl+T setting shows. */
1368
- setAssistantSeparatorContent(separator, message) {
1369
- const content = message.content;
1370
- const parts = Array.isArray(content) ? content : [];
1371
- const hasText = parts.some((part) => typeof part === 'object' &&
1372
- part !== null &&
1373
- part.type === 'text' &&
1374
- typeof part.text === 'string' &&
1375
- part.text.trim() !== '');
1376
- const hasThinking = parts.some((part) => typeof part === 'object' &&
1377
- part !== null &&
1378
- part.type === 'thinking' &&
1379
- typeof part.thinking === 'string' &&
1380
- part.thinking.trim() !== '');
1381
- this.foldedToolSeparatorContents.set(separator, { hasText, hasThinking });
1382
- separator.setSeparatesToolGroup(hasText || (!this.hideThinking && hasThinking));
1383
- }
1384
- /** Tool component with native viewer renderers for crouter-owned tool output. */
1385
- makeToolComponent(name, id, args) {
1386
- const fold = new FoldedToolCallController();
1387
- let resultObserver;
1388
- let toolDefinition;
1389
- if (name === 'bash') {
1390
- const crtr = createCrtrBashToolDefinition(args, fold);
1391
- if (crtr === undefined) {
1392
- toolDefinition = createCrtrPlainBashToolDefinition(this.cwd, fold, this.backgroundBashHint);
1393
- }
1394
- else {
1395
- toolDefinition = crtr.definition;
1396
- resultObserver = crtr.observeResult;
1397
- }
1398
- }
1399
- else if (name === 'edit') {
1400
- const edit = createCrtrEditToolDefinition(this.cwd, fold);
1401
- toolDefinition = edit.definition;
1402
- resultObserver = edit.observeResult;
1403
- }
1404
- else if (name === 'read') {
1405
- toolDefinition = createCrtrReadToolDefinition(this.cwd, fold);
1406
- }
1407
- else if (name === 'write') {
1408
- toolDefinition = createCrtrWriteToolDefinition(this.cwd, fold);
1409
- }
1410
- let component;
1411
- component = new MinimizableToolComponent(name, id, args, { showImages: this.showImages, imageWidthCells: this.imageWidthCells }, toolDefinition, this.componentTui(() => component), this.cwd);
1412
- component.setToolView(toolDefinition === undefined ? undefined : fold, resultObserver);
1413
- component.setExpanded(this.toolOutputExpanded);
1414
- return component;
1415
- }
1416
- /** Append conversation content above the independent live status area — or into
1417
- * the nested container while condensed history is under construction. */
1418
- append(child) {
1419
- this.appendTarget.addChild(child);
1420
- }
1421
- /** Number of rendered conversation components in the container currently being
1422
- * appended to (live history or the nested condensed region). */
1423
- chatChildCount() {
1424
- return this.appendTarget.children.length;
1425
- }
1426
- /** Clear all chat content. */
1427
- resetChat() {
1428
- this.setActivity(undefined);
1429
- this.settleBashComponent();
1430
- this.streamingComponent = undefined;
1431
- this.streamingToolSeparator = undefined;
1432
- this.streamingWasGroupMember = false;
1433
- this.foldedToolSeparatorContents.clear();
1434
- this.groups.length = 0;
1435
- this.openGroup = undefined;
1436
- this.groupSummaries.clear();
1437
- this.nodeRoster.clear();
1438
- this.pendingTools.clear();
1439
- this.lastAssistantText = undefined;
1440
- this.copyBlockRecords.length = 0;
1441
- this.copyIndex.clear();
1442
- this.transcriptFilePaths.length = 0;
1443
- this.pageBlocks.clear();
1444
- this.historyContainer.clear();
1445
- }
1446
- /** Place the transcript block for an inline page a `human send` just raised.
1447
- * The block is a plain history child, NOT a tool-group member: collapsing the
1448
- * tool group folds the command away and leaves the page itself on screen, the
1449
- * way assistant prose stays. Condensed history is skipped deliberately — old
1450
- * cycles keep only prose and cycle seams. */
1451
- maybeAppendPageBlock(result) {
1452
- if (!this.inlinePageBlocks || this.appendTarget !== this.historyContainer)
1453
- return;
1454
- const page = detectInlinePageResult(result);
1455
- if (page === undefined || this.pageBlocks.has(page.pageId))
1456
- return;
1457
- const block = new PageBlockComponent(page.pageId, this.pageOpenHint);
1458
- this.pageBlocks.set(page.pageId, block);
1459
- this.append(block);
1460
- // The block is placed empty and fills itself from the daemon: reading a
1461
- // request is a round trip, and the transcript must not block on one.
1462
- void this.loadPageBlock(block);
1463
- }
1464
- async loadPageBlock(block) {
1465
- if (!(await block.refresh()))
1466
- return;
1467
- this.historyContainer.markDirty(block);
1468
- this.tui.requestRender();
1469
- }
1470
- /** Re-measure the tool calls still in flight. A silent long-running command
1471
- * emits no tool-execution update, so nothing else would evict its cached
1472
- * lines and its backgrounding hint would never appear. Driven by the
1473
- * viewer's existing low-rate chrome poll, and cheap because it touches only
1474
- * in-flight tools — usually one, never the transcript. */
1475
- refreshInFlightTools() {
1476
- if (this.pendingTools.size === 0)
1477
- return;
1478
- for (const component of this.pendingTools.values())
1479
- this.historyContainer.markDirty(component);
1480
- this.tui.requestRender();
1481
- }
1482
- /** Re-read every placed page through the daemon. Driven by the viewer's
1483
- * ticket-activity watcher, so an answer, a cancellation, or a `--replace`
1484
- * revision lands on the block already anchored in the transcript. */
1485
- async refreshPageBlocks() {
1486
- const blocks = [...this.pageBlocks.values()];
1487
- const changed = await Promise.all(blocks.map(async (block) => {
1488
- const moved = await block.refresh();
1489
- if (moved)
1490
- this.historyContainer.markDirty(block);
1491
- return moved;
1492
- }));
1493
- if (changed.some(Boolean))
1494
- this.tui.requestRender();
1495
- }
1496
- makeLoader(message) {
1497
- // Loader updates itself on an interval. Its TUI callback has to evict the
1498
- // status block's cached frame before requesting the next render.
1499
- let loader;
1500
- const statusTui = {
1501
- requestRender: (force) => {
1502
- if (loader && !this.onActivityChange)
1503
- this.statusContainer.markDirty(loader);
1504
- this.tui.requestRender(force);
1505
- },
1506
- terminal: this.tui.terminal,
1507
- };
1508
- loader = new Loader(statusTui, this.spinnerStyle, this.dimStyle, message);
1509
- return loader;
1510
- }
1511
- /** Let a self-updating history child invalidate only its own cached lines. */
1512
- componentTui(component) {
1513
- return {
1514
- requestRender: (force) => {
1515
- this.historyContainer.markDirty(component());
1516
- this.tui.requestRender(force);
1517
- },
1518
- terminal: this.tui.terminal,
1519
- };
1520
- }
1521
- /** Complete and release the live bash component before ChatView gives up ownership. */
1522
- settleBashComponent(result) {
1523
- if (!this.bashComponent)
1524
- return;
1525
- const component = this.bashComponent;
1526
- component.setComplete(result?.exitCode, result?.cancelled ?? true, result?.truncated ? { truncated: true } : undefined, result?.fullOutputPath);
1527
- this.historyContainer.markDirty(component);
1528
- this.bashComponent = undefined;
1529
- }
1530
- /** Swap the single active activity indicator (working/compaction/retry). */
1531
- setActivity(loader) {
1532
- this.activityLoader?.stop();
1533
- this.activityLoader = loader;
1534
- if (this.onActivityChange) {
1535
- this.onActivityChange(loader);
1536
- return;
1537
- }
1538
- this.statusContainer.clear();
1539
- if (loader)
1540
- this.statusContainer.addChild(loader);
1541
- }
1542
- showStatus(message) {
1543
- this.closeOpenGroup();
1544
- this.append(new Spacer(1));
1545
- this.append(new Text(this.dimStyle(message), 1, 0));
1546
- }
1547
- showError(message) {
1548
- this.closeOpenGroup();
1549
- this.append(new Spacer(1));
1550
- this.append(new Text(this.errorStyle(message), 1, 0));
1551
- }
1552
- crtrOutputTheme() {
1553
- return {
1554
- fg: (name, text) => {
1555
- if (name === 'error')
1556
- return this.errorStyle(text);
1557
- if (name === 'warning' || name === 'accent' || name === 'toolTitle' || name === 'success')
1558
- return this.spinnerStyle(text);
1559
- if (name === 'muted')
1560
- return this.dimStyle(text);
1561
- return text;
1562
- },
1563
- bg: (_name, text) => text,
1564
- bold: (text) => this.labelStyle(text),
1565
- };
1566
- }
1567
- /** Extract the tool-call content items from an assistant message. */
1568
- assistantToolCalls(message) {
1569
- const content = message.content;
1570
- if (!Array.isArray(content))
1571
- return [];
1572
- return content.filter((c) => typeof c === 'object' && c !== null && c.type === 'toolCall');
1573
- }
1574
- /** Existing file paths from the rendered transcript, newest first. */
1575
- getTranscriptFilePathsNewestFirst() {
1576
- return [...this.transcriptFilePaths];
1577
- }
1578
- /** The text of the most recent assistant message, for `/copy`. Undefined when
1579
- * no assistant message has been seen (or it had no text content). */
1580
- getLastAssistantText() {
1581
- const t = this.lastAssistantText?.trim();
1582
- return t ? t : undefined;
1583
- }
1584
- /** Copyable source text for a transcript block, if it has any. */
1585
- blockText(block) {
1586
- const index = this.copyIndex.get(block);
1587
- return index === undefined ? undefined : this.copyBlockRecords[index]?.text;
1588
- }
1589
- /** The canonical ordered copy record, oldest → newest. */
1590
- copyBlocks() {
1591
- return this.copyBlockRecords;
1592
- }
1593
- /** Newest tool call's result text (`/copy-tool`). */
1594
- getLastToolOutputText() {
1595
- for (let i = this.copyBlockRecords.length - 1; i >= 0; i--) {
1596
- const copyBlock = this.copyBlockRecords[i];
1597
- if (copyBlock.kind !== 'tool')
1598
- continue;
1599
- return copyBlock.text.trim() === '' ? undefined : copyBlock.text;
1600
- }
1601
- return undefined;
1602
- }
1603
- /** Every copyable block's text, oldest → newest, joined by blank lines. */
1604
- getTranscriptPlainText() {
1605
- return this.copyBlockRecords
1606
- .map((copyBlock) => copyBlock.text)
1607
- .filter((text) => text.trim() !== '')
1608
- .join('\n\n');
1609
- }
1610
- registerCopyBlock(block, kind, text) {
1611
- const condensedCopyBlocks = this.condensedCopyBlocks.get(this.appendTarget);
1612
- if (condensedCopyBlocks) {
1613
- const index = condensedCopyBlocks.findIndex((copyBlock) => copyBlock.block === block);
1614
- if (index === -1)
1615
- condensedCopyBlocks.push({ block, kind, text });
1616
- else
1617
- condensedCopyBlocks[index].text = text;
1618
- return;
1619
- }
1620
- const index = this.copyIndex.get(block);
1621
- if (index === undefined) {
1622
- this.copyIndex.set(block, this.copyBlockRecords.length);
1623
- this.copyBlockRecords.push({ block, kind, text });
1624
- }
1625
- else {
1626
- this.copyBlockRecords[index].text = text;
1627
- }
1628
- }
1629
- unregisterCopyBlock(block) {
1630
- const condensedCopyBlocks = this.condensedCopyBlocks.get(this.appendTarget);
1631
- if (condensedCopyBlocks) {
1632
- const index = condensedCopyBlocks.findIndex((copyBlock) => copyBlock.block === block);
1633
- if (index !== -1)
1634
- condensedCopyBlocks.splice(index, 1);
1635
- return;
1636
- }
1637
- const index = this.copyIndex.get(block);
1638
- if (index === undefined)
1639
- return;
1640
- this.copyBlockRecords.splice(index, 1);
1641
- this.copyIndex.delete(block);
1642
- for (let i = index; i < this.copyBlockRecords.length; i++) {
1643
- this.copyIndex.set(this.copyBlockRecords[i].block, i);
1644
- }
1645
- }
1646
- appendCondensedBlock({ component, copyBlocks }) {
1647
- this.append(component);
1648
- this.registerCopyBlock(component, 'condensed', copyBlocks.map((copyBlock) => copyBlock.text).filter((text) => text.trim() !== '').join('\n\n'));
1649
- }
1650
- /** Flatten arbitrary tool result payloads into the visible text copy target. */
1651
- toolResultText(result) {
1652
- if (typeof result === 'string')
1653
- return result;
1654
- if (typeof result === 'object' && result !== null && 'content' in result) {
1655
- const content = result.content;
1656
- if (typeof content === 'string')
1657
- return content;
1658
- if (Array.isArray(content)) {
1659
- return content
1660
- .filter((part) => typeof part === 'object' &&
1661
- part !== null &&
1662
- part.type === 'text' &&
1663
- typeof part.text === 'string')
1664
- .map((part) => part.text)
1665
- .join('');
1666
- }
1667
- }
1668
- try {
1669
- const text = JSON.stringify(result);
1670
- return typeof text === 'string' ? text : '';
1671
- }
1672
- catch {
1673
- return '';
1674
- }
1675
- }
1676
- pushTranscriptText(text) {
1677
- const trimmed = text.trim();
1678
- if (trimmed === '')
1679
- return;
1680
- const paths = extractFilePaths([trimmed], this.cwd);
1681
- if (paths.length === 0)
1682
- return;
1683
- const next = [...paths, ...this.transcriptFilePaths.filter((path) => !paths.includes(path))].slice(0, 50);
1684
- this.transcriptFilePaths.splice(0, this.transcriptFilePaths.length, ...next);
1685
- }
1686
- pushTranscriptValue(value) {
1687
- try {
1688
- const text = typeof value === 'string' ? value : JSON.stringify(value);
1689
- if (typeof text === 'string')
1690
- this.pushTranscriptText(text);
1691
- }
1692
- catch {
1693
- // Tool payloads that cannot serialize are not transcript text.
1694
- }
1695
- }
1696
- /** Concatenate the text blocks of a user message (string or content array). */
1697
- userMessageText(message) {
1698
- const content = message.content;
1699
- if (typeof content === 'string')
1700
- return content;
1701
- if (!Array.isArray(content))
1702
- return '';
1703
- return content
1704
- .filter((c) => typeof c === 'object' && c !== null && c.type === 'text')
1705
- .map((c) => c.text)
1706
- .join('');
1707
- }
1708
- }
1
+ var v=Object.defineProperty;var p=(h,t)=>v(h,"name",{value:t,configurable:!0});import{Container as j,Loader as F,Spacer as d,Text as x}from"@earendil-works/pi-tui";import{AssistantMessageComponent as L,BashExecutionComponent as M,BranchSummaryMessageComponent as H,CompactionSummaryMessageComponent as W,CustomMessageComponent as $,parseSkillBlock as q,SkillInvocationMessageComponent as V,ToolExecutionComponent as N,UserMessageComponent as S}from"@earendil-works/pi-coding-agent";import{attachMarkdownTheme as u}from"../config.js";import{ContextMessageComponent as U}from"./context-message.js";import{presentationFor as z}from"./card-presentation.js";import{detectInlinePageResult as Y,PageBlockComponent as J}from"./page-block.js";import{CRTR_OUTPUT_CUSTOM_TYPE as K,CrtrOutputMessageComponent as X,createCrtrBashToolDefinition as Q}from"./crtr-output.js";import{CRTR_CYCLE_DIVIDER_CUSTOM_TYPE as Z,endedByAbort as w}from"../../../core/runtime/session-cycles.js";import{parseCard as tt}from"../../../shared/generated-context.js";import{assistantVisibleText as c,isGroupBoundaryKind as et,isTrueUserMessage as C}from"../../../shared/tool-groups.js";import{transformDiagramFences as st}from"./diagram.js";import{styleAttachAgentMarkdown as it,styleAttachMarkdownSource as E,styleAttachMessageMarkdown as ot,styleAttachSummaryMarkdown as O}from"./markdown-source.js";import{createCrtrEditToolDefinition as nt}from"./edit-diff.js";import{GroupActivityRecorder as rt}from"./group-activity.js";import{GroupRecapComponent as at}from"./group-recap.js";import{FoldedToolCallController as ht,bashCallBackgroundHintLines as pt,createCrtrPlainBashToolDefinition as lt,createCrtrReadToolDefinition as dt,createCrtrWriteToolDefinition as ct}from"./tool-calls.js";import{ringCompletionBell as ut}from"../chrome/completion-bell.js";import{extractFilePaths as mt}from"#core/human/visible-paths";import{keepWhenCondensed as ft,liveRegionStart as gt}from"./condensed-history.js";import{ViewerAssistantMessageComponent as A}from"./assistant-message.js";import{CompositeViewportSource as yt,MeasuredContainer as B}from"./measured-container.js";import{readConfig as T,updateRawConfigAtomically as Ct}from"../../../core/config.js";import{DEFAULT_CONDENSED_HISTORY as Tt,DEFAULT_LIVE_CYCLES as kt}from"../../../types.js";import{applySnapshot as bt,applyToolGroupSummary as xt,applyWorkingActivity as St,bashEnd as wt,bashOutput as At,bashStart as Bt,initialConvState as Rt,reduce as Gt}from"../../conversation/projection.js";const I=p(h=>`\x1B[2m${h}\x1B[22m`,"defaultDimStyle"),_=50;function Mt(){try{return T("user").live_cycles}catch{return kt}}p(Mt,"readLiveCycles");function Et(){try{return T("user").condensed_history}catch{return Tt}}p(Et,"readCondensedHistory");function Ot(){try{return T("user").fold_finished_tools}catch{return!1}}p(Ot,"readFoldFinishedTools");function It(){try{return T("user").summarize_tool_calls}catch{return!1}}p(It,"readSummarizeToolCalls");function _t(){try{return T("user").detailed_tool_recaps}catch{return!0}}p(_t,"readDetailedToolRecaps");function Pt(h){try{Ct("user",t=>({...t,fold_finished_tools:h}))}catch{}}p(Pt,"persistFoldFinishedTools");function Dt(h){return typeof h=="object"&&h!==null&&"setExpanded"in h&&typeof h.setExpanded=="function"}p(Dt,"isExpandable");const vt=/\x1b\[[0-9;]*m/g,jt=/\x1b\[([0-9;]*)m/g;function Ft(h){return h.replace(jt,(t,e)=>{const s=e.split(";"),i=[];for(let o=0;o<s.length;o++){const n=Number(s[o]===""?0:s[o]);if(n===38||n===48||n===58){const r=Number(s[o+1]),a=o+(r===5?2:r===2?4:1);n!==48&&i.push(...s.slice(o,a+1)),o=a;continue}n>=40&&n<=47||n>=100&&n<=107||i.push(String(n))}return i.length>0?`\x1B[${i.join(";")}m`:""})}p(Ft,"stripBackground");const Lt=/<from\b[^>]*>[\s\S]*?<\/from>/g;class R extends d{static{p(this,"FoldedToolSeparator")}folded=!1;separatesToolGroup=!1;setFolded(t){this.folded=t,this.refresh()}setSeparatesToolGroup(t){this.separatesToolGroup=t,this.refresh()}refresh(){this.setLines(this.folded&&this.separatesToolGroup?1:0)}}class G extends N{static{p(this,"MinimizableToolComponent")}activityCallId;minimized=!1;expandedState=!1;foldController;resultObserver;setToolView(t,e){this.foldController=t,this.resultObserver=e}updateResult(...t){this.resultObserver?.(t[0],t[1]??!1),super.updateResult(...t)}setExpanded(t){this.expandedState=t,super.setExpanded(t)}setMinimized(t){!this.foldController||this.minimized===t||(this.minimized=t,this.foldController.setFolded(t),super.setExpanded(this.expandedState))}render(t){if(!this.minimized)return[...super.render(t),...pt(this.foldController?.callComponent(),t)];const e=this.foldController?.callComponent();return e?e.render(t).filter(s=>s.replace(vt,"").trim().length>0).map(s=>Ft(s).trimEnd()):super.render(t)}}const Ht=p(h=>`\x1B[31m${h}\x1B[39m`,"defaultErrorStyle"),Wt={accent:p(h=>`\x1B[33m${h}\x1B[39m`,"accent"),active:p(h=>`\x1B[36m${h}\x1B[39m`,"active"),info:p(h=>`\x1B[34m${h}\x1B[39m`,"info"),muted:I,faint:I,border:p(h=>h,"border"),surface:p(h=>h,"surface"),bold:p(h=>`\x1B[1m${h}\x1B[22m`,"bold"),error:Ht,warning:p(h=>`\x1B[33m${h}\x1B[39m`,"warning"),diffAdded:p(h=>`\x1B[32m${h}\x1B[39m`,"diffAdded"),diffRemoved:p(h=>`\x1B[91m${h}\x1B[39m`,"diffRemoved"),bashMode:p(h=>`\x1B[32m${h}\x1B[39m`,"bashMode"),bashModeAlt:p(h=>`\x1B[92m${h}\x1B[39m`,"bashModeAlt")};class ue{static{p(this,"ChatView")}tui;container;historyContainer=new B;statusContainer=new B;bannerContainer;transcript;appendTarget=this.historyContainer;pageBlocks=new Map;inlinePageBlocks;pageOpenHint;backgroundBashHint;liveCycles;condensedHistory;cwd;showImages;imageWidthCells;hideThinking;hiddenThinkingLabel;toolOutputExpanded;foldSettledTools=Ot();summarizeToolCalls=It();detailedToolRecaps=_t();showGroupSummaries=this.summarizeToolCalls&&this.foldSettledTools;groups=[];openGroup;groupSummaries=new Map;nodeRoster=new Map;streamingWasGroupMember=!1;onFooterEvent;onActivityChange;spinnerStyle;dimStyle;errorStyle;recapPalette;labelStyle=p(t=>`\x1B[1m${t}\x1B[22m`,"labelStyle");markdownTransformers=[(t,{messageType:e,availableWidth:s})=>e==="assistant"?st(t,s):t,(t,{messageType:e})=>e==="user"?E(t):it(t)];streamingComponent;streamingToolSeparator;foldedToolSeparatorContents=new Map;pendingTools=new Map;bashComponent;activityLoader;projection=Rt();workingActivity=this.projection.workingActivity;runActive=!1;applyingSnapshot=!1;snapshotGeneration=0;deferredFrames=[];lastAssistantText;transcriptFilePaths=[];copyBlockRecords=[];copyIndex=new Map;condensedCopyBlocks=new WeakMap;constructor(t,e,s={}){if(this.tui=t,this.container=e,this.cwd=s.cwd??process.cwd(),this.showImages=s.showImages??!0,this.imageWidthCells=s.imageWidthCells??60,this.hideThinking=s.hideThinking??!1,this.hiddenThinkingLabel=s.hiddenThinkingLabel??"Thinking...",this.toolOutputExpanded=s.toolOutputExpanded??!1,this.liveCycles=s.liveCycles??Mt(),this.condensedHistory=s.condensedHistory??Et(),this.onFooterEvent=s.onFooterEvent,this.onActivityChange=s.onActivityChange,this.inlinePageBlocks=s.inlinePageBlocks??!1,this.pageOpenHint=s.pageOpenHint??(()=>"crtr human list"),this.backgroundBashHint=s.backgroundBashHint??(()=>null),this.recapPalette=s.palette??Wt,this.spinnerStyle=this.recapPalette.active,this.dimStyle=this.recapPalette.muted,this.errorStyle=this.recapPalette.error,s.banner&&s.banner.length>0){const i=new B;i.addChild(new d(1));for(const o of s.banner)i.addChild(new x(o,1,0));i.addChild(new d(1)),this.bannerContainer=i,this.container.addChild(i)}this.container.addChild(this.historyContainer),this.onActivityChange||this.container.addChild(this.statusContainer),this.transcript=new yt([...this.bannerContainer?[this.bannerContainer]:[],this.historyContainer,...this.onActivityChange?[]:[this.statusContainer]])}transcriptSource(){return this.transcript}async applySnapshot(t){const e=++this.snapshotGeneration;this.applyingSnapshot=!0,this.deferredFrames.length=0,this.resetChat(),this.projection=bt(t,this.projection),this.workingActivity=this.projection.workingActivity,this.runActive=this.projection.isStreaming,this.seedToolGroupSummaries(this.projection.toolGroupSummaryDetails);const s=new Map,i=this.projection.messages,o=i.length-1,n=gt(i,this.liveCycles);if(n>0){const r=await this.buildCondensedBlock(i.slice(0,n),e);if(e!==this.snapshotGeneration)return;r&&this.appendCondensedBlock(r)}for(let r=n;r<i.length;r++){if(!this.projection.isStreaming&&r>n&&(r-n)%_===0&&(await new Promise(l=>setImmediate(l)),e!==this.snapshotGeneration))return;const a=i[r];if(a.role==="assistant"){const l=c(a);l.trim()&&(this.lastAssistantText=l,this.pushTranscriptText(l));const P=r===o&&this.projection.isStreaming&&a.stopReason!=="aborted"&&a.stopReason!=="error",g=c(a).trim()!=="",D=this.assistantToolCalls(a),k=a.stopReason==="aborted"||a.stopReason==="error",y=w(a)?"Interrupted":a.errorMessage??"Error";if(k){for(const m of s.values()){const f={content:[{type:"text",text:y}],isError:!0};m.updateResult(f),this.registerCopyBlock(m,"tool",y),this.settleGroupTool(m,f,!0)}s.clear()}(g||k)&&this.closeOpenGroup();let b;P?(this.streamingComponent=new A(void 0,this.hideThinking,u(),this.hiddenThinkingLabel,this.markdownTransformers),this.appendAssistantPart(this.streamingComponent,!g),this.registerCopyBlock(this.streamingComponent,"assistant",""),this.streamingWasGroupMember=!g,this.streamingComponent.updateContent(a),this.registerCopyBlock(this.streamingComponent,"assistant",c(a)),b=this.streamingToolSeparator=this.appendAssistantSeparator(!g)):b=this.appendAssistantMessage(a,!g&&!k),b&&this.setAssistantSeparatorContent(b,a);for(const m of D){this.pushTranscriptValue(m.arguments);const f=this.appendToolComponent(m.name,m.id,m.arguments);a.stopReason==="aborted"||a.stopReason==="error"?(f.updateResult({content:[{type:"text",text:y}],isError:!0}),this.registerCopyBlock(f,"tool",y),this.settleGroupTool(f,{content:[{type:"text",text:y}],isError:!0},!0)):s.set(m.id,f)}k&&this.closeOpenGroup()}else if(a.role==="toolResult"){this.pushTranscriptText(this.userMessageText(a));const l=s.get(a.toolCallId);l&&(l.updateResult(a),this.registerCopyBlock(l,"tool",this.toolResultText(a)),this.historyContainer.markDirty(l),this.settleGroupTool(l,a,a.isError===!0),s.delete(a.toolCallId),this.maybeAppendPageBlock(a))}else this.addMessageToChat(a)}for(const[r,a]of s)this.pendingTools.set(r,a);this.applyToolDisplay(),this.projection.isStreaming&&this.setActivity(this.makeLoader(this.workingActivity)),this.tui.requestRender(),this.applyingSnapshot=!1,this.replayDeferredFrames()}async buildCondensedBlock(t,e){const s=new j,i=this.appendTarget,o=[];this.appendTarget=s,this.condensedCopyBlocks.set(s,o);try{let n=0;for(const r of t)if(ft(r,this.condensedHistory)){if(n>0&&n%_===0&&(await new Promise(a=>setImmediate(a)),e!==this.snapshotGeneration))return;n++,this.pushTranscriptText(this.userMessageText(r)),this.addMessageToChat(r)}}finally{this.appendTarget=i,this.condensedCopyBlocks.delete(s)}return s.children.length>0?{component:s,copyBlocks:o}:void 0}deferIfBuilding(t){return this.applyingSnapshot?(this.deferredFrames.push(t),!0):!1}replayDeferredFrames(){const t=this.deferredFrames.splice(0);for(const e of t)e()}setWorkingActivity(t){if(this.deferIfBuilding(()=>this.setWorkingActivity(t)))return;const e=this.projection.activity===this.workingActivity;this.projection=St(this.projection,t),this.workingActivity=this.projection.workingActivity,this.runActive&&e&&this.setActivity(this.makeLoader(this.workingActivity))}settleRun(){this.runActive=!1;for(const t of this.pendingTools.values())this.settleGroupTool(t);this.streamingComponent&&(this.historyContainer.removeChild(this.streamingComponent),this.unregisterCopyBlock(this.streamingComponent),this.streamingComponent=void 0),this.streamingToolSeparator=void 0,this.pendingTools.clear(),this.applyToolDisplay(),this.setActivity(void 0),this.settleBashComponent()}dispose(){this.settleRun()}toggleToolsExpanded(){let t;return this.summarizeToolCalls&&this.foldSettledTools?(this.showGroupSummaries=!this.showGroupSummaries,this.toolOutputExpanded=!this.showGroupSummaries,t={kind:"summaries",shown:this.showGroupSummaries}):(this.toolOutputExpanded=!this.toolOutputExpanded,t={kind:"output",expanded:this.toolOutputExpanded}),this.applyToolDisplay(),t}toggleFoldSettledTools(){return this.foldSettledTools=!this.foldSettledTools,Pt(this.foldSettledTools),this.summarizeToolCalls&&this.foldSettledTools&&(this.showGroupSummaries=!0),this.applyToolDisplay(),this.foldSettledTools}applyToolDisplay(){const t=new Set(this.pendingTools.values());for(const e of this.groups)for(const s of e.inFlight)t.add(s);for(const e of this.historyContainer.children)e instanceof G&&e.setMinimized(this.foldSettledTools&&!t.has(e)),Dt(e)&&e.setExpanded(this.toolOutputExpanded);for(const e of this.groups)this.applyGroupDisplay(e);this.updateFoldedToolSeparators(t),this.historyContainer.markDirty(),this.tui.requestRender()}toggleThinking(){this.hideThinking=!this.hideThinking;for(const t of this.historyContainer.children)t instanceof L&&t.setHideThinkingBlock(this.hideThinking);for(const[t,e]of this.foldedToolSeparatorContents)t.setSeparatesToolGroup(e.hasText||!this.hideThinking&&e.hasThinking);return this.historyContainer.markDirty(),this.tui.requestRender(),this.hideThinking}handleEvent(t){if(!this.deferIfBuilding(()=>this.handleEvent(t))){switch(this.projection=Gt(this.projection,t),t.type){case"agent_start":{this.runActive=this.projection.isStreaming;for(const e of this.pendingTools.values())this.settleGroupTool(e);this.pendingTools.clear(),this.setActivity(this.makeLoader(this.workingActivity));break}case"agent_end":{this.settleRun(),ut();break}case"agent_settled":{this.settleRun();break}case"message_start":{if(t.message.role==="custom"||t.message.role==="user")this.addMessageToChat(t.message);else if(t.message.role==="assistant"){const e=c(t.message).trim()!=="";e&&this.closeOpenGroup(),this.streamingComponent=new A(void 0,this.hideThinking,u(),this.hiddenThinkingLabel,this.markdownTransformers),this.streamingWasGroupMember=!e,this.appendAssistantPart(this.streamingComponent,!e),this.registerCopyBlock(this.streamingComponent,"assistant",""),this.streamingComponent.updateContent(t.message),this.registerCopyBlock(this.streamingComponent,"assistant",c(t.message)),this.streamingToolSeparator=this.appendAssistantSeparator(!e),this.setAssistantSeparatorContent(this.streamingToolSeparator,t.message)}break}case"message_update":{if(this.streamingComponent&&t.message.role==="assistant"){this.promoteStreamingAssistantToBoundary(t.message),this.streamingComponent.updateContent(t.message),this.registerCopyBlock(this.streamingComponent,"assistant",c(t.message)),this.historyContainer.markDirty(this.streamingComponent);const e=this.assistantToolCalls(t.message);this.streamingToolSeparator&&this.setAssistantSeparatorContent(this.streamingToolSeparator,t.message);for(const s of e){this.pushTranscriptValue(s.arguments);const i=this.pendingTools.get(s.id);if(i)i.updateArgs(s.arguments),this.noteGroupTool(i,s.name,s.arguments),this.historyContainer.markDirty(i);else{const o=this.appendToolComponent(s.name,s.id,s.arguments);this.pendingTools.set(s.id,o)}}}break}case"message_end":{if(t.message.role!=="assistant")break;const e=t.message.stopReason==="aborted"||t.message.stopReason==="error";if(this.promoteStreamingAssistantToBoundary(t.message,e),this.streamingComponent&&this.registerCopyBlock(this.streamingComponent,"assistant",c(t.message)),t.message.stopReason!=="aborted"&&t.message.stopReason!=="error"){const s=c(t.message);s.trim()&&(this.lastAssistantText=s,this.pushTranscriptText(s))}if(this.streamingComponent){const s=t.message.stopReason;let i=t.message.errorMessage;if(w(t.message)&&(i="Interrupted",t.message.errorMessage=i,t.message.stopReason="aborted"),this.streamingComponent.updateContent(t.message),s==="aborted"||s==="error"){const o=i??"Error";for(const n of this.pendingTools.values())n.updateResult({content:[{type:"text",text:o}],isError:!0}),this.registerCopyBlock(n,"tool",o),this.settleGroupTool(n,{content:[{type:"text",text:o}],isError:!0},!0),this.historyContainer.markDirty(n);this.pendingTools.clear()}else for(const o of this.pendingTools.values())o.setArgsComplete(),this.historyContainer.markDirty(o);this.historyContainer.markDirty(this.streamingComponent),this.streamingComponent=void 0,this.streamingToolSeparator=void 0}e&&(this.closeOpenGroup(),this.applyToolDisplay());break}case"tool_execution_start":{this.pushTranscriptValue(t.args);let e=this.pendingTools.get(t.toolCallId);e?this.noteGroupTool(e,t.toolName,t.args):(e=this.appendToolComponent(t.toolName,t.toolCallId,t.args),this.pendingTools.set(t.toolCallId,e)),e.markExecutionStarted(),this.historyContainer.markDirty(e);break}case"tool_execution_update":{const e=this.projection.partialToolResults.get(t.toolCallId)??t.partialResult;this.pushTranscriptValue(e);const s=this.pendingTools.get(t.toolCallId);s&&(s.updateResult(e,!0),this.registerCopyBlock(s,"tool",this.toolResultText(e)),this.historyContainer.markDirty(s));break}case"tool_execution_end":{const e=this.projection.partialToolResults.get(t.toolCallId)??t.result;this.pushTranscriptValue(e);const s=this.pendingTools.get(t.toolCallId);s&&(s.updateResult(e),this.registerCopyBlock(s,"tool",this.toolResultText(e)),this.pendingTools.delete(t.toolCallId),this.settleGroupTool(s,e,t.isError),this.applyToolDisplay(),this.historyContainer.markDirty(s),this.maybeAppendPageBlock(e));break}case"compaction_start":{const e=t.reason==="manual"?"Compacting context...":"Auto-compacting...";this.setActivity(this.makeLoader(e));break}case"compaction_end":{this.setActivity(this.runActive?this.makeLoader(this.workingActivity):void 0),t.aborted?this.showStatus(t.reason==="manual"?"Compaction cancelled":"Auto-compaction cancelled"):t.result?this.addMessageToChat({role:"compactionSummary",summary:t.result.summary,tokensBefore:t.result.tokensBefore,timestamp:Date.now()}):t.errorMessage&&this.showError(t.errorMessage);break}case"auto_retry_start":{const e=Math.ceil(t.delayMs/1e3);this.setActivity(this.makeLoader(`Retrying (${t.attempt}/${t.maxAttempts}) in ${e}s...`));break}case"auto_retry_end":{this.setActivity(this.runActive?this.makeLoader(this.workingActivity):void 0),t.success||this.showError(`Retry failed after ${t.attempt} attempts: ${t.finalError??"Unknown error"}`);break}case"queue_update":case"session_info_changed":case"thinking_level_changed":this.onFooterEvent?.(t);break;default:break}this.tui.requestRender()}}bashStart(t,e){if(this.deferIfBuilding(()=>this.bashStart(t,e)))return;this.projection=Bt(this.projection,t,e),this.closeOpenGroup(),this.settleBashComponent();let s;s=new M(t,this.componentTui(()=>s),e),this.bashComponent=s,this.append(s),this.tui.requestRender()}bashOutput(t){this.deferIfBuilding(()=>this.bashOutput(t))||(this.projection=At(this.projection,t),this.pushTranscriptText(t),this.bashComponent&&(this.bashComponent.appendOutput(t),this.historyContainer.markDirty(this.bashComponent)),this.tui.requestRender())}bashEnd(t){this.deferIfBuilding(()=>this.bashEnd(t))||(this.projection=wt(this.projection,t),this.settleBashComponent(t),this.tui.requestRender())}addMessageToChat(t){const e=tt(t);if(e!==null&&(t.role!=="custom"||t.display===!0)){this.pushTranscriptText(e.body);const s=e.senders.flatMap(o=>o.entries).filter(o=>o.disposition==="human-answer").map(o=>o.body.trim()).filter(o=>o!=="");if(!(s.length>0&&e.body.replace(Lt,"").trim()===""&&e.senders.every(o=>o.entries.every(n=>n.disposition==="human-answer")))){const o=z(e.kind),n=new U(e,o,this.toolOutputExpanded,this.dimStyle,r=>this.spinnerStyle(this.labelStyle(r)));et(e.kind)?(this.closeOpenGroup(),this.append(n)):this.appendGroupMember(n)?.activity.noteCard(e,o)}for(const o of s)this.appendHumanAnswer(o);return}switch(t.role){case"bashExecution":{this.closeOpenGroup(),this.pushTranscriptText(t.output??"");const s=new M(t.command,this.tui,t.excludeFromContext);t.output&&s.appendOutput(t.output),s.setComplete(t.exitCode,t.cancelled,t.truncated?{truncated:!0}:void 0,t.fullOutputPath),this.append(s);break}case"custom":{if(t.display){if(this.pushTranscriptText(this.userMessageText(t)),t.customType===K){this.appendGroupMember(new X(this.userMessageText(t),this.toolOutputExpanded,this.crtrOutputTheme()));break}if(t.customType===Z){this.closeOpenGroup(),this.append(new d(1)),this.append(new x(this.dimStyle(`\u2500\u2500 ${this.userMessageText(t)} \u2500\u2500`),1,0)),this.append(new d(1));break}const s=new $(ot(t),void 0,u());s.setExpanded(this.toolOutputExpanded),this.appendGroupMember(s)}break}case"compactionSummary":{this.closeOpenGroup(),this.append(new d(1));const s=new W(O(t),u());s.setExpanded(this.toolOutputExpanded),this.append(s);break}case"branchSummary":{this.closeOpenGroup(),this.append(new d(1));const s=new H(O(t),u());s.setExpanded(this.toolOutputExpanded),this.append(s),this.registerCopyBlock(s,"assistant",t.summary);break}case"user":{C(t)&&this.closeOpenGroup();const s=this.userMessageText(t);if(!s)break;this.pushTranscriptText(s),this.chatChildCount()>0&&this.appendUserPart(new d(1),!C(t));const i=q(s);if(i){const o=new V({...i,content:E(i.content)},u());if(o.setExpanded(this.toolOutputExpanded),this.appendUserPart(o,!C(t)),this.registerCopyBlock(o,"user",s),i.userMessage){const n=new S(i.userMessage,u(),void 0,this.markdownTransformers);this.appendUserPart(n,!C(t)),this.registerCopyBlock(n,"user",i.userMessage)}}else{const o=new S(s,u(),void 0,this.markdownTransformers);this.appendUserPart(o,!C(t)),this.registerCopyBlock(o,"user",s)}break}case"assistant":{const s=c(t).trim()!=="";s&&this.closeOpenGroup(),this.appendAssistantMessage(t,!s);break}default:break}}appendAssistantMessage(t,e=!1){const s=new A(void 0,this.hideThinking,u(),this.hiddenThinkingLabel,this.markdownTransformers),i=w(t)?{...t,stopReason:"aborted",errorMessage:"Interrupted"}:t;s.updateContent(i),this.appendAssistantPart(s,e),this.registerCopyBlock(s,"assistant",c(t));const o=this.appendAssistantSeparator(e);return this.setAssistantSeparatorContent(o,t),o}appendAssistantSeparator(t=!1){const e=new R;return t?this.appendGroupMember(e):this.append(e),e}appendAssistantPart(t,e){e?this.appendGroupMember(t):this.append(t)}appendUserPart(t,e){e?this.appendGroupMember(t):this.append(t)}appendHumanAnswer(t){this.closeOpenGroup(),this.chatChildCount()>0&&this.append(new d(1));const e=new S(t,u(),void 0,this.markdownTransformers);this.append(e),this.registerCopyBlock(e,"user",t)}isLiveGroupRegion(){return this.appendTarget===this.historyContainer}ensureGroup(){if(!this.isLiveGroupRegion())return;if(this.openGroup)return this.openGroup;const t=new at,e={members:[],recap:t,activity:new rt(this.cwd,this.nodeRoster),toolCount:0,inFlight:new Set};return this.append(t),this.historyContainer.setHidden(t,!0),this.groups.push(e),this.openGroup=e,e}closeOpenGroup(){this.openGroup=void 0}appendGroupMember(t){const e=this.ensureGroup();return this.append(t),e&&e.members.push(t),e}removeGroupMember(t){for(const e of this.groups){const s=e.members.indexOf(t);s!==-1&&e.members.splice(s,1)}this.historyContainer.setHidden(t,!1)}appendToolComponent(t,e,s){const i=this.isLiveGroupRegion()&&!this.openGroup&&this.historyContainer.children.at(-1)instanceof R?this.historyContainer.children.at(-1):void 0;i&&this.historyContainer.removeChild(i);const o=this.ensureGroup();i&&(this.append(i),o?.members.push(i));const n=this.makeToolComponent(t,e,s);return n.activityCallId=e,this.appendGroupMember(n),this.registerCopyBlock(n,"tool",""),o&&(o.key??=e,o.toolCount++,o.inFlight.add(n),o.activity.noteCall(e,t,s)),n}noteGroupTool(t,e,s){if(t.activityCallId)for(const i of this.groups)i.members.includes(t)&&i.activity.noteCall(t.activityCallId,e,s)}settleGroupTool(t,e,s=!1){for(const i of this.groups)i.inFlight.delete(t),!(!t.activityCallId||!i.members.includes(t))&&(e===void 0?i.activity.resolveWithoutResult(t.activityCallId):i.activity.settle(t.activityCallId,e,s))}promoteStreamingAssistantToBoundary(t,e=!1){!this.streamingWasGroupMember||!e&&c(t).trim()===""||(this.streamingComponent&&this.removeGroupMember(this.streamingComponent),this.streamingToolSeparator&&this.removeGroupMember(this.streamingToolSeparator),this.streamingWasGroupMember=!1,this.closeOpenGroup())}seedToolGroupSummaries(t){this.groupSummaries.clear();for(const[e,s]of Object.entries(t))this.groupSummaries.set(e,s)}applyToolGroupSummary(t,e){if(this.deferIfBuilding(()=>this.applyToolGroupSummary(t,e)))return;this.projection=xt(this.projection,t,e);const s=this.projection.toolGroupSummaryDetails[t];s!==void 0&&(this.groupSummaries.set(t,s),this.applyToolDisplay())}applyGroupDisplay(t){const e=t.key===void 0?void 0:this.groupSummaries.get(t.key),s=this.foldSettledTools&&this.showGroupSummaries&&t.toolCount>0&&t.inFlight.size===0&&e!==void 0;t.recap.setRecap(s?e:void 0,t.toolCount,t.activity.activity(),this.detailedToolRecaps,this.recapPalette),this.historyContainer.setHidden(t.recap,!s);for(const i of t.members)this.historyContainer.setHidden(i,s)}updateFoldedToolSeparators(t=new Set(this.pendingTools.values())){const e=this.historyContainer.children;for(let s=0;s<e.length;s++){const i=e[s];if(!(i instanceof R))continue;const o=e[s+1];i.setFolded(this.foldSettledTools&&!this.historyContainer.hiddenChildren.has(i)&&o instanceof G&&!this.historyContainer.hiddenChildren.has(o)&&!t.has(o)),this.historyContainer.markDirty(i)}}setAssistantSeparatorContent(t,e){const s=e.content,i=Array.isArray(s)?s:[],o=i.some(r=>typeof r=="object"&&r!==null&&r.type==="text"&&typeof r.text=="string"&&r.text.trim()!==""),n=i.some(r=>typeof r=="object"&&r!==null&&r.type==="thinking"&&typeof r.thinking=="string"&&r.thinking.trim()!=="");this.foldedToolSeparatorContents.set(t,{hasText:o,hasThinking:n}),t.setSeparatesToolGroup(o||!this.hideThinking&&n)}makeToolComponent(t,e,s){const i=new ht;let o,n;if(t==="bash"){const a=Q(s,i);a===void 0?n=lt(this.cwd,i,this.backgroundBashHint):(n=a.definition,o=a.observeResult)}else if(t==="edit"){const a=nt(this.cwd,i);n=a.definition,o=a.observeResult}else t==="read"?n=dt(this.cwd,i):t==="write"&&(n=ct(this.cwd,i));let r;return r=new G(t,e,s,{showImages:this.showImages,imageWidthCells:this.imageWidthCells},n,this.componentTui(()=>r),this.cwd),r.setToolView(n===void 0?void 0:i,o),r.setExpanded(this.toolOutputExpanded),r}append(t){this.appendTarget.addChild(t)}chatChildCount(){return this.appendTarget.children.length}resetChat(){this.setActivity(void 0),this.settleBashComponent(),this.streamingComponent=void 0,this.streamingToolSeparator=void 0,this.streamingWasGroupMember=!1,this.foldedToolSeparatorContents.clear(),this.groups.length=0,this.openGroup=void 0,this.groupSummaries.clear(),this.nodeRoster.clear(),this.pendingTools.clear(),this.lastAssistantText=void 0,this.copyBlockRecords.length=0,this.copyIndex.clear(),this.transcriptFilePaths.length=0,this.pageBlocks.clear(),this.historyContainer.clear()}maybeAppendPageBlock(t){if(!this.inlinePageBlocks||this.appendTarget!==this.historyContainer)return;const e=Y(t);if(e===void 0||this.pageBlocks.has(e.pageId))return;const s=new J(e.pageId,this.pageOpenHint);this.pageBlocks.set(e.pageId,s),this.append(s),this.loadPageBlock(s)}async loadPageBlock(t){await t.refresh()&&(this.historyContainer.markDirty(t),this.tui.requestRender())}refreshInFlightTools(){if(this.pendingTools.size!==0){for(const t of this.pendingTools.values())this.historyContainer.markDirty(t);this.tui.requestRender()}}async refreshPageBlocks(){const t=[...this.pageBlocks.values()];(await Promise.all(t.map(async s=>{const i=await s.refresh();return i&&this.historyContainer.markDirty(s),i}))).some(Boolean)&&this.tui.requestRender()}makeLoader(t){let e;const s={requestRender:p(i=>{e&&!this.onActivityChange&&this.statusContainer.markDirty(e),this.tui.requestRender(i)},"requestRender"),terminal:this.tui.terminal};return e=new F(s,this.spinnerStyle,this.dimStyle,t),e}componentTui(t){return{requestRender:p(e=>{this.historyContainer.markDirty(t()),this.tui.requestRender(e)},"requestRender"),terminal:this.tui.terminal}}settleBashComponent(t){if(!this.bashComponent)return;const e=this.bashComponent;e.setComplete(t?.exitCode,t?.cancelled??!0,t?.truncated?{truncated:!0}:void 0,t?.fullOutputPath),this.historyContainer.markDirty(e),this.bashComponent=void 0}setActivity(t){if(this.activityLoader?.stop(),this.activityLoader=t,this.onActivityChange){this.onActivityChange(t);return}this.statusContainer.clear(),t&&this.statusContainer.addChild(t)}showStatus(t){this.closeOpenGroup(),this.append(new d(1)),this.append(new x(this.dimStyle(t),1,0))}showError(t){this.closeOpenGroup(),this.append(new d(1)),this.append(new x(this.errorStyle(t),1,0))}crtrOutputTheme(){return{fg:p((t,e)=>t==="error"?this.errorStyle(e):t==="warning"||t==="accent"||t==="toolTitle"||t==="success"?this.spinnerStyle(e):t==="muted"?this.dimStyle(e):e,"fg"),bg:p((t,e)=>e,"bg"),bold:p(t=>this.labelStyle(t),"bold")}}assistantToolCalls(t){const e=t.content;return Array.isArray(e)?e.filter(s=>typeof s=="object"&&s!==null&&s.type==="toolCall"):[]}getTranscriptFilePathsNewestFirst(){return[...this.transcriptFilePaths]}getLastAssistantText(){const t=this.lastAssistantText?.trim();return t||void 0}blockText(t){const e=this.copyIndex.get(t);return e===void 0?void 0:this.copyBlockRecords[e]?.text}copyBlocks(){return this.copyBlockRecords}getLastToolOutputText(){for(let t=this.copyBlockRecords.length-1;t>=0;t--){const e=this.copyBlockRecords[t];if(e.kind==="tool")return e.text.trim()===""?void 0:e.text}}getTranscriptPlainText(){return this.copyBlockRecords.map(t=>t.text).filter(t=>t.trim()!=="").join(`
2
+
3
+ `)}registerCopyBlock(t,e,s){const i=this.condensedCopyBlocks.get(this.appendTarget);if(i){const n=i.findIndex(r=>r.block===t);n===-1?i.push({block:t,kind:e,text:s}):i[n].text=s;return}const o=this.copyIndex.get(t);o===void 0?(this.copyIndex.set(t,this.copyBlockRecords.length),this.copyBlockRecords.push({block:t,kind:e,text:s})):this.copyBlockRecords[o].text=s}unregisterCopyBlock(t){const e=this.condensedCopyBlocks.get(this.appendTarget);if(e){const i=e.findIndex(o=>o.block===t);i!==-1&&e.splice(i,1);return}const s=this.copyIndex.get(t);if(s!==void 0){this.copyBlockRecords.splice(s,1),this.copyIndex.delete(t);for(let i=s;i<this.copyBlockRecords.length;i++)this.copyIndex.set(this.copyBlockRecords[i].block,i)}}appendCondensedBlock({component:t,copyBlocks:e}){this.append(t),this.registerCopyBlock(t,"condensed",e.map(s=>s.text).filter(s=>s.trim()!=="").join(`
4
+
5
+ `))}toolResultText(t){if(typeof t=="string")return t;if(typeof t=="object"&&t!==null&&"content"in t){const e=t.content;if(typeof e=="string")return e;if(Array.isArray(e))return e.filter(s=>typeof s=="object"&&s!==null&&s.type==="text"&&typeof s.text=="string").map(s=>s.text).join("")}try{const e=JSON.stringify(t);return typeof e=="string"?e:""}catch{return""}}pushTranscriptText(t){const e=t.trim();if(e==="")return;const s=mt([e],this.cwd);if(s.length===0)return;const i=[...s,...this.transcriptFilePaths.filter(o=>!s.includes(o))].slice(0,50);this.transcriptFilePaths.splice(0,this.transcriptFilePaths.length,...i)}pushTranscriptValue(t){try{const e=typeof t=="string"?t:JSON.stringify(t);typeof e=="string"&&this.pushTranscriptText(e)}catch{}}userMessageText(t){const e=t.content;return typeof e=="string"?e:Array.isArray(e)?e.filter(s=>typeof s=="object"&&s!==null&&s.type==="text").map(s=>s.text).join(""):""}}export{ue as ChatView};