@north-light/crouter 0.3.173 → 0.3.175

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 (674) hide show
  1. package/bin/runtime-selector.mjs +8 -1
  2. package/dist/api/__tests__/{client.test.js → serial/client.test.js} +2 -135
  3. package/dist/api/client.d.ts +12 -21
  4. package/dist/api/client.js +22 -31
  5. package/dist/api/dto/broker-ops.d.ts +158 -0
  6. package/dist/api/dto/broker-ops.js +6 -0
  7. package/dist/api/dto/crons.d.ts +6 -0
  8. package/dist/api/dto/human.d.ts +7 -1
  9. package/dist/api/dto/inbox.d.ts +1 -71
  10. package/dist/api/dto/inbox.js +1 -9
  11. package/dist/api/dto/nodes.d.ts +6 -7
  12. package/dist/api/dto/reviews.d.ts +1 -11
  13. package/dist/api/routes.d.ts +7 -4
  14. package/dist/api/routes.js +8 -5
  15. package/dist/build-root.js +3 -3
  16. package/dist/builtin-memory/04-base-worker.md +1 -4
  17. package/dist/builtin-memory/05-kinds/advisor/00-base.md +1 -5
  18. package/dist/builtin-memory/05-kinds/advisor/01-orchestrator.md +2 -7
  19. package/dist/builtin-memory/05-kinds/design/00-base.md +1 -6
  20. package/dist/builtin-memory/05-kinds/developer/00-base.md +1 -6
  21. package/dist/builtin-memory/05-kinds/explore/00-base.md +1 -4
  22. package/dist/builtin-memory/05-kinds/explore/01-orchestrator.md +1 -2
  23. package/dist/builtin-memory/05-kinds/general/00-base.md +1 -3
  24. package/dist/builtin-memory/05-kinds/plan/00-base.md +1 -6
  25. package/dist/builtin-memory/05-kinds/plan/reviewers/00-base.md +1 -2
  26. package/dist/builtin-memory/05-kinds/plan/reviewers/architecture-fit.md +1 -3
  27. package/dist/builtin-memory/05-kinds/plan/reviewers/code-smells.md +1 -3
  28. package/dist/builtin-memory/05-kinds/plan/reviewers/pattern-consistency.md +1 -3
  29. package/dist/builtin-memory/05-kinds/plan/reviewers/requirements-coverage.md +1 -3
  30. package/dist/builtin-memory/05-kinds/plan/reviewers/security.md +1 -4
  31. package/dist/builtin-memory/05-kinds/review/companion/00-base.md +2 -3
  32. package/dist/builtin-memory/05-kinds/spec/00-base.md +1 -2
  33. package/dist/builtin-memory/advisor/council.md +1 -6
  34. package/dist/builtin-memory/design.md +2 -7
  35. package/dist/builtin-memory/development.md +9 -14
  36. package/dist/builtin-memory/internal/marketplaces.md +2 -6
  37. package/dist/builtin-memory/internal/nodes-and-canvas.md +1 -1
  38. package/dist/builtin-memory/internal/plugins.md +2 -8
  39. package/dist/builtin-memory/internal/storage-tiers.md +1 -2
  40. package/dist/builtin-memory/testing.md +41 -0
  41. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/__tests__/{provider-rotation.test.ts → serial/provider-rotation.test.ts} +27 -179
  42. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/claude-plugin-commands.ts +5 -15
  43. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/frontmatter-rules/index.ts +1 -28
  44. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/memory-slash-commands.ts +43 -88
  45. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.js +7 -1
  46. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.ts +9 -1
  47. package/dist/cli.js +2 -2
  48. package/dist/clients/attach/__tests__/attach-remote-readonly.test.js +37 -131
  49. package/dist/clients/attach/__tests__/chat-view-snapshot-ordering.test.js +71 -152
  50. package/dist/clients/attach/__tests__/context-message.test.js +16 -174
  51. package/dist/clients/attach/__tests__/crtr-output.test.js +36 -2069
  52. package/dist/clients/attach/__tests__/diagram.test.js +2 -2
  53. package/dist/clients/attach/__tests__/edit-diff.test.js +0 -4
  54. package/dist/clients/attach/__tests__/file-review-focus.test.js +2 -1
  55. package/dist/clients/attach/__tests__/group-activity.test.js +40 -229
  56. package/dist/clients/attach/__tests__/oauth-dialog-lifecycle.test.js +26 -76
  57. package/dist/clients/attach/__tests__/prompt-preview.test.js +4 -70
  58. package/dist/clients/attach/__tests__/ref-autocomplete.test.js +11 -125
  59. package/dist/clients/attach/__tests__/titled-editor-preview.test.js +14 -205
  60. package/dist/clients/attach/command.d.ts +2 -1
  61. package/dist/clients/attach/command.js +81 -76
  62. package/dist/clients/attach/input/capabilities.d.ts +27 -0
  63. package/dist/clients/attach/input/capabilities.js +96 -0
  64. package/dist/clients/attach/input/controller.d.ts +20 -182
  65. package/dist/clients/attach/input/controller.js +128 -537
  66. package/dist/clients/attach/input/overlay-owner.d.ts +41 -0
  67. package/dist/clients/attach/input/overlay-owner.js +199 -0
  68. package/dist/clients/attach/overlays/file-review.d.ts +0 -4
  69. package/dist/clients/attach/overlays/file-review.js +13 -5
  70. package/dist/clients/attach/overlays/graph.js +2 -10
  71. package/dist/clients/attach/render/chat-view.d.ts +4 -3
  72. package/dist/clients/attach/render/chat-view.js +39 -33
  73. package/dist/clients/attach/render/group-activity.d.ts +1 -0
  74. package/dist/clients/attach/render/group-activity.js +20 -13
  75. package/dist/clients/attach/render/group-recap.js +12 -3
  76. package/dist/clients/attach/session/connection.js +9 -15
  77. package/dist/clients/attach/session/editor-inventory.d.ts +6 -5
  78. package/dist/clients/attach/session/editor-inventory.js +7 -8
  79. package/dist/clients/attach/session/file-links.d.ts +13 -0
  80. package/dist/clients/attach/session/file-links.js +107 -0
  81. package/dist/clients/attach/session/frame.d.ts +3 -0
  82. package/dist/clients/attach/session/frame.js +10 -1
  83. package/dist/clients/attach/session/frames.js +2 -3
  84. package/dist/clients/attach/session/input-wiring.d.ts +4 -1
  85. package/dist/clients/attach/session/input-wiring.js +15 -14
  86. package/dist/clients/attach/session/mouse.d.ts +6 -1
  87. package/dist/clients/attach/session/mouse.js +8 -5
  88. package/dist/clients/attach/session/profile-files.js +18 -12
  89. package/dist/clients/attach/session/reconnect.js +1 -1
  90. package/dist/clients/attach/session/state-sync.js +1 -2
  91. package/dist/clients/attach/session/surface-host.d.ts +3 -2
  92. package/dist/clients/attach/session/surface-host.js +4 -4
  93. package/dist/clients/attach/slash/dispatch.d.ts +8 -31
  94. package/dist/clients/attach/slash/dispatch.js +34 -81
  95. package/dist/clients/attach/viewer.js +820 -860
  96. package/dist/clients/conversation/projection.d.ts +79 -0
  97. package/dist/clients/conversation/projection.js +341 -0
  98. package/dist/clients/inbox/__tests__/serial/inbox-controller.test.js +159 -0
  99. package/dist/clients/inbox/__tests__/serial/mount-panel.test.js +151 -0
  100. package/dist/clients/inbox/controller.d.ts +0 -4
  101. package/dist/clients/inbox/controller.js +0 -2
  102. package/dist/clients/inbox/review/__tests__/review-core.test.js +4 -293
  103. package/dist/clients/inbox/review/__tests__/teardown-notice.test.js +100 -0
  104. package/dist/clients/inbox/review/comments-client.d.ts +3 -2
  105. package/dist/clients/inbox/review/comments-client.js +12 -12
  106. package/dist/clients/inbox/review/companion-pane.d.ts +30 -0
  107. package/dist/clients/inbox/review/companion-pane.js +86 -0
  108. package/dist/clients/inbox/review/document-surface.d.ts +182 -0
  109. package/dist/clients/inbox/review/{document-region.js → document-surface.js} +252 -48
  110. package/dist/clients/inbox/review/frame.js +5 -4
  111. package/dist/clients/inbox/review/launch.d.ts +8 -8
  112. package/dist/clients/inbox/review/launch.js +52 -92
  113. package/dist/clients/inbox/review/nvim.d.ts +2 -0
  114. package/dist/clients/inbox/review/nvim.js +14 -12
  115. package/dist/clients/inbox/review/review-client.d.ts +12 -8
  116. package/dist/clients/inbox/review/review-client.js +46 -35
  117. package/dist/clients/inbox/review-adapter.d.ts +3 -10
  118. package/dist/clients/inbox/review-adapter.js +27 -19
  119. package/dist/clients/inbox/surface.d.ts +0 -4
  120. package/dist/clients/inbox/surface.js +0 -2
  121. package/dist/clients/surfaces/host.d.ts +11 -3
  122. package/dist/commands/__tests__/api-client-cold-start-diagnostic.test.js +7 -34
  123. package/dist/commands/__tests__/human.test.js +11 -322
  124. package/dist/commands/api-client.d.ts +5 -5
  125. package/dist/commands/api-client.js +6 -85
  126. package/dist/commands/canvas-browse.js +3 -29
  127. package/dist/commands/canvas-config.js +1 -1
  128. package/dist/commands/canvas-use.js +3 -3
  129. package/dist/commands/canvas.js +1 -1
  130. package/dist/commands/cron.js +5 -1
  131. package/dist/commands/human/queue.d.ts +0 -4
  132. package/dist/commands/human/queue.js +7 -40
  133. package/dist/commands/memory/list.d.ts +14 -0
  134. package/dist/commands/memory/list.js +35 -31
  135. package/dist/commands/memory/read.d.ts +7 -0
  136. package/dist/commands/memory/read.js +14 -8
  137. package/dist/commands/memory/write.js +13 -12
  138. package/dist/commands/node/bash.d.ts +1 -0
  139. package/dist/commands/node/bash.js +198 -0
  140. package/dist/commands/node/create.d.ts +23 -0
  141. package/dist/commands/node/create.js +207 -0
  142. package/dist/commands/node/inspect.d.ts +2 -0
  143. package/dist/commands/node/inspect.js +302 -0
  144. package/dist/commands/node/lifecycle.d.ts +4 -0
  145. package/dist/commands/node/lifecycle.js +415 -0
  146. package/dist/commands/node/message.d.ts +1 -0
  147. package/dist/commands/node/message.js +164 -0
  148. package/dist/commands/node/pyramid.d.ts +2 -0
  149. package/dist/commands/node/pyramid.js +79 -0
  150. package/dist/commands/node/subscription.d.ts +1 -0
  151. package/dist/commands/node/subscription.js +82 -0
  152. package/dist/commands/node/wait.d.ts +1 -0
  153. package/dist/commands/node/wait.js +159 -0
  154. package/dist/commands/node-lifecycle-revive.js +10 -57
  155. package/dist/commands/node.d.ts +0 -42
  156. package/dist/commands/node.js +11 -2065
  157. package/dist/commands/search.js +1 -1
  158. package/dist/commands/surface/node/cycle.d.ts +1 -0
  159. package/dist/commands/surface/node/cycle.js +83 -0
  160. package/dist/commands/surface/node/focus.d.ts +1 -0
  161. package/dist/commands/surface/node/focus.js +67 -0
  162. package/dist/commands/surface/node/id.d.ts +1 -0
  163. package/dist/commands/surface/node/id.js +38 -0
  164. package/dist/commands/surface/node/pin.d.ts +1 -0
  165. package/dist/commands/surface/node/pin.js +42 -0
  166. package/dist/commands/surface/node/placement.d.ts +46 -0
  167. package/dist/commands/surface/node/placement.js +124 -0
  168. package/dist/commands/surface-node.js +4 -1
  169. package/dist/commands/surface-reload.js +1 -2
  170. package/dist/commands/surface-tmux-spread.js +1 -1
  171. package/dist/commands/surface.js +5 -20
  172. package/dist/commands/sys/__tests__/setup-core.test.js +18 -271
  173. package/dist/commands/sys/config.js +6 -6
  174. package/dist/commands/sys/logs.js +1 -1
  175. package/dist/commands/sys/panels/broker-limits-panel.d.ts +17 -0
  176. package/dist/commands/sys/panels/broker-limits-panel.js +104 -0
  177. package/dist/commands/sys/panels/dependencies-panel.d.ts +14 -0
  178. package/dist/commands/sys/panels/dependencies-panel.js +80 -0
  179. package/dist/commands/sys/panels/keybindings-panel.d.ts +56 -0
  180. package/dist/commands/sys/panels/keybindings-panel.js +703 -0
  181. package/dist/commands/sys/panels/keys-panel.d.ts +16 -0
  182. package/dist/commands/sys/panels/keys-panel.js +60 -0
  183. package/dist/commands/sys/panels/models-panel.d.ts +77 -0
  184. package/dist/commands/sys/panels/models-panel.js +647 -0
  185. package/dist/commands/sys/panels/panel.d.ts +45 -0
  186. package/dist/commands/sys/panels/panel.js +137 -0
  187. package/dist/commands/sys/panels/plugins-panel.d.ts +16 -0
  188. package/dist/commands/sys/panels/plugins-panel.js +80 -0
  189. package/dist/commands/sys/panels/prefs-panel.d.ts +21 -0
  190. package/dist/commands/sys/panels/prefs-panel.js +85 -0
  191. package/dist/commands/sys/panels/provider-panel.d.ts +62 -0
  192. package/dist/commands/sys/panels/provider-panel.js +538 -0
  193. package/dist/commands/sys/settings-shell.d.ts +55 -0
  194. package/dist/commands/sys/settings-shell.js +400 -0
  195. package/dist/commands/sys/settings.d.ts +2 -0
  196. package/dist/commands/sys/settings.js +31 -0
  197. package/dist/commands/sys/setup-core.d.ts +3 -33
  198. package/dist/commands/sys/setup-core.js +27 -78
  199. package/dist/commands/sys/setup-settings-runner.d.ts +24 -0
  200. package/dist/commands/sys/setup-settings-runner.js +63 -0
  201. package/dist/commands/sys/setup-wizard.d.ts +26 -125
  202. package/dist/commands/sys/setup-wizard.js +209 -2473
  203. package/dist/commands/sys/setup.js +5 -7
  204. package/dist/commands/sys.js +3 -2
  205. package/dist/core/__tests__/broker-extension-canvas-db-boundary.test.js +50 -0
  206. package/dist/core/__tests__/broker-launch-candidates.test.js +20 -9
  207. package/dist/core/__tests__/broker-preflight.test.js +1 -1
  208. package/dist/core/__tests__/canvas-inbox-watcher-hold.test.js +108 -27
  209. package/dist/core/__tests__/canvas-inbox-watcher.test.js +14 -0
  210. package/dist/core/__tests__/canvas.test.js +2 -36
  211. package/dist/core/__tests__/close.test.js +14 -3
  212. package/dist/core/__tests__/context-intro.test.js +32 -143
  213. package/dist/core/__tests__/cron-broker-capacity.test.js +22 -3
  214. package/dist/core/__tests__/daemon-boot.test.js +2 -20
  215. package/dist/core/__tests__/daemon-wedge.test.js +1 -1
  216. package/dist/core/__tests__/dead-node-policy-table.test.js +1 -18
  217. package/dist/core/__tests__/fixtures/fake-engine.d.ts +1 -1
  218. package/dist/core/__tests__/fixtures/fake-engine.js +2 -2
  219. package/dist/core/__tests__/fixtures/fake-pi-host.js +2 -2
  220. package/dist/core/__tests__/focuses.test.js +4 -98
  221. package/dist/core/__tests__/helpers/broker-clients.d.ts +0 -3
  222. package/dist/core/__tests__/helpers/broker-clients.js +0 -14
  223. package/dist/core/__tests__/helpers/harness.d.ts +0 -8
  224. package/dist/core/__tests__/helpers/harness.js +7 -87
  225. package/dist/core/__tests__/helpers/viewer-panes.js +1 -1
  226. package/dist/core/__tests__/inline-memory-refs.test.js +5 -134
  227. package/dist/core/__tests__/kickoff.test.js +1 -1
  228. package/dist/core/__tests__/memory-resolver-precedence.test.js +29 -1
  229. package/dist/core/__tests__/migration.test.js +35 -48
  230. package/dist/core/__tests__/on-read-dedup-resume.test.js +22 -12
  231. package/dist/core/__tests__/passive-subscription.test.js +26 -49
  232. package/dist/core/__tests__/preview-registry-sync.test.js +1 -2
  233. package/dist/core/__tests__/prune.test.js +94 -1
  234. package/dist/core/__tests__/review-model-floor.test.js +0 -32
  235. package/dist/core/__tests__/seam/broker-attach-multiclient.test.js +255 -0
  236. package/dist/core/__tests__/{full → seam}/broker-attach-stream.test.js +39 -7
  237. package/dist/core/__tests__/{full → seam}/broker-crash-teardown.test.js +30 -29
  238. package/dist/core/__tests__/{full → seam}/broker-pane-resolution.test.js +54 -5
  239. package/dist/core/__tests__/{full → seam}/broker-provider-retry.test.js +134 -82
  240. package/dist/core/__tests__/{full → seam}/broker-whip-interrupt.test.js +15 -4
  241. package/dist/core/__tests__/{full/idle-release-settlement.test.js → seam/dormancy-release.test.js} +69 -17
  242. package/dist/core/__tests__/{full/yield-message-transaction.test.js → seam/yield-refresh-transaction.test.js} +31 -9
  243. package/dist/core/__tests__/secrets.test.js +1 -7
  244. package/dist/core/__tests__/{broker-fork-seam.test.js → serial/broker-fork-seam.test.js} +58 -7
  245. package/dist/core/__tests__/{broker-sdk-wiring.test.js → serial/broker-sdk-wiring.test.js} +18 -162
  246. package/dist/core/__tests__/{broker-snapshot-history.test.js → serial/broker-snapshot-history.test.js} +9 -9
  247. package/dist/core/__tests__/{command-plugins.test.js → serial/command-plugins.test.js} +105 -15
  248. package/dist/core/__tests__/{deferred-no-wake.test.js → serial/deferred-no-wake.test.js} +23 -20
  249. package/dist/core/__tests__/{flagship-lifecycle.test.js → serial/flagship-lifecycle.test.js} +7 -7
  250. package/dist/core/__tests__/{host-teardown-process-group.test.js → serial/host-teardown-process-group.test.js} +6 -6
  251. package/dist/core/__tests__/{human-deliver-e2e.test.js → serial/human-deliver-e2e.test.js} +12 -12
  252. package/dist/core/__tests__/{live-mutation.test.js → serial/live-mutation.test.js} +5 -5
  253. package/dist/core/__tests__/{refresh-stall-recycle.test.js → serial/refresh-stall-recycle.test.js} +5 -14
  254. package/dist/core/__tests__/{revive.test.js → serial/revive.test.js} +15 -100
  255. package/dist/core/__tests__/{spawn-root.test.js → serial/spawn-root.test.js} +32 -15
  256. package/dist/core/__tests__/serial/subscription-delivery.test.js +126 -0
  257. package/dist/core/__tests__/serial/tmux-surface.test.js +256 -0
  258. package/dist/core/__tests__/{worktree.test.js → serial/worktree.test.js} +15 -15
  259. package/dist/core/__tests__/session-model.test.js +0 -18
  260. package/dist/core/__tests__/spawn-worktree-id-conflict.test.js +9 -0
  261. package/dist/core/__tests__/watchdog-abort-arms-retry.test.js +50 -0
  262. package/dist/core/broker-client/__tests__/transport-relay.test.js +15 -16
  263. package/dist/core/broker-client/__tests__/transport-socket.test.js +28 -0
  264. package/dist/core/broker-client/client.d.ts +2 -2
  265. package/dist/core/broker-client/client.js +4 -7
  266. package/dist/core/broker-client/transport-relay.d.ts +13 -19
  267. package/dist/core/broker-client/transport-relay.js +19 -34
  268. package/dist/core/broker-client/transport-socket.d.ts +2 -2
  269. package/dist/core/broker-client/transport-socket.js +9 -2
  270. package/dist/core/broker-client/transport.d.ts +7 -3
  271. package/dist/core/broker-client/transport.js +4 -4
  272. package/dist/core/canvas/__tests__/attention.test.js +1 -18
  273. package/dist/core/canvas/__tests__/remote-canvas-source.test.js +7 -64
  274. package/dist/core/canvas/__tests__/remote-transport.test.js +2 -3
  275. package/dist/core/canvas/__tests__/render-remote.test.js +7 -52
  276. package/dist/core/canvas/browse/app.d.ts +2 -17
  277. package/dist/core/canvas/browse/app.js +16 -88
  278. package/dist/core/canvas/browse/model.d.ts +0 -4
  279. package/dist/core/canvas/browse/model.js +1 -12
  280. package/dist/core/canvas/browse/render.js +6 -3
  281. package/dist/core/canvas/crons.d.ts +8 -5
  282. package/dist/core/canvas/crons.js +7 -6
  283. package/dist/core/canvas/extensions.d.ts +7 -3
  284. package/dist/core/canvas/extensions.js +16 -4
  285. package/dist/core/canvas/nav-model.d.ts +0 -4
  286. package/dist/core/canvas/nav-model.js +2 -14
  287. package/dist/core/canvas/node-order.d.ts +3 -0
  288. package/dist/core/canvas/node-order.js +12 -0
  289. package/dist/core/canvas/remote-canvas-source.d.ts +3 -6
  290. package/dist/core/canvas/remote-canvas-source.js +8 -15
  291. package/dist/core/command.js +11 -4
  292. package/dist/core/config.js +3 -1
  293. package/dist/core/events/envelope.js +1 -1
  294. package/dist/core/events/read.js +7 -21
  295. package/dist/core/events/source.d.ts +0 -2
  296. package/dist/core/events/source.js +0 -16
  297. package/dist/core/events/types.d.ts +1 -1
  298. package/dist/core/fault-classifier.d.ts +1 -1
  299. package/dist/core/feed/passive.d.ts +0 -11
  300. package/dist/core/feed/passive.js +1 -62
  301. package/dist/core/human/__tests__/{inbox-core.test.js → serial/inbox-core.test.js} +6 -6
  302. package/dist/core/keybindings/__tests__/resolve.test.js +1 -96
  303. package/dist/core/keybindings/background-bash.js +3 -4
  304. package/dist/core/keybindings/catalog.js +1 -1
  305. package/dist/core/memory/inline-ref-grammar.js +3 -3
  306. package/dist/core/memory-resolver.d.ts +11 -25
  307. package/dist/core/memory-resolver.js +51 -33
  308. package/dist/core/model-routes.d.ts +15 -0
  309. package/dist/core/model-routes.js +12 -0
  310. package/dist/core/pool-credential-store.js +1 -1
  311. package/dist/core/preview-registry.js +8 -9
  312. package/dist/core/profiles/__tests__/root-profile.test.js +4 -14
  313. package/dist/core/review/realize.d.ts +0 -13
  314. package/dist/core/review/realize.js +0 -40
  315. package/dist/core/review/types.d.ts +1 -1
  316. package/dist/core/runtime/__tests__/engine-route.test.js +2 -2
  317. package/dist/core/runtime/bearings.js +1 -11
  318. package/dist/core/runtime/broker/client-registry.d.ts +33 -0
  319. package/dist/core/runtime/broker/client-registry.js +164 -0
  320. package/dist/core/runtime/broker/daemon-ops.d.ts +19 -0
  321. package/dist/core/runtime/broker/daemon-ops.js +49 -0
  322. package/dist/core/runtime/broker/event-projection.d.ts +42 -0
  323. package/dist/core/runtime/broker/event-projection.js +178 -0
  324. package/dist/core/runtime/broker/fault-retry.d.ts +39 -0
  325. package/dist/core/runtime/broker/fault-retry.js +277 -0
  326. package/dist/core/runtime/broker/frame-dispatch.d.ts +238 -0
  327. package/dist/core/runtime/broker/frame-dispatch.js +1537 -0
  328. package/dist/core/runtime/broker/inbox.d.ts +22 -0
  329. package/dist/core/runtime/broker/inbox.js +167 -0
  330. package/dist/core/runtime/broker/passive.d.ts +16 -0
  331. package/dist/core/runtime/broker/passive.js +44 -0
  332. package/dist/core/runtime/broker/read-ops.d.ts +23 -0
  333. package/dist/core/runtime/broker/read-ops.js +150 -0
  334. package/dist/core/runtime/broker/rebind.d.ts +74 -0
  335. package/dist/core/runtime/broker/rebind.js +211 -0
  336. package/dist/core/runtime/broker/tool-groups.d.ts +39 -0
  337. package/dist/core/runtime/broker/tool-groups.js +244 -0
  338. package/dist/core/runtime/broker-extension-render.d.ts +11 -0
  339. package/dist/core/runtime/broker-extension-render.js +181 -0
  340. package/dist/core/runtime/broker-persona-guidance.d.ts +13 -0
  341. package/dist/core/runtime/broker-persona-guidance.js +58 -0
  342. package/dist/core/runtime/broker-protocol.d.ts +1 -1
  343. package/dist/core/runtime/broker-protocol.js +1 -1
  344. package/dist/core/runtime/broker.d.ts +5 -196
  345. package/dist/core/runtime/broker.js +276 -3059
  346. package/dist/core/runtime/canvas-extensions.js +11 -2
  347. package/dist/core/runtime/fault.js +1 -1
  348. package/dist/core/runtime/model-selection.d.ts +9 -0
  349. package/dist/core/runtime/model-selection.js +12 -0
  350. package/dist/core/runtime/model-swap.d.ts +3 -3
  351. package/dist/core/runtime/model-swap.js +33 -25
  352. package/dist/core/runtime/placement-tmux.d.ts +3 -14
  353. package/dist/core/runtime/placement-tmux.js +11 -80
  354. package/dist/core/runtime/placement.d.ts +4 -2
  355. package/dist/core/runtime/placement.js +7 -12
  356. package/dist/core/runtime/promote.d.ts +14 -1
  357. package/dist/core/runtime/promote.js +1 -1
  358. package/dist/core/runtime/reset.d.ts +1 -1
  359. package/dist/core/runtime/roadmap.js +1 -1
  360. package/dist/core/runtime/spawn.d.ts +8 -0
  361. package/dist/core/runtime/spawn.js +36 -6
  362. package/dist/core/runtime/stop-guard.d.ts +4 -3
  363. package/dist/core/runtime/stop-guard.js +36 -18
  364. package/dist/core/runtime/stop-signals.d.ts +4 -1
  365. package/dist/core/runtime/stream-watchdog.js +4 -5
  366. package/dist/core/runtime/structured-output.d.ts +15 -2
  367. package/dist/core/runtime/structured-output.js +35 -12
  368. package/dist/core/runtime/tmux-bindings.d.ts +25 -0
  369. package/dist/core/runtime/tmux-bindings.js +682 -0
  370. package/dist/core/runtime/tmux-chrome.d.ts +2 -1
  371. package/dist/core/runtime/tmux-chrome.js +3 -2
  372. package/dist/core/runtime/{tmux.d.ts → tmux-driver.d.ts} +18 -26
  373. package/dist/core/runtime/tmux-driver.js +598 -0
  374. package/dist/core/runtime/view-socket.d.ts +14 -0
  375. package/dist/core/runtime/view-socket.js +83 -0
  376. package/dist/core/session-model/session-state.d.ts +1 -2
  377. package/dist/core/session-model/session-state.js +5 -8
  378. package/dist/core/spawn.d.ts +1 -1
  379. package/dist/core/spawn.js +2 -2
  380. package/dist/core/substrate/gate.d.ts +1 -1
  381. package/dist/core/substrate/on-read-pure.d.ts +7 -0
  382. package/dist/core/substrate/on-read-pure.js +272 -0
  383. package/dist/core/termrender/termrender.js +32 -2
  384. package/dist/core/user-settings.d.ts +23 -1
  385. package/dist/core/user-settings.js +18 -1
  386. package/dist/daemon/api/__tests__/node-model-validation.test.js +134 -0
  387. package/dist/daemon/api/__tests__/review-terminal-conflict.test.js +98 -0
  388. package/dist/daemon/api/__tests__/{full → seam}/api-server.test.js +6 -48
  389. package/dist/daemon/api/__tests__/{full → seam}/b10-attach-modelauth.test.js +17 -44
  390. package/dist/daemon/api/__tests__/{full/push-parity.test.js → seam/leaf-api-parity.test.js} +61 -42
  391. package/dist/daemon/api/bridge.js +40 -81
  392. package/dist/daemon/api/handlers/broker-ops.d.ts +2 -0
  393. package/dist/daemon/api/handlers/broker-ops.js +383 -0
  394. package/dist/daemon/api/handlers/crons.js +9 -4
  395. package/dist/daemon/api/handlers/files.js +6 -7
  396. package/dist/daemon/api/handlers/inbox.js +2 -340
  397. package/dist/daemon/api/handlers/nodes.d.ts +10 -1
  398. package/dist/daemon/api/handlers/nodes.js +74 -39
  399. package/dist/daemon/api/handlers/review-comments.js +5 -1
  400. package/dist/daemon/api/handlers/reviews.js +0 -19
  401. package/dist/daemon/api/map.js +25 -4
  402. package/dist/daemon/api/router.js +2 -3
  403. package/dist/daemon/api/server.js +5 -7
  404. package/dist/daemon/cron-run.d.ts +4 -0
  405. package/dist/daemon/cron-run.js +30 -13
  406. package/dist/daemon/crtrd.d.ts +3 -58
  407. package/dist/daemon/crtrd.js +28 -1244
  408. package/dist/daemon/manage.js +0 -1
  409. package/dist/daemon/reconcilers/broker-supervision.d.ts +50 -0
  410. package/dist/daemon/reconcilers/broker-supervision.js +549 -0
  411. package/dist/daemon/reconcilers/cron-lane.d.ts +10 -0
  412. package/dist/daemon/reconcilers/cron-lane.js +32 -0
  413. package/dist/daemon/reconcilers/dormant-inbox.d.ts +18 -0
  414. package/dist/daemon/reconcilers/dormant-inbox.js +143 -0
  415. package/dist/daemon/reconcilers/storage-maintenance.d.ts +22 -0
  416. package/dist/daemon/reconcilers/storage-maintenance.js +213 -0
  417. package/dist/daemon/review/finish.js +2 -5
  418. package/dist/pi-extensions/__tests__/canvas-context-intro.test.js +34 -53
  419. package/dist/pi-extensions/__tests__/canvas-recap.test.js +16 -113
  420. package/dist/pi-extensions/__tests__/canvas-stophook-agentend.test.js +72 -99
  421. package/dist/pi-extensions/__tests__/canvas-stophook-context-nudge.test.js +29 -12
  422. package/dist/pi-extensions/broker-local.d.ts +20 -0
  423. package/dist/pi-extensions/broker-local.js +89 -0
  424. package/dist/pi-extensions/canvas-context-intro.d.ts +3 -3
  425. package/dist/pi-extensions/canvas-context-intro.js +22 -11
  426. package/dist/pi-extensions/canvas-doc-substrate.js +17 -34
  427. package/dist/pi-extensions/canvas-goal-capture.js +7 -12
  428. package/dist/pi-extensions/canvas-inbox-watcher.js +124 -139
  429. package/dist/pi-extensions/canvas-passive-context.d.ts +3 -3
  430. package/dist/pi-extensions/canvas-passive-context.js +22 -18
  431. package/dist/pi-extensions/canvas-recap.d.ts +2 -2
  432. package/dist/pi-extensions/canvas-recap.js +48 -21
  433. package/dist/pi-extensions/canvas-review-boundary.js +10 -4
  434. package/dist/pi-extensions/canvas-stophook.d.ts +0 -5
  435. package/dist/pi-extensions/canvas-stophook.js +149 -431
  436. package/dist/pi-extensions/canvas-structured-output.js +52 -30
  437. package/dist/pi-extensions/envelope-merge.d.ts +13 -0
  438. package/dist/pi-extensions/envelope-merge.js +29 -0
  439. package/dist/shared/working-activity.d.ts +3 -2
  440. package/dist/shared/working-activity.js +3 -2
  441. package/dist/types.d.ts +6 -5
  442. package/dist/types.js +2 -2
  443. package/docs/compat/hearth-crtr-v1.md +4 -12
  444. package/docs/compat/hearth-crtr-v2.md +3 -11
  445. package/docs/compat/hearth-crtr-v3.md +4 -12
  446. package/docs/compat/hearth-crtr-v4.md +3 -11
  447. package/docs/compat/hearth-crtr-v5.md +3 -11
  448. package/docs/public-api.md +3 -7
  449. package/package.json +7 -49
  450. package/runtime.lock.json +2766 -14533
  451. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/__tests__/claude-plugin-commands.test.ts +0 -49
  452. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/__tests__/memory-slash-commands.test.ts +0 -194
  453. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/__tests__/statusline.test.ts +0 -68
  454. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/frontmatter-rules/test.ts +0 -119
  455. package/dist/clients/attach/__tests__/attach-chrome-remote.test.js +0 -439
  456. package/dist/clients/attach/__tests__/attach-keybindings.test.js +0 -170
  457. package/dist/clients/attach/__tests__/crtr-output-coverage.test.js +0 -57
  458. package/dist/clients/attach/__tests__/editor-frame-title.test.js +0 -19
  459. package/dist/clients/attach/__tests__/input-controller-extension-command.test.js +0 -32
  460. package/dist/clients/attach/__tests__/markdown-headings.test.js +0 -35
  461. package/dist/clients/attach/__tests__/session-identity-refresh.test.js +0 -32
  462. package/dist/clients/conversation/conversation.d.ts +0 -65
  463. package/dist/clients/conversation/conversation.js +0 -318
  464. package/dist/clients/conversation/frames.d.ts +0 -30
  465. package/dist/clients/conversation/frames.js +0 -52
  466. package/dist/clients/conversation/region.d.ts +0 -51
  467. package/dist/clients/conversation/region.js +0 -265
  468. package/dist/clients/inbox/__tests__/inbox-controller.test.js +0 -247
  469. package/dist/clients/inbox/__tests__/mount-panel.test.js +0 -776
  470. package/dist/clients/inbox/review/__tests__/remap.test.js +0 -196
  471. package/dist/clients/inbox/review/columns.d.ts +0 -22
  472. package/dist/clients/inbox/review/columns.js +0 -40
  473. package/dist/clients/inbox/review/composition.d.ts +0 -60
  474. package/dist/clients/inbox/review/composition.js +0 -278
  475. package/dist/clients/inbox/review/document-region.d.ts +0 -120
  476. package/dist/clients/surfaces/region.d.ts +0 -16
  477. package/dist/clients/web/__tests__/push-engine.test.js +0 -158
  478. package/dist/clients/web/__tests__/push-registry.test.d.ts +0 -1
  479. package/dist/clients/web/__tests__/push-registry.test.js +0 -177
  480. package/dist/clients/web/dev-server.d.ts +0 -7
  481. package/dist/clients/web/dev-server.js +0 -46
  482. package/dist/clients/web/events.d.ts +0 -19
  483. package/dist/clients/web/events.js +0 -163
  484. package/dist/clients/web/push-engine.d.ts +0 -44
  485. package/dist/clients/web/push-engine.js +0 -125
  486. package/dist/clients/web/push-registry.d.ts +0 -85
  487. package/dist/clients/web/push-registry.js +0 -373
  488. package/dist/clients/web/server.d.ts +0 -19
  489. package/dist/clients/web/server.js +0 -661
  490. package/dist/clients/web/web-client/shared/protocol.d.ts +0 -214
  491. package/dist/clients/web/web-client/shared/protocol.js +0 -8
  492. package/dist/clients/web/web-cmd.d.ts +0 -2
  493. package/dist/clients/web/web-cmd.js +0 -141
  494. package/dist/commands/__tests__/api-canvas-source.test.d.ts +0 -1
  495. package/dist/commands/__tests__/api-canvas-source.test.js +0 -37
  496. package/dist/commands/__tests__/canvas-config.test.d.ts +0 -1
  497. package/dist/commands/__tests__/canvas-config.test.js +0 -107
  498. package/dist/commands/__tests__/node-no-kickoff-flag.test.d.ts +0 -1
  499. package/dist/commands/__tests__/node-no-kickoff-flag.test.js +0 -73
  500. package/dist/commands/__tests__/node-worktree-flag.test.d.ts +0 -1
  501. package/dist/commands/__tests__/node-worktree-flag.test.js +0 -49
  502. package/dist/commands/__tests__/search-contents.test.d.ts +0 -1
  503. package/dist/commands/__tests__/search-contents.test.js +0 -52
  504. package/dist/commands/memory/__tests__/lint.test.d.ts +0 -1
  505. package/dist/commands/memory/__tests__/lint.test.js +0 -15
  506. package/dist/commands/sys/__tests__/config-broker-thresholds.test.d.ts +0 -1
  507. package/dist/commands/sys/__tests__/config-broker-thresholds.test.js +0 -95
  508. package/dist/commands/sys/__tests__/config-keybindings.test.d.ts +0 -1
  509. package/dist/commands/sys/__tests__/config-keybindings.test.js +0 -55
  510. package/dist/commands/sys/__tests__/helpers/setup-runtime.d.ts +0 -5
  511. package/dist/commands/sys/__tests__/helpers/setup-runtime.js +0 -19
  512. package/dist/commands/sys/__tests__/setup-front-door.test.d.ts +0 -1
  513. package/dist/commands/sys/__tests__/setup-front-door.test.js +0 -102
  514. package/dist/commands/sys/__tests__/setup-models.test.d.ts +0 -1
  515. package/dist/commands/sys/__tests__/setup-models.test.js +0 -205
  516. package/dist/commands/sys/__tests__/setup-providers-viewport.test.d.ts +0 -1
  517. package/dist/commands/sys/__tests__/setup-providers-viewport.test.js +0 -155
  518. package/dist/commands/sys/__tests__/sync-deps.test.d.ts +0 -1
  519. package/dist/commands/sys/__tests__/sync-deps.test.js +0 -179
  520. package/dist/commands/sys/__tests__/sync-import.test.d.ts +0 -1
  521. package/dist/commands/sys/__tests__/sync-import.test.js +0 -315
  522. package/dist/core/__tests__/base-worker-prompt.test.d.ts +0 -1
  523. package/dist/core/__tests__/base-worker-prompt.test.js +0 -57
  524. package/dist/core/__tests__/command-plugins-surfaces.test.d.ts +0 -1
  525. package/dist/core/__tests__/command-plugins-surfaces.test.js +0 -359
  526. package/dist/core/__tests__/connection-reconnect-resume.test.d.ts +0 -1
  527. package/dist/core/__tests__/connection-reconnect-resume.test.js +0 -36
  528. package/dist/core/__tests__/finalization-migration.test.d.ts +0 -1
  529. package/dist/core/__tests__/finalization-migration.test.js +0 -38
  530. package/dist/core/__tests__/fixtures/extra-extension.d.ts +0 -1
  531. package/dist/core/__tests__/fixtures/extra-extension.js +0 -3
  532. package/dist/core/__tests__/fixtures/spawn-proof-target.test.d.ts +0 -1
  533. package/dist/core/__tests__/fixtures/spawn-proof-target.test.js +0 -15
  534. package/dist/core/__tests__/fork.test.d.ts +0 -1
  535. package/dist/core/__tests__/fork.test.js +0 -108
  536. package/dist/core/__tests__/full/broker-attach-limits.test.d.ts +0 -1
  537. package/dist/core/__tests__/full/broker-attach-limits.test.js +0 -147
  538. package/dist/core/__tests__/full/broker-deliver-ack.test.d.ts +0 -1
  539. package/dist/core/__tests__/full/broker-deliver-ack.test.js +0 -73
  540. package/dist/core/__tests__/full/broker-dialogs.test.d.ts +0 -1
  541. package/dist/core/__tests__/full/broker-dialogs.test.js +0 -180
  542. package/dist/core/__tests__/full/broker-display-snapshot.test.d.ts +0 -1
  543. package/dist/core/__tests__/full/broker-display-snapshot.test.js +0 -75
  544. package/dist/core/__tests__/full/broker-dormant-wake.test.d.ts +0 -1
  545. package/dist/core/__tests__/full/broker-dormant-wake.test.js +0 -130
  546. package/dist/core/__tests__/full/broker-model-changed-broadcast.test.d.ts +0 -1
  547. package/dist/core/__tests__/full/broker-model-changed-broadcast.test.js +0 -57
  548. package/dist/core/__tests__/full/broker-navigate-tree-rewelcome.test.d.ts +0 -1
  549. package/dist/core/__tests__/full/broker-navigate-tree-rewelcome.test.js +0 -80
  550. package/dist/core/__tests__/full/cascade-close.test.d.ts +0 -1
  551. package/dist/core/__tests__/full/cascade-close.test.js +0 -240
  552. package/dist/core/__tests__/full/detach-focus.test.d.ts +0 -1
  553. package/dist/core/__tests__/full/detach-focus.test.js +0 -126
  554. package/dist/core/__tests__/full/idle-release-settlement.test.d.ts +0 -1
  555. package/dist/core/__tests__/full/issue-146-yield-spawn-focus.test.d.ts +0 -1
  556. package/dist/core/__tests__/full/issue-146-yield-spawn-focus.test.js +0 -107
  557. package/dist/core/__tests__/full/park-clock-release.test.d.ts +0 -1
  558. package/dist/core/__tests__/full/park-clock-release.test.js +0 -56
  559. package/dist/core/__tests__/full/yield-message-transaction.test.d.ts +0 -1
  560. package/dist/core/__tests__/memory-index-render.test.d.ts +0 -1
  561. package/dist/core/__tests__/memory-index-render.test.js +0 -60
  562. package/dist/core/__tests__/model-routes.test.d.ts +0 -1
  563. package/dist/core/__tests__/model-routes.test.js +0 -41
  564. package/dist/core/__tests__/on-read-identity.test.d.ts +0 -1
  565. package/dist/core/__tests__/on-read-identity.test.js +0 -61
  566. package/dist/core/__tests__/phase4-review-migration.test.d.ts +0 -1
  567. package/dist/core/__tests__/phase4-review-migration.test.js +0 -100
  568. package/dist/core/__tests__/prune-to-limit.test.d.ts +0 -1
  569. package/dist/core/__tests__/prune-to-limit.test.js +0 -126
  570. package/dist/core/__tests__/reset.test.d.ts +0 -1
  571. package/dist/core/__tests__/reset.test.js +0 -69
  572. package/dist/core/__tests__/spawn-no-kickoff.test.d.ts +0 -1
  573. package/dist/core/__tests__/spawn-no-kickoff.test.js +0 -115
  574. package/dist/core/__tests__/steer-note.test.d.ts +0 -1
  575. package/dist/core/__tests__/steer-note.test.js +0 -41
  576. package/dist/core/__tests__/subcommand-tier.test.d.ts +0 -1
  577. package/dist/core/__tests__/subcommand-tier.test.js +0 -99
  578. package/dist/core/__tests__/subscription-delivery.test.js +0 -211
  579. package/dist/core/__tests__/test-runner-cheap-sharding.test.d.ts +0 -1
  580. package/dist/core/__tests__/test-runner-cheap-sharding.test.js +0 -97
  581. package/dist/core/__tests__/tmux-surface.test.js +0 -484
  582. package/dist/core/__tests__/wake-bearings.test.d.ts +0 -1
  583. package/dist/core/__tests__/wake-bearings.test.js +0 -102
  584. package/dist/core/canvas/__tests__/remote-event-stream.test.d.ts +0 -1
  585. package/dist/core/canvas/__tests__/remote-event-stream.test.js +0 -146
  586. package/dist/core/canvas/__tests__/source-resolve.test.d.ts +0 -1
  587. package/dist/core/canvas/__tests__/source-resolve.test.js +0 -77
  588. package/dist/core/canvas/browse/__tests__/model.test.d.ts +0 -1
  589. package/dist/core/canvas/browse/__tests__/model.test.js +0 -290
  590. package/dist/core/canvas/browse/__tests__/rebuild-coalescer.test.d.ts +0 -1
  591. package/dist/core/canvas/browse/__tests__/rebuild-coalescer.test.js +0 -134
  592. package/dist/core/canvas/browse/__tests__/render.test.d.ts +0 -1
  593. package/dist/core/canvas/browse/__tests__/render.test.js +0 -111
  594. package/dist/core/canvas/browse/rebuild-coalescer.d.ts +0 -7
  595. package/dist/core/canvas/browse/rebuild-coalescer.js +0 -61
  596. package/dist/core/canvas/remote-event-stream.d.ts +0 -24
  597. package/dist/core/canvas/remote-event-stream.js +0 -94
  598. package/dist/core/feed/__tests__/coalesce-human.test.d.ts +0 -1
  599. package/dist/core/feed/__tests__/coalesce-human.test.js +0 -36
  600. package/dist/core/feed/__tests__/empty-node-guard.test.d.ts +0 -1
  601. package/dist/core/feed/__tests__/empty-node-guard.test.js +0 -45
  602. package/dist/core/host-exports/__tests__/export-prunes-boot-skill.test.d.ts +0 -1
  603. package/dist/core/host-exports/__tests__/export-prunes-boot-skill.test.js +0 -84
  604. package/dist/core/human/__tests__/visible-paths.test.d.ts +0 -1
  605. package/dist/core/human/__tests__/visible-paths.test.js +0 -28
  606. package/dist/core/keybindings/__tests__/inbox-affordance.test.d.ts +0 -1
  607. package/dist/core/keybindings/__tests__/inbox-affordance.test.js +0 -38
  608. package/dist/core/review/__tests__/project.test.d.ts +0 -1
  609. package/dist/core/review/__tests__/project.test.js +0 -71
  610. package/dist/core/runtime/__tests__/command-expansion.test.d.ts +0 -1
  611. package/dist/core/runtime/__tests__/command-expansion.test.js +0 -25
  612. package/dist/core/runtime/__tests__/session-visibility.test.d.ts +0 -1
  613. package/dist/core/runtime/__tests__/session-visibility.test.js +0 -119
  614. package/dist/core/runtime/__tests__/spawn-at-given-id.test.d.ts +0 -1
  615. package/dist/core/runtime/__tests__/spawn-at-given-id.test.js +0 -34
  616. package/dist/core/runtime/tmux.js +0 -1314
  617. package/dist/daemon/api/__tests__/full/push-parity.test.d.ts +0 -1
  618. package/dist/daemon/api/__tests__/full/worktree-parity.test.d.ts +0 -1
  619. package/dist/daemon/api/__tests__/full/worktree-parity.test.js +0 -160
  620. package/dist/daemon/api/__tests__/inbox.test.d.ts +0 -1
  621. package/dist/daemon/api/__tests__/inbox.test.js +0 -489
  622. package/dist/web-client/apple-touch-icon.png +0 -0
  623. package/dist/web-client/assets/fragment-mono-latin-400-normal-BYwT3kSJ.woff +0 -0
  624. package/dist/web-client/assets/fragment-mono-latin-400-normal-yxdJ5AmL.woff2 +0 -0
  625. package/dist/web-client/assets/fragment-mono-latin-ext-400-normal-BbKYyvR9.woff2 +0 -0
  626. package/dist/web-client/assets/fragment-mono-latin-ext-400-normal-CT4YFKeK.woff +0 -0
  627. package/dist/web-client/assets/index-CCPaLeW7.css +0 -2
  628. package/dist/web-client/assets/index-kyOWsnZK.js +0 -86
  629. package/dist/web-client/assets/martian-mono-cyrillic-wght-normal-B84CD5C_.woff2 +0 -0
  630. package/dist/web-client/assets/martian-mono-latin-ext-wght-normal-DlL6xMw5.woff2 +0 -0
  631. package/dist/web-client/assets/martian-mono-latin-wght-normal-5W32yIyr.woff2 +0 -0
  632. package/dist/web-client/assets/workbox-window.prod.es5-Bd17z0YL.js +0 -2
  633. package/dist/web-client/icon-192.png +0 -0
  634. package/dist/web-client/icon-512.png +0 -0
  635. package/dist/web-client/icon-maskable-512.png +0 -0
  636. package/dist/web-client/index.html +0 -17
  637. package/dist/web-client/manifest.webmanifest +0 -1
  638. package/dist/web-client/sw.js +0 -1
  639. /package/dist/api/__tests__/{client.test.d.ts → serial/client.test.d.ts} +0 -0
  640. /package/dist/clients/inbox/__tests__/{inbox-controller.test.d.ts → serial/inbox-controller.test.d.ts} +0 -0
  641. /package/dist/clients/inbox/__tests__/{mount-panel.test.d.ts → serial/mount-panel.test.d.ts} +0 -0
  642. /package/dist/clients/{attach/__tests__/attach-chrome-remote.test.d.ts → inbox/review/__tests__/teardown-notice.test.d.ts} +0 -0
  643. /package/dist/{clients/attach/__tests__/attach-keybindings.test.d.ts → core/__tests__/broker-extension-canvas-db-boundary.test.d.ts} +0 -0
  644. /package/dist/{clients/attach/__tests__/crtr-output-coverage.test.d.ts → core/__tests__/seam/broker-attach-multiclient.test.d.ts} +0 -0
  645. /package/dist/core/__tests__/{full → seam}/broker-attach-stream.test.d.ts +0 -0
  646. /package/dist/core/__tests__/{full → seam}/broker-crash-teardown.test.d.ts +0 -0
  647. /package/dist/core/__tests__/{full → seam}/broker-pane-resolution.test.d.ts +0 -0
  648. /package/dist/core/__tests__/{full → seam}/broker-provider-retry.test.d.ts +0 -0
  649. /package/dist/core/__tests__/{full → seam}/broker-whip-interrupt.test.d.ts +0 -0
  650. /package/dist/{clients/attach/__tests__/editor-frame-title.test.d.ts → core/__tests__/seam/dormancy-release.test.d.ts} +0 -0
  651. /package/dist/{clients/attach/__tests__/input-controller-extension-command.test.d.ts → core/__tests__/seam/yield-refresh-transaction.test.d.ts} +0 -0
  652. /package/dist/core/__tests__/{broker-fork-seam.test.d.ts → serial/broker-fork-seam.test.d.ts} +0 -0
  653. /package/dist/core/__tests__/{broker-sdk-wiring.test.d.ts → serial/broker-sdk-wiring.test.d.ts} +0 -0
  654. /package/dist/core/__tests__/{broker-snapshot-history.test.d.ts → serial/broker-snapshot-history.test.d.ts} +0 -0
  655. /package/dist/core/__tests__/{command-plugins.test.d.ts → serial/command-plugins.test.d.ts} +0 -0
  656. /package/dist/core/__tests__/{deferred-no-wake.test.d.ts → serial/deferred-no-wake.test.d.ts} +0 -0
  657. /package/dist/core/__tests__/{flagship-lifecycle.test.d.ts → serial/flagship-lifecycle.test.d.ts} +0 -0
  658. /package/dist/core/__tests__/{host-teardown-process-group.test.d.ts → serial/host-teardown-process-group.test.d.ts} +0 -0
  659. /package/dist/core/__tests__/{human-deliver-e2e.test.d.ts → serial/human-deliver-e2e.test.d.ts} +0 -0
  660. /package/dist/core/__tests__/{live-mutation.test.d.ts → serial/live-mutation.test.d.ts} +0 -0
  661. /package/dist/core/__tests__/{refresh-stall-recycle.test.d.ts → serial/refresh-stall-recycle.test.d.ts} +0 -0
  662. /package/dist/core/__tests__/{revive.test.d.ts → serial/revive.test.d.ts} +0 -0
  663. /package/dist/core/__tests__/{spawn-root.test.d.ts → serial/spawn-root.test.d.ts} +0 -0
  664. /package/dist/core/__tests__/{subscription-delivery.test.d.ts → serial/subscription-delivery.test.d.ts} +0 -0
  665. /package/dist/core/__tests__/{tmux-surface.test.d.ts → serial/tmux-surface.test.d.ts} +0 -0
  666. /package/dist/core/__tests__/{worktree.test.d.ts → serial/worktree.test.d.ts} +0 -0
  667. /package/dist/{clients/attach/__tests__/markdown-headings.test.d.ts → core/__tests__/watchdog-abort-arms-retry.test.d.ts} +0 -0
  668. /package/dist/{clients/attach/__tests__/session-identity-refresh.test.d.ts → core/broker-client/__tests__/transport-socket.test.d.ts} +0 -0
  669. /package/dist/core/human/__tests__/{inbox-core.test.d.ts → serial/inbox-core.test.d.ts} +0 -0
  670. /package/dist/{clients/inbox/review/__tests__/remap.test.d.ts → daemon/api/__tests__/node-model-validation.test.d.ts} +0 -0
  671. /package/dist/{clients/surfaces/region.js → daemon/api/__tests__/review-terminal-conflict.test.d.ts} +0 -0
  672. /package/dist/daemon/api/__tests__/{full → seam}/api-server.test.d.ts +0 -0
  673. /package/dist/daemon/api/__tests__/{full → seam}/b10-attach-modelauth.test.d.ts +0 -0
  674. /package/dist/{clients/web/__tests__/push-engine.test.d.ts → daemon/api/__tests__/seam/leaf-api-parity.test.d.ts} +0 -0
