@north-light/crouter 0.3.172 → 0.3.174

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (673) hide show
  1. package/bin/runtime-selector.mjs +8 -1
  2. package/dist/api/__tests__/{client.test.js → serial/client.test.js} +2 -135
  3. package/dist/api/client.d.ts +12 -21
  4. package/dist/api/client.js +22 -31
  5. package/dist/api/dto/broker-ops.d.ts +158 -0
  6. package/dist/api/dto/broker-ops.js +6 -0
  7. package/dist/api/dto/crons.d.ts +6 -0
  8. package/dist/api/dto/human.d.ts +7 -1
  9. package/dist/api/dto/inbox.d.ts +1 -71
  10. package/dist/api/dto/inbox.js +1 -9
  11. package/dist/api/dto/nodes.d.ts +6 -7
  12. package/dist/api/dto/reviews.d.ts +1 -11
  13. package/dist/api/routes.d.ts +7 -4
  14. package/dist/api/routes.js +8 -5
  15. package/dist/build-root.js +3 -3
  16. package/dist/builtin-memory/04-base-worker.md +1 -4
  17. package/dist/builtin-memory/05-kinds/advisor/00-base.md +1 -5
  18. package/dist/builtin-memory/05-kinds/advisor/01-orchestrator.md +2 -7
  19. package/dist/builtin-memory/05-kinds/design/00-base.md +1 -6
  20. package/dist/builtin-memory/05-kinds/developer/00-base.md +1 -6
  21. package/dist/builtin-memory/05-kinds/explore/00-base.md +1 -4
  22. package/dist/builtin-memory/05-kinds/explore/01-orchestrator.md +1 -2
  23. package/dist/builtin-memory/05-kinds/general/00-base.md +1 -3
  24. package/dist/builtin-memory/05-kinds/plan/00-base.md +1 -6
  25. package/dist/builtin-memory/05-kinds/plan/reviewers/00-base.md +1 -2
  26. package/dist/builtin-memory/05-kinds/plan/reviewers/architecture-fit.md +1 -3
  27. package/dist/builtin-memory/05-kinds/plan/reviewers/code-smells.md +1 -3
  28. package/dist/builtin-memory/05-kinds/plan/reviewers/pattern-consistency.md +1 -3
  29. package/dist/builtin-memory/05-kinds/plan/reviewers/requirements-coverage.md +1 -3
  30. package/dist/builtin-memory/05-kinds/plan/reviewers/security.md +1 -4
  31. package/dist/builtin-memory/05-kinds/review/companion/00-base.md +2 -3
  32. package/dist/builtin-memory/05-kinds/spec/00-base.md +1 -2
  33. package/dist/builtin-memory/advisor/council.md +1 -6
  34. package/dist/builtin-memory/design.md +2 -7
  35. package/dist/builtin-memory/development.md +9 -14
  36. package/dist/builtin-memory/internal/marketplaces.md +2 -6
  37. package/dist/builtin-memory/internal/nodes-and-canvas.md +1 -1
  38. package/dist/builtin-memory/internal/plugins.md +2 -8
  39. package/dist/builtin-memory/internal/storage-tiers.md +1 -2
  40. package/dist/builtin-memory/testing.md +41 -0
  41. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/__tests__/{provider-rotation.test.ts → serial/provider-rotation.test.ts} +106 -177
  42. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/claude-plugin-commands.ts +5 -15
  43. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/frontmatter-rules/index.ts +1 -28
  44. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/memory-slash-commands.ts +43 -88
  45. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.js +55 -0
  46. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.ts +60 -0
  47. package/dist/cli.js +2 -2
  48. package/dist/clients/attach/__tests__/attach-remote-readonly.test.js +37 -131
  49. package/dist/clients/attach/__tests__/chat-view-snapshot-ordering.test.js +71 -152
  50. package/dist/clients/attach/__tests__/context-message.test.js +16 -174
  51. package/dist/clients/attach/__tests__/crtr-output.test.js +36 -2069
  52. package/dist/clients/attach/__tests__/diagram.test.js +2 -2
  53. package/dist/clients/attach/__tests__/edit-diff.test.js +0 -4
  54. package/dist/clients/attach/__tests__/file-review-focus.test.js +2 -1
  55. package/dist/clients/attach/__tests__/group-activity.test.js +40 -229
  56. package/dist/clients/attach/__tests__/oauth-dialog-lifecycle.test.js +26 -76
  57. package/dist/clients/attach/__tests__/prompt-preview.test.js +4 -70
  58. package/dist/clients/attach/__tests__/ref-autocomplete.test.js +11 -125
  59. package/dist/clients/attach/__tests__/titled-editor-preview.test.js +14 -205
  60. package/dist/clients/attach/command.d.ts +2 -1
  61. package/dist/clients/attach/command.js +81 -76
  62. package/dist/clients/attach/input/capabilities.d.ts +27 -0
  63. package/dist/clients/attach/input/capabilities.js +96 -0
  64. package/dist/clients/attach/input/controller.d.ts +20 -182
  65. package/dist/clients/attach/input/controller.js +128 -537
  66. package/dist/clients/attach/input/overlay-owner.d.ts +41 -0
  67. package/dist/clients/attach/input/overlay-owner.js +199 -0
  68. package/dist/clients/attach/overlays/file-review.d.ts +0 -4
  69. package/dist/clients/attach/overlays/file-review.js +13 -5
  70. package/dist/clients/attach/overlays/graph.js +2 -10
  71. package/dist/clients/attach/render/chat-view.d.ts +4 -3
  72. package/dist/clients/attach/render/chat-view.js +39 -33
  73. package/dist/clients/attach/render/group-activity.d.ts +1 -0
  74. package/dist/clients/attach/render/group-activity.js +20 -13
  75. package/dist/clients/attach/render/group-recap.js +12 -3
  76. package/dist/clients/attach/session/connection.js +9 -15
  77. package/dist/clients/attach/session/editor-inventory.d.ts +6 -5
  78. package/dist/clients/attach/session/editor-inventory.js +7 -8
  79. package/dist/clients/attach/session/file-links.d.ts +13 -0
  80. package/dist/clients/attach/session/file-links.js +107 -0
  81. package/dist/clients/attach/session/frame.d.ts +3 -0
  82. package/dist/clients/attach/session/frame.js +10 -1
  83. package/dist/clients/attach/session/frames.js +2 -3
  84. package/dist/clients/attach/session/input-wiring.d.ts +4 -1
  85. package/dist/clients/attach/session/input-wiring.js +15 -14
  86. package/dist/clients/attach/session/mouse.d.ts +6 -1
  87. package/dist/clients/attach/session/mouse.js +8 -5
  88. package/dist/clients/attach/session/profile-files.js +18 -12
  89. package/dist/clients/attach/session/reconnect.js +1 -1
  90. package/dist/clients/attach/session/state-sync.js +1 -2
  91. package/dist/clients/attach/session/surface-host.d.ts +3 -2
  92. package/dist/clients/attach/session/surface-host.js +4 -4
  93. package/dist/clients/attach/slash/dispatch.d.ts +8 -31
  94. package/dist/clients/attach/slash/dispatch.js +34 -81
  95. package/dist/clients/attach/viewer.js +820 -860
  96. package/dist/clients/conversation/projection.d.ts +79 -0
  97. package/dist/clients/conversation/projection.js +341 -0
  98. package/dist/clients/inbox/__tests__/serial/inbox-controller.test.js +159 -0
  99. package/dist/clients/inbox/__tests__/serial/mount-panel.test.js +151 -0
  100. package/dist/clients/inbox/controller.d.ts +0 -4
  101. package/dist/clients/inbox/controller.js +0 -2
  102. package/dist/clients/inbox/review/__tests__/review-core.test.js +4 -293
  103. package/dist/clients/inbox/review/__tests__/teardown-notice.test.js +100 -0
  104. package/dist/clients/inbox/review/comments-client.d.ts +3 -2
  105. package/dist/clients/inbox/review/comments-client.js +12 -12
  106. package/dist/clients/inbox/review/companion-pane.d.ts +30 -0
  107. package/dist/clients/inbox/review/companion-pane.js +86 -0
  108. package/dist/clients/inbox/review/document-surface.d.ts +182 -0
  109. package/dist/clients/inbox/review/{document-region.js → document-surface.js} +252 -48
  110. package/dist/clients/inbox/review/frame.js +5 -4
  111. package/dist/clients/inbox/review/launch.d.ts +8 -8
  112. package/dist/clients/inbox/review/launch.js +52 -92
  113. package/dist/clients/inbox/review/nvim.d.ts +2 -0
  114. package/dist/clients/inbox/review/nvim.js +14 -12
  115. package/dist/clients/inbox/review/review-client.d.ts +12 -8
  116. package/dist/clients/inbox/review/review-client.js +46 -35
  117. package/dist/clients/inbox/review-adapter.d.ts +3 -10
  118. package/dist/clients/inbox/review-adapter.js +27 -19
  119. package/dist/clients/inbox/surface.d.ts +0 -4
  120. package/dist/clients/inbox/surface.js +0 -2
  121. package/dist/clients/surfaces/host.d.ts +11 -3
  122. package/dist/commands/__tests__/api-client-cold-start-diagnostic.test.js +7 -34
  123. package/dist/commands/__tests__/human.test.js +11 -322
  124. package/dist/commands/api-client.d.ts +5 -5
  125. package/dist/commands/api-client.js +6 -85
  126. package/dist/commands/canvas-browse.js +3 -29
  127. package/dist/commands/canvas-config.js +1 -1
  128. package/dist/commands/canvas-use.js +3 -3
  129. package/dist/commands/canvas.js +1 -1
  130. package/dist/commands/cron.js +5 -1
  131. package/dist/commands/human/queue.d.ts +0 -4
  132. package/dist/commands/human/queue.js +7 -40
  133. package/dist/commands/memory/list.d.ts +14 -0
  134. package/dist/commands/memory/list.js +35 -31
  135. package/dist/commands/memory/read.d.ts +7 -0
  136. package/dist/commands/memory/read.js +14 -8
  137. package/dist/commands/node/bash.d.ts +1 -0
  138. package/dist/commands/node/bash.js +198 -0
  139. package/dist/commands/node/create.d.ts +23 -0
  140. package/dist/commands/node/create.js +207 -0
  141. package/dist/commands/node/inspect.d.ts +2 -0
  142. package/dist/commands/node/inspect.js +302 -0
  143. package/dist/commands/node/lifecycle.d.ts +4 -0
  144. package/dist/commands/node/lifecycle.js +415 -0
  145. package/dist/commands/node/message.d.ts +1 -0
  146. package/dist/commands/node/message.js +164 -0
  147. package/dist/commands/node/pyramid.d.ts +2 -0
  148. package/dist/commands/node/pyramid.js +79 -0
  149. package/dist/commands/node/subscription.d.ts +1 -0
  150. package/dist/commands/node/subscription.js +82 -0
  151. package/dist/commands/node/wait.d.ts +1 -0
  152. package/dist/commands/node/wait.js +159 -0
  153. package/dist/commands/node-lifecycle-revive.js +10 -57
  154. package/dist/commands/node.d.ts +0 -42
  155. package/dist/commands/node.js +11 -2065
  156. package/dist/commands/search.js +1 -1
  157. package/dist/commands/surface/node/cycle.d.ts +1 -0
  158. package/dist/commands/surface/node/cycle.js +83 -0
  159. package/dist/commands/surface/node/focus.d.ts +1 -0
  160. package/dist/commands/surface/node/focus.js +67 -0
  161. package/dist/commands/surface/node/id.d.ts +1 -0
  162. package/dist/commands/surface/node/id.js +38 -0
  163. package/dist/commands/surface/node/pin.d.ts +1 -0
  164. package/dist/commands/surface/node/pin.js +42 -0
  165. package/dist/commands/surface/node/placement.d.ts +46 -0
  166. package/dist/commands/surface/node/placement.js +124 -0
  167. package/dist/commands/surface-node.js +4 -1
  168. package/dist/commands/surface-reload.js +1 -2
  169. package/dist/commands/surface-tmux-spread.js +1 -1
  170. package/dist/commands/surface.js +5 -20
  171. package/dist/commands/sys/__tests__/setup-core.test.js +18 -271
  172. package/dist/commands/sys/config.js +6 -6
  173. package/dist/commands/sys/logs.js +1 -1
  174. package/dist/commands/sys/panels/broker-limits-panel.d.ts +17 -0
  175. package/dist/commands/sys/panels/broker-limits-panel.js +104 -0
  176. package/dist/commands/sys/panels/dependencies-panel.d.ts +14 -0
  177. package/dist/commands/sys/panels/dependencies-panel.js +80 -0
  178. package/dist/commands/sys/panels/keybindings-panel.d.ts +56 -0
  179. package/dist/commands/sys/panels/keybindings-panel.js +703 -0
  180. package/dist/commands/sys/panels/keys-panel.d.ts +16 -0
  181. package/dist/commands/sys/panels/keys-panel.js +60 -0
  182. package/dist/commands/sys/panels/models-panel.d.ts +77 -0
  183. package/dist/commands/sys/panels/models-panel.js +647 -0
  184. package/dist/commands/sys/panels/panel.d.ts +45 -0
  185. package/dist/commands/sys/panels/panel.js +137 -0
  186. package/dist/commands/sys/panels/plugins-panel.d.ts +16 -0
  187. package/dist/commands/sys/panels/plugins-panel.js +80 -0
  188. package/dist/commands/sys/panels/prefs-panel.d.ts +21 -0
  189. package/dist/commands/sys/panels/prefs-panel.js +85 -0
  190. package/dist/commands/sys/panels/provider-panel.d.ts +62 -0
  191. package/dist/commands/sys/panels/provider-panel.js +538 -0
  192. package/dist/commands/sys/settings-shell.d.ts +55 -0
  193. package/dist/commands/sys/settings-shell.js +400 -0
  194. package/dist/commands/sys/settings.d.ts +2 -0
  195. package/dist/commands/sys/settings.js +31 -0
  196. package/dist/commands/sys/setup-core.d.ts +3 -33
  197. package/dist/commands/sys/setup-core.js +27 -78
  198. package/dist/commands/sys/setup-settings-runner.d.ts +24 -0
  199. package/dist/commands/sys/setup-settings-runner.js +63 -0
  200. package/dist/commands/sys/setup-wizard.d.ts +26 -125
  201. package/dist/commands/sys/setup-wizard.js +209 -2473
  202. package/dist/commands/sys/setup.js +5 -7
  203. package/dist/commands/sys.js +3 -2
  204. package/dist/core/__tests__/broker-extension-canvas-db-boundary.test.js +50 -0
  205. package/dist/core/__tests__/broker-launch-candidates.test.js +20 -9
  206. package/dist/core/__tests__/broker-preflight.test.js +1 -1
  207. package/dist/core/__tests__/canvas-inbox-watcher-hold.test.js +108 -27
  208. package/dist/core/__tests__/canvas-inbox-watcher.test.js +14 -0
  209. package/dist/core/__tests__/canvas.test.js +2 -36
  210. package/dist/core/__tests__/close.test.js +14 -3
  211. package/dist/core/__tests__/context-intro.test.js +32 -143
  212. package/dist/core/__tests__/cron-broker-capacity.test.js +22 -3
  213. package/dist/core/__tests__/daemon-boot.test.js +2 -20
  214. package/dist/core/__tests__/daemon-wedge.test.js +1 -1
  215. package/dist/core/__tests__/dead-node-policy-table.test.js +1 -18
  216. package/dist/core/__tests__/fixtures/fake-engine.d.ts +1 -1
  217. package/dist/core/__tests__/fixtures/fake-engine.js +2 -2
  218. package/dist/core/__tests__/fixtures/fake-pi-host.js +2 -2
  219. package/dist/core/__tests__/focuses.test.js +4 -98
  220. package/dist/core/__tests__/helpers/broker-clients.d.ts +0 -3
  221. package/dist/core/__tests__/helpers/broker-clients.js +0 -14
  222. package/dist/core/__tests__/helpers/harness.d.ts +0 -8
  223. package/dist/core/__tests__/helpers/harness.js +7 -87
  224. package/dist/core/__tests__/helpers/viewer-panes.js +1 -1
  225. package/dist/core/__tests__/inline-memory-refs.test.js +5 -134
  226. package/dist/core/__tests__/kickoff.test.js +1 -1
  227. package/dist/core/__tests__/memory-resolver-precedence.test.js +29 -1
  228. package/dist/core/__tests__/migration.test.js +35 -48
  229. package/dist/core/__tests__/on-read-dedup-resume.test.js +22 -12
  230. package/dist/core/__tests__/passive-subscription.test.js +26 -49
  231. package/dist/core/__tests__/preview-registry-sync.test.js +1 -2
  232. package/dist/core/__tests__/prune.test.js +94 -1
  233. package/dist/core/__tests__/review-model-floor.test.js +0 -32
  234. package/dist/core/__tests__/seam/broker-attach-multiclient.test.js +255 -0
  235. package/dist/core/__tests__/{full → seam}/broker-attach-stream.test.js +39 -7
  236. package/dist/core/__tests__/{full → seam}/broker-crash-teardown.test.js +30 -29
  237. package/dist/core/__tests__/{full → seam}/broker-pane-resolution.test.js +54 -5
  238. package/dist/core/__tests__/{full → seam}/broker-provider-retry.test.js +134 -82
  239. package/dist/core/__tests__/{full → seam}/broker-whip-interrupt.test.js +15 -4
  240. package/dist/core/__tests__/{full/idle-release-settlement.test.js → seam/dormancy-release.test.js} +69 -17
  241. package/dist/core/__tests__/{full/yield-message-transaction.test.js → seam/yield-refresh-transaction.test.js} +31 -9
  242. package/dist/core/__tests__/secrets.test.js +1 -7
  243. package/dist/core/__tests__/{broker-fork-seam.test.js → serial/broker-fork-seam.test.js} +58 -7
  244. package/dist/core/__tests__/{broker-sdk-wiring.test.js → serial/broker-sdk-wiring.test.js} +18 -162
  245. package/dist/core/__tests__/{broker-snapshot-history.test.js → serial/broker-snapshot-history.test.js} +9 -9
  246. package/dist/core/__tests__/{command-plugins.test.js → serial/command-plugins.test.js} +105 -15
  247. package/dist/core/__tests__/{deferred-no-wake.test.js → serial/deferred-no-wake.test.js} +23 -20
  248. package/dist/core/__tests__/{flagship-lifecycle.test.js → serial/flagship-lifecycle.test.js} +7 -7
  249. package/dist/core/__tests__/{host-teardown-process-group.test.js → serial/host-teardown-process-group.test.js} +6 -6
  250. package/dist/core/__tests__/{human-deliver-e2e.test.js → serial/human-deliver-e2e.test.js} +12 -12
  251. package/dist/core/__tests__/{live-mutation.test.js → serial/live-mutation.test.js} +5 -5
  252. package/dist/core/__tests__/{refresh-stall-recycle.test.js → serial/refresh-stall-recycle.test.js} +5 -14
  253. package/dist/core/__tests__/{revive.test.js → serial/revive.test.js} +15 -100
  254. package/dist/core/__tests__/{spawn-root.test.js → serial/spawn-root.test.js} +32 -15
  255. package/dist/core/__tests__/serial/subscription-delivery.test.js +126 -0
  256. package/dist/core/__tests__/serial/tmux-surface.test.js +256 -0
  257. package/dist/core/__tests__/{worktree.test.js → serial/worktree.test.js} +15 -15
  258. package/dist/core/__tests__/session-model.test.js +0 -18
  259. package/dist/core/__tests__/spawn-worktree-id-conflict.test.js +9 -0
  260. package/dist/core/__tests__/watchdog-abort-arms-retry.test.js +50 -0
  261. package/dist/core/broker-client/__tests__/transport-relay.test.js +15 -16
  262. package/dist/core/broker-client/__tests__/transport-socket.test.js +28 -0
  263. package/dist/core/broker-client/client.d.ts +2 -2
  264. package/dist/core/broker-client/client.js +4 -7
  265. package/dist/core/broker-client/transport-relay.d.ts +13 -19
  266. package/dist/core/broker-client/transport-relay.js +19 -34
  267. package/dist/core/broker-client/transport-socket.d.ts +2 -2
  268. package/dist/core/broker-client/transport-socket.js +9 -2
  269. package/dist/core/broker-client/transport.d.ts +7 -3
  270. package/dist/core/broker-client/transport.js +4 -4
  271. package/dist/core/canvas/__tests__/attention.test.js +1 -18
  272. package/dist/core/canvas/__tests__/remote-canvas-source.test.js +7 -64
  273. package/dist/core/canvas/__tests__/remote-transport.test.js +2 -3
  274. package/dist/core/canvas/__tests__/render-remote.test.js +7 -52
  275. package/dist/core/canvas/browse/app.d.ts +2 -17
  276. package/dist/core/canvas/browse/app.js +16 -88
  277. package/dist/core/canvas/browse/model.d.ts +0 -4
  278. package/dist/core/canvas/browse/model.js +1 -12
  279. package/dist/core/canvas/browse/render.js +6 -3
  280. package/dist/core/canvas/crons.d.ts +8 -5
  281. package/dist/core/canvas/crons.js +7 -6
  282. package/dist/core/canvas/extensions.d.ts +7 -3
  283. package/dist/core/canvas/extensions.js +16 -4
  284. package/dist/core/canvas/nav-model.d.ts +0 -4
  285. package/dist/core/canvas/nav-model.js +2 -14
  286. package/dist/core/canvas/node-order.d.ts +3 -0
  287. package/dist/core/canvas/node-order.js +12 -0
  288. package/dist/core/canvas/remote-canvas-source.d.ts +3 -6
  289. package/dist/core/canvas/remote-canvas-source.js +8 -15
  290. package/dist/core/command.js +11 -4
  291. package/dist/core/config.js +3 -1
  292. package/dist/core/events/envelope.js +1 -1
  293. package/dist/core/events/read.js +7 -21
  294. package/dist/core/events/source.d.ts +0 -2
  295. package/dist/core/events/source.js +0 -16
  296. package/dist/core/events/types.d.ts +1 -1
  297. package/dist/core/fault-classifier.d.ts +1 -1
  298. package/dist/core/feed/passive.d.ts +0 -11
  299. package/dist/core/feed/passive.js +1 -62
  300. package/dist/core/human/__tests__/{inbox-core.test.js → serial/inbox-core.test.js} +6 -6
  301. package/dist/core/keybindings/__tests__/resolve.test.js +1 -96
  302. package/dist/core/keybindings/background-bash.js +3 -4
  303. package/dist/core/keybindings/catalog.js +1 -1
  304. package/dist/core/memory/inline-ref-grammar.js +3 -3
  305. package/dist/core/memory-resolver.d.ts +11 -25
  306. package/dist/core/memory-resolver.js +51 -33
  307. package/dist/core/model-routes.d.ts +15 -0
  308. package/dist/core/model-routes.js +12 -0
  309. package/dist/core/pool-credential-store.js +1 -1
  310. package/dist/core/preview-registry.js +8 -9
  311. package/dist/core/profiles/__tests__/root-profile.test.js +4 -14
  312. package/dist/core/review/realize.d.ts +0 -13
  313. package/dist/core/review/realize.js +0 -40
  314. package/dist/core/review/types.d.ts +1 -1
  315. package/dist/core/runtime/__tests__/engine-route.test.js +2 -2
  316. package/dist/core/runtime/bearings.js +1 -11
  317. package/dist/core/runtime/broker/client-registry.d.ts +33 -0
  318. package/dist/core/runtime/broker/client-registry.js +164 -0
  319. package/dist/core/runtime/broker/daemon-ops.d.ts +19 -0
  320. package/dist/core/runtime/broker/daemon-ops.js +49 -0
  321. package/dist/core/runtime/broker/event-projection.d.ts +42 -0
  322. package/dist/core/runtime/broker/event-projection.js +178 -0
  323. package/dist/core/runtime/broker/fault-retry.d.ts +39 -0
  324. package/dist/core/runtime/broker/fault-retry.js +277 -0
  325. package/dist/core/runtime/broker/frame-dispatch.d.ts +238 -0
  326. package/dist/core/runtime/broker/frame-dispatch.js +1537 -0
  327. package/dist/core/runtime/broker/inbox.d.ts +22 -0
  328. package/dist/core/runtime/broker/inbox.js +167 -0
  329. package/dist/core/runtime/broker/passive.d.ts +16 -0
  330. package/dist/core/runtime/broker/passive.js +44 -0
  331. package/dist/core/runtime/broker/read-ops.d.ts +23 -0
  332. package/dist/core/runtime/broker/read-ops.js +150 -0
  333. package/dist/core/runtime/broker/rebind.d.ts +74 -0
  334. package/dist/core/runtime/broker/rebind.js +211 -0
  335. package/dist/core/runtime/broker/tool-groups.d.ts +39 -0
  336. package/dist/core/runtime/broker/tool-groups.js +244 -0
  337. package/dist/core/runtime/broker-extension-render.d.ts +11 -0
  338. package/dist/core/runtime/broker-extension-render.js +181 -0
  339. package/dist/core/runtime/broker-persona-guidance.d.ts +13 -0
  340. package/dist/core/runtime/broker-persona-guidance.js +58 -0
  341. package/dist/core/runtime/broker-protocol.d.ts +1 -1
  342. package/dist/core/runtime/broker-protocol.js +1 -1
  343. package/dist/core/runtime/broker.d.ts +5 -196
  344. package/dist/core/runtime/broker.js +276 -3059
  345. package/dist/core/runtime/canvas-extensions.js +11 -2
  346. package/dist/core/runtime/fault.js +1 -1
  347. package/dist/core/runtime/model-selection.d.ts +9 -0
  348. package/dist/core/runtime/model-selection.js +12 -0
  349. package/dist/core/runtime/model-swap.d.ts +3 -3
  350. package/dist/core/runtime/model-swap.js +33 -25
  351. package/dist/core/runtime/placement-tmux.d.ts +3 -14
  352. package/dist/core/runtime/placement-tmux.js +11 -80
  353. package/dist/core/runtime/placement.d.ts +4 -2
  354. package/dist/core/runtime/placement.js +7 -12
  355. package/dist/core/runtime/promote.d.ts +14 -1
  356. package/dist/core/runtime/promote.js +1 -1
  357. package/dist/core/runtime/reset.d.ts +1 -1
  358. package/dist/core/runtime/roadmap.js +1 -1
  359. package/dist/core/runtime/spawn.d.ts +8 -0
  360. package/dist/core/runtime/spawn.js +36 -6
  361. package/dist/core/runtime/stop-guard.d.ts +4 -3
  362. package/dist/core/runtime/stop-guard.js +36 -18
  363. package/dist/core/runtime/stop-signals.d.ts +4 -1
  364. package/dist/core/runtime/stream-watchdog.js +4 -5
  365. package/dist/core/runtime/structured-output.d.ts +15 -2
  366. package/dist/core/runtime/structured-output.js +35 -12
  367. package/dist/core/runtime/tmux-bindings.d.ts +25 -0
  368. package/dist/core/runtime/tmux-bindings.js +682 -0
  369. package/dist/core/runtime/tmux-chrome.d.ts +2 -1
  370. package/dist/core/runtime/tmux-chrome.js +3 -2
  371. package/dist/core/runtime/{tmux.d.ts → tmux-driver.d.ts} +18 -26
  372. package/dist/core/runtime/tmux-driver.js +598 -0
  373. package/dist/core/runtime/view-socket.d.ts +14 -0
  374. package/dist/core/runtime/view-socket.js +83 -0
  375. package/dist/core/session-model/session-state.d.ts +1 -2
  376. package/dist/core/session-model/session-state.js +5 -8
  377. package/dist/core/spawn.d.ts +1 -1
  378. package/dist/core/spawn.js +2 -2
  379. package/dist/core/substrate/gate.d.ts +1 -1
  380. package/dist/core/substrate/on-read-pure.d.ts +7 -0
  381. package/dist/core/substrate/on-read-pure.js +272 -0
  382. package/dist/core/termrender/termrender.js +32 -2
  383. package/dist/core/user-settings.d.ts +23 -1
  384. package/dist/core/user-settings.js +18 -1
  385. package/dist/daemon/api/__tests__/node-model-validation.test.js +134 -0
  386. package/dist/daemon/api/__tests__/review-terminal-conflict.test.js +98 -0
  387. package/dist/daemon/api/__tests__/{full → seam}/api-server.test.js +6 -48
  388. package/dist/daemon/api/__tests__/{full → seam}/b10-attach-modelauth.test.js +17 -44
  389. package/dist/daemon/api/__tests__/{full/push-parity.test.js → seam/leaf-api-parity.test.js} +61 -42
  390. package/dist/daemon/api/bridge.js +40 -81
  391. package/dist/daemon/api/handlers/broker-ops.d.ts +2 -0
  392. package/dist/daemon/api/handlers/broker-ops.js +383 -0
  393. package/dist/daemon/api/handlers/crons.js +9 -4
  394. package/dist/daemon/api/handlers/files.js +6 -7
  395. package/dist/daemon/api/handlers/inbox.js +2 -340
  396. package/dist/daemon/api/handlers/nodes.d.ts +10 -1
  397. package/dist/daemon/api/handlers/nodes.js +74 -39
  398. package/dist/daemon/api/handlers/review-comments.js +5 -1
  399. package/dist/daemon/api/handlers/reviews.js +0 -19
  400. package/dist/daemon/api/map.js +25 -4
  401. package/dist/daemon/api/router.js +2 -3
  402. package/dist/daemon/api/server.js +5 -7
  403. package/dist/daemon/cron-run.d.ts +4 -0
  404. package/dist/daemon/cron-run.js +30 -13
  405. package/dist/daemon/crtrd.d.ts +3 -58
  406. package/dist/daemon/crtrd.js +28 -1244
  407. package/dist/daemon/manage.js +0 -1
  408. package/dist/daemon/reconcilers/broker-supervision.d.ts +50 -0
  409. package/dist/daemon/reconcilers/broker-supervision.js +549 -0
  410. package/dist/daemon/reconcilers/cron-lane.d.ts +10 -0
  411. package/dist/daemon/reconcilers/cron-lane.js +32 -0
  412. package/dist/daemon/reconcilers/dormant-inbox.d.ts +18 -0
  413. package/dist/daemon/reconcilers/dormant-inbox.js +143 -0
  414. package/dist/daemon/reconcilers/storage-maintenance.d.ts +22 -0
  415. package/dist/daemon/reconcilers/storage-maintenance.js +213 -0
  416. package/dist/daemon/review/finish.js +2 -5
  417. package/dist/pi-extensions/__tests__/canvas-context-intro.test.js +34 -53
  418. package/dist/pi-extensions/__tests__/canvas-recap.test.js +16 -113
  419. package/dist/pi-extensions/__tests__/canvas-stophook-agentend.test.js +72 -99
  420. package/dist/pi-extensions/__tests__/canvas-stophook-context-nudge.test.js +29 -12
  421. package/dist/pi-extensions/broker-local.d.ts +20 -0
  422. package/dist/pi-extensions/broker-local.js +89 -0
  423. package/dist/pi-extensions/canvas-context-intro.d.ts +3 -3
  424. package/dist/pi-extensions/canvas-context-intro.js +22 -11
  425. package/dist/pi-extensions/canvas-doc-substrate.js +17 -34
  426. package/dist/pi-extensions/canvas-goal-capture.js +7 -12
  427. package/dist/pi-extensions/canvas-inbox-watcher.js +124 -139
  428. package/dist/pi-extensions/canvas-passive-context.d.ts +3 -3
  429. package/dist/pi-extensions/canvas-passive-context.js +22 -18
  430. package/dist/pi-extensions/canvas-recap.d.ts +2 -2
  431. package/dist/pi-extensions/canvas-recap.js +48 -21
  432. package/dist/pi-extensions/canvas-review-boundary.js +10 -4
  433. package/dist/pi-extensions/canvas-stophook.d.ts +0 -5
  434. package/dist/pi-extensions/canvas-stophook.js +149 -431
  435. package/dist/pi-extensions/canvas-structured-output.js +52 -30
  436. package/dist/pi-extensions/envelope-merge.d.ts +13 -0
  437. package/dist/pi-extensions/envelope-merge.js +29 -0
  438. package/dist/shared/working-activity.d.ts +3 -2
  439. package/dist/shared/working-activity.js +3 -2
  440. package/dist/types.d.ts +6 -5
  441. package/dist/types.js +2 -2
  442. package/docs/compat/hearth-crtr-v1.md +4 -12
  443. package/docs/compat/hearth-crtr-v2.md +3 -11
  444. package/docs/compat/hearth-crtr-v3.md +4 -12
  445. package/docs/compat/hearth-crtr-v4.md +3 -11
  446. package/docs/compat/hearth-crtr-v5.md +3 -11
  447. package/docs/public-api.md +3 -7
  448. package/package.json +7 -49
  449. package/runtime.lock.json +2766 -14533
  450. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/__tests__/claude-plugin-commands.test.ts +0 -49
  451. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/__tests__/memory-slash-commands.test.ts +0 -194
  452. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/__tests__/statusline.test.ts +0 -68
  453. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/frontmatter-rules/test.ts +0 -119
  454. package/dist/clients/attach/__tests__/attach-chrome-remote.test.js +0 -439
  455. package/dist/clients/attach/__tests__/attach-keybindings.test.js +0 -170
  456. package/dist/clients/attach/__tests__/crtr-output-coverage.test.js +0 -57
  457. package/dist/clients/attach/__tests__/editor-frame-title.test.js +0 -19
  458. package/dist/clients/attach/__tests__/input-controller-extension-command.test.js +0 -32
  459. package/dist/clients/attach/__tests__/markdown-headings.test.js +0 -35
  460. package/dist/clients/attach/__tests__/session-identity-refresh.test.js +0 -32
  461. package/dist/clients/conversation/conversation.d.ts +0 -65
  462. package/dist/clients/conversation/conversation.js +0 -318
  463. package/dist/clients/conversation/frames.d.ts +0 -30
  464. package/dist/clients/conversation/frames.js +0 -52
  465. package/dist/clients/conversation/region.d.ts +0 -51
  466. package/dist/clients/conversation/region.js +0 -265
  467. package/dist/clients/inbox/__tests__/inbox-controller.test.js +0 -247
  468. package/dist/clients/inbox/__tests__/mount-panel.test.js +0 -776
  469. package/dist/clients/inbox/review/__tests__/remap.test.js +0 -196
  470. package/dist/clients/inbox/review/columns.d.ts +0 -22
  471. package/dist/clients/inbox/review/columns.js +0 -40
  472. package/dist/clients/inbox/review/composition.d.ts +0 -60
  473. package/dist/clients/inbox/review/composition.js +0 -278
  474. package/dist/clients/inbox/review/document-region.d.ts +0 -120
  475. package/dist/clients/surfaces/region.d.ts +0 -16
  476. package/dist/clients/web/__tests__/push-engine.test.js +0 -158
  477. package/dist/clients/web/__tests__/push-registry.test.d.ts +0 -1
  478. package/dist/clients/web/__tests__/push-registry.test.js +0 -177
  479. package/dist/clients/web/dev-server.d.ts +0 -7
  480. package/dist/clients/web/dev-server.js +0 -46
  481. package/dist/clients/web/events.d.ts +0 -19
  482. package/dist/clients/web/events.js +0 -163
  483. package/dist/clients/web/push-engine.d.ts +0 -44
  484. package/dist/clients/web/push-engine.js +0 -125
  485. package/dist/clients/web/push-registry.d.ts +0 -85
  486. package/dist/clients/web/push-registry.js +0 -373
  487. package/dist/clients/web/server.d.ts +0 -19
  488. package/dist/clients/web/server.js +0 -661
  489. package/dist/clients/web/web-client/shared/protocol.d.ts +0 -214
  490. package/dist/clients/web/web-client/shared/protocol.js +0 -8
  491. package/dist/clients/web/web-cmd.d.ts +0 -2
  492. package/dist/clients/web/web-cmd.js +0 -141
  493. package/dist/commands/__tests__/api-canvas-source.test.d.ts +0 -1
  494. package/dist/commands/__tests__/api-canvas-source.test.js +0 -37
  495. package/dist/commands/__tests__/canvas-config.test.d.ts +0 -1
  496. package/dist/commands/__tests__/canvas-config.test.js +0 -107
  497. package/dist/commands/__tests__/node-no-kickoff-flag.test.d.ts +0 -1
  498. package/dist/commands/__tests__/node-no-kickoff-flag.test.js +0 -73
  499. package/dist/commands/__tests__/node-worktree-flag.test.d.ts +0 -1
  500. package/dist/commands/__tests__/node-worktree-flag.test.js +0 -49
  501. package/dist/commands/__tests__/search-contents.test.d.ts +0 -1
  502. package/dist/commands/__tests__/search-contents.test.js +0 -52
  503. package/dist/commands/memory/__tests__/lint.test.d.ts +0 -1
  504. package/dist/commands/memory/__tests__/lint.test.js +0 -15
  505. package/dist/commands/sys/__tests__/config-broker-thresholds.test.d.ts +0 -1
  506. package/dist/commands/sys/__tests__/config-broker-thresholds.test.js +0 -95
  507. package/dist/commands/sys/__tests__/config-keybindings.test.d.ts +0 -1
  508. package/dist/commands/sys/__tests__/config-keybindings.test.js +0 -55
  509. package/dist/commands/sys/__tests__/helpers/setup-runtime.d.ts +0 -5
  510. package/dist/commands/sys/__tests__/helpers/setup-runtime.js +0 -19
  511. package/dist/commands/sys/__tests__/setup-front-door.test.d.ts +0 -1
  512. package/dist/commands/sys/__tests__/setup-front-door.test.js +0 -102
  513. package/dist/commands/sys/__tests__/setup-models.test.d.ts +0 -1
  514. package/dist/commands/sys/__tests__/setup-models.test.js +0 -205
  515. package/dist/commands/sys/__tests__/setup-providers-viewport.test.d.ts +0 -1
  516. package/dist/commands/sys/__tests__/setup-providers-viewport.test.js +0 -155
  517. package/dist/commands/sys/__tests__/sync-deps.test.d.ts +0 -1
  518. package/dist/commands/sys/__tests__/sync-deps.test.js +0 -179
  519. package/dist/commands/sys/__tests__/sync-import.test.d.ts +0 -1
  520. package/dist/commands/sys/__tests__/sync-import.test.js +0 -315
  521. package/dist/core/__tests__/base-worker-prompt.test.d.ts +0 -1
  522. package/dist/core/__tests__/base-worker-prompt.test.js +0 -57
  523. package/dist/core/__tests__/command-plugins-surfaces.test.d.ts +0 -1
  524. package/dist/core/__tests__/command-plugins-surfaces.test.js +0 -359
  525. package/dist/core/__tests__/connection-reconnect-resume.test.d.ts +0 -1
  526. package/dist/core/__tests__/connection-reconnect-resume.test.js +0 -36
  527. package/dist/core/__tests__/finalization-migration.test.d.ts +0 -1
  528. package/dist/core/__tests__/finalization-migration.test.js +0 -38
  529. package/dist/core/__tests__/fixtures/extra-extension.d.ts +0 -1
  530. package/dist/core/__tests__/fixtures/extra-extension.js +0 -3
  531. package/dist/core/__tests__/fixtures/spawn-proof-target.test.d.ts +0 -1
  532. package/dist/core/__tests__/fixtures/spawn-proof-target.test.js +0 -15
  533. package/dist/core/__tests__/fork.test.d.ts +0 -1
  534. package/dist/core/__tests__/fork.test.js +0 -108
  535. package/dist/core/__tests__/full/broker-attach-limits.test.d.ts +0 -1
  536. package/dist/core/__tests__/full/broker-attach-limits.test.js +0 -147
  537. package/dist/core/__tests__/full/broker-deliver-ack.test.d.ts +0 -1
  538. package/dist/core/__tests__/full/broker-deliver-ack.test.js +0 -73
  539. package/dist/core/__tests__/full/broker-dialogs.test.d.ts +0 -1
  540. package/dist/core/__tests__/full/broker-dialogs.test.js +0 -180
  541. package/dist/core/__tests__/full/broker-display-snapshot.test.d.ts +0 -1
  542. package/dist/core/__tests__/full/broker-display-snapshot.test.js +0 -75
  543. package/dist/core/__tests__/full/broker-dormant-wake.test.d.ts +0 -1
  544. package/dist/core/__tests__/full/broker-dormant-wake.test.js +0 -130
  545. package/dist/core/__tests__/full/broker-model-changed-broadcast.test.d.ts +0 -1
  546. package/dist/core/__tests__/full/broker-model-changed-broadcast.test.js +0 -57
  547. package/dist/core/__tests__/full/broker-navigate-tree-rewelcome.test.d.ts +0 -1
  548. package/dist/core/__tests__/full/broker-navigate-tree-rewelcome.test.js +0 -80
  549. package/dist/core/__tests__/full/cascade-close.test.d.ts +0 -1
  550. package/dist/core/__tests__/full/cascade-close.test.js +0 -240
  551. package/dist/core/__tests__/full/detach-focus.test.d.ts +0 -1
  552. package/dist/core/__tests__/full/detach-focus.test.js +0 -126
  553. package/dist/core/__tests__/full/idle-release-settlement.test.d.ts +0 -1
  554. package/dist/core/__tests__/full/issue-146-yield-spawn-focus.test.d.ts +0 -1
  555. package/dist/core/__tests__/full/issue-146-yield-spawn-focus.test.js +0 -107
  556. package/dist/core/__tests__/full/park-clock-release.test.d.ts +0 -1
  557. package/dist/core/__tests__/full/park-clock-release.test.js +0 -56
  558. package/dist/core/__tests__/full/yield-message-transaction.test.d.ts +0 -1
  559. package/dist/core/__tests__/memory-index-render.test.d.ts +0 -1
  560. package/dist/core/__tests__/memory-index-render.test.js +0 -60
  561. package/dist/core/__tests__/model-routes.test.d.ts +0 -1
  562. package/dist/core/__tests__/model-routes.test.js +0 -41
  563. package/dist/core/__tests__/on-read-identity.test.d.ts +0 -1
  564. package/dist/core/__tests__/on-read-identity.test.js +0 -61
  565. package/dist/core/__tests__/phase4-review-migration.test.d.ts +0 -1
  566. package/dist/core/__tests__/phase4-review-migration.test.js +0 -100
  567. package/dist/core/__tests__/prune-to-limit.test.d.ts +0 -1
  568. package/dist/core/__tests__/prune-to-limit.test.js +0 -126
  569. package/dist/core/__tests__/reset.test.d.ts +0 -1
  570. package/dist/core/__tests__/reset.test.js +0 -69
  571. package/dist/core/__tests__/spawn-no-kickoff.test.d.ts +0 -1
  572. package/dist/core/__tests__/spawn-no-kickoff.test.js +0 -115
  573. package/dist/core/__tests__/steer-note.test.d.ts +0 -1
  574. package/dist/core/__tests__/steer-note.test.js +0 -41
  575. package/dist/core/__tests__/subcommand-tier.test.d.ts +0 -1
  576. package/dist/core/__tests__/subcommand-tier.test.js +0 -99
  577. package/dist/core/__tests__/subscription-delivery.test.js +0 -211
  578. package/dist/core/__tests__/test-runner-cheap-sharding.test.d.ts +0 -1
  579. package/dist/core/__tests__/test-runner-cheap-sharding.test.js +0 -97
  580. package/dist/core/__tests__/tmux-surface.test.js +0 -484
  581. package/dist/core/__tests__/wake-bearings.test.d.ts +0 -1
  582. package/dist/core/__tests__/wake-bearings.test.js +0 -102
  583. package/dist/core/canvas/__tests__/remote-event-stream.test.d.ts +0 -1
  584. package/dist/core/canvas/__tests__/remote-event-stream.test.js +0 -146
  585. package/dist/core/canvas/__tests__/source-resolve.test.d.ts +0 -1
  586. package/dist/core/canvas/__tests__/source-resolve.test.js +0 -77
  587. package/dist/core/canvas/browse/__tests__/model.test.d.ts +0 -1
  588. package/dist/core/canvas/browse/__tests__/model.test.js +0 -290
  589. package/dist/core/canvas/browse/__tests__/rebuild-coalescer.test.d.ts +0 -1
  590. package/dist/core/canvas/browse/__tests__/rebuild-coalescer.test.js +0 -134
  591. package/dist/core/canvas/browse/__tests__/render.test.d.ts +0 -1
  592. package/dist/core/canvas/browse/__tests__/render.test.js +0 -111
  593. package/dist/core/canvas/browse/rebuild-coalescer.d.ts +0 -7
  594. package/dist/core/canvas/browse/rebuild-coalescer.js +0 -61
  595. package/dist/core/canvas/remote-event-stream.d.ts +0 -24
  596. package/dist/core/canvas/remote-event-stream.js +0 -94
  597. package/dist/core/feed/__tests__/coalesce-human.test.d.ts +0 -1
  598. package/dist/core/feed/__tests__/coalesce-human.test.js +0 -36
  599. package/dist/core/feed/__tests__/empty-node-guard.test.d.ts +0 -1
  600. package/dist/core/feed/__tests__/empty-node-guard.test.js +0 -45
  601. package/dist/core/host-exports/__tests__/export-prunes-boot-skill.test.d.ts +0 -1
  602. package/dist/core/host-exports/__tests__/export-prunes-boot-skill.test.js +0 -84
  603. package/dist/core/human/__tests__/visible-paths.test.d.ts +0 -1
  604. package/dist/core/human/__tests__/visible-paths.test.js +0 -28
  605. package/dist/core/keybindings/__tests__/inbox-affordance.test.d.ts +0 -1
  606. package/dist/core/keybindings/__tests__/inbox-affordance.test.js +0 -38
  607. package/dist/core/review/__tests__/project.test.d.ts +0 -1
  608. package/dist/core/review/__tests__/project.test.js +0 -71
  609. package/dist/core/runtime/__tests__/command-expansion.test.d.ts +0 -1
  610. package/dist/core/runtime/__tests__/command-expansion.test.js +0 -25
  611. package/dist/core/runtime/__tests__/session-visibility.test.d.ts +0 -1
  612. package/dist/core/runtime/__tests__/session-visibility.test.js +0 -119
  613. package/dist/core/runtime/__tests__/spawn-at-given-id.test.d.ts +0 -1
  614. package/dist/core/runtime/__tests__/spawn-at-given-id.test.js +0 -34
  615. package/dist/core/runtime/tmux.js +0 -1314
  616. package/dist/daemon/api/__tests__/full/push-parity.test.d.ts +0 -1
  617. package/dist/daemon/api/__tests__/full/worktree-parity.test.d.ts +0 -1
  618. package/dist/daemon/api/__tests__/full/worktree-parity.test.js +0 -160
  619. package/dist/daemon/api/__tests__/inbox.test.d.ts +0 -1
  620. package/dist/daemon/api/__tests__/inbox.test.js +0 -489
  621. package/dist/web-client/apple-touch-icon.png +0 -0
  622. package/dist/web-client/assets/fragment-mono-latin-400-normal-BYwT3kSJ.woff +0 -0
  623. package/dist/web-client/assets/fragment-mono-latin-400-normal-yxdJ5AmL.woff2 +0 -0
  624. package/dist/web-client/assets/fragment-mono-latin-ext-400-normal-BbKYyvR9.woff2 +0 -0
  625. package/dist/web-client/assets/fragment-mono-latin-ext-400-normal-CT4YFKeK.woff +0 -0
  626. package/dist/web-client/assets/index-CCPaLeW7.css +0 -2
  627. package/dist/web-client/assets/index-kyOWsnZK.js +0 -86
  628. package/dist/web-client/assets/martian-mono-cyrillic-wght-normal-B84CD5C_.woff2 +0 -0
  629. package/dist/web-client/assets/martian-mono-latin-ext-wght-normal-DlL6xMw5.woff2 +0 -0
  630. package/dist/web-client/assets/martian-mono-latin-wght-normal-5W32yIyr.woff2 +0 -0
  631. package/dist/web-client/assets/workbox-window.prod.es5-Bd17z0YL.js +0 -2
  632. package/dist/web-client/icon-192.png +0 -0
  633. package/dist/web-client/icon-512.png +0 -0
  634. package/dist/web-client/icon-maskable-512.png +0 -0
  635. package/dist/web-client/index.html +0 -17
  636. package/dist/web-client/manifest.webmanifest +0 -1
  637. package/dist/web-client/sw.js +0 -1
  638. /package/dist/api/__tests__/{client.test.d.ts → serial/client.test.d.ts} +0 -0
  639. /package/dist/clients/inbox/__tests__/{inbox-controller.test.d.ts → serial/inbox-controller.test.d.ts} +0 -0
  640. /package/dist/clients/inbox/__tests__/{mount-panel.test.d.ts → serial/mount-panel.test.d.ts} +0 -0
  641. /package/dist/clients/{attach/__tests__/attach-chrome-remote.test.d.ts → inbox/review/__tests__/teardown-notice.test.d.ts} +0 -0
  642. /package/dist/{clients/attach/__tests__/attach-keybindings.test.d.ts → core/__tests__/broker-extension-canvas-db-boundary.test.d.ts} +0 -0
  643. /package/dist/{clients/attach/__tests__/crtr-output-coverage.test.d.ts → core/__tests__/seam/broker-attach-multiclient.test.d.ts} +0 -0
  644. /package/dist/core/__tests__/{full → seam}/broker-attach-stream.test.d.ts +0 -0
  645. /package/dist/core/__tests__/{full → seam}/broker-crash-teardown.test.d.ts +0 -0
  646. /package/dist/core/__tests__/{full → seam}/broker-pane-resolution.test.d.ts +0 -0
  647. /package/dist/core/__tests__/{full → seam}/broker-provider-retry.test.d.ts +0 -0
  648. /package/dist/core/__tests__/{full → seam}/broker-whip-interrupt.test.d.ts +0 -0
  649. /package/dist/{clients/attach/__tests__/editor-frame-title.test.d.ts → core/__tests__/seam/dormancy-release.test.d.ts} +0 -0
  650. /package/dist/{clients/attach/__tests__/input-controller-extension-command.test.d.ts → core/__tests__/seam/yield-refresh-transaction.test.d.ts} +0 -0
  651. /package/dist/core/__tests__/{broker-fork-seam.test.d.ts → serial/broker-fork-seam.test.d.ts} +0 -0
  652. /package/dist/core/__tests__/{broker-sdk-wiring.test.d.ts → serial/broker-sdk-wiring.test.d.ts} +0 -0
  653. /package/dist/core/__tests__/{broker-snapshot-history.test.d.ts → serial/broker-snapshot-history.test.d.ts} +0 -0
  654. /package/dist/core/__tests__/{command-plugins.test.d.ts → serial/command-plugins.test.d.ts} +0 -0
  655. /package/dist/core/__tests__/{deferred-no-wake.test.d.ts → serial/deferred-no-wake.test.d.ts} +0 -0
  656. /package/dist/core/__tests__/{flagship-lifecycle.test.d.ts → serial/flagship-lifecycle.test.d.ts} +0 -0
  657. /package/dist/core/__tests__/{host-teardown-process-group.test.d.ts → serial/host-teardown-process-group.test.d.ts} +0 -0
  658. /package/dist/core/__tests__/{human-deliver-e2e.test.d.ts → serial/human-deliver-e2e.test.d.ts} +0 -0
  659. /package/dist/core/__tests__/{live-mutation.test.d.ts → serial/live-mutation.test.d.ts} +0 -0
  660. /package/dist/core/__tests__/{refresh-stall-recycle.test.d.ts → serial/refresh-stall-recycle.test.d.ts} +0 -0
  661. /package/dist/core/__tests__/{revive.test.d.ts → serial/revive.test.d.ts} +0 -0
  662. /package/dist/core/__tests__/{spawn-root.test.d.ts → serial/spawn-root.test.d.ts} +0 -0
  663. /package/dist/core/__tests__/{subscription-delivery.test.d.ts → serial/subscription-delivery.test.d.ts} +0 -0
  664. /package/dist/core/__tests__/{tmux-surface.test.d.ts → serial/tmux-surface.test.d.ts} +0 -0
  665. /package/dist/core/__tests__/{worktree.test.d.ts → serial/worktree.test.d.ts} +0 -0
  666. /package/dist/{clients/attach/__tests__/markdown-headings.test.d.ts → core/__tests__/watchdog-abort-arms-retry.test.d.ts} +0 -0
  667. /package/dist/{clients/attach/__tests__/session-identity-refresh.test.d.ts → core/broker-client/__tests__/transport-socket.test.d.ts} +0 -0
  668. /package/dist/core/human/__tests__/{inbox-core.test.d.ts → serial/inbox-core.test.d.ts} +0 -0
  669. /package/dist/{clients/inbox/review/__tests__/remap.test.d.ts → daemon/api/__tests__/node-model-validation.test.d.ts} +0 -0
  670. /package/dist/{clients/surfaces/region.js → daemon/api/__tests__/review-terminal-conflict.test.d.ts} +0 -0
  671. /package/dist/daemon/api/__tests__/{full → seam}/api-server.test.d.ts +0 -0
  672. /package/dist/daemon/api/__tests__/{full → seam}/b10-attach-modelauth.test.d.ts +0 -0
  673. /package/dist/{clients/web/__tests__/push-engine.test.d.ts → daemon/api/__tests__/seam/leaf-api-parity.test.d.ts} +0 -0
