@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
@@ -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
- });