@north-light/crouter 0.3.172 → 0.3.174

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 (673) 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} +106 -177
  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 +55 -0
  46. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.ts +60 -0
  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/node/bash.d.ts +1 -0
  138. package/dist/commands/node/bash.js +198 -0
  139. package/dist/commands/node/create.d.ts +23 -0
  140. package/dist/commands/node/create.js +207 -0
  141. package/dist/commands/node/inspect.d.ts +2 -0
  142. package/dist/commands/node/inspect.js +302 -0
  143. package/dist/commands/node/lifecycle.d.ts +4 -0
  144. package/dist/commands/node/lifecycle.js +415 -0
  145. package/dist/commands/node/message.d.ts +1 -0
  146. package/dist/commands/node/message.js +164 -0
  147. package/dist/commands/node/pyramid.d.ts +2 -0
  148. package/dist/commands/node/pyramid.js +79 -0
  149. package/dist/commands/node/subscription.d.ts +1 -0
  150. package/dist/commands/node/subscription.js +82 -0
  151. package/dist/commands/node/wait.d.ts +1 -0
  152. package/dist/commands/node/wait.js +159 -0
  153. package/dist/commands/node-lifecycle-revive.js +10 -57
  154. package/dist/commands/node.d.ts +0 -42
  155. package/dist/commands/node.js +11 -2065
  156. package/dist/commands/search.js +1 -1
  157. package/dist/commands/surface/node/cycle.d.ts +1 -0
  158. package/dist/commands/surface/node/cycle.js +83 -0
  159. package/dist/commands/surface/node/focus.d.ts +1 -0
  160. package/dist/commands/surface/node/focus.js +67 -0
  161. package/dist/commands/surface/node/id.d.ts +1 -0
  162. package/dist/commands/surface/node/id.js +38 -0
  163. package/dist/commands/surface/node/pin.d.ts +1 -0
  164. package/dist/commands/surface/node/pin.js +42 -0
  165. package/dist/commands/surface/node/placement.d.ts +46 -0
  166. package/dist/commands/surface/node/placement.js +124 -0
  167. package/dist/commands/surface-node.js +4 -1
  168. package/dist/commands/surface-reload.js +1 -2
  169. package/dist/commands/surface-tmux-spread.js +1 -1
  170. package/dist/commands/surface.js +5 -20
  171. package/dist/commands/sys/__tests__/setup-core.test.js +18 -271
  172. package/dist/commands/sys/config.js +6 -6
  173. package/dist/commands/sys/logs.js +1 -1
  174. package/dist/commands/sys/panels/broker-limits-panel.d.ts +17 -0
  175. package/dist/commands/sys/panels/broker-limits-panel.js +104 -0
  176. package/dist/commands/sys/panels/dependencies-panel.d.ts +14 -0
  177. package/dist/commands/sys/panels/dependencies-panel.js +80 -0
  178. package/dist/commands/sys/panels/keybindings-panel.d.ts +56 -0
  179. package/dist/commands/sys/panels/keybindings-panel.js +703 -0
  180. package/dist/commands/sys/panels/keys-panel.d.ts +16 -0
  181. package/dist/commands/sys/panels/keys-panel.js +60 -0
  182. package/dist/commands/sys/panels/models-panel.d.ts +77 -0
  183. package/dist/commands/sys/panels/models-panel.js +647 -0
  184. package/dist/commands/sys/panels/panel.d.ts +45 -0
  185. package/dist/commands/sys/panels/panel.js +137 -0
  186. package/dist/commands/sys/panels/plugins-panel.d.ts +16 -0
  187. package/dist/commands/sys/panels/plugins-panel.js +80 -0
  188. package/dist/commands/sys/panels/prefs-panel.d.ts +21 -0
  189. package/dist/commands/sys/panels/prefs-panel.js +85 -0
  190. package/dist/commands/sys/panels/provider-panel.d.ts +62 -0
  191. package/dist/commands/sys/panels/provider-panel.js +538 -0
  192. package/dist/commands/sys/settings-shell.d.ts +55 -0
  193. package/dist/commands/sys/settings-shell.js +400 -0
  194. package/dist/commands/sys/settings.d.ts +2 -0
  195. package/dist/commands/sys/settings.js +31 -0
  196. package/dist/commands/sys/setup-core.d.ts +3 -33
  197. package/dist/commands/sys/setup-core.js +27 -78
  198. package/dist/commands/sys/setup-settings-runner.d.ts +24 -0
  199. package/dist/commands/sys/setup-settings-runner.js +63 -0
  200. package/dist/commands/sys/setup-wizard.d.ts +26 -125
  201. package/dist/commands/sys/setup-wizard.js +209 -2473
  202. package/dist/commands/sys/setup.js +5 -7
  203. package/dist/commands/sys.js +3 -2
  204. package/dist/core/__tests__/broker-extension-canvas-db-boundary.test.js +50 -0
  205. package/dist/core/__tests__/broker-launch-candidates.test.js +20 -9
  206. package/dist/core/__tests__/broker-preflight.test.js +1 -1
  207. package/dist/core/__tests__/canvas-inbox-watcher-hold.test.js +108 -27
  208. package/dist/core/__tests__/canvas-inbox-watcher.test.js +14 -0
  209. package/dist/core/__tests__/canvas.test.js +2 -36
  210. package/dist/core/__tests__/close.test.js +14 -3
  211. package/dist/core/__tests__/context-intro.test.js +32 -143
  212. package/dist/core/__tests__/cron-broker-capacity.test.js +22 -3
  213. package/dist/core/__tests__/daemon-boot.test.js +2 -20
  214. package/dist/core/__tests__/daemon-wedge.test.js +1 -1
  215. package/dist/core/__tests__/dead-node-policy-table.test.js +1 -18
  216. package/dist/core/__tests__/fixtures/fake-engine.d.ts +1 -1
  217. package/dist/core/__tests__/fixtures/fake-engine.js +2 -2
  218. package/dist/core/__tests__/fixtures/fake-pi-host.js +2 -2
  219. package/dist/core/__tests__/focuses.test.js +4 -98
  220. package/dist/core/__tests__/helpers/broker-clients.d.ts +0 -3
  221. package/dist/core/__tests__/helpers/broker-clients.js +0 -14
  222. package/dist/core/__tests__/helpers/harness.d.ts +0 -8
  223. package/dist/core/__tests__/helpers/harness.js +7 -87
  224. package/dist/core/__tests__/helpers/viewer-panes.js +1 -1
  225. package/dist/core/__tests__/inline-memory-refs.test.js +5 -134
  226. package/dist/core/__tests__/kickoff.test.js +1 -1
  227. package/dist/core/__tests__/memory-resolver-precedence.test.js +29 -1
  228. package/dist/core/__tests__/migration.test.js +35 -48
  229. package/dist/core/__tests__/on-read-dedup-resume.test.js +22 -12
  230. package/dist/core/__tests__/passive-subscription.test.js +26 -49
  231. package/dist/core/__tests__/preview-registry-sync.test.js +1 -2
  232. package/dist/core/__tests__/prune.test.js +94 -1
  233. package/dist/core/__tests__/review-model-floor.test.js +0 -32
  234. package/dist/core/__tests__/seam/broker-attach-multiclient.test.js +255 -0
  235. package/dist/core/__tests__/{full → seam}/broker-attach-stream.test.js +39 -7
  236. package/dist/core/__tests__/{full → seam}/broker-crash-teardown.test.js +30 -29
  237. package/dist/core/__tests__/{full → seam}/broker-pane-resolution.test.js +54 -5
  238. package/dist/core/__tests__/{full → seam}/broker-provider-retry.test.js +134 -82
  239. package/dist/core/__tests__/{full → seam}/broker-whip-interrupt.test.js +15 -4
  240. package/dist/core/__tests__/{full/idle-release-settlement.test.js → seam/dormancy-release.test.js} +69 -17
  241. package/dist/core/__tests__/{full/yield-message-transaction.test.js → seam/yield-refresh-transaction.test.js} +31 -9
  242. package/dist/core/__tests__/secrets.test.js +1 -7
  243. package/dist/core/__tests__/{broker-fork-seam.test.js → serial/broker-fork-seam.test.js} +58 -7
  244. package/dist/core/__tests__/{broker-sdk-wiring.test.js → serial/broker-sdk-wiring.test.js} +18 -162
  245. package/dist/core/__tests__/{broker-snapshot-history.test.js → serial/broker-snapshot-history.test.js} +9 -9
  246. package/dist/core/__tests__/{command-plugins.test.js → serial/command-plugins.test.js} +105 -15
  247. package/dist/core/__tests__/{deferred-no-wake.test.js → serial/deferred-no-wake.test.js} +23 -20
  248. package/dist/core/__tests__/{flagship-lifecycle.test.js → serial/flagship-lifecycle.test.js} +7 -7
  249. package/dist/core/__tests__/{host-teardown-process-group.test.js → serial/host-teardown-process-group.test.js} +6 -6
  250. package/dist/core/__tests__/{human-deliver-e2e.test.js → serial/human-deliver-e2e.test.js} +12 -12
  251. package/dist/core/__tests__/{live-mutation.test.js → serial/live-mutation.test.js} +5 -5
  252. package/dist/core/__tests__/{refresh-stall-recycle.test.js → serial/refresh-stall-recycle.test.js} +5 -14
  253. package/dist/core/__tests__/{revive.test.js → serial/revive.test.js} +15 -100
  254. package/dist/core/__tests__/{spawn-root.test.js → serial/spawn-root.test.js} +32 -15
  255. package/dist/core/__tests__/serial/subscription-delivery.test.js +126 -0
  256. package/dist/core/__tests__/serial/tmux-surface.test.js +256 -0
  257. package/dist/core/__tests__/{worktree.test.js → serial/worktree.test.js} +15 -15
  258. package/dist/core/__tests__/session-model.test.js +0 -18
  259. package/dist/core/__tests__/spawn-worktree-id-conflict.test.js +9 -0
  260. package/dist/core/__tests__/watchdog-abort-arms-retry.test.js +50 -0
  261. package/dist/core/broker-client/__tests__/transport-relay.test.js +15 -16
  262. package/dist/core/broker-client/__tests__/transport-socket.test.js +28 -0
  263. package/dist/core/broker-client/client.d.ts +2 -2
  264. package/dist/core/broker-client/client.js +4 -7
  265. package/dist/core/broker-client/transport-relay.d.ts +13 -19
  266. package/dist/core/broker-client/transport-relay.js +19 -34
  267. package/dist/core/broker-client/transport-socket.d.ts +2 -2
  268. package/dist/core/broker-client/transport-socket.js +9 -2
  269. package/dist/core/broker-client/transport.d.ts +7 -3
  270. package/dist/core/broker-client/transport.js +4 -4
  271. package/dist/core/canvas/__tests__/attention.test.js +1 -18
  272. package/dist/core/canvas/__tests__/remote-canvas-source.test.js +7 -64
  273. package/dist/core/canvas/__tests__/remote-transport.test.js +2 -3
  274. package/dist/core/canvas/__tests__/render-remote.test.js +7 -52
  275. package/dist/core/canvas/browse/app.d.ts +2 -17
  276. package/dist/core/canvas/browse/app.js +16 -88
  277. package/dist/core/canvas/browse/model.d.ts +0 -4
  278. package/dist/core/canvas/browse/model.js +1 -12
  279. package/dist/core/canvas/browse/render.js +6 -3
  280. package/dist/core/canvas/crons.d.ts +8 -5
  281. package/dist/core/canvas/crons.js +7 -6
  282. package/dist/core/canvas/extensions.d.ts +7 -3
  283. package/dist/core/canvas/extensions.js +16 -4
  284. package/dist/core/canvas/nav-model.d.ts +0 -4
  285. package/dist/core/canvas/nav-model.js +2 -14
  286. package/dist/core/canvas/node-order.d.ts +3 -0
  287. package/dist/core/canvas/node-order.js +12 -0
  288. package/dist/core/canvas/remote-canvas-source.d.ts +3 -6
  289. package/dist/core/canvas/remote-canvas-source.js +8 -15
  290. package/dist/core/command.js +11 -4
  291. package/dist/core/config.js +3 -1
  292. package/dist/core/events/envelope.js +1 -1
  293. package/dist/core/events/read.js +7 -21
  294. package/dist/core/events/source.d.ts +0 -2
  295. package/dist/core/events/source.js +0 -16
  296. package/dist/core/events/types.d.ts +1 -1
  297. package/dist/core/fault-classifier.d.ts +1 -1
  298. package/dist/core/feed/passive.d.ts +0 -11
  299. package/dist/core/feed/passive.js +1 -62
  300. package/dist/core/human/__tests__/{inbox-core.test.js → serial/inbox-core.test.js} +6 -6
  301. package/dist/core/keybindings/__tests__/resolve.test.js +1 -96
  302. package/dist/core/keybindings/background-bash.js +3 -4
  303. package/dist/core/keybindings/catalog.js +1 -1
  304. package/dist/core/memory/inline-ref-grammar.js +3 -3
  305. package/dist/core/memory-resolver.d.ts +11 -25
  306. package/dist/core/memory-resolver.js +51 -33
  307. package/dist/core/model-routes.d.ts +15 -0
  308. package/dist/core/model-routes.js +12 -0
  309. package/dist/core/pool-credential-store.js +1 -1
  310. package/dist/core/preview-registry.js +8 -9
  311. package/dist/core/profiles/__tests__/root-profile.test.js +4 -14
  312. package/dist/core/review/realize.d.ts +0 -13
  313. package/dist/core/review/realize.js +0 -40
  314. package/dist/core/review/types.d.ts +1 -1
  315. package/dist/core/runtime/__tests__/engine-route.test.js +2 -2
  316. package/dist/core/runtime/bearings.js +1 -11
  317. package/dist/core/runtime/broker/client-registry.d.ts +33 -0
  318. package/dist/core/runtime/broker/client-registry.js +164 -0
  319. package/dist/core/runtime/broker/daemon-ops.d.ts +19 -0
  320. package/dist/core/runtime/broker/daemon-ops.js +49 -0
  321. package/dist/core/runtime/broker/event-projection.d.ts +42 -0
  322. package/dist/core/runtime/broker/event-projection.js +178 -0
  323. package/dist/core/runtime/broker/fault-retry.d.ts +39 -0
  324. package/dist/core/runtime/broker/fault-retry.js +277 -0
  325. package/dist/core/runtime/broker/frame-dispatch.d.ts +238 -0
  326. package/dist/core/runtime/broker/frame-dispatch.js +1537 -0
  327. package/dist/core/runtime/broker/inbox.d.ts +22 -0
  328. package/dist/core/runtime/broker/inbox.js +167 -0
  329. package/dist/core/runtime/broker/passive.d.ts +16 -0
  330. package/dist/core/runtime/broker/passive.js +44 -0
  331. package/dist/core/runtime/broker/read-ops.d.ts +23 -0
  332. package/dist/core/runtime/broker/read-ops.js +150 -0
  333. package/dist/core/runtime/broker/rebind.d.ts +74 -0
  334. package/dist/core/runtime/broker/rebind.js +211 -0
  335. package/dist/core/runtime/broker/tool-groups.d.ts +39 -0
  336. package/dist/core/runtime/broker/tool-groups.js +244 -0
  337. package/dist/core/runtime/broker-extension-render.d.ts +11 -0
  338. package/dist/core/runtime/broker-extension-render.js +181 -0
  339. package/dist/core/runtime/broker-persona-guidance.d.ts +13 -0
  340. package/dist/core/runtime/broker-persona-guidance.js +58 -0
  341. package/dist/core/runtime/broker-protocol.d.ts +1 -1
  342. package/dist/core/runtime/broker-protocol.js +1 -1
  343. package/dist/core/runtime/broker.d.ts +5 -196
  344. package/dist/core/runtime/broker.js +276 -3059
  345. package/dist/core/runtime/canvas-extensions.js +11 -2
  346. package/dist/core/runtime/fault.js +1 -1
  347. package/dist/core/runtime/model-selection.d.ts +9 -0
  348. package/dist/core/runtime/model-selection.js +12 -0
  349. package/dist/core/runtime/model-swap.d.ts +3 -3
  350. package/dist/core/runtime/model-swap.js +33 -25
  351. package/dist/core/runtime/placement-tmux.d.ts +3 -14
  352. package/dist/core/runtime/placement-tmux.js +11 -80
  353. package/dist/core/runtime/placement.d.ts +4 -2
  354. package/dist/core/runtime/placement.js +7 -12
  355. package/dist/core/runtime/promote.d.ts +14 -1
  356. package/dist/core/runtime/promote.js +1 -1
  357. package/dist/core/runtime/reset.d.ts +1 -1
  358. package/dist/core/runtime/roadmap.js +1 -1
  359. package/dist/core/runtime/spawn.d.ts +8 -0
  360. package/dist/core/runtime/spawn.js +36 -6
  361. package/dist/core/runtime/stop-guard.d.ts +4 -3
  362. package/dist/core/runtime/stop-guard.js +36 -18
  363. package/dist/core/runtime/stop-signals.d.ts +4 -1
  364. package/dist/core/runtime/stream-watchdog.js +4 -5
  365. package/dist/core/runtime/structured-output.d.ts +15 -2
  366. package/dist/core/runtime/structured-output.js +35 -12
  367. package/dist/core/runtime/tmux-bindings.d.ts +25 -0
  368. package/dist/core/runtime/tmux-bindings.js +682 -0
  369. package/dist/core/runtime/tmux-chrome.d.ts +2 -1
  370. package/dist/core/runtime/tmux-chrome.js +3 -2
  371. package/dist/core/runtime/{tmux.d.ts → tmux-driver.d.ts} +18 -26
  372. package/dist/core/runtime/tmux-driver.js +598 -0
  373. package/dist/core/runtime/view-socket.d.ts +14 -0
  374. package/dist/core/runtime/view-socket.js +83 -0
  375. package/dist/core/session-model/session-state.d.ts +1 -2
  376. package/dist/core/session-model/session-state.js +5 -8
  377. package/dist/core/spawn.d.ts +1 -1
  378. package/dist/core/spawn.js +2 -2
  379. package/dist/core/substrate/gate.d.ts +1 -1
  380. package/dist/core/substrate/on-read-pure.d.ts +7 -0
  381. package/dist/core/substrate/on-read-pure.js +272 -0
  382. package/dist/core/termrender/termrender.js +32 -2
  383. package/dist/core/user-settings.d.ts +23 -1
  384. package/dist/core/user-settings.js +18 -1
  385. package/dist/daemon/api/__tests__/node-model-validation.test.js +134 -0
  386. package/dist/daemon/api/__tests__/review-terminal-conflict.test.js +98 -0
  387. package/dist/daemon/api/__tests__/{full → seam}/api-server.test.js +6 -48
  388. package/dist/daemon/api/__tests__/{full → seam}/b10-attach-modelauth.test.js +17 -44
  389. package/dist/daemon/api/__tests__/{full/push-parity.test.js → seam/leaf-api-parity.test.js} +61 -42
  390. package/dist/daemon/api/bridge.js +40 -81
  391. package/dist/daemon/api/handlers/broker-ops.d.ts +2 -0
  392. package/dist/daemon/api/handlers/broker-ops.js +383 -0
  393. package/dist/daemon/api/handlers/crons.js +9 -4
  394. package/dist/daemon/api/handlers/files.js +6 -7
  395. package/dist/daemon/api/handlers/inbox.js +2 -340
  396. package/dist/daemon/api/handlers/nodes.d.ts +10 -1
  397. package/dist/daemon/api/handlers/nodes.js +74 -39
  398. package/dist/daemon/api/handlers/review-comments.js +5 -1
  399. package/dist/daemon/api/handlers/reviews.js +0 -19
  400. package/dist/daemon/api/map.js +25 -4
  401. package/dist/daemon/api/router.js +2 -3
  402. package/dist/daemon/api/server.js +5 -7
  403. package/dist/daemon/cron-run.d.ts +4 -0
  404. package/dist/daemon/cron-run.js +30 -13
  405. package/dist/daemon/crtrd.d.ts +3 -58
  406. package/dist/daemon/crtrd.js +28 -1244
  407. package/dist/daemon/manage.js +0 -1
  408. package/dist/daemon/reconcilers/broker-supervision.d.ts +50 -0
  409. package/dist/daemon/reconcilers/broker-supervision.js +549 -0
  410. package/dist/daemon/reconcilers/cron-lane.d.ts +10 -0
  411. package/dist/daemon/reconcilers/cron-lane.js +32 -0
  412. package/dist/daemon/reconcilers/dormant-inbox.d.ts +18 -0
  413. package/dist/daemon/reconcilers/dormant-inbox.js +143 -0
  414. package/dist/daemon/reconcilers/storage-maintenance.d.ts +22 -0
  415. package/dist/daemon/reconcilers/storage-maintenance.js +213 -0
  416. package/dist/daemon/review/finish.js +2 -5
  417. package/dist/pi-extensions/__tests__/canvas-context-intro.test.js +34 -53
  418. package/dist/pi-extensions/__tests__/canvas-recap.test.js +16 -113
  419. package/dist/pi-extensions/__tests__/canvas-stophook-agentend.test.js +72 -99
  420. package/dist/pi-extensions/__tests__/canvas-stophook-context-nudge.test.js +29 -12
  421. package/dist/pi-extensions/broker-local.d.ts +20 -0
  422. package/dist/pi-extensions/broker-local.js +89 -0
  423. package/dist/pi-extensions/canvas-context-intro.d.ts +3 -3
  424. package/dist/pi-extensions/canvas-context-intro.js +22 -11
  425. package/dist/pi-extensions/canvas-doc-substrate.js +17 -34
  426. package/dist/pi-extensions/canvas-goal-capture.js +7 -12
  427. package/dist/pi-extensions/canvas-inbox-watcher.js +124 -139
  428. package/dist/pi-extensions/canvas-passive-context.d.ts +3 -3
  429. package/dist/pi-extensions/canvas-passive-context.js +22 -18
  430. package/dist/pi-extensions/canvas-recap.d.ts +2 -2
  431. package/dist/pi-extensions/canvas-recap.js +48 -21
  432. package/dist/pi-extensions/canvas-review-boundary.js +10 -4
  433. package/dist/pi-extensions/canvas-stophook.d.ts +0 -5
  434. package/dist/pi-extensions/canvas-stophook.js +149 -431
  435. package/dist/pi-extensions/canvas-structured-output.js +52 -30
  436. package/dist/pi-extensions/envelope-merge.d.ts +13 -0
  437. package/dist/pi-extensions/envelope-merge.js +29 -0
  438. package/dist/shared/working-activity.d.ts +3 -2
  439. package/dist/shared/working-activity.js +3 -2
  440. package/dist/types.d.ts +6 -5
  441. package/dist/types.js +2 -2
  442. package/docs/compat/hearth-crtr-v1.md +4 -12
  443. package/docs/compat/hearth-crtr-v2.md +3 -11
  444. package/docs/compat/hearth-crtr-v3.md +4 -12
  445. package/docs/compat/hearth-crtr-v4.md +3 -11
  446. package/docs/compat/hearth-crtr-v5.md +3 -11
  447. package/docs/public-api.md +3 -7
  448. package/package.json +7 -49
  449. package/runtime.lock.json +2766 -14533
  450. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/__tests__/claude-plugin-commands.test.ts +0 -49
  451. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/__tests__/memory-slash-commands.test.ts +0 -194
  452. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/__tests__/statusline.test.ts +0 -68
  453. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/frontmatter-rules/test.ts +0 -119
  454. package/dist/clients/attach/__tests__/attach-chrome-remote.test.js +0 -439
  455. package/dist/clients/attach/__tests__/attach-keybindings.test.js +0 -170
  456. package/dist/clients/attach/__tests__/crtr-output-coverage.test.js +0 -57
  457. package/dist/clients/attach/__tests__/editor-frame-title.test.js +0 -19
  458. package/dist/clients/attach/__tests__/input-controller-extension-command.test.js +0 -32
  459. package/dist/clients/attach/__tests__/markdown-headings.test.js +0 -35
  460. package/dist/clients/attach/__tests__/session-identity-refresh.test.js +0 -32
  461. package/dist/clients/conversation/conversation.d.ts +0 -65
  462. package/dist/clients/conversation/conversation.js +0 -318
  463. package/dist/clients/conversation/frames.d.ts +0 -30
  464. package/dist/clients/conversation/frames.js +0 -52
  465. package/dist/clients/conversation/region.d.ts +0 -51
  466. package/dist/clients/conversation/region.js +0 -265
  467. package/dist/clients/inbox/__tests__/inbox-controller.test.js +0 -247
  468. package/dist/clients/inbox/__tests__/mount-panel.test.js +0 -776
  469. package/dist/clients/inbox/review/__tests__/remap.test.js +0 -196
  470. package/dist/clients/inbox/review/columns.d.ts +0 -22
  471. package/dist/clients/inbox/review/columns.js +0 -40
  472. package/dist/clients/inbox/review/composition.d.ts +0 -60
  473. package/dist/clients/inbox/review/composition.js +0 -278
  474. package/dist/clients/inbox/review/document-region.d.ts +0 -120
  475. package/dist/clients/surfaces/region.d.ts +0 -16
  476. package/dist/clients/web/__tests__/push-engine.test.js +0 -158
  477. package/dist/clients/web/__tests__/push-registry.test.d.ts +0 -1
  478. package/dist/clients/web/__tests__/push-registry.test.js +0 -177
  479. package/dist/clients/web/dev-server.d.ts +0 -7
  480. package/dist/clients/web/dev-server.js +0 -46
  481. package/dist/clients/web/events.d.ts +0 -19
  482. package/dist/clients/web/events.js +0 -163
  483. package/dist/clients/web/push-engine.d.ts +0 -44
  484. package/dist/clients/web/push-engine.js +0 -125
  485. package/dist/clients/web/push-registry.d.ts +0 -85
  486. package/dist/clients/web/push-registry.js +0 -373
  487. package/dist/clients/web/server.d.ts +0 -19
  488. package/dist/clients/web/server.js +0 -661
  489. package/dist/clients/web/web-client/shared/protocol.d.ts +0 -214
  490. package/dist/clients/web/web-client/shared/protocol.js +0 -8
  491. package/dist/clients/web/web-cmd.d.ts +0 -2
  492. package/dist/clients/web/web-cmd.js +0 -141
  493. package/dist/commands/__tests__/api-canvas-source.test.d.ts +0 -1
  494. package/dist/commands/__tests__/api-canvas-source.test.js +0 -37
  495. package/dist/commands/__tests__/canvas-config.test.d.ts +0 -1
  496. package/dist/commands/__tests__/canvas-config.test.js +0 -107
  497. package/dist/commands/__tests__/node-no-kickoff-flag.test.d.ts +0 -1
  498. package/dist/commands/__tests__/node-no-kickoff-flag.test.js +0 -73
  499. package/dist/commands/__tests__/node-worktree-flag.test.d.ts +0 -1
  500. package/dist/commands/__tests__/node-worktree-flag.test.js +0 -49
  501. package/dist/commands/__tests__/search-contents.test.d.ts +0 -1
  502. package/dist/commands/__tests__/search-contents.test.js +0 -52
  503. package/dist/commands/memory/__tests__/lint.test.d.ts +0 -1
  504. package/dist/commands/memory/__tests__/lint.test.js +0 -15
  505. package/dist/commands/sys/__tests__/config-broker-thresholds.test.d.ts +0 -1
  506. package/dist/commands/sys/__tests__/config-broker-thresholds.test.js +0 -95
  507. package/dist/commands/sys/__tests__/config-keybindings.test.d.ts +0 -1
  508. package/dist/commands/sys/__tests__/config-keybindings.test.js +0 -55
  509. package/dist/commands/sys/__tests__/helpers/setup-runtime.d.ts +0 -5
  510. package/dist/commands/sys/__tests__/helpers/setup-runtime.js +0 -19
  511. package/dist/commands/sys/__tests__/setup-front-door.test.d.ts +0 -1
  512. package/dist/commands/sys/__tests__/setup-front-door.test.js +0 -102
  513. package/dist/commands/sys/__tests__/setup-models.test.d.ts +0 -1
  514. package/dist/commands/sys/__tests__/setup-models.test.js +0 -205
  515. package/dist/commands/sys/__tests__/setup-providers-viewport.test.d.ts +0 -1
  516. package/dist/commands/sys/__tests__/setup-providers-viewport.test.js +0 -155
  517. package/dist/commands/sys/__tests__/sync-deps.test.d.ts +0 -1
  518. package/dist/commands/sys/__tests__/sync-deps.test.js +0 -179
  519. package/dist/commands/sys/__tests__/sync-import.test.d.ts +0 -1
  520. package/dist/commands/sys/__tests__/sync-import.test.js +0 -315
  521. package/dist/core/__tests__/base-worker-prompt.test.d.ts +0 -1
  522. package/dist/core/__tests__/base-worker-prompt.test.js +0 -57
  523. package/dist/core/__tests__/command-plugins-surfaces.test.d.ts +0 -1
  524. package/dist/core/__tests__/command-plugins-surfaces.test.js +0 -359
  525. package/dist/core/__tests__/connection-reconnect-resume.test.d.ts +0 -1
  526. package/dist/core/__tests__/connection-reconnect-resume.test.js +0 -36
  527. package/dist/core/__tests__/finalization-migration.test.d.ts +0 -1
  528. package/dist/core/__tests__/finalization-migration.test.js +0 -38
  529. package/dist/core/__tests__/fixtures/extra-extension.d.ts +0 -1
  530. package/dist/core/__tests__/fixtures/extra-extension.js +0 -3
  531. package/dist/core/__tests__/fixtures/spawn-proof-target.test.d.ts +0 -1
  532. package/dist/core/__tests__/fixtures/spawn-proof-target.test.js +0 -15
  533. package/dist/core/__tests__/fork.test.d.ts +0 -1
  534. package/dist/core/__tests__/fork.test.js +0 -108
  535. package/dist/core/__tests__/full/broker-attach-limits.test.d.ts +0 -1
  536. package/dist/core/__tests__/full/broker-attach-limits.test.js +0 -147
  537. package/dist/core/__tests__/full/broker-deliver-ack.test.d.ts +0 -1
  538. package/dist/core/__tests__/full/broker-deliver-ack.test.js +0 -73
  539. package/dist/core/__tests__/full/broker-dialogs.test.d.ts +0 -1
  540. package/dist/core/__tests__/full/broker-dialogs.test.js +0 -180
  541. package/dist/core/__tests__/full/broker-display-snapshot.test.d.ts +0 -1
  542. package/dist/core/__tests__/full/broker-display-snapshot.test.js +0 -75
  543. package/dist/core/__tests__/full/broker-dormant-wake.test.d.ts +0 -1
  544. package/dist/core/__tests__/full/broker-dormant-wake.test.js +0 -130
  545. package/dist/core/__tests__/full/broker-model-changed-broadcast.test.d.ts +0 -1
  546. package/dist/core/__tests__/full/broker-model-changed-broadcast.test.js +0 -57
  547. package/dist/core/__tests__/full/broker-navigate-tree-rewelcome.test.d.ts +0 -1
  548. package/dist/core/__tests__/full/broker-navigate-tree-rewelcome.test.js +0 -80
  549. package/dist/core/__tests__/full/cascade-close.test.d.ts +0 -1
  550. package/dist/core/__tests__/full/cascade-close.test.js +0 -240
  551. package/dist/core/__tests__/full/detach-focus.test.d.ts +0 -1
  552. package/dist/core/__tests__/full/detach-focus.test.js +0 -126
  553. package/dist/core/__tests__/full/idle-release-settlement.test.d.ts +0 -1
  554. package/dist/core/__tests__/full/issue-146-yield-spawn-focus.test.d.ts +0 -1
  555. package/dist/core/__tests__/full/issue-146-yield-spawn-focus.test.js +0 -107
  556. package/dist/core/__tests__/full/park-clock-release.test.d.ts +0 -1
  557. package/dist/core/__tests__/full/park-clock-release.test.js +0 -56
  558. package/dist/core/__tests__/full/yield-message-transaction.test.d.ts +0 -1
  559. package/dist/core/__tests__/memory-index-render.test.d.ts +0 -1
  560. package/dist/core/__tests__/memory-index-render.test.js +0 -60
  561. package/dist/core/__tests__/model-routes.test.d.ts +0 -1
  562. package/dist/core/__tests__/model-routes.test.js +0 -41
  563. package/dist/core/__tests__/on-read-identity.test.d.ts +0 -1
  564. package/dist/core/__tests__/on-read-identity.test.js +0 -61
  565. package/dist/core/__tests__/phase4-review-migration.test.d.ts +0 -1
  566. package/dist/core/__tests__/phase4-review-migration.test.js +0 -100
  567. package/dist/core/__tests__/prune-to-limit.test.d.ts +0 -1
  568. package/dist/core/__tests__/prune-to-limit.test.js +0 -126
  569. package/dist/core/__tests__/reset.test.d.ts +0 -1
  570. package/dist/core/__tests__/reset.test.js +0 -69
  571. package/dist/core/__tests__/spawn-no-kickoff.test.d.ts +0 -1
  572. package/dist/core/__tests__/spawn-no-kickoff.test.js +0 -115
  573. package/dist/core/__tests__/steer-note.test.d.ts +0 -1
  574. package/dist/core/__tests__/steer-note.test.js +0 -41
  575. package/dist/core/__tests__/subcommand-tier.test.d.ts +0 -1
  576. package/dist/core/__tests__/subcommand-tier.test.js +0 -99
  577. package/dist/core/__tests__/subscription-delivery.test.js +0 -211
  578. package/dist/core/__tests__/test-runner-cheap-sharding.test.d.ts +0 -1
  579. package/dist/core/__tests__/test-runner-cheap-sharding.test.js +0 -97
  580. package/dist/core/__tests__/tmux-surface.test.js +0 -484
  581. package/dist/core/__tests__/wake-bearings.test.d.ts +0 -1
  582. package/dist/core/__tests__/wake-bearings.test.js +0 -102
  583. package/dist/core/canvas/__tests__/remote-event-stream.test.d.ts +0 -1
  584. package/dist/core/canvas/__tests__/remote-event-stream.test.js +0 -146
  585. package/dist/core/canvas/__tests__/source-resolve.test.d.ts +0 -1
  586. package/dist/core/canvas/__tests__/source-resolve.test.js +0 -77
  587. package/dist/core/canvas/browse/__tests__/model.test.d.ts +0 -1
  588. package/dist/core/canvas/browse/__tests__/model.test.js +0 -290
  589. package/dist/core/canvas/browse/__tests__/rebuild-coalescer.test.d.ts +0 -1
  590. package/dist/core/canvas/browse/__tests__/rebuild-coalescer.test.js +0 -134
  591. package/dist/core/canvas/browse/__tests__/render.test.d.ts +0 -1
  592. package/dist/core/canvas/browse/__tests__/render.test.js +0 -111
  593. package/dist/core/canvas/browse/rebuild-coalescer.d.ts +0 -7
  594. package/dist/core/canvas/browse/rebuild-coalescer.js +0 -61
  595. package/dist/core/canvas/remote-event-stream.d.ts +0 -24
  596. package/dist/core/canvas/remote-event-stream.js +0 -94
  597. package/dist/core/feed/__tests__/coalesce-human.test.d.ts +0 -1
  598. package/dist/core/feed/__tests__/coalesce-human.test.js +0 -36
  599. package/dist/core/feed/__tests__/empty-node-guard.test.d.ts +0 -1
  600. package/dist/core/feed/__tests__/empty-node-guard.test.js +0 -45
  601. package/dist/core/host-exports/__tests__/export-prunes-boot-skill.test.d.ts +0 -1
  602. package/dist/core/host-exports/__tests__/export-prunes-boot-skill.test.js +0 -84
  603. package/dist/core/human/__tests__/visible-paths.test.d.ts +0 -1
  604. package/dist/core/human/__tests__/visible-paths.test.js +0 -28
  605. package/dist/core/keybindings/__tests__/inbox-affordance.test.d.ts +0 -1
  606. package/dist/core/keybindings/__tests__/inbox-affordance.test.js +0 -38
  607. package/dist/core/review/__tests__/project.test.d.ts +0 -1
  608. package/dist/core/review/__tests__/project.test.js +0 -71
  609. package/dist/core/runtime/__tests__/command-expansion.test.d.ts +0 -1
  610. package/dist/core/runtime/__tests__/command-expansion.test.js +0 -25
  611. package/dist/core/runtime/__tests__/session-visibility.test.d.ts +0 -1
  612. package/dist/core/runtime/__tests__/session-visibility.test.js +0 -119
  613. package/dist/core/runtime/__tests__/spawn-at-given-id.test.d.ts +0 -1
  614. package/dist/core/runtime/__tests__/spawn-at-given-id.test.js +0 -34
  615. package/dist/core/runtime/tmux.js +0 -1314
  616. package/dist/daemon/api/__tests__/full/push-parity.test.d.ts +0 -1
  617. package/dist/daemon/api/__tests__/full/worktree-parity.test.d.ts +0 -1
  618. package/dist/daemon/api/__tests__/full/worktree-parity.test.js +0 -160
  619. package/dist/daemon/api/__tests__/inbox.test.d.ts +0 -1
  620. package/dist/daemon/api/__tests__/inbox.test.js +0 -489
  621. package/dist/web-client/apple-touch-icon.png +0 -0
  622. package/dist/web-client/assets/fragment-mono-latin-400-normal-BYwT3kSJ.woff +0 -0
  623. package/dist/web-client/assets/fragment-mono-latin-400-normal-yxdJ5AmL.woff2 +0 -0
  624. package/dist/web-client/assets/fragment-mono-latin-ext-400-normal-BbKYyvR9.woff2 +0 -0
  625. package/dist/web-client/assets/fragment-mono-latin-ext-400-normal-CT4YFKeK.woff +0 -0
  626. package/dist/web-client/assets/index-CCPaLeW7.css +0 -2
  627. package/dist/web-client/assets/index-kyOWsnZK.js +0 -86
  628. package/dist/web-client/assets/martian-mono-cyrillic-wght-normal-B84CD5C_.woff2 +0 -0
  629. package/dist/web-client/assets/martian-mono-latin-ext-wght-normal-DlL6xMw5.woff2 +0 -0
  630. package/dist/web-client/assets/martian-mono-latin-wght-normal-5W32yIyr.woff2 +0 -0
  631. package/dist/web-client/assets/workbox-window.prod.es5-Bd17z0YL.js +0 -2
  632. package/dist/web-client/icon-192.png +0 -0
  633. package/dist/web-client/icon-512.png +0 -0
  634. package/dist/web-client/icon-maskable-512.png +0 -0
  635. package/dist/web-client/index.html +0 -17
  636. package/dist/web-client/manifest.webmanifest +0 -1
  637. package/dist/web-client/sw.js +0 -1
  638. /package/dist/api/__tests__/{client.test.d.ts → serial/client.test.d.ts} +0 -0
  639. /package/dist/clients/inbox/__tests__/{inbox-controller.test.d.ts → serial/inbox-controller.test.d.ts} +0 -0
  640. /package/dist/clients/inbox/__tests__/{mount-panel.test.d.ts → serial/mount-panel.test.d.ts} +0 -0
  641. /package/dist/clients/{attach/__tests__/attach-chrome-remote.test.d.ts → inbox/review/__tests__/teardown-notice.test.d.ts} +0 -0
  642. /package/dist/{clients/attach/__tests__/attach-keybindings.test.d.ts → core/__tests__/broker-extension-canvas-db-boundary.test.d.ts} +0 -0
  643. /package/dist/{clients/attach/__tests__/crtr-output-coverage.test.d.ts → core/__tests__/seam/broker-attach-multiclient.test.d.ts} +0 -0
  644. /package/dist/core/__tests__/{full → seam}/broker-attach-stream.test.d.ts +0 -0
  645. /package/dist/core/__tests__/{full → seam}/broker-crash-teardown.test.d.ts +0 -0
  646. /package/dist/core/__tests__/{full → seam}/broker-pane-resolution.test.d.ts +0 -0
  647. /package/dist/core/__tests__/{full → seam}/broker-provider-retry.test.d.ts +0 -0
  648. /package/dist/core/__tests__/{full → seam}/broker-whip-interrupt.test.d.ts +0 -0
  649. /package/dist/{clients/attach/__tests__/editor-frame-title.test.d.ts → core/__tests__/seam/dormancy-release.test.d.ts} +0 -0
  650. /package/dist/{clients/attach/__tests__/input-controller-extension-command.test.d.ts → core/__tests__/seam/yield-refresh-transaction.test.d.ts} +0 -0
  651. /package/dist/core/__tests__/{broker-fork-seam.test.d.ts → serial/broker-fork-seam.test.d.ts} +0 -0
  652. /package/dist/core/__tests__/{broker-sdk-wiring.test.d.ts → serial/broker-sdk-wiring.test.d.ts} +0 -0
  653. /package/dist/core/__tests__/{broker-snapshot-history.test.d.ts → serial/broker-snapshot-history.test.d.ts} +0 -0
  654. /package/dist/core/__tests__/{command-plugins.test.d.ts → serial/command-plugins.test.d.ts} +0 -0
  655. /package/dist/core/__tests__/{deferred-no-wake.test.d.ts → serial/deferred-no-wake.test.d.ts} +0 -0
  656. /package/dist/core/__tests__/{flagship-lifecycle.test.d.ts → serial/flagship-lifecycle.test.d.ts} +0 -0
  657. /package/dist/core/__tests__/{host-teardown-process-group.test.d.ts → serial/host-teardown-process-group.test.d.ts} +0 -0
  658. /package/dist/core/__tests__/{human-deliver-e2e.test.d.ts → serial/human-deliver-e2e.test.d.ts} +0 -0
  659. /package/dist/core/__tests__/{live-mutation.test.d.ts → serial/live-mutation.test.d.ts} +0 -0
  660. /package/dist/core/__tests__/{refresh-stall-recycle.test.d.ts → serial/refresh-stall-recycle.test.d.ts} +0 -0
  661. /package/dist/core/__tests__/{revive.test.d.ts → serial/revive.test.d.ts} +0 -0
  662. /package/dist/core/__tests__/{spawn-root.test.d.ts → serial/spawn-root.test.d.ts} +0 -0
  663. /package/dist/core/__tests__/{subscription-delivery.test.d.ts → serial/subscription-delivery.test.d.ts} +0 -0
  664. /package/dist/core/__tests__/{tmux-surface.test.d.ts → serial/tmux-surface.test.d.ts} +0 -0
  665. /package/dist/core/__tests__/{worktree.test.d.ts → serial/worktree.test.d.ts} +0 -0
  666. /package/dist/{clients/attach/__tests__/markdown-headings.test.d.ts → core/__tests__/watchdog-abort-arms-retry.test.d.ts} +0 -0
  667. /package/dist/{clients/attach/__tests__/session-identity-refresh.test.d.ts → core/broker-client/__tests__/transport-socket.test.d.ts} +0 -0
  668. /package/dist/core/human/__tests__/{inbox-core.test.d.ts → serial/inbox-core.test.d.ts} +0 -0
  669. /package/dist/{clients/inbox/review/__tests__/remap.test.d.ts → daemon/api/__tests__/node-model-validation.test.d.ts} +0 -0
  670. /package/dist/{clients/surfaces/region.js → daemon/api/__tests__/review-terminal-conflict.test.d.ts} +0 -0
  671. /package/dist/daemon/api/__tests__/{full → seam}/api-server.test.d.ts +0 -0
  672. /package/dist/daemon/api/__tests__/{full → seam}/b10-attach-modelauth.test.d.ts +0 -0
  673. /package/dist/{clients/web/__tests__/push-engine.test.d.ts → daemon/api/__tests__/seam/leaf-api-parity.test.d.ts} +0 -0