@@ -1,33 +1,46 @@
1
1
  // Tests for the <crtr-bearings> preamble:
2
- // 1. Worker and orchestrator bearings carry the `<memory kind="knowledge">`
3
- // block (substrate knowledge docs + node-local docs as a file tree).
4
- // Orchestrators add the across-cycles framing; promotion delivers that
5
- // same orchestrator context-dir framing to a node that spawned base.
2
+ // 1. Situational context rides the bearings as a sibling block, and only
3
+ // once something has been set.
6
4
  // 2. canvas-context-intro injects the block as its own session message at
7
- // session_start (before the first prompt), idempotent across resumes.
5
+ // session_start (before the first prompt), idempotent across resumes,
6
+ // inert without a node id — and its renderer never overruns the terminal.
8
7
  //
9
8
  // Run: node --import tsx/esm --test src/core/__tests__/context-intro.test.ts
10
- import { test, before, beforeEach, after } from 'node:test';
9
+ import { test, before, beforeEach, after, afterEach } from 'node:test';
11
10
  import assert from 'node:assert/strict';
12
- import { mkdtempSync, mkdirSync, rmSync, writeFileSync } from 'node:fs';
11
+ import { existsSync, mkdtempSync, mkdirSync, rmSync } from 'node:fs';
13
12
  import { tmpdir } from 'node:os';
