@north-light/crouter 0.3.173 → 0.3.175

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (674) hide show
  1. package/bin/runtime-selector.mjs +8 -1
  2. package/dist/api/__tests__/{client.test.js → serial/client.test.js} +2 -135
  3. package/dist/api/client.d.ts +12 -21
  4. package/dist/api/client.js +22 -31
  5. package/dist/api/dto/broker-ops.d.ts +158 -0
  6. package/dist/api/dto/broker-ops.js +6 -0
  7. package/dist/api/dto/crons.d.ts +6 -0
  8. package/dist/api/dto/human.d.ts +7 -1
  9. package/dist/api/dto/inbox.d.ts +1 -71
  10. package/dist/api/dto/inbox.js +1 -9
  11. package/dist/api/dto/nodes.d.ts +6 -7
  12. package/dist/api/dto/reviews.d.ts +1 -11
  13. package/dist/api/routes.d.ts +7 -4
  14. package/dist/api/routes.js +8 -5
  15. package/dist/build-root.js +3 -3
  16. package/dist/builtin-memory/04-base-worker.md +1 -4
  17. package/dist/builtin-memory/05-kinds/advisor/00-base.md +1 -5
  18. package/dist/builtin-memory/05-kinds/advisor/01-orchestrator.md +2 -7
  19. package/dist/builtin-memory/05-kinds/design/00-base.md +1 -6
  20. package/dist/builtin-memory/05-kinds/developer/00-base.md +1 -6
  21. package/dist/builtin-memory/05-kinds/explore/00-base.md +1 -4
  22. package/dist/builtin-memory/05-kinds/explore/01-orchestrator.md +1 -2
  23. package/dist/builtin-memory/05-kinds/general/00-base.md +1 -3
  24. package/dist/builtin-memory/05-kinds/plan/00-base.md +1 -6
  25. package/dist/builtin-memory/05-kinds/plan/reviewers/00-base.md +1 -2
  26. package/dist/builtin-memory/05-kinds/plan/reviewers/architecture-fit.md +1 -3
  27. package/dist/builtin-memory/05-kinds/plan/reviewers/code-smells.md +1 -3
  28. package/dist/builtin-memory/05-kinds/plan/reviewers/pattern-consistency.md +1 -3
  29. package/dist/builtin-memory/05-kinds/plan/reviewers/requirements-coverage.md +1 -3
  30. package/dist/builtin-memory/05-kinds/plan/reviewers/security.md +1 -4
  31. package/dist/builtin-memory/05-kinds/review/companion/00-base.md +2 -3
  32. package/dist/builtin-memory/05-kinds/spec/00-base.md +1 -2
  33. package/dist/builtin-memory/advisor/council.md +1 -6
  34. package/dist/builtin-memory/design.md +2 -7
  35. package/dist/builtin-memory/development.md +9 -14
  36. package/dist/builtin-memory/internal/marketplaces.md +2 -6
  37. package/dist/builtin-memory/internal/nodes-and-canvas.md +1 -1
  38. package/dist/builtin-memory/internal/plugins.md +2 -8
  39. package/dist/builtin-memory/internal/storage-tiers.md +1 -2
  40. package/dist/builtin-memory/testing.md +41 -0
  41. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/__tests__/{provider-rotation.test.ts → serial/provider-rotation.test.ts} +27 -179
  42. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/claude-plugin-commands.ts +5 -15
  43. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/frontmatter-rules/index.ts +1 -28
  44. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/memory-slash-commands.ts +43 -88
  45. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.js +7 -1
  46. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.ts +9 -1
  47. package/dist/cli.js +2 -2
  48. package/dist/clients/attach/__tests__/attach-remote-readonly.test.js +37 -131
  49. package/dist/clients/attach/__tests__/chat-view-snapshot-ordering.test.js +71 -152
  50. package/dist/clients/attach/__tests__/context-message.test.js +16 -174
  51. package/dist/clients/attach/__tests__/crtr-output.test.js +36 -2069
  52. package/dist/clients/attach/__tests__/diagram.test.js +2 -2
  53. package/dist/clients/attach/__tests__/edit-diff.test.js +0 -4
  54. package/dist/clients/attach/__tests__/file-review-focus.test.js +2 -1
  55. package/dist/clients/attach/__tests__/group-activity.test.js +40 -229
  56. package/dist/clients/attach/__tests__/oauth-dialog-lifecycle.test.js +26 -76
  57. package/dist/clients/attach/__tests__/prompt-preview.test.js +4 -70
  58. package/dist/clients/attach/__tests__/ref-autocomplete.test.js +11 -125
  59. package/dist/clients/attach/__tests__/titled-editor-preview.test.js +14 -205
  60. package/dist/clients/attach/command.d.ts +2 -1
  61. package/dist/clients/attach/command.js +81 -76
  62. package/dist/clients/attach/input/capabilities.d.ts +27 -0
  63. package/dist/clients/attach/input/capabilities.js +96 -0
  64. package/dist/clients/attach/input/controller.d.ts +20 -182
  65. package/dist/clients/attach/input/controller.js +128 -537
  66. package/dist/clients/attach/input/overlay-owner.d.ts +41 -0
  67. package/dist/clients/attach/input/overlay-owner.js +199 -0
  68. package/dist/clients/attach/overlays/file-review.d.ts +0 -4
  69. package/dist/clients/attach/overlays/file-review.js +13 -5
  70. package/dist/clients/attach/overlays/graph.js +2 -10
  71. package/dist/clients/attach/render/chat-view.d.ts +4 -3
  72. package/dist/clients/attach/render/chat-view.js +39 -33
  73. package/dist/clients/attach/render/group-activity.d.ts +1 -0
  74. package/dist/clients/attach/render/group-activity.js +20 -13
  75. package/dist/clients/attach/render/group-recap.js +12 -3
  76. package/dist/clients/attach/session/connection.js +9 -15
  77. package/dist/clients/attach/session/editor-inventory.d.ts +6 -5
  78. package/dist/clients/attach/session/editor-inventory.js +7 -8
  79. package/dist/clients/attach/session/file-links.d.ts +13 -0
  80. package/dist/clients/attach/session/file-links.js +107 -0
  81. package/dist/clients/attach/session/frame.d.ts +3 -0
  82. package/dist/clients/attach/session/frame.js +10 -1
  83. package/dist/clients/attach/session/frames.js +2 -3
  84. package/dist/clients/attach/session/input-wiring.d.ts +4 -1
  85. package/dist/clients/attach/session/input-wiring.js +15 -14
  86. package/dist/clients/attach/session/mouse.d.ts +6 -1
  87. package/dist/clients/attach/session/mouse.js +8 -5
  88. package/dist/clients/attach/session/profile-files.js +18 -12
  89. package/dist/clients/attach/session/reconnect.js +1 -1
  90. package/dist/clients/attach/session/state-sync.js +1 -2
  91. package/dist/clients/attach/session/surface-host.d.ts +3 -2
  92. package/dist/clients/attach/session/surface-host.js +4 -4
  93. package/dist/clients/attach/slash/dispatch.d.ts +8 -31
  94. package/dist/clients/attach/slash/dispatch.js +34 -81
  95. package/dist/clients/attach/viewer.js +820 -860
  96. package/dist/clients/conversation/projection.d.ts +79 -0
  97. package/dist/clients/conversation/projection.js +341 -0
  98. package/dist/clients/inbox/__tests__/serial/inbox-controller.test.js +159 -0
  99. package/dist/clients/inbox/__tests__/serial/mount-panel.test.js +151 -0
  100. package/dist/clients/inbox/controller.d.ts +0 -4
  101. package/dist/clients/inbox/controller.js +0 -2
  102. package/dist/clients/inbox/review/__tests__/review-core.test.js +4 -293
  103. package/dist/clients/inbox/review/__tests__/teardown-notice.test.js +100 -0
  104. package/dist/clients/inbox/review/comments-client.d.ts +3 -2
  105. package/dist/clients/inbox/review/comments-client.js +12 -12
  106. package/dist/clients/inbox/review/companion-pane.d.ts +30 -0
  107. package/dist/clients/inbox/review/companion-pane.js +86 -0
  108. package/dist/clients/inbox/review/document-surface.d.ts +182 -0
  109. package/dist/clients/inbox/review/{document-region.js → document-surface.js} +252 -48
  110. package/dist/clients/inbox/review/frame.js +5 -4
  111. package/dist/clients/inbox/review/launch.d.ts +8 -8
  112. package/dist/clients/inbox/review/launch.js +52 -92
  113. package/dist/clients/inbox/review/nvim.d.ts +2 -0
  114. package/dist/clients/inbox/review/nvim.js +14 -12
  115. package/dist/clients/inbox/review/review-client.d.ts +12 -8
  116. package/dist/clients/inbox/review/review-client.js +46 -35
  117. package/dist/clients/inbox/review-adapter.d.ts +3 -10
  118. package/dist/clients/inbox/review-adapter.js +27 -19
  119. package/dist/clients/inbox/surface.d.ts +0 -4
  120. package/dist/clients/inbox/surface.js +0 -2
  121. package/dist/clients/surfaces/host.d.ts +11 -3
  122. package/dist/commands/__tests__/api-client-cold-start-diagnostic.test.js +7 -34
  123. package/dist/commands/__tests__/human.test.js +11 -322
  124. package/dist/commands/api-client.d.ts +5 -5
  125. package/dist/commands/api-client.js +6 -85
  126. package/dist/commands/canvas-browse.js +3 -29
  127. package/dist/commands/canvas-config.js +1 -1
  128. package/dist/commands/canvas-use.js +3 -3
  129. package/dist/commands/canvas.js +1 -1
  130. package/dist/commands/cron.js +5 -1
  131. package/dist/commands/human/queue.d.ts +0 -4
  132. package/dist/commands/human/queue.js +7 -40
  133. package/dist/commands/memory/list.d.ts +14 -0
  134. package/dist/commands/memory/list.js +35 -31
  135. package/dist/commands/memory/read.d.ts +7 -0
  136. package/dist/commands/memory/read.js +14 -8
  137. package/dist/commands/memory/write.js +13 -12
  138. package/dist/commands/node/bash.d.ts +1 -0
  139. package/dist/commands/node/bash.js +198 -0
  140. package/dist/commands/node/create.d.ts +23 -0
  141. package/dist/commands/node/create.js +207 -0
  142. package/dist/commands/node/inspect.d.ts +2 -0
  143. package/dist/commands/node/inspect.js +302 -0
  144. package/dist/commands/node/lifecycle.d.ts +4 -0
  145. package/dist/commands/node/lifecycle.js +415 -0
  146. package/dist/commands/node/message.d.ts +1 -0
  147. package/dist/commands/node/message.js +164 -0
  148. package/dist/commands/node/pyramid.d.ts +2 -0
  149. package/dist/commands/node/pyramid.js +79 -0
  150. package/dist/commands/node/subscription.d.ts +1 -0
  151. package/dist/commands/node/subscription.js +82 -0
  152. package/dist/commands/node/wait.d.ts +1 -0
  153. package/dist/commands/node/wait.js +159 -0
  154. package/dist/commands/node-lifecycle-revive.js +10 -57
  155. package/dist/commands/node.d.ts +0 -42
  156. package/dist/commands/node.js +11 -2065
  157. package/dist/commands/search.js +1 -1
  158. package/dist/commands/surface/node/cycle.d.ts +1 -0
  159. package/dist/commands/surface/node/cycle.js +83 -0
  160. package/dist/commands/surface/node/focus.d.ts +1 -0
  161. package/dist/commands/surface/node/focus.js +67 -0
  162. package/dist/commands/surface/node/id.d.ts +1 -0
  163. package/dist/commands/surface/node/id.js +38 -0
  164. package/dist/commands/surface/node/pin.d.ts +1 -0
  165. package/dist/commands/surface/node/pin.js +42 -0
  166. package/dist/commands/surface/node/placement.d.ts +46 -0
  167. package/dist/commands/surface/node/placement.js +124 -0
  168. package/dist/commands/surface-node.js +4 -1
  169. package/dist/commands/surface-reload.js +1 -2
  170. package/dist/commands/surface-tmux-spread.js +1 -1
  171. package/dist/commands/surface.js +5 -20
  172. package/dist/commands/sys/__tests__/setup-core.test.js +18 -271
  173. package/dist/commands/sys/config.js +6 -6
  174. package/dist/commands/sys/logs.js +1 -1
  175. package/dist/commands/sys/panels/broker-limits-panel.d.ts +17 -0
  176. package/dist/commands/sys/panels/broker-limits-panel.js +104 -0
  177. package/dist/commands/sys/panels/dependencies-panel.d.ts +14 -0
  178. package/dist/commands/sys/panels/dependencies-panel.js +80 -0
  179. package/dist/commands/sys/panels/keybindings-panel.d.ts +56 -0
  180. package/dist/commands/sys/panels/keybindings-panel.js +703 -0
  181. package/dist/commands/sys/panels/keys-panel.d.ts +16 -0
  182. package/dist/commands/sys/panels/keys-panel.js +60 -0
  183. package/dist/commands/sys/panels/models-panel.d.ts +77 -0
  184. package/dist/commands/sys/panels/models-panel.js +647 -0
  185. package/dist/commands/sys/panels/panel.d.ts +45 -0
  186. package/dist/commands/sys/panels/panel.js +137 -0
  187. package/dist/commands/sys/panels/plugins-panel.d.ts +16 -0
  188. package/dist/commands/sys/panels/plugins-panel.js +80 -0
  189. package/dist/commands/sys/panels/prefs-panel.d.ts +21 -0
  190. package/dist/commands/sys/panels/prefs-panel.js +85 -0
  191. package/dist/commands/sys/panels/provider-panel.d.ts +62 -0
  192. package/dist/commands/sys/panels/provider-panel.js +538 -0
  193. package/dist/commands/sys/settings-shell.d.ts +55 -0
  194. package/dist/commands/sys/settings-shell.js +400 -0
  195. package/dist/commands/sys/settings.d.ts +2 -0
  196. package/dist/commands/sys/settings.js +31 -0
  197. package/dist/commands/sys/setup-core.d.ts +3 -33
  198. package/dist/commands/sys/setup-core.js +27 -78
  199. package/dist/commands/sys/setup-settings-runner.d.ts +24 -0
  200. package/dist/commands/sys/setup-settings-runner.js +63 -0
  201. package/dist/commands/sys/setup-wizard.d.ts +26 -125
  202. package/dist/commands/sys/setup-wizard.js +209 -2473
  203. package/dist/commands/sys/setup.js +5 -7
  204. package/dist/commands/sys.js +3 -2
  205. package/dist/core/__tests__/broker-extension-canvas-db-boundary.test.js +50 -0
  206. package/dist/core/__tests__/broker-launch-candidates.test.js +20 -9
  207. package/dist/core/__tests__/broker-preflight.test.js +1 -1
  208. package/dist/core/__tests__/canvas-inbox-watcher-hold.test.js +108 -27
  209. package/dist/core/__tests__/canvas-inbox-watcher.test.js +14 -0
  210. package/dist/core/__tests__/canvas.test.js +2 -36
  211. package/dist/core/__tests__/close.test.js +14 -3
  212. package/dist/core/__tests__/context-intro.test.js +32 -143
  213. package/dist/core/__tests__/cron-broker-capacity.test.js +22 -3
  214. package/dist/core/__tests__/daemon-boot.test.js +2 -20
  215. package/dist/core/__tests__/daemon-wedge.test.js +1 -1
  216. package/dist/core/__tests__/dead-node-policy-table.test.js +1 -18
  217. package/dist/core/__tests__/fixtures/fake-engine.d.ts +1 -1
  218. package/dist/core/__tests__/fixtures/fake-engine.js +2 -2
  219. package/dist/core/__tests__/fixtures/fake-pi-host.js +2 -2
  220. package/dist/core/__tests__/focuses.test.js +4 -98
  221. package/dist/core/__tests__/helpers/broker-clients.d.ts +0 -3
  222. package/dist/core/__tests__/helpers/broker-clients.js +0 -14
  223. package/dist/core/__tests__/helpers/harness.d.ts +0 -8
  224. package/dist/core/__tests__/helpers/harness.js +7 -87
  225. package/dist/core/__tests__/helpers/viewer-panes.js +1 -1
  226. package/dist/core/__tests__/inline-memory-refs.test.js +5 -134
  227. package/dist/core/__tests__/kickoff.test.js +1 -1
  228. package/dist/core/__tests__/memory-resolver-precedence.test.js +29 -1
  229. package/dist/core/__tests__/migration.test.js +35 -48
  230. package/dist/core/__tests__/on-read-dedup-resume.test.js +22 -12
  231. package/dist/core/__tests__/passive-subscription.test.js +26 -49
  232. package/dist/core/__tests__/preview-registry-sync.test.js +1 -2
  233. package/dist/core/__tests__/prune.test.js +94 -1
  234. package/dist/core/__tests__/review-model-floor.test.js +0 -32
  235. package/dist/core/__tests__/seam/broker-attach-multiclient.test.js +255 -0
  236. package/dist/core/__tests__/{full → seam}/broker-attach-stream.test.js +39 -7
  237. package/dist/core/__tests__/{full → seam}/broker-crash-teardown.test.js +30 -29
  238. package/dist/core/__tests__/{full → seam}/broker-pane-resolution.test.js +54 -5
  239. package/dist/core/__tests__/{full → seam}/broker-provider-retry.test.js +134 -82
  240. package/dist/core/__tests__/{full → seam}/broker-whip-interrupt.test.js +15 -4
  241. package/dist/core/__tests__/{full/idle-release-settlement.test.js → seam/dormancy-release.test.js} +69 -17
  242. package/dist/core/__tests__/{full/yield-message-transaction.test.js → seam/yield-refresh-transaction.test.js} +31 -9
  243. package/dist/core/__tests__/secrets.test.js +1 -7
  244. package/dist/core/__tests__/{broker-fork-seam.test.js → serial/broker-fork-seam.test.js} +58 -7
  245. package/dist/core/__tests__/{broker-sdk-wiring.test.js → serial/broker-sdk-wiring.test.js} +18 -162
  246. package/dist/core/__tests__/{broker-snapshot-history.test.js → serial/broker-snapshot-history.test.js} +9 -9
  247. package/dist/core/__tests__/{command-plugins.test.js → serial/command-plugins.test.js} +105 -15
  248. package/dist/core/__tests__/{deferred-no-wake.test.js → serial/deferred-no-wake.test.js} +23 -20
  249. package/dist/core/__tests__/{flagship-lifecycle.test.js → serial/flagship-lifecycle.test.js} +7 -7
  250. package/dist/core/__tests__/{host-teardown-process-group.test.js → serial/host-teardown-process-group.test.js} +6 -6
  251. package/dist/core/__tests__/{human-deliver-e2e.test.js → serial/human-deliver-e2e.test.js} +12 -12
  252. package/dist/core/__tests__/{live-mutation.test.js → serial/live-mutation.test.js} +5 -5
  253. package/dist/core/__tests__/{refresh-stall-recycle.test.js → serial/refresh-stall-recycle.test.js} +5 -14
  254. package/dist/core/__tests__/{revive.test.js → serial/revive.test.js} +15 -100
  255. package/dist/core/__tests__/{spawn-root.test.js → serial/spawn-root.test.js} +32 -15
  256. package/dist/core/__tests__/serial/subscription-delivery.test.js +126 -0
  257. package/dist/core/__tests__/serial/tmux-surface.test.js +256 -0
  258. package/dist/core/__tests__/{worktree.test.js → serial/worktree.test.js} +15 -15
  259. package/dist/core/__tests__/session-model.test.js +0 -18
  260. package/dist/core/__tests__/spawn-worktree-id-conflict.test.js +9 -0
  261. package/dist/core/__tests__/watchdog-abort-arms-retry.test.js +50 -0
  262. package/dist/core/broker-client/__tests__/transport-relay.test.js +15 -16
  263. package/dist/core/broker-client/__tests__/transport-socket.test.js +28 -0
  264. package/dist/core/broker-client/client.d.ts +2 -2
  265. package/dist/core/broker-client/client.js +4 -7
  266. package/dist/core/broker-client/transport-relay.d.ts +13 -19
  267. package/dist/core/broker-client/transport-relay.js +19 -34
  268. package/dist/core/broker-client/transport-socket.d.ts +2 -2
  269. package/dist/core/broker-client/transport-socket.js +9 -2
  270. package/dist/core/broker-client/transport.d.ts +7 -3
  271. package/dist/core/broker-client/transport.js +4 -4
  272. package/dist/core/canvas/__tests__/attention.test.js +1 -18
  273. package/dist/core/canvas/__tests__/remote-canvas-source.test.js +7 -64
  274. package/dist/core/canvas/__tests__/remote-transport.test.js +2 -3
  275. package/dist/core/canvas/__tests__/render-remote.test.js +7 -52
  276. package/dist/core/canvas/browse/app.d.ts +2 -17
  277. package/dist/core/canvas/browse/app.js +16 -88
  278. package/dist/core/canvas/browse/model.d.ts +0 -4
  279. package/dist/core/canvas/browse/model.js +1 -12
  280. package/dist/core/canvas/browse/render.js +6 -3
  281. package/dist/core/canvas/crons.d.ts +8 -5
  282. package/dist/core/canvas/crons.js +7 -6
  283. package/dist/core/canvas/extensions.d.ts +7 -3
  284. package/dist/core/canvas/extensions.js +16 -4
  285. package/dist/core/canvas/nav-model.d.ts +0 -4
  286. package/dist/core/canvas/nav-model.js +2 -14
  287. package/dist/core/canvas/node-order.d.ts +3 -0
  288. package/dist/core/canvas/node-order.js +12 -0
  289. package/dist/core/canvas/remote-canvas-source.d.ts +3 -6
  290. package/dist/core/canvas/remote-canvas-source.js +8 -15
  291. package/dist/core/command.js +11 -4
  292. package/dist/core/config.js +3 -1
  293. package/dist/core/events/envelope.js +1 -1
  294. package/dist/core/events/read.js +7 -21
  295. package/dist/core/events/source.d.ts +0 -2
  296. package/dist/core/events/source.js +0 -16
  297. package/dist/core/events/types.d.ts +1 -1
  298. package/dist/core/fault-classifier.d.ts +1 -1
  299. package/dist/core/feed/passive.d.ts +0 -11
  300. package/dist/core/feed/passive.js +1 -62
  301. package/dist/core/human/__tests__/{inbox-core.test.js → serial/inbox-core.test.js} +6 -6
  302. package/dist/core/keybindings/__tests__/resolve.test.js +1 -96
  303. package/dist/core/keybindings/background-bash.js +3 -4
  304. package/dist/core/keybindings/catalog.js +1 -1
  305. package/dist/core/memory/inline-ref-grammar.js +3 -3
  306. package/dist/core/memory-resolver.d.ts +11 -25
  307. package/dist/core/memory-resolver.js +51 -33
  308. package/dist/core/model-routes.d.ts +15 -0
  309. package/dist/core/model-routes.js +12 -0
  310. package/dist/core/pool-credential-store.js +1 -1
  311. package/dist/core/preview-registry.js +8 -9
  312. package/dist/core/profiles/__tests__/root-profile.test.js +4 -14
  313. package/dist/core/review/realize.d.ts +0 -13
  314. package/dist/core/review/realize.js +0 -40
  315. package/dist/core/review/types.d.ts +1 -1
  316. package/dist/core/runtime/__tests__/engine-route.test.js +2 -2
  317. package/dist/core/runtime/bearings.js +1 -11
  318. package/dist/core/runtime/broker/client-registry.d.ts +33 -0
  319. package/dist/core/runtime/broker/client-registry.js +164 -0
  320. package/dist/core/runtime/broker/daemon-ops.d.ts +19 -0
  321. package/dist/core/runtime/broker/daemon-ops.js +49 -0
  322. package/dist/core/runtime/broker/event-projection.d.ts +42 -0
  323. package/dist/core/runtime/broker/event-projection.js +178 -0
  324. package/dist/core/runtime/broker/fault-retry.d.ts +39 -0
  325. package/dist/core/runtime/broker/fault-retry.js +277 -0
  326. package/dist/core/runtime/broker/frame-dispatch.d.ts +238 -0
  327. package/dist/core/runtime/broker/frame-dispatch.js +1537 -0
  328. package/dist/core/runtime/broker/inbox.d.ts +22 -0
  329. package/dist/core/runtime/broker/inbox.js +167 -0
  330. package/dist/core/runtime/broker/passive.d.ts +16 -0
  331. package/dist/core/runtime/broker/passive.js +44 -0
  332. package/dist/core/runtime/broker/read-ops.d.ts +23 -0
  333. package/dist/core/runtime/broker/read-ops.js +150 -0
  334. package/dist/core/runtime/broker/rebind.d.ts +74 -0
  335. package/dist/core/runtime/broker/rebind.js +211 -0
  336. package/dist/core/runtime/broker/tool-groups.d.ts +39 -0
  337. package/dist/core/runtime/broker/tool-groups.js +244 -0
  338. package/dist/core/runtime/broker-extension-render.d.ts +11 -0
  339. package/dist/core/runtime/broker-extension-render.js +181 -0
  340. package/dist/core/runtime/broker-persona-guidance.d.ts +13 -0
  341. package/dist/core/runtime/broker-persona-guidance.js +58 -0
  342. package/dist/core/runtime/broker-protocol.d.ts +1 -1
  343. package/dist/core/runtime/broker-protocol.js +1 -1
  344. package/dist/core/runtime/broker.d.ts +5 -196
  345. package/dist/core/runtime/broker.js +276 -3059
  346. package/dist/core/runtime/canvas-extensions.js +11 -2
  347. package/dist/core/runtime/fault.js +1 -1
  348. package/dist/core/runtime/model-selection.d.ts +9 -0
  349. package/dist/core/runtime/model-selection.js +12 -0
  350. package/dist/core/runtime/model-swap.d.ts +3 -3
  351. package/dist/core/runtime/model-swap.js +33 -25
  352. package/dist/core/runtime/placement-tmux.d.ts +3 -14
  353. package/dist/core/runtime/placement-tmux.js +11 -80
  354. package/dist/core/runtime/placement.d.ts +4 -2
  355. package/dist/core/runtime/placement.js +7 -12
  356. package/dist/core/runtime/promote.d.ts +14 -1
  357. package/dist/core/runtime/promote.js +1 -1
  358. package/dist/core/runtime/reset.d.ts +1 -1
  359. package/dist/core/runtime/roadmap.js +1 -1
  360. package/dist/core/runtime/spawn.d.ts +8 -0
  361. package/dist/core/runtime/spawn.js +36 -6
  362. package/dist/core/runtime/stop-guard.d.ts +4 -3
  363. package/dist/core/runtime/stop-guard.js +36 -18
  364. package/dist/core/runtime/stop-signals.d.ts +4 -1
  365. package/dist/core/runtime/stream-watchdog.js +4 -5
  366. package/dist/core/runtime/structured-output.d.ts +15 -2
  367. package/dist/core/runtime/structured-output.js +35 -12
  368. package/dist/core/runtime/tmux-bindings.d.ts +25 -0
  369. package/dist/core/runtime/tmux-bindings.js +682 -0
  370. package/dist/core/runtime/tmux-chrome.d.ts +2 -1
  371. package/dist/core/runtime/tmux-chrome.js +3 -2
  372. package/dist/core/runtime/{tmux.d.ts → tmux-driver.d.ts} +18 -26
  373. package/dist/core/runtime/tmux-driver.js +598 -0
  374. package/dist/core/runtime/view-socket.d.ts +14 -0
  375. package/dist/core/runtime/view-socket.js +83 -0
  376. package/dist/core/session-model/session-state.d.ts +1 -2
  377. package/dist/core/session-model/session-state.js +5 -8
  378. package/dist/core/spawn.d.ts +1 -1
  379. package/dist/core/spawn.js +2 -2
  380. package/dist/core/substrate/gate.d.ts +1 -1
  381. package/dist/core/substrate/on-read-pure.d.ts +7 -0
  382. package/dist/core/substrate/on-read-pure.js +272 -0
  383. package/dist/core/termrender/termrender.js +32 -2
  384. package/dist/core/user-settings.d.ts +23 -1
  385. package/dist/core/user-settings.js +18 -1
  386. package/dist/daemon/api/__tests__/node-model-validation.test.js +134 -0
  387. package/dist/daemon/api/__tests__/review-terminal-conflict.test.js +98 -0
  388. package/dist/daemon/api/__tests__/{full → seam}/api-server.test.js +6 -48
  389. package/dist/daemon/api/__tests__/{full → seam}/b10-attach-modelauth.test.js +17 -44
  390. package/dist/daemon/api/__tests__/{full/push-parity.test.js → seam/leaf-api-parity.test.js} +61 -42
  391. package/dist/daemon/api/bridge.js +40 -81
  392. package/dist/daemon/api/handlers/broker-ops.d.ts +2 -0
  393. package/dist/daemon/api/handlers/broker-ops.js +383 -0
  394. package/dist/daemon/api/handlers/crons.js +9 -4
  395. package/dist/daemon/api/handlers/files.js +6 -7
  396. package/dist/daemon/api/handlers/inbox.js +2 -340
  397. package/dist/daemon/api/handlers/nodes.d.ts +10 -1
  398. package/dist/daemon/api/handlers/nodes.js +74 -39
  399. package/dist/daemon/api/handlers/review-comments.js +5 -1
  400. package/dist/daemon/api/handlers/reviews.js +0 -19
  401. package/dist/daemon/api/map.js +25 -4
  402. package/dist/daemon/api/router.js +2 -3
  403. package/dist/daemon/api/server.js +5 -7
  404. package/dist/daemon/cron-run.d.ts +4 -0
  405. package/dist/daemon/cron-run.js +30 -13
  406. package/dist/daemon/crtrd.d.ts +3 -58
  407. package/dist/daemon/crtrd.js +28 -1244
  408. package/dist/daemon/manage.js +0 -1
  409. package/dist/daemon/reconcilers/broker-supervision.d.ts +50 -0
  410. package/dist/daemon/reconcilers/broker-supervision.js +549 -0
  411. package/dist/daemon/reconcilers/cron-lane.d.ts +10 -0
  412. package/dist/daemon/reconcilers/cron-lane.js +32 -0
  413. package/dist/daemon/reconcilers/dormant-inbox.d.ts +18 -0
  414. package/dist/daemon/reconcilers/dormant-inbox.js +143 -0
  415. package/dist/daemon/reconcilers/storage-maintenance.d.ts +22 -0
  416. package/dist/daemon/reconcilers/storage-maintenance.js +213 -0
  417. package/dist/daemon/review/finish.js +2 -5
  418. package/dist/pi-extensions/__tests__/canvas-context-intro.test.js +34 -53
  419. package/dist/pi-extensions/__tests__/canvas-recap.test.js +16 -113
  420. package/dist/pi-extensions/__tests__/canvas-stophook-agentend.test.js +72 -99
  421. package/dist/pi-extensions/__tests__/canvas-stophook-context-nudge.test.js +29 -12
  422. package/dist/pi-extensions/broker-local.d.ts +20 -0
  423. package/dist/pi-extensions/broker-local.js +89 -0
  424. package/dist/pi-extensions/canvas-context-intro.d.ts +3 -3
  425. package/dist/pi-extensions/canvas-context-intro.js +22 -11
  426. package/dist/pi-extensions/canvas-doc-substrate.js +17 -34
  427. package/dist/pi-extensions/canvas-goal-capture.js +7 -12
  428. package/dist/pi-extensions/canvas-inbox-watcher.js +124 -139
  429. package/dist/pi-extensions/canvas-passive-context.d.ts +3 -3
  430. package/dist/pi-extensions/canvas-passive-context.js +22 -18
  431. package/dist/pi-extensions/canvas-recap.d.ts +2 -2
  432. package/dist/pi-extensions/canvas-recap.js +48 -21
  433. package/dist/pi-extensions/canvas-review-boundary.js +10 -4
  434. package/dist/pi-extensions/canvas-stophook.d.ts +0 -5
  435. package/dist/pi-extensions/canvas-stophook.js +149 -431
  436. package/dist/pi-extensions/canvas-structured-output.js +52 -30
  437. package/dist/pi-extensions/envelope-merge.d.ts +13 -0
  438. package/dist/pi-extensions/envelope-merge.js +29 -0
  439. package/dist/shared/working-activity.d.ts +3 -2
  440. package/dist/shared/working-activity.js +3 -2
  441. package/dist/types.d.ts +6 -5
  442. package/dist/types.js +2 -2
  443. package/docs/compat/hearth-crtr-v1.md +4 -12
  444. package/docs/compat/hearth-crtr-v2.md +3 -11
  445. package/docs/compat/hearth-crtr-v3.md +4 -12
  446. package/docs/compat/hearth-crtr-v4.md +3 -11
  447. package/docs/compat/hearth-crtr-v5.md +3 -11
  448. package/docs/public-api.md +3 -7
  449. package/package.json +7 -49
  450. package/runtime.lock.json +2766 -14533
  451. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/__tests__/claude-plugin-commands.test.ts +0 -49
  452. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/__tests__/memory-slash-commands.test.ts +0 -194
  453. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/__tests__/statusline.test.ts +0 -68
  454. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/frontmatter-rules/test.ts +0 -119
  455. package/dist/clients/attach/__tests__/attach-chrome-remote.test.js +0 -439
  456. package/dist/clients/attach/__tests__/attach-keybindings.test.js +0 -170
  457. package/dist/clients/attach/__tests__/crtr-output-coverage.test.js +0 -57
  458. package/dist/clients/attach/__tests__/editor-frame-title.test.js +0 -19
  459. package/dist/clients/attach/__tests__/input-controller-extension-command.test.js +0 -32
  460. package/dist/clients/attach/__tests__/markdown-headings.test.js +0 -35
  461. package/dist/clients/attach/__tests__/session-identity-refresh.test.js +0 -32
  462. package/dist/clients/conversation/conversation.d.ts +0 -65
  463. package/dist/clients/conversation/conversation.js +0 -318
  464. package/dist/clients/conversation/frames.d.ts +0 -30
  465. package/dist/clients/conversation/frames.js +0 -52
  466. package/dist/clients/conversation/region.d.ts +0 -51
  467. package/dist/clients/conversation/region.js +0 -265
  468. package/dist/clients/inbox/__tests__/inbox-controller.test.js +0 -247
  469. package/dist/clients/inbox/__tests__/mount-panel.test.js +0 -776
  470. package/dist/clients/inbox/review/__tests__/remap.test.js +0 -196
  471. package/dist/clients/inbox/review/columns.d.ts +0 -22
  472. package/dist/clients/inbox/review/columns.js +0 -40
  473. package/dist/clients/inbox/review/composition.d.ts +0 -60
  474. package/dist/clients/inbox/review/composition.js +0 -278
  475. package/dist/clients/inbox/review/document-region.d.ts +0 -120
  476. package/dist/clients/surfaces/region.d.ts +0 -16
  477. package/dist/clients/web/__tests__/push-engine.test.js +0 -158
  478. package/dist/clients/web/__tests__/push-registry.test.d.ts +0 -1
  479. package/dist/clients/web/__tests__/push-registry.test.js +0 -177
  480. package/dist/clients/web/dev-server.d.ts +0 -7
  481. package/dist/clients/web/dev-server.js +0 -46
  482. package/dist/clients/web/events.d.ts +0 -19
  483. package/dist/clients/web/events.js +0 -163
  484. package/dist/clients/web/push-engine.d.ts +0 -44
  485. package/dist/clients/web/push-engine.js +0 -125
  486. package/dist/clients/web/push-registry.d.ts +0 -85
  487. package/dist/clients/web/push-registry.js +0 -373
  488. package/dist/clients/web/server.d.ts +0 -19
  489. package/dist/clients/web/server.js +0 -661
  490. package/dist/clients/web/web-client/shared/protocol.d.ts +0 -214
  491. package/dist/clients/web/web-client/shared/protocol.js +0 -8
  492. package/dist/clients/web/web-cmd.d.ts +0 -2
  493. package/dist/clients/web/web-cmd.js +0 -141
  494. package/dist/commands/__tests__/api-canvas-source.test.d.ts +0 -1
  495. package/dist/commands/__tests__/api-canvas-source.test.js +0 -37
  496. package/dist/commands/__tests__/canvas-config.test.d.ts +0 -1
  497. package/dist/commands/__tests__/canvas-config.test.js +0 -107
  498. package/dist/commands/__tests__/node-no-kickoff-flag.test.d.ts +0 -1
  499. package/dist/commands/__tests__/node-no-kickoff-flag.test.js +0 -73
  500. package/dist/commands/__tests__/node-worktree-flag.test.d.ts +0 -1
  501. package/dist/commands/__tests__/node-worktree-flag.test.js +0 -49
  502. package/dist/commands/__tests__/search-contents.test.d.ts +0 -1
  503. package/dist/commands/__tests__/search-contents.test.js +0 -52
  504. package/dist/commands/memory/__tests__/lint.test.d.ts +0 -1
  505. package/dist/commands/memory/__tests__/lint.test.js +0 -15
  506. package/dist/commands/sys/__tests__/config-broker-thresholds.test.d.ts +0 -1
  507. package/dist/commands/sys/__tests__/config-broker-thresholds.test.js +0 -95
  508. package/dist/commands/sys/__tests__/config-keybindings.test.d.ts +0 -1
  509. package/dist/commands/sys/__tests__/config-keybindings.test.js +0 -55
  510. package/dist/commands/sys/__tests__/helpers/setup-runtime.d.ts +0 -5
  511. package/dist/commands/sys/__tests__/helpers/setup-runtime.js +0 -19
  512. package/dist/commands/sys/__tests__/setup-front-door.test.d.ts +0 -1
  513. package/dist/commands/sys/__tests__/setup-front-door.test.js +0 -102
  514. package/dist/commands/sys/__tests__/setup-models.test.d.ts +0 -1
  515. package/dist/commands/sys/__tests__/setup-models.test.js +0 -205
  516. package/dist/commands/sys/__tests__/setup-providers-viewport.test.d.ts +0 -1
  517. package/dist/commands/sys/__tests__/setup-providers-viewport.test.js +0 -155
  518. package/dist/commands/sys/__tests__/sync-deps.test.d.ts +0 -1
  519. package/dist/commands/sys/__tests__/sync-deps.test.js +0 -179
  520. package/dist/commands/sys/__tests__/sync-import.test.d.ts +0 -1
  521. package/dist/commands/sys/__tests__/sync-import.test.js +0 -315
  522. package/dist/core/__tests__/base-worker-prompt.test.d.ts +0 -1
  523. package/dist/core/__tests__/base-worker-prompt.test.js +0 -57
  524. package/dist/core/__tests__/command-plugins-surfaces.test.d.ts +0 -1
  525. package/dist/core/__tests__/command-plugins-surfaces.test.js +0 -359
  526. package/dist/core/__tests__/connection-reconnect-resume.test.d.ts +0 -1
  527. package/dist/core/__tests__/connection-reconnect-resume.test.js +0 -36
  528. package/dist/core/__tests__/finalization-migration.test.d.ts +0 -1
  529. package/dist/core/__tests__/finalization-migration.test.js +0 -38
  530. package/dist/core/__tests__/fixtures/extra-extension.d.ts +0 -1
  531. package/dist/core/__tests__/fixtures/extra-extension.js +0 -3
  532. package/dist/core/__tests__/fixtures/spawn-proof-target.test.d.ts +0 -1
  533. package/dist/core/__tests__/fixtures/spawn-proof-target.test.js +0 -15
  534. package/dist/core/__tests__/fork.test.d.ts +0 -1
  535. package/dist/core/__tests__/fork.test.js +0 -108
  536. package/dist/core/__tests__/full/broker-attach-limits.test.d.ts +0 -1
  537. package/dist/core/__tests__/full/broker-attach-limits.test.js +0 -147
  538. package/dist/core/__tests__/full/broker-deliver-ack.test.d.ts +0 -1
  539. package/dist/core/__tests__/full/broker-deliver-ack.test.js +0 -73
  540. package/dist/core/__tests__/full/broker-dialogs.test.d.ts +0 -1
  541. package/dist/core/__tests__/full/broker-dialogs.test.js +0 -180
  542. package/dist/core/__tests__/full/broker-display-snapshot.test.d.ts +0 -1
  543. package/dist/core/__tests__/full/broker-display-snapshot.test.js +0 -75
  544. package/dist/core/__tests__/full/broker-dormant-wake.test.d.ts +0 -1
  545. package/dist/core/__tests__/full/broker-dormant-wake.test.js +0 -130
  546. package/dist/core/__tests__/full/broker-model-changed-broadcast.test.d.ts +0 -1
  547. package/dist/core/__tests__/full/broker-model-changed-broadcast.test.js +0 -57
  548. package/dist/core/__tests__/full/broker-navigate-tree-rewelcome.test.d.ts +0 -1
  549. package/dist/core/__tests__/full/broker-navigate-tree-rewelcome.test.js +0 -80
  550. package/dist/core/__tests__/full/cascade-close.test.d.ts +0 -1
  551. package/dist/core/__tests__/full/cascade-close.test.js +0 -240
  552. package/dist/core/__tests__/full/detach-focus.test.d.ts +0 -1
  553. package/dist/core/__tests__/full/detach-focus.test.js +0 -126
  554. package/dist/core/__tests__/full/idle-release-settlement.test.d.ts +0 -1
  555. package/dist/core/__tests__/full/issue-146-yield-spawn-focus.test.d.ts +0 -1
  556. package/dist/core/__tests__/full/issue-146-yield-spawn-focus.test.js +0 -107
  557. package/dist/core/__tests__/full/park-clock-release.test.d.ts +0 -1
  558. package/dist/core/__tests__/full/park-clock-release.test.js +0 -56
  559. package/dist/core/__tests__/full/yield-message-transaction.test.d.ts +0 -1
  560. package/dist/core/__tests__/memory-index-render.test.d.ts +0 -1
  561. package/dist/core/__tests__/memory-index-render.test.js +0 -60
  562. package/dist/core/__tests__/model-routes.test.d.ts +0 -1
  563. package/dist/core/__tests__/model-routes.test.js +0 -41
  564. package/dist/core/__tests__/on-read-identity.test.d.ts +0 -1
  565. package/dist/core/__tests__/on-read-identity.test.js +0 -61
  566. package/dist/core/__tests__/phase4-review-migration.test.d.ts +0 -1
  567. package/dist/core/__tests__/phase4-review-migration.test.js +0 -100
  568. package/dist/core/__tests__/prune-to-limit.test.d.ts +0 -1
  569. package/dist/core/__tests__/prune-to-limit.test.js +0 -126
  570. package/dist/core/__tests__/reset.test.d.ts +0 -1
  571. package/dist/core/__tests__/reset.test.js +0 -69
  572. package/dist/core/__tests__/spawn-no-kickoff.test.d.ts +0 -1
  573. package/dist/core/__tests__/spawn-no-kickoff.test.js +0 -115
  574. package/dist/core/__tests__/steer-note.test.d.ts +0 -1
  575. package/dist/core/__tests__/steer-note.test.js +0 -41
  576. package/dist/core/__tests__/subcommand-tier.test.d.ts +0 -1
  577. package/dist/core/__tests__/subcommand-tier.test.js +0 -99
  578. package/dist/core/__tests__/subscription-delivery.test.js +0 -211
  579. package/dist/core/__tests__/test-runner-cheap-sharding.test.d.ts +0 -1
  580. package/dist/core/__tests__/test-runner-cheap-sharding.test.js +0 -97
  581. package/dist/core/__tests__/tmux-surface.test.js +0 -484
  582. package/dist/core/__tests__/wake-bearings.test.d.ts +0 -1
  583. package/dist/core/__tests__/wake-bearings.test.js +0 -102
  584. package/dist/core/canvas/__tests__/remote-event-stream.test.d.ts +0 -1
  585. package/dist/core/canvas/__tests__/remote-event-stream.test.js +0 -146
  586. package/dist/core/canvas/__tests__/source-resolve.test.d.ts +0 -1
  587. package/dist/core/canvas/__tests__/source-resolve.test.js +0 -77
  588. package/dist/core/canvas/browse/__tests__/model.test.d.ts +0 -1
  589. package/dist/core/canvas/browse/__tests__/model.test.js +0 -290
  590. package/dist/core/canvas/browse/__tests__/rebuild-coalescer.test.d.ts +0 -1
  591. package/dist/core/canvas/browse/__tests__/rebuild-coalescer.test.js +0 -134
  592. package/dist/core/canvas/browse/__tests__/render.test.d.ts +0 -1
  593. package/dist/core/canvas/browse/__tests__/render.test.js +0 -111
  594. package/dist/core/canvas/browse/rebuild-coalescer.d.ts +0 -7
  595. package/dist/core/canvas/browse/rebuild-coalescer.js +0 -61
  596. package/dist/core/canvas/remote-event-stream.d.ts +0 -24
  597. package/dist/core/canvas/remote-event-stream.js +0 -94
  598. package/dist/core/feed/__tests__/coalesce-human.test.d.ts +0 -1
  599. package/dist/core/feed/__tests__/coalesce-human.test.js +0 -36
  600. package/dist/core/feed/__tests__/empty-node-guard.test.d.ts +0 -1
  601. package/dist/core/feed/__tests__/empty-node-guard.test.js +0 -45
  602. package/dist/core/host-exports/__tests__/export-prunes-boot-skill.test.d.ts +0 -1
  603. package/dist/core/host-exports/__tests__/export-prunes-boot-skill.test.js +0 -84
  604. package/dist/core/human/__tests__/visible-paths.test.d.ts +0 -1
  605. package/dist/core/human/__tests__/visible-paths.test.js +0 -28
  606. package/dist/core/keybindings/__tests__/inbox-affordance.test.d.ts +0 -1
  607. package/dist/core/keybindings/__tests__/inbox-affordance.test.js +0 -38
  608. package/dist/core/review/__tests__/project.test.d.ts +0 -1
  609. package/dist/core/review/__tests__/project.test.js +0 -71
  610. package/dist/core/runtime/__tests__/command-expansion.test.d.ts +0 -1
  611. package/dist/core/runtime/__tests__/command-expansion.test.js +0 -25
  612. package/dist/core/runtime/__tests__/session-visibility.test.d.ts +0 -1
  613. package/dist/core/runtime/__tests__/session-visibility.test.js +0 -119
  614. package/dist/core/runtime/__tests__/spawn-at-given-id.test.d.ts +0 -1
  615. package/dist/core/runtime/__tests__/spawn-at-given-id.test.js +0 -34
  616. package/dist/core/runtime/tmux.js +0 -1314
  617. package/dist/daemon/api/__tests__/full/push-parity.test.d.ts +0 -1
  618. package/dist/daemon/api/__tests__/full/worktree-parity.test.d.ts +0 -1
  619. package/dist/daemon/api/__tests__/full/worktree-parity.test.js +0 -160
  620. package/dist/daemon/api/__tests__/inbox.test.d.ts +0 -1
  621. package/dist/daemon/api/__tests__/inbox.test.js +0 -489
  622. package/dist/web-client/apple-touch-icon.png +0 -0
  623. package/dist/web-client/assets/fragment-mono-latin-400-normal-BYwT3kSJ.woff +0 -0
  624. package/dist/web-client/assets/fragment-mono-latin-400-normal-yxdJ5AmL.woff2 +0 -0
  625. package/dist/web-client/assets/fragment-mono-latin-ext-400-normal-BbKYyvR9.woff2 +0 -0
  626. package/dist/web-client/assets/fragment-mono-latin-ext-400-normal-CT4YFKeK.woff +0 -0
  627. package/dist/web-client/assets/index-CCPaLeW7.css +0 -2
  628. package/dist/web-client/assets/index-kyOWsnZK.js +0 -86
  629. package/dist/web-client/assets/martian-mono-cyrillic-wght-normal-B84CD5C_.woff2 +0 -0
  630. package/dist/web-client/assets/martian-mono-latin-ext-wght-normal-DlL6xMw5.woff2 +0 -0
  631. package/dist/web-client/assets/martian-mono-latin-wght-normal-5W32yIyr.woff2 +0 -0
  632. package/dist/web-client/assets/workbox-window.prod.es5-Bd17z0YL.js +0 -2
  633. package/dist/web-client/icon-192.png +0 -0
  634. package/dist/web-client/icon-512.png +0 -0
  635. package/dist/web-client/icon-maskable-512.png +0 -0
  636. package/dist/web-client/index.html +0 -17
  637. package/dist/web-client/manifest.webmanifest +0 -1
  638. package/dist/web-client/sw.js +0 -1
  639. /package/dist/api/__tests__/{client.test.d.ts → serial/client.test.d.ts} +0 -0
  640. /package/dist/clients/inbox/__tests__/{inbox-controller.test.d.ts → serial/inbox-controller.test.d.ts} +0 -0
  641. /package/dist/clients/inbox/__tests__/{mount-panel.test.d.ts → serial/mount-panel.test.d.ts} +0 -0
  642. /package/dist/clients/{attach/__tests__/attach-chrome-remote.test.d.ts → inbox/review/__tests__/teardown-notice.test.d.ts} +0 -0
  643. /package/dist/{clients/attach/__tests__/attach-keybindings.test.d.ts → core/__tests__/broker-extension-canvas-db-boundary.test.d.ts} +0 -0
  644. /package/dist/{clients/attach/__tests__/crtr-output-coverage.test.d.ts → core/__tests__/seam/broker-attach-multiclient.test.d.ts} +0 -0
  645. /package/dist/core/__tests__/{full → seam}/broker-attach-stream.test.d.ts +0 -0
  646. /package/dist/core/__tests__/{full → seam}/broker-crash-teardown.test.d.ts +0 -0
  647. /package/dist/core/__tests__/{full → seam}/broker-pane-resolution.test.d.ts +0 -0
  648. /package/dist/core/__tests__/{full → seam}/broker-provider-retry.test.d.ts +0 -0
  649. /package/dist/core/__tests__/{full → seam}/broker-whip-interrupt.test.d.ts +0 -0
  650. /package/dist/{clients/attach/__tests__/editor-frame-title.test.d.ts → core/__tests__/seam/dormancy-release.test.d.ts} +0 -0
  651. /package/dist/{clients/attach/__tests__/input-controller-extension-command.test.d.ts → core/__tests__/seam/yield-refresh-transaction.test.d.ts} +0 -0
  652. /package/dist/core/__tests__/{broker-fork-seam.test.d.ts → serial/broker-fork-seam.test.d.ts} +0 -0
  653. /package/dist/core/__tests__/{broker-sdk-wiring.test.d.ts → serial/broker-sdk-wiring.test.d.ts} +0 -0
  654. /package/dist/core/__tests__/{broker-snapshot-history.test.d.ts → serial/broker-snapshot-history.test.d.ts} +0 -0
  655. /package/dist/core/__tests__/{command-plugins.test.d.ts → serial/command-plugins.test.d.ts} +0 -0
  656. /package/dist/core/__tests__/{deferred-no-wake.test.d.ts → serial/deferred-no-wake.test.d.ts} +0 -0
  657. /package/dist/core/__tests__/{flagship-lifecycle.test.d.ts → serial/flagship-lifecycle.test.d.ts} +0 -0
  658. /package/dist/core/__tests__/{host-teardown-process-group.test.d.ts → serial/host-teardown-process-group.test.d.ts} +0 -0
  659. /package/dist/core/__tests__/{human-deliver-e2e.test.d.ts → serial/human-deliver-e2e.test.d.ts} +0 -0
  660. /package/dist/core/__tests__/{live-mutation.test.d.ts → serial/live-mutation.test.d.ts} +0 -0
  661. /package/dist/core/__tests__/{refresh-stall-recycle.test.d.ts → serial/refresh-stall-recycle.test.d.ts} +0 -0
  662. /package/dist/core/__tests__/{revive.test.d.ts → serial/revive.test.d.ts} +0 -0
  663. /package/dist/core/__tests__/{spawn-root.test.d.ts → serial/spawn-root.test.d.ts} +0 -0
  664. /package/dist/core/__tests__/{subscription-delivery.test.d.ts → serial/subscription-delivery.test.d.ts} +0 -0
  665. /package/dist/core/__tests__/{tmux-surface.test.d.ts → serial/tmux-surface.test.d.ts} +0 -0
  666. /package/dist/core/__tests__/{worktree.test.d.ts → serial/worktree.test.d.ts} +0 -0
  667. /package/dist/{clients/attach/__tests__/markdown-headings.test.d.ts → core/__tests__/watchdog-abort-arms-retry.test.d.ts} +0 -0
  668. /package/dist/{clients/attach/__tests__/session-identity-refresh.test.d.ts → core/broker-client/__tests__/transport-socket.test.d.ts} +0 -0
  669. /package/dist/core/human/__tests__/{inbox-core.test.d.ts → serial/inbox-core.test.d.ts} +0 -0
  670. /package/dist/{clients/inbox/review/__tests__/remap.test.d.ts → daemon/api/__tests__/node-model-validation.test.d.ts} +0 -0
  671. /package/dist/{clients/surfaces/region.js → daemon/api/__tests__/review-terminal-conflict.test.d.ts} +0 -0
  672. /package/dist/daemon/api/__tests__/{full → seam}/api-server.test.d.ts +0 -0
  673. /package/dist/daemon/api/__tests__/{full → seam}/b10-attach-modelauth.test.d.ts +0 -0
  674. /package/dist/{clients/web/__tests__/push-engine.test.d.ts → daemon/api/__tests__/seam/leaf-api-parity.test.d.ts} +0 -0
