@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,1055 +1,3 @@
1
- // render.ts — pure frame rendering for the canvas browser.
2
- //
3
- // renderFrame(state, size, caps) → a full-screen string. The app writes it
4
- // verbatim on every keystroke. Redraw is flicker-free: home the cursor (\x1b[H),
5
- // clear each line to EOL (\x1b[K), and clear below the last line (\x1b[J) so a
6
- // shrunk frame leaves no stale rows. A full frame per keypress is fine for a
7
- // picker.
8
- //
9
- // COLOR is browse-only and *reinforces* the status glyphs (`● ○ ✓ ✗ ⊘`) which
10
- // stay the primary, color-free encoding (colorblind / light-bg / NO_COLOR safe).
11
- // Every hue (fg / bg color) is gated on `caps.color`; structural SGR (bold/dim/
12
- // reverse) is allowed always. See detectColorCaps() for the gate, and the
13
- // canvas-browse color spec for the rationale + palette.
14
- import { STATUS_GLYPH, STATUS_COLOR, isFrozenRow, resolveNodeVisual, faultSummary } from '../status-glyph.js';
15
- import { TABS, promptText, previewSnippet } from './model.js';
16
- import { matchIndices } from '../../tui/fuzzy.js';
17
- // Span/color primitives live in core/tui/draw.ts (one copy, shared with the
18
- // `crtr view` host). Re-export the color caps so browse's importers + tests keep
19
- // resolving them from this module.
20
- import { clip, assemble, detectColorCaps } from '../../tui/draw.js';
21
- import { renderMarkdownSpans } from '../../tui/markdown.js';
22
- export { detectColorCaps };
23
- // Fixed chrome heights, shared with app.ts so its viewport math never drifts
24
- // from what renderFrame actually draws.
25
- // header = title + tab bar + status line + separator (+ search input when searching)
26
- // preview = separator + meta line + PREVIEW_BODY lines of node briefing
27
- // The body budget is FIXED and divided between four blocks at paint time (see
28
- // previewPanel): the two optional blocks (recap, report) take two lines each when
29
- // the node has them, and whatever is left over is split between the two blocks that
30
- // always render (the ask and the reply). A node with neither therefore shows twice
31
- // as much literal conversation instead of half a panel of blanks.
32
- export const RECAP_LINES = 2;
33
- export const REPORT_LINES = 2;
34
- export const PREVIEW_BODY = 8;
35
- export const PREVIEW_HEIGHT = PREVIEW_BODY + 2;
36
- // ── Preview placement ─────────────────────────────────────────────────────────
37
- // A wide terminal gets the preview as a full-height RIGHT-HAND COLUMN: the row
38
- // table drops its flush-right metadata cluster (those per-row facts are noise when
39
- // you only care about the hovered node — they come back as a facts block inside the
40
- // panel) and the reclaimed columns become the panel. A narrow terminal cannot spare
41
- // the columns, so it keeps the bottom panel. The choice is width alone, so there is
42
- // one code path per layout and never two hand-maintained copies of the content.
43
- const SIDE_MIN_COLS = 100; // below this the side column would starve the name column
44
- const SIDE_PANEL_MIN = 46;
45
- const SIDE_PANEL_MAX = 110;
46
- const SIDE_PANEL_RATIO = 0.55;
47
- const SIDE_ROWS_MIN = 40; // the row table never shrinks below this
48
- const SIDE_GUTTER = ' │ '; // rows │ panel — the dim rule that separates them
49
- export function previewLayout(cols, previewOn) {
50
- const width = Math.max(20, cols) - 1; // last column is reserved for \x1b[K
51
- if (!previewOn)
52
- return { mode: 'none', panelW: 0, rowsW: width };
53
- if (cols < SIDE_MIN_COLS)
54
- return { mode: 'bottom', panelW: 0, rowsW: width };
55
- const gutter = [...SIDE_GUTTER].length;
56
- let panelW = Math.min(SIDE_PANEL_MAX, Math.max(SIDE_PANEL_MIN, Math.round(width * SIDE_PANEL_RATIO)));
57
- if (width - panelW - gutter < SIDE_ROWS_MIN)
58
- panelW = width - gutter - SIDE_ROWS_MIN;
59
- if (panelW < SIDE_PANEL_MIN)
60
- return { mode: 'bottom', panelW: 0, rowsW: width };
61
- return { mode: 'side', panelW, rowsW: width - panelW - gutter };
62
- }
63
- // header = title + tab bar + status line + column header + separator (+ input line)
64
- // `inputLine` is true whenever a text-input mode is open (search / rename / message)
65
- // — each adds one prompt row above the column header.
66
- export function headerHeight(inputLine) {
67
- return 5 + (inputLine ? 1 : 0);
68
- }
69
- // ── Row table layout ──────────────────────────────────────────────────────────
70
- // A row is three zones: a fixed-width STATUS rail (glyph + word) on the left, the
71
- // flexible tree-indented NAME in the middle, and a flush-right METADATA cluster
72
- // (kind/mode · ctx · age · project) whose fixed-width segments align into clean
73
- // vertical columns down the right edge. Wide terminals widen the name; narrow ones
74
- // clip the name (and drop the cluster) first. The status WORD — not a lone glyph —
75
- // is the legible, NO_COLOR-safe state signal.
76
- const STATUS_W = 10; // glyph + ' ' + longest word ('active'/'cancel') + trailing gap
77
- const KM_W = 22; // kind/mode column
78
- const CTX_W = 6; // ctx tokens column
79
- const AGE_W = 5; // age column
80
- const PROJ_W = 16; // project (~basename) column, only across All dirs
81
- const COL_GAP = ' ';
82
- // ── ANSI ────────────────────────────────────────────────────────────────────
83
- const ESC = '\x1b[';
84
- const RESET = `${ESC}0m`;
85
- const REVERSE = `${ESC}7m`;
86
- const DIM = `${ESC}2m`;
87
- const BOLD = `${ESC}1m`;
88
- const CURSOR_BG = `${ESC}48;5;236m`; // subtle dark-gray cursor-row bg (256-color)
89
- // Basic-16 ANSI fg codes used by the palette.
90
- const FG_YELLOW = '33';
91
- const FG_RED = '31';
92
- const FG_CYAN = '36';
93
- const FG_GRAY = '90'; // bright-black
94
- const FG_BRIGHT_YELLOW = '93';
95
- const FG_BRIGHT_CYAN = '96'; // query-match highlight (ties to the cyan search accent)
96
- const FG_MAGENTA = '35'; // pin star (distinct from the yellow ⚑ asks flag)
97
- function fmtCtx(tokens) {
98
- if (tokens <= 0)
99
- return '0k';
100
- return `${Math.floor(tokens / 1000)}k`;
101
- }
102
- /** Tiered ctx-budget hue: dim under 50k, yellow 50–100k, red ≥100k. `undefined`
103
- * → dim (structural), so low budgets recede. */
104
- function ctxColorCode(tokens) {
105
- if (tokens >= 100_000)
106
- return FG_RED;
107
- if (tokens >= 50_000)
108
- return FG_YELLOW;
109
- return undefined;
110
- }
111
- /** Compact relative age, e.g. `45s` `12m` `3h` `5d` `2w` `4mo`. Empty on a bad
112
- * timestamp. Drives the per-row recency cue + the preview meta line. */
113
- function relAge(created, now) {
114
- const t = Date.parse(created);
115
- if (Number.isNaN(t))
116
- return '';
117
- const s = Math.max(0, Math.floor((now - t) / 1000));
118
- if (s < 60)
119
- return `${s}s`;
120
- const m = Math.floor(s / 60);
121
- if (m < 60)
122
- return `${m}m`;
123
- const h = Math.floor(m / 60);
124
- if (h < 24)
125
- return `${h}h`;
126
- const d = Math.floor(h / 24);
127
- if (d < 7)
128
- return `${d}d`;
129
- const w = Math.floor(d / 7);
130
- if (w < 5)
131
- return `${w}w`;
132
- return `${Math.floor(d / 30)}mo`;
133
- }
134
- /** Last path segment of a cwd — the project name shown as the All-dirs cue. */
135
- function baseDir(cwd) {
136
- const parts = cwd.replace(/\/+$/, '').split('/');
137
- return parts[parts.length - 1] || cwd;
138
- }
139
- // ── Styled spans ──────────────────────────────────────────────────────────────
140
- //
141
- // A row is built from styled spans, then assembled to a width-clipped line. This
142
- // lets each cell carry its own hue (status glyph, ctx tier, asks, match highlight)
143
- // while clipping by VISIBLE width — ANSI bytes don't count toward the column
144
- // budget. `fg` is hue (gated on `color`); `bold`/`dim` are structural (always).
145
- // Span / styleSpan / assemble now live in core/tui/draw.ts (imported above).
146
- /** Status tallies across the whole canvas, for the right-aligned header. Memoized
147
- * per tree — the snapshot is immutable for a browse session, so counting is done
148
- * once, not O(N) on every keystroke (the "massive canvas" target). */
149
- const summaryCache = new WeakMap();
150
- function statusCounts(tree) {
151
- const cached = summaryCache.get(tree);
152
- if (cached !== undefined)
153
- return cached;
154
- const counts = { active: 0, idle: 0, done: 0, dead: 0, canceled: 0 };
155
- for (const node of tree.nodes.values())
156
- counts[node.row.status]++;
157
- const parts = [];
158
- for (const s of ['active', 'idle', 'done', 'dead', 'canceled']) {
159
- if (counts[s] > 0)
160
- parts.push({ status: s, count: counts[s] });
161
- }
162
- summaryCache.set(tree, parts);
163
- return parts;
164
- }
165
- function tabBar(active, color) {
166
- return TABS.map((t) => {
167
- if (t === active) {
168
- // Keep the [ ] brackets in BOTH paths so the active tab reads without color.
169
- return color ? `${BOLD}${ESC}${FG_CYAN}m[ ${t} ]${RESET}` : `${REVERSE}[ ${t} ]${RESET}`;
170
- }
171
- return color ? `${DIM} ${t} ${RESET}` : ` ${t} `;
172
- }).join('');
173
- }
174
- const EMPTY_HI = new Set();
175
- /** Name → spans, splitting out the query-matched chars (bold + bright-cyan) so
176
- * matches are scannable. Non-matched chars carry the row's name style (dim for
177
- * terminal status, bold on the cursor row). */
178
- function nameSpans(name, query, style) {
179
- const hi = query === '' ? EMPTY_HI : matchIndices(query, name);
180
- if (hi.size === 0)
181
- return [{ text: name, style: { dim: style.dim, bold: style.bold } }];
182
- const out = [];
183
- let buf = '';
184
- let bufHi = false;
185
- const flush = () => {
186
- if (buf === '')
187
- return;
188
- if (bufHi)
189
- out.push({ text: buf, style: { fg: FG_BRIGHT_CYAN, bold: true } });
190
- else
191
- out.push({ text: buf, style: { dim: style.dim, bold: style.bold } });
192
- buf = '';
193
- };
194
- for (let i = 0; i < name.length; i++) {
195
- const h = hi.has(i);
196
- if (h !== bufHi) {
197
- flush();
198
- bufHi = h;
199
- }
200
- buf += name[i];
201
- }
202
- flush();
203
- return out;
204
- }
205
- /** Visible (cell) width of a span group — ANSI-free, surrogate-safe. */
206
- function spansWidth(spans) {
207
- let n = 0;
208
- for (const s of spans)
209
- n += [...s.text].length;
210
- return n;
211
- }
212
- /** The status rail: a status WORD next to its glyph, both in the status hue, padded
213
- * to STATUS_W so the rail forms a clean left column. `live` (bright green) when the
214
- * node is genuinely mid-turn; otherwise the lifecycle word. The word is what makes
215
- * state legible at a glance and survives NO_COLOR (the glyph is the second cue). */
216
- function statusRail(r) {
217
- const v = resolveNodeVisual(r.status, {
218
- streaming: r.streaming === true,
219
- frozen: isFrozenRow(r),
220
- hanging: r.hanging ?? null,
221
- });
222
- // Plain status keeps browse's own status WORD; overlays (hanging/⟳)
223
- // carry their own word from resolveNodeVisual. A hanging kind label can exceed
224
- // STATUS_W — acceptable: the rare, attention-demanding row gets a slightly
225
- // wider rail (Math.max(1,…) keeps a gap), which draws the eye.
226
- const word = v.word ?? ({ active: 'active', idle: 'idle', done: 'done', dead: 'dead', canceled: 'cancel' }[r.status] ?? r.status);
227
- const fg = v.color;
228
- const text = `${v.glyph} ${word}`;
229
- const pad = Math.max(1, STATUS_W - [...text].length);
230
- return [
231
- { text, style: { fg, bold: v.bold === true } },
232
- { text: ' '.repeat(pad) },
233
- ];
234
- }
235
- /** The flush-right metadata cluster as fixed-width segments, so kind/mode · ctx ·
236
- * age · project align into vertical columns down the right edge. `showCwd` adds the
237
- * project column (only meaningful across All dirs). */
238
- function metaCluster(r, now, showCwd) {
239
- const ctxFg = ctxColorCode(r.ctx_tokens);
240
- const out = [
241
- { text: clipPad(`${r.kind}/${r.mode}`, KM_W), style: { fg: FG_GRAY } },
242
- { text: COL_GAP },
243
- { text: fmtCtx(r.ctx_tokens).padStart(CTX_W), style: { fg: ctxFg, dim: ctxFg === undefined } },
244
- { text: COL_GAP },
245
- { text: relAge(r.created, now).padStart(AGE_W), style: { dim: true } },
246
- ];
247
- if (showCwd) {
248
- out.push({ text: COL_GAP }, { text: clipPad(`~${baseDir(r.cwd)}`, PROJ_W), style: { fg: FG_GRAY } });
249
- }
250
- return out;
251
- }
252
- /** Left-clip-pad: clip `s` to `w` cells then pad-end with spaces to exactly `w`. */
253
- function clipPad(s, w) {
254
- return clip(s, w).padEnd(w);
255
- }
256
- /** Compose a row from a flexible LEFT zone and a fixed flush-right RIGHT cluster:
257
- * pad fills the gap so RIGHT hugs the edge; when the terminal is too narrow the
258
- * cluster is dropped rather than colliding with the name. The caller has already
259
- * clipped the name to fit. */
260
- function assembleRow(left, right, width, color, lineBase, fill) {
261
- const leftW = spansWidth(left);
262
- const rightW = spansWidth(right);
263
- if (right.length === 0 || leftW + rightW + 1 > width) {
264
- return assemble(left, width, color, lineBase, fill);
265
- }
266
- const pad = width - leftW - rightW;
267
- return assemble([...left, { text: ' '.repeat(pad) }, ...right], width, color, lineBase, fill);
268
- }
269
- /** One table row: `<status rail> <indent><collapse> <name> <flags>` ........ `<meta>`.
270
- * `showCwd` adds the project column (All-dirs view); `now` drives the age. */
271
- function rowLine(row, tree, width, isCursor, query, caps, showCwd, now, isPinned,
272
- /** false in side-preview mode: the metadata cluster is replaced by the panel's
273
- * facts block, so the name gets the whole row. */
274
- showMeta = true,
275
- /** true in side-preview mode: pad every row to exactly `width` so the vertical
276
- * rule and the panel land in the same columns on every line. */
277
- padToWidth = false) {
278
- const node = tree.nodes.get(row.id);
279
- if (node === undefined)
280
- return '';
281
- const r = node.row;
282
- const indent = ' '.repeat(row.depth);
283
- const collapse = !row.hasChildren ? ' ' : row.collapsed ? '▸' : '▾';
284
- const terminal = r.status === 'done' || r.status === 'dead' || r.status === 'canceled';
285
- // Left gutter (fixed slot): an eye when a viewer is ATTACHED — a scannable rail
286
- // down the left edge of "what's on a screen right now". Blank otherwise.
287
- const gutter = r.viewed === true
288
- ? { text: '\uf06e ', style: { fg: FG_BRIGHT_CYAN, bold: true } }
289
- : { text: ' ' };
290
- // Inline attention flag that travels with the name (fault summary lives in the rail,
291
- // attached lives in the gutter).
292
- const flags = [];
293
- if (r.asks > 0)
294
- flags.push({ text: ` ⚑${r.asks}`, style: { fg: FG_BRIGHT_YELLOW, bold: true } }); // pending asks
295
- // Hanging: the fault summary travels with the name (the ⚠ + kind
296
- // label live in the rail). Dim yellow so it reads as secondary detail.
297
- if (r.hanging != null)
298
- flags.push({ text: ` · ${faultSummary(r.hanging, now)}`, style: { fg: FG_YELLOW, dim: true } });
299
- // Pin marker travels just before the name so a starred node is scannable in any
300
- // tab/sort. Magenta keeps it distinct from the yellow ⚑ asks flag.
301
- const pinMark = isPinned ? [{ text: '★ ', style: { fg: FG_MAGENTA, bold: true } }] : [];
302
- const status = statusRail(r);
303
- const right = showMeta ? metaCluster(r, now, showCwd) : [];
304
- const treeLead = `${indent}${collapse} `;
305
- // Clip the NAME (only) so gutter + status + tree + pin + name + flags + meta all
306
- // fit; the cluster is dropped first (assembleRow) when even a 4-col name won't fit.
307
- const fixed = spansWidth([gutter]) + spansWidth(status) + [...treeLead].length + spansWidth(pinMark) + spansWidth(flags);
308
- const rightW = spansWidth(right);
309
- const nameMax = Math.max(4, width - fixed - rightW - 1);
310
- const nameStyle = { dim: !isCursor && terminal, bold: isCursor }; // dim terminal names; bold the cursor row
311
- const left = [
312
- gutter,
313
- ...status,
314
- { text: treeLead, style: { dim: true } },
315
- ...pinMark,
316
- ...nameSpans(clip(r.name, nameMax), query, nameStyle),
317
- ...flags,
318
- ];
319
- // Row base: cursor → subtle bg (256) or reverse fallback (also !color); non-matched
320
- // ancestor → whole-row dim for tree context.
321
- let lineBase = '';
322
- let fill = padToWidth;
323
- if (isCursor) {
324
- lineBase = caps.color256 ? CURSOR_BG : REVERSE;
325
- fill = true;
326
- }
327
- else if (!row.matched) {
328
- lineBase = DIM;
329
- }
330
- return assembleRow(left, right, width, caps.color, lineBase, fill);
331
- }
332
- /** The column-header row — dim labels aligned to the same zones the rows use, so
333
- * the metadata columns read as a table. */
334
- function columnHeaderLine(width, showCwd, caps, showMeta = true, padToWidth = false) {
335
- const left = [
336
- { text: ' ' }, // viewer gutter (no label)
337
- { text: 'STATUS'.padEnd(STATUS_W), style: { dim: true, bold: true } },
338
- { text: 'NAME', style: { dim: true, bold: true } },
339
- ];
340
- if (!showMeta)
341
- return assemble(left, width, caps.color, '', padToWidth);
342
- const right = [
343
- { text: 'KIND/MODE'.padEnd(KM_W), style: { dim: true, bold: true } },
344
- { text: COL_GAP },
345
- { text: 'CTX'.padStart(CTX_W), style: { dim: true, bold: true } },
346
- { text: COL_GAP },
347
- { text: 'AGE'.padStart(AGE_W), style: { dim: true, bold: true } },
348
- ];
349
- if (showCwd)
350
- right.push({ text: COL_GAP }, { text: 'PROJECT'.padEnd(PROJ_W), style: { dim: true, bold: true } });
351
- return assembleRow(left, right, width, caps.color, '', false);
352
- }
353
- /** The status line (always present): active profile/cwd scopes · sort mode ·
354
- * committed filter. The committed-filter indicator lives here now (not its own
355
- * line) so a filtered view always advertises its query without consuming a header row. */
356
- function statusLine(state) {
357
- const dim = (s) => `${DIM}${s}${RESET}`;
358
- const profile = state.profileScope === undefined ? 'all profiles' : 'current';
359
- const scope = state.cwdScope === null ? 'all dirs' : baseDir(state.cwdScope);
360
- const segs = [
361
- `${dim('profile')} ${profile}`,
362
- `${dim('scope')} ${scope}`,
363
- `${dim('sort')} ${state.sort}`,
364
- `${dim('lifecycle')} ${state.residentsOnly ? 'residents' : 'all'}`,
365
- ];
366
- if (!state.search && state.query !== '')
367
- segs.push(`${dim('filter')} ${state.query}`);
368
- return segs.join(dim(' · '));
369
- }
370
- /** One snippet line → a rendered string with the query-matched columns in bold
371
- * bright-cyan (mirrors the row name highlight). Unmatched text stays default. */
372
- function snippetLine(ln, width, caps, base) {
373
- if (ln.hi.size === 0)
374
- return assemble([{ text: ln.text, style: base }], width, caps.color, '', false);
375
- const spans = [];
376
- let buf = '';
377
- let bufHi = false;
378
- const flush = () => {
379
- if (buf === '')
380
- return;
381
- spans.push(bufHi ? { text: buf, style: { fg: FG_BRIGHT_CYAN, bold: true } } : { text: buf, style: base });
382
- buf = '';
383
- };
384
- for (let i = 0; i < ln.text.length; i++) {
385
- const h = ln.hi.has(i);
386
- if (h !== bufHi) {
387
- flush();
388
- bufHi = h;
389
- }
390
- buf += ln.text[i];
391
- }
392
- flush();
393
- return assemble(spans, width, caps.color, '', false);
394
- }
395
- /** How the fixed PREVIEW_BODY budget is divided for one row: the optional blocks
396
- * take their two lines only when the node actually has them, and the remainder is
397
- * split between the ask and the reply (ask keeps the odd line). */
398
- export function previewAllocation(hasRecap, hasReport) {
399
- const recap = hasRecap ? RECAP_LINES : 0;
400
- const report = hasReport ? REPORT_LINES : 0;
401
- const free = Math.max(2, PREVIEW_BODY - recap - report);
402
- const ask = Math.ceil(free / 2);
403
- return { recap, ask, reply: free - ask, report };
404
- }
405
- /** Render one marked block (`marker` on the first line, aligned continuation after)
406
- * into exactly `lines` rows, or the `empty` placeholder when there is no text. */
407
- function markedBlock(marker, text, empty, lines, width, caps, query) {
408
- if (lines <= 0)
409
- return [];
410
- const out = [];
411
- const mark = caps.color ? `${DIM}${marker}${RESET}` : marker;
412
- const inner = Math.max(1, width - 2);
413
- // No query → render the text as markdown (see blockLines for why a live query
414
- // keeps the raw windowed path instead). No spacing: this panel is cramped.
415
- if (query === '') {
416
- const md = renderMarkdownSpans(text, inner, lines, false);
417
- if (md.length === 0)
418
- out.push(`${mark}${DIM}${clip(empty, inner)}${RESET}`);
419
- else
420
- for (const spans of md)
421
- out.push(`${out.length === 0 ? mark : ' '}${assemble(spans, inner, caps.color, '', false)}`);
422
- while (out.length < lines)
423
- out.push('');
424
- return out;
425
- }
426
- const snippet = previewSnippet(query, text, inner, lines);
427
- if (snippet.length === 0) {
428
- out.push(`${mark}${DIM}${clip(empty, inner)}${RESET}`);
429
- }
430
- else {
431
- for (const ln of snippet)
432
- out.push(`${out.length === 0 ? mark : ' '}${snippetLine(ln, inner, caps)}`);
433
- }
434
- while (out.length < lines)
435
- out.push('');
436
- return out;
437
- }
438
- /** One `Goal`/`State` briefing line: a dim fixed-width label then the text. */
439
- function recapLine(label, text, width, caps) {
440
- const lbl = `${label.padEnd(6)}`;
441
- const body = clip(text, Math.max(1, width - lbl.length));
442
- return caps.color ? `${DIM}${lbl}${RESET}${BOLD}${body}${RESET}` : `${lbl}${body}`;
443
- }
444
- /** The bottom preview panel — exactly PREVIEW_HEIGHT lines, ordered by how fast
445
- * each answers "which node was this, and can I pick it back up?":
446
- *
447
- * separator
448
- * meta status · kind/mode · project · age · ctx · asks · fault/viewing
449
- * Goal/State the node's last persisted recap briefing — the one-glance answer
450
- * ❯ ask the spawn prompt in the user's own words (the recognition anchor),
451
- * or, under a live query, the WINDOWED matching prompt from anywhere
452
- * in the conversation with the match highlighted
453
- * ↩ reply the node's last assistant message — where it actually left off
454
- * ▣ report the newest thing it pushed (age · kind · headline), because a
455
- * resident's reports are written to be read, unlike its live tail
456
- *
457
- * The optional blocks yield their lines to the literal ones when absent, so the
458
- * panel is never padded with blanks. Always full height so viewport math holds. */
459
- function previewPanel(r, width, caps, now, query) {
460
- const out = [`${DIM}${'─'.repeat(width)}${RESET}`];
461
- if (r === undefined) {
462
- while (out.length < PREVIEW_HEIGHT)
463
- out.push('');
464
- return out;
465
- }
466
- const v = resolveNodeVisual(r.status, {
467
- streaming: r.streaming === true,
468
- frozen: isFrozenRow(r),
469
- hanging: r.hanging ?? null,
470
- });
471
- const glyph = caps.color
472
- ? `${ESC}${v.color}m${v.glyph}${RESET}`
473
- : v.glyph;
474
- const metaPieces = [`${r.status} ${r.kind}/${r.mode}`, baseDir(r.cwd), relAge(r.created, now), `ctx ${fmtCtx(r.ctx_tokens)}`];
475
- if (r.asks > 0)
476
- metaPieces.push(`⚑${r.asks}`);
477
- if (r.hanging != null)
478
- metaPieces.push(faultSummary(r.hanging, now));
479
- if (r.streaming === true)
480
- metaPieces.push('⟳');
481
- if (r.viewed === true)
482
- metaPieces.push('\uf06e viewing');
483
- const metaText = clip(metaPieces.filter((p) => p !== '').join(' · '), Math.max(0, width - 2));
484
- out.push(caps.color ? `${glyph} ${DIM}${metaText}${RESET}` : `${glyph} ${metaText}`);
485
- const alloc = previewAllocation(r.recap !== undefined, r.report !== undefined);
486
- // Goal / State — the generated briefing, the fastest "what is this and where is
487
- // it" in the panel. Absent for a node that never idled long enough to make one.
488
- if (r.recap !== undefined) {
489
- out.push(recapLine('Goal', r.recap.goal === '' ? '—' : r.recap.goal, width, caps));
490
- out.push(recapLine('State', r.recap.state === '' ? '—' : r.recap.state, width, caps));
491
- }
492
- // The ask, verbatim. Under a live query this becomes the windowed match from the
493
- // WHOLE conversation (the one thing a search result must show), so it keeps the
494
- // query highlight; with no query it is the spawn prompt from the start.
495
- const askText = query !== '' ? promptText(r) : (r.goal ?? '');
496
- out.push(...markedBlock('❯ ', askText, '(no spawn prompt)', alloc.ask, width, caps, query));
497
- // Where it left off.
498
- out.push(...markedBlock('↩ ', r.lastAssistant ?? '', '(no reply yet)', alloc.reply, width, caps, ''));
499
- // What it last delivered. The stamp + kind lead the line because a report's value
500
- // here is "how recently did this node report, and was that its final?".
501
- if (r.report !== undefined) {
502
- const age = relAge(r.report.ts, now);
503
- const stamp = `${age === '' ? '' : `${age} `}${r.report.kind}`;
504
- const headline = r.report.heading === '' ? r.report.body : r.report.heading;
505
- const mark = caps.color ? `${DIM}▣ ${RESET}` : '▣ ';
506
- const inner = Math.max(1, width - 2);
507
- const stampText = caps.color ? `${ESC}${FG_CYAN}m${stamp}${RESET}${DIM} · ${RESET}` : `${stamp} · `;
508
- out.push(`${mark}${stampText}${clip(headline, Math.max(1, inner - stamp.length - 3))}`);
509
- for (let i = 1; i < alloc.report; i++) {
510
- const detail = r.report.heading === '' ? '' : r.report.body;
511
- const ln = previewSnippet('', detail, inner, alloc.report - 1)[i - 1];
512
- out.push(ln === undefined ? '' : ` ${DIM}${clip(ln.text, inner)}${RESET}`);
513
- }
514
- }
515
- return out;
516
- }
517
- // ── The side preview panel ────────────────────────────────────────────────────
518
- //
519
- // Same four zones as the bottom panel (recap · ask · reply · report) with room to
520
- // breathe, drawn as designed chrome instead of a wall of prose:
521
- //
522
- // <title row, drawn on the column-header line> ★ node name 8-char id
523
- // ● active ⚑2 asks viewing ← state, in the status hue
524
- // kind general/base ctx 42k ← facts block: dim right-aligned
525
- // proj ~northlight age 3h labels, values in their own hues
526
- // ── GOAL ───────────────────────────── ← hairline + small-caps label
527
- // ▌ what this conversation is for ← accent bar: the hero quote
528
- // ── ASK ──────────────────────────────
529
- // ❯ the spawn prompt, hanging-indented
530
- //
531
- // Section bodies are allocated from the panel's real height: everyone asks for a
532
- // natural size, the largest gives a line back until it fits, and only then does the
533
- // least-valuable section drop out entirely (report → state → goal → reply; the ask
534
- // is the recognition anchor and never drops).
535
- /** A dim hairline with a small-caps section label — `── GOAL ────────`. The optional
536
- * suffix rides after the label in its own hue (the report's age · kind stamp). */
537
- function sectionRule(label, width, caps, suffix) {
538
- const suf = suffix === undefined ? '' : `${suffix.text} `;
539
- const tail = Math.max(0, width - 4 - label.length - suf.length);
540
- const sufStyled = suffix === undefined
541
- ? ''
542
- : caps.color ? `${ESC}${suffix.fg}m${suffix.text}${RESET}${DIM} ` : `${suffix.text} `;
543
- return `${DIM}── ${BOLD}${label}${RESET}${DIM} ${sufStyled}${'─'.repeat(tail)}${RESET}`;
544
- }
545
- /** A marked body block with a hanging indent: `marker` leads the first line, `cont`
546
- * every wrapped line after it (`▌ ` keeps the accent bar running down a quote).
547
- * Returns the lines it actually filled — never padded, so the panel stacks tight.
548
- * `empty` renders a dim placeholder for a block that must show even when absent. */
549
- function blockLines(marker, cont, markerStyle, text, empty, maxLines, width, caps, query, bodyStyle) {
550
- if (maxLines <= 0)
551
- return [];
552
- const indent = [...marker].length;
553
- const inner = Math.max(1, width - indent);
554
- const mk = (s, st) => assemble([{ text: s, style: st }], indent, caps.color, '', true);
555
- // The ONE case that stays raw: under a live query the ask shows the windowed
556
- // match with the matched columns highlighted, and stripping `**` would shift
557
- // every later column out from under the highlight. Everything else renders
558
- // markdown — headings, lists, and emphasis are how these messages were written.
559
- if (query === '') {
560
- const md = renderMarkdownSpans(text, inner, maxLines, true, bodyStyle);
561
- if (md.length === 0) {
562
- if (empty === undefined)
563
- return [];
564
- return [`${mk(marker, markerStyle)}${DIM}${clip(empty, inner)}${RESET}`];
565
- }
566
- return md.map((spans, i) => `${mk(i === 0 ? marker : cont, markerStyle)}${assemble(spans, inner, caps.color, '', false)}`);
567
- }
568
- const snippet = previewSnippet(query, text, inner, maxLines);
569
- if (snippet.length === 0) {
570
- if (empty === undefined)
571
- return [];
572
- return [`${mk(marker, markerStyle)}${DIM}${clip(empty, inner)}${RESET}`];
573
- }
574
- return snippet.map((ln, i) => `${mk(i === 0 ? marker : cont, markerStyle)}${snippetLine(ln, inner, caps, bodyStyle)}`);
575
- }
576
- // ── The chat transcript ───────────────────────────────────────────────
577
- //
578
- // The panel's centrepiece: the node's conversation painted the way the attach viewer
579
- // paints it — a coloured left bar per turn, a small-caps role label, and the message
580
- // body with its markdown honoured. It serves two jobs from one renderer:
581
- //
582
- // no query — the RECENT tail, newest turn last, so the panel reads as "where did
583
- // this conversation get to".
584
- // a query — only the turns that CONTAIN the query, oldest match first, with every
585
- // occurrence highlighted and the skipped turns counted in a dim elision
586
- // marker. Every visible line is then evidence for the search.
587
- /** Rendered lines a single turn may occupy before it is windowed. Bounded by the
588
- * per-message cap in readTranscript, so this is a ceiling, not a budget. */
589
- const TURN_RENDER_MAX = 400;
590
- /** Rendered lines kept above the first match when a matched turn must be windowed. */
591
- const TURN_MATCH_LEAD = 1;
592
- /** Lines a single turn may take when several turns share the panel. */
593
- const TURN_SOFT_CAP = 14;
594
- /** The matched-run style. `reverse` is structural SGR, so a search match stays
595
- * visible with hue disabled — which the fg-only row highlight cannot manage. */
596
- const MATCH_STYLE = { fg: FG_BRIGHT_CYAN, bold: true, reverse: true };
597
- function spansText(spans) {
598
- let out = '';
599
- for (const s of spans)
600
- out += s.text;
601
- return out;
602
- }
603
- /** Re-style every case-insensitive occurrence of `query` inside already-rendered
604
- * spans, splitting runs at the match edges. Working on the RENDERED text is what
605
- * lets a transcript keep its markdown and still highlight: the markup is already
606
- * gone, so no column can drift out from under a highlight. */
607
- export function highlightSpans(spans, query) {
608
- if (query === '')
609
- return { spans, hits: 0 };
610
- const text = spansText(spans);
611
- const lower = text.toLowerCase();
612
- const q = query.toLowerCase();
613
- if (lower.indexOf(q) < 0)
614
- return { spans, hits: 0 };
615
- const hi = new Uint8Array(text.length);
616
- let hits = 0;
617
- for (let i = lower.indexOf(q); i >= 0; i = lower.indexOf(q, i + q.length)) {
618
- hits++;
619
- for (let j = i; j < i + q.length; j++)
620
- hi[j] = 1;
621
- }
622
- const out = [];
623
- let col = 0;
624
- for (const s of spans) {
625
- let buf = '';
626
- let bufHi = hi[col] === 1;
627
- for (let k = 0; k < s.text.length; k++) {
628
- const h = hi[col] === 1;
629
- if (h !== bufHi) {
630
- if (buf !== '')
631
- out.push({ text: buf, style: bufHi ? MATCH_STYLE : s.style });
632
- buf = '';
633
- bufHi = h;
634
- }
635
- buf += s.text[k];
636
- col++;
637
- }
638
- if (buf !== '')
639
- out.push({ text: buf, style: bufHi ? MATCH_STYLE : s.style });
640
- }
641
- return { spans: out, hits };
642
- }
643
- const TURN_BAR = '▌ ';
644
- /** Paint one turn: `▌ YOU` / `▌ AGENT` then the body, every line carrying the bar so
645
- * a turn stays one contiguous block. The user's bar is the cyan accent and the
646
- * agent's is dim gray — the same weight distinction the row table already uses
647
- * between what you said and what the runtime produced. */
648
- function turnBlock(turn, query, maxLines, width, caps) {
649
- if (maxLines < 2)
650
- return { lines: [], hits: 0, truncated: true };
651
- const user = turn.role === 'user';
652
- const barStyle = user ? { fg: FG_BRIGHT_CYAN, bold: true } : { fg: FG_GRAY };
653
- const inner = Math.max(1, width - TURN_BAR.length);
654
- const bar = () => assemble([{ text: TURN_BAR, style: barStyle }], TURN_BAR.length, caps.color, '', true);
655
- const out = [
656
- assemble([{ text: TURN_BAR, style: barStyle }, { text: user ? 'YOU' : 'AGENT', style: { ...barStyle, bold: true } }], width, caps.color, '', false),
657
- ];
658
- const body = renderMarkdownSpans(turn.text, inner, TURN_RENDER_MAX, false, user ? {} : { dim: true });
659
- const marked = body.map((spans) => highlightSpans(spans, query));
660
- const hits = marked.reduce((n, m) => n + m.hits, 0);
661
- // Window the body when it outgrows its slice of the panel. Searching, the window
662
- // opens on the first match (that is the only line the search has to prove); idle,
663
- // it opens at the top of the message.
664
- const budget = maxLines - 1;
665
- let start = 0;
666
- if (marked.length > budget && hits > 0) {
667
- start = Math.max(0, marked.findIndex((m) => m.hits > 0) - TURN_MATCH_LEAD);
668
- start = Math.min(start, marked.length - budget);
669
- }
670
- const shown = marked.slice(start, start + budget);
671
- for (const m of shown)
672
- out.push(`${bar()}${assemble(m.spans, inner, caps.color, '', false)}`);
673
- // An honest edge: a windowed body must not read as the whole message. The marker
674
- // costs a body line, so it is only worth drawing when a body line survives it.
675
- const cutHead = start > 0;
676
- const cutTail = start + shown.length < marked.length;
677
- if (cutHead && shown.length > 1)
678
- out[1] = `${bar()}${DIM}⋯${RESET}`;
679
- if (cutTail && shown.length > (cutHead ? 2 : 1))
680
- out[out.length - 1] = `${bar()}${DIM}⋯${RESET}`;
681
- return { lines: out, hits, truncated: cutHead || cutTail };
682
- }
683
- /** The dim `⋯ n turns` marker standing in for turns the search skipped over. */
684
- function elisionLine(n, width, caps) {
685
- return assemble([{ text: ` ⋯ ${n} ${n === 1 ? 'turn' : 'turns'}`, style: { dim: true } }], width, caps.color, '', false);
686
- }
687
- /** Does this turn contain the query as a literal, case-insensitive substring?
688
- * Scattered letters are not a transcript hit — the same rule the row preview uses. */
689
- function turnMatches(turn, query) {
690
- return query !== '' && turn.text.toLowerCase().indexOf(query.toLowerCase()) >= 0;
691
- }
692
- /** How many turns contain the query — the count the section rule advertises. */
693
- export function transcriptHitTurns(turns, query) {
694
- return turns.reduce((n, t) => n + (turnMatches(t, query) ? 1 : 0), 0);
695
- }
696
- /** The transcript body, at most `height` lines. With a query it shows the matching
697
- * turns from the oldest match forward; without one it shows the newest turns,
698
- * bottom-anchored so the latest turn is the last line — the chat reading order. */
699
- function transcriptLines(turns, query, width, height, caps) {
700
- if (height <= 0 || turns.length === 0)
701
- return [];
702
- const hitIdx = query === '' ? [] : turns.map((t, i) => (turnMatches(t, query) ? i : -1)).filter((i) => i >= 0);
703
- // Searching with hits: forward from the oldest match, eliding the gaps.
704
- if (hitIdx.length > 0) {
705
- const out = [];
706
- let prev = -1;
707
- for (const i of hitIdx) {
708
- const lead = out.length === 0 ? 0 : 1; // blank separator between turns
709
- const left = height - out.length - lead;
710
- if (left < 3)
711
- break; // a header over one elision marker proves nothing
712
- const { lines } = turnBlock(turns[i], query, Math.min(left, TURN_SOFT_CAP), width, caps);
713
- if (lines.length === 0)
714
- break;
715
- const gap = prev < 0 ? i : i - prev - 1;
716
- const marker = gap > 0 && out.length + lead + lines.length + 1 <= height;
717
- if (lead > 0)
718
- out.push('');
719
- if (marker)
720
- out.push(elisionLine(gap, width, caps));
721
- out.push(...lines);
722
- prev = i;
723
- }
724
- // Slack goes to the turns that FOLLOW the last match, painted in full, so the
725
- // panel reads on as a conversation instead of stopping dead at the evidence.
726
- let last = prev;
727
- for (let i = prev + 1; i < turns.length; i++) {
728
- const left = height - out.length - 1;
729
- if (left < 3)
730
- break;
731
- const { lines, truncated } = turnBlock(turns[i], query, Math.min(left, TURN_SOFT_CAP), width, caps);
732
- if (lines.length === 0 || truncated)
733
- break;
734
- out.push('', ...lines);
735
- last = i;
736
- }
737
- if (last >= 0 && last < turns.length - 1 && out.length < height) {
738
- out.push(elisionLine(turns.length - 1 - last, width, caps));
739
- }
740
- return out.slice(0, height);
741
- }
742
- // No query (or a query that only matched the node's name/kind/id): the tail.
743
- // Built newest-first so the budget is spent on recent turns, then reversed.
744
- const blocks = [];
745
- let used = 0;
746
- for (let i = turns.length - 1; i >= 0; i--) {
747
- const newest = blocks.length === 0;
748
- const lead = newest ? 0 : 1;
749
- const left = height - used - lead;
750
- if (left < 3)
751
- break;
752
- const { lines, truncated } = turnBlock(turns[i], '', Math.min(left, TURN_SOFT_CAP), width, caps);
753
- if (lines.length === 0)
754
- break;
755
- // Only the newest turn may be shown cut — an older one that no longer fits is
756
- // dropped whole rather than left as a header over an elision marker, which
757
- // reads as a message the panel refused to show.
758
- if (truncated && !newest)
759
- break;
760
- if (lead > 0)
761
- blocks.push(['']);
762
- blocks.push(lines);
763
- used += lines.length + lead;
764
- }
765
- return blocks.reverse().flat().slice(-height);
766
- }
767
- /** What an empty panel body MEANS. `(no conversation yet)` is a claim about the
768
- * node; it is only true once the session has actually been read. Until then the
769
- * same blank body means the read is still in flight, and printing the claim made a
770
- * node the panel had simply not gotten to yet look like a node that had never
771
- * spoken. */
772
- function emptyBodyNote(r) {
773
- const read = r.transcriptLoaded === true || r.previewLoaded === true;
774
- return read ? `${DIM}(no conversation yet)${RESET}` : `${DIM}(loading…)${RESET}`;
775
- }
776
- /** The turns the panel paints. A node that was never revived has no session, so its
777
- * spawn prompt and last reply stand in — the panel then still reads as a chat
778
- * rather than going blank, and a remote canvas (no local session file) keeps a body. */
779
- function panelTurns(r) {
780
- const t = r.transcript;
781
- if (t !== undefined && t.length > 0)
782
- return t;
783
- const out = [];
784
- if (r.goal !== undefined && r.goal !== '')
785
- out.push({ role: 'user', text: r.goal });
786
- if (r.lastAssistant !== undefined && r.lastAssistant !== '')
787
- out.push({ role: 'assistant', text: r.lastAssistant });
788
- return out;
789
- }
790
- /** Lines the GOAL and STATE briefings each get. They are one-sentence summaries by
791
- * construction, so a small fixed budget leaves the chat everything else. */
792
- const BRIEFING_LINES = 4;
793
- /** The panel's one metadata line. Deliberately ONE line: the row the cursor sits on
794
- * already carries this node's status word, ask flag, fault and viewer cues, so a
795
- * status line and a four-cell facts grid here would spend six of the panel's rows
796
- * repeating what is on screen a few columns to the left. What is left is what the
797
- * row table gave up in side mode — kind/mode, project, age, ctx. */
798
- function panelFactsLine(r, width, now, caps) {
799
- const ctxFg = ctxColorCode(r.ctx_tokens);
800
- const dot = () => ({ text: ' · ', style: { dim: true } });
801
- const spans = [
802
- { text: `${r.kind}/${r.mode}`, style: { fg: FG_GRAY } },
803
- dot(),
804
- { text: `~${baseDir(r.cwd)}`, style: { fg: FG_GRAY } },
805
- dot(),
806
- { text: relAge(r.created, now), style: { dim: true } },
807
- dot(),
808
- { text: `ctx ${fmtCtx(r.ctx_tokens)}`, style: { fg: ctxFg, dim: ctxFg === undefined } },
809
- ];
810
- return assemble(spans, width, caps.color, '', false);
811
- }
812
- /** The panel's title, drawn on the column-header row so the header rule crosses
813
- * beneath it: the pinned star, the node name in bold, its short id flush right. */
814
- function panelTitleLine(r, width, caps, isPinned) {
815
- if (r === undefined)
816
- return assemble([{ text: 'PREVIEW', style: { dim: true, bold: true } }], width, caps.color, '', false);
817
- const left = [];
818
- if (isPinned)
819
- left.push({ text: '★ ', style: { fg: FG_MAGENTA, bold: true } });
820
- const id = r.node_id.slice(0, 8);
821
- left.push({ text: clip(r.name, Math.max(4, width - id.length - 2 - spansWidth(left))), style: { bold: true } });
822
- return assembleRow(left, [{ text: id, style: { dim: true } }], width, caps.color, '', false);
823
- }
824
- /** The side panel's body, at most `height` lines. Three exclusive shapes:
825
- *
826
- * searching — the panel IS a chat transcript: the turns that literally contain
827
- * the query, oldest match first, every occurrence highlighted.
828
- * report — the node's newest pushed report in full (toggled with `V`).
829
- * default — goal on top, the recent conversation in the middle, state pinned to
830
- * the bottom edge. That is the vertical order the live chat surface
831
- * uses, so the preview reads as a small copy of the conversation it
832
- * is previewing instead of a different presentation of the same node.
833
- */
834
- function sidePanelBody(r, width, height, caps, now, query, showReport) {
835
- if (height <= 0)
836
- return [];
837
- if (r === undefined)
838
- return [`${DIM}(no selection)${RESET}`];
839
- // ── searching ── the transcript takes the whole panel. The goal/state briefing is
840
- // a summary, and a summary cannot show you WHERE your term appears.
841
- if (query !== '') {
842
- const turns = panelTurns(r);
843
- const hits = transcriptHitTurns(turns, query);
844
- const out = [sectionRule('TRANSCRIPT', width, caps, hits > 0
845
- ? { text: `${hits} ${hits === 1 ? 'turn' : 'turns'}`, fg: FG_BRIGHT_CYAN }
846
- : { text: 'matched on name', fg: FG_GRAY })];
847
- const body = transcriptLines(turns, query, width, height - 1, caps);
848
- out.push(...(body.length === 0 ? [emptyBodyNote(r)] : body));
849
- return out.slice(0, height);
850
- }
851
- const rep = r.report;
852
- const accentOf = () => {
853
- const v = resolveNodeVisual(r.status, {
854
- streaming: r.streaming === true, frozen: isFrozenRow(r), hanging: r.hanging ?? null,
855
- });
856
- return { fg: v.color };
857
- };
858
- // ── report ── what the node deliberately DELIVERED, at full length. Reports are
859
- // written to be read, so this one gets the panel rather than a two-line teaser.
860
- if (showReport && rep !== undefined) {
861
- const age = relAge(rep.ts, now);
862
- const out = [sectionRule('REPORT', width, caps, { text: `${age === '' ? '' : `${age} · `}${rep.kind}`, fg: FG_CYAN })];
863
- const headline = rep.heading === '' ? rep.body : rep.heading;
864
- out.push(...blockLines('▣ ', ' ', { fg: FG_CYAN, bold: true }, headline, undefined, 3, width, caps, '', { bold: true }));
865
- if (rep.heading !== '' && rep.body !== '') {
866
- out.push('');
867
- out.push(...blockLines(' ', ' ', undefined, rep.body, undefined, height - out.length, width, caps, ''));
868
- }
869
- return out.slice(0, height);
870
- }
871
- // ── default ── goal, chat, state.
872
- const out = [panelFactsLine(r, width, now, caps), ''];
873
- const accent = accentOf();
874
- const briefing = (label, text) => [
875
- sectionRule(label, width, caps),
876
- ...blockLines('▌ ', '▌ ', accent, text, undefined, BRIEFING_LINES, width, caps, '', { bold: true }),
877
- ];
878
- const goal = r.recap?.goal ?? '';
879
- if (goal !== '')
880
- out.push(...briefing('GOAL', goal), '');
881
- // State is measured before the chat is drawn so the chat can claim exactly the
882
- // slack that is left and state still lands on the panel's bottom edge.
883
- const stateText = r.recap?.state ?? '';
884
- const stateBlock = stateText === '' ? [] : [...briefing('STATE', stateText)];
885
- const reserved = stateBlock.length === 0 ? 0 : stateBlock.length + 1;
886
- const chatH = height - out.length - reserved - 1 /* the CHAT rule */;
887
- if (chatH >= 2) {
888
- out.push(sectionRule('CHAT', width, caps));
889
- const body = transcriptLines(panelTurns(r), '', width, chatH, caps);
890
- out.push(...(body.length === 0 ? [emptyBodyNote(r)] : body));
891
- }
892
- if (stateBlock.length > 0) {
893
- while (out.length < height - stateBlock.length)
894
- out.push('');
895
- out.push(...stateBlock);
896
- }
897
- return out.slice(0, height);
898
- }
899
- /** The keybinding help overlay — a full-screen cheatsheet that replaces the body
900
- * while `?` is held open. Grouped by intent so the whole key surface is legible in
901
- * one glance (the footer only ever advertises the common few). */
902
- const HELP_ROWS = [
903
- ['Move', '↑/↓ j/k', 'up / down'],
904
- ['', 'g / G', 'top / bottom'],
905
- ['', '.', 'jump to this node (recenter)'],
906
- ['Tree', '→/← h/l', 'expand / collapse'],
907
- ['', 'space', 'toggle fold'],
908
- ['Tabs', 'Tab / 1-5', 'All · Live · Dormant · Attention · Pinned'],
909
- ['Find', '/', 'fuzzy search (name · kind · id · prompts)'],
910
- ['Pin', 'p', 'star / unstar — floats to top, Pinned tab'],
911
- ['Open', '⏎ o', 'open conversation (closes navigator)'],
912
- ['', 'O', 'open, keep browsing (background)'],
913
- ['Act', 'y', 'copy the node id to the clipboard'],
914
- ['', 'm', 'message the node (no resume)'],
915
- ['', 'R', 'rename the node'],
916
- ['', 'x', 'close-out node + subtree'],
917
- ['', 'K', 'revive now (a hanging node)'],
918
- ['View', 's', 'cycle sort (attention/tree/relevance/recency)'],
919
- ['', 'c', 'toggle cwd scope'],
920
- ['', 'P', 'toggle profile scope'],
921
- ['', 'r', 'toggle residents-only'],
922
- ['', 'v', 'toggle preview (goal, chat, state)'],
923
- ['', 'V', 'in the preview: swap chat for the newest report'],
924
- ['Quit', 'q / Esc', ''],
925
- ];
926
- function renderHelp(size, caps) {
927
- const cols = Math.max(20, size.cols);
928
- const rows = Math.max(8, size.rows);
929
- const width = cols - 1;
930
- const lines = [];
931
- lines.push(`${BOLD}Canvas navigator — keys${RESET}`);
932
- lines.push('');
933
- const dim = (s) => `${DIM}${s}${RESET}`;
934
- for (const [group, keys, desc] of HELP_ROWS) {
935
- const g = group.padEnd(6);
936
- const k = keys.padEnd(12);
937
- const line = ` ${dim(g)}${BOLD}${k}${RESET}${desc === '' ? '' : ` ${dim(desc)}`}`;
938
- lines.push(clip(line, width));
939
- }
940
- lines.push('');
941
- lines.push(dim(' ? or any key to close'));
942
- while (lines.length < rows - 1)
943
- lines.push('');
944
- const body = lines.map((l) => `${l}${ESC}K`).join('\r\n');
945
- return `${ESC}H${body}${ESC}J`;
946
- }
947
- /**
948
- * Render the whole frame. Returns a single string that, written as-is, repaints
949
- * the screen in place. `caps` gates all hue (defaults to a no-color frame so
950
- * existing callers / non-TTY paths stay color-free).
951
- */
952
- export function renderFrame(state, size, caps = { color: false, color256: false }) {
953
- if (state.help === true)
954
- return renderHelp(size, caps);
955
- const cols = Math.max(20, size.cols);
956
- const rows = Math.max(8, size.rows);
957
- const width = cols - 1; // leave the last column for \x1b[K
958
- const now = Date.now();
959
- const inputMode = state.search || state.rename === true || state.message === true;
960
- const lines = [];
961
- // line 1 — title + right-aligned status summary (each glyph in its status hue).
962
- const title = `${BOLD}Canvas${RESET} — ${state.totalNodes} nodes`;
963
- const titlePlainLen = `Canvas — ${state.totalNodes} nodes`.length;
964
- const parts = statusCounts(state.tree);
965
- const summaryPlain = parts.map((p) => `${STATUS_GLYPH[p.status]}${p.count}`).join(' ');
966
- const summaryColored = caps.color
967
- ? parts.map((p) => `${ESC}${STATUS_COLOR[p.status]}m${STATUS_GLYPH[p.status]}${RESET}${DIM}${p.count}${RESET}`).join(' ')
968
- : `${DIM}${summaryPlain}${RESET}`;
969
- const gap = width - titlePlainLen - summaryPlain.length;
970
- lines.push(gap > 1 ? `${title}${' '.repeat(gap)}${summaryColored}` : title);
971
- // line 2 — tab bar.
972
- lines.push(tabBar(state.tab, caps.color));
973
- // line 3 — status line (scope · sort · filter).
974
- lines.push(statusLine(state));
975
- // line 4 — the text-input prompt, only while a search / rename / message is open.
976
- if (inputMode) {
977
- const prefix = state.rename === true ? 'rename ▸' : state.message === true ? 'msg ▸' : '/';
978
- const buf = state.rename === true ? (state.renameBuf ?? '') : state.message === true ? (state.messageBuf ?? '') : state.query;
979
- const p = caps.color ? `${ESC}${FG_CYAN}m${prefix}${RESET}` : prefix;
980
- lines.push(`${p} ${buf}▎`);
981
- }
982
- // Where the preview goes at this width: a full-height right-hand column when
983
- // there is room for one, else the bottom panel. In side mode the rows give up
984
- // their metadata cluster and the panel takes those columns.
985
- const previewOn = state.preview && state.visible.length > 0;
986
- const layout = previewLayout(cols, previewOn);
987
- const side = layout.mode === 'side';
988
- const rowsW = side ? layout.rowsW : width;
989
- const gutter = `${DIM}${SIDE_GUTTER}${RESET}`;
990
- const sel = state.visible[state.cursor];
991
- const selRow = sel !== undefined ? state.tree.nodes.get(sel.id)?.row : undefined;
992
- // column header (table labels, plus the panel title in side mode) + separator.
993
- const showCwd = state.cwdScope === null && !side; // project column only matters across dirs
994
- const colHeader = columnHeaderLine(rowsW, showCwd, caps, !side, side);
995
- lines.push(side
996
- ? `${colHeader}${gutter}${panelTitleLine(selRow, layout.panelW, caps, sel !== undefined && state.pinned.has(sel.id))}`
997
- : colHeader);
998
- lines.push(side
999
- ? `${DIM}${'─'.repeat(rowsW)}─┼─${'─'.repeat(layout.panelW)}${RESET}`
1000
- : `${DIM}${'─'.repeat(width)}${RESET}`);
1001
- // body — windowed visible rows, leaving room for the (optional) bottom panel.
1002
- const head = lines.length; // === headerHeight(state.search)
1003
- const previewH = layout.mode === 'bottom' ? PREVIEW_HEIGHT : 0;
1004
- const viewport = Math.max(1, rows - head - 1 /* footer */ - previewH);
1005
- const start = state.scrollOffset;
1006
- const end = Math.min(state.visible.length, start + viewport);
1007
- // In side mode each body line is `<row><rule><panel line>`, so the rows are padded
1008
- // to an exact width and the panel body is rendered once for the whole column.
1009
- const panel = side ? sidePanelBody(selRow, layout.panelW, viewport, caps, now, state.query, state.showReport === true) : [];
1010
- const compose = (row, i) => (side ? `${row}${gutter}${panel[i] ?? ''}` : row);
1011
- const blankRow = side ? ' '.repeat(rowsW) : '';
1012
- if (state.visible.length === 0) {
1013
- lines.push(`${DIM} (no nodes match this view)${RESET}`);
1014
- for (let i = 1; i < viewport; i++)
1015
- lines.push('');
1016
- }
1017
- else {
1018
- for (let i = start; i < end; i++) {
1019
- const vr = state.visible[i];
1020
- lines.push(compose(rowLine(vr, state.tree, rowsW, i === state.cursor, state.query, caps, showCwd, now, state.pinned.has(vr.id), !side, side), i - start));
1021
- }
1022
- for (let i = end - start; i < viewport; i++)
1023
- lines.push(compose(blankRow, i));
1024
- }
1025
- // bottom preview panel — the narrow-terminal layout.
1026
- if (layout.mode === 'bottom') {
1027
- for (const l of previewPanel(selRow, width, caps, now, state.query))
1028
- lines.push(l);
1029
- }
1030
- // footer — the y/n close-out confirm takes over when pending; else search / nav.
1031
- if (state.pendingClose !== null && state.pendingClose !== undefined) {
1032
- const node = state.tree.nodes.get(state.pendingClose);
1033
- const who = node !== undefined ? node.row.name : state.pendingClose;
1034
- const warn = `⚠ ${who} is ⟳ — close it (and its subtree) anyway? y / n`;
1035
- lines.push(caps.color ? `${BOLD}${ESC}${FG_BRIGHT_YELLOW}m${clip(warn, width)}${RESET}` : `${REVERSE}${clip(warn, width)}${RESET}`);
1036
- }
1037
- else if (state.flash !== null && state.flash !== undefined && state.flash !== '') {
1038
- lines.push(caps.color ? `${BOLD}${clip(state.flash, width)}${RESET}` : `${REVERSE}${clip(state.flash, width)}${RESET}`);
1039
- }
1040
- else {
1041
- // When the cursor row has an active fault, lead the footer with the on-demand kick
1042
- // hint (K shells `node lifecycle revive <id> --now` — immediate revive instead of
1043
- // waiting for the daemon's retry schedule).
1044
- const hangingHint = selRow?.hanging != null ? 'K revive now ' : '';
1045
- const footer = inputMode
1046
- ? '⏎ commit Esc cancel ⌫ delete'
1047
- : state.readOnly === true
1048
- ? '↑↓ move →/← tree / search p pin v preview Tab tabs ? more q quit — read-only remote canvas'
1049
- : `${hangingHint}${selRow?.report !== undefined && side && state.query === '' ? (state.showReport === true ? 'V chat ' : 'V report ') : ''}↑↓ move ⏎ open O bg / search p pin v preview m msg x close ? more q quit`;
1050
- lines.push(`${DIM}${clip(footer, width)}${RESET}`);
1051
- }
1052
- // Assemble: home, each line cleared to EOL, then clear below.
1053
- const body = lines.map((l) => `${l}${ESC}K`).join('\r\n');
1054
- return `${ESC}H${body}${ESC}J`;
1055
- }
1
+ var Nt=Object.defineProperty;var f=(t,n)=>Nt(t,"name",{value:n,configurable:!0});import{STATUS_GLYPH as rt,STATUS_COLOR as It,isFrozenRow as J,resolveNodeVisual as X,faultSummary as lt}from"../status-glyph.js";import{TABS as Pt,promptText as Ht,previewSnippet as q}from"./model.js";import{matchIndices as Gt}from"../../tui/fuzzy.js";import{clip as _,assemble as w,detectColorCaps as Dt}from"../../tui/draw.js";import{renderMarkdownSpans as Q}from"../../tui/markdown.js";const Bt=2,Ft=2,ct=8,it=ct+2,Ut=100,ut=46,jt=110,Yt=.55,at=40,dt=" \u2502 ";function Vt(t,n){const e=Math.max(20,t)-1;if(!n)return{mode:"none",panelW:0,rowsW:e};if(t<Ut)return{mode:"bottom",panelW:0,rowsW:e};const s=[...dt].length;let r=Math.min(jt,Math.max(ut,Math.round(e*Yt)));return e-r-s<at&&(r=e-s-at),r<ut?{mode:"bottom",panelW:0,rowsW:e}:{mode:"side",panelW:r,rowsW:e-r-s}}f(Vt,"previewLayout");function Me(t){return 5+(t?1:0)}f(Me,"headerHeight");const ft=10,$t=22,ht=6,pt=5,gt=16,W=" ",M="\x1B[",$=`${M}0m`,U=`${M}7m`,y=`${M}2m`,C=`${M}1m`,Kt=`${M}48;5;236m`,mt="33",zt="31",H="36",N="90",xt="93",I="96",bt="35";function Z(t){return t<=0?"0k":`${Math.floor(t/1e3)}k`}f(Z,"fmtCtx");function yt(t){if(t>=1e5)return zt;if(t>=5e4)return mt}f(yt,"ctxColorCode");function G(t,n){const e=Date.parse(t);if(Number.isNaN(e))return"";const s=Math.max(0,Math.floor((n-e)/1e3));if(s<60)return`${s}s`;const r=Math.floor(s/60);if(r<60)return`${r}m`;const o=Math.floor(r/60);if(o<24)return`${o}h`;const u=Math.floor(o/24);if(u<7)return`${u}d`;const i=Math.floor(u/7);return i<5?`${i}w`:`${Math.floor(u/30)}mo`}f(G,"relAge");function j(t){const n=t.replace(/\/+$/,"").split("/");return n[n.length-1]||t}f(j,"baseDir");const vt=new WeakMap;function Jt(t){const n=vt.get(t);if(n!==void 0)return n;const e={active:0,idle:0,done:0,dead:0,canceled:0};for(const r of t.nodes.values())e[r.row.status]++;const s=[];for(const r of["active","idle","done","dead","canceled"])e[r]>0&&s.push({status:r,count:e[r]});return vt.set(t,s),s}f(Jt,"statusCounts");function Xt(t,n){return Pt.map(e=>e===t?n?`${C}${M}${H}m[ ${e} ]${$}`:`${U}[ ${e} ]${$}`:n?`${y} ${e} ${$}`:` ${e} `).join("")}f(Xt,"tabBar");const qt=new Set;function Qt(t,n,e){const s=n===""?qt:Gt(n,t);if(s.size===0)return[{text:t,style:{dim:e.dim,bold:e.bold}}];const r=[];let o="",u=!1;const i=f(()=>{o!==""&&(u?r.push({text:o,style:{fg:I,bold:!0}}):r.push({text:o,style:{dim:e.dim,bold:e.bold}}),o="")},"flush");for(let l=0;l<t.length;l++){const c=s.has(l);c!==u&&(i(),u=c),o+=t[l]}return i(),r}f(Qt,"nameSpans");function L(t){let n=0;for(const e of t)n+=[...e.text].length;return n}f(L,"spansWidth");function Zt(t){const n=X(t.status,{streaming:t.streaming===!0,frozen:J(t),hanging:t.hanging??null}),e=n.word??{active:"active",idle:"idle",done:"done",dead:"dead",canceled:"cancel"}[t.status]??t.status,s=n.color,r=`${n.glyph} ${e}`,o=Math.max(1,ft-[...r].length);return[{text:r,style:{fg:s,bold:n.bold===!0}},{text:" ".repeat(o)}]}f(Zt,"statusRail");function te(t,n,e){const s=yt(t.ctx_tokens),r=[{text:Et(`${t.kind}/${t.mode}`,$t),style:{fg:N}},{text:W},{text:Z(t.ctx_tokens).padStart(ht),style:{fg:s,dim:s===void 0}},{text:W},{text:G(t.created,n).padStart(pt),style:{dim:!0}}];return e&&r.push({text:W},{text:Et(`~${j(t.cwd)}`,gt),style:{fg:N}}),r}f(te,"metaCluster");function Et(t,n){return _(t,n).padEnd(n)}f(Et,"clipPad");function tt(t,n,e,s,r,o){const u=L(t),i=L(n);if(n.length===0||u+i+1>e)return w(t,e,s,r,o);const l=e-u-i;return w([...t,{text:" ".repeat(l)},...n],e,s,r,o)}f(tt,"assembleRow");function ee(t,n,e,s,r,o,u,i,l,c=!0,h=!1){const a=n.nodes.get(t.id);if(a===void 0)return"";const d=a.row,b=" ".repeat(t.depth),m=t.hasChildren?t.collapsed?"\u25B8":"\u25BE":" ",E=d.status==="done"||d.status==="dead"||d.status==="canceled",v=d.viewed===!0?{text:"\uF06E ",style:{fg:I,bold:!0}}:{text:" "},p=[];d.asks>0&&p.push({text:` \u2691${d.asks}`,style:{fg:xt,bold:!0}}),d.hanging!=null&&p.push({text:` \xB7 ${lt(d.hanging,i)}`,style:{fg:mt,dim:!0}});const x=l?[{text:"\u2605 ",style:{fg:bt,bold:!0}}]:[],T=Zt(d),R=c?te(d,i,u):[],A=`${b}${m} `,D=L([v])+L(T)+[...A].length+L(x)+L(p),B=L(R),K=Math.max(4,e-D-B-1),z={dim:!s&&E,bold:s},O=[v,...T,{text:A,style:{dim:!0}},...x,...Qt(_(d.name,K),r,z),...p];let k="",P=h;return s?(k=o.color256?Kt:U,P=!0):t.matched||(k=y),tt(O,R,e,o.color,k,P)}f(ee,"rowLine");function ne(t,n,e,s=!0,r=!1){const o=[{text:" "},{text:"STATUS".padEnd(ft),style:{dim:!0,bold:!0}},{text:"NAME",style:{dim:!0,bold:!0}}];if(!s)return w(o,t,e.color,"",r);const u=[{text:"KIND/MODE".padEnd($t),style:{dim:!0,bold:!0}},{text:W},{text:"CTX".padStart(ht),style:{dim:!0,bold:!0}},{text:W},{text:"AGE".padStart(pt),style:{dim:!0,bold:!0}}];return n&&u.push({text:W},{text:"PROJECT".padEnd(gt),style:{dim:!0,bold:!0}}),tt(o,u,t,e.color,"",!1)}f(ne,"columnHeaderLine");function oe(t){const n=f(o=>`${y}${o}${$}`,"dim"),e=t.profileScope===void 0?"all profiles":"current",s=t.cwdScope===null?"all dirs":j(t.cwdScope),r=[`${n("profile")} ${e}`,`${n("scope")} ${s}`,`${n("sort")} ${t.sort}`,`${n("lifecycle")} ${t.residentsOnly?"residents":"all"}`];return!t.search&&t.query!==""&&r.push(`${n("filter")} ${t.query}`),r.join(n(" \xB7 "))}f(oe,"statusLine");function Mt(t,n,e,s){if(t.hi.size===0)return w([{text:t.text,style:s}],n,e.color,"",!1);const r=[];let o="",u=!1;const i=f(()=>{o!==""&&(r.push(u?{text:o,style:{fg:I,bold:!0}}:{text:o,style:s}),o="")},"flush");for(let l=0;l<t.text.length;l++){const c=t.hi.has(l);c!==u&&(i(),u=c),o+=t.text[l]}return i(),w(r,n,e.color,"",!1)}f(Mt,"snippetLine");function se(t,n){const e=t?Bt:0,s=n?Ft:0,r=Math.max(2,ct-e-s),o=Math.ceil(r/2);return{recap:e,ask:o,reply:r-o,report:s}}f(se,"previewAllocation");function _t(t,n,e,s,r,o,u){if(s<=0)return[];const i=[],l=o.color?`${y}${t}${$}`:t,c=Math.max(1,r-2);if(u===""){const a=Q(n,c,s,!1);if(a.length===0)i.push(`${l}${y}${_(e,c)}${$}`);else for(const d of a)i.push(`${i.length===0?l:" "}${w(d,c,o.color,"",!1)}`);for(;i.length<s;)i.push("");return i}const h=q(u,n,c,s);if(h.length===0)i.push(`${l}${y}${_(e,c)}${$}`);else for(const a of h)i.push(`${i.length===0?l:" "}${Mt(a,c,o)}`);for(;i.length<s;)i.push("");return i}f(_t,"markedBlock");function Tt(t,n,e,s){const r=`${t.padEnd(6)}`,o=_(n,Math.max(1,e-r.length));return s.color?`${y}${r}${$}${C}${o}${$}`:`${r}${o}`}f(Tt,"recapLine");function re(t,n,e,s,r){const o=[`${y}${"\u2500".repeat(n)}${$}`];if(t===void 0){for(;o.length<it;)o.push("");return o}const u=X(t.status,{streaming:t.streaming===!0,frozen:J(t),hanging:t.hanging??null}),i=e.color?`${M}${u.color}m${u.glyph}${$}`:u.glyph,l=[`${t.status} ${t.kind}/${t.mode}`,j(t.cwd),G(t.created,s),`ctx ${Z(t.ctx_tokens)}`];t.asks>0&&l.push(`\u2691${t.asks}`),t.hanging!=null&&l.push(lt(t.hanging,s)),t.streaming===!0&&l.push("\u27F3"),t.viewed===!0&&l.push("\uF06E viewing");const c=_(l.filter(d=>d!=="").join(" \xB7 "),Math.max(0,n-2));o.push(e.color?`${i} ${y}${c}${$}`:`${i} ${c}`);const h=se(t.recap!==void 0,t.report!==void 0);t.recap!==void 0&&(o.push(Tt("Goal",t.recap.goal===""?"\u2014":t.recap.goal,n,e)),o.push(Tt("State",t.recap.state===""?"\u2014":t.recap.state,n,e)));const a=r!==""?Ht(t):t.goal??"";if(o.push(..._t("\u276F ",a,"(no spawn prompt)",h.ask,n,e,r)),o.push(..._t("\u21A9 ",t.lastAssistant??"","(no reply yet)",h.reply,n,e,"")),t.report!==void 0){const d=G(t.report.ts,s),b=`${d===""?"":`${d} `}${t.report.kind}`,m=t.report.heading===""?t.report.body:t.report.heading,E=e.color?`${y}\u25A3 ${$}`:"\u25A3 ",v=Math.max(1,n-2),p=e.color?`${M}${H}m${b}${$}${y} \xB7 ${$}`:`${b} \xB7 `;o.push(`${E}${p}${_(m,Math.max(1,v-b.length-3))}`);for(let x=1;x<h.report;x++){const T=t.report.heading===""?"":t.report.body,R=q("",T,v,h.report-1)[x-1];o.push(R===void 0?"":` ${y}${_(R.text,v)}${$}`)}}return o}f(re,"previewPanel");function Y(t,n,e,s){const r=s===void 0?"":`${s.text} `,o=Math.max(0,n-4-t.length-r.length),u=s===void 0?"":e.color?`${M}${s.fg}m${s.text}${$}${y} `:`${s.text} `;return`${y}\u2500\u2500 ${C}${t}${$}${y} ${u}${"\u2500".repeat(o)}${$}`}f(Y,"sectionRule");function et(t,n,e,s,r,o,u,i,l,c){if(o<=0)return[];const h=[...t].length,a=Math.max(1,u-h),d=f((m,E)=>w([{text:m,style:E}],h,i.color,"",!0),"mk");if(l===""){const m=Q(s,a,o,!0,c);return m.length===0?r===void 0?[]:[`${d(t,e)}${y}${_(r,a)}${$}`]:m.map((E,v)=>`${d(v===0?t:n,e)}${w(E,a,i.color,"",!1)}`)}const b=q(l,s,a,o);return b.length===0?r===void 0?[]:[`${d(t,e)}${y}${_(r,a)}${$}`]:b.map((m,E)=>`${d(E===0?t:n,e)}${Mt(m,a,i,c)}`)}f(et,"blockLines");const le=400,ce=1,nt=14,wt={fg:I,bold:!0,reverse:!0};function ie(t){let n="";for(const e of t)n+=e.text;return n}f(ie,"spansText");function ue(t,n){if(n==="")return{spans:t,hits:0};const e=ie(t),s=e.toLowerCase(),r=n.toLowerCase();if(s.indexOf(r)<0)return{spans:t,hits:0};const o=new Uint8Array(e.length);let u=0;for(let c=s.indexOf(r);c>=0;c=s.indexOf(r,c+r.length)){u++;for(let h=c;h<c+r.length;h++)o[h]=1}const i=[];let l=0;for(const c of t){let h="",a=o[l]===1;for(let d=0;d<c.text.length;d++){const b=o[l]===1;b!==a&&(h!==""&&i.push({text:h,style:a?wt:c.style}),h="",a=b),h+=c.text[d],l++}h!==""&&i.push({text:h,style:a?wt:c.style})}return{spans:i,hits:u}}f(ue,"highlightSpans");const V="\u258C ";function ot(t,n,e,s,r){if(e<2)return{lines:[],hits:0,truncated:!0};const o=t.role==="user",u=o?{fg:I,bold:!0}:{fg:N},i=Math.max(1,s-V.length),l=f(()=>w([{text:V,style:u}],V.length,r.color,"",!0),"bar"),c=[w([{text:V,style:u},{text:o?"YOU":"AGENT",style:{...u,bold:!0}}],s,r.color,"",!1)],a=Q(t.text,i,le,!1,o?{}:{dim:!0}).map(x=>ue(x,n)),d=a.reduce((x,T)=>x+T.hits,0),b=e-1;let m=0;a.length>b&&d>0&&(m=Math.max(0,a.findIndex(x=>x.hits>0)-ce),m=Math.min(m,a.length-b));const E=a.slice(m,m+b);for(const x of E)c.push(`${l()}${w(x.spans,i,r.color,"",!1)}`);const v=m>0,p=m+E.length<a.length;return v&&E.length>1&&(c[1]=`${l()}${y}\u22EF${$}`),p&&E.length>(v?2:1)&&(c[c.length-1]=`${l()}${y}\u22EF${$}`),{lines:c,hits:d,truncated:v||p}}f(ot,"turnBlock");function Rt(t,n,e){return w([{text:` \u22EF ${t} ${t===1?"turn":"turns"}`,style:{dim:!0}}],n,e.color,"",!1)}f(Rt,"elisionLine");function St(t,n){return n!==""&&t.text.toLowerCase().indexOf(n.toLowerCase())>=0}f(St,"turnMatches");function ae(t,n){return t.reduce((e,s)=>e+(St(s,n)?1:0),0)}f(ae,"transcriptHitTurns");function At(t,n,e,s,r){if(s<=0||t.length===0)return[];const o=n===""?[]:t.map((l,c)=>St(l,n)?c:-1).filter(l=>l>=0);if(o.length>0){const l=[];let c=-1;for(const a of o){const d=l.length===0?0:1,b=s-l.length-d;if(b<3)break;const{lines:m}=ot(t[a],n,Math.min(b,nt),e,r);if(m.length===0)break;const E=c<0?a:a-c-1,v=E>0&&l.length+d+m.length+1<=s;d>0&&l.push(""),v&&l.push(Rt(E,e,r)),l.push(...m),c=a}let h=c;for(let a=c+1;a<t.length;a++){const d=s-l.length-1;if(d<3)break;const{lines:b,truncated:m}=ot(t[a],n,Math.min(d,nt),e,r);if(b.length===0||m)break;l.push("",...b),h=a}return h>=0&&h<t.length-1&&l.length<s&&l.push(Rt(t.length-1-h,e,r)),l.slice(0,s)}const u=[];let i=0;for(let l=t.length-1;l>=0;l--){const c=u.length===0,h=c?0:1,a=s-i-h;if(a<3)break;const{lines:d,truncated:b}=ot(t[l],"",Math.min(a,nt),e,r);if(d.length===0||b&&!c)break;h>0&&u.push([""]),u.push(d),i+=d.length+h}return u.reverse().flat().slice(-s)}f(At,"transcriptLines");function kt(t){return t.transcriptLoaded===!0||t.previewLoaded===!0?`${y}(no conversation yet)${$}`:`${y}(loading\u2026)${$}`}f(kt,"emptyBodyNote");function Ct(t){const n=t.transcript;if(n!==void 0&&n.length>0)return n;const e=[];return t.goal!==void 0&&t.goal!==""&&e.push({role:"user",text:t.goal}),t.lastAssistant!==void 0&&t.lastAssistant!==""&&e.push({role:"assistant",text:t.lastAssistant}),e}f(Ct,"panelTurns");const de=4;function fe(t,n,e,s){const r=yt(t.ctx_tokens),o=f(()=>({text:" \xB7 ",style:{dim:!0}}),"dot"),u=[{text:`${t.kind}/${t.mode}`,style:{fg:N}},o(),{text:`~${j(t.cwd)}`,style:{fg:N}},o(),{text:G(t.created,e),style:{dim:!0}},o(),{text:`ctx ${Z(t.ctx_tokens)}`,style:{fg:r,dim:r===void 0}}];return w(u,n,s.color,"",!1)}f(fe,"panelFactsLine");function $e(t,n,e,s){if(t===void 0)return w([{text:"PREVIEW",style:{dim:!0,bold:!0}}],n,e.color,"",!1);const r=[];s&&r.push({text:"\u2605 ",style:{fg:bt,bold:!0}});const o=t.node_id.slice(0,8);return r.push({text:_(t.name,Math.max(4,n-o.length-2-L(r))),style:{bold:!0}}),tt(r,[{text:o,style:{dim:!0}}],n,e.color,"",!1)}f($e,"panelTitleLine");function he(t,n,e,s,r,o,u){if(e<=0)return[];if(t===void 0)return[`${y}(no selection)${$}`];if(o!==""){const p=Ct(t),x=ae(p,o),T=[Y("TRANSCRIPT",n,s,x>0?{text:`${x} ${x===1?"turn":"turns"}`,fg:I}:{text:"matched on name",fg:N})],R=At(p,o,n,e-1,s);return T.push(...R.length===0?[kt(t)]:R),T.slice(0,e)}const i=t.report,l=f(()=>({fg:X(t.status,{streaming:t.streaming===!0,frozen:J(t),hanging:t.hanging??null}).color}),"accentOf");if(u&&i!==void 0){const p=G(i.ts,r),x=[Y("REPORT",n,s,{text:`${p===""?"":`${p} \xB7 `}${i.kind}`,fg:H})],T=i.heading===""?i.body:i.heading;return x.push(...et("\u25A3 "," ",{fg:H,bold:!0},T,void 0,3,n,s,"",{bold:!0})),i.heading!==""&&i.body!==""&&(x.push(""),x.push(...et(" "," ",void 0,i.body,void 0,e-x.length,n,s,""))),x.slice(0,e)}const c=[fe(t,n,r,s),""],h=l(),a=f((p,x)=>[Y(p,n,s),...et("\u258C ","\u258C ",h,x,void 0,de,n,s,"",{bold:!0})],"briefing"),d=t.recap?.goal??"";d!==""&&c.push(...a("GOAL",d),"");const b=t.recap?.state??"",m=b===""?[]:[...a("STATE",b)],E=m.length===0?0:m.length+1,v=e-c.length-E-1;if(v>=2){c.push(Y("CHAT",n,s));const p=At(Ct(t),"",n,v,s);c.push(...p.length===0?[kt(t)]:p)}if(m.length>0){for(;c.length<e-m.length;)c.push("");c.push(...m)}return c.slice(0,e)}f(he,"sidePanelBody");const pe=[["Move","\u2191/\u2193 j/k","up / down"],["","g / G","top / bottom"],["",".","jump to this node (recenter)"],["Tree","\u2192/\u2190 h/l","expand / collapse"],["","space","toggle fold"],["Tabs","Tab / 1-5","All \xB7 Live \xB7 Dormant \xB7 Attention \xB7 Pinned"],["Find","/","fuzzy search (name \xB7 kind \xB7 id \xB7 prompts)"],["Pin","p","star / unstar \u2014 floats to top, Pinned tab"],["Open","\u23CE o","open conversation (closes navigator)"],["","O","open, keep browsing (background)"],["Act","y","copy the node id to the clipboard"],["","m","message the node (no resume)"],["","R","rename the node"],["","x","close-out node + subtree"],["","K","revive now (a hanging node)"],["View","s","cycle sort (attention/tree/relevance/recency)"],["","c","toggle cwd scope"],["","P","toggle profile scope"],["","r","toggle residents-only"],["","v","toggle preview (goal, chat, state)"],["","V","in the preview: swap chat for the newest report"],["Quit","q / Esc",""]];function ge(t,n){const e=Math.max(20,t.cols),s=Math.max(8,t.rows),r=e-1,o=[];o.push(`${C}Canvas navigator \u2014 keys${$}`),o.push("");const u=f(l=>`${y}${l}${$}`,"dim");for(const[l,c,h]of pe){const a=l.padEnd(6),d=c.padEnd(12),b=` ${u(a)}${C}${d}${$}${h===""?"":` ${u(h)}`}`;o.push(_(b,r))}for(o.push(""),o.push(u(" ? or any key to close"));o.length<s-1;)o.push("");const i=o.map(l=>`${l}${M}K`).join(`\r
2
+ `);return`${M}H${i}${M}J`}f(ge,"renderHelp");function _e(t,n,e={color:!1,color256:!1}){if(t.help===!0)return ge(n,e);const s=Math.max(20,n.cols),r=Math.max(8,n.rows),o=s-1,u=Date.now(),i=t.search||t.rename===!0||t.message===!0,l=[],c=`${C}Canvas${$} \u2014 ${t.totalNodes} nodes`,h=`Canvas \u2014 ${t.totalNodes} nodes`.length,a=Jt(t.tree),d=a.map(g=>`${rt[g.status]}${g.count}`).join(" "),b=e.color?a.map(g=>`${M}${It[g.status]}m${rt[g.status]}${$}${y}${g.count}${$}`).join(" "):`${y}${d}${$}`,m=o-h-d.length;if(l.push(m>1?`${c}${" ".repeat(m)}${b}`:c),l.push(Xt(t.tab,e.color)),l.push(oe(t)),i){const g=t.rename===!0?"rename \u25B8":t.message===!0?"msg \u25B8":"/",S=t.rename===!0?t.renameBuf??"":t.message===!0?t.messageBuf??"":t.query,F=e.color?`${M}${H}m${g}${$}`:g;l.push(`${F} ${S}\u258E`)}const E=t.preview&&t.visible.length>0,v=Vt(s,E),p=v.mode==="side",x=p?v.rowsW:o,T=`${y}${dt}${$}`,R=t.visible[t.cursor],A=R!==void 0?t.tree.nodes.get(R.id)?.row:void 0,D=t.cwdScope===null&&!p,B=ne(x,D,e,!p,p);l.push(p?`${B}${T}${$e(A,v.panelW,e,R!==void 0&&t.pinned.has(R.id))}`:B),l.push(p?`${y}${"\u2500".repeat(x)}\u2500\u253C\u2500${"\u2500".repeat(v.panelW)}${$}`:`${y}${"\u2500".repeat(o)}${$}`);const K=l.length,z=v.mode==="bottom"?it:0,O=Math.max(1,r-K-1-z),k=t.scrollOffset,P=Math.min(t.visible.length,k+O),Lt=p?he(A,v.panelW,O,e,u,t.query,t.showReport===!0):[],st=f((g,S)=>p?`${g}${T}${Lt[S]??""}`:g,"compose"),Ot=p?" ".repeat(x):"";if(t.visible.length===0){l.push(`${y} (no nodes match this view)${$}`);for(let g=1;g<O;g++)l.push("")}else{for(let g=k;g<P;g++){const S=t.visible[g];l.push(st(ee(S,t.tree,x,g===t.cursor,t.query,e,D,u,t.pinned.has(S.id),!p,p),g-k))}for(let g=P-k;g<O;g++)l.push(st(Ot,g))}if(v.mode==="bottom")for(const g of re(A,o,e,u,t.query))l.push(g);if(t.pendingClose!==null&&t.pendingClose!==void 0){const g=t.tree.nodes.get(t.pendingClose),F=`\u26A0 ${g!==void 0?g.row.name:t.pendingClose} is \u27F3 \u2014 close it (and its subtree) anyway? y / n`;l.push(e.color?`${C}${M}${xt}m${_(F,o)}${$}`:`${U}${_(F,o)}${$}`)}else if(t.flash!==null&&t.flash!==void 0&&t.flash!=="")l.push(e.color?`${C}${_(t.flash,o)}${$}`:`${U}${_(t.flash,o)}${$}`);else{const g=A?.hanging!=null?"K revive now ":"",S=i?"\u23CE commit Esc cancel \u232B delete":t.readOnly===!0?"\u2191\u2193 move \u2192/\u2190 tree / search p pin v preview Tab tabs ? more q quit \u2014 read-only remote canvas":`${g}${A?.report!==void 0&&p&&t.query===""?t.showReport===!0?"V chat ":"V report ":""}\u2191\u2193 move \u23CE open O bg / search p pin v preview m msg x close ? more q quit`;l.push(`${y}${_(S,o)}${$}`)}const Wt=l.map(g=>`${g}${M}K`).join(`\r
3
+ `);return`${M}H${Wt}${M}J`}f(_e,"renderFrame");export{ct as PREVIEW_BODY,it as PREVIEW_HEIGHT,Bt as RECAP_LINES,Ft as REPORT_LINES,Dt as detectColorCaps,Me as headerHeight,ue as highlightSpans,se as previewAllocation,Vt as previewLayout,_e as renderFrame,ae as transcriptHitTurns};