14
13
  import { join } from 'node:path';
15
14
  import { closeDb } from '../canvas/db.js';
16
- import { contextDir } from '../canvas/paths.js';
15
+ import { apiSocketPath } from '../canvas/paths.js';
17
16
  import { spawnNode } from '../runtime/nodes.js';
18
- import { promote } from '../runtime/promote.js';
19
- import { personaDrift } from '../runtime/persona.js';
20
- import { memoryDir } from '../runtime/memory.js';
21
17
  import { appendSituationalContext, situationalContextBlock } from '../runtime/situational-context.js';
22
- import registerCanvasContextIntro, { buildContextIntro, renderContextMessage, CONTEXT_INTRO_CUSTOM_TYPE, } from '../../pi-extensions/canvas-context-intro.js';
18
+ import registerCanvasContextIntro, { renderContextMessage, CONTEXT_INTRO_CUSTOM_TYPE, } from '../../pi-extensions/canvas-context-intro.js';
19
+ import { buildContextBearings as buildContextIntro } from '../runtime/bearings.js';
20
+ import { createApiServer } from '../../daemon/api/server.js';
23
21
  let home;
22
+ let server;
23
+ async function waitForSocket(path) {
24
+ for (let i = 0; i < 200; i++) {
25
+ if (existsSync(path))
26
+ return;
27
+ await new Promise((resolve) => setTimeout(resolve, 10));
28
+ }
29
+ throw new Error(`api socket never bound at ${path}`);
30
+ }
24
31
  before(() => {
25
32
  home = mkdtempSync(join(tmpdir(), 'crtr-ctxintro-'));
26
33
  process.env['CRTR_HOME'] = home;
27
34
  });
