@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,20 +1,18 @@
1
+ // Run with: node --import tsx/esm --test src/pi-extensions/__tests__/canvas-recap.test.ts
2
+ //
3
+ // Failure atomicity: a recap that has been requested but has not produced a
4
+ // briefing yet must leave the pinned recap alone. A regenerating (or failing)
5
+ // recap that cleared the widget first would blank the user's pinned summary.
1
6
  import { test } from 'node:test';
2
7
  import assert from 'node:assert/strict';
3
- import { mkdtempSync, rmSync } from 'node:fs';
4
- import { tmpdir } from 'node:os';
5
- import { join } from 'node:path';
6
8
  import { registerCanvasRecap } from '../canvas-recap.js';
7
- import { createNode } from '../../core/canvas/canvas.js';
8
- import { closeDb } from '../../core/canvas/db.js';
9
- test('a streaming manual recap snapshots the partial response and replaces the pinned recap only on success', () => {
9
+ test('a recap replaces the pinned widget only when its generation succeeds', () => {
10
10
  const originalNodeId = process.env['CRTR_NODE_ID'];
11
11
  process.env['CRTR_NODE_ID'] = 'recap-regression-node';
12
12
  const handlers = new Map();
13
13
  let commandHandler;
14
14
  const widgetWrites = [];
15
- const notifications = [];
16
15
  const generations = [];
17
- let idleWaits = 0;
18
16
  const recapGenerator = (conversation, finish) => {
19
17
  generations.push({ conversation, finish });
20
18
  };
@@ -24,133 +22,38 @@ test('a streaming manual recap snapshots the partial response and replaces the p
24
22
  commandHandler = options.handler;
25
23
  },
26
24
  };
27
- const sessionManager = {
28
- getEntries: () => [{ type: 'message', message: { role: 'user', content: 'Build the recap command.' } }],
29
- };
30
25
  const ctx = {
31
26
  ui: {
32
27
  setWidget: (_key, content) => { widgetWrites.push(content); },
33
- notify: (message) => { notifications.push(message); },
28
+ notify: () => undefined,
29
+ },
30
+ sessionManager: {
31
+ getEntries: () => [{ type: 'message', message: { role: 'user', content: 'Build the recap command.' } }],
34
32
  },
35
- sessionManager,
36
33
  model: { provider: 'test', id: 'light' },
37
34
  isIdle: () => false,
38
- waitForIdle: async () => { idleWaits += 1; },
35
+ waitForIdle: async () => undefined,
39
36
  };
40
37
  try {
41
38
  registerCanvasRecap(pi, recapGenerator);
42
39
  handlers.get('session_start')?.({}, ctx);
43
40
  commandHandler?.('', ctx);
44
- assert.equal(notifications.at(-1), 'Generating recap…', 'the manually selected command confirms that generation started');
45
41
  generations[0]?.finish('Goal: Existing goal\nState: Existing state');
46
42
  assert.deepEqual(widgetWrites.at(-1), ['Goal: Existing goal', 'State: Existing state']);
47
- assert.equal(notifications.at(-1), 'Recap ready', 'a completed manual recap confirms that the widget was refreshed');
43
+ // A second recap requested mid-response must not disturb the pinned one
44
+ // until its own briefing arrives.
48
45
  handlers.get('message_update')?.({
49
46
  message: { role: 'assistant', content: [{ type: 'text', text: 'I am editing the live implementation now.' }] },
50
47
  }, ctx);
51
48
  const writesBeforeRequest = widgetWrites.length;
52
- const result = commandHandler?.('', ctx);
53
- assert.equal(result, undefined, 'the command starts synchronously while the main response is streaming');
54
- assert.equal(idleWaits, 0);
55
- assert.equal(generations.length, 2);
56
- assert.match(generations[1].conversation, /Agent: I am editing the live implementation now\./);
49
+ commandHandler?.('', ctx);
50
+ assert.equal(generations.length, 2, 'the second request started its own generation');
57
51
  assert.equal(widgetWrites.length, writesBeforeRequest, 'the pinned recap remains while its replacement generates');
58
- handlers.get('message_update')?.({
59
- message: { role: 'assistant', content: [{ type: 'text', text: 'I am now verifying the implementation.' }] },
60
- }, ctx);
61
52
  generations[1].finish('Goal: Updated goal\nState: Updated click-time state');
62
- assert.deepEqual(widgetWrites.at(-1), ['Goal: Updated goal', 'State: Updated click-time state']);
63
- }
64
- finally {
65
- handlers.get('session_shutdown')?.({}, ctx);
66
- if (originalNodeId === undefined)
67
- delete process.env['CRTR_NODE_ID'];
68
- else
69
- process.env['CRTR_NODE_ID'] = originalNodeId;
70
- }
71
- });
72
- test('review recap and naming input exclude inherited entries while retaining the post-boundary conversation', () => {
73
- const originalNodeId = process.env['CRTR_NODE_ID'];
74
- const originalHome = process.env['CRTR_HOME'];
75
- const home = mkdtempSync(join(tmpdir(), 'crtr-recap-boundary-'));
76
- const nodeId = 'review-recap-node';
77
- const handlers = new Map();
78
- let commandHandler;
79
- const widgetWrites = [];
80
- const recapInputs = [];
81
- const namingInputs = [];
82
- let entries = [
83
- { type: 'message', message: { role: 'user', content: 'PREBOUNDARY_CANARY inherited request' } },
84
- { type: 'message', message: { role: 'assistant', content: 'inherited answer' } },
85
- {
86
- type: 'custom_message',
87
- customType: 'crtr-review-boundary',
88
- details: { reviewId: 'review-1' },
89
- },
90
- { type: 'message', message: { role: 'user', content: 'review-only finding' } },
91
- { type: 'message', message: { role: 'assistant', content: 'review-only resolution' } },
92
- ];
93
- const pi = {
94
- on: (event, handler) => { handlers.set(event, handler); },
95
- registerCommand: (_name, options) => {
96
- commandHandler = options.handler;
97
- },
98
- getSessionName: () => 'developer',
99
- setSessionName: () => undefined,
100
- };
101
- const sessionManager = { getEntries: () => entries };
102
- const ctx = {
103
- ui: { setWidget: (_key, content) => { widgetWrites.push(content); } },
104
- sessionManager,
105
- };
106
- const recapGenerator = (conversation) => { recapInputs.push(conversation); };
107
- try {
108
- closeDb();
109
- process.env['CRTR_HOME'] = home;
110
- process.env['CRTR_NODE_ID'] = nodeId;
111
- createNode({
112
- node_id: nodeId,
113
- name: 'developer',
114
- created: new Date().toISOString(),
115
- cwd: '/tmp/work',
116
- kind: 'developer',
117
- mode: 'base',
118
- lifecycle: 'terminal',
119
- status: 'active',
120
- review_binding: {
121
- review_id: 'review-1',
122
- origin_node_id: 'origin',
123
- branch_file: '/tmp/review.jsonl',
124
- target_file: '/tmp/target.ts',
125
- },
126
- });
127
- registerCanvasRecap(pi, recapGenerator, (_id, conversation) => { namingInputs.push(conversation); });
128
- handlers.get('session_start')?.({}, ctx);
129
- commandHandler?.('', ctx);
130
- assert.equal(recapInputs.length, 1);
131
- assert.equal(namingInputs.length, 1);
132
- for (const input of [...recapInputs, ...namingInputs]) {
133
- assert.doesNotMatch(input, /PREBOUNDARY_CANARY/);
134
- assert.match(input, /review-only finding/);
135
- assert.match(input, /review-only resolution/);
136
- }
137
- entries = [{ type: 'message', message: { role: 'user', content: 'PREBOUNDARY_CANARY without a boundary' } }];
138
- handlers.get('message_update')?.({
139
- message: { role: 'assistant', content: 'PREBOUNDARY_CANARY streaming response without a boundary' },
140
- }, ctx);
141
- commandHandler?.('', ctx);
142
- assert.equal(recapInputs.length, 1, 'a markerless review produces no recap input, including a streaming partial');
143
- assert.equal(namingInputs.length, 1, 'a markerless review produces no naming input, including a streaming partial');
144
- assert.equal(widgetWrites.at(-1), undefined, 'a markerless review clears the recap widget');
53
+ assert.deepEqual(widgetWrites.at(-1), ['Goal: Updated goal', 'State: Updated click-time state'], 'success replaces the pinned recap');
145
54
  }
146
55
  finally {
147
56
  handlers.get('session_shutdown')?.({}, ctx);
148
- closeDb();
149
- rmSync(home, { recursive: true, force: true });
150
- if (originalHome === undefined)
151
- delete process.env['CRTR_HOME'];
152
- else
153
- process.env['CRTR_HOME'] = originalHome;
154
57
  if (originalNodeId === undefined)
155
58
  delete process.env['CRTR_NODE_ID'];
156
59
  else
@@ -9,7 +9,7 @@
9
9
  // Every assertion is on DB / disk effects (report files, inbox pointers) plus
10
10
  // the captured sendUserMessage — tmux is unavailable here, so the focus/respawn
11
11
  // helpers no-op (TMUX_PANE is cleared) and we drive a clean shutdown path.
12
- import { test, before, after, beforeEach } from 'node:test';
12
+ import { test, before, after, beforeEach, afterEach } from 'node:test';
13
13
  import assert from 'node:assert/strict';
14
14
  import { mkdtempSync, rmSync, existsSync, readdirSync } from 'node:fs';
15
15
  import { tmpdir } from 'node:os';
@@ -18,6 +18,9 @@ import registerCanvasStophook from '../canvas-stophook.js';
18
18
  import { createNode, subscribe, getNode, setStatus } from '../../core/canvas/canvas.js';
19
19
  import { openFocusRow, getFocusByNode, getFocusById, listFocuses } from '../../core/canvas/focuses.js';
20
20
  import { closeDb } from '../../core/canvas/db.js';
21
+ import { apiSocketPath } from '../../core/canvas/paths.js';
22
+ import { createApiServer } from '../../daemon/api/server.js';
23
+ import { CrtrClient } from '../../api/client.js';
21
24
  import { reportsDir } from '../../core/canvas/paths.js';
22
25
  import { readInboxSince, appendInbox } from '../../core/feed/inbox.js';
23
26
  import { STALL_REPROMPT } from '../../core/runtime/stop-guard.js';
@@ -25,6 +28,7 @@ import { markStopSignal } from '../../core/runtime/stop-signals.js';
25
28
  import { isBusy } from '../../core/runtime/busy.js';
26
29
  import { recordFault, readFault } from '../../core/runtime/fault.js';
27
30
  let home;
31
+ let server;
28
32
  let origNode;
29
33
  let origPane;
30
34
  function node(id, over = {}) {
@@ -46,12 +50,12 @@ function makeFakePi() {
46
50
  injected: [],
47
51
  on(e, h) { handlers[e] = h; },
48
52
  sendUserMessage(content, options) { this.injected.push({ content, deliverAs: options?.deliverAs }); },
49
- fire(e, ev, ctx) { handlers[e]?.(ev, ctx); },
53
+ async fire(e, ev, ctx) { await handlers[e]?.(ev, ctx); },
50
54
  };
51
55
  }
52
- function settle(pi, event, ctx) {
53
- pi.fire('agent_end', event, ctx);
54
- pi.fire('agent_settled', { type: 'agent_settled' }, ctx);
56
+ async function settle(pi, event, ctx) {
57
+ await pi.fire('agent_end', event, ctx);
58
+ await pi.fire('agent_settled', { type: 'agent_settled' }, ctx);
55
59
  }
56
60
  /** A natural-stop agent_end event carrying one assistant text block. */
57
61
  function stopEvent(text) {
@@ -66,16 +70,39 @@ before(() => {
66
70
  origNode = process.env['CRTR_NODE_ID'];
67
71
  origPane = process.env['TMUX_PANE'];
68
72
  });
69
- beforeEach(() => {
73
+ async function waitForSocket() {
74
+ const probe = CrtrClient.forLocalSocket({ autostart: false });
75
+ for (let i = 0; i < 200; i++) {
76
+ if (existsSync(apiSocketPath())) {
77
+ try {
78
+ await probe.healthz();
79
+ return;
80
+ }
81
+ catch {
82
+ // The socket path appears before the in-process server accepts requests.
83
+ }
84
+ }
85
+ await new Promise((resolve) => setTimeout(resolve, 5));
86
+ }
87
+ throw new Error(`api socket never answered at ${apiSocketPath()}`);
88
+ }
89
+ beforeEach(async () => {
70
90
  closeDb();
71
91
  if (home)
72
92
  rmSync(home, { recursive: true, force: true });
73
93
  home = mkdtempSync(join(tmpdir(), 'crtr-stophook-end-'));
74
94
  process.env['CRTR_HOME'] = home;
95
+ server = createApiServer();
96
+ await waitForSocket();
75
97
  // Force the clean-shutdown path (no in-place respawn) so the refresh test is
76
98
  // deterministic even when the suite runs inside a tmux pane.
77
99
  delete process.env['TMUX_PANE'];
78
100
  });
101
+ afterEach(async () => {
102
+ await server?.close();
103
+ server = undefined;
104
+ closeDb();
105
+ });
79
106
  after(() => {
80
107
  closeDb();
81
108
  if (home)
@@ -90,7 +117,7 @@ after(() => {
90
117
  else
91
118
  process.env['TMUX_PANE'] = origPane;
92
119
  });
93
- test('natural stop commits idle-release only at agent_settled', { timeout: 1_000 }, () => {
120
+ test('natural stop commits idle-release only at agent_settled', { timeout: 1_000 }, async () => {
94
121
  createNode(node('root', { parent: null, lifecycle: 'resident' }));
95
122
  createNode(node('mgr', { parent: 'root', lifecycle: 'terminal', mode: 'orchestrator' }));
96
123
  createNode(node('worker', { parent: 'mgr', lifecycle: 'terminal', status: 'active' }));
@@ -101,12 +128,12 @@ test('natural stop commits idle-release only at agent_settled', { timeout: 1_000
101
128
  registerCanvasStophook(pi);
102
129
  let shutdown = false;
103
130
  const ctx = { shutdown: () => { shutdown = true; } };
104
- pi.fire('agent_start', { type: 'agent_start' }, ctx);
105
- pi.fire('agent_end', stopEvent('still waiting on the worker'), ctx);
131
+ await pi.fire('agent_start', { type: 'agent_start' }, ctx);
132
+ await pi.fire('agent_end', stopEvent('still waiting on the worker'), ctx);
106
133
  assert.equal(getNode('mgr')?.status, 'active', 'agent_end is staging-only');
107
134
  assert.equal(isBusy('mgr'), true, 'agent_end cannot clear whole-run busy state');
108
135
  assert.equal(shutdown, false, 'agent_end cannot route a natural stop');
109
- pi.fire('agent_settled', { type: 'agent_settled' }, ctx);
136
+ await pi.fire('agent_settled', { type: 'agent_settled' }, ctx);
110
137
  const m = getNode('mgr');
111
138
  assert.equal(isBusy('mgr'), false, 'agent_settled clears whole-run busy state');
112
139
  assert.equal(m?.intent, 'idle-release', 'mgr idle-released');
@@ -120,7 +147,7 @@ test('natural stop commits idle-release only at agent_settled', { timeout: 1_000
120
147
  // the done-branch handoff/openFocus on an idle-release would leave a row here.
121
148
  assert.equal(listFocuses().length, 0, 'awaiting+unfocused leaves the focuses table empty');
122
149
  });
123
- test('gh-451: idle-release does NOT release while a non-deferred inbox entry sits past the cursor', { timeout: 1_000 }, () => {
150
+ test('gh-451: idle-release does NOT release while a non-deferred inbox entry sits past the cursor', { timeout: 1_000 }, async () => {
124
151
  // Reproduces the #451 race: a subscriber's push landed in mgr's inbox but the
125
152
  // in-process watcher has not yet flushed/committed the durable cursor past it
126
153
  // (its DEBOUNCE_MS hold). If this settle released anyway, the daemon would
@@ -138,12 +165,12 @@ test('gh-451: idle-release does NOT release while a non-deferred inbox entry sit
138
165
  registerCanvasStophook(pi);
139
166
  let shutdown = false;
140
167
  const ctx = { shutdown: () => { shutdown = true; } };
141
- settle(pi, stopEvent('still waiting on the worker'), ctx);
168
+ await settle(pi, stopEvent('still waiting on the worker'), ctx);
142
169
  assert.equal(getNode('mgr')?.status, 'active', 'mgr stays active — NOT idle-released while behind the cursor');
143
170
  assert.equal(getNode('mgr')?.intent ?? null, null, 'no idle-release intent while a non-deferred entry is unseen');
144
171
  assert.equal(shutdown, false, 'pi stays alive so the in-process watcher can still deliver/commit');
145
172
  });
146
- test('gh-451: finished does NOT shut down while a non-deferred inbox entry sits past the cursor', { timeout: 1_000 }, () => {
173
+ test('gh-451: finished does NOT shut down while a non-deferred inbox entry sits past the cursor', { timeout: 1_000 }, async () => {
147
174
  // A canonical final can settle while the in-process watcher has delivered a
148
175
  // child report into the inbox but has not yet committed the durable cursor.
149
176
  // The finished branch must keep this broker alive for that delivery.
@@ -154,12 +181,12 @@ test('gh-451: finished does NOT shut down while a non-deferred inbox entry sits
154
181
  registerCanvasStophook(pi);
155
182
  let shutdown = false;
156
183
  const ctx = { shutdown: () => { shutdown = true; } };
157
- settle(pi, stopEvent('already finalized'), ctx);
184
+ await settle(pi, stopEvent('already finalized'), ctx);
158
185
  assert.equal(getNode('mgr')?.status, 'active', 'mgr stays active while the watcher catches up');
159
186
  assert.equal(getNode('mgr')?.intent ?? null, null, 'no idle-release intent while a non-deferred entry is unseen');
160
187
  assert.equal(shutdown, false, 'pi stays alive so the in-process watcher can still deliver/commit');
161
188
  });
162
- test('gh-451: a DEFERRED-only unseen entry does not block idle-release (matches the daemon\'s own wake gate)', { timeout: 1_000 }, () => {
189
+ test('gh-451: a DEFERRED-only unseen entry does not block idle-release (matches the daemon\'s own wake gate)', { timeout: 1_000 }, async () => {
163
190
  createNode(node('root', { parent: null, lifecycle: 'resident' }));
164
191
  createNode(node('mgr', { parent: 'root', lifecycle: 'terminal', mode: 'orchestrator' }));
165
192
  createNode(node('worker', { parent: 'mgr', lifecycle: 'terminal', status: 'active' }));
@@ -171,26 +198,26 @@ test('gh-451: a DEFERRED-only unseen entry does not block idle-release (matches
171
198
  registerCanvasStophook(pi);
172
199
  let shutdown = false;
173
200
  const ctx = { shutdown: () => { shutdown = true; } };
174
- settle(pi, stopEvent('still waiting on the worker'), ctx);
201
+ await settle(pi, stopEvent('still waiting on the worker'), ctx);
175
202
  assert.equal(getNode('mgr')?.intent, 'idle-release', 'a deferred-only unseen entry does not block release (#341 parity)');
176
203
  assert.equal(getNode('mgr')?.status, 'idle');
177
204
  assert.equal(shutdown, true, 'pi shuts down — deferred entries ride the next natural cycle, not this settle');
178
205
  });
179
- test('queued continuation finishes before natural-stop routing commits', { timeout: 1_000 }, () => {
206
+ test('queued continuation finishes before natural-stop routing commits', { timeout: 1_000 }, async () => {
180
207
  createNode(node('leaf', { parent: null, lifecycle: 'terminal' }));
181
208
  process.env['CRTR_NODE_ID'] = 'leaf';
182
209
  const pi = makeFakePi();
183
210
  registerCanvasStophook(pi);
184
211
  let shutdown = false;
185
212
  const ctx = { shutdown: () => { shutdown = true; } };
186
- pi.fire('agent_start', { type: 'agent_start' }, ctx);
187
- pi.fire('agent_end', stopEvent('first attempt ended while a continuation was queued'), ctx);
213
+ await pi.fire('agent_start', { type: 'agent_start' }, ctx);
214
+ await pi.fire('agent_end', stopEvent('first attempt ended while a continuation was queued'), ctx);
188
215
  assert.equal(shutdown, false, 'the intermediate agent_end cannot route a natural stop');
189
216
  assert.equal(getNode('leaf')?.status, 'active');
190
217
  setStatus('leaf', 'done');
191
- pi.fire('agent_start', { type: 'agent_start' }, ctx);
192
- pi.fire('agent_end', stopEvent('queued continuation completed the assignment'), ctx);
193
- pi.fire('agent_settled', { type: 'agent_settled' }, ctx);
218
+ await pi.fire('agent_start', { type: 'agent_start' }, ctx);
219
+ await pi.fire('agent_end', stopEvent('queued continuation completed the assignment'), ctx);
220
+ await pi.fire('agent_settled', { type: 'agent_settled' }, ctx);
194
221
  assert.equal(shutdown, true, 'settlement routes from the completed continuation');
195
222
  assert.equal(getNode('leaf')?.intent ?? null, null, 'the intermediate natural stop never idle-released the node');
196
223
  });
@@ -201,42 +228,12 @@ test('queued continuation finishes before natural-stop routing commits', { timeo
201
228
  // used by the handler now GC-prunes a viewer row whose pane is not a LIVE tmux
202
229
  // pane (liveOrPrune → paneExists), so a fabricated '%pane' id is pruned on the
203
230
  // first read. To drive the handler's focus path deterministically in the
204
- // tmux-free fast tier we register viewer rows with a NULL pane (a registered-
231
+ // tmux-free ordinary suite we register viewer rows with a NULL pane (a registered-
205
232
  // but-not-yet-realized viewer, which liveOrPrune passes through). status='done'
206
233
  // is reached by setting the runtime row directly (the branch reads
207
234
  // getNode(nodeId).status).
208
235
  // ---------------------------------------------------------------------------
209
- test('§5.1.1 truly-done + focused → focus row CLOSED, NO manager takeover (broker cut deleted handFocusToManager)', () => {
210
- // Regression guard for the broker-host cut: the engine is now a detached
211
- // broker, not a pane, so there is no engine to hand to a manager. The old
212
- // "dormant idle-release manager takes over the finished node's focus row"
213
- // path (handFocusToManager) is DELETED — a truly-done focused node just
214
- // tearDownNode's its own viewer and shuts down, EVEN when a dormant
215
- // idle-release manager exists (the exact case that used to trigger takeover).
216
- createNode(node('root', { parent: null, lifecycle: 'resident' }));
217
- createNode(node('mgr', { parent: 'root', lifecycle: 'terminal', mode: 'orchestrator', status: 'idle', intent: 'idle-release' }));
218
- // M starts WITH a recorded LOCATION so the done-path presence-null is observable.
219
- createNode(node('M', { parent: 'mgr', lifecycle: 'terminal', pane: '%m', tmux_session: 'Suser', window: '@wm' }));
220
- subscribe('mgr', 'M', true);
221
- openFocusRow('fM', null, 'Suser', 'M'); // null pane → focusOf returns it → drives tearDownNode
222
- process.env['CRTR_NODE_ID'] = 'M';
223
- setStatus('M', 'done'); // pushed final this turn
224
- const pi = makeFakePi();
225
- registerCanvasStophook(pi);
226
- let shutdown = false;
227
- settle(pi, stopEvent('done — pushed final'), { shutdown: () => { shutdown = true; } });
228
- // The done branch: focusOf('M') != null → tearDownNode('M') CLOSES fM. The
229
- // manager is NOT handed anything (takeover deleted). Non-vacuous: a takeover
230
- // impl would leave getFocusByNode('mgr').focus_id === 'fM'.
231
- assert.equal(getFocusByNode('mgr'), null, 'the manager is NOT handed the finished node\'s focus (takeover deleted)');
232
- assert.equal(getFocusById('fM'), null, 'the finished node\'s viewer focus row is closed');
233
- assert.equal(getFocusByNode('M'), null, 'the finished node no longer occupies any focus');
234
- assert.equal(shutdown, true, 'pi shut down after teardown');
235
- // The done node's own presence is nulled (setPresence(null) on the done path).
236
- assert.equal(getNode('M')?.pane ?? null, null, 'the finished node\'s own LOCATION pane is nulled');
237
- assert.equal(getNode('M')?.window ?? null, null, 'the finished node\'s window presence is nulled too');
238
- });
239
- test('§5.1.2 truly-done + focused + NO manager (root) → focus row CLOSED (Q1)', () => {
236
+ test('§5.1.2 truly-done + focused → focus row CLOSED, own presence nulled (Q1)', async () => {
240
237
  // R carries a LOCATION so the close-path presence-null is observable.
241
238
  createNode(node('R', { parent: null, lifecycle: 'terminal', pane: '%r', tmux_session: 'Suser', window: '@wr' }));
242
239
  openFocusRow('fR', '%r', 'Suser', 'R');
@@ -244,40 +241,16 @@ test('§5.1.2 truly-done + focused + NO manager (root) → focus row CLOSED (Q1)
244
241
  setStatus('R', 'done');
245
242
  const pi = makeFakePi();
246
243
  registerCanvasStophook(pi);
247
- settle(pi, stopEvent('root done'), { shutdown: () => { } });
248
- // managerId = R.parent(null) ?? subscribersOf(R)[0](none) = null →
249
- // handFocusToManager returns false → the close path: closeFocusRow(fR) +
244
+ await settle(pi, stopEvent('root done'), { shutdown: () => { } });
245
+ // The done branch closes the viewer row: closeFocusRow(fR) +
250
246
  // setRemainOnExit(%r's window, false) (return-to-shell) + null R's presence.
251
- // Non-vacuous: a takeover-instead-of-close impl would leave the row present;
252
- // an impl that skips the MINOR presence-null leaves getNode('R').pane === '%r'.
253
- assert.equal(getFocusById('fR'), null, 'a manager-less finished focus is closed, not handed off');
247
+ // Non-vacuous: an impl that leaves the row open keeps it present; one that
248
+ // skips the presence-null leaves getNode('R').pane === '%r'.
249
+ assert.equal(getFocusById('fR'), null, 'a finished node\'s focus row is closed');
254
250
  assert.equal(listFocuses().length, 0, 'no focus rows survive');
255
251
  assert.equal(getNode('R')?.pane ?? null, null, 'the finished root\'s own LOCATION pane is nulled (close path reaps)');
256
252
  });
257
- test('§5.1.3 truly-done + focused + manager ALREADY focused elsewhere → focus CLOSED, manager UNMOVED', () => {
258
- createNode(node('root', { parent: null, lifecycle: 'resident' }));
259
- createNode(node('mgr', { parent: 'root', lifecycle: 'terminal', mode: 'orchestrator' }));
260
- createNode(node('M', { parent: 'mgr', lifecycle: 'terminal', pane: '%m', tmux_session: 'Sa', window: '@wm' }));
261
- subscribe('mgr', 'M', true);
262
- openFocusRow('fOther', '%o', 'Sb', 'mgr'); // mgr already on its OWN viewport
263
- openFocusRow('fM', '%m', 'Sa', 'M');
264
- process.env['CRTR_NODE_ID'] = 'M';
265
- setStatus('M', 'done');
266
- const pi = makeFakePi();
267
- registerCanvasStophook(pi);
268
- settle(pi, stopEvent('M done'), { shutdown: () => { } });
269
- // handFocusToManager sees getFocusByNode('mgr') != null → returns false →
270
- // closeFocusRow(fM). Non-vacuous: moving mgr would either repoint its focus_id
271
- // to fM (and a wrong impl that didn't close fM would leave it present) or throw
272
- // UNIQUE(node_id); this pins mgr's OTHER focus untouched and M's focus gone.
273
- assert.equal(getFocusById('fM'), null, "M's focus is closed");
274
- assert.equal(getFocusByNode('mgr')?.focus_id, 'fOther', "the manager's other viewport is NOT stolen");
275
- // MINOR: M (done) is reaped on the close path — its own presence nulled.
276
- // Non-vacuous: an impl that skips the done-path setPresence-null leaves
277
- // getNode('M').pane === '%m'.
278
- assert.equal(getNode('M')?.pane ?? null, null, "the finished node's own LOCATION pane is nulled");
279
- });
280
- test('§5.1.4 truly-done + UNFOCUSED → no focus row created/touched, shuts down (Invariant P)', () => {
253
+ test('§5.1.4 truly-done + UNFOCUSED → no focus row created/touched, shuts down (Invariant P)', async () => {
281
254
  createNode(node('mgr', { parent: null, lifecycle: 'terminal', mode: 'orchestrator' }));
282
255
  createNode(node('M', { parent: 'mgr', lifecycle: 'terminal' }));
283
256
  subscribe('mgr', 'M', true);
@@ -286,28 +259,28 @@ test('§5.1.4 truly-done + UNFOCUSED → no focus row created/touched, shuts dow
286
259
  const pi = makeFakePi();
287
260
  registerCanvasStophook(pi);
288
261
  let shutdown = false;
289
- settle(pi, stopEvent('done, never had a viewport'), { shutdown: () => { shutdown = true; } });
262
+ await settle(pi, stopEvent('done, never had a viewport'), { shutdown: () => { shutdown = true; } });
290
263
  // focusOf(M) is null → the focus block is skipped entirely → just shutdown.
291
264
  // Non-vacuous: an impl that created or handed off a focus row would leave
292
265
  // listFocuses non-empty.
293
266
  assert.equal(shutdown, true, 'an unfocused done node shuts down');
294
267
  assert.equal(listFocuses().length, 0, 'no focus row was created or touched');
295
268
  });
296
- test('§5.1.5 awaiting + FOCUSED → STAY ALIVE: pi keeps running (no release), focus row untouched (F3)', () => {
269
+ test('§5.1.5 awaiting + FOCUSED → STAY ALIVE: pi keeps running (no release), focus row untouched (F3)', async () => {
297
270
  createNode(node('root', { parent: null, lifecycle: 'resident' }));
298
271
  createNode(node('mgr', { parent: 'root', lifecycle: 'terminal', mode: 'orchestrator' }));
299
272
  createNode(node('worker', { parent: 'mgr', lifecycle: 'terminal', status: 'active' }));
300
273
  subscribe('root', 'mgr', true);
301
274
  subscribe('mgr', 'worker', true); // mgr awaits a live worker → would idle-release if UNfocused
302
275
  // null pane (broker cut): focusOf passes a null-pane viewer row through, so the
303
- // handler reads mgr as FOCUSED in the tmux-free fast tier (a fabricated %pane
276
+ // handler reads mgr as FOCUSED in the tmux-free ordinary suite (a fabricated %pane
304
277
  // would be GC-pruned by liveOrPrune and the node would wrongly release).
305
278
  openFocusRow('fMgr', null, 'Suser', 'mgr');
306
279
  process.env['CRTR_NODE_ID'] = 'mgr';
307
280
  const pi = makeFakePi();
308
281
  registerCanvasStophook(pi);
309
282
  let shutdown = false;
310
- settle(pi, stopEvent('still waiting on the worker'), { shutdown: () => { shutdown = true; } });
283
+ await settle(pi, stopEvent('still waiting on the worker'), { shutdown: () => { shutdown = true; } });
311
284
  // A FOCUSED awaiting node holds the user's viewport, so the awaiting branch
312
285
  // keeps pi LIVE and dormant (the in-process inbox-watcher wakes it) instead of
313
286
  // releasing + shutting down. It must NOT release, NOT shut down, and NOT touch
@@ -318,14 +291,14 @@ test('§5.1.5 awaiting + FOCUSED → STAY ALIVE: pi keeps running (no release),
318
291
  assert.equal(shutdown, false, 'a focused awaiting node is NOT shut down — pi stays live');
319
292
  assert.equal(getFocusByNode('mgr')?.focus_id, 'fMgr', 'the focus row is UNCHANGED — not closed, not handed off');
320
293
  });
321
- test('§5.1.7 resident attended (no live subs) → nothing happens; focus + status survive', () => {
294
+ test('§5.1.7 resident attended (no live subs) → nothing happens; focus + status survive', async () => {
322
295
  createNode(node('root', { parent: null, lifecycle: 'resident' }));
323
296
  openFocusRow('fR', '%r', 'Suser', 'root');
324
297
  process.env['CRTR_NODE_ID'] = 'root';
325
298
  const pi = makeFakePi();
326
299
  registerCanvasStophook(pi);
327
300
  let shutdown = false;
328
- settle(pi, stopEvent('I have wrapped up'), { shutdown: () => { shutdown = true; } });
301
+ await settle(pi, stopEvent('I have wrapped up'), { shutdown: () => { shutdown = true; } });
329
302
  // evaluateStop on a resident → reason 'dormant' (NOT 'awaiting'), so the
330
303
  // awaiting branch is skipped and the handler does nothing: no release, no
331
304
  // shutdown, no focus touch. Non-vacuous: an impl that idle-released a resident
@@ -336,7 +309,7 @@ test('§5.1.7 resident attended (no live subs) → nothing happens; focus + stat
336
309
  assert.equal(getFocusByNode('root')?.focus_id, 'fR', 'focus row survives untouched');
337
310
  assert.equal(shutdown, false, 'a resident attended node is not shut down');
338
311
  });
339
- test('refresh-yield (intent=refresh) writes NO push — silent to subscribers', () => {
312
+ test('refresh-yield (intent=refresh) writes NO push — silent to subscribers', async () => {
340
313
  createNode(node('root', { parent: null, lifecycle: 'resident' }));
341
314
  createNode(node('orch', { parent: 'root', lifecycle: 'terminal', mode: 'orchestrator', intent: 'refresh' }));
342
315
  subscribe('root', 'orch', true);
@@ -344,7 +317,7 @@ test('refresh-yield (intent=refresh) writes NO push — silent to subscribers',
344
317
  const pi = makeFakePi();
345
318
  registerCanvasStophook(pi);
346
319
  let shutdown = false;
347
- settle(pi, stopEvent('checkpoint before refreshing'), { shutdown: () => { shutdown = true; } });
320
+ await settle(pi, stopEvent('checkpoint before refreshing'), { shutdown: () => { shutdown = true; } });
348
321
  assert.equal(shutdown, true, 'pi shut down (no tmux pane → clean shutdown)');
349
322
  assert.equal(reportCount('orch'), 0, 'a yield is silent: NO report file');
350
323
  assert.equal(readInboxSince('root').length, 0, 'a yield is silent: NO inbox pointer');
@@ -390,19 +363,19 @@ test('turn_end still clears a daemon→node wedge fault (existing behavior, unch
390
363
  pi.fire('turn_end', turnEndEvent('turn completed'), {});
391
364
  assert.equal(readFault('leaf'), null, 'the daemon→node wedge fault is still cleared at turn_end');
392
365
  });
393
- test('a successful final or human ask suppresses the stop reprompt without a canvas read', () => {
366
+ test('a successful final or human ask suppresses the stop reprompt without a canvas read', async () => {
394
367
  for (const [signal, shutsDown] of [['pushedFinal', true], ['askedHuman', false]]) {
395
368
  process.env['CRTR_NODE_ID'] = 'signal-only';
396
369
  markStopSignal('signal-only', signal);
397
370
  const pi = makeFakePi();
398
371
  registerCanvasStophook(pi);
399
372
  let shutdown = false;
400
- settle(pi, stopEvent(`completed ${signal}`), { shutdown: () => { shutdown = true; } });
373
+ await settle(pi, stopEvent(`completed ${signal}`), { shutdown: () => { shutdown = true; } });
401
374
  assert.equal(pi.injected.length, 0, `${signal} does not re-prompt when the broker cannot read its node`);
402
375
  assert.equal(shutdown, shutsDown, `${signal} takes its expected settled action`);
403
376
  }
404
377
  });
405
- test('an in-run retry (agent_start with no new input) does not erase this run\'s stop signal', () => {
378
+ test('an in-run retry (agent_start with no new input) does not erase this run\'s stop signal', async () => {
406
379
  // Regression: pi re-fires agent_start for automatic retries and post-compaction
407
380
  // continuations WITHIN one run. Clearing the marker there erased the ask/final
408
381
  // recorded earlier in the same run, so settlement fell back to a canvas read
@@ -418,15 +391,15 @@ test('an in-run retry (agent_start with no new input) does not erase this run\'s
418
391
  pi.fire('agent_start', { type: 'agent_start' }, ctx);
419
392
  markStopSignal('leaf', 'askedHuman'); // the node ran `crtr human ask` mid-run
420
393
  pi.fire('agent_start', { type: 'agent_start' }, ctx); // pi auto-retried after a provider error
421
- settle(pi, stopEvent('waiting on the human now'), ctx);
394
+ await settle(pi, stopEvent('waiting on the human now'), ctx);
422
395
  assert.equal(pi.injected.length, 0, 'the ask survives the in-run retry — no stall reprompt');
423
396
  // ...and the NEXT user-directed run does start clean.
424
397
  markStopSignal('leaf', 'askedHuman');
425
398
  pi.fire('input', { type: 'input' }, ctx);
426
- settle(pi, stopEvent('I think I am basically done here'), ctx);
399
+ await settle(pi, stopEvent('I think I am basically done here'), ctx);
427
400
  assert.equal(pi.injected.length, 1, 'a new input discards a leftover marker from a prior run');
428
401
  });
429
- test('stalled leaf (nothing live to await, no final) is still reprompted', () => {
402
+ test('stalled leaf (nothing live to await, no final) is still reprompted', async () => {
430
403
  createNode(node('mgr', { parent: null, lifecycle: 'terminal', mode: 'orchestrator' }));
431
404
  createNode(node('leaf', { parent: 'mgr', lifecycle: 'terminal', status: 'active' }));
432
405
  subscribe('mgr', 'leaf', true); // mgr subscribes to leaf; leaf itself awaits nothing
@@ -434,7 +407,7 @@ test('stalled leaf (nothing live to await, no final) is still reprompted', () =>
434
407
  const pi = makeFakePi();
435
408
  registerCanvasStophook(pi);
436
409
  let shutdown = false;
437
- settle(pi, stopEvent('I think I am basically done here'), { shutdown: () => { shutdown = true; } });
410
+ await settle(pi, stopEvent('I think I am basically done here'), { shutdown: () => { shutdown = true; } });
438
411
  assert.equal(pi.injected.length, 1, 'the stall reprompt fired');
439
412
  assert.equal(pi.injected[0].content, STALL_REPROMPT, 'reprompt carries the stall nudge to push final / ask');
440
413
  assert.equal(pi.injected[0].deliverAs, 'followUp', 'reprompt delivered as a followUp');