@@ -3,8 +3,8 @@ import test from 'node:test';
3
3
  import { ensureRenderer, isRendererReady } from '../../../core/termrender/termrender.js';
4
4
  import { transformDiagramFences } from '../render/diagram.js';
5
5
  // This asserts a REAL termrender render (box-drawing glyphs), so it only holds
6
- // once the managed renderer is provisioned — true in the full tier and on a dev
7
- // box, but the fast tier is deliberately termrender-free (no uv to provision the
6
+ // once the managed renderer is provisioned — true in the compiled seam and on a dev
7
+ // box, but the ordinary suite is deliberately termrender-free (no uv to provision the
8
8
  // venv). Skip cleanly when the renderer is unavailable, exactly as the tmux
9
9
  // tests skip when tmux is absent, rather than failing on the environment.
10
10
  ensureRenderer();
@@ -28,8 +28,4 @@ test('edit cards stream argument diffs, then keep the executed result authoritat
28
28
  const settled = definition.renderCall(laterArgs, theme, context).render(80).join('\n');
29
29
  assert.match(settled, /executed/);
30
30
  assert.doesNotMatch(settled, /stale preview/);
31
- fold.setFolded(true);
32
- const folded = definition.renderCall(laterArgs, theme, context).render(80).join('\n');
33
- assert.match(folded, /\+2/);
34
- assert.match(folded, /-1/);
35
31
  });