28
- beforeEach(() => {
35
+ beforeEach(async () => {
29
36
  closeDb();
30
37
  rmSync(home, { recursive: true, force: true });
38
+ mkdirSync(home, { recursive: true });
39
+ server = createApiServer();
40
+ await waitForSocket(apiSocketPath());
41
+ });
42
+ afterEach(async () => {
43
+ await server.close();
31
44
  });
32
45
  after(() => {
33
46
  closeDb();
@@ -35,42 +48,6 @@ after(() => {
35
48
  delete process.env['CRTR_HOME'];
36
49
  delete process.env['CRTR_NODE_ID'];
37
50
  });
38
- test('worker bearings: base framing + <knowledge> block, NO across-cycles framing', () => {
39
- // Bug-regression: review finding M1 — buildContextBearings renders the
40
- // <knowledge> block (renderKnowledgeBlock): a kind-wrapped file tree of
41
- // knowledge docs. This test locks in that contract.
42
- const meta = spawnNode({ kind: 'general', cwd: '/tmp/work', parent: null });
43
- // Seed a node-local substrate doc so the knowledge block is non-empty.
44
- const dir = memoryDir(meta.node_id);
45
- mkdirSync(dir, { recursive: true });
46
- writeFileSync(join(dir, 'test-ref.md'), '---\nkind: knowledge\nwhen-and-why-to-read: When testing, this reference should be read because it is a regression fixture\nsystem-prompt-visibility: preview\n---\nTest body.\n');
47
- const block = buildContextIntro(meta.node_id);
48
- assert.match(block, /<crtr-bearings>/, 'opens with the bearings section');
49
- assert.ok(block.includes(contextDir(meta.node_id)), 'names the context-dir path inline (no dir= attribute)');
50
- assert.doesNotMatch(block, /<crtr-context/, 'no legacy <crtr-context dir=…> wrapper');
51
- assert.match(block, /## Your context directory/, 'context dir is its own markdown subsection');
52
- assert.match(block, /shared document store, not a task tracker/, 'base = shared docs, not tasks');
53
- // The catalog is a sibling <memory kind="knowledge"> block, never nested
54
- // under anything dir-scoped.
55
- assert.match(block, /<memory kind="knowledge">/, 'knowledge catalog present as a memory block');
56
- // Per-store stanza headers (label · dir) never appear.
57
- assert.doesNotMatch(block, /user-global · /, 'no user-global label·dir stanza');
58
- assert.doesNotMatch(block, /node-local · /, 'no node-local label·dir stanza');
59
- // No (empty) placeholder marker.
60
- assert.doesNotMatch(block, /\(empty\)/, 'no (empty) placeholder');
61
- assert.match(block, /\nknowledge\n/, 'tree headed by the `knowledge` root label');
62
- // The node-local preview-rung doc renders as a tree entry with a `# read when:`
63
- // routing line (verbatim previewLine output).
64
- assert.match(block, /test-ref {2}# read when: When testing, this reference should be read because it is a regression fixture\./, 'node-local preview doc renders its routing line');
65
- assert.match(block, /<project_context>/, 'project_context now rides the bearings even without project files');
66
- assert.match(block, /<environment cwd="\/tmp\/work">/, 'environment block is always present');
67
- assert.match(block, /Host: .+ \u00b7 tmux server: (reachable|none)/, 'environment block reports a host/runtime line with tmux server reachability');
68
- assert.match(block, /Directory listing: unavailable \(cwd missing or unreadable\)\./, 'missing cwd degrades the directory listing');
69
- assert.match(block, /Git: not a git repository\./, 'missing cwd degrades git info');
70
- // A terminal worker must NOT carry the orchestrator across-cycles framing.
71
- assert.doesNotMatch(block, /refresh cycles/, 'no across-cycles framing for a terminal worker');
72
- assert.match(block, /<\/crtr-bearings>/);
73
- });
74
51
  test('situational context rides the bearings as a sibling <situational-context> block; empty when unset', () => {
75
52
  const meta = spawnNode({ kind: 'general', cwd: '/tmp/work', parent: null });
76
53
  assert.equal(situationalContextBlock(meta.node_id), '', 'no block until something is set');
@@ -81,94 +58,6 @@ test('situational context rides the bearings as a sibling <situational-context>
81
58
  assert.match(block, /user is looking at the billing applet/, 'block carries the ambient text');
82
59
  assert.ok(!/<situational-context>[\s\S]*<\/crtr-bearings>/.test(block), 'the block is a sibling of <crtr-bearings>, not nested inside it');
83
60
  });
84
- test('node-local doc identity honors explicit frontmatter `name`, not the physical filename', () => {
85
- // node-local docs follow the one substrate identity rule (resolveDocName):
86
- // an explicit `name:` renders and dedups under that name, not the filename.
87
- const meta = spawnNode({ kind: 'general', cwd: '/tmp/work', parent: null });
88
- const dir = memoryDir(meta.node_id);
89
- mkdirSync(dir, { recursive: true });
90
- writeFileSync(join(dir, 'physical-filename.md'), '---\nkind: knowledge\nname: explicit-identity\nwhen-and-why-to-read: When testing, this reference should be read because it is a regression fixture\nsystem-prompt-visibility: preview\n---\nTest body.\n');
91
- const block = buildContextIntro(meta.node_id);
92
- assert.match(block, /\u2500 explicit-identity {2}# read when:/, 'tree entry renders under the explicit frontmatter name');
93
- assert.ok(!block.includes('physical-filename'), 'the physical filename never surfaces once an explicit name is set');
94
- });
95
- test('a CLAUDE.md in the node\'s cwd does not enter the bearings; only the <environment> snapshot remains', () => {
96
- // buildProjectContextBlock now emits only the cwd/git environment snapshot.
97
- // Project guidance lives in the document substrate instead, so a bare on-disk
98
- // CLAUDE.md stays out of the bearings entirely.
99
- const proj = mkdtempSync(join(tmpdir(), 'crtr-proj-'));
100
- writeFileSync(join(proj, 'CLAUDE.md'), 'PROJECT_MARKER: build then commit.\n');
101
- const meta = spawnNode({ kind: 'general', cwd: proj, parent: null });
102
- const block = buildContextIntro(meta.node_id);
103
- assert.doesNotMatch(block, /<project_instructions/, 'no <project_instructions> block is ever emitted');
104
- assert.doesNotMatch(block, /PROJECT_MARKER: build then commit\./, 'the CLAUDE.md body never rides the bearings');
105
- assert.match(block, /<project_context>/, 'project_context wrapper still present');
106
- assert.match(block, /<environment cwd=".*crtr-proj-.*">/, 'environment block still rides inside project_context');
107
- assert.match(block, /Directory:\n CLAUDE\.md\n/, 'environment block still includes an ls-style listing');
108
- assert.match(block, /Git: not a git repository\./, 'git snapshot degrades cleanly for a non-repo');
109
- assert.match(block, /<environment[\s\S]*<\/environment>\n<\/project_context>$/, 'environment block closes project_context');
110
- assert.ok(block.indexOf('</crtr-bearings>') < block.indexOf('<project_context>'), 'project_context follows the crtr-bearings block');
111
- rmSync(proj, { recursive: true, force: true });
112
- });
113
- test('orchestrator bearings: across-cycles framing + node-local substrate docs ride into <knowledge>; a non-substrate .md file is never inlined', () => {
114
- // Bug-regression: review finding M1 — buildContextBearings renders <knowledge>.
115
- // Node-local substrate docs render as tree entries at their rung; a
116
- // non-substrate .md file (no frontmatter `kind`) never surfaces.
117
- const meta = spawnNode({ kind: 'general', cwd: '/tmp/work', parent: null });
118
- promote(meta.node_id); // flip to orchestrator mode — the across-cycles gate
119
- const dir = memoryDir(meta.node_id);
120
- mkdirSync(dir, { recursive: true });
121
- // Write a non-substrate MEMORY.md file to verify it is never surfaced in the block.
122
- const legacyIndexPath = join(dir, 'MEMORY.md');
123
- writeFileSync(legacyIndexPath, '# memory index — one pointer line per memory; how-to in "Your long-term memory".\n\n- [Flaky build](flaky-build.md) — first run fails\n');
124
- // A node-local substrate doc DOES ride into the knowledge block at its rung.
125
- writeFileSync(join(dir, 'flaky-build.md'), '---\nkind: knowledge\nwhen-and-why-to-read: When the build flakes, this reference should be read because the first run fails\nsystem-prompt-visibility: preview\n---\nFirst run always fails; rerun once.\n');
126
- const block = buildContextIntro(meta.node_id);
127
- assert.match(block, /shared document store, not a task tracker/, 'still carries the base framing');
128
- assert.match(block, /refresh cycles/, 'orchestrator gets the across-cycles framing');
129
- assert.match(block, /<memory kind="knowledge">/, 'knowledge catalog present as a memory block');
130
- assert.match(block, /flaky-build {2}# read when: When the build flakes, this reference should be read because the first run fails\./, 'node-local doc renders as a tree entry with its routing line');
131
- // The non-substrate file never renders: no header line, no pointer line, no path.
132
- assert.ok(!block.includes('# memory index'), 'the index header comment is NOT inlined');
133
- assert.ok(!block.includes('- [Flaky build](flaky-build.md)'), 'index pointer lines are NOT inlined');
134
- assert.ok(!block.includes(legacyIndexPath), 'no absolute index (MEMORY.md) path');
135
- assert.ok(!block.includes('node-local · '), 'no label·dir stanza header');
136
- assert.match(block, /<\/crtr-bearings>/);
137
- });
138
- test('orchestrator bearings: no per-store stanzas or (empty) markers; a rung-none node-local doc still surfaces as a bare-name tree entry', () => {
139
- // Bug-regression: review findings M1 + M6 — the <knowledge> block carries no
140
- // per-store `label · dir` stanzas or (empty) markers, and node-local docs are
141
- // NOT filtered on rung: a migrated node-local doc defaults
142
- // system-prompt-visibility: none and must still ride into the knowledge memory block as
143
- // its bare name (floored to the `name` rung; never its body).
144
- const meta = spawnNode({ kind: 'general', cwd: '/tmp/work', parent: null });
145
- promote(meta.node_id); // flip to orchestrator mode
146
- const dir = memoryDir(meta.node_id);
147
- mkdirSync(dir, { recursive: true });
148
- writeFileSync(join(dir, 'rung-none-fact.md'), '---\nkind: knowledge\n---\nbody that must not render at the none rung\n');
149
- const block = buildContextIntro(meta.node_id);
150
- // No per-store stanza headers, no (empty) markers, no MEMORY.md paths.
151
- assert.ok(!block.includes(`node-local · ${memoryDir(meta.node_id)}`), 'no node-local stanza header');
152
- assert.ok(!block.includes('user-global · '), 'no user-global stanza header');
153
- assert.ok(!block.includes('project · '), 'no project stanza header');
154
- assert.doesNotMatch(block, /\(empty\)/, 'no (empty) markers');
155
- assert.ok(!block.includes('MEMORY.md'), 'no MEMORY.md path in the block');
156
- // M6: rung-none node-local doc surfaces as a bare-name tree entry only.
157
- assert.match(block, /─ rung-none-fact\n/, 'rung-none node-local doc surfaces as a bare-name tree entry');
158
- assert.ok(!block.includes('body that must not render'), 'none rung renders the name only, not the body');
159
- });
160
- test('promotion guidance delivers the orchestrator context-dir framing', () => {
161
- // A node spawns as a base worker (no orchestrator bearings). On promotion the
162
- // persona injector must build the across-cycles context-dir framing it never
163
- // got at spawn (delivered at the next turn boundary, not returned by promote).
164
- const meta = spawnNode({ kind: 'general', cwd: '/tmp/work', parent: null });
165
- promote(meta.node_id);
166
- const drift = personaDrift(meta.node_id);
167
- const guidance = drift?.guidance ?? '';
168
- assert.ok(drift !== null, 'promotion drifts the persona (base→orchestrator)');
169
- assert.match(guidance, /refresh cycles/, 'promotion guidance carries the across-cycles framing');
170
- assert.ok(guidance.includes(contextDir(meta.node_id)), 'and names the context dir path');
171
- });
172
61
  function makeFakePi() {
173
62
  return {
174
63
  sent: [],
@@ -182,7 +71,7 @@ function makeFakePi() {
182
71
  function fakeCtx(entries = []) {
183
72
  return { sessionManager: { getEntries: () => entries } };
184
73
  }
185
- test('session_start injects the block as the first message of an empty session', () => {
74
+ test('session_start injects the block as the first message of an empty session', async () => {
186
75
  const meta = spawnNode({ kind: 'general', cwd: '/tmp/work', parent: null });
187
76
  process.env['CRTR_NODE_ID'] = meta.node_id;
188
77
  const pi = makeFakePi();
@@ -190,13 +79,13 @@ test('session_start injects the block as the first message of an empty session',
190
79
  assert.ok(pi.handler, 'session_start handler registered');
191
80
  // Empty session → inject the block as its own custom message (no delivery
192
81
  // options → it precedes the first prompt).
193
- pi.handler({ reason: 'startup' }, fakeCtx());
82
+ await pi.handler({ reason: 'startup' }, fakeCtx());
194
83
  assert.equal(pi.sent.length, 1, 'one message injected');
195
84
  assert.equal(pi.sent[0].customType, CONTEXT_INTRO_CUSTOM_TYPE);
196
85
  assert.equal(pi.sent[0].display, true);
197
86
  assert.match(pi.sent[0].content, /<crtr-bearings>/);
198
87
  });
199
- test('session_start is idempotent across resume (skips if already in history)', () => {
88
+ test('session_start is idempotent across resume (skips if already in history)', async () => {
200
89
  const meta = spawnNode({ kind: 'general', cwd: '/tmp/work', parent: null });
201
90
  process.env['CRTR_NODE_ID'] = meta.node_id;
202
91
  // Restored session already carries OUR block (which names this node id) → no
@@ -209,14 +98,14 @@ test('session_start is idempotent across resume (skips if already in history)',
209
98
  const entries = [
210
99
  { type: 'custom_message', customType: CONTEXT_INTRO_CUSTOM_TYPE, content: buildContextIntro(meta.node_id) },
211
100
  ];
212
- pi.handler({ reason: 'resume' }, fakeCtx(entries));
101
+ await pi.handler({ reason: 'resume' }, fakeCtx(entries));
213
102
  assert.equal(pi.sent.length, 0, 'our own block already in history → skip');
214
103
  });
215
- test('session_start is inert when CRTR_NODE_ID is absent', () => {
104
+ test('session_start is inert when CRTR_NODE_ID is absent', async () => {
216
105
  delete process.env['CRTR_NODE_ID'];
217
106
  const pi = makeFakePi();
218
107
  registerCanvasContextIntro(pi);
219
- pi.handler({ reason: 'startup' }, fakeCtx());
108
+ await pi.handler({ reason: 'startup' }, fakeCtx());
220
109
  assert.equal(pi.sent.length, 0);
221
110
  });
222
111
  test('renderer registered for the customType; collapsed hides body, ctrl+o expand reveals it', () => {
@@ -9,12 +9,13 @@
9
9
  // no broker capacity and is never gated.
10
10
  import { after, afterEach, before, test } from 'node:test';
11
11
  import assert from 'node:assert/strict';
12
- import { mkdtempSync, rmSync } from 'node:fs';
12
+ import { existsSync, mkdtempSync, readFileSync, rmSync } from 'node:fs';
13
13
  import { tmpdir } from 'node:os';
14
14
  import { join } from 'node:path';
15
+ import { setTimeout as delay } from 'node:timers/promises';
15
16
  import { closeDb } from '../canvas/db.js';
16
- import { armCron, getCron, listCronRuns } from '../canvas/crons.js';
17
- import { cronLaunchesNode, runDueCrons } from '../../daemon/cron-run.js';
17
+ import { armCron, cancelCron, getCron, listCronRuns } from '../canvas/crons.js';
18
+ import { cronLaunchesNode, executeCron, markSelfCanceledCronRun, runDueCrons } from '../../daemon/cron-run.js';
18
19
  let home;
19
20
  let realHome;
20
21
  function arm(overrides) {
@@ -87,6 +88,24 @@ test('a plain shell cron runs at zero capacity — only launches are gated', asy
87
88
  await Promise.all(settlements);
88
89
  assert.equal(getCron('plain-shell'), null, 'the one-shot settled and was consumed');
89
90
  });
91
+ test('an on-change cron that cancels itself still delivers its final output', async () => {
92
+ const runIdPath = join(home, 'self-cancel-run-id');
93
+ arm({
94
+ cron_id: 'self-cancel-delivery',
95
+ command: `printf '%s' "$CRTR_RUN_ID" > '${runIdPath}'; echo settled; sleep 0.1`,
96
+ recur: JSON.stringify({ every: '1h' }),
97
+ on_output: 'on-change',
98
+ sink: JSON.stringify({ human: true }),
99
+ });
100
+ const run = executeCron(getCron('self-cancel-delivery'), { outOfBand: false });
101
+ for (let i = 0; i < 50 && !existsSync(runIdPath); i++)
102
+ await delay(10);
103
+ assert.ok(existsSync(runIdPath), 'the live run exposed its id to its self-cancel command');
104
+ assert.equal(markSelfCanceledCronRun('self-cancel-delivery', readFileSync(runIdPath, 'utf8')), true);
105
+ assert.equal(cancelCron('self-cancel-delivery', { preserveRunningProcess: true }), true);
106
+ const record = await run;
107
+ assert.equal(record?.delivered, 'delivered: human notify');
108
+ });
90
109
  test('cronLaunchesNode classifies by command verb and armed sink', () => {
91
110
  const of = (command, sink = '{}') => cronLaunchesNode({ command, sink });
92
111
  assert.equal(of("crtr node lifecycle revive 'n' --fresh"), true);
@@ -8,11 +8,11 @@ import { createServer } from 'node:net';
8
8
  import { createNode, getNode, subscribe } from '../canvas/canvas.js';
9
9
  import { closeDb } from '../canvas/db.js';
10
10
  import { readInboxSince } from '../feed/inbox.js';
11
- import { superviseTick, readPidfile } from '../../daemon/crtrd.js';
11
+ import { superviseTick } from '../../daemon/crtrd.js';
12
+ import { readPidfile } from '../../daemon/pidfile.js';
12
13
  import { verifyDaemonStartup, waitForDaemonExit } from '../../daemon/manage.js';
13
14
  import { waitForBrokerViewSocket } from '../runtime/placement-tmux.js';
14
15
  import { viewSocketPath } from '../canvas/paths.js';
15
- import { signBrandedHostArtifacts, brandedHostWorks, codesignIdentitiesForBrandedHost } from '../runtime/branded-host.js';
16
16
  import { markBusy, clearBusy } from '../runtime/busy.js';
17
17
  import { bindTestFleet } from './helpers/fleet.js';
18
18
  import { resetFleetForTests } from '../runtime/fleet.js';
@@ -354,21 +354,3 @@ test('waitForBrokerViewSocket returns false as soon as the real broker process e
354
354
  assert.equal(ready, false, 'an exited broker must fail readiness');
355
355
  assert.ok(Date.now() - started < 1000, 'the readiness guard must fail fast instead of waiting for the socket deadline');
356
356
  });
357
- test('signBrandedHostArtifacts signs the copied libnode before the branded binary', () => {
358
- const signed = [];
359
- signBrandedHostArtifacts('/tmp/crouter', '/tmp/libnode.dylib', (path) => signed.push(path));
360
- assert.deepEqual(signed, ['/tmp/libnode.dylib', '/tmp/crouter']);
361
- });
362
- test('codesignIdentitiesForBrandedHost prefers configured or discovered identities and otherwise ad-hoc signs', () => {
363
- assert.deepEqual(codesignIdentitiesForBrandedHost({ configured: 'Developer ID Application: Example', discovered: 'Apple Development: Local' }), ['Developer ID Application: Example']);
364
- assert.deepEqual(codesignIdentitiesForBrandedHost({ discovered: 'Apple Development: Local' }), ['Apple Development: Local']);
365
- assert.deepEqual(codesignIdentitiesForBrandedHost(), ['-']);
366
- });
367
- test('brandedHostWorks health-checks if a binary is executable', () => {
368
- // Issue #102: the branded host binary can be corrupted or killed by macOS
369
- // before exec, causing spawn() to fail silently. The health-check detects this.
370
- const goodBin = process.execPath; // a real, executable binary
371
- const badBin = '/nonexistent/crouter-broken';
372
- assert.equal(brandedHostWorks(goodBin), true, 'health-check passes for a real executable binary');
373
- assert.equal(brandedHostWorks(badBin), false, 'health-check fails for a nonexistent binary');
374
- });
@@ -12,7 +12,7 @@
12
12
  // fires on its own (fails toward 'pending', not 'wedged').
13
13
  import { test } from 'node:test';
14
14
  import assert from 'node:assert/strict';
15
- import { wedgeVerdict, WEDGE_QUIET_MS, WEDGE_CPU_MAX_PERCENT, sumTreeCpu, treeHasDescendants } from '../../daemon/crtrd.js';
15
+ import { wedgeVerdict, WEDGE_QUIET_MS, WEDGE_CPU_MAX_PERCENT, sumTreeCpu, treeHasDescendants, } from '../../daemon/reconcilers/broker-supervision.js';
16
16
  test('wedgeVerdict: a node whose turn already ended is never wedged, regardless of the other signals', () => {
17
17
  assert.equal(wedgeVerdict({ busy: false, quietForMs: null, cpuPercent: null }), 'leave');
18
18
  assert.equal(wedgeVerdict({ busy: false, quietForMs: 10 * 60 * 60_000, cpuPercent: 0 }), 'leave');
@@ -11,7 +11,7 @@
11
11
  // unchanged — only its caller moved into the table).
12
12
  import { test } from 'node:test';
13
13
  import assert from 'node:assert/strict';
14
- import { classifyDeadNode, retryResumeMode, respawnBackoffMs, HEALTHY_UPTIME_MS, MAX_RESPAWN_ATTEMPTS, } from '../../daemon/fleet.js';
14
+ import { classifyDeadNode, retryResumeMode } from '../../daemon/fleet.js';
15
15
  /** A table-row fixture: an active, booted-or-not node in the named state. */
16
16
  function row(over = {}) {
17
17
  return {
@@ -83,20 +83,3 @@ test('retryResumeMode: interrupted turns and pending cycles recover as cycles; i
83
83
  assert.equal(retryResumeMode({}, false), true, 'cycle_pending undefined idle crash resumes strictly');
84
84
  assert.equal(retryResumeMode(null, false), true, 'no meta and no busy marker resumes strictly');
85
85
  });
86
- // ===========================================================================
87
- // The throttle's backoff schedule (pure): attempt n waits min(5s·2^(n-1), 10min);
88
- // zero consecutive failures respawn immediately (the sub-second yield respawn
89
- // D-3 buys). The stateful throttle behavior lives in respawn-throttle.test.ts.
90
- // ===========================================================================
91
- test('respawnBackoffMs: immediate at zero failures, doubling from 5s, capped at 10 minutes', () => {
92
- assert.equal(respawnBackoffMs(0), 0);
93
- assert.equal(respawnBackoffMs(1), 5_000);
94
- assert.equal(respawnBackoffMs(2), 10_000);
95
- assert.equal(respawnBackoffMs(3), 20_000);
96
- assert.equal(respawnBackoffMs(5), 80_000);
97
- assert.equal(respawnBackoffMs(20), 600_000, 'the backoff is capped, never unbounded');
98
- });
99
- test('throttle constants: healthy uptime is 60s; the loop terminalizes at 6 consecutive short-lived exits', () => {
100
- assert.equal(HEALTHY_UPTIME_MS, 60_000);
101
- assert.equal(MAX_RESPAWN_ATTEMPTS, 6);
102
- });
@@ -121,7 +121,7 @@ declare class FakeSession {
121
121
  private disposed;
122
122
  private eventSeq;
123
123
  private timer;
124
- /** Full-tier graceful-teardown seam: a real active turn that only settles
124
+ /** Compiled-seam graceful-teardown vehicle: a real active turn that only settles
125
125
  * after abort(), so the broker's bounded abort wait is observable. */
126
126
  private heldTurn;
127
127
  private readonly listeners;
@@ -269,7 +269,7 @@ class FakeSession {
269
269
  disposed = false;
270
270
  eventSeq = 0;
271
271
  timer;
272
- /** Full-tier graceful-teardown seam: a real active turn that only settles
272
+ /** Compiled-seam graceful-teardown vehicle: a real active turn that only settles
273
273
  * after abort(), so the broker's bounded abort wait is observable. */
274
274
  heldTurn;
275
275
  // The broker's fan-out subscribers (broker.ts `session.subscribe(...)`) and the
@@ -306,7 +306,7 @@ class FakeSession {
306
306
  // Mirror the real pi SDK: a model-less construction (`model === undefined`)
307
307
  // does NOT leave `session.model` undefined — Agent.createMutableAgentState()
308
308
  // falls back to a hardcoded unknown-stub. Representing that here is what
309
- // makes the full/ tests exercise the broker's real sessionHasNoModel()/
309
+ // makes the compiled seam tests exercise the broker's real sessionHasNoModel()/
310
310
  // isUnknownModel() guard path (broker.ts) rather than the `=== undefined`
311
311
  // shortcut that never happens against the real engine.
312
312
  this.currentModel = model ?? UNKNOWN_MODEL_STUB;
@@ -7,8 +7,8 @@
7
7
  // and fires REAL lifecycle events under harness control, so the real hooks
8
8
  // drive real canvas state across the process boundary.
9
9
  //
10
- // The runtime exec's us exactly where it would exec `pi`, via the CRTR_PI_BINARY
11
- // seam in piCommand (src/core/runtime/tmux.ts). We therefore receive:
10
+ // The runtime execs us exactly where it would exec `pi`, via the CRTR_PI_BINARY
11
+ // seam in piCommand (src/core/runtime/tmux-driver.ts). We therefore receive:
12
12
  // • argv: -e <ext> … -n <label> [--session <path>] [--model …] [--tools …]
13
13
  // [--append-system-prompt <file>] [<kickoff prompt>] (buildPiArgv)
14
14
  // • env: CRTR_NODE_ID, CRTR_KIND, CRTR_MODE, CRTR_LIFECYCLE, CRTR_HOME,
@@ -3,12 +3,9 @@
3
3
  // The `focuses` table (canvas.db, migration v6) + its canvas setters + the
4
4
  // placement reads that compose over them. The table is the CANONICAL focus store
5
5
  // — there is no focus.ptr file and no dual-write bridge. Covers:
6
- // - migration v6 adds `focuses` to a fresh db (and a legacy v5 db migrates up);
7
- // idempotent / forward-only on re-run + re-open
6
+ // - migration v6 adds `focuses` to a fresh db
8
7
  // - canvas setters/reads round-trip: open / setOccupant / setPane / close;
9
8
  // getFocusByNode / getFocusByPane / getFocusById / listFocuses
10
- // - UNIQUE(node_id): a second focus row (and an occupant UPDATE) for one node
11
- // is rejected (upholds "a node occupies <=1 focus", Q5)
12
9
  // - independent focus rows don't contend
13
10
  // - placement focusOf / isFocused / focusByPane / focusedNodes / listFocuses
14
11
  // GC dead-pane viewer rows on read (liveOrPrune), and pass null-pane rows
@@ -18,10 +15,8 @@ import assert from 'node:assert/strict';
18
15
  import { mkdtempSync, rmSync } from 'node:fs';
19
16
  import { tmpdir } from 'node:os';
20
17
  import { join } from 'node:path';
21
- import { DatabaseSync } from 'node:sqlite';
22
18
  import { openFocusRow, setFocusOccupant, setFocusPane, closeFocusRow, getFocusByNode, getFocusByPane, getFocusById, listFocuses, } from '../canvas/focuses.js';
23
- import { openDb, closeDb, migrate, MIGRATIONS } from '../canvas/db.js';
24
- import { canvasDbPath, ensureHome } from '../canvas/paths.js';
19
+ import { openDb, closeDb, MIGRATIONS } from '../canvas/db.js';
25
20
  import { focusOf, isFocused, focusByPane, focusedNodes, listFocuses as placementListFocuses, } from '../runtime/placement.js';
26
21
  let home;
27
22
  function userVersion(db) {
@@ -51,76 +46,6 @@ test('a fresh db migrates to the latest version and has the focuses table', () =
51
46
  assert.equal(userVersion(db), MIGRATIONS.length);
52
47
  assert.ok(tableNames(db).includes('focuses'), 'focuses table exists on a fresh db');
53
48
  });
54
- test('the focuses table has the v6 shape (UNIQUE node_id, nullable pane/session)', () => {
55
- const db = openDb();
56
- const cols = db.prepare('PRAGMA table_info(focuses)').all();
57
- const byName = new Map(cols.map((c) => [c.name, c]));
58
- assert.equal(byName.get('focus_id')?.pk, 1, 'focus_id is the primary key');
59
- assert.equal(byName.get('node_id')?.notnull, 1, 'node_id is NOT NULL');
60
- assert.equal(byName.get('pane')?.notnull, 0, 'pane is nullable');
61
- assert.equal(byName.get('session')?.notnull, 0, 'session is nullable');
62
- // node_id carries a UNIQUE index.
63
- const idx = db.prepare('PRAGMA index_list(focuses)').all();
64
- assert.ok(idx.some((i) => i.unique === 1), 'a UNIQUE index exists (the node_id constraint)');
65
- });
66
- test('a v5 db migrates forward, adding focuses without disturbing existing data', () => {
67
- // Hand-build a db at exactly v5: baseline + the four v2 runtime columns + the
68
- // v5 pane column + edges WITH the v4 FK shape, user_version=5 — the shape just
69
- // before v6.
70
- ensureHome();
71
- const raw = new DatabaseSync(canvasDbPath());
72
- raw.exec(`
73
- CREATE TABLE nodes (
74
- node_id TEXT PRIMARY KEY, name TEXT NOT NULL, kind TEXT NOT NULL,
75
- mode TEXT NOT NULL DEFAULT 'base', lifecycle TEXT NOT NULL DEFAULT 'terminal',
76
- status TEXT NOT NULL DEFAULT 'active', cwd TEXT NOT NULL, parent TEXT,
77
- created TEXT NOT NULL,
78
- intent TEXT, pi_pid INTEGER, window TEXT, tmux_session TEXT, pane TEXT
79
- );
80
- CREATE TABLE edges (
81
- type TEXT NOT NULL, from_id TEXT NOT NULL, to_id TEXT NOT NULL,
82
- active INTEGER NOT NULL DEFAULT 1, created TEXT NOT NULL,
83
- PRIMARY KEY (type, from_id, to_id),
84
- FOREIGN KEY (from_id) REFERENCES nodes(node_id) ON DELETE CASCADE,
85
- FOREIGN KEY (to_id) REFERENCES nodes(node_id) ON DELETE CASCADE
86
- );
87
- PRAGMA user_version = 5;
88
- `);
89
- raw
90
- .prepare('INSERT INTO nodes (node_id, name, kind, status, cwd, created, window, tmux_session, pane) VALUES (?,?,?,?,?,?,?,?,?)')
91
- .run('legacy', 'Legacy', 'general', 'idle', '/tmp/work', '2020-01-01T00:00:00Z', '@9', 'crtr', '%3');
92
- assert.equal(userVersion(raw), 5);
93
- assert.ok(!tableNames(raw).includes('focuses'), 'precondition: no focuses table at v5');
94
- raw.close();
95
- // openDb() runs v6 forward.
96
- const db = openDb();
97
- assert.equal(userVersion(db), MIGRATIONS.length);
98
- assert.ok(tableNames(db).includes('focuses'), 'focuses table added by v6');
99
- // The pre-existing node row is intact (the v6 migration only adds a table).
100
- const row = db
101
- .prepare('SELECT status, window, tmux_session, pane FROM nodes WHERE node_id = ?')
102
- .get('legacy');
103
- assert.equal(row['status'], 'idle', 'existing status untouched');
104
- assert.equal(row['window'], '@9', 'existing window untouched');
105
- assert.equal(row['tmux_session'], 'crtr', 'existing session untouched');
106
- assert.equal(row['pane'], '%3', 'existing pane untouched');
107
- // The fresh focuses table is empty.
108
- const n = db.prepare('SELECT COUNT(*) AS n FROM focuses').get().n;
109
- assert.equal(n, 0, 'a fresh focuses table starts empty');
110
- });
111
- test('the v6 migration is idempotent / forward-only on re-run and re-open', () => {
112
- const db = openDb();
113
- assert.equal(userVersion(db), MIGRATIONS.length);
114
- // Re-running migrate() is a no-op — the gate skips applied steps. The CREATE
115
- // TABLE IF NOT EXISTS would be harmless anyway, but the gate must not re-fire.
116
- assert.doesNotThrow(() => migrate(db));
117
- assert.equal(userVersion(db), MIGRATIONS.length);
118
- // Re-opening from disk is likewise a no-op.
119
- closeDb();
120
- const db2 = openDb();
121
- assert.equal(userVersion(db2), MIGRATIONS.length);
122
- assert.ok(tableNames(db2).includes('focuses'));
123
- });
124
49
  // ---------------------------------------------------------------------------
125
50
  // Canvas setters / reads — open / setOccupant / setPane / close round-trip.
126
51
  // ---------------------------------------------------------------------------
@@ -148,25 +73,6 @@ test('open / setOccupant / close round-trip with the reads', () => {
148
73
  assert.equal(getFocusById('f1'), null);
149
74
  assert.deepEqual(listFocuses(), []);
150
75
  });
151
- test('UNIQUE(node_id): a second focus row for the same node is rejected', () => {
152
- openDb();
153
- openFocusRow('f1', '%a', 'Sa', 'A');
154
- // A second viewport occupied by the SAME node violates UNIQUE(node_id) — this
155
- // is the constraint that upholds "a node occupies <=1 focus" (Q5).
156
- assert.throws(() => openFocusRow('f2', '%b', 'Sb', 'A'), /UNIQUE|constraint/i);
157
- // The first row is untouched; no stray second row was created.
158
- assert.deepEqual(listFocuses().map((f) => f.focus_id), ['f1']);
159
- });
160
- test('UNIQUE(node_id): hot-swapping an occupant onto an already-focused node is rejected', () => {
161
- openDb();
162
- openFocusRow('f1', '%a', 'Sa', 'A');
163
- openFocusRow('f2', '%b', 'Sb', 'B');
164
- // B already occupies f2 — moving it onto f1 via setFocusOccupant must throw
165
- // (the Q5 vacate-first is placement.focus()'s job, not this setter's).
166
- assert.throws(() => setFocusOccupant('f1', 'B'), /UNIQUE|constraint/i);
167
- assert.deepEqual(getFocusByNode('A'), { focus_id: 'f1', pane: '%a', session: 'Sa', node_id: 'A' });
168
- assert.deepEqual(getFocusByNode('B'), { focus_id: 'f2', pane: '%b', session: 'Sb', node_id: 'B' });
169
- });
170
76
  test('independent focus rows do not contend', () => {
171
77
  openDb();
172
78
  openFocusRow('f1', '%a', 'Sa', 'A');
@@ -185,8 +91,8 @@ test('independent focus rows do not contend', () => {
185
91
  // A row whose viewer pane no longer exists is pruned the next time it is read,
186
92
  // so the registry self-heals without a sweeper; a row with a null pane (a
187
93
  // registered-but-not-yet-realized viewer) is passed through. A live tmux pane
188
- // can't be fabricated in the fast tier, so we cover the prune + null-pane paths
189
- // here; the live-pane read is covered in the full-tier broker lifecycle suite.
94
+ // can't be fabricated in the ordinary suite, so we cover the prune + null-pane paths
95
+ // here; the live-pane read is covered in the compiled-seam broker lifecycle suite.
190
96
  // ---------------------------------------------------------------------------
191
97
  test('placement reads GC dead-pane viewer rows and keep null-pane rows', () => {
192
98
  openDb();
@@ -6,9 +6,6 @@ export declare const delay: (ms: number) => Promise<void>;
6
6
  export declare const tok: (s: string) => string;
7
7
  export declare const frameHas: (f: BrokerToClient, token: string) => boolean;
8
8
  export declare function brokerLogText(h: Harness, id: string): string;
9
- /** lsof the holders of `path`, or null when lsof is unavailable (skip the fd
10
- * check). Exit-non-zero with empty stdout means "no holders". */
11
- export declare function lsofHolders(path: string): number[] | null;
12
9
  export interface Attached {
13
10
  client: BrokerClient;
14
11
  frames: BrokerToClient[];
@@ -12,7 +12,6 @@
12
12
  import { existsSync, readFileSync } from 'node:fs';
13
13
  import { join } from 'node:path';
14
14
  import { createConnection } from 'node:net';
15
- import { spawnSync } from 'node:child_process';
16
15
  import { BrokerClient } from '../../broker-client/index.js';
17
16
  import { CLIENT_READ_CAPS, FrameDecoder, encodeFrame, } from '../../runtime/broker-protocol.js';
18
17
  export const delay = (ms) => new Promise((r) => setTimeout(r, ms));
@@ -30,19 +29,6 @@ export function brokerLogText(h, id) {
30
29
  return '';
31
30
  }
32
31
  }
33
- /** lsof the holders of `path`, or null when lsof is unavailable (skip the fd
34
- * check). Exit-non-zero with empty stdout means "no holders". */
35
- export function lsofHolders(path) {
36
- if (spawnSync('which', ['lsof'], { stdio: 'ignore' }).status !== 0)
37
- return null;
38
- const out = (spawnSync('lsof', ['-t', '--', path], { encoding: 'utf8' }).stdout ?? '').trim();
39
- if (out === '')
40
- return [];
41
- return out
42
- .split('\n')
43
- .map((l) => Number(l.trim()))
44
- .filter((n) => Number.isFinite(n));
45
- }
46
32
  /** Build the attach kit against a lazily-resolved harness (the harness is
47
33
  * created in the file's before() hook, after the kit is constructed). */
48
34
  export function createAttachKit(getH) {
@@ -77,17 +77,12 @@ export interface Harness {
77
77
  session: string;
78
78
  spawnRoot(task: string, o?: SpawnOpts): string;
79
79
  fabricateBrokerNode(o?: FabricateOpts): string;
80
- spawnChild(parentId: string, task: string, o?: SpawnOpts): Promise<string>;
81
80
  cli(nodeId: string | null, args: string[]): CliResult;
82
81
  spawnHeadlessChild(parentId: string, task: string, o?: SpawnOpts): Promise<string>;
83
- spawnHeadlessChildNoBoot(parentId: string, task: string, o?: SpawnOpts): Promise<string>;
84
- turn(nodeId: string, text?: string): Promise<void>;
85
82
  stop(nodeId: string, reason?: 'stop' | 'length' | 'aborted' | 'error', errorMessage?: string): Promise<void>;
86
- finish(nodeId: string, finalText: string): Promise<void>;
87
83
  tick(now?: number): Promise<void>;
88
84
  fleet: DaemonFleet;
89
85
  deliverExit(nodeId: string, status?: FleetExitStatus): Promise<void>;
90
- drainFleet(): Promise<void>;
91
86
  awaitFleetExit(nodeId: string, timeoutMs?: number): Promise<void>;
92
87
  awaitBoot(nodeId: string, o?: {
93
88
  minCount?: number;
@@ -98,12 +93,9 @@ export interface Harness {
98
93
  timeoutMs?: number;
99
94
  match?: RegExp;
100
95
  }): Promise<string[]>;
101
- waitForStatus(nodeId: string, status: NodeStatus, timeoutMs?: number): Promise<void>;
102
- waitForPaneGone(nodeId: string, timeoutMs?: number): Promise<void>;
103
96
  waitFor<T>(probe: () => T | undefined | null | false, o?: WaitOpts): Promise<T>;
104
97
  node(nodeId: string): NodeMeta | null;
105
98
  status(nodeId: string): NodeStatus | null;
106
- paneAlive(nodeId: string): boolean;
107
99
  inbox(nodeId: string): InboxEntry[];
108
100
  injected(nodeId: string): Injected[];
109
101
  fakeCmd(nodeId: string, cmd: Record<string, unknown>): void;