@north-light/crouter 0.3.317 → 0.3.319

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 (1305) hide show
  1. package/README.md +0 -3
  2. package/dist/api/client.d.ts +1 -1
  3. package/dist/api/client.js +2 -912
  4. package/dist/api/dto/attach.js +0 -13
  5. package/dist/api/dto/bash-jobs.js +1 -9
  6. package/dist/api/dto/broker-ops.js +0 -6
  7. package/dist/api/dto/broker.js +0 -20
  8. package/dist/api/dto/canvas.js +0 -2
  9. package/dist/api/dto/chat-inventory.js +0 -11
  10. package/dist/api/dto/common.js +1 -15
  11. package/dist/api/dto/config.js +0 -3
  12. package/dist/api/dto/crons.js +1 -10
  13. package/dist/api/dto/files.js +0 -7
  14. package/dist/api/dto/focus.js +0 -10
  15. package/dist/api/dto/health.js +0 -2
  16. package/dist/api/dto/human-requests.js +0 -4
  17. package/dist/api/dto/human.js +0 -4
  18. package/dist/api/dto/inbox.js +0 -4
  19. package/dist/api/dto/lifecycle.js +0 -3
  20. package/dist/api/dto/mail.js +0 -1
  21. package/dist/api/dto/memory.js +0 -6
  22. package/dist/api/dto/messages.js +0 -2
  23. package/dist/api/dto/model-config.js +0 -1
  24. package/dist/api/dto/modelauth.js +0 -4
  25. package/dist/api/dto/node-outcomes.js +0 -2
  26. package/dist/api/dto/nodes.js +0 -3
  27. package/dist/api/dto/profiles.js +1 -4
  28. package/dist/api/dto/recovery.js +0 -1
  29. package/dist/api/dto/reports.js +0 -2
  30. package/dist/api/dto/review-comments.js +0 -5
  31. package/dist/api/dto/reviews.js +0 -5
  32. package/dist/api/dto/subscriptions.js +0 -2
  33. package/dist/api/dto/worktree.js +0 -6
  34. package/dist/api/errors.js +1 -40
  35. package/dist/api/index.js +1 -33
  36. package/dist/api/plugin-manifest-schema.js +0 -23
  37. package/dist/api/routes.js +1 -147
  38. package/dist/build-root.js +1 -198
  39. package/dist/cli.js +3 -99
  40. package/dist/clients/attach/ansi-cells.js +1 -137
  41. package/dist/clients/attach/chrome/bash-jobs.js +1 -31
  42. package/dist/clients/attach/chrome/canvas-panels.js +1 -194
  43. package/dist/clients/attach/chrome/completion-bell.js +1 -89
  44. package/dist/clients/attach/chrome/cron-wait.js +1 -34
  45. package/dist/clients/attach/chrome/git-info.js +2 -44
  46. package/dist/clients/attach/chrome/header.js +1 -30
  47. package/dist/clients/attach/chrome/inbox-strip.js +1 -199
  48. package/dist/clients/attach/chrome/recap.js +1 -19
  49. package/dist/clients/attach/chrome/review-wait.js +1 -22
  50. package/dist/clients/attach/chrome/roster.js +4 -275
  51. package/dist/clients/attach/chrome/status-line.js +1 -117
  52. package/dist/clients/attach/chrome/ticket-panel.js +1 -280
  53. package/dist/clients/attach/chrome/widgets.js +1 -51
  54. package/dist/clients/attach/command.js +1 -107
  55. package/dist/clients/attach/config.js +1 -274
  56. package/dist/clients/attach/input/capabilities.js +1 -104
  57. package/dist/clients/attach/input/clipboard-image.js +3 -220
  58. package/dist/clients/attach/input/completion-frecency.js +1 -141
  59. package/dist/clients/attach/input/controller.js +7 -377
  60. package/dist/clients/attach/input/overlay-owner.js +1 -199
  61. package/dist/clients/attach/input/ref-autocomplete.js +2 -176
  62. package/dist/clients/attach/input/titled-editor.js +4 -859
  63. package/dist/clients/attach/overlays/auth.js +2 -271
  64. package/dist/clients/attach/overlays/dialogs.js +2 -102
  65. package/dist/clients/attach/overlays/file-review.js +2 -128
  66. package/dist/clients/attach/overlays/graph.js +1 -661
  67. package/dist/clients/attach/overlays/help.js +1 -211
  68. package/dist/clients/attach/overlays/mcp.js +1 -302
  69. package/dist/clients/attach/overlays/pickers.js +1 -163
  70. package/dist/clients/attach/render/activity-slot.js +1 -13
  71. package/dist/clients/attach/render/assistant-message.js +1 -56
  72. package/dist/clients/attach/render/card-presentation.js +5 -218
  73. package/dist/clients/attach/render/chat-view.js +5 -1708
  74. package/dist/clients/attach/render/condensed-history.js +1 -60
  75. package/dist/clients/attach/render/context-message.js +1 -63
  76. package/dist/clients/attach/render/crtr-output.js +17 -905
  77. package/dist/clients/attach/render/diagram.js +7 -111
  78. package/dist/clients/attach/render/edit-diff.js +5 -304
  79. package/dist/clients/attach/render/glyph-codepoints.js +1 -42
  80. package/dist/clients/attach/render/group-activity.js +2 -263
  81. package/dist/clients/attach/render/group-recap.js +1 -152
  82. package/dist/clients/attach/render/markdown-source.js +5 -266
  83. package/dist/clients/attach/render/measured-container.js +1 -322
  84. package/dist/clients/attach/render/page-block.js +1 -183
  85. package/dist/clients/attach/render/scroll-animation.js +1 -80
  86. package/dist/clients/attach/render/tool-calls.js +3 -361
  87. package/dist/clients/attach/render/transcript-copy.js +2 -81
  88. package/dist/clients/attach/render/transcript-search.js +1 -152
  89. package/dist/clients/attach/render/viewport.js +1 -184
  90. package/dist/clients/attach/session/banner.js +1 -29
  91. package/dist/clients/attach/session/bindings.js +1 -71
  92. package/dist/clients/attach/session/chrome-refresh.js +1 -94
  93. package/dist/clients/attach/session/connection.js +1 -186
  94. package/dist/clients/attach/session/context.js +0 -16
  95. package/dist/clients/attach/session/editor-frame.js +1 -142
  96. package/dist/clients/attach/session/editor-inventory.js +6 -160
  97. package/dist/clients/attach/session/file-links.js +1 -68
  98. package/dist/clients/attach/session/focus-events.js +1 -12
  99. package/dist/clients/attach/session/frame.js +1 -214
  100. package/dist/clients/attach/session/frames.js +1 -188
  101. package/dist/clients/attach/session/identity.js +1 -26
  102. package/dist/clients/attach/session/input-wiring.js +1 -140
  103. package/dist/clients/attach/session/invariant.js +1 -15
  104. package/dist/clients/attach/session/keys.js +1 -77
  105. package/dist/clients/attach/session/layout.js +1 -59
  106. package/dist/clients/attach/session/mouse.js +1 -78
  107. package/dist/clients/attach/session/pane-focus.js +1 -42
  108. package/dist/clients/attach/session/pane-tag.js +1 -112
  109. package/dist/clients/attach/session/pi-assets.js +1 -24
  110. package/dist/clients/attach/session/pi-oauth-flows.js +1 -21
  111. package/dist/clients/attach/session/profile-files.js +1 -228
  112. package/dist/clients/attach/session/reconnect.js +1 -175
  113. package/dist/clients/attach/session/selection.js +3 -108
  114. package/dist/clients/attach/session/state-sync.js +1 -67
  115. package/dist/clients/attach/session/surface-frame.js +1 -73
  116. package/dist/clients/attach/session/surface-host.js +1 -255
  117. package/dist/clients/attach/session/teardown.js +5 -94
  118. package/dist/clients/attach/session/transcript-search.js +3 -151
  119. package/dist/clients/attach/session/whip-achievements.js +2 -145
  120. package/dist/clients/attach/session/whip.js +1 -362
  121. package/dist/clients/attach/slash/dispatch.js +1 -706
  122. package/dist/clients/attach/slash/prompt-preview.js +1 -121
  123. package/dist/clients/attach/viewer.js +1 -1
  124. package/dist/clients/conversation/projection.js +1 -324
  125. package/dist/clients/conversation/submit.js +1 -51
  126. package/dist/clients/inbox/controller.js +1 -701
  127. package/dist/clients/inbox/dto-adapt.js +1 -93
  128. package/dist/clients/inbox/layout.js +1 -9
  129. package/dist/clients/inbox/page-adapter.js +1 -55
  130. package/dist/clients/inbox/resolve.js +1 -35
  131. package/dist/clients/inbox/review/anchors.js +1 -89
  132. package/dist/clients/inbox/review/comments-client.js +1 -98
  133. package/dist/clients/inbox/review/companion-pane.js +1 -82
  134. package/dist/clients/inbox/review/document-surface.js +2 -1188
  135. package/dist/clients/inbox/review/frame.js +1 -216
  136. package/dist/clients/inbox/review/keys.js +1 -123
  137. package/dist/clients/inbox/review/launch.js +1 -151
  138. package/dist/clients/inbox/review/live-source.js +1 -160
  139. package/dist/clients/inbox/review/nvim.js +1 -44
  140. package/dist/clients/inbox/review/remap.js +1 -157
  141. package/dist/clients/inbox/review/review-client.js +1 -123
  142. package/dist/clients/inbox/review/roundtrip.js +3 -36
  143. package/dist/clients/inbox/review/state.js +4 -315
  144. package/dist/clients/inbox/review-adapter.js +1 -43
  145. package/dist/clients/inbox/surface.js +1 -152
  146. package/dist/clients/inbox/tui/ansi.js +3 -321
  147. package/dist/clients/inbox/tui/input.js +5 -392
  148. package/dist/clients/inbox/tui/keys.js +1 -104
  149. package/dist/clients/inbox/tui/page-body.js +1 -66
  150. package/dist/clients/inbox/tui/panel.js +1 -84
  151. package/dist/clients/inbox/tui/render.js +2 -368
  152. package/dist/clients/inbox/tui/slots.js +3 -134
  153. package/dist/clients/inbox/tui/types.js +0 -1
  154. package/dist/clients/inbox/tui.js +1 -86
  155. package/dist/clients/surfaces/host.js +0 -1
  156. package/dist/commands/api-client.js +4 -290
  157. package/dist/commands/attention.js +1 -215
  158. package/dist/commands/canvas-browse.js +1 -70
  159. package/dist/commands/canvas-config.js +2 -192
  160. package/dist/commands/canvas-history/grep.js +7 -85
  161. package/dist/commands/canvas-history/read.js +3 -50
  162. package/dist/commands/canvas-history/search.js +10 -99
  163. package/dist/commands/canvas-history/shared.js +1 -139
  164. package/dist/commands/canvas-history/stats.js +6 -68
  165. package/dist/commands/canvas-history.js +1 -32
  166. package/dist/commands/canvas-issue.js +14 -149
  167. package/dist/commands/canvas-prune.js +1 -108
  168. package/dist/commands/canvas-roster.js +1 -69
  169. package/dist/commands/canvas-snapshot.js +1 -34
  170. package/dist/commands/canvas-use.js +1 -61
  171. package/dist/commands/canvas.js +1 -49
  172. package/dist/commands/chord.js +1 -241
  173. package/dist/commands/cron.js +11 -534
  174. package/dist/commands/dashboard.js +1 -85
  175. package/dist/commands/human/components.js +3 -77
  176. package/dist/commands/human/feedback.js +1 -112
  177. package/dist/commands/human/prompts.js +1 -331
  178. package/dist/commands/human/queue.js +1 -191
  179. package/dist/commands/human/request.js +1 -266
  180. package/dist/commands/human/review.js +1 -288
  181. package/dist/commands/human/shared.js +1 -67
  182. package/dist/commands/human.js +4 -60
  183. package/dist/commands/memory/delete.js +1 -100
  184. package/dist/commands/memory/edit.js +21 -219
  185. package/dist/commands/memory/find.js +2 -244
  186. package/dist/commands/memory/history.js +5 -199
  187. package/dist/commands/memory/lint.js +1 -107
  188. package/dist/commands/memory/list.js +1 -142
  189. package/dist/commands/memory/move.js +1 -223
  190. package/dist/commands/memory/origin.js +1 -130
  191. package/dist/commands/memory/read.js +6 -232
  192. package/dist/commands/memory/shared.js +12 -802
  193. package/dist/commands/memory/write.js +13 -235
  194. package/dist/commands/memory.js +1 -30
  195. package/dist/commands/node/bash.js +5 -245
  196. package/dist/commands/node/create.js +3 -332
  197. package/dist/commands/node/inspect.js +12 -300
  198. package/dist/commands/node/lifecycle.js +2 -453
  199. package/dist/commands/node/message.js +1 -161
  200. package/dist/commands/node/outcome.js +4 -134
  201. package/dist/commands/node/pyramid.js +2 -79
  202. package/dist/commands/node/subscription.js +1 -78
  203. package/dist/commands/node/wait.js +7 -163
  204. package/dist/commands/node-context.js +2 -159
  205. package/dist/commands/node-inspect-artifacts.js +8 -109
  206. package/dist/commands/node-lifecycle-revive.js +1 -217
  207. package/dist/commands/node-snapshot.js +1 -37
  208. package/dist/commands/node-transcript.js +1 -62
  209. package/dist/commands/node-worktree.js +1 -138
  210. package/dist/commands/node.js +1 -29
  211. package/dist/commands/pkg/browse/actions.js +1 -198
  212. package/dist/commands/pkg/browse/catalog.js +1 -466
  213. package/dist/commands/pkg/browse/command-view.js +1 -191
  214. package/dist/commands/pkg/browse/detail-panel.js +1 -402
  215. package/dist/commands/pkg/browse/doc-view.js +1 -89
  216. package/dist/commands/pkg/browse/list-panel.js +2 -168
  217. package/dist/commands/pkg/browse/model.js +1 -36
  218. package/dist/commands/pkg/browse/shell.js +1 -640
  219. package/dist/commands/pkg/browse.js +1 -27
  220. package/dist/commands/pkg/market-inspect.js +1 -141
  221. package/dist/commands/pkg/market-manage.js +1 -327
  222. package/dist/commands/pkg/market.js +1 -14
  223. package/dist/commands/pkg/plugin-inspect.js +1 -168
  224. package/dist/commands/pkg/plugin-manage.js +17 -1109
  225. package/dist/commands/pkg/plugin.js +1 -14
  226. package/dist/commands/pkg/shared.js +1 -62
  227. package/dist/commands/pkg.js +1 -21
  228. package/dist/commands/profile/default.js +1 -139
  229. package/dist/commands/profile/delete.js +1 -66
  230. package/dist/commands/profile/env.js +3 -188
  231. package/dist/commands/profile/kind.js +2 -35
  232. package/dist/commands/profile/list.js +1 -43
  233. package/dist/commands/profile/meta.js +1 -67
  234. package/dist/commands/profile/new.js +1 -115
  235. package/dist/commands/profile/pause.js +1 -59
  236. package/dist/commands/profile/project.js +1 -113
  237. package/dist/commands/profile/rename.js +1 -38
  238. package/dist/commands/profile/show.js +1 -52
  239. package/dist/commands/profile.js +1 -35
  240. package/dist/commands/push.js +9 -265
  241. package/dist/commands/revive.js +10 -181
  242. package/dist/commands/surface/node/cycle.js +1 -83
  243. package/dist/commands/surface/node/focus.js +1 -81
  244. package/dist/commands/surface/node/id.js +1 -38
  245. package/dist/commands/surface/node/pin.js +1 -42
  246. package/dist/commands/surface/node/placement.js +1 -134
  247. package/dist/commands/surface-edit.js +1 -157
  248. package/dist/commands/surface-inbox.js +1 -98
  249. package/dist/commands/surface-inspect.js +1 -39
  250. package/dist/commands/surface-node.js +1 -19
  251. package/dist/commands/surface-reload.js +2 -134
  252. package/dist/commands/surface-tmux-spread.js +1 -214
  253. package/dist/commands/surface.js +1 -28
  254. package/dist/commands/sys/branch.js +1 -19
  255. package/dist/commands/sys/config.js +1 -353
  256. package/dist/commands/sys/context/admin/actions.js +2 -246
  257. package/dist/commands/sys/context/admin/detail-panel.js +1 -247
  258. package/dist/commands/sys/context/admin/docs-panel.js +1 -191
  259. package/dist/commands/sys/context/admin/list-view.js +1 -183
  260. package/dist/commands/sys/context/admin/model.js +1 -229
  261. package/dist/commands/sys/context/admin/rail-panel.js +1 -227
  262. package/dist/commands/sys/context/admin/read-view.js +2 -194
  263. package/dist/commands/sys/context/admin/shell.js +1 -910
  264. package/dist/commands/sys/context/admin.js +2 -126
  265. package/dist/commands/sys/context/doc.js +3 -197
  266. package/dist/commands/sys/context/prompt-review.js +11 -291
  267. package/dist/commands/sys/context/resolve.js +10 -489
  268. package/dist/commands/sys/context/sysprompt.js +5 -96
  269. package/dist/commands/sys/context.js +1 -20
  270. package/dist/commands/sys/daemon.js +1 -313
  271. package/dist/commands/sys/doctor.js +1 -617
  272. package/dist/commands/sys/feedback.js +7 -228
  273. package/dist/commands/sys/logs.js +3 -129
  274. package/dist/commands/sys/migrate.js +1 -94
  275. package/dist/commands/sys/panels/broker-limits-panel.js +2 -110
  276. package/dist/commands/sys/panels/dependencies-panel.js +1 -80
  277. package/dist/commands/sys/panels/keybindings-panel.js +1 -703
  278. package/dist/commands/sys/panels/models-panel.js +1 -1133
  279. package/dist/commands/sys/panels/plugins-panel.js +1 -80
  280. package/dist/commands/sys/panels/prefs-panel.js +1 -85
  281. package/dist/commands/sys/panels/profiles-panel.js +1 -601
  282. package/dist/commands/sys/panels/provider-panel.js +1 -538
  283. package/dist/commands/sys/settings-shell.js +1 -400
  284. package/dist/commands/sys/settings.js +1 -46
  285. package/dist/commands/sys/setup-core.js +6 -579
  286. package/dist/commands/sys/setup-settings-runner.js +1 -16
  287. package/dist/commands/sys/setup-wizard.js +1 -279
  288. package/dist/commands/sys/setup.js +1 -34
  289. package/dist/commands/sys/shared.js +1 -81
  290. package/dist/commands/sys/support/prepare.js +3 -239
  291. package/dist/commands/sys/support/submit.js +6 -524
  292. package/dist/commands/sys/support.js +1 -18
  293. package/dist/commands/sys/sync-deps.js +15 -498
  294. package/dist/commands/sys/sync-project-guidance.js +4 -481
  295. package/dist/commands/sys/sync-shared.js +1 -49
  296. package/dist/commands/sys/sync-skills.js +2 -311
  297. package/dist/commands/sys/sync.js +1 -18
  298. package/dist/commands/sys/update.js +1 -147
  299. package/dist/commands/sys/worktrees.js +5 -53
  300. package/dist/commands/sys.js +1 -18
  301. package/dist/core/activity-signal.js +2 -38
  302. package/dist/core/asset-root.js +1 -18
  303. package/dist/core/auth-file.js +2 -179
  304. package/dist/core/auth-interaction.js +3 -94
  305. package/dist/core/auto-update.js +4 -94
  306. package/dist/core/bash-guard.js +11 -393
  307. package/dist/core/bash-jobs.js +7 -411
  308. package/dist/core/bootstrap.js +2 -53
  309. package/dist/core/broker-client/client.js +1 -184
  310. package/dist/core/broker-client/index.js +1 -13
  311. package/dist/core/broker-client/transport-relay.js +1 -157
  312. package/dist/core/broker-client/transport-socket.js +1 -179
  313. package/dist/core/broker-client/transport.js +1 -26
  314. package/dist/core/canvas/attention.js +1 -47
  315. package/dist/core/canvas/boot-id.js +1 -26
  316. package/dist/core/canvas/boot.js +1 -186
  317. package/dist/core/canvas/browse/app.js +3 -919
  318. package/dist/core/canvas/browse/model.js +1 -477
  319. package/dist/core/canvas/browse/pins.js +1 -29
  320. package/dist/core/canvas/browse/render.js +3 -1055
  321. package/dist/core/canvas/canvas.js +15 -922
  322. package/dist/core/canvas/crons.js +11 -481
  323. package/dist/core/canvas/daemon-owner.js +2 -146
  324. package/dist/core/canvas/db.js +2 -100
  325. package/dist/core/canvas/deliveries.js +22 -283
  326. package/dist/core/canvas/delivery-contract.js +1 -8
  327. package/dist/core/canvas/executions.js +1 -68
  328. package/dist/core/canvas/extensions.js +1 -83
  329. package/dist/core/canvas/focuses.js +1 -77
  330. package/dist/core/canvas/history.js +24 -860
  331. package/dist/core/canvas/index.js +1 -15
  332. package/dist/core/canvas/install-id.js +1 -84
  333. package/dist/core/canvas/labels.js +1 -43
  334. package/dist/core/canvas/meta-file.js +1 -89
  335. package/dist/core/canvas/migrations.js +41 -1150
  336. package/dist/core/canvas/nav-model.js +1 -231
  337. package/dist/core/canvas/nav-render.js +1 -260
  338. package/dist/core/canvas/node-order.js +1 -37
  339. package/dist/core/canvas/node-recap.js +2 -67
  340. package/dist/core/canvas/node-sql-migration.js +2 -209
  341. package/dist/core/canvas/paths.js +1 -153
  342. package/dist/core/canvas/pid.js +4 -683
  343. package/dist/core/canvas/recovery.js +3 -565
  344. package/dist/core/canvas/remote-canvas-source.js +1 -288
  345. package/dist/core/canvas/remote-transport.js +1 -57
  346. package/dist/core/canvas/render-source.js +10 -635
  347. package/dist/core/canvas/sessions.js +1 -78
  348. package/dist/core/canvas/source.js +1 -47
  349. package/dist/core/canvas/status-glyph.js +1 -132
  350. package/dist/core/canvas/telemetry.js +1 -35
  351. package/dist/core/canvas/types.js +1 -6
  352. package/dist/core/canvas/waits.js +4 -68
  353. package/dist/core/canvas/worktrees.js +1 -93
  354. package/dist/core/clipboard-text.js +1 -57
  355. package/dist/core/command-hooks/artifact.js +1 -145
  356. package/dist/core/command-hooks/catalog.js +1 -38
  357. package/dist/core/command-hooks/compose.js +1 -99
  358. package/dist/core/command-hooks/discovery.js +1 -228
  359. package/dist/core/command-hooks/help.js +1 -18
  360. package/dist/core/command-hooks/index.js +1 -7
  361. package/dist/core/command-hooks/lifecycle-catalog.js +1 -9
  362. package/dist/core/command-hooks/lifecycle-create.js +1 -51
  363. package/dist/core/command-hooks/report.js +1 -28
  364. package/dist/core/command-hooks/schema.js +1 -157
  365. package/dist/core/command-hooks/transport/exec-invoke.js +1 -276
  366. package/dist/core/command-hooks/transport/exec-lifecycle.js +1 -211
  367. package/dist/core/command-manifests/manifest.js +1 -324
  368. package/dist/core/command-manifests/registry.js +1 -118
  369. package/dist/core/command-manifests/schema.js +1 -736
  370. package/dist/core/command-plugins/bundle.js +1 -261
  371. package/dist/core/command-plugins/compose.js +1 -65
  372. package/dist/core/command-plugins/discovery.js +1 -245
  373. package/dist/core/command-plugins/endpoint.js +1 -48
  374. package/dist/core/command-plugins/extensions.js +1 -166
  375. package/dist/core/command-plugins/help-addenda.js +1 -44
  376. package/dist/core/command-plugins/presence.js +1 -17
  377. package/dist/core/command-plugins/revalidate.js +2 -152
  378. package/dist/core/command-plugins/transport/exec-invoke.js +1 -215
  379. package/dist/core/command-plugins/transport/http-fetch.js +1 -68
  380. package/dist/core/command-plugins/transport/http-invoke.js +3 -546
  381. package/dist/core/command.js +10 -739
  382. package/dist/core/config.js +1 -1059
  383. package/dist/core/document-lines.js +3 -6
  384. package/dist/core/env-name.js +1 -9
  385. package/dist/core/errors.js +1 -52
  386. package/dist/core/events/emit.js +1 -17
  387. package/dist/core/events/envelope.js +1 -84
  388. package/dist/core/events/errors.js +1 -69
  389. package/dist/core/events/index.js +1 -4
  390. package/dist/core/events/operation-id.js +1 -24
  391. package/dist/core/events/read.js +1 -623
  392. package/dist/core/events/serialize.js +1 -199
  393. package/dist/core/events/source.js +1 -31
  394. package/dist/core/events/types.js +1 -11
  395. package/dist/core/exclusive-lock.js +1 -197
  396. package/dist/core/fault-classifier.js +1 -96
  397. package/dist/core/feed/feed.js +7 -202
  398. package/dist/core/feed/inbox-migrate.js +3 -135
  399. package/dist/core/feed/inbox.js +10 -122
  400. package/dist/core/feed/messages.js +6 -212
  401. package/dist/core/frontmatter.js +1 -35
  402. package/dist/core/fs-utils.js +3 -202
  403. package/dist/core/git.js +2 -103
  404. package/dist/core/help.js +9 -310
  405. package/dist/core/host-exports/builtins.js +9 -68
  406. package/dist/core/host-exports/export.js +3 -124
  407. package/dist/core/human/action-binding.js +1 -40
  408. package/dist/core/human/answer-text.js +5 -100
  409. package/dist/core/human/answer.js +1 -119
  410. package/dist/core/human/claim.js +3 -67
  411. package/dist/core/human/completion.js +1 -27
  412. package/dist/core/human/component-docs.js +78 -272
  413. package/dist/core/human/convention.js +2 -82
  414. package/dist/core/human/feedback-companion.js +1 -106
  415. package/dist/core/human/feedback.js +1 -88
  416. package/dist/core/human/page-authoring.js +1 -19
  417. package/dist/core/human/page-catalog.js +1 -172
  418. package/dist/core/human/page-errors.js +1 -7
  419. package/dist/core/human/page-eval.js +1 -125
  420. package/dist/core/human/page-html-markdown.js +8 -260
  421. package/dist/core/human/page-markdown.js +17 -295
  422. package/dist/core/human/page-schema.js +1 -373
  423. package/dist/core/human/page-synth.js +8 -27
  424. package/dist/core/human/page.js +1 -198
  425. package/dist/core/human/requests.js +15 -466
  426. package/dist/core/human/review-schema.js +1 -34
  427. package/dist/core/human/root.js +1 -11
  428. package/dist/core/human/scan.js +1 -69
  429. package/dist/core/human/summary.js +1 -5
  430. package/dist/core/human/tickets.js +1 -171
  431. package/dist/core/human/types.js +0 -1
  432. package/dist/core/human/visible-paths.js +1 -77
  433. package/dist/core/human-actions.js +1 -101
  434. package/dist/core/inspector/chrome.js +1 -14
  435. package/dist/core/inspector/contract.js +0 -1
  436. package/dist/core/inspector/core.js +2 -295
  437. package/dist/core/inspector/host.js +4 -538
  438. package/dist/core/inspector/model.js +2 -226
  439. package/dist/core/inspector/text.js +6 -45
  440. package/dist/core/inspector/transport.js +1 -36
  441. package/dist/core/inspector/tui.js +2 -295
  442. package/dist/core/installed-plugins.js +1 -78
  443. package/dist/core/io.js +7 -356
  444. package/dist/core/keybindings/attach-control.js +1 -42
  445. package/dist/core/keybindings/background-bash.js +1 -33
  446. package/dist/core/keybindings/catalog.js +1 -256
  447. package/dist/core/keybindings/inbox.js +1 -25
  448. package/dist/core/keybindings/index.js +1 -7
  449. package/dist/core/keybindings/match.js +1 -127
  450. package/dist/core/keybindings/persistence.js +1 -49
  451. package/dist/core/keybindings/resolve.js +1 -348
  452. package/dist/core/keybindings/types.js +0 -1
  453. package/dist/core/locked-file.js +1 -118
  454. package/dist/core/log.js +3 -27
  455. package/dist/core/manifest-recovery.js +1 -72
  456. package/dist/core/manifest-stale.js +1 -39
  457. package/dist/core/manifest.js +1 -20
  458. package/dist/core/memory/doc-link-grammar.js +2 -109
  459. package/dist/core/memory/extensions.js +1 -221
  460. package/dist/core/memory/history.js +6 -268
  461. package/dist/core/memory/identity.js +1 -181
  462. package/dist/core/memory/inline-ref-grammar.js +1 -98
  463. package/dist/core/memory/inline-ref-guidance.js +2 -35
  464. package/dist/core/memory/inline-ref-inventory.js +1 -59
  465. package/dist/core/memory/lint.js +2 -671
  466. package/dist/core/memory/project-namespace.js +2 -85
  467. package/dist/core/memory/repository-association.js +1 -129
  468. package/dist/core/memory/tree.js +1 -93
  469. package/dist/core/memory-resolver.js +2 -611
  470. package/dist/core/model-config.js +1 -107
  471. package/dist/core/model-routes.js +1 -201
  472. package/dist/core/nested-stores.js +2 -166
  473. package/dist/core/output.js +7 -99
  474. package/dist/core/pagination.js +1 -88
  475. package/dist/core/plugin-swap-lock.js +1 -31
  476. package/dist/core/pool-credential-store.js +1 -116
  477. package/dist/core/predicate.js +1 -191
  478. package/dist/core/preview-registry.js +2 -411
  479. package/dist/core/preview-result-path.js +1 -26
  480. package/dist/core/profiles/default-binding.js +1 -24
  481. package/dist/core/profiles/deletion-reservation.js +1 -42
  482. package/dist/core/profiles/env-store.js +2 -162
  483. package/dist/core/profiles/fuzzy-match.js +1 -92
  484. package/dist/core/profiles/manifest.js +1 -574
  485. package/dist/core/profiles/select.js +35 -741
  486. package/dist/core/profiles/state-block.js +3 -17
  487. package/dist/core/provider-error-recognition.js +1 -74
  488. package/dist/core/provider-failure.js +1 -86
  489. package/dist/core/provider-management.js +1 -22
  490. package/dist/core/remote-canvas-target.js +1 -30
  491. package/dist/core/render.js +18 -138
  492. package/dist/core/resolver.js +1 -111
  493. package/dist/core/review/birth.js +1 -52
  494. package/dist/core/review/comments.js +5 -279
  495. package/dist/core/review/companion.js +1 -215
  496. package/dist/core/review/document.js +2 -138
  497. package/dist/core/review/project.js +1 -36
  498. package/dist/core/review/realize.js +1 -71
  499. package/dist/core/review/remap.js +4 -141
  500. package/dist/core/review/signal.js +1 -12
  501. package/dist/core/review/stage.js +1 -184
  502. package/dist/core/review/store.js +1 -168
  503. package/dist/core/review/types.js +1 -23
  504. package/dist/core/runtime/advertised-command-invocation.js +1 -233
  505. package/dist/core/runtime/auth-reload.js +1 -67
  506. package/dist/core/runtime/banner.js +1 -51
  507. package/dist/core/runtime/bearings-render.js +18 -250
  508. package/dist/core/runtime/bearings.js +7 -194
  509. package/dist/core/runtime/bin-contributions.js +2 -186
  510. package/dist/core/runtime/boot-root.js +1 -107
  511. package/dist/core/runtime/branded-host.js +2 -264
  512. package/dist/core/runtime/broker/auth-reload.js +1 -157
  513. package/dist/core/runtime/broker/client-registry.js +1 -179
  514. package/dist/core/runtime/broker/daemon-ops.js +1 -88
  515. package/dist/core/runtime/broker/engine-drive.js +1 -354
  516. package/dist/core/runtime/broker/engine-routing.js +1 -211
  517. package/dist/core/runtime/broker/event-projection.js +1 -193
  518. package/dist/core/runtime/broker/extension-abort.js +1 -36
  519. package/dist/core/runtime/broker/fault-retry.js +1 -588
  520. package/dist/core/runtime/broker/frame-client.js +1 -132
  521. package/dist/core/runtime/broker/frame-dispatch.js +1 -183
  522. package/dist/core/runtime/broker/frame-engine-control.js +1 -231
  523. package/dist/core/runtime/broker/frame-memory-refs.js +1 -41
  524. package/dist/core/runtime/broker/frame-model-query.js +1 -69
  525. package/dist/core/runtime/broker/frame-read.js +1 -116
  526. package/dist/core/runtime/broker/frame-replies.js +1 -64
  527. package/dist/core/runtime/broker/frame-session.js +4 -203
  528. package/dist/core/runtime/broker/held-deferred-inbox.js +1 -13
  529. package/dist/core/runtime/broker/inbox.js +13 -163
  530. package/dist/core/runtime/broker/node-named.js +1 -27
  531. package/dist/core/runtime/broker/read-ops.js +1 -171
  532. package/dist/core/runtime/broker/rebind.js +1 -318
  533. package/dist/core/runtime/broker/tool-groups.js +1 -246
  534. package/dist/core/runtime/broker/turn-admission.js +1 -31
  535. package/dist/core/runtime/broker/turn-ignition.js +1 -84
  536. package/dist/core/runtime/broker-cli.js +3 -81
  537. package/dist/core/runtime/broker-extension-render.js +5 -135
  538. package/dist/core/runtime/broker-inventory.js +1 -116
  539. package/dist/core/runtime/broker-persona-guidance.js +4 -154
  540. package/dist/core/runtime/broker-protocol.js +3 -152
  541. package/dist/core/runtime/broker-request.js +1 -85
  542. package/dist/core/runtime/broker-sdk.js +1 -129
  543. package/dist/core/runtime/broker.js +1 -1214
  544. package/dist/core/runtime/canvas-extensions.js +1 -96
  545. package/dist/core/runtime/chat-inventory-rows.js +1 -105
  546. package/dist/core/runtime/close.js +1 -265
  547. package/dist/core/runtime/command-expansion.js +9 -104
  548. package/dist/core/runtime/command-surface.js +1 -117
  549. package/dist/core/runtime/connectivity.js +1 -73
  550. package/dist/core/runtime/deliver-live.js +1 -88
  551. package/dist/core/runtime/fault-recovery.js +1 -83
  552. package/dist/core/runtime/fault.js +1 -17
  553. package/dist/core/runtime/fleet.js +1 -58
  554. package/dist/core/runtime/front-door-env.js +1 -16
  555. package/dist/core/runtime/front-door.js +7 -183
  556. package/dist/core/runtime/headless-pi.js +1 -161
  557. package/dist/core/runtime/host.js +1 -457
  558. package/dist/core/runtime/interactive-deliver.js +1 -51
  559. package/dist/core/runtime/invocation.js +0 -10
  560. package/dist/core/runtime/kickoff.js +30 -327
  561. package/dist/core/runtime/launch-config-worker.js +1 -12
  562. package/dist/core/runtime/launch-prompt.js +4 -13
  563. package/dist/core/runtime/launch-target.js +1 -55
  564. package/dist/core/runtime/launch.js +1 -483
  565. package/dist/core/runtime/lifecycle.js +2 -213
  566. package/dist/core/runtime/managed-provider-cooling.js +1 -62
  567. package/dist/core/runtime/memory.js +1 -17
  568. package/dist/core/runtime/model-registry.js +1 -13
  569. package/dist/core/runtime/model-selection.js +1 -135
  570. package/dist/core/runtime/model-swap.js +1 -86
  571. package/dist/core/runtime/naming.js +14 -298
  572. package/dist/core/runtime/nerd-font.js +2 -127
  573. package/dist/core/runtime/node-read.js +2 -386
  574. package/dist/core/runtime/nodes.js +1 -331
  575. package/dist/core/runtime/outcome-document.js +1 -97
  576. package/dist/core/runtime/package-health.js +4 -99
  577. package/dist/core/runtime/persona.js +2 -55
  578. package/dist/core/runtime/pi-cli.js +1 -65
  579. package/dist/core/runtime/pi-vendored.js +1 -66
  580. package/dist/core/runtime/placement-tmux.js +1 -81
  581. package/dist/core/runtime/placement.js +1 -386
  582. package/dist/core/runtime/promote.js +1 -174
  583. package/dist/core/runtime/prospective-inventory-cli.js +3 -61
  584. package/dist/core/runtime/prospective-inventory.js +2 -88
  585. package/dist/core/runtime/recap.js +27 -103
  586. package/dist/core/runtime/recycle.js +1 -190
  587. package/dist/core/runtime/reopen.js +1 -138
  588. package/dist/core/runtime/reset.js +1 -245
  589. package/dist/core/runtime/resume-root.js +10 -290
  590. package/dist/core/runtime/revive-all.js +1 -107
  591. package/dist/core/runtime/revive.js +4 -544
  592. package/dist/core/runtime/roadmap.js +4 -38
  593. package/dist/core/runtime/session-branch.js +1 -46
  594. package/dist/core/runtime/session-cycles.js +1 -110
  595. package/dist/core/runtime/session-list-cache.js +1 -406
  596. package/dist/core/runtime/session-visibility.js +1 -99
  597. package/dist/core/runtime/shell-expansion.js +9 -100
  598. package/dist/core/runtime/situational-context.js +2 -67
  599. package/dist/core/runtime/situational-live.js +1 -41
  600. package/dist/core/runtime/spawn-env.js +1 -255
  601. package/dist/core/runtime/spawn.js +3 -577
  602. package/dist/core/runtime/stamp/channel.js +1 -76
  603. package/dist/core/runtime/stamp/protocol.js +1 -113
  604. package/dist/core/runtime/stop-guard.js +7 -116
  605. package/dist/core/runtime/stop-signals.js +1 -46
  606. package/dist/core/runtime/stream-watchdog.js +1 -134
  607. package/dist/core/runtime/structured-output.js +4 -156
  608. package/dist/core/runtime/surface-bg.js +1 -85
  609. package/dist/core/runtime/tmux-bindings.js +4 -730
  610. package/dist/core/runtime/tmux-chrome.js +1 -5
  611. package/dist/core/runtime/tmux-driver.js +7 -637
  612. package/dist/core/runtime/tool-group-summary.js +6 -85
  613. package/dist/core/runtime/turn-visibility.js +1 -31
  614. package/dist/core/runtime/view-socket.js +1 -83
  615. package/dist/core/runtime/warm-pool.d.ts +3 -2
  616. package/dist/core/runtime/warm-pool.js +1 -385
  617. package/dist/core/scope.js +1 -254
  618. package/dist/core/scoped-state/db.js +1 -135
  619. package/dist/core/scoped-state/migrate.js +3 -181
  620. package/dist/core/scoped-state/paths.js +1 -27
  621. package/dist/core/scoped-state/profiles.js +1 -62
  622. package/dist/core/scoped-state/providers.js +1 -8
  623. package/dist/core/scoped-state/schema.js +3 -16
  624. package/dist/core/scoped-state/settings.js +1 -82
  625. package/dist/core/secrets.js +2 -55
  626. package/dist/core/self-update.js +1 -71
  627. package/dist/core/session-model/session-state.js +1 -180
  628. package/dist/core/shell-segments.js +4 -169
  629. package/dist/core/spawn.js +1 -26
  630. package/dist/core/stdout-errors.js +1 -14
  631. package/dist/core/subscription-state.js +3 -193
  632. package/dist/core/substrate/frontmatter-validation.js +1 -105
  633. package/dist/core/substrate/gate-explain.js +1 -424
  634. package/dist/core/substrate/gate.js +1 -26
  635. package/dist/core/substrate/index.js +1 -30
  636. package/dist/core/substrate/injected-store.js +1 -249
  637. package/dist/core/substrate/listings.js +1 -115
  638. package/dist/core/substrate/on-read-node.js +1 -36
  639. package/dist/core/substrate/on-read.js +9 -315
  640. package/dist/core/substrate/plan.js +1 -266
  641. package/dist/core/substrate/render-node.js +1 -30
  642. package/dist/core/substrate/render.js +65 -689
  643. package/dist/core/substrate/schema.js +1 -186
  644. package/dist/core/substrate/session-cache.js +1 -83
  645. package/dist/core/substrate/subject-fields.js +1 -35
  646. package/dist/core/substrate/subject.js +1 -47
  647. package/dist/core/substrate/surface-match.js +1 -242
  648. package/dist/core/termrender/code-doc.js +5 -92
  649. package/dist/core/termrender/display.js +2 -56
  650. package/dist/core/termrender/termrender.js +14 -719
  651. package/dist/core/termrender/version.js +1 -1
  652. package/dist/core/timing.js +2 -94
  653. package/dist/core/tui/draw.js +2 -378
  654. package/dist/core/tui/fuzzy.js +1 -38
  655. package/dist/core/tui/markdown.js +3 -407
  656. package/dist/core/tui/page-host.js +1 -74
  657. package/dist/core/tui/panel.js +1 -137
  658. package/dist/core/tui/terminal.js +2 -100
  659. package/dist/core/user-settings.js +1 -454
  660. package/dist/core/wake.js +1 -296
  661. package/dist/core/worktree-close.js +6 -228
  662. package/dist/core/worktree-containment.js +3 -48
  663. package/dist/core/worktree-landing.js +4 -56
  664. package/dist/core/worktree-mutation-async.js +10 -280
  665. package/dist/core/worktree-quarantine.js +1 -54
  666. package/dist/core/worktree-sweep.js +6 -453
  667. package/dist/core/worktree.js +18 -899
  668. package/dist/daemon/api/bridge.js +8 -418
  669. package/dist/daemon/api/handlers/attach.js +1 -65
  670. package/dist/daemon/api/handlers/bash-jobs.js +2 -91
  671. package/dist/daemon/api/handlers/broker-ops.js +1 -447
  672. package/dist/daemon/api/handlers/broker-recovery.js +1 -251
  673. package/dist/daemon/api/handlers/canvas.js +6 -490
  674. package/dist/daemon/api/handlers/chat-inventory.js +1 -25
  675. package/dist/daemon/api/handlers/crons.js +1 -373
  676. package/dist/daemon/api/handlers/daemon.js +1 -76
  677. package/dist/daemon/api/handlers/feedback-comments.js +3 -199
  678. package/dist/daemon/api/handlers/files.js +1 -63
  679. package/dist/daemon/api/handlers/focus.js +1 -92
  680. package/dist/daemon/api/handlers/health.js +1 -76
  681. package/dist/daemon/api/handlers/human-requests.js +1 -379
  682. package/dist/daemon/api/handlers/human.js +1 -3
  683. package/dist/daemon/api/handlers/inbox-page.js +1 -89
  684. package/dist/daemon/api/handlers/inbox.js +1 -301
  685. package/dist/daemon/api/handlers/memory.js +1 -50
  686. package/dist/daemon/api/handlers/messages.js +2 -506
  687. package/dist/daemon/api/handlers/model-config.js +1 -44
  688. package/dist/daemon/api/handlers/modelauth.js +1 -165
  689. package/dist/daemon/api/handlers/node-outcomes.js +1 -181
  690. package/dist/daemon/api/handlers/nodes.js +1 -943
  691. package/dist/daemon/api/handlers/profiles.js +1 -140
  692. package/dist/daemon/api/handlers/prospective-chat-inventory.js +1 -59
  693. package/dist/daemon/api/handlers/reports.js +16 -332
  694. package/dist/daemon/api/handlers/review-comments.js +1 -465
  695. package/dist/daemon/api/handlers/reviews.js +1 -200
  696. package/dist/daemon/api/handlers/subscriptions.js +1 -53
  697. package/dist/daemon/api/handlers/validate.js +1 -58
  698. package/dist/daemon/api/handlers/worktree.js +1 -39
  699. package/dist/daemon/api/map.js +2 -735
  700. package/dist/daemon/api/router.js +1 -190
  701. package/dist/daemon/api/server.js +11 -408
  702. package/dist/daemon/boot-migrations.js +1 -31
  703. package/dist/daemon/companion-retire.js +1 -34
  704. package/dist/daemon/control.js +1 -22
  705. package/dist/daemon/cron/armed-context.js +1 -100
  706. package/dist/daemon/cron/capture.js +2 -45
  707. package/dist/daemon/cron/disposition.js +1 -55
  708. package/dist/daemon/cron/escalation.js +3 -124
  709. package/dist/daemon/cron/held.js +1 -20
  710. package/dist/daemon/cron/lease-recovery.js +1 -119
  711. package/dist/daemon/cron/live-runs.js +1 -23
  712. package/dist/daemon/cron/passes.js +1 -58
  713. package/dist/daemon/cron/settle.js +1 -61
  714. package/dist/daemon/cron/sinks.js +2 -59
  715. package/dist/daemon/cron-run.js +1 -405
  716. package/dist/daemon/crtrd-cli.js +1 -23
  717. package/dist/daemon/crtrd.js +8 -854
  718. package/dist/daemon/delivery/run-delivery.js +1 -164
  719. package/dist/daemon/fleet.js +17 -475
  720. package/dist/daemon/human/finish.js +10 -179
  721. package/dist/daemon/human/settle.js +1 -89
  722. package/dist/daemon/human/sweep.js +1 -66
  723. package/dist/daemon/manage.js +2 -595
  724. package/dist/daemon/messaging/node-message.js +1 -99
  725. package/dist/daemon/park-activity.js +1 -30
  726. package/dist/daemon/park-pending.js +1 -52
  727. package/dist/daemon/pidfile.js +1 -37
  728. package/dist/daemon/profile-delete.js +1 -306
  729. package/dist/daemon/reconcilers/bash-deadline.js +1 -80
  730. package/dist/daemon/reconcilers/broker-supervision.js +4 -761
  731. package/dist/daemon/reconcilers/controller-death.js +1 -14
  732. package/dist/daemon/reconcilers/cron-lane.js +1 -29
  733. package/dist/daemon/reconcilers/delivery-lane.js +1 -130
  734. package/dist/daemon/reconcilers/live-obligation.js +1 -87
  735. package/dist/daemon/reconcilers/managed-worktree-sweep.js +1 -202
  736. package/dist/daemon/reconcilers/node-deadline.js +1 -82
  737. package/dist/daemon/reconcilers/node-lifecycle/freeze-lane.js +1 -172
  738. package/dist/daemon/reconcilers/node-lifecycle/respawn-policy.js +1 -59
  739. package/dist/daemon/reconcilers/node-lifecycle/terminating.js +1 -12
  740. package/dist/daemon/reconcilers/node-lifecycle/tick.js +1 -146
  741. package/dist/daemon/reconcilers/node-lifecycle/wants-execution.js +1 -11
  742. package/dist/daemon/reconcilers/pending-review-submit.js +1 -36
  743. package/dist/daemon/reconcilers/storage-maintenance.js +1 -207
  744. package/dist/daemon/review/comment-notify.js +2 -109
  745. package/dist/daemon/review/companion.js +1 -29
  746. package/dist/daemon/review/deliver.js +3 -8
  747. package/dist/daemon/review/finish.js +1 -122
  748. package/dist/daemon/review/sweep.js +1 -18
  749. package/dist/daemon/startup-policy.js +1 -1
  750. package/dist/daemon/supervise-cadence.js +1 -6
  751. package/dist/hook-authoring.js +5 -447
  752. package/dist/hook-process.js +1 -34
  753. package/dist/index.js +1 -52
  754. package/dist/migrations/001-surfaces-frontmatter.js +1 -161
  755. package/dist/migrations/002-profile-project-memory.js +1 -72
  756. package/dist/migrations/003-repository-root-memory-identity/front-door.js +11 -231
  757. package/dist/migrations/003-repository-root-memory-identity/index.js +5 -513
  758. package/dist/migrations/003-repository-root-memory-identity/references.js +5 -469
  759. package/dist/migrations/003-repository-root-memory-identity/repository-facts.js +3 -349
  760. package/dist/migrations/activation.js +2 -89
  761. package/dist/migrations/convergent.js +2 -82
  762. package/dist/migrations/corpus.js +3 -483
  763. package/dist/migrations/frontmatter-splice.js +8 -176
  764. package/dist/migrations/profile-manifests.js +2 -70
  765. package/dist/migrations/registry.js +1 -42
  766. package/dist/migrations/runner.js +1 -85
  767. package/dist/migrations/types.js +0 -24
  768. package/dist/pi-extensions/broker-local.js +2 -106
  769. package/dist/pi-extensions/canvas-bash-valve.js +7 -461
  770. package/dist/pi-extensions/canvas-context-intro.js +2 -113
  771. package/dist/pi-extensions/canvas-doc-substrate.js +9 -178
  772. package/dist/pi-extensions/canvas-goal-capture.js +1 -83
  773. package/dist/pi-extensions/canvas-inbox-watcher.js +1 -1010
  774. package/dist/pi-extensions/canvas-passive-context.js +14 -203
  775. package/dist/pi-extensions/canvas-preview-result.js +2 -72
  776. package/dist/pi-extensions/canvas-prompt-scrub.js +2 -54
  777. package/dist/pi-extensions/canvas-recap.js +11 -405
  778. package/dist/pi-extensions/canvas-review-boundary.js +3 -63
  779. package/dist/pi-extensions/canvas-stamp.js +2 -77
  780. package/dist/pi-extensions/canvas-stophook.js +1 -643
  781. package/dist/pi-extensions/canvas-structured-output.js +13 -35
  782. package/dist/pi-extensions/canvas-tool-guide.js +9 -78
  783. package/dist/pi-extensions/envelope-merge.js +8 -29
  784. package/dist/prompts/review.js +20 -42
  785. package/dist/shared/birth-announcement.js +1 -25
  786. package/dist/shared/crtr-version.js +1 -18
  787. package/dist/shared/env.js +1 -214
  788. package/dist/shared/generated-context.js +11 -226
  789. package/dist/shared/predicates.js +1 -4
  790. package/dist/shared/shell-quote.js +1 -5
  791. package/dist/shared/tool-groups.js +1 -64
  792. package/dist/shared/working-activity.js +1 -27
  793. package/dist/suppress-experimental-warnings.js +1 -15
  794. package/dist/types.js +1 -185
  795. package/docs/public-api.md +10 -9
  796. package/package.json +6 -5
  797. package/runtime.lock.json +5 -5
  798. package/dist/api/__tests__/integration/client.test.d.ts +0 -1
  799. package/dist/api/__tests__/integration/client.test.js +0 -163
  800. package/dist/builtin-pi-packages/pi-crtr-extensions/__tests__/insights-active-init.test.ts +0 -98
  801. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/__tests__/crtr-commands.test.ts +0 -93
  802. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/__tests__/integration/provider-rotation.test.ts +0 -2530
  803. package/dist/clients/__tests__/helpers/human-daemon.d.ts +0 -11
  804. package/dist/clients/__tests__/helpers/human-daemon.js +0 -60
  805. package/dist/clients/attach/__tests__/attach-remote-readonly.test.d.ts +0 -1
  806. package/dist/clients/attach/__tests__/attach-remote-readonly.test.js +0 -97
  807. package/dist/clients/attach/__tests__/bash-call-width.test.d.ts +0 -1
  808. package/dist/clients/attach/__tests__/bash-call-width.test.js +0 -38
  809. package/dist/clients/attach/__tests__/chat-view-snapshot-ordering.test.d.ts +0 -1
  810. package/dist/clients/attach/__tests__/chat-view-snapshot-ordering.test.js +0 -175
  811. package/dist/clients/attach/__tests__/completion-frecency.test.d.ts +0 -1
  812. package/dist/clients/attach/__tests__/completion-frecency.test.js +0 -35
  813. package/dist/clients/attach/__tests__/context-message.test.d.ts +0 -1
  814. package/dist/clients/attach/__tests__/context-message.test.js +0 -130
  815. package/dist/clients/attach/__tests__/crtr-output.test.d.ts +0 -1
  816. package/dist/clients/attach/__tests__/crtr-output.test.js +0 -68
  817. package/dist/clients/attach/__tests__/diagram.test.d.ts +0 -1
  818. package/dist/clients/attach/__tests__/diagram.test.js +0 -42
  819. package/dist/clients/attach/__tests__/edit-diff.test.d.ts +0 -1
  820. package/dist/clients/attach/__tests__/edit-diff.test.js +0 -31
  821. package/dist/clients/attach/__tests__/frame-selection.test.d.ts +0 -1
  822. package/dist/clients/attach/__tests__/frame-selection.test.js +0 -84
  823. package/dist/clients/attach/__tests__/group-activity.test.d.ts +0 -1
  824. package/dist/clients/attach/__tests__/group-activity.test.js +0 -165
  825. package/dist/clients/attach/__tests__/oauth-dialog-lifecycle.test.d.ts +0 -1
  826. package/dist/clients/attach/__tests__/oauth-dialog-lifecycle.test.js +0 -83
  827. package/dist/clients/attach/__tests__/pane-tag-successor.test.d.ts +0 -1
  828. package/dist/clients/attach/__tests__/pane-tag-successor.test.js +0 -56
  829. package/dist/clients/attach/__tests__/profile-files.test.d.ts +0 -1
  830. package/dist/clients/attach/__tests__/profile-files.test.js +0 -21
  831. package/dist/clients/attach/__tests__/prompt-preview.test.d.ts +0 -1
  832. package/dist/clients/attach/__tests__/prompt-preview.test.js +0 -21
  833. package/dist/clients/attach/__tests__/ref-autocomplete.test.d.ts +0 -1
  834. package/dist/clients/attach/__tests__/ref-autocomplete.test.js +0 -64
  835. package/dist/clients/attach/__tests__/titled-editor-paste.test.d.ts +0 -1
  836. package/dist/clients/attach/__tests__/titled-editor-paste.test.js +0 -114
  837. package/dist/clients/attach/__tests__/titled-editor-preview.test.d.ts +0 -1
  838. package/dist/clients/attach/__tests__/titled-editor-preview.test.js +0 -83
  839. package/dist/clients/inbox/__tests__/integration/inbox-controller.test.d.ts +0 -1
  840. package/dist/clients/inbox/__tests__/integration/inbox-controller.test.js +0 -81
  841. package/dist/clients/inbox/__tests__/integration/mount-panel.test.d.ts +0 -1
  842. package/dist/clients/inbox/__tests__/integration/mount-panel.test.js +0 -135
  843. package/dist/clients/inbox/__tests__/integration/stale-row-activation.test.d.ts +0 -1
  844. package/dist/clients/inbox/__tests__/integration/stale-row-activation.test.js +0 -66
  845. package/dist/clients/inbox/review/__tests__/editor-roundtrip.test.d.ts +0 -1
  846. package/dist/clients/inbox/review/__tests__/editor-roundtrip.test.js +0 -35
  847. package/dist/clients/inbox/review/__tests__/review-core.test.d.ts +0 -1
  848. package/dist/clients/inbox/review/__tests__/review-core.test.js +0 -52
  849. package/dist/clients/inbox/review/__tests__/teardown-notice.test.d.ts +0 -1
  850. package/dist/clients/inbox/review/__tests__/teardown-notice.test.js +0 -100
  851. package/dist/commands/__tests__/api-client-cold-start-diagnostic.test.d.ts +0 -1
  852. package/dist/commands/__tests__/api-client-cold-start-diagnostic.test.js +0 -69
  853. package/dist/commands/__tests__/human.test.d.ts +0 -1
  854. package/dist/commands/__tests__/human.test.js +0 -172
  855. package/dist/commands/__tests__/integration/dashboard-snapshot.test.d.ts +0 -1
  856. package/dist/commands/__tests__/integration/dashboard-snapshot.test.js +0 -237
  857. package/dist/commands/__tests__/integration/migrate.test.d.ts +0 -1
  858. package/dist/commands/__tests__/integration/migrate.test.js +0 -1330
  859. package/dist/commands/__tests__/node-message.test.d.ts +0 -1
  860. package/dist/commands/__tests__/node-message.test.js +0 -112
  861. package/dist/commands/__tests__/node-new.test.d.ts +0 -1
  862. package/dist/commands/__tests__/node-new.test.js +0 -58
  863. package/dist/commands/__tests__/revive-now-gate.test.d.ts +0 -1
  864. package/dist/commands/__tests__/revive-now-gate.test.js +0 -62
  865. package/dist/commands/__tests__/seam/daemon-status.test.d.ts +0 -1
  866. package/dist/commands/__tests__/seam/daemon-status.test.js +0 -29
  867. package/dist/commands/__tests__/surface-reload-target.test.d.ts +0 -1
  868. package/dist/commands/__tests__/surface-reload-target.test.js +0 -21
  869. package/dist/commands/memory/__tests__/command-selector-and-mutation-guards.test.d.ts +0 -1
  870. package/dist/commands/memory/__tests__/command-selector-and-mutation-guards.test.js +0 -379
  871. package/dist/commands/memory/__tests__/memory-list-and-lint-ignore.test.d.ts +0 -1
  872. package/dist/commands/memory/__tests__/memory-list-and-lint-ignore.test.js +0 -124
  873. package/dist/commands/memory/__tests__/repository-root-lint.test.d.ts +0 -1
  874. package/dist/commands/memory/__tests__/repository-root-lint.test.js +0 -148
  875. package/dist/commands/sys/__tests__/config-model-ladders.test.d.ts +0 -1
  876. package/dist/commands/sys/__tests__/config-model-ladders.test.js +0 -114
  877. package/dist/commands/sys/__tests__/setup-core.test.d.ts +0 -1
  878. package/dist/commands/sys/__tests__/setup-core.test.js +0 -45
  879. package/dist/commands/sys/__tests__/sync-project-guidance.test.d.ts +0 -1
  880. package/dist/commands/sys/__tests__/sync-project-guidance.test.js +0 -244
  881. package/dist/core/__tests__/bash-guard.test.d.ts +0 -1
  882. package/dist/core/__tests__/bash-guard.test.js +0 -190
  883. package/dist/core/__tests__/boot-fault-attempt.test.d.ts +0 -1
  884. package/dist/core/__tests__/boot-fault-attempt.test.js +0 -105
  885. package/dist/core/__tests__/boot.test.d.ts +0 -1
  886. package/dist/core/__tests__/boot.test.js +0 -274
  887. package/dist/core/__tests__/branded-host-concurrency.test.d.ts +0 -1
  888. package/dist/core/__tests__/branded-host-concurrency.test.js +0 -72
  889. package/dist/core/__tests__/broker-extension-canvas-db-boundary.test.d.ts +0 -1
  890. package/dist/core/__tests__/broker-extension-canvas-db-boundary.test.js +0 -75
  891. package/dist/core/__tests__/broker-launch-candidates.test.d.ts +0 -1
  892. package/dist/core/__tests__/broker-launch-candidates.test.js +0 -311
  893. package/dist/core/__tests__/broker-preflight.test.d.ts +0 -1
  894. package/dist/core/__tests__/broker-preflight.test.js +0 -95
  895. package/dist/core/__tests__/broker-stream-watchdog-floor.test.d.ts +0 -1
  896. package/dist/core/__tests__/broker-stream-watchdog-floor.test.js +0 -82
  897. package/dist/core/__tests__/broker-turn-admission.test.d.ts +0 -1
  898. package/dist/core/__tests__/broker-turn-admission.test.js +0 -44
  899. package/dist/core/__tests__/canvas-db-boundary.test.d.ts +0 -1
  900. package/dist/core/__tests__/canvas-db-boundary.test.js +0 -46
  901. package/dist/core/__tests__/canvas-inbox-watcher-hold.test.d.ts +0 -1
  902. package/dist/core/__tests__/canvas-inbox-watcher-hold.test.js +0 -710
  903. package/dist/core/__tests__/canvas-inbox-watcher-naming.test.d.ts +0 -1
  904. package/dist/core/__tests__/canvas-inbox-watcher-naming.test.js +0 -310
  905. package/dist/core/__tests__/canvas-inbox-watcher.test.d.ts +0 -1
  906. package/dist/core/__tests__/canvas-inbox-watcher.test.js +0 -397
  907. package/dist/core/__tests__/canvas.test.d.ts +0 -1
  908. package/dist/core/__tests__/canvas.test.js +0 -138
  909. package/dist/core/__tests__/child-death-wake.test.d.ts +0 -1
  910. package/dist/core/__tests__/child-death-wake.test.js +0 -153
  911. package/dist/core/__tests__/cli-help-contract.test.d.ts +0 -1
  912. package/dist/core/__tests__/cli-help-contract.test.js +0 -152
  913. package/dist/core/__tests__/close.test.d.ts +0 -1
  914. package/dist/core/__tests__/close.test.js +0 -284
  915. package/dist/core/__tests__/collectible.test.d.ts +0 -1
  916. package/dist/core/__tests__/collectible.test.js +0 -89
  917. package/dist/core/__tests__/config-change-delta.test.d.ts +0 -1
  918. package/dist/core/__tests__/config-change-delta.test.js +0 -108
  919. package/dist/core/__tests__/context-intro.test.d.ts +0 -1
  920. package/dist/core/__tests__/context-intro.test.js +0 -123
  921. package/dist/core/__tests__/cron-armed-context-failure.test.d.ts +0 -1
  922. package/dist/core/__tests__/cron-armed-context-failure.test.js +0 -150
  923. package/dist/core/__tests__/cron-held-settlement.test.d.ts +0 -1
  924. package/dist/core/__tests__/cron-held-settlement.test.js +0 -240
  925. package/dist/core/__tests__/cron-node-sink-parked-root.test.d.ts +0 -1
  926. package/dist/core/__tests__/cron-node-sink-parked-root.test.js +0 -166
  927. package/dist/core/__tests__/cron-self-cancel-delivery.test.d.ts +0 -1
  928. package/dist/core/__tests__/cron-self-cancel-delivery.test.js +0 -84
  929. package/dist/core/__tests__/cron-timeout-descendants.test.d.ts +0 -1
  930. package/dist/core/__tests__/cron-timeout-descendants.test.js +0 -114
  931. package/dist/core/__tests__/daemon-boot.test.d.ts +0 -1
  932. package/dist/core/__tests__/daemon-boot.test.js +0 -422
  933. package/dist/core/__tests__/daemon-wedge.test.d.ts +0 -1
  934. package/dist/core/__tests__/daemon-wedge.test.js +0 -106
  935. package/dist/core/__tests__/dead-node-policy-table.test.d.ts +0 -1
  936. package/dist/core/__tests__/dead-node-policy-table.test.js +0 -77
  937. package/dist/core/__tests__/events-contract.test.d.ts +0 -1
  938. package/dist/core/__tests__/events-contract.test.js +0 -76
  939. package/dist/core/__tests__/extension-abort.test.d.ts +0 -1
  940. package/dist/core/__tests__/extension-abort.test.js +0 -21
  941. package/dist/core/__tests__/fault-classifier.test.d.ts +0 -1
  942. package/dist/core/__tests__/fault-classifier.test.js +0 -138
  943. package/dist/core/__tests__/fixtures/api-server-host.d.ts +0 -1
  944. package/dist/core/__tests__/fixtures/api-server-host.js +0 -47
  945. package/dist/core/__tests__/fixtures/c3-custom-provider-ext.d.ts +0 -2
  946. package/dist/core/__tests__/fixtures/c3-custom-provider-ext.js +0 -34
  947. package/dist/core/__tests__/fixtures/c5-command-boundary-ext.d.ts +0 -2
  948. package/dist/core/__tests__/fixtures/c5-command-boundary-ext.js +0 -32
  949. package/dist/core/__tests__/fixtures/fake-engine.d.ts +0 -347
  950. package/dist/core/__tests__/fixtures/fake-engine.js +0 -1509
  951. package/dist/core/__tests__/fixtures/fake-pi-host.d.ts +0 -2
  952. package/dist/core/__tests__/fixtures/fake-pi-host.js +0 -311
  953. package/dist/core/__tests__/fixtures/memory-slash-live-probe.d.ts +0 -1
  954. package/dist/core/__tests__/fixtures/memory-slash-live-probe.js +0 -75
  955. package/dist/core/__tests__/fixtures/metadata-migration-race.d.ts +0 -1
  956. package/dist/core/__tests__/fixtures/metadata-migration-race.js +0 -49
  957. package/dist/core/__tests__/focuses.test.d.ts +0 -1
  958. package/dist/core/__tests__/focuses.test.js +0 -113
  959. package/dist/core/__tests__/fs-utils.test.d.ts +0 -1
  960. package/dist/core/__tests__/fs-utils.test.js +0 -50
  961. package/dist/core/__tests__/helpers/broker-clients.d.ts +0 -43
  962. package/dist/core/__tests__/helpers/broker-clients.js +0 -174
  963. package/dist/core/__tests__/helpers/fleet.d.ts +0 -12
  964. package/dist/core/__tests__/helpers/fleet.js +0 -50
  965. package/dist/core/__tests__/helpers/harness.d.ts +0 -124
  966. package/dist/core/__tests__/helpers/harness.js +0 -806
  967. package/dist/core/__tests__/helpers/viewer-panes.d.ts +0 -12
  968. package/dist/core/__tests__/helpers/viewer-panes.js +0 -133
  969. package/dist/core/__tests__/history-inbox.test.d.ts +0 -1
  970. package/dist/core/__tests__/history-inbox.test.js +0 -121
  971. package/dist/core/__tests__/human-action-delivery.test.d.ts +0 -1
  972. package/dist/core/__tests__/human-action-delivery.test.js +0 -162
  973. package/dist/core/__tests__/human-actions.test.d.ts +0 -1
  974. package/dist/core/__tests__/human-actions.test.js +0 -120
  975. package/dist/core/__tests__/inline-memory-refs.test.d.ts +0 -1
  976. package/dist/core/__tests__/inline-memory-refs.test.js +0 -225
  977. package/dist/core/__tests__/integration/broker-fork-seam.test.d.ts +0 -1
  978. package/dist/core/__tests__/integration/broker-fork-seam.test.js +0 -193
  979. package/dist/core/__tests__/integration/broker-sdk-wiring.test.d.ts +0 -1
  980. package/dist/core/__tests__/integration/broker-sdk-wiring.test.js +0 -750
  981. package/dist/core/__tests__/integration/broker-snapshot-history.test.d.ts +0 -1
  982. package/dist/core/__tests__/integration/broker-snapshot-history.test.js +0 -288
  983. package/dist/core/__tests__/integration/broker-wedge-supervision.test.d.ts +0 -1
  984. package/dist/core/__tests__/integration/broker-wedge-supervision.test.js +0 -103
  985. package/dist/core/__tests__/integration/command-plugins.test.d.ts +0 -1
  986. package/dist/core/__tests__/integration/command-plugins.test.js +0 -1200
  987. package/dist/core/__tests__/integration/deferred-no-wake.test.d.ts +0 -1
  988. package/dist/core/__tests__/integration/deferred-no-wake.test.js +0 -610
  989. package/dist/core/__tests__/integration/flagship-lifecycle.test.d.ts +0 -1
  990. package/dist/core/__tests__/integration/flagship-lifecycle.test.js +0 -264
  991. package/dist/core/__tests__/integration/fresh-home-commands.test.d.ts +0 -1
  992. package/dist/core/__tests__/integration/fresh-home-commands.test.js +0 -49
  993. package/dist/core/__tests__/integration/git-optional-locks.test.d.ts +0 -1
  994. package/dist/core/__tests__/integration/git-optional-locks.test.js +0 -81
  995. package/dist/core/__tests__/integration/host-teardown-process-group.test.d.ts +0 -1
  996. package/dist/core/__tests__/integration/host-teardown-process-group.test.js +0 -480
  997. package/dist/core/__tests__/integration/lifecycle-hooks.test.d.ts +0 -1
  998. package/dist/core/__tests__/integration/lifecycle-hooks.test.js +0 -498
  999. package/dist/core/__tests__/integration/live-mutation-verbs.test.d.ts +0 -1
  1000. package/dist/core/__tests__/integration/live-mutation-verbs.test.js +0 -180
  1001. package/dist/core/__tests__/integration/live-mutation.test.d.ts +0 -1
  1002. package/dist/core/__tests__/integration/live-mutation.test.js +0 -173
  1003. package/dist/core/__tests__/integration/plugin-revalidate.test.d.ts +0 -1
  1004. package/dist/core/__tests__/integration/plugin-revalidate.test.js +0 -359
  1005. package/dist/core/__tests__/integration/profile-pause.test.d.ts +0 -1
  1006. package/dist/core/__tests__/integration/profile-pause.test.js +0 -115
  1007. package/dist/core/__tests__/integration/refresh-stall-recycle.test.d.ts +0 -1
  1008. package/dist/core/__tests__/integration/refresh-stall-recycle.test.js +0 -151
  1009. package/dist/core/__tests__/integration/revive.test.d.ts +0 -1
  1010. package/dist/core/__tests__/integration/revive.test.js +0 -615
  1011. package/dist/core/__tests__/integration/spawn-root.test.d.ts +0 -1
  1012. package/dist/core/__tests__/integration/spawn-root.test.js +0 -536
  1013. package/dist/core/__tests__/integration/subscription-delivery.test.d.ts +0 -1
  1014. package/dist/core/__tests__/integration/subscription-delivery.test.js +0 -132
  1015. package/dist/core/__tests__/integration/tmux-surface.test.d.ts +0 -1
  1016. package/dist/core/__tests__/integration/tmux-surface.test.js +0 -330
  1017. package/dist/core/__tests__/integration/worktree-land.test.d.ts +0 -1
  1018. package/dist/core/__tests__/integration/worktree-land.test.js +0 -607
  1019. package/dist/core/__tests__/integration/worktree-reap.test.d.ts +0 -1
  1020. package/dist/core/__tests__/integration/worktree-reap.test.js +0 -842
  1021. package/dist/core/__tests__/kickoff.test.d.ts +0 -1
  1022. package/dist/core/__tests__/kickoff.test.js +0 -196
  1023. package/dist/core/__tests__/lifecycle-terminal-reasons.test.d.ts +0 -1
  1024. package/dist/core/__tests__/lifecycle-terminal-reasons.test.js +0 -62
  1025. package/dist/core/__tests__/lifecycle.test.d.ts +0 -1
  1026. package/dist/core/__tests__/lifecycle.test.js +0 -176
  1027. package/dist/core/__tests__/live-lifecycle-prompt.test.d.ts +0 -1
  1028. package/dist/core/__tests__/live-lifecycle-prompt.test.js +0 -63
  1029. package/dist/core/__tests__/memory-resolver-precedence.test.d.ts +0 -1
  1030. package/dist/core/__tests__/memory-resolver-precedence.test.js +0 -228
  1031. package/dist/core/__tests__/migration.test.d.ts +0 -1
  1032. package/dist/core/__tests__/migration.test.js +0 -946
  1033. package/dist/core/__tests__/model-pin-durability.test.d.ts +0 -1
  1034. package/dist/core/__tests__/model-pin-durability.test.js +0 -195
  1035. package/dist/core/__tests__/model-routes-config.test.d.ts +0 -1
  1036. package/dist/core/__tests__/model-routes-config.test.js +0 -150
  1037. package/dist/core/__tests__/nested-store-discovery.test.d.ts +0 -1
  1038. package/dist/core/__tests__/nested-store-discovery.test.js +0 -89
  1039. package/dist/core/__tests__/node-outcome.test.d.ts +0 -1
  1040. package/dist/core/__tests__/node-outcome.test.js +0 -246
  1041. package/dist/core/__tests__/on-read-crouter-home-fence.test.d.ts +0 -1
  1042. package/dist/core/__tests__/on-read-crouter-home-fence.test.js +0 -66
  1043. package/dist/core/__tests__/on-read-dedup-resume.test.d.ts +0 -1
  1044. package/dist/core/__tests__/on-read-dedup-resume.test.js +0 -132
  1045. package/dist/core/__tests__/on-read-nested-store.test.d.ts +0 -1
  1046. package/dist/core/__tests__/on-read-nested-store.test.js +0 -135
  1047. package/dist/core/__tests__/parse-argv-stdin-secret.test.d.ts +0 -1
  1048. package/dist/core/__tests__/parse-argv-stdin-secret.test.js +0 -68
  1049. package/dist/core/__tests__/passive-subscription.test.d.ts +0 -1
  1050. package/dist/core/__tests__/passive-subscription.test.js +0 -120
  1051. package/dist/core/__tests__/pid-identity-match.test.d.ts +0 -1
  1052. package/dist/core/__tests__/pid-identity-match.test.js +0 -145
  1053. package/dist/core/__tests__/pid-zombie.test.d.ts +0 -1
  1054. package/dist/core/__tests__/pid-zombie.test.js +0 -42
  1055. package/dist/core/__tests__/plugin-kinds.test.d.ts +0 -1
  1056. package/dist/core/__tests__/plugin-kinds.test.js +0 -182
  1057. package/dist/core/__tests__/plugin-link-symlinked-scope-root.test.d.ts +0 -1
  1058. package/dist/core/__tests__/plugin-link-symlinked-scope-root.test.js +0 -43
  1059. package/dist/core/__tests__/plugin-page-components.test.d.ts +0 -1
  1060. package/dist/core/__tests__/plugin-page-components.test.js +0 -159
  1061. package/dist/core/__tests__/preview-mirror-cap.test.d.ts +0 -1
  1062. package/dist/core/__tests__/preview-mirror-cap.test.js +0 -53
  1063. package/dist/core/__tests__/preview-registry-sync.test.d.ts +0 -1
  1064. package/dist/core/__tests__/preview-registry-sync.test.js +0 -107
  1065. package/dist/core/__tests__/profile-project-memory-delivery.test.d.ts +0 -1
  1066. package/dist/core/__tests__/profile-project-memory-delivery.test.js +0 -644
  1067. package/dist/core/__tests__/prospective-inventory-capability-parity.test.d.ts +0 -1
  1068. package/dist/core/__tests__/prospective-inventory-capability-parity.test.js +0 -91
  1069. package/dist/core/__tests__/prune.test.d.ts +0 -1
  1070. package/dist/core/__tests__/prune.test.js +0 -243
  1071. package/dist/core/__tests__/push-final-guard.test.d.ts +0 -1
  1072. package/dist/core/__tests__/push-final-guard.test.js +0 -191
  1073. package/dist/core/__tests__/relaunch-root.test.d.ts +0 -1
  1074. package/dist/core/__tests__/relaunch-root.test.js +0 -249
  1075. package/dist/core/__tests__/remote-canvas-target.test.d.ts +0 -1
  1076. package/dist/core/__tests__/remote-canvas-target.test.js +0 -93
  1077. package/dist/core/__tests__/repository-association.test.d.ts +0 -1
  1078. package/dist/core/__tests__/repository-association.test.js +0 -153
  1079. package/dist/core/__tests__/repository-root-identity.test.d.ts +0 -1
  1080. package/dist/core/__tests__/repository-root-identity.test.js +0 -223
  1081. package/dist/core/__tests__/respawn-throttle.test.d.ts +0 -1
  1082. package/dist/core/__tests__/respawn-throttle.test.js +0 -20
  1083. package/dist/core/__tests__/review-model-floor.test.d.ts +0 -1
  1084. package/dist/core/__tests__/review-model-floor.test.js +0 -83
  1085. package/dist/core/__tests__/revive-all.test.d.ts +0 -1
  1086. package/dist/core/__tests__/revive-all.test.js +0 -157
  1087. package/dist/core/__tests__/revive-capacity.test.d.ts +0 -1
  1088. package/dist/core/__tests__/revive-capacity.test.js +0 -184
  1089. package/dist/core/__tests__/revive-parked-fresh.test.d.ts +0 -1
  1090. package/dist/core/__tests__/revive-parked-fresh.test.js +0 -176
  1091. package/dist/core/__tests__/scope-crouter-home-fence.test.d.ts +0 -1
  1092. package/dist/core/__tests__/scope-crouter-home-fence.test.js +0 -55
  1093. package/dist/core/__tests__/seam/broker-attach-multiclient.test.d.ts +0 -1
  1094. package/dist/core/__tests__/seam/broker-attach-multiclient.test.js +0 -262
  1095. package/dist/core/__tests__/seam/broker-attach-stream.test.d.ts +0 -1
  1096. package/dist/core/__tests__/seam/broker-attach-stream.test.js +0 -176
  1097. package/dist/core/__tests__/seam/broker-cap-freeze.test.d.ts +0 -1
  1098. package/dist/core/__tests__/seam/broker-cap-freeze.test.js +0 -155
  1099. package/dist/core/__tests__/seam/broker-crash-teardown.test.d.ts +0 -1
  1100. package/dist/core/__tests__/seam/broker-crash-teardown.test.js +0 -131
  1101. package/dist/core/__tests__/seam/broker-pane-resolution.test.d.ts +0 -1
  1102. package/dist/core/__tests__/seam/broker-pane-resolution.test.js +0 -204
  1103. package/dist/core/__tests__/seam/broker-provider-retry.test.d.ts +0 -1
  1104. package/dist/core/__tests__/seam/broker-provider-retry.test.js +0 -686
  1105. package/dist/core/__tests__/seam/broker-startup-diagnostics.test.d.ts +0 -1
  1106. package/dist/core/__tests__/seam/broker-startup-diagnostics.test.js +0 -82
  1107. package/dist/core/__tests__/seam/broker-whip-interrupt.test.d.ts +0 -1
  1108. package/dist/core/__tests__/seam/broker-whip-interrupt.test.js +0 -50
  1109. package/dist/core/__tests__/seam/deadline-wake-delivery.test.d.ts +0 -1
  1110. package/dist/core/__tests__/seam/deadline-wake-delivery.test.js +0 -138
  1111. package/dist/core/__tests__/seam/dormancy-release.test.d.ts +0 -1
  1112. package/dist/core/__tests__/seam/dormancy-release.test.js +0 -516
  1113. package/dist/core/__tests__/seam/held-deferred-human-prompt.test.d.ts +0 -1
  1114. package/dist/core/__tests__/seam/held-deferred-human-prompt.test.js +0 -65
  1115. package/dist/core/__tests__/seam/inbox-reference-guidance.test.d.ts +0 -1
  1116. package/dist/core/__tests__/seam/inbox-reference-guidance.test.js +0 -84
  1117. package/dist/core/__tests__/seam/memory-slash-node-relative-inventory.test.d.ts +0 -1
  1118. package/dist/core/__tests__/seam/memory-slash-node-relative-inventory.test.js +0 -160
  1119. package/dist/core/__tests__/seam/node-outcome-delivery.test.d.ts +0 -1
  1120. package/dist/core/__tests__/seam/node-outcome-delivery.test.js +0 -177
  1121. package/dist/core/__tests__/seam/prospective-inventory-stdout.test.d.ts +0 -1
  1122. package/dist/core/__tests__/seam/prospective-inventory-stdout.test.js +0 -31
  1123. package/dist/core/__tests__/seam/reopen-invalidated-worktree.test.d.ts +0 -1
  1124. package/dist/core/__tests__/seam/reopen-invalidated-worktree.test.js +0 -60
  1125. package/dist/core/__tests__/seam/self-close-teardown.test.d.ts +0 -1
  1126. package/dist/core/__tests__/seam/self-close-teardown.test.js +0 -49
  1127. package/dist/core/__tests__/seam/yield-refresh-transaction.test.d.ts +0 -1
  1128. package/dist/core/__tests__/seam/yield-refresh-transaction.test.js +0 -100
  1129. package/dist/core/__tests__/secrets.test.d.ts +0 -1
  1130. package/dist/core/__tests__/secrets.test.js +0 -49
  1131. package/dist/core/__tests__/self-update.test.d.ts +0 -1
  1132. package/dist/core/__tests__/self-update.test.js +0 -46
  1133. package/dist/core/__tests__/session-branch.test.d.ts +0 -1
  1134. package/dist/core/__tests__/session-branch.test.js +0 -61
  1135. package/dist/core/__tests__/session-cycles.test.d.ts +0 -1
  1136. package/dist/core/__tests__/session-cycles.test.js +0 -133
  1137. package/dist/core/__tests__/session-model.test.d.ts +0 -1
  1138. package/dist/core/__tests__/session-model.test.js +0 -111
  1139. package/dist/core/__tests__/spawn-worktree-id-conflict.test.d.ts +0 -1
  1140. package/dist/core/__tests__/spawn-worktree-id-conflict.test.js +0 -71
  1141. package/dist/core/__tests__/stdin-body-no-discard.test.d.ts +0 -1
  1142. package/dist/core/__tests__/stdin-body-no-discard.test.js +0 -33
  1143. package/dist/core/__tests__/stdout-errors.test.d.ts +0 -1
  1144. package/dist/core/__tests__/stdout-errors.test.js +0 -16
  1145. package/dist/core/__tests__/stop-guard.test.d.ts +0 -1
  1146. package/dist/core/__tests__/stop-guard.test.js +0 -237
  1147. package/dist/core/__tests__/stream-watchdog.test.d.ts +0 -1
  1148. package/dist/core/__tests__/stream-watchdog.test.js +0 -154
  1149. package/dist/core/__tests__/subscription-pool-credential-guard.test.d.ts +0 -1
  1150. package/dist/core/__tests__/subscription-pool-credential-guard.test.js +0 -95
  1151. package/dist/core/__tests__/tmux-driver-boundary.test.d.ts +0 -1
  1152. package/dist/core/__tests__/tmux-driver-boundary.test.js +0 -50
  1153. package/dist/core/__tests__/warm-claim-preference-snapshot.test.d.ts +0 -1
  1154. package/dist/core/__tests__/warm-claim-preference-snapshot.test.js +0 -54
  1155. package/dist/core/__tests__/worktree-landing.test.d.ts +0 -1
  1156. package/dist/core/__tests__/worktree-landing.test.js +0 -11
  1157. package/dist/core/__tests__/yield-ensures-daemon.test.d.ts +0 -1
  1158. package/dist/core/__tests__/yield-ensures-daemon.test.js +0 -55
  1159. package/dist/core/broker-client/__tests__/transport-relay.test.d.ts +0 -1
  1160. package/dist/core/broker-client/__tests__/transport-relay.test.js +0 -214
  1161. package/dist/core/broker-client/__tests__/transport-socket.test.d.ts +0 -1
  1162. package/dist/core/broker-client/__tests__/transport-socket.test.js +0 -73
  1163. package/dist/core/canvas/__tests__/attention.test.d.ts +0 -1
  1164. package/dist/core/canvas/__tests__/attention.test.js +0 -83
  1165. package/dist/core/canvas/__tests__/history-transcript.test.d.ts +0 -1
  1166. package/dist/core/canvas/__tests__/history-transcript.test.js +0 -102
  1167. package/dist/core/canvas/__tests__/remote-canvas-source.test.d.ts +0 -1
  1168. package/dist/core/canvas/__tests__/remote-canvas-source.test.js +0 -328
  1169. package/dist/core/canvas/__tests__/remote-transport.test.d.ts +0 -1
  1170. package/dist/core/canvas/__tests__/remote-transport.test.js +0 -97
  1171. package/dist/core/canvas/__tests__/render-remote.test.d.ts +0 -1
  1172. package/dist/core/canvas/__tests__/render-remote.test.js +0 -243
  1173. package/dist/core/canvas/__tests__/session-window.test.d.ts +0 -1
  1174. package/dist/core/canvas/__tests__/session-window.test.js +0 -70
  1175. package/dist/core/feed/__tests__/inbox-migrate.test.d.ts +0 -1
  1176. package/dist/core/feed/__tests__/inbox-migrate.test.js +0 -49
  1177. package/dist/core/human/__tests__/page-catalog.test.d.ts +0 -1
  1178. package/dist/core/human/__tests__/page-catalog.test.js +0 -20
  1179. package/dist/core/human/__tests__/page-html-markdown.test.d.ts +0 -1
  1180. package/dist/core/human/__tests__/page-html-markdown.test.js +0 -48
  1181. package/dist/core/human/__tests__/page.test.d.ts +0 -1
  1182. package/dist/core/human/__tests__/page.test.js +0 -92
  1183. package/dist/core/keybindings/__tests__/resolve.test.d.ts +0 -1
  1184. package/dist/core/keybindings/__tests__/resolve.test.js +0 -171
  1185. package/dist/core/profiles/__tests__/env-store.test.d.ts +0 -1
  1186. package/dist/core/profiles/__tests__/env-store.test.js +0 -99
  1187. package/dist/core/profiles/__tests__/fuzzy-match.test.d.ts +0 -1
  1188. package/dist/core/profiles/__tests__/fuzzy-match.test.js +0 -51
  1189. package/dist/core/profiles/__tests__/root-profile.test.d.ts +0 -1
  1190. package/dist/core/profiles/__tests__/root-profile.test.js +0 -59
  1191. package/dist/core/review/__tests__/capture-origin.test.d.ts +0 -1
  1192. package/dist/core/review/__tests__/capture-origin.test.js +0 -150
  1193. package/dist/core/review/__tests__/comments.test.d.ts +0 -1
  1194. package/dist/core/review/__tests__/comments.test.js +0 -116
  1195. package/dist/core/review/__tests__/remap.test.d.ts +0 -1
  1196. package/dist/core/review/__tests__/remap.test.js +0 -177
  1197. package/dist/core/review/__tests__/stage-identity.test.d.ts +0 -1
  1198. package/dist/core/review/__tests__/stage-identity.test.js +0 -150
  1199. package/dist/core/runtime/__tests__/engine-route.test.d.ts +0 -1
  1200. package/dist/core/runtime/__tests__/engine-route.test.js +0 -36
  1201. package/dist/core/runtime/__tests__/install-id-cache-scoping.test.d.ts +0 -1
  1202. package/dist/core/runtime/__tests__/install-id-cache-scoping.test.js +0 -45
  1203. package/dist/core/runtime/__tests__/node-env.test.d.ts +0 -1
  1204. package/dist/core/runtime/__tests__/node-env.test.js +0 -73
  1205. package/dist/core/runtime/__tests__/spawn-env.test.d.ts +0 -1
  1206. package/dist/core/runtime/__tests__/spawn-env.test.js +0 -259
  1207. package/dist/core/substrate/__tests__/surface-match-command.test.d.ts +0 -1
  1208. package/dist/core/substrate/__tests__/surface-match-command.test.js +0 -89
  1209. package/dist/core/substrate/__tests__/surface-match-memory-read.test.d.ts +0 -1
  1210. package/dist/core/substrate/__tests__/surface-match-memory-read.test.js +0 -28
  1211. package/dist/core/substrate/__tests__/surface-match-pre-command.test.d.ts +0 -1
  1212. package/dist/core/substrate/__tests__/surface-match-pre-command.test.js +0 -92
  1213. package/dist/daemon/__tests__/autostart-storm.test.d.ts +0 -1
  1214. package/dist/daemon/__tests__/autostart-storm.test.js +0 -128
  1215. package/dist/daemon/__tests__/broker-ownership.test.d.ts +0 -1
  1216. package/dist/daemon/__tests__/broker-ownership.test.js +0 -25
  1217. package/dist/daemon/__tests__/daemon-ownership.test.d.ts +0 -1
  1218. package/dist/daemon/__tests__/daemon-ownership.test.js +0 -27
  1219. package/dist/daemon/__tests__/helpers/source-daemon.d.ts +0 -30
  1220. package/dist/daemon/__tests__/helpers/source-daemon.js +0 -176
  1221. package/dist/daemon/__tests__/integration/api-startup-readiness.test.d.ts +0 -1
  1222. package/dist/daemon/__tests__/integration/api-startup-readiness.test.js +0 -83
  1223. package/dist/daemon/__tests__/integration/migration-startup.test.d.ts +0 -1
  1224. package/dist/daemon/__tests__/integration/migration-startup.test.js +0 -127
  1225. package/dist/daemon/__tests__/node-deadline-lane.test.d.ts +0 -1
  1226. package/dist/daemon/__tests__/node-deadline-lane.test.js +0 -77
  1227. package/dist/daemon/__tests__/node-outcome-birth-invariants.test.d.ts +0 -1
  1228. package/dist/daemon/__tests__/node-outcome-birth-invariants.test.js +0 -146
  1229. package/dist/daemon/__tests__/node-outcome-delivery.test.d.ts +0 -1
  1230. package/dist/daemon/__tests__/node-outcome-delivery.test.js +0 -116
  1231. package/dist/daemon/__tests__/reconciler-signature.test.d.ts +0 -1
  1232. package/dist/daemon/__tests__/reconciler-signature.test.js +0 -37
  1233. package/dist/daemon/__tests__/subtree-filter-freshness.test.d.ts +0 -1
  1234. package/dist/daemon/__tests__/subtree-filter-freshness.test.js +0 -63
  1235. package/dist/daemon/__tests__/thaw-order.test.d.ts +0 -1
  1236. package/dist/daemon/__tests__/thaw-order.test.js +0 -55
  1237. package/dist/daemon/api/__tests__/bridge-heartbeat.test.d.ts +0 -1
  1238. package/dist/daemon/api/__tests__/bridge-heartbeat.test.js +0 -58
  1239. package/dist/daemon/api/__tests__/broker-settle-park.test.d.ts +0 -1
  1240. package/dist/daemon/api/__tests__/broker-settle-park.test.js +0 -175
  1241. package/dist/daemon/api/__tests__/canvas-snapshot-fields.test.d.ts +0 -1
  1242. package/dist/daemon/api/__tests__/canvas-snapshot-fields.test.js +0 -216
  1243. package/dist/daemon/api/__tests__/error-seam.test.d.ts +0 -1
  1244. package/dist/daemon/api/__tests__/error-seam.test.js +0 -83
  1245. package/dist/daemon/api/__tests__/model-config.test.d.ts +0 -1
  1246. package/dist/daemon/api/__tests__/model-config.test.js +0 -73
  1247. package/dist/daemon/api/__tests__/node-create-description.test.d.ts +0 -1
  1248. package/dist/daemon/api/__tests__/node-create-description.test.js +0 -107
  1249. package/dist/daemon/api/__tests__/node-model-validation.test.d.ts +0 -1
  1250. package/dist/daemon/api/__tests__/node-model-validation.test.js +0 -183
  1251. package/dist/daemon/api/__tests__/nodes-activity-query.test.d.ts +0 -1
  1252. package/dist/daemon/api/__tests__/nodes-activity-query.test.js +0 -99
  1253. package/dist/daemon/api/__tests__/profile-launch-gates.test.d.ts +0 -1
  1254. package/dist/daemon/api/__tests__/profile-launch-gates.test.js +0 -172
  1255. package/dist/daemon/api/__tests__/profile-metadata-route.test.d.ts +0 -1
  1256. package/dist/daemon/api/__tests__/profile-metadata-route.test.js +0 -95
  1257. package/dist/daemon/api/__tests__/reopen-delivery.test.d.ts +0 -1
  1258. package/dist/daemon/api/__tests__/reopen-delivery.test.js +0 -260
  1259. package/dist/daemon/api/__tests__/seam/api-server.test.d.ts +0 -1
  1260. package/dist/daemon/api/__tests__/seam/api-server.test.js +0 -442
  1261. package/dist/daemon/api/__tests__/seam/b10-attach-modelauth.test.d.ts +0 -1
  1262. package/dist/daemon/api/__tests__/seam/b10-attach-modelauth.test.js +0 -310
  1263. package/dist/daemon/api/__tests__/seam/leaf-api-parity.test.d.ts +0 -1
  1264. package/dist/daemon/api/__tests__/seam/leaf-api-parity.test.js +0 -351
  1265. package/dist/daemon/api/__tests__/seam/node-outcome-api.test.d.ts +0 -1
  1266. package/dist/daemon/api/__tests__/seam/node-outcome-api.test.js +0 -159
  1267. package/dist/daemon/api/__tests__/seam/profile-delete.test.d.ts +0 -1
  1268. package/dist/daemon/api/__tests__/seam/profile-delete.test.js +0 -372
  1269. package/dist/daemon/api/__tests__/submit-result.test.d.ts +0 -1
  1270. package/dist/daemon/api/__tests__/submit-result.test.js +0 -215
  1271. package/dist/migrations/__tests__/activation-concurrency.test.d.ts +0 -1
  1272. package/dist/migrations/__tests__/activation-concurrency.test.js +0 -146
  1273. package/dist/migrations/__tests__/activation.test.d.ts +0 -1
  1274. package/dist/migrations/__tests__/activation.test.js +0 -152
  1275. package/dist/migrations/__tests__/deletion-and-root-declaration.test.d.ts +0 -1
  1276. package/dist/migrations/__tests__/deletion-and-root-declaration.test.js +0 -149
  1277. package/dist/pi-extensions/__tests__/canvas-bash-valve.test.d.ts +0 -1
  1278. package/dist/pi-extensions/__tests__/canvas-bash-valve.test.js +0 -86
  1279. package/dist/pi-extensions/__tests__/canvas-context-intro.test.d.ts +0 -1
  1280. package/dist/pi-extensions/__tests__/canvas-context-intro.test.js +0 -364
  1281. package/dist/pi-extensions/__tests__/canvas-goal-capture-envelope.test.d.ts +0 -1
  1282. package/dist/pi-extensions/__tests__/canvas-goal-capture-envelope.test.js +0 -106
  1283. package/dist/pi-extensions/__tests__/canvas-recap.test.d.ts +0 -1
  1284. package/dist/pi-extensions/__tests__/canvas-recap.test.js +0 -62
  1285. package/dist/pi-extensions/__tests__/canvas-stophook-agentend.test.d.ts +0 -1
  1286. package/dist/pi-extensions/__tests__/canvas-stophook-agentend.test.js +0 -432
  1287. package/dist/pi-extensions/__tests__/canvas-stophook-context-nudge.test.d.ts +0 -1
  1288. package/dist/pi-extensions/__tests__/canvas-stophook-context-nudge.test.js +0 -152
  1289. package/dist/pi-extensions/__tests__/canvas-structured-output.test.d.ts +0 -1
  1290. package/dist/pi-extensions/__tests__/canvas-structured-output.test.js +0 -88
  1291. package/dist/pi-extensions/__tests__/canvas-tool-guide.test.d.ts +0 -1
  1292. package/dist/pi-extensions/__tests__/canvas-tool-guide.test.js +0 -96
  1293. package/dist/pi-extensions/__tests__/integration/canvas-bash-valve.test.d.ts +0 -1
  1294. package/dist/pi-extensions/__tests__/integration/canvas-bash-valve.test.js +0 -133
  1295. package/dist/pi-extensions/__tests__/pre-command-gate.test.d.ts +0 -1
  1296. package/dist/pi-extensions/__tests__/pre-command-gate.test.js +0 -232
  1297. package/dist/shared/__tests__/env-boundary.test.d.ts +0 -1
  1298. package/dist/shared/__tests__/env-boundary.test.js +0 -95
  1299. package/dist/shared/__tests__/generated-context-grammar.test.d.ts +0 -1
  1300. package/dist/shared/__tests__/generated-context-grammar.test.js +0 -80
  1301. package/docs/compat/hearth-crtr-v1.md +0 -179
  1302. package/docs/compat/hearth-crtr-v2.md +0 -177
  1303. package/docs/compat/hearth-crtr-v3.md +0 -176
  1304. package/docs/compat/hearth-crtr-v4.md +0 -182
  1305. 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};