@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,146 +0,0 @@
1
- // remote-event-stream.test.ts — `RemoteEventStream` (`../remote-event-stream.ts`),
2
- // a manual SSE client over `/__crtr/events`. Covers the wire parse (only
3
- // known `kind`s fire listeners; comments/pings/unknown kinds are silently
4
- // ignored) and that `stop()` actually halts the reconnect loop rather than
5
- // leaving it retrying forever in the background.
6
- //
7
- // Reconnect/backoff timing uses an INJECTABLE backoff (`RemoteEventStreamOptions`)
8
- // so these tests run against a small, fast backoff window instead of the
9
- // production 1s→30s one, and every wait is a condition-poll on an observed
10
- // request/event count (`waitFor`) rather than a fixed wall-clock sleep —
11
- // less flaky under scheduler variance, and fast.
12
- import { test } from 'node:test';
13
- import assert from 'node:assert/strict';
14
- import { createServer } from 'node:http';
15
- import { RemoteEventStream } from '../remote-event-stream.js';
16
- function startSseServer(onRequest) {
17
- return new Promise((resolve) => {
18
- let hits = 0;
19
- const requests = [];
20
- const server = createServer((req, res) => {
21
- hits += 1;
22
- requests.push({ method: req.method, url: req.url ?? '', headers: req.headers });
23
- onRequest(res, req);
24
- });
25
- server.listen(0, '127.0.0.1', () => {
26
- const addr = server.address();
27
- const port = typeof addr === 'object' && addr !== null ? addr.port : 0;
28
- resolve({
29
- url: `http://127.0.0.1:${port}`,
30
- hitCount: () => hits,
31
- requests,
32
- close: () => new Promise((res) => server.close(() => res())),
33
- });
34
- });
35
- });
36
- }
37
- /** Poll `predicate` until it's true, or throw after `timeoutMs` — used in
38
- * place of a fixed sleep so tests assert on the OBSERVED condition (a
39
- * request landed, an event fired) rather than a guessed timing window. */
40
- async function waitFor(predicate, timeoutMs = 2000, intervalMs = 5) {
41
- const deadline = Date.now() + timeoutMs;
42
- while (!predicate()) {
43
- if (Date.now() > deadline)
44
- throw new Error(`waitFor: condition not met within ${timeoutMs}ms`);
45
- await new Promise((r) => setTimeout(r, intervalMs));
46
- }
47
- }
48
- test('a listener fires once per known-kind SSE event, and never for a ping or an unknown kind', async (t) => {
49
- const server = await startSseServer((res) => {
50
- res.writeHead(200, { 'content-type': 'text/event-stream' });
51
- res.write(': connected\n\n');
52
- res.write('data: {"kind":"nodes"}\n\n');
53
- res.write(': ping\n\n');
54
- res.write('data: {"kind":"bogus"}\n\n');
55
- res.end();
56
- });
57
- const stream = new RemoteEventStream(server.url, 'tok');
58
- // Register cleanup BEFORE any assertion runs — a thrown assertion must not
59
- // leave the client's reconnect loop or the server's listening socket alive
60
- // (see the CI-hang postmortem on rebuild-coalescer.test.ts).
61
- t.after(() => { stream.stop(); return server.close(); });
62
- const seen = [];
63
- stream.subscribe((kind) => seen.push(kind));
64
- stream.start();
65
- await waitFor(() => seen.length > 0);
66
- stream.stop();
67
- assert.deepEqual(seen, ['nodes']);
68
- });
69
- test('the SSE connection carries the token ONLY in the Authorization header — not in the URL or any other header', async (t) => {
70
- const server = await startSseServer((res) => {
71
- res.writeHead(200, { 'content-type': 'text/event-stream' });
72
- res.end();
73
- });
74
- // A token that cannot collide with a hostname/port (unlike 'tok', which is a
75
- // substring of numeric-looking noise) so a pass here can't be a coincidence —
76
- // no header, including Host, is permitted to carry it.
77
- const token = 'secret-sse-token-value';
78
- const stream = new RemoteEventStream(server.url, token);
79
- t.after(() => { stream.stop(); return server.close(); });
80
- stream.start();
81
- await waitFor(() => server.requests.length > 0);
82
- stream.stop();
83
- assert.equal(server.requests.length, 1);
84
- const req = server.requests[0];
85
- assert.equal(req.method, 'GET');
86
- assert.equal(req.url, '/__crtr/events');
87
- assert.equal(req.headers['authorization'], `Bearer ${token}`);
88
- for (const [k, v] of Object.entries(req.headers)) {
89
- if (k.toLowerCase() === 'authorization')
90
- continue;
91
- assert.ok(!String(v).includes(token), `header ${k} must not carry the token`);
92
- }
93
- assert.ok(!req.url.includes(token));
94
- });
95
- test('stop() cancels a pending reconnect timer — no zombie loop survives a stop()+start() cycle', async (t) => {
96
- const server = await startSseServer((res) => {
97
- res.writeHead(500);
98
- res.end();
99
- });
100
- // A small injected backoff (200ms, not production's 1s) — the test asserts
101
- // the SAME relative-timing invariant (a stopped loop's dangling reconnect
102
- // timer must not fire) but the deliberate gap below (half the backoff)
103
- // between the stale deadline and the new deadline is kept proportionally
104
- // wide enough that ordinary event-loop/scheduler jitter can't flip it.
105
- const BACKOFF = 200;
106
- const stream = new RemoteEventStream(server.url, 'tok', { initialBackoffMs: BACKOFF });
107
- t.after(() => { stream.stop(); return server.close(); });
108
- stream.start();
109
- // t≈0: first request fires+fails, backoff(BACKOFF) scheduled → stale deadline ≈ BACKOFF.
110
- await waitFor(() => server.hitCount() >= 1);
111
- assert.equal(server.hitCount(), 1);
112
- // Deliberate mid-backoff gap (half the window) before stop()+start(), so the
113
- // stale deadline (hit1 + BACKOFF) and the new loop's own deadline
114
- // (hit2 + BACKOFF) land ~BACKOFF/2 apart — the window this test inspects.
115
- await new Promise((r) => setTimeout(r, BACKOFF / 2));
116
- stream.stop();
117
- stream.start();
118
- await waitFor(() => server.hitCount() >= 2);
119
- assert.equal(server.hitCount(), 2, 'restart fires its own immediate request');
120
- // Wait past the STALE timer's deadline (~BACKOFF from the first request) but
121
- // well before the NEW loop's own deadline (~BACKOFF from the second,
122
- // later, request). A dangling old-loop timer (bug) would add a 3rd hit in
123
- // this window; a cleared one (fixed) leaves it at 2.
124
- await new Promise((r) => setTimeout(r, BACKOFF * 0.7));
125
- assert.equal(server.hitCount(), 2, "no zombie request from the stopped loop's dangling timer");
126
- });
127
- test('stop() halts the reconnect loop — no further requests after it is called', async (t) => {
128
- const server = await startSseServer((res) => {
129
- // Every connection is refused immediately (no SSE headers, just a close)
130
- // so the client's loop falls into its backoff-and-retry path.
131
- res.writeHead(500);
132
- res.end();
133
- });
134
- const BACKOFF = 20;
135
- const stream = new RemoteEventStream(server.url, 'tok', { initialBackoffMs: BACKOFF });
136
- t.after(() => { stream.stop(); return server.close(); });
137
- stream.start();
138
- await waitFor(() => server.hitCount() >= 1);
139
- const hitsAtStop = server.hitCount();
140
- stream.stop();
141
- // The reconnect backoff is BACKOFF ms; wait well past it and confirm no new
142
- // connection was attempted — proves the loop actually stopped rather than
143
- // continuing to retry in the background after stop() returned.
144
- await new Promise((r) => setTimeout(r, BACKOFF * 5));
145
- assert.equal(server.hitCount(), hitsAtStop);
146
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,77 +0,0 @@
1
- // source-resolve.test.ts — `resolveCanvasSource` (`../source.ts`), the
2
- // --canvas > activeCanvas > local precedence a command's read path goes
3
- // through. The one invariant worth pinning: the local case returns the SAME
4
- // `localCanvasSource` singleton by identity, not a structurally-equal copy —
5
- // callers that hold onto a source reference (e.g. `canvas browse`'s
6
- // `instanceof RemoteCanvasSource` checks) depend on that.
7
- import { test, before, after, beforeEach } from 'node:test';
8
- import assert from 'node:assert/strict';
9
- import { mkdtempSync, rmSync } from 'node:fs';
10
- import { tmpdir } from 'node:os';
11
- import { join } from 'node:path';
12
- import { resolveCanvasSource, localCanvasSource } from '../source.js';
13
- import { RemoteCanvasSource } from '../remote-canvas-source.js';
14
- import { updateConfig, updateState } from '../../config.js';
15
- import { setRelayToken } from '../../secrets.js';
16
- let home;
17
- let realHome;
18
- before(() => {
19
- realHome = process.env['HOME'];
20
- home = mkdtempSync(join(tmpdir(), 'crtr-source-resolve-'));
21
- process.env['HOME'] = home;
22
- });
23
- beforeEach(() => {
24
- rmSync(home, { recursive: true, force: true });
25
- });
26
- after(() => {
27
- rmSync(home, { recursive: true, force: true });
28
- if (realHome !== undefined)
29
- process.env['HOME'] = realHome;
30
- else
31
- delete process.env['HOME'];
32
- });
33
- test('no --canvas and no activeCanvas resolves to the local singleton by identity', () => {
34
- const source = resolveCanvasSource();
35
- assert.equal(source, localCanvasSource);
36
- });
37
- test('an explicit canvasName wins over local, even with no activeCanvas set', () => {
38
- updateConfig('user', (cfg) => {
39
- cfg.remoteCanvas.targets['cloud'] = { previewEndpoint: 'https://x.preview.bl.run', relayTokenRef: 'cloud' };
40
- });
41
- setRelayToken('cloud', 'tok', 'user');
42
- const source = resolveCanvasSource({ canvasName: 'cloud' });
43
- assert.ok(source instanceof RemoteCanvasSource);
44
- assert.notEqual(source, localCanvasSource);
45
- });
46
- test('the durable activeCanvas selection is honored when no explicit canvasName is passed', () => {
47
- updateConfig('user', (cfg) => {
48
- cfg.remoteCanvas.targets['cloud'] = { previewEndpoint: 'https://x.preview.bl.run', relayTokenRef: 'cloud' };
49
- });
50
- setRelayToken('cloud', 'tok', 'user');
51
- updateState('user', (s) => {
52
- s.activeCanvas = 'cloud';
53
- });
54
- const source = resolveCanvasSource();
55
- assert.ok(source instanceof RemoteCanvasSource);
56
- });
57
- test('an explicit --canvas wins over a different durable activeCanvas selection', () => {
58
- updateConfig('user', (cfg) => {
59
- cfg.remoteCanvas.targets['cloud-a'] = { previewEndpoint: 'https://a.preview.bl.run', relayTokenRef: 'cloud-a' };
60
- cfg.remoteCanvas.targets['cloud-b'] = { previewEndpoint: 'https://b.preview.bl.run', relayTokenRef: 'cloud-b' };
61
- });
62
- setRelayToken('cloud-a', 'tok-a', 'user');
63
- setRelayToken('cloud-b', 'tok-b', 'user');
64
- updateState('user', (s) => {
65
- s.activeCanvas = 'cloud-a';
66
- });
67
- const source = resolveCanvasSource({ canvasName: 'cloud-b' });
68
- assert.ok(source instanceof RemoteCanvasSource);
69
- assert.equal(source.previewEndpoint, 'https://b.preview.bl.run');
70
- });
71
- test('activeCanvas set to null (explicit local) falls back to the local singleton', () => {
72
- updateState('user', (s) => {
73
- s.activeCanvas = null;
74
- });
75
- const source = resolveCanvasSource();
76
- assert.equal(source, localCanvasSource);
77
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,290 +0,0 @@
1
- import { test } from 'node:test';
2
- import assert from 'node:assert/strict';
3
- import { buildTree, flatten, fuzzyMatch, pruneNode, tabPredicate, TABS, attentionTier, attentionMtime } from '../model.js';
4
- // ── Fixture canvas ───────────────────────────────────────────────────────────
5
- // root1 (active) ← rank 0
6
- // child-a (idle)
7
- // grand-x (done)
8
- // child-b (active, ⚑2)
9
- // root2 (done) ← rank 2 (dormant root, but ancestor of a live node)
10
- // child-c (active)
11
- // lonely (idle) ← straggler: in rows, no edge reaches it, not a root
12
- function row(node_id, name, status, asks = 0) {
13
- return { node_id, name, status, kind: 'general', mode: 'base', ctx_tokens: 0, asks, cwd: '/tmp/proj', created: '2026-01-01T00:00:00.000Z' };
14
- }
15
- function lrow(node_id, name, status, lifecycle) {
16
- return { ...row(node_id, name, status), lifecycle };
17
- }
18
- const ROWS = [
19
- row('root1', 'root-one', 'active'),
20
- row('child-a', 'child-a', 'idle'),
21
- row('grand-x', 'grand-x', 'done'),
22
- row('child-b', 'child-b', 'active', 2),
23
- row('root2', 'root-two', 'done'),
24
- row('child-c', 'child-c', 'active'),
25
- row('lonely', 'lonely-node', 'idle'),
26
- ];
27
- // rootIds intentionally unsorted to prove buildTree sorts live-first.
28
- const ROOT_IDS = ['root2', 'root1'];
29
- const CHILDREN = {
30
- root1: ['child-a', 'child-b'],
31
- 'child-a': ['grand-x'],
32
- root2: ['child-c'],
33
- };
34
- const childIdsOf = (id) => CHILDREN[id] ?? [];
35
- function tree() {
36
- return buildTree(ROWS, ROOT_IDS, childIdsOf);
37
- }
38
- // ── fuzzyMatch ───────────────────────────────────────────────────────────────
39
- test('fuzzyMatch: empty query matches everything', () => {
40
- assert.equal(fuzzyMatch('', 'whatever'), true);
41
- });
42
- test('fuzzyMatch: case-insensitive subsequence', () => {
43
- assert.equal(fuzzyMatch('abc', 'aXbXc'), true);
44
- assert.equal(fuzzyMatch('AB', 'xaYbz'), true);
45
- assert.equal(fuzzyMatch('grandx', 'grand-x'), true);
46
- });
47
- test('fuzzyMatch: out-of-order is not a match', () => {
48
- assert.equal(fuzzyMatch('abc', 'acb'), false);
49
- assert.equal(fuzzyMatch('zz', 'z'), false);
50
- });
51
- // ── buildTree ────────────────────────────────────────────────────────────────
52
- test('buildTree: roots sorted live-first, stragglers appended', () => {
53
- const t = tree();
54
- assert.deepEqual(t.roots, ['root1', 'root2', 'lonely']);
55
- });
56
- test('buildTree: depth, parentId, childIds', () => {
57
- const t = tree();
58
- assert.equal(t.nodes.size, 7);
59
- assert.deepEqual(t.nodes.get('root1'), {
60
- row: ROWS[0], depth: 0, parentId: null, childIds: ['child-a', 'child-b'],
61
- });
62
- assert.equal(t.nodes.get('child-a').depth, 1);
63
- assert.equal(t.nodes.get('child-a').parentId, 'root1');
64
- assert.deepEqual(t.nodes.get('child-a').childIds, ['grand-x']);
65
- assert.equal(t.nodes.get('grand-x').depth, 2);
66
- assert.equal(t.nodes.get('grand-x').parentId, 'child-a');
67
- // straggler attaches at depth 0 with no parent
68
- assert.equal(t.nodes.get('lonely').depth, 0);
69
- assert.equal(t.nodes.get('lonely').parentId, null);
70
- });
71
- test('buildTree: unknown child ids are dropped (missing meta safe)', () => {
72
- const t = buildTree(ROWS, ['root1'], (id) => (id === 'root1' ? ['child-a', 'ghost'] : childIdsOf(id)));
73
- assert.deepEqual(t.nodes.get('root1').childIds, ['child-a']);
74
- assert.equal(t.nodes.has('ghost'), false);
75
- });
76
- // ── pruneNode ────────────────────────────────────────────────────────────────
77
- // Regression: pressing `x` in canvas browse on an EMPTY active node looked like a
78
- // no-op — closeNode hard-deletes (reaps) an empty node, but doClose never removed
79
- // it from the in-memory tree, so the stale active row kept painting. pruneNode is
80
- // the splice doClose now applies for a reaped (getNode===null) close.
81
- test('pruneNode: reaping a leaf removes it from its parent and the node map', () => {
82
- const t = tree();
83
- pruneNode(t, 'grand-x'); // leaf under child-a
84
- assert.equal(t.nodes.has('grand-x'), false);
85
- assert.deepEqual(t.nodes.get('child-a').childIds, []);
86
- });
87
- test('pruneNode: reaping a mid-tree node re-homes its children to its parent', () => {
88
- const t = tree();
89
- pruneNode(t, 'child-a'); // child-a (under root1) owns grand-x
90
- assert.equal(t.nodes.has('child-a'), false);
91
- // grand-x lifts into child-a's slot in root1's child order (before child-b).
92
- assert.deepEqual(t.nodes.get('root1').childIds, ['grand-x', 'child-b']);
93
- assert.equal(t.nodes.get('grand-x').parentId, 'root1');
94
- });
95
- test('pruneNode: reaping a root lifts its children into the root list', () => {
96
- const t = tree();
97
- const rootIdx = t.roots.indexOf('root2');
98
- pruneNode(t, 'root2'); // root2 owns child-c
99
- assert.equal(t.nodes.has('root2'), false);
100
- assert.equal(t.roots.includes('root2'), false);
101
- assert.equal(t.roots[rootIdx], 'child-c'); // child-c took root2's slot
102
- assert.equal(t.nodes.get('child-c').parentId, null);
103
- });
104
- test('pruneNode: absent id is a no-op', () => {
105
- const t = tree();
106
- const before = t.nodes.size;
107
- pruneNode(t, 'ghost');
108
- assert.equal(t.nodes.size, before);
109
- });
110
- // ── tab predicates ───────────────────────────────────────────────────────────
111
- test('tabPredicate: All / Live / Dormant / Attention / Pinned', () => {
112
- assert.deepEqual([...TABS], ['All', 'Live', 'Dormant', 'Attention', 'Pinned']);
113
- const active = ROWS[0]; // root1 active
114
- const idle = ROWS[1]; // child-a idle
115
- const done = ROWS[2]; // grand-x done
116
- const attention = ROWS[3]; // child-b active asks 2
117
- assert.equal(tabPredicate('All', done), true);
118
- assert.equal(tabPredicate('Live', active), true);
119
- assert.equal(tabPredicate('Live', idle), true);
120
- assert.equal(tabPredicate('Live', done), false);
121
- assert.equal(tabPredicate('Dormant', done), true);
122
- assert.equal(tabPredicate('Dormant', active), false);
123
- // Attention = pending asks OR a fault.
124
- assert.equal(tabPredicate('Attention', attention), true);
125
- assert.equal(tabPredicate('Attention', active), false);
126
- assert.equal(tabPredicate('Attention', { ...active, asks: 0, hanging: { kind: 'provider' } }), true);
127
- // Pinned reads the isPinned arg, not the row.
128
- assert.equal(tabPredicate('Pinned', active), false);
129
- assert.equal(tabPredicate('Pinned', active, true), true);
130
- });
131
- // ── flatten: pins ────────────────────────────────────────────────────────────
132
- test('flatten: profile scope keeps only the launching profile, with ancestors for context', () => {
133
- const profileRows = [
134
- { ...row('profile-root', 'profile-root', 'active'), profile_id: 'alpha-11111111' },
135
- { ...row('profile-child', 'profile-child', 'idle'), profile_id: 'beta-22222222' },
136
- { ...row('other-root', 'other-root', 'active'), profile_id: 'beta-22222222' },
137
- ];
138
- const t = buildTree(profileRows, ['profile-root', 'other-root'], (id) => id === 'profile-root' ? ['profile-child'] : []);
139
- const v = flatten(t, { collapsed: new Set(), tab: 'All', query: '', profileScope: 'alpha-11111111' });
140
- assert.deepEqual(v.map((r) => r.id), ['profile-root']);
141
- assert.equal(v[0].matched, true);
142
- });
143
- test('flatten: Pinned tab shows only pinned rows', () => {
144
- const pinned = new Set(['child-c']);
145
- const v = flatten(tree(), { collapsed: new Set(), tab: 'Pinned', query: '', pinned });
146
- // child-c is directly matched; root2 rides along as its ancestor (context).
147
- const matched = v.filter((r) => r.matched).map((r) => r.id);
148
- assert.deepEqual(matched, ['child-c']);
149
- });
150
- test('flatten: pinned rows float to the top in a flat sort', () => {
151
- const pinned = new Set(['lonely']); // an idle straggler that would otherwise sort late
152
- const v = flatten(tree(), { collapsed: new Set(), tab: 'All', query: '', sort: 'recency', pinned });
153
- assert.equal(v[0].id, 'lonely');
154
- });
155
- // ── flatten: collapse / expand ───────────────────────────────────────────────
156
- const allCollapsed = () => new Set(['root1', 'child-a', 'root2']); // every node with children
157
- test('flatten: default-collapsed shows only top-level', () => {
158
- const v = flatten(tree(), { collapsed: allCollapsed(), tab: 'All', query: '' });
159
- assert.deepEqual(v.map((r) => r.id), ['root1', 'root2', 'lonely']);
160
- // root1 has children and is collapsed → glyph state
161
- assert.equal(v[0].hasChildren, true);
162
- assert.equal(v[0].collapsed, true);
163
- assert.equal(v[2].hasChildren, false); // lonely is a leaf
164
- });
165
- test('flatten: expanding a root reveals its (still-collapsed) children', () => {
166
- const collapsed = allCollapsed();
167
- collapsed.delete('root1');
168
- const v = flatten(tree(), { collapsed, tab: 'All', query: '' });
169
- assert.deepEqual(v.map((r) => r.id), ['root1', 'child-a', 'child-b', 'root2', 'lonely']);
170
- // child-a still collapsed → grand-x hidden
171
- assert.equal(v.find((r) => r.id === 'child-a').collapsed, true);
172
- });
173
- test('flatten: fully expanded shows the whole subtree', () => {
174
- const collapsed = new Set(); // nothing collapsed
175
- const v = flatten(tree(), { collapsed, tab: 'All', query: '' });
176
- assert.deepEqual(v.map((r) => r.id), ['root1', 'child-a', 'grand-x', 'child-b', 'root2', 'child-c', 'lonely']);
177
- });
178
- // ── flatten: tab filtering + ancestor context ────────────────────────────────
179
- test('flatten: Live tab dims dormant ancestors, keeps live matches', () => {
180
- const v = flatten(tree(), { collapsed: allCollapsed(), tab: 'Live', query: '' });
181
- assert.deepEqual(v.map((r) => r.id), ['root1', 'root2', 'lonely']);
182
- const byId = Object.fromEntries(v.map((r) => [r.id, r]));
183
- assert.equal(byId['root1'].matched, true); // active
184
- assert.equal(byId['lonely'].matched, true); // idle
185
- assert.equal(byId['root2'].matched, false); // dormant, shown only as ancestor of child-c
186
- });
187
- test('flatten: Dormant tab excludes live-only branches', () => {
188
- const v = flatten(tree(), { collapsed: new Set(), tab: 'Dormant', query: '' });
189
- const ids = v.map((r) => r.id);
190
- assert.ok(ids.includes('grand-x')); // done
191
- assert.ok(ids.includes('root2')); // done
192
- assert.ok(!ids.includes('child-b')); // active → excluded
193
- assert.ok(!ids.includes('lonely')); // idle → excluded
194
- });
195
- // ── flatten: query auto-expands ancestors of matches ─────────────────────────
196
- test('flatten: query force-expands ancestors even when collapsed', () => {
197
- // Everything collapsed; query targets a deep leaf. Its ancestors must appear.
198
- const v = flatten(tree(), { collapsed: allCollapsed(), tab: 'All', query: 'grandx' });
199
- assert.deepEqual(v.map((r) => r.id), ['root1', 'child-a', 'grand-x']);
200
- const byId = Object.fromEntries(v.map((r) => [r.id, r]));
201
- assert.equal(byId['grand-x'].matched, true); // the actual match
202
- assert.equal(byId['child-a'].matched, false); // ancestor for context
203
- assert.equal(byId['root1'].matched, false); // ancestor for context
204
- });
205
- test('flatten: query with no matches yields nothing', () => {
206
- const v = flatten(tree(), { collapsed: allCollapsed(), tab: 'All', query: 'zzzznope' });
207
- assert.deepEqual(v, []);
208
- });
209
- // ── flatten: residentsOnly fold-reveal ───────────────────────────────────────
210
- // resident-root → terminal-worker (child) → terminal-grand (grandchild)
211
- // resident-only must hide the terminals from the TOP LEVEL + flat search, yet
212
- // still reveal them once you expand the resident fold that owns them.
213
- const RES_ROWS = [
214
- lrow('res-root', 'resident-root', 'idle', 'resident'),
215
- lrow('term-a', 'worker-a', 'active', 'terminal'),
216
- lrow('term-g', 'worker-grand', 'active', 'terminal'),
217
- lrow('term-root', 'lone-worker', 'active', 'terminal'), // pure-terminal root
218
- ];
219
- const RES_CHILDREN = { 'res-root': ['term-a'], 'term-a': ['term-g'] };
220
- function resTree() {
221
- return buildTree(RES_ROWS, ['res-root', 'term-root'], (id) => RES_CHILDREN[id] ?? []);
222
- }
223
- test('flatten: residentsOnly hides terminal top-level rows (incl. terminal roots)', () => {
224
- // Everything collapsed → only the resident root shows; the lone terminal root
225
- // and the worker subtree are hidden at the top level.
226
- const v = flatten(resTree(), { collapsed: new Set(['res-root', 'term-a']), tab: 'All', query: '', residentsOnly: true });
227
- assert.deepEqual(v.map((r) => r.id), ['res-root']);
228
- });
229
- test('flatten: residentsOnly reveals terminal children once their fold is expanded', () => {
230
- // Expand the resident root → its terminal worker appears (still collapsed, so
231
- // its own terminal grandchild stays hidden).
232
- const v1 = flatten(resTree(), { collapsed: new Set(['term-a']), tab: 'All', query: '', residentsOnly: true });
233
- assert.deepEqual(v1.map((r) => r.id), ['res-root', 'term-a']);
234
- // Expand the worker too → the terminal grandchild is revealed.
235
- const v2 = flatten(resTree(), { collapsed: new Set(), tab: 'All', query: '', residentsOnly: true });
236
- assert.deepEqual(v2.map((r) => r.id), ['res-root', 'term-a', 'term-g']);
237
- });
238
- test('flatten: residentsOnly keeps terminals out of flat (relevance) search results', () => {
239
- // A query that matches the workers must not surface them in the flat search —
240
- // resident-only de-clutters search even though the fold would reveal them.
241
- const v = flatten(resTree(), { collapsed: new Set(), tab: 'All', query: 'worker', residentsOnly: true, sort: 'relevance' });
242
- assert.deepEqual(v.map((r) => r.id), []);
243
- });
244
- test('flatten: residentsOnly off shows every lifecycle at the top level', () => {
245
- // Roots are live-first: term-root (active) ranks ahead of res-root (idle).
246
- const v = flatten(resTree(), { collapsed: new Set(['res-root', 'term-a']), tab: 'All', query: '', residentsOnly: false });
247
- assert.deepEqual(v.map((r) => r.id), ['term-root', 'res-root']);
248
- });
249
- function arow(node_id, status, opts) {
250
- return { ...row(node_id, node_id, status), ...opts };
251
- }
252
- test('attentionTier: classifies each cheap-field combination', () => {
253
- assert.equal(attentionTier(arow('x', 'active', { viewed: true, streaming: true })), 0);
254
- assert.equal(attentionTier(arow('x', 'active', { viewed: true })), 1);
255
- assert.equal(attentionTier(arow('x', 'active', { streaming: true, viewed: false })), 2);
256
- assert.equal(attentionTier(arow('x', 'active', {})), 3);
257
- assert.equal(attentionTier(arow('x', 'idle', {})), 3);
258
- assert.equal(attentionTier(arow('x', 'done', {})), 4);
259
- assert.equal(attentionTier(arow('x', 'dead', {})), 4);
260
- assert.equal(attentionTier(arow('x', 'canceled', {})), 4);
261
- });
262
- test('attentionMtime: prefers mtimeMs, falls back to created', () => {
263
- assert.equal(attentionMtime(arow('x', 'active', { mtimeMs: 1234 })), 1234);
264
- // No mtimeMs → epoch-ms of the ISO `created` (fixture is 2026-01-01T00:00:00Z).
265
- assert.equal(attentionMtime(arow('x', 'active', {})), Date.parse('2026-01-01T00:00:00.000Z'));
266
- });
267
- test('flatten: attention sort tiers rows (attached/streaming/live first)', () => {
268
- // One row per tier, deliberately shuffled in input order.
269
- const rows = [
270
- arow('dormant', 'done', { mtimeMs: 100 }), // T4
271
- arow('live', 'active', { mtimeMs: 100 }), // T3
272
- arow('streaming', 'active', { streaming: true, mtimeMs: 100 }), // T2
273
- arow('attached', 'idle', { viewed: true, mtimeMs: 100 }), // T1
274
- arow('both', 'active', { viewed: true, streaming: true, mtimeMs: 100 }), // T0
275
- ];
276
- const t = buildTree(rows, [], () => []);
277
- const v = flatten(t, { collapsed: new Set(), tab: 'All', query: '', sort: 'attention' });
278
- assert.deepEqual(v.map((r) => r.id), ['both', 'attached', 'streaming', 'live', 'dormant']);
279
- });
280
- test('flatten: attention sort orders newest-message-first WITHIN a tier', () => {
281
- // All dormant (T4) → ordering is purely by mtime, newest first.
282
- const rows = [
283
- arow('old', 'done', { mtimeMs: 1000 }),
284
- arow('newest', 'done', { mtimeMs: 3000 }),
285
- arow('mid', 'done', { mtimeMs: 2000 }),
286
- ];
287
- const t = buildTree(rows, [], () => []);
288
- const v = flatten(t, { collapsed: new Set(), tab: 'All', query: '', sort: 'attention' });
289
- assert.deepEqual(v.map((r) => r.id), ['newest', 'mid', 'old']);
290
- });