@north-light/crouter 0.3.173 → 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} +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/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
@@ -1,7 +1,18 @@
1
- // Run with: node --import tsx/esm --test src/core/__tests__/full/idle-release-settlement.test.ts
1
+ // Run with: node --import tsx/esm --test src/core/__tests__/seam/dormancy-release.test.ts
2
2
  //
3
- // Issue #222: a real idle-release cycle must settle the inbox watcher before the
4
- // broker exits. The daemon may only revive for a row strictly after that cursor.
3
+ // The two real dormancy journeys of a live broker, sharing one harness and one
4
+ // acting root:
5
+ //
6
+ // (1) Issue #222/#353 — a real idle-release cycle must settle the inbox watcher
7
+ // before the broker exits, and the daemon may only revive for a row strictly
8
+ // after the committed cursor.
9
+ // (2) The observed 57-broker / ~5.4GB leak — a boot-revived settled node that
10
+ // receives no new work must still traverse bounded release: DAEMON
11
+ // SUPERVISION, not an agent event, owns the unattended park clock, and the
12
+ // exit policy frees the fleet slot without reviving.
13
+ //
14
+ // Both drive a real broker process through the real watcher/supervision paths, so
15
+ // they belong to the compiled seam tier; neither needs tmux.
5
16
  import { after, before, test } from 'node:test';
6
17
  import assert from 'node:assert/strict';
7
18
  import { appendInbox, readCursor, readInboxSince } from '../../feed/inbox.js';
@@ -12,8 +23,8 @@ import { createHarness } from '../helpers/harness.js';
12
23
  let h;
13
24
  let root;
14
25
  before(async () => {
15
- h = await createHarness({ headless: true, sessionPrefix: 'crtr-settle' });
16
- root = h.spawnRoot('settlement suite root');
26
+ h = await createHarness({ headless: true, sessionPrefix: 'crtr-dormancy' });
27
+ root = h.spawnRoot('dormancy-release suite root');
17
28
  });