@@ -3,6 +3,7 @@ import { test } from 'node:test';
3
3
  import assert from 'node:assert/strict';
4
4
  import { initTheme } from '@earendil-works/pi-coding-agent';
5
5
  import { InputController } from '../input/controller.js';
6
+ import { createViewerCapabilities } from '../input/capabilities.js';
6
7
  initTheme(undefined, false);
7
8
  function fakeEditor() {
8
9
  const obj = {
@@ -38,7 +39,7 @@ test('choosing a review file closes the inline picker before the review surface
38
39
  onDialogResponse: () => { },
39
40
  onMountPicker: (component) => { mountedPicker = component; },
40
41
  onUnmountPicker: () => { },
41
- });
42
+ }, createViewerCapabilities({ role: 'controller', remote: false, nodeId: 'test', profileId: undefined }));
42
43
  controller.openFileReviewPicker([fileURLToPath(import.meta.url)], process.cwd(), () => {
43
44
  tui.setFocus(reviewSurface);
44
45
  });
@@ -1,20 +1,17 @@
1
+ // Two fold-boundary regressions for the attach viewer's summarized tool groups:
2
+ //
3
+ // 1. An aborted or errored assistant ending must stay VISIBLE outside the
4
+ // folded group. If the recap swallows it, the user never learns the turn
5
+ // failed — the folded rows just stop.
6
+ // 2. A recap is a digest, never a payload dump: edit diffs and write bodies
7
+ // must never leak into it.
1
8
  import assert from 'node:assert/strict';