@@ -0,0 +1,79 @@
1
+ import type { AgentSessionEvent } from '@earendil-works/pi-coding-agent';
2
+ import type { Message, ToolResultMessage } from '@earendil-works/pi-ai';
3
+ import type { BrokerSnapshot } from '../../core/runtime/broker-protocol.js';
4
+ import { type ToolGroupSummary } from '../../shared/tool-groups.js';
5
+ /** A persisted pi message or a crouter custom message carried on the broker wire. */
6
+ export type AnyMessage = Message | ({
7
+ role: string;
8
+ } & Record<string, unknown>);
9
+ export interface ConvState {
10
+ /** The full ordered transcript (snapshot history + streamed messages). */
11
+ messages: AnyMessage[];
12
+ /** Index of the assistant message currently streaming, or null. */
13
+ streamingIndex: number | null;
14
+ /** toolCallIds whose `tool_execution_*` is in flight (for an "executing…" badge). */
15
+ executingToolIds: ReadonlySet<string>;
16
+ /** Latest streaming/final result carried by tool_execution_* before the persisted toolResult message lands. */
17
+ partialToolResults: ReadonlyMap<string, ToolResultMessage>;
18
+ /** True between `agent_start` and `agent_end` (drives prompt-vs-steer + Stop). */
19
+ isStreaming: boolean;
20
+ /** A transient activity label (working / compacting / retrying), or null. */
21
+ activity: string | null;
22
+ /** Broker-selected normal label restored after temporary compaction/retry activity. */
23
+ workingActivity: string;
24
+ /** Texts still waiting to run — a writable view's steer/follow-up sent mid-turn
25
+ * (pi's `_steeringMessages` + `_followUpMessages`), authoritative from the
26
+ * engine's `queue_update` event. Drained (and removed here) the moment each
27
+ * one starts as a real `message_start`, so a queued row and the eventual
28
+ * transcript message never both show. */
29
+ queued: readonly string[];
30
+ /** Plain-text presentation recaps, keyed by the group's first tool-call id. */
31
+ toolGroupSummaries: Readonly<Record<string, string>>;
32
+ /** Canonical broker-owned completed tool-group summaries, keyed by the group's first tool-call id. */
33
+ toolGroupSummaryDetails: Readonly<Record<string, ToolGroupSummary>>;
34
+ }
35
+ export declare function initialConvState(): ConvState;
36
+ /** Rebuild the ephemeral reconciliation fields from a persisted transcript cache. */
37
+ export declare function restoreConvState(entry: {
38
+ messages: AnyMessage[];
39
+ isStreaming: boolean;
40
+ activity: string | null;
41
+ toolGroupSummaries: unknown;
42
+ }): ConvState;
43
+ /** Seed state from the broker's catch-up snapshot.
44
+ *
45
+ * `welcome.snapshot` is the PERSISTED history (`snapshotMessages()` in the
46
+ * broker), not the live in-memory array. During an active turn — after
47
+ * `message_start`, before `message_end` — the in-flight assistant message may
48
+ * not be persisted yet, so a mid-stream `welcome` can report
49
+ * `state.isStreaming: true` with no trailing assistant in the snapshot.
50
+ * Wholesale-replacing in that case (as we always did) drops the in-flight
51
+ * turn: `streamingIndex` resets to null and the next `message_update`/
52
+ * `message_end` has nothing to land on (see `reduce`).
53
+ *
54
+ * So: idle snapshots replace wholesale exactly as before. Streaming snapshots
55
+ * reconcile — if the persisted history already ends in an assistant, adopt
56
+ * it as the streaming target; otherwise adopt the caller-supplied `previous`
57
+ * state's in-flight assistant (a cache-first render or an earlier live
58
+ * session) if one exists, or synthesize an empty placeholder. Either way the
59
+ * first `message_update` REPLACES that message wholesale, so no duplicate or
60
+ * dropped turn results. */
61
+ export declare function applySnapshot(snapshot: BrokerSnapshot, previous?: ConvState): ConvState;
62
+ /** Apply the broker's random choice for the newly received user message. */
63
+ export declare function applyWorkingActivity(state: ConvState, activity: string): ConvState;
64
+ /** Apply one broker-published structured summary without touching transcript ordering. */
65
+ export declare function applyToolGroupSummary(state: ConvState, key: string, summary: ToolGroupSummary): ConvState;
66
+ export declare function bashStart(state: ConvState, command: string, excludeFromContext?: boolean): ConvState;
67
+ export declare function bashOutput(state: ConvState, chunk: string): ConvState;
68
+ export declare function bashEnd(state: ConvState, result: {
69
+ exitCode: number | undefined;
70
+ cancelled: boolean;
71
+ truncated: boolean;
72
+ fullOutputPath?: string;
73
+ }): ConvState;
74
+ /** Apply one broker→client AGENT event (an `AgentSessionEvent`) to the transcript.
75
+ * Broker control frames (welcome/model_changed/error/…) are handled by the hook,
76
+ * NOT here — only pi agent events reach this function. Returns a NEW state object
77
+ * (with fresh `messages`/`executingToolIds` only when they actually change) so
78
+ * React re-renders correctly. */
79
+ export declare function reduce(state: ConvState, event: AgentSessionEvent): ConvState;
@@ -0,0 +1,341 @@
1
+ // projection.ts — the surface-neutral reducer that turns a broker snapshot and
2
+ // its live frames into one ordered transcript model. Renderers retain their own
3
+ // folding and presentation; this module owns only wire-state reconciliation.
4
+ import { isInboxDigest } from '../../shared/generated-context.js';
5
+ import { normalizeToolGroupSummary, normalizeToolGroupSummaryRecord } from '../../shared/tool-groups.js';
6
+ import { DEFAULT_WORKING_ACTIVITY } from '../../shared/working-activity.js';
7
+ export function initialConvState() {
8
+ return {
9
+ messages: [],
10
+ streamingIndex: null,
11
+ executingToolIds: new Set(),
12
+ partialToolResults: new Map(),
13
+ isStreaming: false,
14
+ activity: null,
15
+ workingActivity: DEFAULT_WORKING_ACTIVITY,
16
+ queued: [],
17
+ toolGroupSummaries: {},
18
+ toolGroupSummaryDetails: {},
19
+ };
20
+ }
21
+ /** Rebuild the ephemeral reconciliation fields from a persisted transcript cache. */
22
+ export function restoreConvState(entry) {
23
+ const lastIndex = entry.messages.length - 1;
24
+ return {
25
+ ...initialConvState(),
26
+ messages: entry.messages,
27
+ streamingIndex: entry.isStreaming && lastIndex >= 0 ? lastIndex : null,
28
+ isStreaming: entry.isStreaming,
29
+ activity: entry.activity,
30
+ workingActivity: entry.isStreaming && entry.activity !== null ? entry.activity : DEFAULT_WORKING_ACTIVITY,
31
+ toolGroupSummaries: textToolGroupSummaries(entry.toolGroupSummaries),
32
+ toolGroupSummaryDetails: normalizeToolGroupSummaryRecord(entry.toolGroupSummaries),
33
+ };
34
+ }
35
+ /** Plain text of a user message (string content or concatenated text blocks),
36
+ * for inbox-digest detection. */
37
+ function userMessageText(m) {
38
+ const content = m.content;
39
+ if (typeof content === 'string')
40
+ return content;
41
+ if (Array.isArray(content)) {
42
+ return content
43
+ .filter((b) => !!b && b.type === 'text')
44
+ .map((b) => (typeof b.text === 'string' ? b.text : ''))
45
+ .join('');
46
+ }
47
+ return '';
48
+ }
49
+ /** Tag a `role:'user'` message as inbox-origin when its text matches the
50
+ * canvas-inbox-watcher coalesce digest; other messages pass through unchanged.
51
+ * The broker relays pi AgentMessages verbatim and never carries `origin` on the
52
+ * wire, so this is the sole writer of `origin:'inbox'` — recognized from the
53
+ * digest text. (Idempotent: a message already tagged is left as-is.) */
54
+ function tagInboxOrigin(m) {
55
+ if (roleOf(m) !== 'user')
56
+ return m;
57
+ if (m.origin)
58
+ return m;
59
+ if (!isInboxDigest(userMessageText(m)))
60
+ return m;
61
+ return { ...m, origin: 'inbox' };
62
+ }
63
+ /** An empty assistant message shaped so the next `message_update`/`message_end`
64
+ * (which replace, not append — see `reduce`'s `message_update` case) has a
65
+ * slot to land on. */
66
+ function placeholderAssistant() {
67
+ return { role: 'assistant', content: [] };
68
+ }
69
+ /** Seed state from the broker's catch-up snapshot.
70
+ *
71
+ * `welcome.snapshot` is the PERSISTED history (`snapshotMessages()` in the
72
+ * broker), not the live in-memory array. During an active turn — after
73
+ * `message_start`, before `message_end` — the in-flight assistant message may
74
+ * not be persisted yet, so a mid-stream `welcome` can report
75
+ * `state.isStreaming: true` with no trailing assistant in the snapshot.
76
+ * Wholesale-replacing in that case (as we always did) drops the in-flight
77
+ * turn: `streamingIndex` resets to null and the next `message_update`/
78
+ * `message_end` has nothing to land on (see `reduce`).
79
+ *
80
+ * So: idle snapshots replace wholesale exactly as before. Streaming snapshots
81
+ * reconcile — if the persisted history already ends in an assistant, adopt
82
+ * it as the streaming target; otherwise adopt the caller-supplied `previous`
83
+ * state's in-flight assistant (a cache-first render or an earlier live
84
+ * session) if one exists, or synthesize an empty placeholder. Either way the
85
+ * first `message_update` REPLACES that message wholesale, so no duplicate or
86
+ * dropped turn results. */
87
+ export function applySnapshot(snapshot, previous) {
88
+ const messages = snapshot.messages.map(tagInboxOrigin);
89
+ const toolGroupSummaryDetails = snapshotToolGroupSummaries(snapshot);
90
+ const toolGroupSummaries = summaryTexts(toolGroupSummaryDetails);
91
+ const isStreaming = snapshot.state?.isStreaming === true;
92
+ const workingActivity = snapshotWorkingActivity(snapshot);
93
+ if (!isStreaming) {
94
+ return {
95
+ messages,
96
+ streamingIndex: null,
97
+ executingToolIds: new Set(),
98
+ partialToolResults: new Map(),
99
+ isStreaming: false,
100
+ activity: null,
101
+ workingActivity,
102
+ queued: [],
103
+ toolGroupSummaries,
104
+ toolGroupSummaryDetails,
105
+ };
106
+ }
107
+ const lastIdx = messages.length - 1;
108
+ if (lastIdx >= 0 && roleOf(messages[lastIdx]) === 'assistant') {
109
+ // The in-flight assistant is already in the persisted snapshot — adopt it.
110
+ return {
111
+ messages,
112
+ streamingIndex: lastIdx,
113
+ executingToolIds: new Set(),
114
+ partialToolResults: new Map(),
115
+ isStreaming: true,
116
+ activity: workingActivity,
117
+ workingActivity,
118
+ queued: [],
119
+ toolGroupSummaries,
120
+ toolGroupSummaryDetails,
121
+ };
122
+ }
123
+ // Not persisted yet — adopt the previous in-flight assistant if one was
124
+ // already rendered, else synthesize a placeholder.
125
+ const cachedAssistant = previous && previous.streamingIndex !== null ? previous.messages[previous.streamingIndex] : undefined;
126
+ const inFlightAssistant = cachedAssistant && roleOf(cachedAssistant) === 'assistant' ? cachedAssistant : placeholderAssistant();
127
+ const withInFlight = [...messages, inFlightAssistant];
128
+ return {
129
+ messages: withInFlight,
130
+ streamingIndex: withInFlight.length - 1,
131
+ executingToolIds: new Set(),
132
+ partialToolResults: new Map(),
133
+ isStreaming: true,
134
+ activity: workingActivity,
135
+ workingActivity,
136
+ queued: [],
137
+ toolGroupSummaries,
138
+ toolGroupSummaryDetails,
139
+ };
140
+ }
141
+ function snapshotWorkingActivity(snapshot) {
142
+ const activity = snapshot.workingActivity;
143
+ return typeof activity === 'string' && activity.trim() !== '' ? activity : DEFAULT_WORKING_ACTIVITY;
144
+ }
145
+ /** Apply the broker's random choice for the newly received user message. */
146
+ export function applyWorkingActivity(state, activity) {
147
+ const next = activity.trim() === '' ? DEFAULT_WORKING_ACTIVITY : activity;
148
+ return state.workingActivity === next ? state : { ...state, workingActivity: next };
149
+ }
150
+ /** Snapshot additions are optional across broker generations. Invalid entries
151
+ * are absent rather than adapted, so every surface receives the canonical
152
+ * structured summary or no summary at all. */
153
+ function snapshotToolGroupSummaries(snapshot) {
154
+ return normalizeToolGroupSummaryRecord(snapshot.toolGroupSummaries);
155
+ }
156
+ /** The web's compact recap is a presentation derived from canonical broker data. */
157
+ function summaryTexts(summaries) {
158
+ return Object.fromEntries(Object.entries(summaries).map(([key, summary]) => [key, summary.bullets.join(' · ')]));
159
+ }
160
+ /** Legacy browser-cache entries retain their prior presentation strings; live
161
+ * snapshots and frames always rebuild these from the structured source. */
162
+ function textToolGroupSummaries(value) {
163
+ if (typeof value !== 'object' || value === null || Array.isArray(value))
164
+ return {};
165
+ return Object.fromEntries(Object.entries(value).filter((entry) => typeof entry[1] === 'string'));
166
+ }
167
+ /** Apply one broker-published structured summary without touching transcript ordering. */
168
+ export function applyToolGroupSummary(state, key, summary) {
169
+ const normalized = key.trim() === '' ? null : normalizeToolGroupSummary(summary);
170
+ if (normalized === null)
171
+ return state;
172
+ return {
173
+ ...state,
174
+ toolGroupSummaries: { ...state.toolGroupSummaries, [key]: normalized.bullets.join(' · ') },
175
+ toolGroupSummaryDetails: { ...state.toolGroupSummaryDetails, [key]: normalized },
176
+ };
177
+ }
178
+ function roleOf(m) {
179
+ return m.role ?? '';
180
+ }
181
+ // ---------------------------------------------------------------------------
182
+ // `!` bash execution (broker bash_start/bash_output/bash_end frames). These are
183
+ // broker control frames, NOT AgentSessionEvents, so the hook routes them here
184
+ // explicitly. They build a synthetic `bashExecution` message in the transcript
185
+ // that mirrors the one pi persists to context — rendered by MessageView.
186
+ // ---------------------------------------------------------------------------
187
+ /** Index of the most recent bashExecution message (the active `!` run), or null. */
188
+ function lastBashIndex(state) {
189
+ for (let i = state.messages.length - 1; i >= 0; i--) {
190
+ if (roleOf(state.messages[i]) === 'bashExecution')
191
+ return i;
192
+ }
193
+ return null;
194
+ }
195
+ export function bashStart(state, command, excludeFromContext) {
196
+ const msg = {
197
+ role: 'bashExecution',
198
+ command,
199
+ output: '',
200
+ exitCode: undefined,
201
+ cancelled: false,
202
+ truncated: false,
203
+ excludeFromContext,
204
+ timestamp: Date.now(),
205
+ };
206
+ return { ...state, messages: [...state.messages, msg] };
207
+ }
208
+ export function bashOutput(state, chunk) {
209
+ const idx = lastBashIndex(state);
210
+ if (idx === null)
211
+ return state;
212
+ const messages = [...state.messages];
213
+ const m = messages[idx];
214
+ messages[idx] = { ...m, output: `${m.output ?? ''}${chunk}` };
215
+ return { ...state, messages };
216
+ }
217
+ export function bashEnd(state, result) {
218
+ const idx = lastBashIndex(state);
219
+ if (idx === null)
220
+ return state;
221
+ const messages = [...state.messages];
222
+ const m = messages[idx];
223
+ messages[idx] = {
224
+ ...m,
225
+ exitCode: result.exitCode,
226
+ cancelled: result.cancelled,
227
+ truncated: result.truncated,
228
+ fullOutputPath: result.fullOutputPath,
229
+ };
230
+ return { ...state, messages };
231
+ }
232
+ /** Apply one broker→client AGENT event (an `AgentSessionEvent`) to the transcript.
233
+ * Broker control frames (welcome/model_changed/error/…) are handled by the hook,
234
+ * NOT here — only pi agent events reach this function. Returns a NEW state object
235
+ * (with fresh `messages`/`executingToolIds` only when they actually change) so
236
+ * React re-renders correctly. */
237
+ export function reduce(state, event) {
238
+ switch (event.type) {
239
+ case 'agent_start':
240
+ return { ...state, isStreaming: true, activity: state.workingActivity };
241
+ case 'agent_end':
242
+ case 'agent_settled':
243
+ return {
244
+ ...state,
245
+ isStreaming: false,
246
+ activity: null,
247
+ streamingIndex: null,
248
+ executingToolIds: state.executingToolIds.size ? new Set() : state.executingToolIds,
249
+ };
250
+ case 'message_start': {
251
+ // User messages arrive complete on message_start (no streaming deltas), so
252
+ // tagging here is sufficient — update/end only mutate the assistant message.
253
+ const tagged = tagInboxOrigin(event.message);
254
+ const messages = [...state.messages, tagged];
255
+ const isAssistant = roleOf(tagged) === 'assistant';
256
+ let partialToolResults = state.partialToolResults;
257
+ if (roleOf(tagged) === 'toolResult') {
258
+ const id = tagged.toolCallId;
259
+ if (typeof id === 'string' && partialToolResults.has(id)) {
260
+ const next = new Map(partialToolResults);
261
+ next.delete(id);
262
+ partialToolResults = next;
263
+ }
264
+ }
265
+ return {
266
+ ...state,
267
+ messages,
268
+ partialToolResults,
269
+ streamingIndex: isAssistant ? messages.length - 1 : state.streamingIndex,
270
+ };
271
+ }
272
+ case 'message_update': {
273
+ // Only assistant messages stream. Replace the in-progress message with the
274
+ // event's full `message`. If we attached mid-stream (no message_start seen),
275
+ // adopt the last message when it is the assistant being streamed.
276
+ let idx = state.streamingIndex;
277
+ if (idx === null) {
278
+ const last = state.messages.length - 1;
279
+ if (last >= 0 && roleOf(state.messages[last]) === 'assistant')
280
+ idx = last;
281
+ }
282
+ if (idx === null)
283
+ return state;
284
+ const messages = [...state.messages];
285
+ messages[idx] = event.message;
286
+ return { ...state, messages, streamingIndex: idx };
287
+ }
288
+ case 'message_end': {
289
+ if (state.streamingIndex === null)
290
+ return state;
291
+ const messages = [...state.messages];
292
+ messages[state.streamingIndex] = event.message;
293
+ return { ...state, messages, streamingIndex: null };
294
+ }
295
+ case 'tool_execution_start': {
296
+ const next = new Set(state.executingToolIds);
297
+ next.add(event.toolCallId);
298
+ return { ...state, executingToolIds: next };
299
+ }
300
+ case 'tool_execution_update': {
301
+ const next = new Map(state.partialToolResults);
302
+ next.set(event.toolCallId, toolResultFromExecution(event.toolCallId, event.toolName, event.partialResult, false));
303
+ return { ...state, partialToolResults: next };
304
+ }
305
+ case 'tool_execution_end': {
306
+ const nextExecuting = new Set(state.executingToolIds);
307
+ nextExecuting.delete(event.toolCallId);
308
+ const nextResults = new Map(state.partialToolResults);
309
+ nextResults.set(event.toolCallId, toolResultFromExecution(event.toolCallId, event.toolName, event.result, event.isError));
310
+ return { ...state, executingToolIds: nextExecuting, partialToolResults: nextResults };
311
+ }
312
+ case 'compaction_start':
313
+ return { ...state, activity: 'Compacting context…' };
314
+ case 'compaction_end':
315
+ return { ...state, activity: state.isStreaming ? state.workingActivity : null };
316
+ case 'auto_retry_start':
317
+ return {
318
+ ...state,
319
+ activity: `Retrying (${event.attempt}/${event.maxAttempts}) in ${Math.ceil(event.delayMs / 1000)}s…`,
320
+ };
321
+ case 'auto_retry_end':
322
+ return { ...state, activity: state.isStreaming ? state.workingActivity : null };
323
+ case 'queue_update':
324
+ return { ...state, queued: [...event.steering, ...event.followUp] };
325
+ // turn_* / session_info_changed / thinking_level_changed — no transcript
326
+ // mutation in v1 (footer-only or covered by adjacent message events).
327
+ default:
328
+ return state;
329
+ }
330
+ }
331
+ function toolResultFromExecution(toolCallId, toolName, result, isError) {
332
+ const fields = typeof result === 'object' && result !== null ? result : {};
333
+ return {
334
+ role: 'toolResult',
335
+ toolCallId,
336
+ toolName,
337
+ ...fields,
338
+ content: Array.isArray(fields.content) ? fields.content : [],
339
+ isError,
340
+ };
341
+ }
@@ -0,0 +1,159 @@
1
+ import assert from 'node:assert/strict';
2
+ import { createServer } from 'node:http';
3
+ import { existsSync, mkdtempSync, realpathSync, rmSync } from 'node:fs';
4
+ import { tmpdir } from 'node:os';
5
+ import { join } from 'node:path';
6
+ import { claimExists } from '#core/human/claim';
7
+ import { ticketDir } from '#core/human/root';
8
+ import { cancelTicket, submitDeck, takeoverAndCompleteDeck } from '#core/human/tickets';
9
+ import { InboxController } from '../../controller.js';
10
+ const key = (part = {}) => ({ ctrl: false, meta: false, upArrow: false, downArrow: false, leftArrow: false, rightArrow: false, wordLeft: false, wordRight: false, home: false, end: false, pageUp: false, pageDown: false, del: false, return: false, newline: false, escape: false, tab: false, backspace: false, ...part });
11
+ function fakeHost() {
12
+ let closed = false;
13
+ const cleanup = [];
14
+ const handle = {
15
+ close() {
16
+ if (closed)
17
+ return;
18
+ closed = true;
19
+ for (const fn of cleanup)
20
+ void fn();
21
+ cleanup.length = 0;
22
+ },
23
+ invalidate() { },
24
+ onClose(fn) {
25
+ if (!closed)
26
+ cleanup.push(fn);
27
+ },
28
+ };
29
+ return {
30
+ capabilities: { remote: false, canFocusNode: false, selfPane: undefined },
31
+ mount() { return handle; },
32
+ notice() { },
33
+ suspendForChild() { return () => { }; },
34
+ focusNode: async () => false,
35
+ pickReviewFile: async () => null,
36
+ };
37
+ }
38
+ const makeController = (options) => new InboxController({ host: fakeHost(), onDirty: () => { }, onClosed: () => { }, ...options });
39
+ const tick = () => new Promise((resolve) => setImmediate(resolve));
40
+ function select(controller, dir) {
41
+ const count = controller.snapshot().items.length;
42
+ const matches = () => {
43
+ const selected = controller.snapshot().selectedDir;
44
+ return selected !== undefined && realpathSync(selected) === realpathSync(dir);
45
+ };
46
+ for (let i = 0; i < count && !matches(); i++)
47
+ controller.handleKey('j', key());
48
+ assert.ok(matches(), `expected ${dir} to be selectable`);
49
+ }
50
+ async function waitFor(predicate, message) {
51
+ const deadline = Date.now() + 1_000;
52
+ while (!predicate()) {
53
+ if (Date.now() >= deadline)
54
+ throw new Error(message);
55
+ await new Promise((resolve) => setTimeout(resolve, 10));
56
+ }
57
+ }
58
+ // The controller answers a ticket by crossing the daemon `/resolve` seam. This
59
+ // fake daemon plays back each failure the seam can return so the controller's
60
+ // unmount-or-retry decision is exercised against a real socket.
61
+ let mode = 'success';
62
+ async function startDaemon() {
63
+ const server = createServer(async (req, res) => {
64
+ if (!req.url?.endsWith('/resolve')) {
65
+ res.statusCode = 404;
66
+ res.end(JSON.stringify({ error: { code: 'not_found', message: 'not found' } }));
67
+ return;
68
+ }
69
+ if (mode === 'unreachable') {
70
+ res.statusCode = 503;
71
+ res.end(JSON.stringify({ error: { code: 'daemon_unavailable', message: 'offline' } }));
72
+ return;
73
+ }
74
+ const body = await new Promise((resolve) => {
75
+ let text = '';
76
+ req.on('data', (chunk) => { text += chunk; });
77
+ req.on('end', () => resolve(text));
78
+ });
79
+ const nodeId = req.url.split('/').at(-2);
80
+ if (mode === 'already_resolved') {
81
+ res.statusCode = 409;
82
+ res.end(JSON.stringify({ error: { code: 'ticket_already_resolved', message: 'ticket already resolved' } }));
83
+ return;
84
+ }
85
+ const request = JSON.parse(body);
86
+ if (request.responses === undefined)
87
+ throw new Error('expected a deck resolution');
88
+ takeoverAndCompleteDeck(ticketDir(nodeId), request.responses, { host: 'daemon', pid: 1 });
89
+ if (mode === 'delivery_failed') {
90
+ res.statusCode = 500;
91
+ res.end(JSON.stringify({ error: { code: 'delivery_failed', message: 'final report delivery failed' } }));
92
+ return;
93
+ }
94
+ res.end(JSON.stringify({ delivered: true, kind: 'deck' }));
95
+ });
96
+ await new Promise((resolve) => server.listen(join(process.env['CRTR_HOME'], 'crtrd.sock'), resolve));
97
+ return server;
98
+ }
99
+ const temp = mkdtempSync(join(tmpdir(), 'crtr-inbox-controller-'));
100
+ process.env['CRTR_HOME'] = temp;
101
+ const server = await startDaemon();
102
+ const deck = (id) => ({ title: id, source: { blockedSince: new Date().toISOString(), sessionName: 'Release planning', nodeId: 'node-private-123' }, interactions: [{ id: 'answer', title: 'Answer', subtitle: 'Answer requires your attention.', options: [{ id: 'yes', label: 'Yes', shortcut: 'y' }] }] });
103
+ try {
104
+ const first = submitDeck({ dir: ticketDir('first'), deck: deck('first') });
105
+ const active = makeController({ cols: 100, rows: 24 });
106
+ active.activate();
107
+ active.handleKey('y', key());
108
+ await waitFor(() => existsSync(join(first.dir, 'response.json')), 'a deck resolution crosses the controller daemon seam');
109
+ await waitFor(() => active.snapshot().screen === 'list', 'a successful daemon resolution unmounts the ticket');
110
+ active.close();
111
+ // A ticket arriving mid-edit must not move selection or clobber the freetext
112
+ // the user is part way through typing.
113
+ const editing = submitDeck({ dir: ticketDir('editing'), deck: { title: 'Editing', interactions: [{ id: 'note', title: 'Notes', subtitle: 'Notes require your attention.', options: [], allowFreetext: true }] } });
114
+ const editingController = makeController({ cols: 100, rows: 24 });
115
+ select(editingController, editing.dir);
116
+ editingController.activate();
117
+ editingController.handleKey('r', key());
118
+ for (const char of 'draft')
119
+ editingController.handleKey(char, key());
120
+ submitDeck({ dir: ticketDir('arrival'), deck: deck('arrival') });
121
+ editingController.rescan();
122
+ assert.equal(realpathSync(editingController.snapshot().selectedDir), realpathSync(editing.dir), 'arrival does not steal active selection');
123
+ assert.equal(editingController.snapshot().inputBuffer, 'draft', 'arrival does not alter freetext input');
124
+ editingController.close();
125
+ cancelTicket(editing.dir, { reason: 'done editing' });
126
+ const already = submitDeck({ dir: ticketDir('already'), deck: deck('already') });
127
+ const alreadyController = makeController({ cols: 100, rows: 24 });
128
+ alreadyController.activate();
129
+ cancelTicket(already.dir, { reason: 'resolved elsewhere' });
130
+ mode = 'already_resolved';
131
+ alreadyController.handleKey('y', key());
132
+ await waitFor(() => alreadyController.snapshot().screen === 'list', 'already_resolved unmounts instead of offering a stale resubmit');
133
+ assert.equal(claimExists(already.dir), true, 'already_resolved retains the daemon-taken claim');
134
+ alreadyController.close();
135
+ const delivery = submitDeck({ dir: ticketDir('delivery'), deck: deck('delivery') });
136
+ mode = 'delivery_failed';
137
+ const deliveryController = makeController({ cols: 100, rows: 24 });
138
+ deliveryController.activate();
139
+ deliveryController.handleKey('y', key());
140
+ await waitFor(() => deliveryController.snapshot().screen === 'list', 'delivery_failed unmounts because the canonical answer is already recorded');
141
+ assert.equal(existsSync(join(delivery.dir, 'response.json')), true, 'delivery_failed still leaves the canonical response on disk');
142
+ deliveryController.close();
143
+ const retry = submitDeck({ dir: ticketDir('retry'), deck: deck('retry') });
144
+ mode = 'unreachable';
145
+ const retryController = makeController({ cols: 100, rows: 24 });
146
+ retryController.activate();
147
+ retryController.handleKey('y', key());
148
+ await tick();
149
+ assert.equal(retryController.snapshot().screen, 'detail', 'unreachable keeps the mounted answer available for retry');
150
+ assert.equal(existsSync(join(retry.dir, 'response.json')), false, 'unreachable does not manufacture a local completion');
151
+ retryController.close();
152
+ }
153
+ finally {
154
+ server.closeAllConnections();
155
+ await new Promise((resolve) => server.close(() => resolve()));
156
+ rmSync(temp, { recursive: true, force: true });
157
+ delete process.env['CRTR_HOME'];
158
+ }
159
+ console.log('inbox controller tests passed');