@@ -1,129 +1,89 @@
1
- import { ApiError } from '../../../api/errors.js';
2
- import { CompanionRegion } from '../../conversation/region.js';
3
- import { createCommentAuthority } from './comments-client.js';
4
- import { ReviewCompositionComponent } from './composition.js';
5
- import { DocumentRegion } from './document-region.js';
1
+ import { ReviewDocumentSurface } from './document-surface.js';
6
2
  import { openLiveSource } from './live-source.js';
7
- import { createReviewClient, ReviewTerminalError } from './review-client.js';
8
- /** Mount the canonical live-document and companion-conversation review. */
9
- export async function openComposedReview(host, opts) {
10
- if (host.capabilities.remote) {
11
- host.notice('The composed review is unavailable in a remote attach — the file and companion live on the host.');
12
- return;
13
- }
14
- const reviewClient = createReviewClient();
15
- let opened;
16
- try {
17
- opened = await reviewClient.open(opts.reviewId);
18
- }
19
- catch (error) {
20
- host.notice(error instanceof ReviewTerminalError
21
- ? terminalRefusalNotice(error)
22
- : `couldn't open review: ${describeError(error)}`);
23
- return;
24
- }
3
+ import { createReviewClient } from './review-client.js';
4
+ /** Mount the review document. Both callers — the inbox's `ReviewAdapter` and
5
+ * the viewer's `launchFileReview` — refuse a remote attach and resolve the
6
+ * review record themselves, so this function is never reached from a remote
7
+ * viewer and never reads a review record of its own. */
8
+ export async function openReviewSurface(host, opts) {
9
+ const review = opts.review;
25
10
  let source;
26
11
  try {
27
- source = openLiveSource(opened.file);
12
+ source = openLiveSource(review.file);
28
13
  }
29
14
  catch (error) {
30
- host.notice(`couldn't open ${opened.file}: ${describeError(error)}`);
15
+ host.notice(`couldn't open ${review.file}: ${describeError(error)}`);
31
16
  return;
32
17
  }
33
- const comments = createCommentAuthority(opened.reviewId);
18
+ let terminalConflict = false;
19
+ const reviewClient = createReviewClient({
20
+ onTerminalConflict: (notice) => {
21
+ terminalConflict = true;
22
+ surface.teardown(notice);
23
+ },
24
+ });
25
+ const comments = reviewClient.comments(review.reviewId);
34
26
  let handle;
35
- let composition;
36
27
  let submitting = false;
37
- const documentRegion = new DocumentRegion({
38
- reviewId: opened.reviewId,
39
- absFile: opened.file,
40
- cwd: opened.cwd,
28
+ let canceling = false;
29
+ const surface = new ReviewDocumentSurface({
30
+ review,
41
31
  source,
42
32
  comments,
33
+ callerPane: host.capabilities.selfPane,
43
34
  services: {
44
- notice: (text) => host.notice(text),
45
- suspendForChild: () => {
46
- const resumeHost = host.suspendForChild();
47
- const resumeComposition = composition?.suspendForChild() ?? (() => { });
48
- let resumed = false;
49
- return () => {
50
- if (resumed)
51
- return;
52
- resumed = true;
53
- resumeComposition();
54
- resumeHost();
55
- };
56
- },
35
+ notice: (text, opts) => host.notice(text, opts),
36
+ suspendForChild: () => host.suspendForChild(),
57
37
  requestClose: () => handle?.close(),
58
38
  submit: () => { void submit(); },
39
+ cancel: () => { void cancel(); },
59
40
  },
60
41
  });
61
- const companionRegion = new CompanionRegion({
62
- companionNodeId: opened.companionNodeId,
63
- tui: opts.tui,
64
- canvasSource: opts.canvasSource,
65
- reopenDormantCompanion: async () => {
66
- await reviewClient.open(opened.reviewId);
67
- },
68
- onRequestClose: () => handle?.close(),
69
- });
70
- await documentRegion.open();
71
- composition = new ReviewCompositionComponent({
72
- document: documentRegion,
73
- companion: companionRegion,
74
- notice: (text) => host.notice(text),
75
- onRequestClose: () => { },
76
- });
77
- handle = host.mount(composition);
78
- composition.setHandle(handle);
79
- void companionRegion.open();
42
+ await surface.open();
43
+ handle = host.mount(surface);
44
+ surface.setHandle(handle);
45
+ // The conversation is opened only once the document is standing, so a tmux
46
+ // refusal costs the person a notice rather than the review. The tmux calls
47
+ // are blocking subprocesses, so they are deferred past the render tick the
48
+ // mount just scheduled — a macrotask lands after it, a microtask would not.
49
+ setImmediate(() => { surface.openCompanion(); });
80
50
  async function submit() {
81
51
  if (submitting)
82
52
  return;
83
53
  submitting = true;
84
54
  try {
85
- const result = await reviewClient.submit(opened.reviewId);
86
- host.notice(approvalNotice(result));
87
- handle?.close();
55
+ const result = await reviewClient.submit(review.reviewId);
56
+ surface.teardown(approvalNotice(result));
88
57
  }
89
58
  catch (error) {
90
- const conflict = terminalConflictNotice(error);
91
- if (conflict !== undefined) {
92
- host.notice(conflict);
93
- handle?.close();
59
+ if (terminalConflict)
94
60
  return;
95
- }
96
61
  submitting = false;
97
62
  host.notice(`couldn't submit review: ${describeError(error)}`);
98
63
  }
99
64
  }
100
- }
101
- function terminalRefusalNotice(error) {
102
- if (error.state === 'approved')
103
- return `This review was already approved. Result: ${error.resultPath ?? 'unknown'}`;
104
- return error.reason === undefined || error.reason === '' ? 'This review was canceled.' : `This review was canceled: ${error.reason}`;
65
+ async function cancel() {
66
+ if (canceling)
67
+ return;
68
+ canceling = true;
69
+ try {
70
+ await reviewClient.cancel(review.reviewId, 'canceled from the review surface');
71
+ surface.teardown('Review canceled.');
72
+ }
73
+ catch (error) {
74
+ if (terminalConflict)
75
+ return;
76
+ // Nothing moved: the review is still open and both panes stand.
77
+ canceling = false;
78
+ host.notice(`couldn't cancel review: ${describeError(error)}`);
79
+ }
80
+ }
105
81
  }
106
82
  function approvalNotice(result) {
107
83
  return result.changed
108
84
  ? `Approved — the document changed during review. Result: ${result.resultPath}`
109
85
  : `Approved — the document was not modified. Result: ${result.resultPath}`;
110
86
  }
111
- function terminalConflictNotice(error) {
112
- if (!(error instanceof ApiError) || error.status !== 409 || error.code !== 'review_terminal_conflict')
113
- return undefined;
114
- const review = error.details?.review;
115
- if (review === undefined)
116
- return undefined;
117
- if (review.state === 'approved')
118
- return review.result_path === undefined
119
- ? 'This review was already approved by someone else.'
120
- : `This review was already approved by someone else. Result: ${review.result_path}`;
121
- if (review.state === 'canceled')
122
- return review.cancel_reason === undefined || review.cancel_reason === ''
123
- ? 'This review was canceled before this submission landed.'
124
- : `This review was canceled before this submission landed: ${review.cancel_reason}`;
125
- return undefined;
126
- }
127
87
  function describeError(error) {
128
88
  return error instanceof Error ? error.message : String(error);
129
89
  }
@@ -1,6 +1,8 @@
1
1
  /**
2
2
  * Open the reviewed file in the user's configured editor, optionally at a specific line.
3
3
  * Resolves $VISUAL, then $EDITOR, then falls back to 'vi'.
4
+ * The configured value may be a shell fragment such as "code --wait" — it runs whole
5
+ * through /bin/sh, exactly like the comment-compose round-trip editor.
4
6
  * For vi-family editors (nvim, vim, vi, view), passes the line with the +line syntax.
5
7
  * For other editors, opens the file without line positioning.
6
8
  *
@@ -2,6 +2,8 @@ import { spawnSync } from 'node:child_process';
2
2
  /**
3
3
  * Open the reviewed file in the user's configured editor, optionally at a specific line.
4
4
  * Resolves $VISUAL, then $EDITOR, then falls back to 'vi'.
5
+ * The configured value may be a shell fragment such as "code --wait" — it runs whole
6
+ * through /bin/sh, exactly like the comment-compose round-trip editor.
5
7
  * For vi-family editors (nvim, vim, vi, view), passes the line with the +line syntax.
6
8
  * For other editors, opens the file without line positioning.
7
9
  *
@@ -10,28 +12,28 @@ import { spawnSync } from 'node:child_process';
10
12
  * @returns An object with an optional `error` property if the editor launch or execution failed
11
13
  */
12
14
  export function openReviewedFileInEditor(absFile, line) {
13
- const editor = process.env.VISUAL ?? process.env.EDITOR ?? 'vi';
14
- // Extract the first shell token (the command itself)
15
- const firstToken = editor.trim().split(/\s+/)[0];
16
- if (!firstToken) {
15
+ const editor = (process.env.VISUAL ?? process.env.EDITOR ?? 'vi').trim();
16
+ if (!editor) {
17
17
  return { error: 'editor configuration is empty' };
18
18
  }
19
- // Determine if this is a vi-family editor
19
+ // Determine if this is a vi-family editor from the fragment's command token
20
+ const firstToken = editor.split(/\s+/)[0] ?? '';
20
21
  const editorBasename = firstToken.split('/').pop() || firstToken;
21
22
  const isViFamily = ['nvim', 'vim', 'vi', 'view'].includes(editorBasename);
22
- // Build the command arguments
23
- const args = isViFamily ? [`+${line}`, absFile] : [absFile];
23
+ const lineArg = isViFamily ? ` "+${line}"` : '';
24
24
  try {
25
- const result = spawnSync(firstToken, args, { stdio: 'inherit' });
26
- // Check for errors
25
+ const result = spawnSync('/bin/sh', ['-c', `${editor}${lineArg} "$1"`, 'sh', absFile], { stdio: 'inherit' });
27
26
  if (result.error) {
28
- return { error: result.error.message };
27
+ return { error: `$EDITOR ("${editor}") failed to launch: ${result.error.message}` };
29
28
  }
30
29
  if (result.signal !== null) {
31
- return { error: `editor was killed by signal ${result.signal}` };
30
+ return { error: `$EDITOR ("${editor}") was killed by signal ${result.signal}` };
31
+ }
32
+ if (result.status === 127 || result.status === 126) {
33
+ return { error: `$EDITOR ("${editor}") failed to launch (shell exit ${result.status}) — check $VISUAL/$EDITOR` };
32
34
  }
33
35
  if (result.status !== 0) {
34
- return { error: `editor exited with code ${result.status}` };
36
+ return { error: `$EDITOR ("${editor}") exited with code ${result.status}` };
35
37
  }
36
38
  return {};
37
39
  }
@@ -1,3 +1,4 @@
1
+ import { type CommentAuthority } from './comments-client.js';
1
2
  export declare class ReviewTerminalError extends Error {
2
3
  readonly state: 'approved' | 'canceled';
3
4
  readonly resultPath?: string;
@@ -5,26 +6,29 @@ export declare class ReviewTerminalError extends Error {
5
6
  constructor(state: 'approved', resultPath: string);
6
7
  constructor(state: 'canceled', reason?: string);
7
8
  }
8
- export interface OpenedReview {
9
+ export interface ResolvedReview {
9
10
  reviewId: string;
10
11
  companionNodeId: string;
11
12
  file: string;
12
13
  cwd: string;
13
14
  }
14
15
  export interface ReviewClient {
15
- open(reviewId: string): Promise<OpenedReview>;
16
- byBridge(bridgeNodeId: string): Promise<{
17
- reviewId: string;
18
- }>;
16
+ byBridge(bridgeNodeId: string): Promise<ResolvedReview>;
19
17
  createInline(p: {
20
18
  originNodeId: string;
21
19
  file: string;
22
- }): Promise<OpenedReview>;
20
+ }): Promise<ResolvedReview>;
21
+ comments(reviewId: string): CommentAuthority;
23
22
  submit(reviewId: string): Promise<{
24
23
  changed: boolean;
25
24
  resultPath: string;
26
25
  }>;
27
26
  cancel(reviewId: string, reason: string): Promise<void>;
28
27
  }
29
- /** The terminal's complete daemon seam for review lifecycle operations. */
30
- export declare function createReviewClient(): ReviewClient;
28
+ export interface ReviewClientOptions {
29
+ onTerminalConflict?: (notice: string) => void;
30
+ }
31
+ /** The terminal's complete daemon seam for review lifecycle and comment operations. */
32
+ export declare function createReviewClient(opts?: ReviewClientOptions): ReviewClient;
33
+ export declare function terminalRefusalNotice(error: ReviewTerminalError): string;
34
+ export declare function terminalConflictNotice(error: unknown): string | undefined;
@@ -1,6 +1,7 @@
1
1
  import { randomUUID } from 'node:crypto';
2
2
  import { ApiError } from '../../../api/errors.js';
3
3
  import { cliClient } from '../../../commands/api-client.js';
4
+ import { createCommentAuthority } from './comments-client.js';
4
5
  export class ReviewTerminalError extends Error {
5
6
  state;
6
7
  resultPath;
@@ -21,49 +22,52 @@ export class ReviewTerminalError extends Error {
21
22
  this.state = state;
22
23
  }
23
24
  }
24
- /** The terminal's complete daemon seam for review lifecycle operations. */
25
- export function createReviewClient() {
25
+ /** The terminal's complete daemon seam for review lifecycle and comment operations. */
26
+ export function createReviewClient(opts = {}) {
27
+ const request = async (operation) => {
28
+ try {
29
+ return await operation();
30
+ }
31
+ catch (error) {
32
+ const notice = terminalConflictNotice(error);
33
+ if (notice !== undefined)
34
+ opts.onTerminalConflict?.(notice);
35
+ throw error;
36
+ }
37
+ };
26
38
  return {
27
- async open(reviewId) {
28
- try {
29
- const opened = await cliClient().openReview(reviewId);
30
- if (opened.disposition === 'terminal')
31
- throw terminalError(opened.review);
32
- return await openedReview(opened.review, opened.companion_node_id);
33
- }
34
- catch (error) {
35
- throw terminalErrorFromApi(error);
36
- }
37
- },
38
39
  async byBridge(bridgeNodeId) {
39
- const review = await cliClient().getReviewByBridge(bridgeNodeId);
40
- return { reviewId: review.review_id };
40
+ const review = await request(() => cliClient().getReviewByBridge(bridgeNodeId));
41
+ return await resolveReview(review, review.companion_node_id, request);
41
42
  },
42
43
  async createInline(p) {
43
- const review = await cliClient().createReview({
44
+ const review = await request(() => cliClient().createReview({
44
45
  origin_kind: 'inline',
45
46
  origin_node_id: p.originNodeId,
46
47
  file: p.file,
47
48
  idempotency_key: randomUUID(),
48
- });
49
- return await openedReview(review, review.companion_node_id);
49
+ }));
50
+ return await resolveReview(review, review.companion_node_id, request);
51
+ },
52
+ comments(reviewId) {
53
+ return createCommentAuthority(reviewId, request);
50
54
  },
51
55
  async submit(reviewId) {
52
- const submitted = await cliClient().submitReview(reviewId);
56
+ const submitted = await request(() => cliClient().submitReview(reviewId));
53
57
  return {
54
58
  changed: requireChanged(submitted.review),
55
59
  resultPath: requireResultPath(submitted.review),
56
60
  };
57
61
  },
58
62
  async cancel(reviewId, reason) {
59
- await cliClient().cancelReview(reviewId, { reason, actor: 'human' });
63
+ await request(() => cliClient().cancelReview(reviewId, { reason, actor: 'human' }));
60
64
  },
61
65
  };
62
66
  }
63
- async function openedReview(review, companionNodeId) {
67
+ async function resolveReview(review, companionNodeId, request) {
64
68
  if (review.state !== 'open')
65
69
  throw terminalError(review);
66
- const companion = await cliClient().getNode(companionNodeId);
70
+ const companion = await request(() => cliClient().getNode(companionNodeId));
67
71
  return {
68
72
  reviewId: review.review_id,
69
73
  companionNodeId,
@@ -71,14 +75,6 @@ async function openedReview(review, companionNodeId) {
71
75
  cwd: companion.cwd,
72
76
  };
73
77
  }
74
- function terminalErrorFromApi(error) {
75
- if (!(error instanceof ApiError) || error.status !== 409 || error.code !== 'review_terminal_conflict')
76
- return error;
77
- const review = error.details?.review;
78
- if (!isTerminalReview(review))
79
- return error;
80
- return terminalError(review);
81
- }
82
78
  function terminalError(review) {
83
79
  if (review.state !== 'approved' && review.state !== 'canceled') {
84
80
  throw new Error(`terminal review ${review.review_id} has invalid state ${review.state}`);
@@ -99,9 +95,24 @@ function requireResultPath(review) {
99
95
  }
100
96
  return review.result_path;
101
97
  }
102
- function isTerminalReview(value) {
103
- if (typeof value !== 'object' || value === null)
104
- return false;
105
- const state = value.state;
106
- return state === 'approved' || state === 'canceled';
98
+ export function terminalRefusalNotice(error) {
99
+ if (error.state === 'approved')
100
+ return `This review was already approved. Result: ${error.resultPath ?? 'unknown'}`;
101
+ return error.reason === undefined || error.reason === '' ? 'This review was canceled.' : `This review was canceled: ${error.reason}`;
102
+ }
103
+ export function terminalConflictNotice(error) {
104
+ if (!(error instanceof ApiError) || error.status !== 409 || error.code !== 'review_terminal_conflict')
105
+ return undefined;
106
+ const review = error.details?.review;
107
+ if (review === undefined)
108
+ return undefined;
109
+ if (review.state === 'approved')
110
+ return review.result_path === undefined
111
+ ? 'This review was already approved by someone else.'
112
+ : `This review was already approved by someone else. Result: ${review.result_path}`;
113
+ if (review.state === 'canceled')
114
+ return review.cancel_reason === undefined || review.cancel_reason === ''
115
+ ? 'This review was canceled before this submission landed.'
116
+ : `This review was canceled before this submission landed: ${review.cancel_reason}`;
117
+ return undefined;
107
118
  }
@@ -1,20 +1,13 @@
1
- import type { TUI } from '@earendil-works/pi-tui';
2
- import type { CanvasSource } from '../../core/canvas/source.js';
3
1
  import type { SurfaceHost } from '../surfaces/host.js';
4
2
  export interface ReviewAdapterOptions {
5
3
  host: SurfaceHost;
6
4
  dir: string;
7
- /** Threaded from the attach session so the composed surface can attach the
8
- * companion's transcript through the same terminal and canvas read authority
9
- * the outer viewer already holds. */
10
- tui: TUI;
11
- canvasSource: CanvasSource;
12
5
  }
13
6
  /**
14
7
  * Resolves a durable review ticket to its canonical daemon review and mounts
15
- * the one composed terminal review surface. Approval flows entirely through
16
- * `reviewClient.submit` inside that composition — this adapter owns only the
17
- * bridge lookup and the mounted surface's lifecycle.
8
+ * the one terminal review surface. Approval flows entirely through
9
+ * `reviewClient.submit` inside that surface — this adapter owns only the
10
+ * remote refusal, the bridge lookup, and the mounted surface's lifecycle.
18
11
  */
19
12
  export declare class ReviewAdapter {
20
13
  private readonly opts;
@@ -1,12 +1,12 @@
1
1
  import { basename } from 'node:path';
2
2
  import { ApiError } from '../../api/errors.js';
3
- import { openComposedReview } from './review/launch.js';
4
- import { createReviewClient } from './review/review-client.js';
3
+ import { openReviewSurface } from './review/launch.js';
4
+ import { createReviewClient, ReviewTerminalError, terminalRefusalNotice } from './review/review-client.js';
5
5
  /**
6
6
  * Resolves a durable review ticket to its canonical daemon review and mounts
7
- * the one composed terminal review surface. Approval flows entirely through
8
- * `reviewClient.submit` inside that composition — this adapter owns only the
9
- * bridge lookup and the mounted surface's lifecycle.
7
+ * the one terminal review surface. Approval flows entirely through
8
+ * `reviewClient.submit` inside that surface — this adapter owns only the
9
+ * remote refusal, the bridge lookup, and the mounted surface's lifecycle.
10
10
  */
11
11
  export class ReviewAdapter {
12
12
  opts;
@@ -32,15 +32,19 @@ export class ReviewAdapter {
32
32
  await this.running;
33
33
  }
34
34
  async run() {
35
+ // The refusal precedes the record read: a remote viewer can reach neither
36
+ // the reviewed file nor the companion's pane.
37
+ if (this.opts.host.capabilities.remote) {
38
+ this.opts.host.notice('The review is unavailable in a remote attach — the file and companion live on the host.');
39
+ return;
40
+ }
35
41
  const bridgeNodeId = basename(this.opts.dir);
36
- let reviewId;
42
+ let review;
37
43
  try {
38
- ({ reviewId } = await createReviewClient().byBridge(bridgeNodeId));
44
+ review = await createReviewClient().byBridge(bridgeNodeId);
39
45
  }
40
46
  catch (error) {
41
- if (!isReviewPredatesSystem(error))
42
- throw error;
43
- this.opts.host.notice('This review predates canonical review records — cancel it and re-file the review.');
47
+ this.opts.host.notice(noticeForBridgeFailure(error));
44
48
  return;
45
49
  }
46
50
  if (this.stopped)
@@ -54,13 +58,9 @@ export class ReviewAdapter {
54
58
  resolveClosed();
55
59
  });
56
60
  });
57
- await openComposedReview(host, {
58
- reviewId,
59
- tui: this.opts.tui,
60
- canvasSource: this.opts.canvasSource,
61
- });
62
- // A remote refusal, a terminal-review notice, or a live-source failure
63
- // reports through `host.notice` and returns without ever mounting.
61
+ await openReviewSurface(host, { review });
62
+ // A live-source failure reports through `host.notice` and returns without
63
+ // ever mounting.
64
64
  if (this.mountedHandle === undefined)
65
65
  return;
66
66
  if (this.stopped) {
@@ -70,7 +70,7 @@ export class ReviewAdapter {
70
70
  await closed;
71
71
  }
72
72
  }
73
- /** Observes the one surface `openComposedReview` mounts so this adapter can
73
+ /** Observes the one surface `openReviewSurface` mounts so this adapter can
74
74
  * await its close and close it itself from `stop()`, without widening
75
75
  * `SurfaceHost` or reaching into the real host's internals. */
76
76
  function wrapHostForMount(host, onMount) {
@@ -81,12 +81,20 @@ function wrapHostForMount(host, onMount) {
81
81
  onMount(handle);
82
82
  return handle;
83
83
  },
84
- notice: (text) => host.notice(text),
84
+ notice: (text, opts) => host.notice(text, opts),
85
85
  suspendForChild: () => host.suspendForChild(),
86
86
  focusNode: (nodeId) => host.focusNode(nodeId),
87
87
  pickReviewFile: (spec) => host.pickReviewFile(spec),
88
88
  };
89
89
  }
90
+ function noticeForBridgeFailure(error) {
91
+ if (error instanceof ReviewTerminalError)
92
+ return terminalRefusalNotice(error);
93
+ if (isReviewPredatesSystem(error)) {
94
+ return 'This review predates canonical review records — cancel it and re-file the review.';
95
+ }
96
+ return error instanceof Error ? error.message : String(error);
97
+ }
90
98
  function isReviewPredatesSystem(error) {
91
99
  return error instanceof ApiError && error.status === 409 && error.code === 'review_predates_system';
92
100
  }
@@ -1,11 +1,7 @@
1
- import type { TUI } from '@earendil-works/pi-tui';
2
1
  import type { SurfaceHost } from '../surfaces/host.js';
3
2
  import type { TicketSummary } from '../../core/human/types.js';
4
- import type { CanvasSource } from '../../core/canvas/source.js';
5
3
  export interface InboxSurfaceOptions {
6
4
  host: SurfaceHost;
7
- tui: TUI;
8
- canvasSource: CanvasSource;
9
5
  /** Injection seams for tests; production passes none. */
10
6
  scan?: () => TicketSummary[];
11
7
  }
@@ -65,8 +65,6 @@ export function createInboxSurface(opts) {
65
65
  const localScan = opts.scan ?? scanInbox;
66
66
  const nextController = new InboxController({
67
67
  host: opts.host,
68
- tui: opts.tui,
69
- canvasSource: opts.canvasSource,
70
68
  onDirty: () => current.handle?.invalidate(),
71
69
  onClosed: close,
72
70
  scan: () => filterVisibleReviewTickets(localScan(), current.visibleIds),
@@ -9,11 +9,16 @@ import type { Component } from '@earendil-works/pi-tui';
9
9
  export interface SurfaceComponent extends Component {
10
10
  /** Set the number of rows assigned by the host for the next render. */
11
11
  setRows(rows: number): void;
12
- /** Consume wheel input at the terminal's 1-based column, when applicable. */
13
- handleWheel?(direction: 'up' | 'down', lines: number, column: number): boolean;
12
+ /** Consume wheel input when applicable. */
13
+ handleWheel?(direction: 'up' | 'down', lines: number): boolean;
14
14
  }
15
15
  /** The identities used for mounted Phase 3 surfaces. */
16
16
  export type SurfaceId = 'inbox' | 'review';
17
+ /** How long a notice stays up. */
18
+ export interface SurfaceNoticeOptions {
19
+ /** Keep the notice up until it is replaced or cleared, with no auto-clear. */
20
+ sticky?: boolean;
21
+ }
17
22
  /**
18
23
  * The only host boundary available to a surface. Surfaces render only through
19
24
  * the mounted component and use {@link notice} as their only output channel;
@@ -29,7 +34,7 @@ export interface SurfaceHost {
29
34
  focus?: Component;
30
35
  }): SurfaceHandle;
31
36
  /** Report transient output through the host; this is the only surface output channel. */
32
- notice(text: string): void;
37
+ notice(text: string, opts?: SurfaceNoticeOptions): void;
33
38
  /**
34
39
  * Temporarily release the terminal for a child process and return a resume
35
40
  * closure. Callers must invoke the closure in a `finally` block.
@@ -49,6 +54,9 @@ export interface SurfaceHost {
49
54
  readonly remote: boolean;
50
55
  /** True when focusing another node's viewer is available. */
51
56
  readonly canFocusNode: boolean;
57
+ /** This viewer's own tmux pane — the target a surface splits against.
58
+ * Undefined outside tmux. */
59
+ readonly selfPane: string | undefined;
52
60
  };
53
61
  }
54
62
  /** A mounted surface's lifecycle controls. */
@@ -4,17 +4,16 @@
4
4
  // (`../api-client.ts`) is what `cliClient()` wires into `CrtrClient` as
5
5
  // `coldStartDiagnostic` — this proves it reads a BOUNDED tail of crtrd.err
6
6
  // (never the whole file) and degrades to `undefined` (not a throw) when the
7
- // log is missing. The two tests below prove the READ itself is bounded (not
8
- // just the returned string) — the prior implementation `readFileSync`'d the
9
- // whole append-only log before slicing, which allocates/blocks unboundedly on
10
- // a runaway log. Node ESM snapshots named imports of builtins at load time
7
+ // log is missing. The final test proves the READ itself is bounded (not just
8
+ // the returned string) — the prior implementation `readFileSync`'d the whole
9
+ // append-only log before slicing, which allocates/blocks unboundedly on a
10
+ // runaway log. Node ESM snapshots named imports of builtins at load time
11
11
  // (mocking `node:fs` per-call does not reach `api-client.ts`'s own import
12
- // binding), so both tests exercise real I/O instead of spying on it: one
13
- // proves the read stays fast/cheap against a huge (sparse) file, the other
14
- // proves the byte offset the read starts from is exact.
12
+ // binding), so it exercises real I/O instead of spying on it: the byte offset
13
+ // the read starts from is exact.
15
14
  import { after, before, test } from 'node:test';
16
15
  import assert from 'node:assert/strict';
17
- import { closeSync, ftruncateSync, mkdtempSync, openSync, rmSync, writeFileSync, writeSync } from 'node:fs';
16
+ import { mkdtempSync, rmSync, writeFileSync } from 'node:fs';
18
17
  import { join } from 'node:path';
19
18
  import { COLD_START_DIAGNOSTIC_TAIL_BYTES, readColdStartDiagnostic } from '../api-client.js';
20
19
  let home;
@@ -55,32 +54,6 @@ test('bounds the tail instead of leaking the whole log', () => {
55
54
  assert.match(diagnostic, /line 4999/);
56
55
  assert.doesNotMatch(diagnostic, /line 0:/);
57
56
  });
58
- test('bounds the READ itself — stays fast/cheap against a huge sparse log instead of materializing it whole', () => {
59
- // A sparse 400MB file: `ftruncateSync` sets the logical size instantly
60
- // without writing 400MB of real content, so creating it is cheap, but a
61
- // `readFileSync` of the whole file would still have to MATERIALIZE all
62
- // 400MB into a JS string — measurably (100ms+) slower than a bounded tail
63
- // read (sub-millisecond). The marker sits inside the final
64
- // `COLD_START_DIAGNOSTIC_TAIL_BYTES` so a correctly bounded read still
65
- // surfaces it.
66
- const path = join(home, 'crtrd.err');
67
- const size = 400 * 1024 * 1024;
68
- const marker = 'Error: EADDRINUSE (huge-log marker)\n';
69
- const fd = openSync(path, 'w');
70
- ftruncateSync(fd, size);
71
- writeSync(fd, Buffer.from(marker), 0, marker.length, size - 200);
72
- closeSync(fd);
73
- const startedAt = performance.now();
74
- const diagnostic = readColdStartDiagnostic();
75
- const elapsedMs = performance.now() - startedAt;
76
- assert.match(diagnostic ?? '', /EADDRINUSE \(huge-log marker\)/);
77
- // A bounded 4KB read finishes in low single-digit ms; a whole-file
78
- // `readFileSync` of 400MB measured ~150-175ms locally (and scales with log
79
- // size, which is exactly the unbounded-resource bug) — 100ms leaves ample
80
- // margin above the bounded read and below the whole-file read even on a
81
- // slower CI runner.
82
- assert.ok(elapsedMs < 100, `expected a bounded read well under 100ms, took ${elapsedMs.toFixed(2)}ms`);
83
- });
84
57
  test('bounds the READ itself — the tail window starts at an exact byte offset, not an in-memory slice', () => {
85
58
  // Bytes immediately BEFORE the tail window must never be read at all, not
86
59
  // just excluded from the output — place a sentinel there and one at the