@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,439 +0,0 @@
1
- // attach-chrome-remote.test.ts — the safe-defaults contract for the attach
2
- // chrome (buildCanvasPanelLines + GraphOverlay) when the `canvasSource` is a
3
- // RemoteCanvasSource, i.e. `crtr surface attach --canvas <name>`.
4
- //
5
- // Adversarial, not merely a clean-machine assertion (mirrors
6
- // core/canvas/__tests__/render-remote.test.ts): BEFORE rendering, this test
7
- // seeds real, CONFLICTING local state for node id `a` — a poisoned telemetry
8
- // reading (context tokens + a live-activity cue), an active fault, a local
9
- // tmux focus, and a broker attach.json marking it human-watched — every
10
- // historically-broken local read the remote suppression in nav-model.ts is
11
- // supposed to bypass. If the production suppression ever regressed back to
12
- // consulting local disk/SQLite for a remote id, the rendered lines below would
13
- // carry the poisoned tokens/glyph/background instead of the safe defaults, so
14
- // a clean-machine run could never mask the regression.
15
- //
16
- // Also proves the read-only contract: GraphOverlay's Enter/m/x key handlers
17
- // must no-op against a remote graph row instead of shelling local
18
- // `crtr surface node focus` / `crtr node lifecycle close`.
19
- import { test, before, beforeEach, after } from 'node:test';
20
- import assert from 'node:assert/strict';
21
- import { createServer } from 'node:http';
22
- import { mkdtempSync, rmSync, writeFileSync } from 'node:fs';
23
- import { tmpdir } from 'node:os';
24
- import { join } from 'node:path';
25
- import { RemoteCanvasSource } from '../../../core/canvas/remote-canvas-source.js';
26
- import { createNode } from '../../../core/canvas/canvas.js';
27
- import { closeDb } from '../../../core/canvas/db.js';
28
- import { openFocusRow } from '../../../core/canvas/focuses.js';
29
- import { jobDir } from '../../../core/canvas/paths.js';
30
- import { recordFault } from '../../../core/runtime/fault.js';
31
- import { BG_ATTACHED } from '../../../core/canvas/nav-model.js';
32
- import { resolveKeybindings } from '../../../core/keybindings/index.js';
33
- import { dispatchSlashCommand, slashCommandList } from '../slash/dispatch.js';
34
- import { tagAttachPane, untagAttachPane } from '../session/pane-tag.js';
35
- import { createMemoryRefRefreshCoordinator } from '../session/editor-inventory.js';
36
- import { InputController } from '../input/controller.js';
37
- import { buildCanvasPanelLines } from '../chrome/canvas-panels.js';
38
- import { GraphOverlay } from '../overlays/graph.js';
39
- function startMockCrtrServer(route) {
40
- return new Promise((resolve) => {
41
- const server = createServer((req, res) => {
42
- const chunks = [];
43
- req.on('data', (c) => chunks.push(c));
44
- req.on('end', () => {
45
- const bodyText = Buffer.concat(chunks).toString('utf8');
46
- const parsed = JSON.parse(bodyText);
47
- const result = route(parsed.args);
48
- res.writeHead(result.status ?? 200, { 'content-type': 'application/json' });
49
- res.end(JSON.stringify({ ok: true, exitCode: 0, stdout: JSON.stringify(result.body), stderr: '' }));
50
- });
51
- });
52
- server.listen(0, '127.0.0.1', () => {
53
- const addr = server.address();
54
- const port = typeof addr === 'object' && addr !== null ? addr.port : 0;
55
- resolve({
56
- url: `http://127.0.0.1:${port}`,
57
- close: () => new Promise((res) => server.close(() => res())),
58
- });
59
- });
60
- });
61
- }
62
- function meta(id, extra) {
63
- return {
64
- node_id: id,
65
- name: id,
66
- created: new Date().toISOString(),
67
- cwd: '/tmp/work',
68
- kind: 'general',
69
- mode: 'base',
70
- lifecycle: 'terminal',
71
- status: 'active',
72
- ...extra,
73
- };
74
- }
75
- function show(node, reports, managers) {
76
- return {
77
- node,
78
- reports: reports.map((id) => ({ node_id: id, name: id, kind: 'general', status: 'active', active: true })),
79
- managers: managers.map((id) => ({ node_id: id, name: id, kind: 'general', status: 'active', active: true })),
80
- artifacts: { report: 0, doc: 0, roadmap: 0 },
81
- pending_crons: 0,
82
- paths: { context_dir: '/tmp/context', reports_dir: '/tmp/reports', session_file: null },
83
- follow_up: '',
84
- };
85
- }
86
- const IDENTITY_PALETTE = {
87
- accent: (s) => s,
88
- active: (s) => s,
89
- info: (s) => s,
90
- muted: (s) => s,
91
- faint: (s) => s,
92
- border: (s) => s,
93
- bold: (s) => s,
94
- error: (s) => s,
95
- warning: (s) => s,
96
- diffAdded: (s) => s,
97
- diffRemoved: (s) => s,
98
- bashMode: (s) => s,
99
- bashModeAlt: (s) => s,
100
- surface: (s) => s,
101
- };
102
- /** A fake `TUI` carrying just what `GraphOverlay` touches: `showOverlay` (a
103
- * no-op handle) and `requestRender`. GraphOverlay's key handlers only shell
104
- * `crtr` (via execFile) and toggle local overlay/handle state — they never
105
- * reach into the real TUI beyond these two calls. */
106
- function fakeTui() {
107
- let renders = 0;
108
- const tui = {
109
- showOverlay: () => ({
110
- hide: () => { },
111
- setHidden: () => { },
112
- isHidden: () => false,
113
- focus: () => { },
114
- unfocus: () => { },
115
- isFocused: () => true,
116
- }),
117
- requestRender: () => { renders++; },
118
- };
119
- return { tui, renderCount: () => renders };
120
- }
121
- let home;
122
- let localCwd;
123
- before(() => {
124
- home = mkdtempSync(join(tmpdir(), 'crtr-attach-chrome-remote-'));
125
- localCwd = mkdtempSync(join(tmpdir(), 'crtr-attach-chrome-remote-cwd-'));
126
- process.env['CRTR_HOME'] = home;
127
- });
128
- beforeEach(() => {
129
- closeDb();
130
- rmSync(home, { recursive: true, force: true });
131
- });
132
- after(() => {
133
- closeDb();
134
- rmSync(home, { recursive: true, force: true });
135
- rmSync(localCwd, { recursive: true, force: true });
136
- delete process.env['CRTR_HOME'];
137
- });
138
- /** Seed conflicting local state for node id `a` — every local read the
139
- * attach-chrome remote suppression is supposed to bypass. */
140
- function seedPoisonedLocalState() {
141
- createNode(meta('a', { cwd: localCwd }));
142
- // A local focus — poisons focusedNodeIds()/isAttached's fast path.
143
- openFocusRow('poison-focus', null, null, 'a');
144
- // A broker attach.json — poisons isAttached's slow path.
145
- writeFileSync(join(jobDir('a'), 'attach.json'), JSON.stringify({ viewers: 1 }));
146
- // An active, manually-retried fault — poisons nodeGlyph's hanging overlay.
147
- recordFault('a', {
148
- link: 'viewer↔broker',
149
- op: 'poison',
150
- kind: 'other',
151
- retry: { disposition: 'manual' },
152
- message: 'POISON FAULT — local read leaked into remote attach chrome',
153
- });
154
- // Local telemetry — poisons tokensCell + activityCell.
155
- writeFileSync(join(jobDir('a'), 'telemetry.json'), JSON.stringify({
156
- context_tokens: 999_999,
157
- last_activity: 'POISON ACTIVITY — local read leaked into remote attach chrome',
158
- }));
159
- }
160
- test('buildCanvasPanelLines suppresses every local-read adornment for a RemoteCanvasSource, even with conflicting local state for the same node id', async (t) => {
161
- seedPoisonedLocalState();
162
- const rootMeta = meta('root');
163
- const aMeta = meta('a'); // the REMOTE node's meta — unrelated to the poisoned local NodeMeta above
164
- const server = await startMockCrtrServer((args) => {
165
- if (args[1] === 'node' && args[2] === 'inspect' && args[3] === 'show') {
166
- const id = args[4];
167
- if (id === 'root')
168
- return { body: show(rootMeta, ['a'], []) };
169
- if (id === 'a')
170
- return { body: show(aMeta, [], ['root']) };
171
- }
172
- return { status: 500, body: {} };
173
- });
174
- // Register the close BEFORE any assertion runs — a listening server left
175
- // open by a thrown assertion keeps this test file's process alive forever
176
- // (see the CI-hang postmortem on rebuild-coalescer.test.ts).
177
- t.after(() => server.close());
178
- const source = new RemoteCanvasSource(server.url, 'tok');
179
- // The roster excludes the attached root because it is already identified by
180
- // the editor, leaving its one live child 'a'. The poisoned local node id is
181
- // 'a', so the load-bearing assertions target that rendered row.
182
- const { reports, reportIds } = await buildCanvasPanelLines('root', {}, IDENTITY_PALETTE, source);
183
- assert.deepEqual(reportIds, ['a'], 'roster omits the node already open in the editor');
184
- assert.equal(reports.length, 1);
185
- const line = reports[0];
186
- assert.ok(!line.includes('1000k'), `local telemetry (999999 tokens) must not leak into a remote row: ${line}`);
187
- assert.ok(!line.includes('POISON'), `poisoned local text must never appear in a remote row: ${line}`);
188
- assert.ok(!line.includes('⚠'), `a local active fault must not surface as the hanging glyph on a remote row: ${line}`);
189
- // A child's parent remains in the below-editor roster with an ↑ prefix, which
190
- // distinguishes it from the ↓ rows for reports.
191
- const childPanels = await buildCanvasPanelLines('a', {}, IDENTITY_PALETTE, source);
192
- assert.deepEqual(childPanels.reportIds, ['root']);
193
- assert.equal(childPanels.reports.length, 1);
194
- assert.match(childPanels.reports[0], /↑.*root/);
195
- assert.match(reports[0], /↓.*a/);
196
- });
197
- test('GraphOverlay suppresses every local-read adornment for a RemoteCanvasSource AND makes Enter/m/x no-ops, even with conflicting local state for the same node id', async (t) => {
198
- seedPoisonedLocalState();
199
- const rootMeta = meta('root');
200
- const aMeta = meta('a');
201
- const server = await startMockCrtrServer((args) => {
202
- if (args[1] === 'node' && args[2] === 'inspect' && args[3] === 'show') {
203
- const id = args[4];
204
- if (id === 'root')
205
- return { body: show(rootMeta, ['a'], []) };
206
- if (id === 'a')
207
- return { body: show(aMeta, [], ['root']) };
208
- }
209
- return { status: 500, body: {} };
210
- });
211
- // Register the close BEFORE any assertion runs — see the note above.
212
- t.after(() => server.close());
213
- const source = new RemoteCanvasSource(server.url, 'tok');
214
- const { tui } = fakeTui();
215
- const overlay = new GraphOverlay(tui, 'root', () => ({}), IDENTITY_PALETTE, resolveKeybindings(), source);
216
- overlay.open();
217
- // buildSnapshot() is async (chased through the mock server); poll for it to land.
218
- for (let i = 0; i < 100 && overlay.snapshot === undefined; i++) {
219
- await new Promise((r) => setImmediate(r));
220
- }
221
- assert.notEqual(overlay.snapshot, undefined, 'snapshot never built');
222
- const lines = overlay.render(100).join('\n');
223
- assert.ok(!lines.includes('1000k'), `local telemetry must not leak into the remote graph overlay: ${lines}`);
224
- assert.ok(!lines.includes('POISON'), `poisoned local text must never appear in the remote graph overlay: ${lines}`);
225
- assert.ok(!lines.includes('⚠'), `a local active fault must not surface as the hanging glyph in the remote graph overlay: ${lines}`);
226
- assert.ok(!lines.includes(BG_ATTACHED), `a local focus/attach must not paint a remote row as attached in the graph overlay: ${lines}`);
227
- // Footer hint must drop the focus/kill/mgr hints in remote mode.
228
- assert.ok(!lines.includes('kill'), `remote overlay footer must not advertise kill: ${lines}`);
229
- assert.ok(!lines.includes('focus') && !lines.includes('mgr'), `remote overlay footer must not advertise focus/mgr: ${lines}`);
230
- // Enter must NOT close the overlay (a local `close()` is the observable
231
- // effect of a real `focusTarget` dispatch) — it must no-op instead.
232
- overlay.handleInput('\r');
233
- assert.equal(overlay.isOpen(), true, 'Enter must not act (close) on a remote graph row');
234
- // x must NOT arm the close confirm on a remote row. The confirmation UI never
235
- // literally contains legacy `y/n`, so assert the real state directly:
236
- // pendingConfirm stays unset and no `kill …?` accept/cancel prompt renders.
237
- overlay.handleInput('x');
238
- assert.equal(overlay.pendingConfirm, undefined, 'x must not arm pendingConfirm on a remote graph row');
239
- const afterX = overlay.render(100).join('\n');
240
- assert.ok(!afterX.includes('kill'), `x must not surface a kill confirm prompt on a remote graph row: ${afterX}`);
241
- assert.ok(!/accept|cancel/.test(afterX), `x must not surface an accept/cancel confirm on a remote graph row: ${afterX}`);
242
- // m must NOT close the overlay either (it would focusTarget the manager).
243
- overlay.handleInput('m');
244
- assert.equal(overlay.isOpen(), true, 'm must not act (close) on a remote graph row');
245
- });
246
- // ---------------------------------------------------------------------------
247
- // Phase 3 review 2 — the ENCLOSING attach viewer (slash commands, pane tag,
248
- // detach-reap), not just the GraphOverlay/panel rendering
249
- // the fix above already covers. Same adversarial shape: seed colliding LOCAL
250
- // state for the remote node id `a`, then assert the remote path never touches
251
- // it — and, symmetrically, that the LOCAL path is byte-for-byte unchanged
252
- // (every guard below defaults to acting exactly as before when `remote` is
253
- // `false`).
254
- // ---------------------------------------------------------------------------
255
- function fakeSlashContext(remote, nodeId) {
256
- const notices = [];
257
- const sent = [];
258
- const ctx = {
259
- send: (frame) => sent.push(frame),
260
- notify: (m) => notices.push(m),
261
- cwd: '/tmp/does-not-matter',
262
- // Explicit empty string (not `undefined`) so promoteNode/openContext's
263
- // `ctx.nodeId ?? process.env['CRTR_NODE_ID']` fallback can NEVER pick up
264
- // this test process's own real CRTR_NODE_ID (this test runs INSIDE a live
265
- // crtr node) — the local-mode assertions below must reach the real
266
- // no-node-id early return, never an accidental real `crtr node promote`
267
- // against ourselves.
268
- nodeId: '',
269
- remote,
270
- };
271
- return { ctx, notices, sent };
272
- }
273
- test('slash autocomplete structurally omits local-only native canvas commands in remote mode and keeps them in local mode', () => {
274
- const remoteNames = slashCommandList(undefined, true).map((c) => c.name);
275
- assert.ok(!remoteNames.includes('promote'), `remote autocomplete must not offer /promote: ${remoteNames.join(',')}`);
276
- assert.ok(!remoteNames.includes('resume-node'), `remote autocomplete must not offer /resume-node: ${remoteNames.join(',')}`);
277
- assert.ok(!remoteNames.includes('context'), `remote autocomplete must not offer /context: ${remoteNames.join(',')}`);
278
- assert.ok(remoteNames.includes('graph'), 'remote autocomplete must still offer /graph');
279
- const localNames = slashCommandList().map((c) => c.name);
280
- for (const name of ['graph', 'promote', 'resume-node', 'context']) {
281
- assert.ok(localNames.includes(name), `local autocomplete must still offer /${name}: ${localNames.join(',')}`);
282
- }
283
- });
284
- test('dispatchSlashCommand no-ops /promote, /resume-node, /context in remote mode instead of shelling a local crtr command', () => {
285
- const { ctx, notices, sent } = fakeSlashContext(true, 'a');
286
- for (const cmd of ['/promote', '/resume-node', '/context', '/promote orchestrator']) {
287
- notices.length = 0;
288
- const handled = dispatchSlashCommand(cmd, ctx);
289
- assert.equal(handled, true, `${cmd} must be handled (native, never forwarded to the engine as a prompt)`);
290
- assert.equal(notices.length, 1, `${cmd} must notify exactly once (the remote-unsafe notice), got: ${JSON.stringify(notices)}`);
291
- assert.match(notices[0], /not available for a remote attach/, `${cmd} must notify the remote-unsafe message, not proceed into its local handler: ${notices[0]}`);
292
- }
293
- assert.equal(sent.length, 0, 'no command frame must ever be sent for a gated remote canvas command');
294
- // /graph is remote-safe via GraphOverlay's own `remote` handling.
295
- notices.length = 0;
296
- ctx.onGraph = () => notices.push('graph-toggled');
297
- dispatchSlashCommand('/graph', ctx);
298
- assert.deepEqual(notices, ['graph-toggled'], '/graph must still work normally in remote mode');
299
- });
300
- test('dispatchSlashCommand leaves the LOCAL (non-remote) path for /promote, /resume-node, /context byte-for-byte unchanged', () => {
301
- const { ctx, notices } = fakeSlashContext(false, '');
302
- // No TMUX in this test process (a headless `node --test` run), so
303
- // /resume-node and /context hit their OWN "needs tmux" notices — proving
304
- // dispatch reached their real local handlers, not our new remote gate.
305
- const savedTmux = process.env['TMUX'];
306
- const savedTmuxPane = process.env['TMUX_PANE'];
307
- delete process.env['TMUX'];
308
- delete process.env['TMUX_PANE'];
309
- try {
310
- notices.length = 0;
311
- dispatchSlashCommand('/promote', ctx);
312
- assert.deepEqual(notices, ['/promote: no node to promote (viewer has no node id)']);
313
- notices.length = 0;
314
- dispatchSlashCommand('/resume-node', ctx);
315
- assert.deepEqual(notices, ['/resume-node needs tmux']);
316
- notices.length = 0;
317
- dispatchSlashCommand('/context', ctx);
318
- assert.deepEqual(notices, ['/context needs tmux']);
319
- }
320
- finally {
321
- if (savedTmux !== undefined)
322
- process.env['TMUX'] = savedTmux;
323
- else
324
- delete process.env['TMUX'];
325
- if (savedTmuxPane !== undefined)
326
- process.env['TMUX_PANE'] = savedTmuxPane;
327
- else
328
- delete process.env['TMUX_PANE'];
329
- }
330
- });
331
- test('tagAttachPane/untagAttachPane never tag/untag the pane for a remote attach, and are unchanged for local', () => {
332
- let calls = [];
333
- const setOpt = (pane, name, value) => {
334
- calls.push([pane, name, value]);
335
- };
336
- calls = [];
337
- tagAttachPane(true, '%3', 'a', setOpt);
338
- assert.deepEqual(calls, [], 'remote must never tag the pane with @crtr_node');
339
- calls = [];
340
- tagAttachPane(false, '%3', 'a', setOpt);
341
- assert.deepEqual(calls, [['%3', '@crtr_node', 'a']], 'local tag must still fire unchanged');
342
- calls = [];
343
- untagAttachPane(true, '%3', setOpt);
344
- assert.deepEqual(calls, [], 'remote must never untag the pane');
345
- calls = [];
346
- untagAttachPane(false, '%3', setOpt);
347
- assert.deepEqual(calls, [['%3', '@crtr_node', '']], 'local untag must still fire unchanged');
348
- // No pane resolved (outside tmux) — unaffected either way.
349
- calls = [];
350
- tagAttachPane(false, undefined, 'a', setOpt);
351
- assert.deepEqual(calls, [], 'no pane to tag when outside tmux');
352
- });
353
- // ---------------------------------------------------------------------------
354
- // T3 — memory-ref inventory lifecycle/race (design: inline memory references,
355
- // terminal integration) and the input-layer whitespace-preservation contract.
356
- // ---------------------------------------------------------------------------
357
- test('createMemoryRefRefreshCoordinator: a stale reply from a superseded reset cannot overwrite a newer inventory, and malformed/rejected replies degrade to empty without throwing', async () => {
358
- const snapshots = [];
359
- const engineNameSnapshots = [];
360
- const setMemoryRefs = (refs, engineLeadingCommandNames) => {
361
- snapshots.push(refs);
362
- engineNameSnapshots.push(engineLeadingCommandNames);
363
- };
364
- const pending = [];
365
- const request = () => new Promise((resolve, reject) => { pending.push({ resolve, reject }); });
366
- const coordinator = createMemoryRefRefreshCoordinator(setMemoryRefs, request);
367
- const flush = async () => { await Promise.resolve(); await Promise.resolve(); };
368
- // First reset (e.g. the initial welcome) — clears synchronously, then waits
369
- // on its correlated request.
370
- coordinator.reset();
371
- assert.deepEqual(snapshots, [[]], 'first reset clears the inventory immediately');
372
- assert.deepEqual(engineNameSnapshots, [[]], 'the engine-command inventory clears alongside refs, synchronously');
373
- const firstRequest = pending[0];
374
- // A second reset — a reconnect's fresh welcome, or an explicit /reload —
375
- // supersedes it BEFORE the first reply lands: clears again and issues its
376
- // own request.
377
- coordinator.reset();
378
- assert.deepEqual(snapshots, [[], []], 'a superseding reset clears the inventory again immediately');
379
- const secondRequest = pending[1];
380
- // The SECOND (latest) request resolves first — its refs AND engine-command
381
- // names must both be installed (Major 6 — broker's `engineLeadingCommandNames`
382
- // propagates through the coordinator alongside `refs`, not just `refs` alone).
383
- const latestRefs = [{ name: 'dev', kind: 'knowledge', scope: 'project', shortForm: 'dev docs' }];
384
- const latestEngineNames = ['reload'];
385
- secondRequest.resolve({
386
- type: 'data',
387
- id: 'latest',
388
- kind: 'list_memory_refs',
389
- refs: latestRefs,
390
- engineLeadingCommandNames: latestEngineNames,
391
- });
392
- await flush();
393
- assert.deepEqual(snapshots.at(-1), latestRefs, 'the latest reset\'s reply installs its refs');
394
- assert.deepEqual(engineNameSnapshots.at(-1), latestEngineNames, 'the latest reset\'s reply installs its engine-command names');
395
- // The FIRST (now-stale) request's reply arrives late — it must be dropped,
396
- // never overwriting the newer inventory the second reset already installed.
397
- const staleRefs = [{ name: 'stale', kind: 'knowledge', scope: 'project', shortForm: 'stale' }];
398
- firstRequest.resolve({ type: 'data', id: 'stale', kind: 'list_memory_refs', refs: staleRefs, engineLeadingCommandNames: ['stale-cmd'] });
399
- await flush();
400
- assert.equal(snapshots.length, 3, 'a stale reply from a superseded reset must never install refs');
401
- assert.deepEqual(snapshots.at(-1), latestRefs, 'the newer inventory must survive a late stale reply');
402
- assert.deepEqual(engineNameSnapshots.at(-1), latestEngineNames, 'the newer engine-command inventory must survive a late stale reply too');
403
- // A malformed reply (wrong `kind`) degrades to the already-empty inventory.
404
- coordinator.reset();
405
- const thirdRequest = pending[2];
406
- thirdRequest.resolve({ type: 'data', id: 'malformed', kind: 'dequeue', steering: [], followUp: [] });
407
- await flush();
408
- assert.deepEqual(snapshots.at(-1), [], 'a malformed-kind reply must never install refs');
409
- assert.deepEqual(engineNameSnapshots.at(-1), [], 'a malformed-kind reply must never install engine-command names');
410
- // A rejected request (timeout) degrades silently too — no retry, no throw.
411
- coordinator.reset();
412
- const fourthRequest = pending[3];
413
- fourthRequest.reject(new Error('request timed out'));
414
- await flush();
415
- assert.deepEqual(snapshots.at(-1), [], 'a rejected request must never throw and must stay empty');
416
- assert.deepEqual(engineNameSnapshots.at(-1), [], 'a rejected request must never throw and engine-command names must stay empty');
417
- });
418
- test('InputController.handleSubmit sends the prompt frame with the exact typed leading/trailing whitespace, even though emptiness/slash classification uses a trimmed view', () => {
419
- const sent = [];
420
- const fakeEditor = {
421
- onSubmit: undefined,
422
- onEscape: undefined,
423
- onPasteImage: undefined,
424
- onPasteImagePath: undefined,
425
- onAction: () => { },
426
- addToHistory: () => { },
427
- setText: () => { },
428
- getText: () => '',
429
- insertTextAtCursor: () => { },
430
- };
431
- new InputController({}, fakeEditor, { matches: () => false }, { onCommand: (frame) => sent.push(frame), onDialogResponse: () => { } });
432
- fakeEditor.onSubmit(' hello world ');
433
- assert.deepEqual(sent, [{ type: 'prompt', text: ' hello world ' }], 'the sent prompt frame must keep the human\'s exact leading/trailing whitespace');
434
- // Emptiness classification reads the TRIMMED view — whitespace-only input
435
- // must never submit a frame.
436
- sent.length = 0;
437
- fakeEditor.onSubmit(' \n ');
438
- assert.deepEqual(sent, [], 'a whitespace-only submit must not send a frame');
439
- });
@@ -1,170 +0,0 @@
1
- import test from 'node:test';
2
- import assert from 'node:assert/strict';
3
- import { decodeAttachControlInput, encodeAttachControlInput, extractAttachControlInput, resolveKeybindings, } from '../../../core/keybindings/index.js';
4
- import { detachHint, inboxOpenHint, dispatchAttachAction, dispatchAttachBinding, matchesAttachBinding, refreshAttachBindingSnapshot, } from '../session/bindings.js';
5
- import { GraphOverlay } from '../overlays/graph.js';
6
- const PALETTE = {
7
- accent: (s) => s,
8
- active: (s) => s,
9
- info: (s) => s,
10
- muted: (s) => s,
11
- faint: (s) => s,
12
- border: (s) => s,
13
- bold: (s) => s,
14
- error: (s) => s,
15
- warning: (s) => s,
16
- diffAdded: (s) => s,
17
- diffRemoved: (s) => s,
18
- bashMode: (s) => s,
19
- bashModeAlt: (s) => s,
20
- surface: (s) => s,
21
- };
22
- function fakeTui() {
23
- return {
24
- showOverlay: () => ({ hide: () => { } }),
25
- requestRender: () => { },
26
- };
27
- }
28
- test('attach direct and private control input dispatch through the same action map', () => {
29
- const bindings = resolveKeybindings({
30
- 'crtr.attach.detach': ['ctrl+x'],
31
- 'crtr.attach.clear-or-detach': [],
32
- 'crtr.attach.graph.toggle': [],
33
- 'crtr.attach.help.toggle': ['alt+shift+k'],
34
- 'crtr.attach.inbox.toggle': [],
35
- 'crtr.attach.model-ladder.next': ['alt+z'],
36
- 'crtr.attach.model-ladder.previous': ['alt+y'],
37
- 'crtr.attach.command.inspect': ['alt+shift+h'],
38
- 'crtr.attach.file-review': [],
39
- 'crtr.attach.profile-files': [],
40
- 'crtr.attach.whip': [],
41
- });
42
- const calls = [];
43
- const actions = {
44
- 'crtr.attach.detach': () => calls.push('detach'),
45
- 'crtr.attach.clear-or-detach': () => calls.push('clear'),
46
- 'crtr.attach.graph.toggle': () => calls.push('graph'),
47
- 'crtr.attach.help.toggle': () => calls.push('help'),
48
- 'crtr.attach.inbox.toggle': () => calls.push('inbox'),
49
- 'crtr.attach.model-ladder.next': () => calls.push('ladder'),
50
- 'crtr.attach.model-ladder.previous': () => calls.push('ladder-back'),
51
- 'crtr.attach.command.inspect': () => calls.push('inspect'),
52
- 'crtr.attach.file-review': () => calls.push('review'),
53
- 'crtr.attach.profile-files': () => calls.push('profile-files'),
54
- 'crtr.attach.whip': () => calls.push('whip'),
55
- };
56
- assert.equal(dispatchAttachBinding(bindings, '\x18', actions), true);
57
- assert.equal(dispatchAttachBinding(bindings, '\x04', actions), false, 'old detach must not reach the listener action');
58
- assert.equal(dispatchAttachBinding(bindings, '\x1bg', actions), false, 'disabled graph must not reach the listener action');
59
- assert.equal(dispatchAttachBinding(bindings, '\x1bx', actions), false, 'removed mode key must stay ordinary input');
60
- assert.equal(dispatchAttachBinding(bindings, '\x1bP', actions), false, 'removed mode key must stay ordinary input');
61
- assert.equal(dispatchAttachBinding(bindings, '\x1bz', actions), true);
62
- assert.equal(dispatchAttachBinding(bindings, '\x1bm', actions), false, 'old ladder key must not reach the listener action');
63
- assert.equal(dispatchAttachBinding(bindings, '\x1by', actions), true);
64
- assert.equal(dispatchAttachBinding(bindings, '\x1bM', actions), false, 'old ladder-back key must not reach the listener action');
65
- assert.equal(dispatchAttachBinding(bindings, '\x1b[72;4u', actions), true);
66
- assert.equal(dispatchAttachBinding(bindings, '\x1b[75;4u', actions), true);
67
- assert.equal(dispatchAttachBinding(bindings, '\x06', actions), false, 'disabled direct binding must stay disabled');
68
- const privateInput = encodeAttachControlInput('crtr.attach.profile-files');
69
- const privateAction = decodeAttachControlInput(privateInput);
70
- assert.equal(privateAction, 'crtr.attach.profile-files');
71
- dispatchAttachAction(privateAction, actions);
72
- const helpPrivateInput = encodeAttachControlInput('crtr.attach.help.toggle');
73
- assert.equal(decodeAttachControlInput(helpPrivateInput), 'crtr.attach.help.toggle');
74
- dispatchAttachAction('crtr.attach.help.toggle', actions);
75
- assert.deepEqual(calls, ['detach', 'ladder', 'ladder-back', 'inspect', 'help', 'profile-files', 'help']);
76
- assert.equal(decodeAttachControlInput(`${privateInput}x`), undefined, 'whole-input decoding must be exact');
77
- assert.equal(decodeAttachControlInput('\x1b_crtr;crtr.attach.not-real\x1b\\'), undefined, 'unknown actions must stay ordinary input');
78
- assert.deepEqual(extractAttachControlInput(`before${privateInput}after`), {
79
- actionId: 'crtr.attach.profile-files',
80
- remaining: 'beforeafter',
81
- });
82
- assert.equal(detachHint(bindings), 'Ctrl+X', 'disabled clear-or-detach must fall back to enabled detach');
83
- const noDetach = resolveKeybindings({ 'crtr.attach.detach': [], 'crtr.attach.clear-or-detach': [] });
84
- assert.equal(detachHint(noDetach), undefined, 'a disabled pair must not render "Disabled to detach"');
85
- });
86
- test('closed-inbox footer hint resolves the configured inbox shortcut(s)', () => {
87
- // Default: alt+i renders as the configured shortcut plus 'inbox'.
88
- assert.equal(inboxOpenHint(resolveKeybindings()), 'Alt+I inbox');
89
- // Custom single key.
90
- assert.equal(inboxOpenHint(resolveKeybindings({ 'crtr.tmux.inbox.toggle': ['alt+j'] })), 'Alt+J inbox');
91
- // Multiple gestures join with ' / ' (crouter's formatBinding convention).
92
- assert.equal(inboxOpenHint(resolveKeybindings({ 'crtr.tmux.inbox.toggle': ['alt+i', 'alt+j'] })), 'Alt+I / Alt+J inbox');
93
- // Disabled: omit the shortcut clause and fall back to the CLI affordance,
94
- // never render the word "Disabled".
95
- const disabled = inboxOpenHint(resolveKeybindings({ 'crtr.tmux.inbox.toggle': [] }));
96
- assert.equal(disabled, 'crtr human list');
97
- assert.doesNotMatch(disabled, /Disabled/);
98
- });
99
- test('attach startup and reload replace the dispatch/GRAPH snapshots and install each complete tmux snapshot', () => {
100
- const first = resolveKeybindings({ 'crtr.attach.detach': ['ctrl+x'], 'crtr.graph.focus': ['f'] });
101
- const second = resolveKeybindings({
102
- 'crtr.attach.detach': ['ctrl+z'],
103
- 'crtr.graph.focus': ['r'],
104
- 'crtr.graph.revive': [],
105
- });
106
- const settings = [
107
- { bindings: first, tmuxPassthrough: ['crtr.attach.detach'] },
108
- { bindings: second, tmuxPassthrough: ['crtr.attach.copy.message'] },
109
- ];
110
- const graphSnapshots = [];
111
- const installed = [];
112
- let active = refreshAttachBindingSnapshot(() => settings.shift(), (bindings) => graphSnapshots.push(bindings), () => true, (bindings, tmuxPassthrough) => installed.push({ bindings, tmuxPassthrough }));
113
- assert.equal(matchesAttachBinding(active.bindings, 'crtr.attach.detach', '\x18'), true, 'startup snapshot drives attach dispatch');
114
- assert.equal(active.bindings.gestures('crtr.graph.focus')[0], 'f', 'startup snapshot reaches GRAPH');
115
- active = refreshAttachBindingSnapshot(() => settings.shift(), (bindings) => graphSnapshots.push(bindings), () => true, (bindings, tmuxPassthrough) => installed.push({ bindings, tmuxPassthrough }));
116
- assert.equal(matchesAttachBinding(active.bindings, 'crtr.attach.detach', '\x18'), false, 'reload replaces the old attach snapshot');
117
- assert.equal(matchesAttachBinding(active.bindings, 'crtr.attach.detach', '\x1a'), true, 'reload dispatches through the new attach snapshot');
118
- assert.equal(active.bindings.gestures('crtr.graph.focus')[0], 'r', 'reload replaces GRAPH bindings too');
119
- assert.deepEqual(graphSnapshots, [first, second]);
120
- assert.deepEqual(installed, [
121
- { bindings: first, tmuxPassthrough: ['crtr.attach.detach'] },
122
- { bindings: second, tmuxPassthrough: ['crtr.attach.copy.message'] },
123
- ], 'the unified tmux installer receives startup and reload settings snapshots');
124
- });
125
- test('GRAPH navigation and hints use effective bindings rather than default literals', () => {
126
- const bindings = resolveKeybindings({
127
- 'crtr.graph.down': ['z'],
128
- 'crtr.graph.up': [],
129
- 'crtr.graph.focus': ['f'],
130
- 'crtr.graph.close-subtree': [],
131
- 'crtr.graph.dismiss': ['q'],
132
- 'crtr.graph.confirm.accept': ['t'],
133
- 'crtr.graph.confirm.cancel': ['c'],
134
- });
135
- const overlay = new GraphOverlay(fakeTui(), 'a', () => ({}), PALETTE, bindings, {});
136
- const internal = overlay;
137
- internal.cursorId = 'a';
138
- internal.snapshot = {
139
- rows: [
140
- { id: 'a', hasKids: false, isSelf: true, branch: '', cycle: false, collapsed: false },
141
- { id: 'b', hasKids: false, isSelf: false, branch: '', cycle: false, collapsed: false },
142
- ],
143
- activeBelow: new Map(),
144
- nodes: new Map([['a', null], ['b', null]]),
145
- childIds: new Map(),
146
- sortedChildIds: new Map(),
147
- managerOf: new Map(),
148
- focused: new Set(),
149
- };
150
- overlay.handleInput('j');
151
- assert.equal(internal.cursorId, 'a', 'replaced default must stop matching');
152
- overlay.handleInput('z');
153
- assert.equal(internal.cursorId, 'b', 'replacement must drive navigation');
154
- const rendered = overlay.render(58).join('\n');
155
- // Bare printable keys render exactly as they must be typed (lowercase),
156
- // never uppercased into a shift chord the matcher would reject.
157
- assert.match(rendered, /f focus/, 'narrow GRAPH footer must prioritize remapped local focus');
158
- assert.match(rendered, /q dismiss/, 'narrow GRAPH footer must prioritize remapped dismiss');
159
- assert.doesNotMatch(rendered, /close/);
160
- assert.doesNotMatch(rendered, /j down/);
161
- assert.doesNotMatch(rendered, /Disabled/);
162
- let closed = 0;
163
- internal.pendingConfirm = { label: 'close b?', action: () => { closed++; } };
164
- assert.match(overlay.render(80).join('\n'), /t accept · c cancel/);
165
- overlay.handleInput('y');
166
- assert.equal(closed, 0, 'replaced accept default must stop confirming');
167
- internal.pendingConfirm = { label: 'close b?', action: () => { closed++; } };
168
- overlay.handleInput('t');
169
- assert.equal(closed, 1, 'replacement must confirm close');
170
- });