2
- import { homedir } from 'node:os';
3
- import { resolve } from 'node:path';
4
9
  import test from 'node:test';
5
- import { Container, TUI, getCapabilities, setCapabilities } from '@earendil-works/pi-tui';
10
+ import { Container, TUI } from '@earendil-works/pi-tui';
6
11
  import { initTheme } from '@earendil-works/pi-coding-agent';
7
- import { AUTH_FAULT_RECOVERY_BODY, RUNTIME_RESTART_CONTINUATION, isRuntimeRestartContinuation } from '../../../shared/generated-context.js';
8
12
  import { ChatView } from '../render/chat-view.js';
9
13
  import { GroupActivityRecorder } from '../render/group-activity.js';
10
14
  import { GroupRecapComponent } from '../render/group-recap.js';
11
- import { TOOL_ICON } from '../../../core/preview-registry.js';
12
- function memoryRead(name, pathStyle = 'section') {
13
- const path = pathStyle === 'field'
14
- ? `- path: /tmp/memories/${name}.md`
15
- : `**path:** /tmp/memories/${name}.md`;
16
- return `- name: ${name}\n- kind: knowledge\n- scope: project\n${pathStyle === 'section' ? '\n' : ''}${path}`;
17
- }
18
15
  function fakeTerminal() {
19
16
  return {
20
17
  start() { }, stop() { }, async drainInput() { }, write() { },
@@ -22,142 +19,7 @@ function fakeTerminal() {
22
19
  moveBy() { }, hideCursor() { }, showCursor() { }, clearLine() { }, clearFromCursor() { }, clearScreen() { }, setTitle() { }, setProgress() { },
23
20
  };
24
21
  }
25
- function snapshotWithContinuation(body) {
26
- return {
27
- messages: [
28
- { role: 'assistant', content: [{ type: 'toolCall', id: 'before', name: 'bash', arguments: { command: 'true' } }] },
29
- { role: 'toolResult', toolCallId: 'before', toolName: 'bash', content: [{ type: 'text', text: '' }], isError: false },
30
- { role: 'user', content: body },
31
- { role: 'assistant', content: [{ type: 'toolCall', id: 'after', name: 'bash', arguments: { command: 'true' } }] },
32
- { role: 'toolResult', toolCallId: 'after', toolName: 'bash', content: [{ type: 'text', text: '' }], isError: false },
33
- ],
34
- stats: {},
35
- state: { isStreaming: false },
36
- };
37
- }
38
22
  initTheme(undefined, false);
39
- test('group activity aggregates successful file changes and resolved memory reads', () => {
40
- const cwd = '/tmp/activity';
41
- const recorder = new GroupActivityRecorder(cwd);
42
- recorder.noteCall('edit-1', 'edit', { path: 'same.ts' });
43
- recorder.settle('edit-1', { details: { diff: '-1 old\n+1 new' } }, false);
44
- recorder.noteCall('write', 'write', { path: 'other.ts', content: 'one\ntwo\n' });
45
- recorder.settle('write', {}, false);
46
- recorder.noteCall('edit-2', 'edit', { path: resolve(cwd, 'same.ts') });
47
- recorder.settle('edit-2', { details: { diff: '+2 later' } }, false);
48
- recorder.noteCall('home-edit', 'edit', { path: '~/same-home.ts' });
49
- recorder.settle('home-edit', { details: { diff: '+1 home' } }, false);
50
- recorder.noteCall('home-write', 'write', { path: resolve(homedir(), 'same-home.ts'), content: 'replacement' });
51
- recorder.settle('home-write', {}, false);
52
- recorder.noteCall('failed', 'edit', { path: 'failed.ts' });
53
- recorder.settle('failed', { details: { diff: '+1 never' } }, true);
54
- recorder.noteCall('memory', 'bash', { command: 'crtr memory read alpha && crtr memory read beta' });
55
- recorder.settle('memory', { content: [{ type: 'text', text: `${memoryRead('alpha')}\n\n${memoryRead('beta', 'field')}` }] }, false);
56
- recorder.noteCall('repeat', 'bash', { command: 'crtr memory read alpha' });
57
- recorder.settle('repeat', { content: [{ type: 'text', text: memoryRead('alpha') }] }, false);
58
- recorder.noteCall('not-a-read', 'bash', { command: 'crtr memory list' });
59
- recorder.settle('not-a-read', { content: [{ type: 'text', text: memoryRead('ignored') }] }, false);
60
- recorder.noteCall('quoted-not-a-read', 'bash', { command: 'echo "not a command; crtr memory read fabricated"' });
61
- recorder.settle('quoted-not-a-read', { content: [{ type: 'text', text: memoryRead('fabricated') }] }, false);
62
- const activity = recorder.activity();
63
- assert.deepEqual(activity.memories, [
64
- { name: 'alpha', path: '/tmp/memories/alpha.md' },
65
- { name: 'beta', path: '/tmp/memories/beta.md' },
66
- ]);
67
- assert.deepEqual(activity.files.map((file) => [file.kind, file.displayPath]), [
68
- ['edit', 'same.ts'],
69
- ['write', 'other.ts'],
70
- ['edit', '~/same-home.ts'],
71
- ['write', resolve(homedir(), 'same-home.ts')],
72
- ]);
73
- assert.deepEqual(activity.files[0], {
74
- key: resolve(cwd, 'same.ts'),
75
- displayPath: 'same.ts',
76
- kind: 'edit',
77
- added: 2,
78
- removed: 1,
79
- hasKnownCounts: true,
80
- countsIncomplete: false,
81
- });
82
- assert.deepEqual(activity.files[1], {
83
- key: resolve(cwd, 'other.ts'),
84
- displayPath: 'other.ts',
85
- kind: 'write',
86
- added: 2,
87
- removed: 0,
88
- hasKnownCounts: true,
89
- countsIncomplete: false,
90
- });
91
- assert.equal(activity.files[2]?.added, 1, 'edits retain their own aggregate');
92
- assert.equal(activity.files[3]?.added, 1, 'writes retain their own aggregate');
93
- });
94
- test('the detailed folded recap retains paths and counts without diff or payload bodies', () => {
95
- const recorder = new GroupActivityRecorder('/tmp/activity');
96
- recorder.noteCall('edit', 'edit', { path: 'overwritten.ts' });
97
- const addedDiff = Array.from({ length: 11 }, (_, index) => `+${index + 1} sensitive-new-diff`).join('\n');
98
- recorder.settle('edit', { details: { diff: `-1 sensitive-old-diff\n${addedDiff}` } }, false);
99
- recorder.noteCall('write', 'write', {
100
- path: 'overwritten.ts',
101
- content: Array.from({ length: 8 }, () => 'sensitive-write-payload').join('\n'),
102
- });
103
- recorder.settle('write', {}, false);
104
- recorder.noteCall('zero', 'edit', { path: 'overwritten.ts' });
105
- recorder.settle('zero', { details: { diff: '' } }, false);
106
- recorder.noteCall('unavailable', 'edit', { path: 'overwritten.ts' });
107
- recorder.settle('unavailable', {}, false);
108
- const tone = (key) => (text) => `[${key}]${text}`;
109
- const palette = {
110
- accent: tone('accent'), active: tone('active'), info: tone('info'), muted: tone('muted'),
111
- faint: tone('faint'), border: tone('border'), surface: tone('surface'), bold: tone('bold'),
112
- error: tone('error'), warning: tone('warning'), diffAdded: tone('diffAdded'), diffRemoved: tone('diffRemoved'),
113
- bashMode: tone('bashMode'), bashModeAlt: tone('bashModeAlt'),
114
- };
115
- const recap = new GroupRecapComponent();
116
- const originalCapabilities = getCapabilities();
117
- let lines;
118
- try {
119
- setCapabilities({ ...originalCapabilities, hyperlinks: true });
120
- recap.setRecap({ bullets: ['finished'], nodesSpawned: 1, filesEdited: 3 }, 2, {
121
- memories: [
122
- { name: 'alpha', path: '/tmp/memories/alpha.md' },
123
- { name: 'beta', path: '/tmp/memories/beta.md' },
124
- ],
125
- files: recorder.activity().files,
126
- }, true, palette);
127
- lines = recap.render(120);
128
- }
129
- finally {
130
- setCapabilities(originalCapabilities);
131
- }
132
- const text = lines.join('\n');
133
- assert.equal(lines[0], '');
134
- assert.equal(lines.at(-1), '');
135
- assert.match(text, /2 tool calls/, 'tool-call count remains visible in every recap mode');
136
- assert.doesNotMatch(text, /✦/, 'the tool-call count has no decorative prefix');
137
- assert.doesNotMatch(text, /files?\s+edited|memory\s+reads/, 'detailed recaps do not duplicate their itemized activity with count chrome');
138
- assert.equal(lines.filter((line) => line.includes('[muted]alpha')).length, 1, 'each memory renders on one line');
139
- assert.equal(lines.filter((line) => line.includes('[muted]beta')).length, 1, 'each memory renders on one line');
140
- assert.match(text, /file:\/\/\/tmp\/memories\/alpha\.md/);
141
- assert.match(text, /file:\/\/\/tmp\/memories\/beta\.md/);
142
- assert.doesNotMatch(text, /alpha · beta/);
143
- const fileLines = lines.filter((line) => line.includes('overwritten.ts'));
144
- assert.equal(fileLines.length, 2, 'edits and writes remain independently visible');
145
- const editLine = fileLines.find((line) => line.includes(`[warning]${TOOL_ICON.edit}`));
146
- const writeLine = fileLines.find((line) => line.includes(`[warning]${TOOL_ICON.write}`));
147
- assert.ok(editLine.indexOf(TOOL_ICON.edit) < editLine.indexOf('overwritten.ts'), 'the edit path stays inline with its glyph');
148
- assert.ok(writeLine.indexOf(TOOL_ICON.write) < writeLine.indexOf('overwritten.ts'), 'the write path stays inline with its glyph');
149
- assert.ok(editLine.endsWith('[diffAdded]+11 [diffRemoved]-1[muted] · counts incomplete'), 'edit counts stay with the edit');
150
- assert.ok(writeLine.endsWith('[diffAdded]+8'), 'write counts stay with the write');
151
- assert.equal(lines.filter((line) => line.includes('[diffAdded]')).length, 2, 'each action has one count row');
152
- const toolCallIndex = lines.findIndex((line) => line.includes('2 tool calls'));
153
- const bulletIndex = lines.findIndex((line) => line.includes('finished'));
154
- assert.ok(lines.findIndex((line) => line.includes('[muted]alpha')) < toolCallIndex, 'memory reads precede the tool-call count');
155
- assert.ok(lines.findIndex((line) => line.includes(`[warning]${TOOL_ICON.edit}`)) < toolCallIndex, 'file actions precede the tool-call count');
156
- assert.ok(toolCallIndex < bulletIndex, 'the tool-call count precedes recap bullets');
157
- assert.ok(!text.includes('sensitive-old-diff'));
158
- assert.ok(!text.includes('sensitive-new-diff'));
159
- assert.ok(!text.includes('sensitive-write-payload'));
160
- });
161
23
  async function summarizedGroup(messages, key) {
162
24
  const view = new ChatView(new TUI(fakeTerminal()), new Container());
163
25
  const internals = view;
@@ -179,88 +41,37 @@ async function summarizedGroup(messages, key) {
179
41
  hidden: internals.historyContainer.hiddenChildren,
180
42
  };
181
43
  }
182
- test('broker summaries hide every settled call while aborted/error assistant endings remain visible boundaries', async () => {
183
- const successful = await summarizedGroup([
184
- { role: 'assistant', content: [{ type: 'toolCall', id: 'successful', name: 'bash', arguments: { command: 'true' } }] },
185
- { role: 'toolResult', toolCallId: 'successful', toolName: 'bash', content: [{ type: 'text', text: 'ok' }], isError: false },
186
- ], 'successful');
187
- assert.equal(successful.hidden.has(successful.group.recap), false, 'a settled successful group still folds to its recap');
188
- assert.ok(successful.group.members.every((member) => successful.hidden.has(member)), 'successful group members hide behind the recap');
189
- const mixed = await summarizedGroup([
190
- {
191
- role: 'assistant',
192
- content: [
193
- { type: 'toolCall', id: 'mixed-success', name: 'bash', arguments: { command: 'true' } },
194
- { type: 'toolCall', id: 'mixed-failure', name: 'bash', arguments: { command: 'false' } },
195
- ],
196
- },
197
- { role: 'toolResult', toolCallId: 'mixed-success', toolName: 'bash', content: [{ type: 'text', text: 'ok' }], isError: false },
198
- { role: 'toolResult', toolCallId: 'mixed-failure', toolName: 'bash', content: [{ type: 'text', text: 'failed' }], isError: true },
199
- ], 'mixed-success');
200
- assert.equal(mixed.hidden.has(mixed.group.recap), false, 'a failed call does not suppress the valid group recap');
201
- assert.ok(mixed.group.members.every((member) => mixed.hidden.has(member)), 'successful and failed calls all hide behind the recap');
202
- for (const stopReason of ['aborted', 'error']) {
203
- const key = `terminal-${stopReason}`;
204
- const terminalMessage = stopReason === 'aborted'
205
- ? { role: 'assistant', content: [], stopReason }
206
- : { role: 'assistant', content: [{ type: 'text', text: 'partial reply' }], stopReason, errorMessage: 'provider failed' };
207
- const terminalMessages = [
208
- { role: 'assistant', content: [{ type: 'toolCall', id: key, name: 'bash', arguments: { command: 'true' } }] },
209
- ];
210
- if (stopReason === 'error') {
211
- terminalMessages.push({ role: 'toolResult', toolCallId: key, toolName: 'bash', content: [{ type: 'text', text: 'ok' }], isError: false });
212
- }
213
- terminalMessages.push(terminalMessage);
214
- const terminal = await summarizedGroup(terminalMessages, key);
215
- assert.equal(terminal.hidden.has(terminal.group.recap), false, `${stopReason} does not suppress the preceding valid recap`);
216
- assert.ok(terminal.group.members.every((member) => terminal.hidden.has(member)), `${stopReason} leaves preceding tool rows folded`);
217
- const visibleBoundary = terminal.children
218
- .filter((component) => component !== terminal.group.recap && !terminal.hidden.has(component))
219
- .flatMap((component) => component.render(80))
220
- .join('\n');
221
- assert.match(visibleBoundary, stopReason === 'aborted' ? /Operation aborted|Interrupted/ : /partial reply|provider failed/, `${stopReason} assistant ending remains visible outside the folded group`);
222
- }
223
- });
224
- test('streamed aborted/error endings stay visible while the preceding summarized tools remain folded', () => {
225
- for (const stopReason of ['aborted', 'error']) {
226
- const view = new ChatView(new TUI(fakeTerminal()), new Container());
227
- const internals = view;
228
- internals.foldSettledTools = true;
229
- internals.showGroupSummaries = true;
230
- const key = `live-${stopReason}`;
231
- view.handleEvent({ type: 'message_start', message: { role: 'assistant', content: [] } });
232
- view.handleEvent({ type: 'tool_execution_start', toolCallId: key, toolName: 'bash', args: { command: 'true' } });
233
- if (stopReason === 'error') {
234
- view.handleEvent({ type: 'tool_execution_end', toolCallId: key, result: { content: [{ type: 'text', text: 'ok' }] }, isError: false });
235
- }
236
- view.applyToolGroupSummary(key, { bullets: ['broker recap'], nodesSpawned: 0, filesEdited: 0 });
237
- const group = internals.groups.find((candidate) => candidate.key === key);
238
- assert.ok(group, `missing ${stopReason} live group`);
239
- assert.equal(internals.historyContainer.hiddenChildren.has(group.recap), stopReason === 'aborted', 'only an in-flight call holds back an early recap');
240
- const content = stopReason === 'aborted' ? [] : [{ type: 'text', text: 'partial reply' }];
241
- if (content.length > 0) {
242
- view.handleEvent({ type: 'message_update', message: { role: 'assistant', content } });
243
- }
244
- view.handleEvent({ type: 'message_end', message: { role: 'assistant', content, stopReason, errorMessage: 'provider failed' } });
245
- view.applyToolGroupSummary(key, { bullets: ['broker recap'], nodesSpawned: 0, filesEdited: 0 });
246
- assert.equal(internals.historyContainer.hiddenChildren.has(group.recap), false, `${stopReason} does not suppress the preceding streamed recap`);
247
- assert.ok(group.members.every((member) => internals.historyContainer.hiddenChildren.has(member)), `${stopReason} leaves preceding streamed tool rows folded`);
248
- const visibleBoundary = internals.historyContainer.children
249
- .filter((component) => component !== group.recap && !internals.historyContainer.hiddenChildren.has(component))
250
- .flatMap((component) => component.render(80))
251
- .join('\n');
252
- assert.match(visibleBoundary, stopReason === 'aborted' ? /Interrupted/ : /partial reply|provider failed/, `${stopReason} streamed assistant ending remains visible outside the folded group`);
253
- }
44
+ test('a summarized group folds its settled calls but never hides an errored assistant ending', async () => {
45
+ const key = 'terminal-error';
46
+ const terminal = await summarizedGroup([
47
+ { role: 'assistant', content: [{ type: 'toolCall', id: key, name: 'bash', arguments: { command: 'true' } }] },
48
+ { role: 'toolResult', toolCallId: key, toolName: 'bash', content: [{ type: 'text', text: 'ok' }], isError: false },
49
+ { role: 'assistant', content: [{ type: 'text', text: 'partial reply' }], stopReason: 'error', errorMessage: 'provider failed' },
50
+ ], key);
51
+ assert.equal(terminal.hidden.has(terminal.group.recap), false, 'the valid recap is not suppressed by the failed ending');
52
+ assert.ok(terminal.group.members.every((member) => terminal.hidden.has(member)), 'preceding tool rows stay folded');
53
+ const visibleBoundary = terminal.children
54
+ .filter((component) => component !== terminal.group.recap && !terminal.hidden.has(component))
55
+ .flatMap((component) => component.render(80))
56
+ .join('\n');
57
+ assert.match(visibleBoundary, /partial reply|provider failed/, 'the failed assistant ending remains visible outside the folded group');
254
58
  });
255
- test('only the exact runtime-restart continuation closes an attach tool group', async () => {
256
- assert.equal(isRuntimeRestartContinuation({ role: 'user', content: RUNTIME_RESTART_CONTINUATION }), true);
257
- assert.equal(isRuntimeRestartContinuation({ role: 'user', content: AUTH_FAULT_RECOVERY_BODY }), false);
258
- const runtimeView = new ChatView(new TUI(fakeTerminal()), new Container());
259
- await runtimeView.applySnapshot(snapshotWithContinuation(RUNTIME_RESTART_CONTINUATION));
260
- const runtimeGroups = runtimeView.groups;
261
- assert.deepEqual(runtimeGroups.map((group) => group.key), ['before', 'after']);
262
- const recoveryView = new ChatView(new TUI(fakeTerminal()), new Container());
263
- await recoveryView.applySnapshot(snapshotWithContinuation(AUTH_FAULT_RECOVERY_BODY));
264
- const recoveryGroups = recoveryView.groups;
265
- assert.deepEqual(recoveryGroups.map((group) => group.key), ['before']);
59
+ test('a folded recap carries paths and counts, never diff or write payload bodies', () => {
60
+ const recorder = new GroupActivityRecorder('/tmp/activity');
61
+ recorder.noteCall('edit', 'edit', { path: 'overwritten.ts' });
62
+ recorder.settle('edit', { details: { diff: '-1 sensitive-old-diff\n+1 sensitive-new-diff' } }, false);
63
+ recorder.noteCall('write', 'write', { path: 'overwritten.ts', content: 'sensitive-write-payload' });
64
+ recorder.settle('write', {}, false);
65
+ const tone = (key) => (text) => `[${key}]${text}`;
66
+ const palette = {
67
+ accent: tone('accent'), active: tone('active'), info: tone('info'), muted: tone('muted'),
68
+ faint: tone('faint'), border: tone('border'), surface: tone('surface'), bold: tone('bold'),
69
+ error: tone('error'), warning: tone('warning'), diffAdded: tone('diffAdded'), diffRemoved: tone('diffRemoved'),
70
+ bashMode: tone('bashMode'), bashModeAlt: tone('bashModeAlt'),
71
+ };
72
+ const recap = new GroupRecapComponent();
73
+ recap.setRecap({ bullets: ['finished'], nodesSpawned: 0, filesEdited: 2 }, 2, { memories: [{ action: 'read', name: 'alpha', path: '/tmp/memories/alpha.md' }], files: recorder.activity().files }, true, palette);
74
+ const text = recap.render(120).join('\n');
75
+ assert.match(text, /overwritten\.ts/, 'the recap still names what changed');
76
+ assert.doesNotMatch(text, /sensitive-old-diff|sensitive-new-diff|sensitive-write-payload/, 'payload bodies never leak into a recap');
266
77
  });
@@ -1,44 +1,23 @@
1
1
  // oauth-dialog-lifecycle.test.ts — review mrf68z4h (OAuth dialog lifecycle).
2
2
  //
3
- // Two attach-viewer regressions, proven against a REAL InputController built from
4
- // minimal fakes:
5
- //
6
- // A. An unrelated extension `notify` must NOT tear down a blocking dialog whose
7
- // broker request is still pending. (The old code dismissed the active dialog
8
- // on ANY notify — leaving the request unanswered in the broker and the user
9
- // with no way to answer it.)
10
- // B. A broker-driven `extension_ui_dismiss` (the correlated cleanup emitted when
11
- // a dialog's request is aborted/timed out out-of-band) tears down ONLY the
12
- // overlay whose id matches, never an unrelated one.
13
- //
14
- // Plus the same hazard for the display half of pi's uniform envelope: once
15
- // setStatus/setWidget/setTitle travel as `extension_ui_request`, a chrome paint
16
- // reaching `attachDialog` would orphan an in-flight dialog the same way (A).
3
+ // The demonstrated regression: an unrelated extension `notify` tore down a
4
+ // blocking dialog whose broker request was still pending, orphaning the request
5
+ // so the user could never finish login. Teardown is correlated — only the
6
+ // `extension_ui_dismiss` carrying this dialog's own request id closes it.
7
+ // Proven against a REAL InputController built from minimal fakes.
17
8
  import { test } from 'node:test';
18
9
  import assert from 'node:assert/strict';
19
10
  import { initTheme } from '@earendil-works/pi-coding-agent';
20
11
  import { InputController } from '../input/controller.js';
12
+ import { createViewerCapabilities } from '../input/capabilities.js';
21
13
  // pi's ExtensionInputComponent reads the process-global theme in its constructor
22
14
  // (the broker calls initTheme() at boot); initialize it once so renderDialog can
23
15
  // build a real dialog component here.
24
16
  initTheme(undefined, false);
25
- function fakeEditor() {
26
- const actions = new Map();
27
- const obj = {
28
- onSubmit: undefined,
29
- onEscape: undefined,
30
- onPasteImage: undefined,
31
- onAction: (name, cb) => { actions.set(name, cb); },
32
- getText: () => '',
33
- setText: () => { },
34
- addToHistory: () => { },
35
- insertTextAtCursor: () => { },
36
- };
37
- return { obj };
38
- }
39
17
  /** A TUI fake whose `showOverlay` returns a handle whose `hide()` is observable,
40
18
  * so a test can tell whether a dialog was actually torn down. */
41
- function fakeTui() {
19
+ function buildController() {
20
+ const notices = [];
42
21
  const hides = [];
43
22
  let seq = 0;
44
23
  const tui = {
@@ -51,17 +30,21 @@ function fakeTui() {
51
30
  start: () => { },
52
31
  stop: () => { },
53
32
  };
54
- return { tui, hides };
55
- }
56
- function buildController() {
57
- const notices = [];
58
- const editor = fakeEditor();
59
- const { tui, hides } = fakeTui();
60
- const ic = new InputController(tui, editor.obj, {}, {
33
+ const editor = {
34
+ onSubmit: undefined,
35
+ onEscape: undefined,
36
+ onPasteImage: undefined,
37
+ onAction: () => { },
38
+ getText: () => '',
39
+ setText: () => { },
40
+ addToHistory: () => { },
41
+ insertTextAtCursor: () => { },
42
+ };
43
+ const ic = new InputController(tui, editor, {}, {
61
44
  onCommand: () => { },
62
45
  onDialogResponse: () => { },
63
46
  onNotice: (m) => notices.push(m),
64
- });
47
+ }, createViewerCapabilities({ role: 'controller', remote: false, nodeId: 'test', profileId: undefined }));
65
48
  return { ic, notices, hides };
66
49
  }
67
50
  const inputDialog = (id) => ({
@@ -71,63 +54,30 @@ const inputDialog = (id) => ({
71
54
  title: 'Paste the redirect URL or code',
72
55
  placeholder: 'http://localhost/callback?...',
73
56
  });
74
- const notify = (message) => ({
75
- type: 'extension_ui_request',
76
- id: 'notify-1',
77
- method: 'notify',
78
- message,
79
- notifyType: 'info',
80
- });
81
57
  test('an unrelated notify does NOT dismiss an active blocking dialog (its broker request stays live)', () => {
82
58
  const { ic, notices, hides } = buildController();
83
59
  ic.attachDialog(inputDialog('oauth-manual-1'));
84
60
  assert.equal(hides.length, 0, 'the dialog overlay is up, not torn down');
85
61
  // An unrelated extension fires a notify while the blocking dialog is showing.
86
- ic.attachDialog(notify('Some unrelated background progress'));
87
- assert.equal(hides.length, 0, 'the blocking dialog must remain on screen — a notify is NOT a dismissal signal');
88
- assert.ok(notices.some((n) => /unrelated background progress/i.test(n)), `the notify still shows as a notice line, got: ${JSON.stringify(notices)}`);
89
- });
90
- test('a display method (setStatus) does NOT dismiss an active blocking dialog', () => {
91
- const { ic, hides } = buildController();
92
- ic.attachDialog(inputDialog('oauth-manual-1'));
93
- assert.equal(hides.length, 0);
94
- // setStatus/setWidget/setTitle ride pi's SAME `extension_ui_request` envelope.
95
- // The viewer routes them to chrome before attachDialog, but a stray one
96
- // reaching here must be inert — never a teardown of a live request.
97
62
  ic.attachDialog({
98
63
  type: 'extension_ui_request',
99
- id: 'status-1',
100
- method: 'setStatus',
101
- statusKey: 'crtr-provider',
102
- statusText: 'anthropic · ok',
64
+ id: 'notify-1',
65
+ method: 'notify',
66
+ message: 'Some unrelated background progress',
67
+ notifyType: 'info',
103
68
  });
104
- assert.equal(hides.length, 0, 'a non-blocking display paint must not tear down the pending dialog');
105
- // And the dialog is still the one the correlated dismiss addresses.
106
- ic.dismissDialog('oauth-manual-1');
107
- assert.equal(hides.length, 1, 'the dialog id was not clobbered by the display request');
69
+ assert.equal(hides.length, 0, 'the blocking dialog must remain on screen — a notify is NOT a dismissal signal');
70
+ assert.ok(notices.some((n) => /unrelated background progress/i.test(n)), `the notify still shows as a notice line, got: ${JSON.stringify(notices)}`);
108
71
  });
109
72
  test('extension_ui_dismiss tears down ONLY the overlay whose request id matches', () => {
110
73
  const { ic, hides } = buildController();
111
74
  ic.attachDialog(inputDialog('oauth-manual-1'));
112
- assert.equal(hides.length, 0);
113
75
  // A dismiss for a DIFFERENT request id must be a no-op.
114
76
  ic.dismissDialog('some-other-request');
115
77
  assert.equal(hides.length, 0, 'a non-matching dismiss must not tear down the current dialog');
116
- // The correlated dismiss for THIS dialog's id tears it down.
117
78
  ic.dismissDialog('oauth-manual-1');
118
79
  assert.equal(hides.length, 1, 'the matching correlated dismiss tears down exactly the current overlay');
119
80
  // Idempotent: a repeat dismiss (or a late one after teardown) is inert.
120
81
  ic.dismissDialog('oauth-manual-1');
121
82
  assert.equal(hides.length, 1, 'a repeat dismiss must not double-tear-down');
122
83
  });
123
- test('a new blocking dialog still supersedes the previous one (correlated dismissal remains isolated)', () => {
124
- const { ic, hides } = buildController();
125
- ic.attachDialog(inputDialog('dialog-a'));
126
- ic.attachDialog(inputDialog('dialog-b'));
127
- assert.equal(hides.length, 1, 'the first dialog is superseded (dismissed) when a second blocking dialog arrives');
128
- // Now a correlated dismiss for the OLD id must not touch the current one.
129
- ic.dismissDialog('dialog-a');
130
- assert.equal(hides.length, 1, 'a stale dismiss for the superseded dialog does not tear down the current one');
131
- ic.dismissDialog('dialog-b');
132
- assert.equal(hides.length, 2, 'the current dialog is torn down by its own correlated dismiss');
133
- });
@@ -1,6 +1,9 @@
1
1
  import assert from 'node:assert/strict';
2
2
  import test from 'node:test';
3
- import { loadedCommandPreview, parsePreviewableCommands } from '../slash/prompt-preview.js';
3
+ import { loadedCommandPreview } from '../slash/prompt-preview.js';
4
+ // A preview that expands placeholders differently from submission misleads the
5
+ // user about what they are about to send, so the live preview must reproduce
6
+ // pi's expansion exactly — and must not fire for a non-previewable invocation.
4
7
  test('live slash prompt preview matches pi placeholder expansion as arguments change', () => {
5
8
  const commands = [{
6
9
  name: 'author',
@@ -16,72 +19,3 @@ test('live slash prompt preview matches pi placeholder expansion as arguments ch
16
19
  assert.equal(loadedCommandPreview('explain /author testing', commands), undefined);
17
20
  assert.equal(loadedCommandPreview('/model', commands), undefined);
18
21
  });
19
- test('deterministic extension preview uses the same raw-argument expansion as /dev submission', () => {
20
- const commands = [{
21
- name: 'dev',
22
- source: 'command',
23
- description: 'operate the local stack',
24
- expansion: {
25
- kind: 'memory-slash',
26
- commandName: 'dev',
27
- body: 'Interpret `$ARGUMENTS` as the requested stack operation.\nThen act.',
28
- },
29
- }];
30
- assert.deepEqual(loadedCommandPreview('/dev restart:stack --carefully ', commands), {
31
- name: 'dev',
32
- invocation: '/dev restart:stack --carefully ',
33
- content: 'Interpret `restart:stack --carefully` as the requested stack operation.\nThen act.',
34
- });
35
- });
36
- test('fresh command metadata replaces a pre-reload expansion before preview recomputes', () => {
37
- const before = parsePreviewableCommands(JSON.stringify([{
38
- name: 'dev', description: 'operate', source: 'command',
39
- expansion: { kind: 'memory-slash', commandName: 'dev', body: 'old $ARGUMENTS' },
40
- }]));
41
- const after = parsePreviewableCommands(JSON.stringify([{
42
- name: 'dev', description: 'operate', source: 'command',
43
- expansion: { kind: 'memory-slash', commandName: 'dev', body: 'new $ARGUMENTS' },
44
- }]));
45
- assert.equal(loadedCommandPreview('/dev restart', before)?.content, 'old restart');
46
- assert.equal(loadedCommandPreview('/dev restart', after)?.content, 'new restart');
47
- });
48
- test('malformed broker command metadata is discarded without breaking valid inventory', () => {
49
- const commands = parsePreviewableCommands(JSON.stringify([
50
- { name: 'safe', description: 'safe', source: 'command', expansion: { kind: 'memory-slash', commandName: 'safe', body: 'ok' } },
51
- { name: 'bad-kind', description: 'bad', source: 'command', expansion: { kind: 'other', commandName: 'bad-kind', body: 'bad' } },
52
- { name: 'bad-body', description: 'bad', source: 'command', expansion: { kind: 'memory-slash', commandName: 'bad-body', body: 3 } },
53
- { name: 'bad-template', description: 'bad', source: 'template', template: {} },
54
- ]));
55
- assert.deepEqual(commands.map((command) => command.name), ['safe']);
56
- assert.equal(loadedCommandPreview('/safe', commands)?.content.includes('ok'), true);
57
- });
58
- test('submission precedence prevents previews for shadowed templates', () => {
59
- const template = { name: 'model', source: 'template', template: 'misleading prompt' };
60
- assert.equal(loadedCommandPreview('/model', [
61
- { name: 'model', source: 'builtin' },
62
- template,
63
- ]), undefined, 'viewer builtin wins before template');
64
- assert.equal(loadedCommandPreview('/dev now', [
65
- { name: 'dev', source: 'command' },
66
- { name: 'dev', source: 'template', template: 'also misleading' },
67
- ]), undefined, 'non-previewable extension command wins before template');
68
- });
69
- test('extension previews use pi ASCII-space matching while templates retain whitespace matching', () => {
70
- const commands = [{
71
- name: 'dev', source: 'command', description: 'extension',
72
- expansion: { kind: 'memory-slash', commandName: 'dev', body: 'extension: $ARGUMENTS' },
73
- }, {
74
- name: 'dev', source: 'template', description: 'template', template: 'template: $ARGUMENTS',
75
- }];
76
- assert.equal(loadedCommandPreview('/dev literal space', commands)?.content, 'extension: literal space');
77
- assert.equal(loadedCommandPreview('/dev\ttab arg', commands)?.content, 'template: tab arg');
78
- assert.equal(loadedCommandPreview('/dev\nnewline arg', commands)?.content, 'template: newline arg');
79
- });
80
- test('an empty command inventory clears a loaded preview while fresh metadata is pending', () => {
81
- const commands = [{
82
- name: 'dev', source: 'command', description: 'extension',
83
- expansion: { kind: 'memory-slash', commandName: 'dev', body: 'old $ARGUMENTS' },
84
- }];
85
- assert.equal(loadedCommandPreview('/dev restart', commands)?.content, 'old restart');
86
- assert.equal(loadedCommandPreview('/dev restart', []), undefined);
87
- });