18
29
  after(async () => {
19
30
  if (h !== undefined)
@@ -38,18 +49,11 @@ test('idle-release settles its real watcher before exit; daemon revives exactly
38
49
  // launch.env, and calling reviveNode rather than through `spawnHeadlessChild`.
39
50
  //
40
51
  // The same launch.env carries the REAL canvas-inbox-watcher's injectable
41
- // cadence seam (CRTR_WATCHER_TICK_MS / CRTR_WATCHER_DEBOUNCE_MS — the same
42
- // seam canvas-inbox-watcher.test.ts/canvas-inbox-watcher-hold.test.ts/
43
- // deferred-no-wake.test.ts already drive fast, there via ambient env since
44
- // they run the watcher in-process). Left at the production 800ms/1000ms
45
- // default, this test's two full delivery cycles bake in >=3.6s of pure
46
- // wall-clock polling on top of two real broker boots — negligible in
47
- // isolation, but on a loaded CI runner deep in the serial `heavy` lane (the
48
- // only heavy-tier test that calls h.awaitWake()'s real, non-overridable 15s
49
- // cap) that starved interval tick has repeatedly lost the race and timed
50
- // out (issue: CI runs 29549096301/29549658681/29550017548, always at the
51
- // first h.awaitWake). Driving the cadence fast here removes the wall-clock
52
- // dependency entirely without weakening what's under test: the settlement
52
+ // cadence seam (CRTR_WATCHER_TICK_MS / CRTR_WATCHER_DEBOUNCE_MS). The
53
+ // ordinary source watcher suites drive it through ambient env because they
54
+ // run in-process. Keeping this compiled seam at production cadence would add
55
+ // multiple seconds of polling around two real broker boots, so it uses the
56
+ // same fast cadence without weakening what it proves: the settlement
53
57
  // lifecycle, cursor semantics, and hasPendingMessages veto are all
54
58
  // independent of how fast the watcher polls.
55
59
  const manager = h.fabricateBrokerNode({ id: 'settle-veto-manager', status: 'idle', parent: root });
@@ -106,3 +110,51 @@ test('idle-release settles its real watcher before exit; daemon revives exactly
106
110
  await h.tick();
107
111
  assert.equal(h.node(manager).cycles ?? 0, cyclesAfterRelease + 1, 'the settled later row does not cause a duplicate revival');
108
112
  });
113
+ test('a revived settled node with no work releases on the daemon park clock and leaves no broker', { timeout: 30_000 }, async () => {
114
+ // The park clock is read per supervision pass (unattendedParkMsForDaemon), so
115
+ // it is armed for THIS test only — a file-global 1500ms park clock would also
116
+ // apply to the idle-release manager above and race its own release path.
117
+ const priorParkMs = process.env['CRTR_TEST_UNATTENDED_PARK_MS'];
118
+ process.env['CRTR_TEST_UNATTENDED_PARK_MS'] = '1500';
119
+ try {
120
+ const nodeId = h.fabricateBrokerNode({
121
+ id: 'settled-no-work',
122
+ parent: root,
123
+ status: 'idle',
124
+ intent: 'idle-release',
125
+ });
126
+ updateNode(nodeId, {
127
+ launch: {
128
+ extensions: [],
129
+ tools: [],
130
+ systemPrompt: '',
131
+ env: {},
132
+ },
133
+ });
134
+ reviveNode(nodeId, { resume: true });
135
+ const boot = await h.awaitBoot(nodeId);
136
+ assert.equal(h.fleet.has(nodeId), true, 'the revived broker is fleet-owned');
137
+ const seenAt = 10_000;
138
+ await h.tick(seenAt);
139
+ await h.tick(seenAt + 1499);
140
+ assert.equal(h.fleet.has(nodeId), true, 'the daemon keeps the broker through the full grace');
141
+ await h.tick(seenAt + 1500);
142
+ await h.waitFor(() => {
143
+ const node = h.node(nodeId);
144
+ return node?.status === 'idle' && node.intent === 'idle-release' && !isPidAlive(boot.pid);
145
+ }, { timeoutMs: 10_000, intervalMs: 20, label: 'park-clock release and broker exit' });
146
+ // The pid vanishing is not the fleet learning about it: wait for the child
147
+ // 'exit' delivery + its policy job, which is what actually frees the slot.
148
+ await h.awaitFleetExit(nodeId);
149
+ assert.equal(h.fleet.has(nodeId), false, 'exit policy forgets the idle-release broker');
150
+ assert.equal(h.node(nodeId)?.intent, 'idle-release', 'the row remains durably dormant');
151
+ await h.tick();
152
+ assert.equal(h.fleet.has(nodeId), false, 'a supervision tick does not revive without inbox work');
153
+ }
154
+ finally {
155
+ if (priorParkMs === undefined)
156
+ delete process.env['CRTR_TEST_UNATTENDED_PARK_MS'];
157
+ else
158
+ process.env['CRTR_TEST_UNATTENDED_PARK_MS'] = priorParkMs;
159
+ }
160
+ });
@@ -1,14 +1,17 @@
1
- // Run with: node --import tsx/esm --test src/core/__tests__/full/yield-message-transaction.test.ts
1
+ // Run with: node --import tsx/esm --test src/core/__tests__/seam/yield-refresh-transaction.test.ts
2
2
  //
3
3
  // Regression: one-shot <yield-message/> handoff must survive pre-session_start cycle
4
- // death and only clear once session_start confirms a successful boot. This test
5
- // runs against the real broker process (headless harness) and a deterministic
6
- // one-shot pre-start fault injection so a single retry is exercised in-band.
4
+ // death and only clear once session_start confirms a successful boot, and a
5
+ // competing strict-resume revive (issue #146: a real `surface node focus` while
6
+ // the refresh is still pending) must not reopen the old session. This test runs
7
+ // against the real broker process (headless harness) and a deterministic one-shot
8
+ // pre-start fault injection so a single retry is exercised in-band.
7
9
  import { test, before, after } from 'node:test';
8
10
  import assert from 'node:assert/strict';
9
11
  import { existsSync } from 'node:fs';
10
12
  import { createHarness } from '../helpers/harness.js';
11
13
  import { isPidAlive } from '../../canvas/pid.js';
14
+ import { reviveNode } from '../../runtime/revive.js';
12
15
  import { readYieldMessage, yieldMessagePath } from '../../runtime/kickoff.js';
13
16
  import { FAIL_BEFORE_SESSION_START_ONCE } from '../fixtures/fake-engine.js';
14
17
  let h;
@@ -21,7 +24,7 @@ after(async () => {
21
24
  if (h !== undefined)
22
25
  await h.dispose();
23
26
  });
24
- // 30s (approved full-tier cap): three real broker boots plus the exit-policy
27
+ // 30s (approved compiled-seam cap): three real broker boots plus the exit-policy
25
28
  // respawn throttle's first ~5s backoff before the successful retry.
26
29
  test('yield-message survives one pre-session_start retry and clears on session_start', { timeout: 30_000 }, async () => {
27
30
  const note = `Issue #146 pre-session_start replay ${FAIL_BEFORE_SESSION_START_ONCE} keeps the wake note`;
@@ -44,15 +47,34 @@ test('yield-message survives one pre-session_start retry and clears on session_s
44
47
  return pid != null && pid !== oldPid ? pid : null;
45
48
  }, { label: 'exit-event refresh attempt recorded its broker pid', timeoutMs: 30_000 });
46
49
  await h.waitFor(() => !isPidAlive(failedCyclePid), { label: 'one-shot cycling broker died before session_start' });
50
+ // PID death precedes Node's ChildProcess `exit` delivery. Wait through the
51
+ // authoritative fleet barrier and its queued exit-policy job so the contender
52
+ // below reaches refresh arbitration instead of returning on stale liveness.
53
+ // The policy has only armed its backoff timer at this point; no recovery broker
54
+ // owns the slot yet.
55
+ await h.awaitFleetExit(id);
47
56
  const afterFirstExit = h.node(id);
57
+ assert.equal(h.fleet.has(id), false, 'the failed broker has left the authoritative fleet before focus competes');
48
58
  assert.equal(afterFirstExit?.cycles, baseCycles + 1, 'the first refresh attempt advances cycles');
59
+ assert.equal(afterFirstExit?.intent, 'refresh', 'the durable refresh intent still confronts the strict-resume contender');
49
60
  assert.equal(afterFirstExit?.cycle_pending, true, 'cycle_pending remains true until session_start confirms');
50
61
  assert.equal(readYieldMessage(id), note, 'yield note stays present after pre-session_start failure');
51
62
  assert.equal(existsSync(yieldMessagePath(id)), true, 'yield file survives the failed cycle');
52
- // That failed attempt's real exit classifies row 7 (cycle_pending) and keeps
53
- // the retry in cycle mode until session_start confirms. The respawn throttle
54
- // may delay it briefly, but no poll is required.
63
+ // A real `surface node focus` on the node right now asks the revive arbiter for
64
+ // a STRICT RESUME (issue #146). It must lose to the durable pending refresh:
65
+ // the retry still roots a fresh cycle carrying the note, never reopening the
66
+ // old session. Driving reviveNode directly is exactly what focus's revive path
67
+ // calls, minus a tmux pane this contract does not involve.
68
+ const focusRevive = reviveNode(id, { resume: true });
69
+ const focusPid = focusRevive.launch?.pid;
70
+ assert.ok(focusPid != null, 'the competing focus invocation launches the replacement broker');
71
+ assert.equal(focusRevive.resumed, false, 'refresh intent overrides this invocation\'s strict-resume request');
72
+ assert.equal(h.fleet.get(id)?.pid, focusPid, 'the focus invocation synchronously owns the authoritative fleet slot');
73
+ // Registering the manual launch cancels the exit policy's deferred recovery.
74
+ // Its pid must therefore be the successful observed boot, proving these
75
+ // assertions belong to the contender above rather than an already-queued boot.
55
76
  const boot = await h.awaitBoot(id, { minCount: baseBoot + 1, timeoutMs: 120_000 });
77
+ assert.equal(boot.pid, focusPid, 'the competing focus invocation owns the confirmed boot');
56
78
  const afterRetry = h.node(id);
57
79
  assert.equal(afterRetry?.cycles, baseCycles + 2, 'the retry advances once from the latest locked cycle');
58
80
  assert.equal(afterRetry?.cycle_pending, false, 'session_start cleared cycle_pending');
@@ -62,7 +84,7 @@ test('yield-message survives one pre-session_start retry and clears on session_s
62
84
  assert.equal(boot.prompt.includes(note), true, 'the successful retry kickoff still contains the yield note');
63
85
  assert.match(boot.prompt, /<goal file="[^"]+">/, 'a no-roadmap base refresh includes its original goal');
64
86
  assert.equal(boot.prompt.includes('headless worker — yield message transactional retry'), true, 'the kickoff carries the original base-node mandate');
65
- assert.equal(boot.resuming, false, 'yield refresh roots a fresh cycle instead of strictly resuming');
87
+ assert.equal(boot.resuming, false, 'a competing focus resume=true cannot reopen the old session while the refresh is pending');
66
88
  const updated = h.node(id);
67
89
  assert.equal(updated?.mode, 'base', 'a plain yield refresh remains base');
68
90
  assert.ok(updated?.pi_session_id != null, 'successful retry recorded a session id');
@@ -7,7 +7,7 @@ import assert from 'node:assert/strict';
7
7
  import { mkdtempSync, rmSync, statSync, existsSync, chmodSync } from 'node:fs';
8
8
  import { tmpdir } from 'node:os';
9
9
  import { join } from 'node:path';
10
- import { readSecrets, writeSecrets, getRelayToken, setRelayToken, deleteRelayToken, fingerprint } from '../secrets.js';
10
+ import { readSecrets, writeSecrets, getRelayToken, setRelayToken, deleteRelayToken } from '../secrets.js';
11
11
  let home;
12
12
  let realHome;
13
13
  before(() => {
@@ -47,9 +47,3 @@ test('writeSecrets writes secrets.json 0600, even over a pre-existing looser-mod
47
47
  writeSecrets('user', { relayTokens: { a: 'x', b: 'y' } });
48
48
  assert.equal(statSync(p).mode & 0o777, 0o600);
49
49
  });
50
- test('fingerprint is the sha256(token) hex prefix — pinned, so a reversible encoding fails', () => {
51
- assert.equal(fingerprint('sekret-token-value'), '662bda51b31e');
52
- assert.notEqual(fingerprint('a-different-token'), fingerprint('sekret-token-value'));
53
- assert.match(fingerprint('sekret-token-value'), /^[0-9a-f]{12}$/);
54
- assert.ok(!fingerprint('sekret-token-value').includes('sekret-token-value'));
55
- });
@@ -1,4 +1,4 @@
1
- // Run with: node --import tsx/esm --test src/core/__tests__/broker-fork-seam.test.ts
1
+ // Run with: npm run test:serial
2
2
  //
3
3
  // BUG-REGRESSION (broker-universal-host cut, design §B.broker; U1 report
4
4
  // mq8ftenr-5d55313d). Before the cut, the headless broker had NO fork path — its
@@ -24,17 +24,20 @@
24
24
  // uses, whose fixture omits forkFrom and so could never exercise this branch. It
25
25
  // runs offline (fork + session/services assembly are all local: no network/auth).
26
26
  //
27
- // (fork.test.ts covers the pure argv/resolve layers — buildPiArgv emitting
28
- // `--fork`, resolveForkSource turning a ref into a path. THIS file covers the
29
- // broker runtime branch those layers feed.)
27
+ // The tail of this file covers the pre-launch resolve layer that feeds the
28
+ // broker branch: `resolveForkSource` refusing a reference that resolves to no
29
+ // forkable session file.
30
30
  import { test, before, after } from 'node:test';
31
31
  import assert from 'node:assert/strict';
32
32
  import { mkdtempSync, rmSync, writeFileSync } from 'node:fs';
33
33
  import { tmpdir } from 'node:os';
34
34
  import { dirname, join } from 'node:path';
35
35
  import { fileURLToPath } from 'node:url';
36
- import { createAgentSessionServices, createAgentSessionFromServices, SessionManager, VERSION, } from '../runtime/broker-sdk.js';
37
- import { buildBrokerSession } from '../runtime/broker.js';
36
+ import { createNode } from '../../canvas/canvas.js';
37
+ import { closeDb } from '../../canvas/db.js';
38
+ import { resolveForkSource } from '../../runtime/spawn.js';
39
+ import { createAgentSessionServices, createAgentSessionFromServices, SessionManager, VERSION, } from '../../runtime/broker-sdk.js';
40
+ import { buildBrokerSession } from '../../runtime/broker.js';
38
41
  // M-9 (broker.ts fault-and-die model gate): buildBrokerSession with no cfg.model
39
42
  // now calls the REAL SDK's modelRegistry.getAvailable() and faults if it's empty
40
43
  // — which it always is on a host/CI runner with no authenticated provider. This
@@ -42,7 +45,7 @@ import { buildBrokerSession } from '../runtime/broker.js';
42
45
  // fake-but-authenticated model the C3 wiring tests use, rather than depending on
43
46
  // ambient host credentials (which don't exist in CI — see broker-sdk-wiring's
44
47
  // c3-custom-provider-ext.ts fixture).
45
- const HERE = dirname(fileURLToPath(import.meta.url));
48
+ const HERE = join(dirname(fileURLToPath(import.meta.url)), '..');
46
49
  const C3_EXT = join(HERE, 'fixtures', 'c3-custom-provider-ext.ts');
47
50
  // The REAL engine — bypasses the CRTR_BROKER_ENGINE fake entirely (the whole
48
51
  // point: the fake omits forkFrom, so only the real SDK can prove the branch).
@@ -115,3 +118,51 @@ test('D2 broker fork branch: buildBrokerSession(cfg.forkFrom) yields a NEW id +
115
118
  session.dispose();
116
119
  }
117
120
  });
121
+ // ---------------------------------------------------------------------------
122
+ // resolveForkSource — a reference that resolves to no forkable session file
123
+ // must fail loudly BEFORE launch, rather than hand the broker a source it
124
+ // cannot fork.
125
+ // ---------------------------------------------------------------------------
126
+ function nodeRow(id, over = {}) {
127
+ return {
128
+ node_id: id,
129
+ name: id,
130
+ created: new Date().toISOString(),
131
+ cwd: '/tmp/work',
132
+ kind: 'developer',
133
+ mode: 'base',
134
+ lifecycle: 'terminal',
135
+ status: 'active',
136
+ ...over,
137
+ };
138
+ }
139
+ test('resolveForkSource refuses every reference that resolves to no forkable session file', () => {
140
+ const home = mkdtempSync(join(tmpdir(), 'crtr-fork-resolve-'));
141
+ const sessions = mkdtempSync(join(tmpdir(), 'crtr-pi-agent-'));
142
+ const previousHome = process.env['CRTR_HOME'];
143
+ process.env['CRTR_HOME'] = home;
144
+ process.env['PI_CODING_AGENT_DIR'] = sessions;
145
+ try {
146
+ // Broker-cut contract (U6/§B.broker): the broker forks an absolute .jsonl
147
+ // PATH, never a bare session id, so a node row carrying only pi_session_id
148
+ // is unforkable.
149
+ createNode(nodeRow('id-only', { pi_session_id: 'uuid-1' }));
150
+ assert.throws(() => resolveForkSource('id-only'), /no pi session yet|session FILE/);
151
+ createNode(nodeRow('fresh'));
152
+ assert.throws(() => resolveForkSource('fresh'), /no pi session yet/);
153
+ // An unknown bare/partial uuid is scanned against pi's sessions store and
154
+ // fails when it matches nothing — never passed through verbatim.
155
+ assert.throws(() => resolveForkSource('019e8ce3-322e'), /no pi session/);
156
+ assert.throws(() => resolveForkSource(' '), /requires a node id/);
157
+ }
158
+ finally {
159
+ closeDb();
160
+ delete process.env['PI_CODING_AGENT_DIR'];
161
+ if (previousHome === undefined)
162
+ delete process.env['CRTR_HOME'];
163
+ else
164
+ process.env['CRTR_HOME'] = previousHome;
165
+ rmSync(home, { recursive: true, force: true });
166
+ rmSync(sessions, { recursive: true, force: true });
167
+ }
168
+ });
@@ -1,4 +1,4 @@
1
- // Run with: node --import tsx/esm --test src/core/__tests__/broker-sdk-wiring.test.ts
1
+ // Run with: npm run test:serial
2
2
  //
3
3
  // REAL-SDK regression tests for the latent broker gaps the viewer-reuse scout
4
4
  // (node mq5thyli) found (findings-viewer-reuse.md §Q2). These deliberately drive
@@ -25,13 +25,10 @@ import { spawnSync } from 'node:child_process';
25
25
  import { tmpdir } from 'node:os';
26
26
  import { join, dirname } from 'node:path';
27
27
  import { fileURLToPath } from 'node:url';
28
- import { createAgentSessionServices, createAgentSessionFromServices, SessionManager, VERSION, } from '../runtime/broker-sdk.js';
29
- import { buildBrokerSession, makeBrokerUiContext, isLeadingEngineCommand, resolveSteerCall, chooseGuidanceDeliveryMode, promptWithNextTurnGuidance, isHiddenJsonlBranchEntry, stripHiddenEntriesFromJsonlExport, engineLeadingCommandTokens, } from '../runtime/broker.js';
30
- import { CANVAS_EXTENSIONS } from '../runtime/launch.js';
31
- import { buildRefInventory } from '../memory/inline-ref-inventory.js';
32
- import { buildGuidance } from '../memory/inline-ref-guidance.js';
33
- import { resetScopeCache } from '../scope.js';
34
- import { clearSessionCache } from '../substrate/session-cache.js';
28
+ import { createAgentSessionServices, createAgentSessionFromServices, SessionManager, VERSION, } from '../../runtime/broker-sdk.js';
29
+ import { buildBrokerSession, makeBrokerUiContext } from '../../runtime/broker.js';
30
+ import { isLeadingEngineCommand, resolveSteerCall, chooseGuidanceDeliveryMode, promptWithNextTurnGuidance, isHiddenJsonlBranchEntry, stripHiddenEntriesFromJsonlExport, engineLeadingCommandTokens, } from '../../runtime/broker/frame-dispatch.js';
31
+ import { CANVAS_EXTENSIONS } from '../../runtime/launch.js';
35
32
  // The REAL engine, assembled from broker-sdk's static SDK re-exports — bypasses
36
33
  // the CRTR_BROKER_ENGINE seam entirely so these tests can never accidentally hit
37
34
  // the fake (the whole point: prove the wiring the mock hid).
@@ -41,7 +38,7 @@ const realEngine = {
41
38
  SessionManager,
42
39
  VERSION,
43
40
  };
44
- const HERE = dirname(fileURLToPath(import.meta.url));
41
+ const HERE = join(dirname(fileURLToPath(import.meta.url)), '..');
45
42
  const C3_EXT = join(HERE, 'fixtures', 'c3-custom-provider-ext.ts');
46
43
  const C5_EXT = join(HERE, 'fixtures', 'c5-command-boundary-ext.ts');
47
44
  const priorModelIntent = process.env['CRTR_MODEL_INTENT'];
@@ -161,9 +158,9 @@ function runIsolatedManagedLaunch(pool) {
161
158
  const home = mkdtempSync(join(tmpdir(), 'crtr-c3-managed-home-'));
162
159
  const cwd = mkdtempSync(join(tmpdir(), 'crtr-c3-managed-cwd-'));
163
160
  const script = `
164
- const { createAgentSessionServices, createAgentSessionFromServices, SessionManager, VERSION } = await import(${JSON.stringify(new URL('../runtime/broker-sdk.ts', import.meta.url).href)});
165
- const { buildBrokerSession } = await import(${JSON.stringify(new URL('../runtime/broker.ts', import.meta.url).href)});
166
- const { writeSubscriptionPool } = await import(${JSON.stringify(new URL('../subscription-state.ts', import.meta.url).href)});
161
+ const { createAgentSessionServices, createAgentSessionFromServices, SessionManager, VERSION } = await import(${JSON.stringify(new URL('../../runtime/broker-sdk.ts', import.meta.url).href)});
162
+ const { buildBrokerSession } = await import(${JSON.stringify(new URL('../../runtime/broker.ts', import.meta.url).href)});
163
+ const { writeSubscriptionPool } = await import(${JSON.stringify(new URL('../../subscription-state.ts', import.meta.url).href)});
167
164
  await writeSubscriptionPool('anthropic', ${JSON.stringify(pool)});
168
165
  const realEngine = { createAgentSessionServices, createAgentSessionFromServices, SessionManager, VERSION };
169
166
  const engine = {
@@ -358,14 +355,13 @@ test('M2 — a forwarded dialog stays pending when its writable viewer detaches,
358
355
  assert.equal(pending.size, 0, 'M2: the pending registry is drained after the timeout');
359
356
  });
360
357
  // ===========================================================================
361
- // C5 — inline memory-reference read-op, memoized inventory + reload
362
- // invalidation, exact leading engine-command suppression, and hidden
363
- // display:false guidance delivery ordering.
358
+ // C5 — exact leading engine-command suppression and hidden display:false
359
+ // guidance delivery ordering.
364
360
  //
365
361
  // REACHABILITY NOTE: broker.ts's `handleFrame`/`driveEngine` switches are
366
- // private closures inside `runBroker`, so the fast tier does not boot a broker
367
- // process to drive raw wire frames (that end-to-end plumbing lives in the
368
- // full/ tier alongside the sibling `list_models` read-op). Instead every
362
+ // private closures inside `runBroker`, so this serialized source suite does not
363
+ // boot a broker process to drive raw wire frames (that end-to-end plumbing lives
364
+ // in the compiled seam alongside the sibling `list_models` read-op). Instead every
369
365
  // EXPORTED building block those closures call is driven directly — the pure
370
366
  // decision functions (`isLeadingEngineCommand`, `chooseGuidanceDeliveryMode`,
371
367
  // `engineLeadingCommandTokens`) AND the stateful delivery/export helpers
@@ -374,41 +370,10 @@ test('M2 — a forwarded dialog stays pending when its writable viewer detaches,
374
370
  // JSONL bytes, including the exact interception/leak window (Major 1) and the
375
371
  // actual exported file (Major 2). What remains untested here is only the
376
372
  // one-line frame relay (`sendFrame(client, buildListMemoryRefsData(id))`), a
377
- // verbatim sibling of the full-tier-covered `list_models` dispatch whose only
373
+ // verbatim sibling of the compiled-seam-covered `list_models` dispatch whose only
378
374
  // non-trivial input, `engineLeadingCommandTokens(session)`, is proven below
379
375
  // against a real session.
380
376
  // ===========================================================================
381
- test('C5 — isLeadingEngineCommand truth table against structural stubs (pure, no live session)', () => {
382
- // Extension command: matches / does not match.
383
- const extOnly = { extensionRunner: { getCommand: (name) => (name === 'dev' ? { name: 'dev' } : undefined) } };
384
- assert.equal(isLeadingEngineCommand('/dev', extOnly), true, 'registered extension command matches');
385
- assert.equal(isLeadingEngineCommand('/dev extra args', extOnly), true, 'space-separated still matches (name up to first space)');
386
- assert.equal(isLeadingEngineCommand('/nope', extOnly), false, 'unregistered command name does not match');
387
- // Skill: matches / does not match.
388
- const skillOnly = { resourceLoader: { getSkills: () => ({ skills: [{ name: 'myskill' }] }) } };
389
- assert.equal(isLeadingEngineCommand('/skill:myskill', skillOnly), true, 'registered skill matches');
390
- assert.equal(isLeadingEngineCommand('/skill:other', skillOnly), false, 'unregistered skill name does not match');
391
- // Template: matches / does not match.
392
- const templateOnly = { promptTemplates: [{ name: 'mytemplate' }] };
393
- assert.equal(isLeadingEngineCommand('/mytemplate', templateOnly), true, 'registered prompt template matches');
394
- assert.equal(isLeadingEngineCommand('/other', templateOnly), false, 'unregistered template name does not match');
395
- // Prose with no leading slash never matches any of the three checks.
396
- assert.equal(isLeadingEngineCommand('no leading slash here /dev', extOnly), false, 'a leading command check only looks at text start');
397
- // An engine missing an accessor entirely degrades to "not a match", never throws.
398
- assert.equal(isLeadingEngineCommand('/dev', {}), false, 'a bare {} session (no accessors) degrades to false without throwing');
399
- // A throwing accessor for one check must not abort the OTHER independent
400
- // checks — here extensionRunner.getCommand throws, but the SAME text still
401
- // correctly resolves via promptTemplates.
402
- const throwingExtButRealTemplate = {
403
- extensionRunner: {
404
- getCommand: () => {
405
- throw new Error('boom: no live extensionRunner');
406
- },
407
- },
408
- promptTemplates: [{ name: 'mytemplate' }],
409
- };
410
- assert.equal(isLeadingEngineCommand('/mytemplate', throwingExtButRealTemplate), true, 'a throwing extensionRunner check degrades to false for ITSELF but does not abort the template check');
411
- });
412
377
  test('a streaming extension command uses prompt preflight instead of the rejecting steer queue', () => {
413
378
  const session = { extensionRunner: { getCommand: (name) => (name === 'recap' ? { name: 'recap' } : undefined) } };
414
379
  assert.equal(resolveSteerCall('/recap', session), 'prompt');
@@ -420,9 +385,8 @@ test('C5 — isLeadingEngineCommand against a REAL session (registered extension
420
385
  // (the real broker's initial-boot step, which fires `resources_discover`) —
421
386
  // not reachable from `buildBrokerSession` alone, and driving it directly
422
387
  // pulls in this machine's full local pi resource corpus (slow, environment-
423
- // dependent). Those two branches are covered structurally instead, in the
424
- // stub-based truth-table test above — same decision logic, same code path,
425
- // proven against a plain object shaped like the real accessors.
388
+ // dependent). The skill/prompt-template branches run the same accessor-
389
+ // guarded decision logic as the extension-command branch proven here.
426
390
  const cwd = mkdtempSync(join(tmpdir(), 'crtr-c5-cmd-'));
427
391
  try {
428
392
  const { session } = await buildBrokerSession(realEngine, cfg(cwd, { extensionPaths: [C3_EXT, C5_EXT], model: 'c3prov/c3model' }));
@@ -454,77 +418,6 @@ test('C5 — chooseGuidanceDeliveryMode truth table (pure)', () => {
454
418
  // steer, never nextTurn (that would attach guidance to a later, unrelated turn).
455
419
  assert.equal(chooseGuidanceDeliveryMode('prompt', 'prompt', true), 'steer');
456
420
  });
457
- test('C5 — buildRefInventory reflects a new doc only after clearSessionCache (the invalidation contract `case \'reload\'` relies on)', () => {
458
- const canvasHome = mkdtempSync(join(tmpdir(), 'crtr-c5-inv-canvas-'));
459
- const userHome = mkdtempSync(join(tmpdir(), 'crtr-c5-inv-user-'));
460
- const projectBase = mkdtempSync(join(tmpdir(), 'crtr-c5-inv-project-'));
461
- const projectRoot = join(projectBase, 'root');
462
- const prevCanvasHome = process.env['CRTR_HOME'];
463
- const prevUserHome = process.env['HOME'];
464
- const prevNodeId = process.env['CRTR_NODE_ID'];
465
- const prevCwd = process.cwd();
466
- try {
467
- mkdirSync(projectRoot, { recursive: true });
468
- process.env['CRTR_HOME'] = canvasHome;
469
- process.env['HOME'] = userHome;
470
- delete process.env['CRTR_NODE_ID'];
471
- process.chdir(projectRoot);
472
- resetScopeCache();
473
- clearSessionCache();
474
- const memoryDir = join(projectRoot, '.crouter', 'memory');
475
- mkdirSync(memoryDir, { recursive: true });
476
- writeFileSync(join(memoryDir, 'crtr-c5-inv-first.md'), '---\nkind: knowledge\n---\nBody.\n');
477
- const first = buildRefInventory();
478
- assert.ok(first.names.has('crtr-c5-inv-first'), 'the first doc is visible on the first build');
479
- // A second doc written after the first inventory build must NOT appear
480
- // until the session parse cache is cleared — this is the exact mechanism
481
- // broker.ts's `case 'reload'` invalidates by calling `clearSessionCache()`
482
- // (and, in broker.ts, also resetting its own `memoizedRefInventory`).
483
- writeFileSync(join(memoryDir, 'crtr-c5-inv-second.md'), '---\nkind: knowledge\n---\nBody.\n');
484
- const stale = buildRefInventory();
485
- assert.ok(!stale.names.has('crtr-c5-inv-second'), 'a doc written after the cache was warmed is NOT yet visible');
486
- clearSessionCache();
487
- const fresh = buildRefInventory();
488
- assert.ok(fresh.names.has('crtr-c5-inv-second'), 'clearSessionCache() makes the new doc visible — the reload contract');
489
- }
490
- finally {
491
- process.chdir(prevCwd);
492
- resetScopeCache();
493
- clearSessionCache();
494
- rmSync(canvasHome, { recursive: true, force: true });
495
- rmSync(userHome, { recursive: true, force: true });
496
- rmSync(projectBase, { recursive: true, force: true });
497
- if (prevCanvasHome === undefined)
498
- delete process.env['CRTR_HOME'];
499
- else
500
- process.env['CRTR_HOME'] = prevCanvasHome;
501
- if (prevUserHome === undefined)
502
- delete process.env['HOME'];
503
- else
504
- process.env['HOME'] = prevUserHome;
505
- if (prevNodeId === undefined)
506
- delete process.env['CRTR_NODE_ID'];
507
- else
508
- process.env['CRTR_NODE_ID'] = prevNodeId;
509
- }
510
- });
511
- test('C5 — guidance composition mirrors broker.ts\'s private resolveFrameGuidance: leading-command check first, then buildGuidance', () => {
512
- // Mirrors broker.ts's private `resolveFrameGuidance(text)`:
513
- // if (isLeadingEngineCommand(text, session)) return null;
514
- // return buildGuidance(text, getRefInventory().names);
515
- // `isLeadingEngineCommand`/`buildGuidance` are each independently covered
516
- // above / in C4's own suite (inline-memory-refs.test.ts) — this proves only
517
- // the ORDER of composition: a leading match short-circuits before any ref
518
- // in the SAME text is ever resolved.
519
- const stubSession = { extensionRunner: { getCommand: () => undefined } };
520
- const names = new Set(['dev']);
521
- assert.equal(isLeadingEngineCommand('/dev /dev', stubSession), false, 'not a registered command against this stub');
522
- assert.equal(buildGuidance('/dev /dev', names), [
523
- 'The human explicitly referenced these memory documents. Before acting on the portion of their message that references each document, run the corresponding command and treat its returned content as authoritative context:',
524
- '- crtr memory read dev',
525
- ].join('\n'), 'a non-leading-command text with a resolvable ref still produces guidance');
526
- assert.equal(buildGuidance('/nope has nothing to do with it', names), null, 'an unresolvable ref alone produces no guidance');
527
- });
528
421
  test('C5 — fake-engine sendCustomMessage records the call in order without crashing', async () => {
529
422
  const home = mkdtempSync(join(tmpdir(), 'crtr-c5-fake-home-'));
530
423
  const cwd = mkdtempSync(join(tmpdir(), 'crtr-c5-fake-cwd-'));
@@ -533,7 +426,7 @@ test('C5 — fake-engine sendCustomMessage records the call in order without cra
533
426
  try {
534
427
  process.env['CRTR_HOME'] = home;
535
428
  process.env['CRTR_NODE_ID'] = 'crtr-c5-fake-node';
536
- const fake = await import('./fixtures/fake-engine.js');
429
+ const fake = await import('.././fixtures/fake-engine.js');
537
430
  const services = await fake.createAgentSessionServices({ cwd });
538
431
  const sessionManager = fake.SessionManager.create(cwd);
539
432
  const { session } = await fake.createAgentSessionFromServices({ services, sessionManager });
@@ -609,27 +502,6 @@ test('promptWithNextTurnGuidance uses a structured-clone-safe cleanup marker', a
609
502
  await promptWithNextTurnGuidance(session, 'crtr memory read dev', async () => undefined);
610
503
  assert.deepEqual(pending, [], 'clone-safe marker still identifies and clears exactly its own pending entry');
611
504
  });
612
- test('Major 1 fix — pre-fix sequence (sendCustomMessage THEN prompt, no cleanup) reproduces the leak this fix removes', async () => {
613
- // Negative control: proves the fixture/interception setup above genuinely
614
- // exercises the leak window — the OLD sequencing (what driveEngine did
615
- // before this fix) strands the guidance under the exact same interception.
616
- const cwd = mkdtempSync(join(tmpdir(), 'crtr-m1-repro-'));
617
- try {
618
- const { session } = await buildBrokerSession(realEngine, cfg(cwd, { extensionPaths: [C5_EXT] }));
619
- try {
620
- await session.sendCustomMessage({ customType: 'crtr-memory-refs', content: 'guidance', display: false }, { deliverAs: 'nextTurn' });
621
- await session.prompt('/devcmd', {});
622
- const pending = session._pendingNextTurnMessages;
623
- assert.equal(pending.length, 1, 'Major 1 (control): the pre-fix sequence strands exactly the guidance message it pushed');
624
- }
625
- finally {
626
- session.dispose();
627
- }
628
- }
629
- finally {
630
- rmSync(cwd, { recursive: true, force: true });
631
- }
632
- });
633
505
  test('Major 1 fix — promptWithNextTurnGuidance leaves the queue drained (not doubly-cleared) on a normal successful prompt', async () => {
634
506
  // Guards against the cleanup over-firing on the HAPPY path: a prompt that
635
507
  // genuinely reaches pi's drain already empties `_pendingNextTurnMessages`
@@ -718,22 +590,6 @@ test('Major 2 fix — exportToJsonl (via the broker export path) strips display:
718
590
  // (RefMeta rows), exactly matching `isLeadingEngineCommand`'s three sources,
719
591
  // so viewers can combine it with their own locally-consumed commands.
720
592
  // ===========================================================================
721
- test('Major 6 (broker half) — engineLeadingCommandTokens exactly matches isLeadingEngineCommand\'s sources (round-trip, pure stubs)', () => {
722
- const session = {
723
- extensionRunner: {
724
- getRegisteredCommands: () => [{ invocationName: 'devcmd' }],
725
- getCommand: (n) => (n === 'devcmd' ? {} : undefined),
726
- },
727
- resourceLoader: { getSkills: () => ({ skills: [{ name: 'myskill' }] }) },
728
- promptTemplates: [{ name: 'mytemplate' }],
729
- };
730
- const tokens = engineLeadingCommandTokens(session);
731
- assert.deepEqual(new Set(tokens), new Set(['devcmd', 'skill:myskill', 'mytemplate']), 'every one of the three sources is enumerated, in isLeadingEngineCommand\'s own token shape');
732
- for (const token of tokens) {
733
- assert.equal(isLeadingEngineCommand(`/${token}`, session), true, `emitted token "${token}" round-trips through isLeadingEngineCommand as a leading match`);
734
- }
735
- assert.equal(isLeadingEngineCommand('/nope', session), false, 'a name NOT in the enumeration correctly does not match');
736
- });
737
593
  test('Major 6 (broker half) — engineLeadingCommandTokens degrades to empty per-source without throwing, and never touches refs/RefMeta shape', () => {
738
594
  assert.deepEqual(engineLeadingCommandTokens({}), [], 'a bare session with no accessors at all degrades to an empty enumeration');
739
595
  const throwingExtButRealTemplate = {
@@ -1,4 +1,4 @@
1
- // Run with: node --import tsx/esm --test src/core/__tests__/broker-snapshot-history.test.ts
1
+ // Run with: npm run test:serial
2
2
  //
3
3
  // BUG-REGRESSION (real, observed; surfaced during the crouter-web build, proven
4
4
  // broker-side). After a revive resumes a previously-CLOSED pi session, the
@@ -29,19 +29,19 @@ import { mkdtempSync, rmSync } from 'node:fs';
29
29
  import { tmpdir } from 'node:os';
30
30
  import { dirname, join } from 'node:path';
31
31
  import { fileURLToPath } from 'node:url';
32
- import { createAgentSessionServices, createAgentSessionFromServices, SessionManager, VERSION, } from '../runtime/broker-sdk.js';
33
- import { CANVAS_EXTENSIONS } from '../runtime/launch.js';
34
- import { buildBrokerSession, snapshotMessages } from '../runtime/broker.js';
35
- import { createNode } from '../canvas/canvas.js';
36
- import { closeDb } from '../canvas/db.js';
37
- import { transcriptMarkdown } from '../runtime/node-read.js';
32
+ import { createAgentSessionServices, createAgentSessionFromServices, SessionManager, VERSION, } from '../../runtime/broker-sdk.js';
33
+ import { CANVAS_EXTENSIONS } from '../../runtime/launch.js';
34
+ import { buildBrokerSession, snapshotMessages } from '../../runtime/broker.js';
35
+ import { createNode } from '../../canvas/canvas.js';
36
+ import { closeDb } from '../../canvas/db.js';
37
+ import { transcriptMarkdown } from '../../runtime/node-read.js';
38
38
  // M-9 (broker.ts fault-and-die model gate): a boot with no cfg.model now calls
39
39
  // the REAL SDK's modelRegistry.getAvailable() and faults if it's empty, which it
40
40
  // always is on a host/CI runner with no authenticated provider. This test only
41
41
  // exercises snapshot/history reconstruction, so it registers the same hermetic
42
42
  // fake-but-authenticated model the C3 wiring tests use instead of depending on
43
43
  // ambient host credentials (see broker-sdk-wiring's c3-custom-provider-ext.ts).
44
- const HERE = dirname(fileURLToPath(import.meta.url));
44
+ const HERE = join(dirname(fileURLToPath(import.meta.url)), '..');
45
45
  const C3_EXT = join(HERE, 'fixtures', 'c3-custom-provider-ext.ts');
46
46
  const realEngine = {
47
47
  createAgentSessionServices,
@@ -66,7 +66,7 @@ function assistantMsg(text, stopReason = 'stop') {
66
66
  timestamp: Date.now(),
67
67
  };
68
68
  }
69
- // 30s (approved in scripts/test-runner.mjs): this boot loads the REAL mandatory
69
+ // 30s: this boot loads the REAL mandatory
70
70
  // canvas extension set from TypeScript sources, and those extensions pull the
71
71
  // crouter module graph through tsx for the first time in the process — ~6s of
72
72
  // the ~9s local runtime, and 12.6s total on a hosted runner, which blew the