@north-light/crouter 0.3.170 → 0.3.172

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 (670) hide show
  1. package/dist/api/client.d.ts +37 -11
  2. package/dist/api/client.js +84 -15
  3. package/dist/api/dto/human.d.ts +53 -39
  4. package/dist/api/dto/human.js +2 -3
  5. package/dist/api/dto/inbox.d.ts +0 -1
  6. package/dist/api/dto/nodes.d.ts +12 -0
  7. package/dist/api/dto/review-comments.d.ts +137 -0
  8. package/dist/api/dto/review-comments.js +5 -0
  9. package/dist/api/dto/reviews.d.ts +109 -0
  10. package/dist/api/dto/reviews.js +5 -0
  11. package/dist/api/index.d.ts +2 -0
  12. package/dist/api/index.js +2 -0
  13. package/dist/api/routes.d.ts +17 -4
  14. package/dist/api/routes.js +21 -5
  15. package/dist/build-root.d.ts +1 -16
  16. package/dist/build-root.js +1 -25
  17. package/dist/builtin-memory/00-runtime-base.md +7 -5
  18. package/dist/builtin-memory/04-base-worker.md +1 -1
  19. package/dist/builtin-memory/04-orchestration-kernel.md +7 -7
  20. package/dist/builtin-memory/05-kinds/design/00-base.md +1 -1
  21. package/dist/builtin-memory/05-kinds/design/01-orchestrator.md +1 -1
  22. package/dist/builtin-memory/05-kinds/developer/00-base.md +1 -1
  23. package/dist/builtin-memory/05-kinds/explore/00-base.md +1 -1
  24. package/dist/builtin-memory/05-kinds/plan/00-base.md +1 -1
  25. package/dist/builtin-memory/05-kinds/plan/01-orchestrator.md +1 -1
  26. package/dist/builtin-memory/05-kinds/review/00-base.md +1 -1
  27. package/dist/builtin-memory/05-kinds/review/companion/00-base.md +20 -0
  28. package/dist/builtin-memory/05-kinds/spec/00-base.md +3 -7
  29. package/dist/builtin-memory/05-kinds/spec/01-orchestrator.md +3 -3
  30. package/dist/builtin-memory/05-kinds/spec/requirements.md +3 -3
  31. package/dist/builtin-memory/design.md +2 -2
  32. package/dist/builtin-memory/insights/capture.md +50 -0
  33. package/dist/builtin-memory/insights/init.md +45 -0
  34. package/dist/builtin-memory/insights/listen.md +9 -0
  35. package/dist/builtin-memory/internal/agent-shaping.md +2 -2
  36. package/dist/builtin-memory/internal/nodes-and-canvas.md +1 -1
  37. package/dist/builtin-memory/internal/plugins.md +12 -11
  38. package/dist/builtin-memory/internal/storage-tiers.md +2 -2
  39. package/dist/builtin-memory/{planning.md → plan/roadmap.md} +3 -3
  40. package/dist/builtin-memory/plan.md +19 -0
  41. package/dist/builtin-memory/spec/guide.md +38 -0
  42. package/dist/builtin-memory/spec/requirements.md +31 -0
  43. package/dist/builtin-memory/spec/roadmap.md +35 -0
  44. package/dist/builtin-memory/spec.md +10 -86
  45. package/dist/builtin-pi-packages/pi-crtr-extensions/README.md +3 -4
  46. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/__tests__/provider-rotation.test.ts +49 -5
  47. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.d.ts +56 -0
  48. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.js +920 -0
  49. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.ts +221 -156
  50. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/statusline.ts +4 -5
  51. package/dist/cli.js +2 -6
  52. package/dist/clients/attach/__tests__/attach-chrome-remote.test.js +7 -35
  53. package/dist/clients/attach/__tests__/attach-keybindings.test.js +32 -16
  54. package/dist/clients/attach/__tests__/context-message.test.js +142 -6
  55. package/dist/clients/attach/__tests__/crtr-output.test.js +29 -45
  56. package/dist/clients/attach/__tests__/diagram.test.js +1 -1
  57. package/dist/clients/attach/__tests__/file-review-focus.test.js +48 -0
  58. package/dist/clients/attach/__tests__/group-activity.test.js +266 -0
  59. package/dist/clients/attach/__tests__/input-controller-extension-command.test.js +32 -0
  60. package/dist/clients/attach/__tests__/session-identity-refresh.test.js +32 -0
  61. package/dist/clients/attach/__tests__/titled-editor-preview.test.js +1 -2
  62. package/dist/clients/attach/chrome/header.d.ts +10 -0
  63. package/dist/clients/attach/chrome/header.js +30 -0
  64. package/dist/clients/attach/chrome/recap.d.ts +7 -0
  65. package/dist/clients/attach/chrome/recap.js +19 -0
  66. package/dist/clients/attach/chrome/status-line.d.ts +3 -0
  67. package/dist/clients/attach/chrome/status-line.js +5 -0
  68. package/dist/clients/attach/chrome/widgets.js +11 -21
  69. package/dist/clients/attach/command.js +11 -7
  70. package/dist/clients/attach/config.d.ts +4 -0
  71. package/dist/clients/attach/config.js +3 -0
  72. package/dist/clients/attach/input/controller.d.ts +19 -0
  73. package/dist/clients/attach/input/controller.js +62 -28
  74. package/dist/clients/attach/input/titled-editor.d.ts +0 -4
  75. package/dist/clients/attach/input/titled-editor.js +2 -10
  76. package/dist/clients/attach/overlays/file-review.d.ts +9 -5
  77. package/dist/clients/attach/overlays/file-review.js +9 -70
  78. package/dist/clients/attach/overlays/help.d.ts +33 -0
  79. package/dist/clients/attach/overlays/help.js +204 -0
  80. package/dist/clients/attach/render/activity-slot.d.ts +4 -0
  81. package/dist/clients/attach/render/activity-slot.js +13 -0
  82. package/dist/clients/attach/render/chat-view.d.ts +117 -12
  83. package/dist/clients/attach/render/chat-view.js +604 -135
  84. package/dist/clients/attach/render/context-message.d.ts +2 -1
  85. package/dist/clients/attach/render/context-message.js +17 -13
  86. package/dist/clients/attach/render/crtr-output.js +1 -3
  87. package/dist/clients/attach/render/diagram.js +2 -2
  88. package/dist/clients/attach/render/edit-diff.d.ts +4 -1
  89. package/dist/clients/attach/render/edit-diff.js +7 -11
  90. package/dist/clients/attach/render/group-activity.d.ts +32 -0
  91. package/dist/clients/attach/render/group-activity.js +206 -0
  92. package/dist/clients/attach/render/group-recap.d.ts +10 -0
  93. package/dist/clients/attach/render/group-recap.js +93 -0
  94. package/dist/clients/attach/render/html-markdown.d.ts +17 -0
  95. package/dist/clients/attach/render/html-markdown.js +228 -0
  96. package/dist/clients/attach/render/measured-container.d.ts +96 -0
  97. package/dist/clients/attach/render/measured-container.js +322 -0
  98. package/dist/clients/attach/render/scroll-animation.d.ts +8 -0
  99. package/dist/clients/attach/render/scroll-animation.js +80 -0
  100. package/dist/clients/attach/render/tool-calls.js +6 -6
  101. package/dist/clients/attach/render/transcript-copy.d.ts +9 -0
  102. package/dist/clients/attach/render/transcript-copy.js +81 -0
  103. package/dist/clients/attach/render/viewport.d.ts +29 -0
  104. package/dist/clients/attach/render/viewport.js +159 -0
  105. package/dist/clients/attach/session/bindings.d.ts +10 -7
  106. package/dist/clients/attach/session/bindings.js +23 -8
  107. package/dist/clients/attach/session/connection.js +4 -5
  108. package/dist/clients/attach/session/context.d.ts +6 -4
  109. package/dist/clients/attach/session/frame.d.ts +34 -0
  110. package/dist/clients/attach/session/frame.js +176 -0
  111. package/dist/clients/attach/session/frames.d.ts +4 -1
  112. package/dist/clients/attach/session/frames.js +14 -1
  113. package/dist/clients/attach/session/identity.js +4 -3
  114. package/dist/clients/attach/session/input-wiring.d.ts +14 -4
  115. package/dist/clients/attach/session/input-wiring.js +15 -13
  116. package/dist/clients/attach/session/invariant.d.ts +9 -0
  117. package/dist/clients/attach/session/invariant.js +15 -0
  118. package/dist/clients/attach/session/keys.d.ts +10 -2
  119. package/dist/clients/attach/session/keys.js +13 -5
  120. package/dist/clients/attach/session/layout.d.ts +10 -8
  121. package/dist/clients/attach/session/layout.js +33 -34
  122. package/dist/clients/attach/session/mouse.d.ts +18 -0
  123. package/dist/clients/attach/session/mouse.js +64 -0
  124. package/dist/clients/attach/session/pane-tag.d.ts +3 -0
  125. package/dist/clients/attach/session/pane-tag.js +51 -8
  126. package/dist/clients/attach/session/reconnect.d.ts +3 -0
  127. package/dist/clients/attach/session/reconnect.js +42 -5
  128. package/dist/clients/attach/session/surface-frame.d.ts +20 -0
  129. package/dist/clients/attach/session/surface-frame.js +73 -0
  130. package/dist/clients/attach/session/surface-host.d.ts +64 -0
  131. package/dist/clients/attach/session/surface-host.js +255 -0
  132. package/dist/clients/attach/session/whip.d.ts +17 -0
  133. package/dist/clients/attach/session/whip.js +334 -0
  134. package/dist/clients/attach/slash/dispatch.d.ts +13 -1
  135. package/dist/clients/attach/slash/dispatch.js +51 -29
  136. package/dist/clients/attach/viewer.js +907 -819
  137. package/dist/clients/conversation/conversation.d.ts +65 -0
  138. package/dist/clients/conversation/conversation.js +318 -0
  139. package/dist/clients/conversation/frames.d.ts +30 -0
  140. package/dist/clients/conversation/frames.js +52 -0
  141. package/dist/clients/conversation/region.d.ts +51 -0
  142. package/dist/clients/conversation/region.js +265 -0
  143. package/dist/clients/conversation/submit.d.ts +38 -0
  144. package/dist/clients/conversation/submit.js +51 -0
  145. package/dist/clients/inbox/__tests__/inbox-controller.test.js +247 -0
  146. package/dist/clients/inbox/__tests__/mount-panel.test.js +776 -0
  147. package/dist/clients/inbox/controller.d.ts +79 -0
  148. package/dist/clients/inbox/controller.js +448 -0
  149. package/dist/clients/inbox/deck-adapter.d.ts +29 -0
  150. package/dist/clients/inbox/deck-adapter.js +62 -0
  151. package/dist/clients/inbox/layout.d.ts +8 -0
  152. package/dist/clients/inbox/layout.js +9 -0
  153. package/dist/clients/inbox/resolve.d.ts +10 -0
  154. package/dist/clients/inbox/resolve.js +34 -0
  155. package/dist/clients/inbox/review/__tests__/editor-roundtrip.test.js +29 -0
  156. package/dist/clients/inbox/review/__tests__/remap.test.js +196 -0
  157. package/dist/clients/inbox/review/__tests__/review-core.test.js +341 -0
  158. package/dist/clients/inbox/review/anchors.d.ts +41 -0
  159. package/dist/clients/inbox/review/anchors.js +89 -0
  160. package/dist/clients/inbox/review/columns.d.ts +22 -0
  161. package/dist/clients/inbox/review/columns.js +40 -0
  162. package/dist/clients/inbox/review/comments-client.d.ts +66 -0
  163. package/dist/clients/inbox/review/comments-client.js +98 -0
  164. package/dist/clients/inbox/review/composition.d.ts +60 -0
  165. package/dist/clients/inbox/review/composition.js +278 -0
  166. package/dist/clients/inbox/review/document-region.d.ts +120 -0
  167. package/dist/clients/inbox/review/document-region.js +902 -0
  168. package/dist/clients/inbox/review/frame.d.ts +45 -0
  169. package/dist/clients/inbox/review/frame.js +215 -0
  170. package/dist/clients/inbox/review/keys.d.ts +67 -0
  171. package/dist/clients/inbox/review/keys.js +130 -0
  172. package/dist/clients/inbox/review/launch.d.ts +10 -0
  173. package/dist/clients/inbox/review/launch.js +129 -0
  174. package/dist/clients/inbox/review/live-source.d.ts +24 -0
  175. package/dist/clients/inbox/review/live-source.js +160 -0
  176. package/dist/clients/inbox/review/nvim.d.ts +13 -0
  177. package/dist/clients/inbox/review/nvim.js +42 -0
  178. package/dist/clients/inbox/review/remap.d.ts +51 -0
  179. package/dist/clients/inbox/review/remap.js +157 -0
  180. package/dist/clients/inbox/review/review-client.d.ts +30 -0
  181. package/dist/clients/inbox/review/review-client.js +107 -0
  182. package/dist/clients/inbox/review/roundtrip.d.ts +5 -0
  183. package/dist/clients/inbox/review/roundtrip.js +36 -0
  184. package/dist/clients/inbox/review/state.d.ts +143 -0
  185. package/dist/clients/inbox/review/state.js +282 -0
  186. package/dist/clients/inbox/review-adapter.d.ts +29 -0
  187. package/dist/clients/inbox/review-adapter.js +92 -0
  188. package/dist/clients/inbox/review-visibility.d.ts +5 -0
  189. package/dist/clients/inbox/review-visibility.js +19 -0
  190. package/dist/clients/inbox/surface.d.ts +19 -0
  191. package/dist/clients/inbox/surface.js +128 -0
  192. package/dist/clients/inbox/tui/ansi.d.ts +66 -0
  193. package/dist/clients/inbox/tui/ansi.js +317 -0
  194. package/dist/clients/inbox/tui/clipboard.d.ts +2 -0
  195. package/dist/clients/inbox/tui/clipboard.js +26 -0
  196. package/dist/clients/inbox/tui/input.d.ts +7 -0
  197. package/dist/clients/inbox/tui/input.js +653 -0
  198. package/dist/clients/inbox/tui/keys.d.ts +28 -0
  199. package/dist/clients/inbox/tui/keys.js +111 -0
  200. package/dist/clients/inbox/tui/panel.d.ts +2 -0
  201. package/dist/clients/inbox/tui/panel.js +217 -0
  202. package/dist/clients/inbox/tui/render.d.ts +37 -0
  203. package/dist/clients/inbox/tui/render.js +476 -0
  204. package/dist/clients/inbox/tui/types.d.ts +57 -0
  205. package/dist/clients/inbox/tui/types.js +1 -0
  206. package/dist/clients/inbox/tui.d.ts +6 -0
  207. package/dist/clients/inbox/tui.js +74 -0
  208. package/dist/clients/surfaces/host.d.ts +66 -0
  209. package/dist/clients/surfaces/host.js +1 -0
  210. package/dist/clients/surfaces/region.d.ts +16 -0
  211. package/dist/clients/surfaces/region.js +1 -0
  212. package/dist/clients/web/__tests__/push-engine.test.js +14 -158
  213. package/dist/clients/web/dev-server.d.ts +3 -3
  214. package/dist/clients/web/dev-server.js +9 -23
  215. package/dist/clients/web/events.js +4 -6
  216. package/dist/clients/web/push-engine.d.ts +2 -66
  217. package/dist/clients/web/push-engine.js +30 -161
  218. package/dist/clients/web/push-registry.d.ts +0 -4
  219. package/dist/clients/web/push-registry.js +2 -7
  220. package/dist/clients/web/server.js +3 -35
  221. package/dist/clients/web/web-client/shared/protocol.d.ts +0 -108
  222. package/dist/clients/web/web-cmd.js +2 -2
  223. package/dist/commands/__tests__/human.test.js +27 -15
  224. package/dist/commands/api-client.js +3 -3
  225. package/dist/commands/canvas-browse.js +1 -1
  226. package/dist/commands/canvas-issue.js +1 -1
  227. package/dist/commands/canvas-use.js +1 -1
  228. package/dist/commands/human/doc.d.ts +2 -0
  229. package/dist/commands/human/doc.js +98 -0
  230. package/dist/commands/human/inbox.d.ts +2 -0
  231. package/dist/commands/human/inbox.js +101 -0
  232. package/dist/commands/human/prompts.d.ts +2 -3
  233. package/dist/commands/human/prompts.js +27 -180
  234. package/dist/commands/human/queue.d.ts +1 -5
  235. package/dist/commands/human/queue.js +54 -216
  236. package/dist/commands/human/review.d.ts +2 -0
  237. package/dist/commands/human/review.js +298 -0
  238. package/dist/commands/human/shared.d.ts +2 -69
  239. package/dist/commands/human/shared.js +1 -181
  240. package/dist/commands/human.js +15 -20
  241. package/dist/commands/memory/__tests__/lint.test.d.ts +1 -0
  242. package/dist/commands/memory/__tests__/lint.test.js +15 -0
  243. package/dist/commands/memory/delete.js +2 -2
  244. package/dist/commands/memory/lint.d.ts +1 -0
  245. package/dist/commands/memory/lint.js +21 -3
  246. package/dist/commands/memory/read.js +4 -4
  247. package/dist/commands/node.js +8 -7
  248. package/dist/commands/pkg/plugin-manage.js +143 -68
  249. package/dist/commands/surface-inspect.js +2 -2
  250. package/dist/commands/surface.js +6 -12
  251. package/dist/commands/sys/__tests__/setup-core.test.js +9 -5
  252. package/dist/commands/sys/__tests__/setup-front-door.test.js +7 -42
  253. package/dist/commands/sys/config.js +29 -3
  254. package/dist/commands/sys/feedback.js +1 -1
  255. package/dist/commands/sys/setup-core.d.ts +12 -11
  256. package/dist/commands/sys/setup-core.js +55 -46
  257. package/dist/commands/sys/setup-wizard.d.ts +4 -1
  258. package/dist/commands/sys/setup-wizard.js +50 -9
  259. package/dist/commands/sys/sync-deps.js +1 -1
  260. package/dist/commands/sys.js +4 -6
  261. package/dist/core/__tests__/broker-sdk-wiring.test.js +6 -1
  262. package/dist/core/__tests__/broker-snapshot-history.test.js +9 -1
  263. package/dist/core/__tests__/dead-node-policy-table.test.js +3 -4
  264. package/dist/core/__tests__/fixtures/fake-engine.d.ts +8 -5
  265. package/dist/core/__tests__/fixtures/fake-engine.js +28 -2
  266. package/dist/core/__tests__/full/broker-provider-retry.test.js +87 -2
  267. package/dist/core/__tests__/full/broker-whip-interrupt.test.d.ts +1 -0
  268. package/dist/core/__tests__/full/broker-whip-interrupt.test.js +39 -0
  269. package/dist/core/__tests__/full/detach-focus.test.js +1 -1
  270. package/dist/core/__tests__/human-deliver-e2e.test.js +64 -64
  271. package/dist/core/__tests__/human-deliver.test.js +71 -345
  272. package/dist/core/__tests__/inline-memory-refs.test.js +2 -12
  273. package/dist/core/__tests__/memory-resolver-precedence.test.js +12 -15
  274. package/dist/core/__tests__/migration.test.js +10 -0
  275. package/dist/core/__tests__/model-pin-durability.test.js +14 -0
  276. package/dist/core/__tests__/phase4-review-migration.test.d.ts +1 -0
  277. package/dist/core/__tests__/phase4-review-migration.test.js +100 -0
  278. package/dist/core/__tests__/phase4-review-store.test.d.ts +1 -0
  279. package/dist/core/__tests__/phase4-review-store.test.js +143 -0
  280. package/dist/core/__tests__/remote-canvas-target.test.js +2 -2
  281. package/dist/core/__tests__/revive.test.js +22 -53
  282. package/dist/core/__tests__/session-cycles.test.js +48 -18
  283. package/dist/core/__tests__/spawn-no-kickoff.test.js +8 -12
  284. package/dist/core/__tests__/stop-guard.test.js +16 -1
  285. package/dist/core/__tests__/tmux-surface.test.js +21 -25
  286. package/dist/core/asset-root.d.ts +7 -0
  287. package/dist/core/asset-root.js +18 -0
  288. package/dist/core/broker-client/client.d.ts +0 -7
  289. package/dist/core/broker-client/client.js +4 -10
  290. package/dist/core/broker-client/transport-relay.d.ts +3 -4
  291. package/dist/core/broker-client/transport-relay.js +3 -4
  292. package/dist/core/canvas/__tests__/attention.test.js +1 -1
  293. package/dist/core/canvas/__tests__/remote-canvas-source.test.js +1 -1
  294. package/dist/core/canvas/__tests__/remote-transport.test.d.ts +1 -0
  295. package/dist/core/{view/__tests__/transport-remote.test.js → canvas/__tests__/remote-transport.test.js} +2 -2
  296. package/dist/core/canvas/__tests__/render-remote.test.js +1 -1
  297. package/dist/core/canvas/attention.js +4 -4
  298. package/dist/core/canvas/canvas.d.ts +6 -11
  299. package/dist/core/canvas/canvas.js +11 -33
  300. package/dist/core/canvas/db.js +207 -38
  301. package/dist/core/canvas/extensions.d.ts +1 -1
  302. package/dist/core/canvas/extensions.js +8 -1
  303. package/dist/core/canvas/index.d.ts +0 -1
  304. package/dist/core/canvas/index.js +0 -1
  305. package/dist/core/canvas/nav-model.d.ts +1 -1
  306. package/dist/core/canvas/nav-model.js +1 -1
  307. package/dist/core/canvas/paths.d.ts +5 -0
  308. package/dist/core/canvas/paths.js +16 -0
  309. package/dist/core/canvas/remote-canvas-source.js +2 -2
  310. package/dist/core/canvas/remote-transport.d.ts +7 -0
  311. package/dist/core/{view/transport-remote.js → canvas/remote-transport.js} +3 -4
  312. package/dist/core/canvas/source.js +1 -1
  313. package/dist/core/canvas/status-glyph.js +4 -12
  314. package/dist/core/canvas/types.d.ts +10 -35
  315. package/dist/core/clipboard-text.d.ts +8 -0
  316. package/dist/core/clipboard-text.js +18 -0
  317. package/dist/core/command-manifests/registry.d.ts +1 -3
  318. package/dist/core/command-plugins/bundle.d.ts +29 -0
  319. package/dist/core/command-plugins/bundle.js +198 -0
  320. package/dist/core/command-plugins/discovery.d.ts +0 -8
  321. package/dist/core/command-plugins/discovery.js +2 -39
  322. package/dist/core/command-plugins/transport/http-fetch.d.ts +4 -30
  323. package/dist/core/command-plugins/transport/http-fetch.js +17 -95
  324. package/dist/core/command.d.ts +1 -13
  325. package/dist/core/command.js +1 -16
  326. package/dist/core/config.d.ts +4 -0
  327. package/dist/core/config.js +28 -3
  328. package/dist/core/document-lines.d.ts +4 -0
  329. package/dist/core/document-lines.js +6 -0
  330. package/dist/core/feed/feed.d.ts +2 -0
  331. package/dist/core/feed/feed.js +11 -7
  332. package/dist/core/human/__tests__/inbox-cancel-worker.d.ts +1 -0
  333. package/dist/core/human/__tests__/inbox-cancel-worker.js +7 -0
  334. package/dist/core/human/__tests__/inbox-claim-worker.d.ts +1 -0
  335. package/dist/core/human/__tests__/inbox-claim-worker.js +17 -0
  336. package/dist/core/human/__tests__/inbox-core.test.d.ts +1 -0
  337. package/dist/core/human/__tests__/inbox-core.test.js +144 -0
  338. package/dist/core/human/__tests__/inbox-stale-claim-worker.d.ts +1 -0
  339. package/dist/core/human/__tests__/inbox-stale-claim-worker.js +8 -0
  340. package/dist/core/human/__tests__/visible-paths.test.d.ts +1 -0
  341. package/dist/{clients/attach → core/human}/__tests__/visible-paths.test.js +9 -0
  342. package/dist/core/human/claim.d.ts +23 -0
  343. package/dist/core/human/claim.js +67 -0
  344. package/dist/core/human/convention.d.ts +30 -0
  345. package/dist/core/human/convention.js +202 -0
  346. package/dist/core/human/deck-factories.d.ts +8 -0
  347. package/dist/core/human/deck-factories.js +15 -0
  348. package/dist/core/human/deck-schema.d.ts +70 -0
  349. package/dist/core/human/deck-schema.js +92 -0
  350. package/dist/core/human/root.d.ts +7 -0
  351. package/dist/core/human/root.js +37 -0
  352. package/dist/core/human/scan.d.ts +3 -0
  353. package/dist/core/human/scan.js +76 -0
  354. package/dist/core/human/summary.d.ts +8 -0
  355. package/dist/core/human/summary.js +44 -0
  356. package/dist/core/human/tickets.d.ts +49 -0
  357. package/dist/core/human/tickets.js +190 -0
  358. package/dist/core/human/types.d.ts +136 -0
  359. package/dist/core/human/types.js +5 -0
  360. package/dist/{clients/attach → core/human}/visible-paths.d.ts +1 -1
  361. package/dist/{clients/attach → core/human}/visible-paths.js +3 -2
  362. package/dist/core/inspector/chrome.d.ts +6 -0
  363. package/dist/core/inspector/chrome.js +14 -0
  364. package/dist/core/inspector/contract.d.ts +105 -0
  365. package/dist/core/inspector/contract.js +1 -0
  366. package/dist/core/inspector/core.d.ts +4 -5
  367. package/dist/core/inspector/core.js +3 -5
  368. package/dist/core/inspector/host.d.ts +46 -0
  369. package/dist/core/{tui → inspector}/host.js +42 -208
  370. package/dist/core/inspector/text.d.ts +2 -2
  371. package/dist/core/inspector/transport.d.ts +6 -0
  372. package/dist/core/inspector/transport.js +36 -0
  373. package/dist/core/inspector/tui.d.ts +2 -2
  374. package/dist/core/inspector/tui.js +15 -15
  375. package/dist/core/keybindings/__tests__/inbox-affordance.test.js +11 -11
  376. package/dist/core/keybindings/__tests__/resolve.test.js +10 -19
  377. package/dist/core/keybindings/attach-control.d.ts +9 -3
  378. package/dist/core/keybindings/attach-control.js +3 -1
  379. package/dist/core/keybindings/catalog.d.ts +6 -5
  380. package/dist/core/keybindings/catalog.js +61 -133
  381. package/dist/core/keybindings/inbox.d.ts +5 -6
  382. package/dist/core/keybindings/inbox.js +9 -10
  383. package/dist/core/keybindings/index.d.ts +3 -3
  384. package/dist/core/keybindings/index.js +3 -3
  385. package/dist/core/keybindings/persistence.d.ts +5 -1
  386. package/dist/core/keybindings/persistence.js +24 -6
  387. package/dist/core/keybindings/resolve.d.ts +6 -0
  388. package/dist/core/keybindings/resolve.js +10 -3
  389. package/dist/core/memory/inline-ref-grammar.js +2 -3
  390. package/dist/core/memory-resolver.d.ts +27 -29
  391. package/dist/core/memory-resolver.js +45 -39
  392. package/dist/core/model-routes.d.ts +33 -0
  393. package/dist/core/model-routes.js +42 -3
  394. package/dist/core/preview-registry.js +17 -55
  395. package/dist/core/profiles/select.js +3 -3
  396. package/dist/core/{view/remote-canvas-target.d.ts → remote-canvas-target.d.ts} +2 -2
  397. package/dist/core/{view/remote-canvas-target.js → remote-canvas-target.js} +4 -4
  398. package/dist/core/review/__tests__/capture-origin.test.d.ts +1 -0
  399. package/dist/core/review/__tests__/capture-origin.test.js +139 -0
  400. package/dist/core/review/__tests__/comments.test.d.ts +1 -0
  401. package/dist/core/review/__tests__/comments.test.js +98 -0
  402. package/dist/core/review/__tests__/project.test.d.ts +1 -0
  403. package/dist/core/review/__tests__/project.test.js +71 -0
  404. package/dist/core/review/__tests__/remap.test.d.ts +1 -0
  405. package/dist/core/review/__tests__/remap.test.js +159 -0
  406. package/dist/core/review/__tests__/stage-identity.test.d.ts +1 -0
  407. package/dist/core/review/__tests__/stage-identity.test.js +140 -0
  408. package/dist/core/review/birth.d.ts +7 -0
  409. package/dist/core/review/birth.js +23 -0
  410. package/dist/core/review/comments.d.ts +69 -0
  411. package/dist/core/review/comments.js +295 -0
  412. package/dist/core/review/companion.d.ts +35 -0
  413. package/dist/core/review/companion.js +205 -0
  414. package/dist/core/review/document.d.ts +27 -0
  415. package/dist/core/review/document.js +138 -0
  416. package/dist/core/review/project.d.ts +13 -0
  417. package/dist/core/review/project.js +58 -0
  418. package/dist/core/review/realize.d.ts +19 -0
  419. package/dist/core/review/realize.js +217 -0
  420. package/dist/core/review/remap.d.ts +24 -0
  421. package/dist/core/review/remap.js +156 -0
  422. package/dist/core/review/signal.d.ts +5 -0
  423. package/dist/core/review/signal.js +31 -0
  424. package/dist/core/review/stage.d.ts +26 -0
  425. package/dist/core/review/stage.js +184 -0
  426. package/dist/core/review/store.d.ts +46 -0
  427. package/dist/core/review/store.js +163 -0
  428. package/dist/core/review/ticket-filter.d.ts +17 -0
  429. package/dist/core/review/ticket-filter.js +32 -0
  430. package/dist/core/review/types.d.ts +130 -0
  431. package/dist/core/review/types.js +23 -0
  432. package/dist/core/runtime/__tests__/session-visibility.test.d.ts +1 -0
  433. package/dist/core/runtime/__tests__/session-visibility.test.js +119 -0
  434. package/dist/core/runtime/bearings.d.ts +5 -17
  435. package/dist/core/runtime/bearings.js +88 -71
  436. package/dist/core/runtime/broker-protocol.d.ts +31 -8
  437. package/dist/core/runtime/broker.d.ts +15 -1
  438. package/dist/core/runtime/broker.js +573 -141
  439. package/dist/core/runtime/canvas-extensions.d.ts +4 -5
  440. package/dist/core/runtime/canvas-extensions.js +5 -5
  441. package/dist/core/runtime/front-door.js +4 -4
  442. package/dist/core/runtime/headless-pi.d.ts +24 -0
  443. package/dist/core/runtime/headless-pi.js +152 -0
  444. package/dist/core/runtime/kickoff.d.ts +1 -5
  445. package/dist/core/runtime/kickoff.js +1 -5
  446. package/dist/core/runtime/model-registry.d.ts +3 -0
  447. package/dist/core/runtime/model-registry.js +13 -0
  448. package/dist/core/runtime/naming-persist.d.ts +4 -0
  449. package/dist/core/runtime/naming-persist.js +27 -1
  450. package/dist/core/runtime/naming.d.ts +17 -12
  451. package/dist/core/runtime/naming.js +91 -140
  452. package/dist/core/runtime/node-read.js +19 -10
  453. package/dist/core/runtime/nodes.d.ts +9 -14
  454. package/dist/core/runtime/nodes.js +3 -53
  455. package/dist/core/runtime/package-health.d.ts +6 -21
  456. package/dist/core/runtime/package-health.js +12 -123
  457. package/dist/core/runtime/placement-tmux.d.ts +2 -1
  458. package/dist/core/runtime/placement-tmux.js +6 -4
  459. package/dist/core/runtime/placement.d.ts +1 -0
  460. package/dist/core/runtime/placement.js +4 -8
  461. package/dist/core/runtime/promote.js +3 -0
  462. package/dist/core/runtime/recap.d.ts +2 -7
  463. package/dist/core/runtime/recap.js +35 -69
  464. package/dist/core/runtime/revive.js +34 -77
  465. package/dist/core/runtime/session-cycles.d.ts +4 -0
  466. package/dist/core/runtime/session-cycles.js +14 -1
  467. package/dist/core/runtime/session-visibility.d.ts +37 -0
  468. package/dist/core/runtime/session-visibility.js +83 -0
  469. package/dist/core/runtime/spawn.js +10 -22
  470. package/dist/core/runtime/stop-guard.d.ts +1 -1
  471. package/dist/core/runtime/stop-guard.js +18 -13
  472. package/dist/core/runtime/surface-bg.js +1 -1
  473. package/dist/core/runtime/tmux-chrome.d.ts +1 -1
  474. package/dist/core/runtime/tmux-chrome.js +1 -1
  475. package/dist/core/runtime/tmux.d.ts +35 -7
  476. package/dist/core/runtime/tmux.js +439 -62
  477. package/dist/core/runtime/tool-group-summary.d.ts +19 -0
  478. package/dist/core/runtime/tool-group-summary.js +88 -0
  479. package/dist/core/scope.d.ts +2 -7
  480. package/dist/core/scope.js +9 -35
  481. package/dist/core/substrate/schema.d.ts +2 -2
  482. package/dist/core/termrender/code-doc.d.ts +12 -0
  483. package/dist/core/termrender/code-doc.js +92 -0
  484. package/dist/core/termrender/display.d.ts +12 -0
  485. package/dist/core/termrender/display.js +19 -0
  486. package/dist/core/termrender/termrender.d.ts +73 -0
  487. package/dist/core/termrender/termrender.js +795 -0
  488. package/dist/core/termrender/version.d.ts +1 -0
  489. package/dist/core/termrender/version.js +1 -0
  490. package/dist/core/tui/terminal.js +1 -2
  491. package/dist/core/user-settings.d.ts +71 -3
  492. package/dist/core/user-settings.js +83 -1
  493. package/dist/daemon/api/__tests__/inbox.test.js +44 -133
  494. package/dist/daemon/api/handlers/human.d.ts +0 -10
  495. package/dist/daemon/api/handlers/human.js +104 -702
  496. package/dist/daemon/api/handlers/inbox.js +113 -142
  497. package/dist/daemon/api/handlers/review-comments.d.ts +2 -0
  498. package/dist/daemon/api/handlers/review-comments.js +500 -0
  499. package/dist/daemon/api/handlers/reviews.d.ts +2 -0
  500. package/dist/daemon/api/handlers/reviews.js +287 -0
  501. package/dist/daemon/api/map.d.ts +22 -7
  502. package/dist/daemon/api/map.js +159 -11
  503. package/dist/daemon/api/server.js +4 -0
  504. package/dist/daemon/cron-run.js +6 -9
  505. package/dist/daemon/crtrd.js +17 -33
  506. package/dist/daemon/fleet.d.ts +1 -8
  507. package/dist/daemon/fleet.js +4 -30
  508. package/dist/daemon/human/finish.d.ts +14 -0
  509. package/dist/daemon/human/finish.js +115 -0
  510. package/dist/daemon/human/sweep.d.ts +6 -0
  511. package/dist/daemon/human/sweep.js +49 -0
  512. package/dist/daemon/messaging/node-message.d.ts +18 -0
  513. package/dist/daemon/messaging/node-message.js +70 -0
  514. package/dist/daemon/review/comment-notify.d.ts +26 -0
  515. package/dist/daemon/review/comment-notify.js +107 -0
  516. package/dist/daemon/review/deliver.d.ts +7 -0
  517. package/dist/daemon/review/deliver.js +56 -0
  518. package/dist/daemon/review/finish.d.ts +22 -0
  519. package/dist/daemon/review/finish.js +254 -0
  520. package/dist/daemon/review/sweep.d.ts +11 -0
  521. package/dist/daemon/review/sweep.js +120 -0
  522. package/dist/index.d.ts +2 -0
  523. package/dist/index.js +2 -2
  524. package/dist/pi-extensions/__tests__/canvas-context-intro.test.js +42 -64
  525. package/dist/pi-extensions/__tests__/canvas-recap.test.d.ts +1 -0
  526. package/dist/pi-extensions/__tests__/canvas-recap.test.js +159 -0
  527. package/dist/pi-extensions/__tests__/canvas-stophook-agentend.test.js +16 -38
  528. package/dist/pi-extensions/__tests__/canvas-structured-output.test.d.ts +1 -0
  529. package/dist/pi-extensions/__tests__/canvas-structured-output.test.js +63 -0
  530. package/dist/pi-extensions/canvas-context-intro.d.ts +8 -11
  531. package/dist/pi-extensions/canvas-context-intro.js +50 -104
  532. package/dist/pi-extensions/canvas-recap.d.ts +15 -2
  533. package/dist/pi-extensions/canvas-recap.js +192 -69
  534. package/dist/pi-extensions/canvas-review-boundary.d.ts +59 -0
  535. package/dist/pi-extensions/canvas-review-boundary.js +81 -0
  536. package/dist/pi-extensions/canvas-stophook.d.ts +3 -3
  537. package/dist/pi-extensions/canvas-stophook.js +78 -128
  538. package/dist/pi-extensions/canvas-structured-output.js +52 -8
  539. package/dist/shared/generated-context.d.ts +29 -4
  540. package/dist/shared/generated-context.js +122 -7
  541. package/dist/shared/tool-groups.d.ts +23 -0
  542. package/dist/shared/tool-groups.js +60 -0
  543. package/dist/shared/working-activity.d.ts +8 -0
  544. package/dist/shared/working-activity.js +26 -0
  545. package/dist/types.d.ts +36 -2
  546. package/dist/types.js +51 -0
  547. package/dist/web-client/assets/index-CCPaLeW7.css +2 -0
  548. package/dist/web-client/assets/index-kyOWsnZK.js +86 -0
  549. package/dist/web-client/index.html +2 -2
  550. package/dist/web-client/sw.js +1 -1
  551. package/docs/compat/hearth-crtr-v4.md +2 -2
  552. package/docs/compat/hearth-crtr-v5.md +4 -2
  553. package/docs/public-api.md +3 -3
  554. package/package.json +21 -14
  555. package/runtime.lock.json +4661 -1453
  556. package/scripts/postinstall.mjs +15 -2
  557. package/dist/builtin-pi-packages/pi-mode-switch/README.md +0 -36
  558. package/dist/builtin-pi-packages/pi-mode-switch/bin/mode +0 -36
  559. package/dist/builtin-pi-packages/pi-mode-switch/extensions/index.ts +0 -449
  560. package/dist/builtin-pi-packages/pi-mode-switch/package.json +0 -14
  561. package/dist/builtin-pi-packages/pi-mode-switch/tsconfig.json +0 -9
  562. package/dist/builtin-views/_lib/states.mjs +0 -161
  563. package/dist/builtin-views/canvas/core.mjs +0 -657
  564. package/dist/builtin-views/canvas/text.mjs +0 -58
  565. package/dist/builtin-views/canvas/tui.mjs +0 -168
  566. package/dist/builtin-views/canvas/web.jsx +0 -121
  567. package/dist/builtin-views/chat/core.mjs +0 -684
  568. package/dist/builtin-views/chat/text.mjs +0 -101
  569. package/dist/builtin-views/chat/tui.mjs +0 -360
  570. package/dist/builtin-views/chat/web.jsx +0 -362
  571. package/dist/builtin-views/git-pr/core.mjs +0 -673
  572. package/dist/builtin-views/git-pr/text.mjs +0 -84
  573. package/dist/builtin-views/git-pr/tui.mjs +0 -301
  574. package/dist/builtin-views/git-pr/web.jsx +0 -216
  575. package/dist/builtin-views/inbox/_lib/render.mjs +0 -175
  576. package/dist/builtin-views/inbox/core.mjs +0 -1273
  577. package/dist/builtin-views/inbox/text.mjs +0 -73
  578. package/dist/builtin-views/inbox/tui.mjs +0 -314
  579. package/dist/builtin-views/inbox/web.jsx +0 -188
  580. package/dist/builtin-views/linkedin/core.mjs +0 -906
  581. package/dist/builtin-views/linkedin/text.mjs +0 -69
  582. package/dist/builtin-views/linkedin/tui.mjs +0 -413
  583. package/dist/builtin-views/linkedin/web.jsx +0 -206
  584. package/dist/builtin-views/prompt-review/core.mjs +0 -735
  585. package/dist/builtin-views/prompt-review/text.mjs +0 -15
  586. package/dist/builtin-views/prompt-review/tui.mjs +0 -196
  587. package/dist/builtin-views/prompt-review/web.jsx +0 -484
  588. package/dist/builtin-views/workspace-sidebar/__tests__/core.test.js +0 -50
  589. package/dist/builtin-views/workspace-sidebar/__tests__/core.test.ts +0 -53
  590. package/dist/builtin-views/workspace-sidebar/core.mjs +0 -670
  591. package/dist/builtin-views/workspace-sidebar/text.mjs +0 -53
  592. package/dist/builtin-views/workspace-sidebar/tui.mjs +0 -141
  593. package/dist/builtin-views/workspace-sidebar/web.jsx +0 -109
  594. package/dist/clients/attach/session/mode.d.ts +0 -25
  595. package/dist/clients/attach/session/mode.js +0 -97
  596. package/dist/commands/sys/promptstudio.d.ts +0 -2
  597. package/dist/commands/sys/promptstudio.js +0 -65
  598. package/dist/commands/view-cycle.d.ts +0 -2
  599. package/dist/commands/view-cycle.js +0 -130
  600. package/dist/commands/view-list.d.ts +0 -2
  601. package/dist/commands/view-list.js +0 -66
  602. package/dist/commands/view-new.d.ts +0 -2
  603. package/dist/commands/view-new.js +0 -74
  604. package/dist/commands/view-pick.d.ts +0 -6
  605. package/dist/commands/view-pick.js +0 -129
  606. package/dist/commands/view-run.d.ts +0 -2
  607. package/dist/commands/view-run.js +0 -214
  608. package/dist/commands/view.d.ts +0 -2
  609. package/dist/commands/view.js +0 -31
  610. package/dist/commands/workspace.d.ts +0 -2
  611. package/dist/commands/workspace.js +0 -165
  612. package/dist/core/__tests__/chat-view-reconnect.test.js +0 -105
  613. package/dist/core/__tests__/full/consult-startup-failure.test.js +0 -124
  614. package/dist/core/canvas/__tests__/human-work-outbox.test.js +0 -123
  615. package/dist/core/canvas/human-work-outbox.d.ts +0 -73
  616. package/dist/core/canvas/human-work-outbox.js +0 -261
  617. package/dist/core/command-plugins/store.d.ts +0 -16
  618. package/dist/core/command-plugins/store.js +0 -64
  619. package/dist/core/keybindings/__tests__/bespoke-consumers.test.js +0 -40
  620. package/dist/core/runtime/fault-recovery-nudge.d.ts +0 -3
  621. package/dist/core/runtime/fault-recovery-nudge.js +0 -3
  622. package/dist/core/tui/__tests__/host-keybindings.test.js +0 -113
  623. package/dist/core/tui/host.d.ts +0 -66
  624. package/dist/core/view/__tests__/transport-cache.test.js +0 -62
  625. package/dist/core/view/bridge.d.ts +0 -10
  626. package/dist/core/view/bridge.js +0 -31
  627. package/dist/core/view/chrome.d.ts +0 -9
  628. package/dist/core/view/chrome.js +0 -22
  629. package/dist/core/view/contract.d.ts +0 -205
  630. package/dist/core/view/contract.js +0 -23
  631. package/dist/core/view/loader.d.ts +0 -31
  632. package/dist/core/view/loader.js +0 -188
  633. package/dist/core/view/stream-local.d.ts +0 -3
  634. package/dist/core/view/stream-local.js +0 -231
  635. package/dist/core/view/transport-cache.d.ts +0 -8
  636. package/dist/core/view/transport-cache.js +0 -38
  637. package/dist/core/view/transport-local.d.ts +0 -7
  638. package/dist/core/view/transport-local.js +0 -83
  639. package/dist/core/view/transport-remote.d.ts +0 -2
  640. package/dist/core/view/transport.d.ts +0 -10
  641. package/dist/core/view/transport.js +0 -15
  642. package/dist/pi-extensions/naming-tool.d.ts +0 -24
  643. package/dist/pi-extensions/naming-tool.js +0 -67
  644. package/dist/prompts/view.d.ts +0 -7
  645. package/dist/prompts/view.js +0 -172
  646. package/dist/web/ViewChrome.d.ts +0 -7
  647. package/dist/web/ViewChrome.js +0 -28
  648. package/dist/web/ViewPane.d.ts +0 -39
  649. package/dist/web/ViewPane.js +0 -48
  650. package/dist/web/index.d.ts +0 -8
  651. package/dist/web/index.js +0 -22
  652. package/dist/web/runtime.d.ts +0 -39
  653. package/dist/web/runtime.js +0 -232
  654. package/dist/web/states.d.ts +0 -24
  655. package/dist/web/states.js +0 -24
  656. package/dist/web/transport-http.d.ts +0 -5
  657. package/dist/web/transport-http.js +0 -34
  658. package/dist/web/transport-stream.d.ts +0 -3
  659. package/dist/web/transport-stream.js +0 -204
  660. package/dist/web-client/assets/index-U_NZ66VE.js +0 -79
  661. package/dist/web-client/assets/index-aaeu4adv.css +0 -2
  662. /package/dist/{builtin-views/workspace-sidebar/__tests__/core.test.d.ts → clients/attach/__tests__/file-review-focus.test.d.ts} +0 -0
  663. /package/dist/clients/attach/__tests__/{visible-paths.test.d.ts → group-activity.test.d.ts} +0 -0
  664. /package/dist/{core/__tests__/chat-view-reconnect.test.d.ts → clients/attach/__tests__/input-controller-extension-command.test.d.ts} +0 -0
  665. /package/dist/{core/__tests__/full/consult-startup-failure.test.d.ts → clients/attach/__tests__/session-identity-refresh.test.d.ts} +0 -0
  666. /package/dist/{core/canvas/__tests__/human-work-outbox.test.d.ts → clients/inbox/__tests__/inbox-controller.test.d.ts} +0 -0
  667. /package/dist/{core/keybindings/__tests__/bespoke-consumers.test.d.ts → clients/inbox/__tests__/mount-panel.test.d.ts} +0 -0
  668. /package/dist/{core/tui/__tests__/host-keybindings.test.d.ts → clients/inbox/review/__tests__/editor-roundtrip.test.d.ts} +0 -0
  669. /package/dist/{core/view/__tests__/transport-cache.test.d.ts → clients/inbox/review/__tests__/remap.test.d.ts} +0 -0
  670. /package/dist/{core/view/__tests__/transport-remote.test.d.ts → clients/inbox/review/__tests__/review-core.test.d.ts} +0 -0
@@ -0,0 +1,143 @@
1
+ import type { AnchoredComment } from './comments-client.js';
2
+ import type { RenderedDoc } from '../../../core/termrender/termrender.js';
3
+ import { type AnchorDoc, type AnchorUnit } from './anchors.js';
4
+ export interface ComposeState {
5
+ buffer: string;
6
+ cursor: number;
7
+ /** Id of the comment being edited, or null when composing a new comment. */
8
+ editingId: string | null;
9
+ /** Submode to return to once compose closes (Escape or a successful save). */
10
+ returnMode: 'view' | 'list';
11
+ anchor: {
12
+ line: number;
13
+ endLine: number;
14
+ };
15
+ }
16
+ export interface ReviewState {
17
+ sourceLines: string[];
18
+ /** Ordered leaf anchor units. Never empty. */
19
+ units: AnchorUnit[];
20
+ /** Per rendered row: owning unit index, or null for separator rows. */
21
+ rowUnits: (number | null)[];
22
+ /** Current comment projection supplied by the daemon. */
23
+ comments: AnchoredComment[];
24
+ /** Revision of the live source snapshot the rendered units came from. */
25
+ sourceRevision: number;
26
+ /** Original ranges for comments whose current source range no longer survives. */
27
+ detached: Record<string, {
28
+ line: number;
29
+ endLine: number;
30
+ }>;
31
+ /** 0-based index of the anchored unit. */
32
+ activeUnit: number;
33
+ /** Set while a Shift+j/k range is being extended from this unit. */
34
+ selectionAnchor: number | null;
35
+ /** Scroll offset into the rendered (termrender) lines. */
36
+ scroll: number;
37
+ /** Horizontal pan offset, in display cells, for rows wider than the body
38
+ * rectangle (diagrams). Rows that fit never move. */
39
+ hscroll: number;
40
+ mode: 'view' | 'list' | 'compose' | 'help';
41
+ compose: ComposeState | null;
42
+ listIndex: number;
43
+ }
44
+ /** Best unit for a source line: the NARROWEST unit containing it — code/table
45
+ * chrome units carry their whole block's range and sit before the per-line
46
+ * content units in rendered order, so "first whose end reaches the line"
47
+ * would wrongly pick the chrome over the exact code line. A line no unit
48
+ * contains (a blank separator) snaps forward to the next unit; past the end
49
+ * clamps to the last. */
50
+ export declare function initReviewState(sourceLines: string[], anchor: AnchorDoc, comments: AnchoredComment[], sourceRevision: number): ReviewState;
51
+ export declare function selectedUnitBounds(state: ReviewState): {
52
+ lo: number;
53
+ hi: number;
54
+ };
55
+ /** Source-line anchor of the current unit selection — what a committed
56
+ * comment records as `line`/`endLine`. Whole-block chrome units can carry a
57
+ * wider range than their neighbors, so take the min/max over the selection
58
+ * rather than trusting the endpoints alone. */
59
+ export declare function currentAnchor(state: ReviewState): {
60
+ line: number;
61
+ endLine: number;
62
+ };
63
+ export declare function moveActiveUnit(state: ReviewState, delta: number, extend: boolean): ReviewState;
64
+ /** Unit indices overlapped by any existing comment's source range. A projected
65
+ * range lying wholly past the last unit (the file shrank before its range was
66
+ * remapped) still gets a marker on its clamped unit, so every comment is
67
+ * visible somewhere in the document. */
68
+ export declare function commentedUnitSet(state: ReviewState): Set<number>;
69
+ /** First/last rendered-row indices spanned by units `lo..hi`, or null when
70
+ * the indices fall outside the unit list. */
71
+ export declare function anchorRowRange(units: AnchorUnit[], lo: number, hi: number): {
72
+ first: number;
73
+ last: number;
74
+ } | null;
75
+ /** Minimal scroll adjustment that keeps rows `first..last` visible with
76
+ * `margin` rows of context (the margin yields whenever honoring it would push
77
+ * either edge of the span out of view); a taller-than-view span pins `first`
78
+ * at the top — one row down when scrolled, so the `↑ more above` indicator
79
+ * overwrites the preceding row, never the pinned one. Always returns a scroll
80
+ * clamped to the document. */
81
+ export declare function scrollToReveal(scroll: number, first: number, last: number, bodyHeight: number, total: number, margin?: number): number;
82
+ /** Auto-scroll so the active unit (the moving edge of a selection) is
83
+ * visible. Free-scrolling (`u`/`d`) is untouched until the next anchor move. */
84
+ export declare function ensureAnchorVisible(state: ReviewState, doc: RenderedDoc, bodyHeight: number): ReviewState;
85
+ export declare function scrollBy(state: ReviewState, delta: number, bodyHeight: number, totalLines: number): ReviewState;
86
+ export declare function openComposeNew(state: ReviewState): ReviewState;
87
+ export declare function openComposeEdit(state: ReviewState, index: number): ReviewState;
88
+ export declare function closeCompose(state: ReviewState): ReviewState;
89
+ export interface ComposeCommit {
90
+ editingId: string | null;
91
+ anchor: {
92
+ line: number;
93
+ endLine: number;
94
+ };
95
+ text: string;
96
+ }
97
+ /** Closes compose and returns the daemon mutation payload. The daemon projection, not this reducer, repaints comments. */
98
+ export declare function commitCompose(state: ReviewState): {
99
+ state: ReviewState;
100
+ commit: ComposeCommit | null;
101
+ };
102
+ export declare function openList(state: ReviewState): ReviewState;
103
+ export declare function closeList(state: ReviewState): ReviewState;
104
+ export declare function moveListIndex(state: ReviewState, delta: number): ReviewState;
105
+ export declare function deleteAtListIndex(state: ReviewState): {
106
+ state: ReviewState;
107
+ id: string | null;
108
+ };
109
+ export declare function undoLast(state: ReviewState): {
110
+ state: ReviewState;
111
+ id: string | null;
112
+ };
113
+ export declare function openHelp(state: ReviewState): ReviewState;
114
+ export declare function closeHelp(state: ReviewState): ReviewState;
115
+ export declare function cleanPastedText(input: string): string;
116
+ export declare function textInsert(buffer: string, cursor: number, text: string): {
117
+ buffer: string;
118
+ cursor: number;
119
+ };
120
+ export declare function textBackspace(buffer: string, cursor: number): {
121
+ buffer: string;
122
+ cursor: number;
123
+ };
124
+ export declare function textDelete(buffer: string, cursor: number): {
125
+ buffer: string;
126
+ cursor: number;
127
+ };
128
+ export declare function textHome(buffer: string, cursor: number): number;
129
+ export declare function textEnd(buffer: string, cursor: number): number;
130
+ export declare function textVertical(buffer: string, cursor: number, delta: number): number;
131
+ /** Vertical motion by *visual* row (what up/down mean in a wrapped compose box):
132
+ * a long soft-wrapped comment has many rows even though it is one logical
133
+ * line. Shares `verticalCursor` with the frame renderer's own wrap. */
134
+ export declare function textVerticalWrapped(buffer: string, cursor: number, delta: number, width: number): number;
135
+ /** Start of the word before the cursor (readline alt-b / alt+left). */
136
+ export declare function textWordLeft(buffer: string, cursor: number): number;
137
+ /** Just past the end of the word after the cursor (readline alt-f / alt+right). */
138
+ export declare function textWordRight(buffer: string, cursor: number): number;
139
+ /** Delete back to the start of the previous word (alt+backspace / ctrl+w). */
140
+ export declare function textWordBackspace(buffer: string, cursor: number): {
141
+ buffer: string;
142
+ cursor: number;
143
+ };
@@ -0,0 +1,282 @@
1
+ import { verticalCursor } from '../tui/render.js';
2
+ import { unitIndexForLine, unitRangeForSpan } from './anchors.js';
3
+ /** Best unit for a source line: the NARROWEST unit containing it — code/table
4
+ * chrome units carry their whole block's range and sit before the per-line
5
+ * content units in rendered order, so "first whose end reaches the line"
6
+ * would wrongly pick the chrome over the exact code line. A line no unit
7
+ * contains (a blank separator) snaps forward to the next unit; past the end
8
+ * clamps to the last. */
9
+ export function initReviewState(sourceLines, anchor, comments, sourceRevision) {
10
+ const safe = anchor.units.length > 0
11
+ ? anchor
12
+ : { units: [{ start: 1, end: Math.max(1, sourceLines.length), firstRow: 0, lastRow: 0 }], rowUnits: anchor.rowUnits };
13
+ return {
14
+ sourceLines,
15
+ units: safe.units,
16
+ rowUnits: safe.rowUnits,
17
+ comments: [...comments],
18
+ sourceRevision,
19
+ detached: Object.fromEntries(comments.flatMap((comment) => comment.anchorStatus === 'detached'
20
+ ? [[comment.id, comment.originalRange ?? { line: comment.line, endLine: comment.endLine }]]
21
+ : [])),
22
+ activeUnit: comments.length > 0 ? unitIndexForLine(safe.units, comments[0].line) : 0,
23
+ selectionAnchor: null,
24
+ scroll: 0,
25
+ hscroll: 0,
26
+ mode: 'view',
27
+ compose: null,
28
+ listIndex: 0,
29
+ };
30
+ }
31
+ export function selectedUnitBounds(state) {
32
+ const sel = state.selectionAnchor ?? state.activeUnit;
33
+ return { lo: Math.min(state.activeUnit, sel), hi: Math.max(state.activeUnit, sel) };
34
+ }
35
+ /** Source-line anchor of the current unit selection — what a committed
36
+ * comment records as `line`/`endLine`. Whole-block chrome units can carry a
37
+ * wider range than their neighbors, so take the min/max over the selection
38
+ * rather than trusting the endpoints alone. */
39
+ export function currentAnchor(state) {
40
+ const { lo, hi } = selectedUnitBounds(state);
41
+ let line = Number.POSITIVE_INFINITY;
42
+ let endLine = 0;
43
+ for (let i = lo; i <= hi; i++) {
44
+ const u = state.units[i];
45
+ if (u === undefined)
46
+ continue;
47
+ line = Math.min(line, u.start);
48
+ endLine = Math.max(endLine, u.end);
49
+ }
50
+ if (!Number.isFinite(line))
51
+ return { line: 1, endLine: Math.max(1, state.sourceLines.length) };
52
+ return { line, endLine: Math.max(line, endLine) };
53
+ }
54
+ export function moveActiveUnit(state, delta, extend) {
55
+ const last = Math.max(0, state.units.length - 1);
56
+ const next = Math.max(0, Math.min(last, state.activeUnit + delta));
57
+ if (!extend)
58
+ return { ...state, activeUnit: next, selectionAnchor: null };
59
+ return { ...state, activeUnit: next, selectionAnchor: state.selectionAnchor ?? state.activeUnit };
60
+ }
61
+ /** Unit indices overlapped by any existing comment's source range. A projected
62
+ * range lying wholly past the last unit (the file shrank before its range was
63
+ * remapped) still gets a marker on its clamped unit, so every comment is
64
+ * visible somewhere in the document. */
65
+ export function commentedUnitSet(state) {
66
+ const out = new Set();
67
+ for (const c of state.comments) {
68
+ if (c.status === 'deleted' || c.anchorStatus === 'detached')
69
+ continue;
70
+ let hit = false;
71
+ state.units.forEach((u, i) => {
72
+ if (u.start <= c.endLine && u.end >= c.line) {
73
+ out.add(i);
74
+ hit = true;
75
+ }
76
+ });
77
+ if (!hit)
78
+ out.add(unitIndexForLine(state.units, c.line));
79
+ }
80
+ return out;
81
+ }
82
+ /** First/last rendered-row indices spanned by units `lo..hi`, or null when
83
+ * the indices fall outside the unit list. */
84
+ export function anchorRowRange(units, lo, hi) {
85
+ const a = units[lo];
86
+ const b = units[hi];
87
+ if (a === undefined || b === undefined)
88
+ return null;
89
+ return { first: a.firstRow, last: b.lastRow };
90
+ }
91
+ /** Minimal scroll adjustment that keeps rows `first..last` visible with
92
+ * `margin` rows of context (the margin yields whenever honoring it would push
93
+ * either edge of the span out of view); a taller-than-view span pins `first`
94
+ * at the top — one row down when scrolled, so the `↑ more above` indicator
95
+ * overwrites the preceding row, never the pinned one. Always returns a scroll
96
+ * clamped to the document. */
97
+ export function scrollToReveal(scroll, first, last, bodyHeight, total, margin = 2) {
98
+ const maxScroll = Math.max(0, total - bodyHeight);
99
+ let next = Math.max(0, Math.min(scroll, maxScroll));
100
+ if (last - first + 1 >= bodyHeight)
101
+ return Math.max(0, Math.min(Math.max(0, first - 1), maxScroll));
102
+ if (first - margin < next)
103
+ next = Math.max(first - margin, last - (bodyHeight - 1));
104
+ else if (last + margin > next + bodyHeight - 1)
105
+ next = Math.min(last + margin - (bodyHeight - 1), first);
106
+ return Math.max(0, Math.min(next, maxScroll));
107
+ }
108
+ /** Auto-scroll so the active unit (the moving edge of a selection) is
109
+ * visible. Free-scrolling (`u`/`d`) is untouched until the next anchor move. */
110
+ export function ensureAnchorVisible(state, doc, bodyHeight) {
111
+ const range = anchorRowRange(state.units, state.activeUnit, state.activeUnit);
112
+ if (range === null)
113
+ return state;
114
+ const scroll = scrollToReveal(state.scroll, range.first, range.last, bodyHeight, doc.lines.length);
115
+ return scroll === state.scroll ? state : { ...state, scroll };
116
+ }
117
+ export function scrollBy(state, delta, bodyHeight, totalLines) {
118
+ const maxScroll = Math.max(0, totalLines - bodyHeight);
119
+ return { ...state, scroll: Math.max(0, Math.min(state.scroll + delta, maxScroll)) };
120
+ }
121
+ export function openComposeNew(state) {
122
+ return { ...state, mode: 'compose', compose: { buffer: '', cursor: 0, editingId: null, returnMode: 'view', anchor: currentAnchor(state) } };
123
+ }
124
+ export function openComposeEdit(state, index) {
125
+ const comment = state.comments[index];
126
+ if (comment === undefined)
127
+ return state;
128
+ const buffer = comment.comment;
129
+ const { lo, hi } = unitRangeForSpan(state.units, comment.line, comment.endLine);
130
+ return {
131
+ ...state,
132
+ activeUnit: hi,
133
+ selectionAnchor: lo === hi ? null : lo,
134
+ mode: 'compose',
135
+ compose: { buffer, cursor: [...buffer].length, editingId: comment.id, returnMode: 'list', anchor: { line: comment.line, endLine: comment.endLine } },
136
+ };
137
+ }
138
+ export function closeCompose(state) {
139
+ const returnMode = state.compose?.returnMode ?? 'view';
140
+ return { ...state, mode: returnMode, compose: null };
141
+ }
142
+ /** Closes compose and returns the daemon mutation payload. The daemon projection, not this reducer, repaints comments. */
143
+ export function commitCompose(state) {
144
+ const c = state.compose;
145
+ if (c === null || c === undefined)
146
+ return { state, commit: null };
147
+ const text = c.buffer.trim();
148
+ if (text.length === 0)
149
+ return { state: closeCompose(state), commit: null };
150
+ return {
151
+ state: closeCompose(state),
152
+ commit: { editingId: c.editingId, anchor: c.anchor, text },
153
+ };
154
+ }
155
+ export function openList(state) {
156
+ return { ...state, mode: 'list', listIndex: Math.max(0, Math.min(state.listIndex, state.comments.length - 1)) };
157
+ }
158
+ export function closeList(state) {
159
+ return { ...state, mode: 'view' };
160
+ }
161
+ export function moveListIndex(state, delta) {
162
+ if (state.comments.length === 0)
163
+ return state;
164
+ const next = Math.max(0, Math.min(state.comments.length - 1, state.listIndex + delta));
165
+ return { ...state, listIndex: next };
166
+ }
167
+ export function deleteAtListIndex(state) {
168
+ const comment = state.comments[state.listIndex];
169
+ return { state, id: comment?.id ?? null };
170
+ }
171
+ export function undoLast(state) {
172
+ return { state, id: state.comments.at(-1)?.id ?? null };
173
+ }
174
+ export function openHelp(state) {
175
+ return { ...state, mode: 'help' };
176
+ }
177
+ export function closeHelp(state) {
178
+ return { ...state, mode: 'view' };
179
+ }
180
+ // ── Multi-line text-buffer helpers (flat string + code-point cursor) ────────
181
+ function codePoints(s) {
182
+ return [...s];
183
+ }
184
+ // A single physical keypress (including Enter) almost always arrives as its
185
+ // own 'data' event, so parseKeypress's per-event key flags cover the normal
186
+ // typing path. A chunk longer than one character is a paste (or, rarely,
187
+ // several keystrokes the OS coalesced into one read) and is never re-parsed
188
+ // for key semantics — an embedded CR there means a pasted newline, not a
189
+ // commit. Mirrors tui/input.ts's paste cleaning: strip escape sequences,
190
+ // normalize CR/CRLF to LF, drop remaining control bytes, keep LF.
191
+ export function cleanPastedText(input) {
192
+ return input
193
+ .replace(/\x1b\[20[01]~/g, '')
194
+ .replace(/\x1b\[[0-9;?]*[a-zA-Z]/g, '')
195
+ .replace(/\r\n?/g, '\n')
196
+ .replace(/[\x00-\x09\x0B-\x1F\x7F]/g, '');
197
+ }
198
+ export function textInsert(buffer, cursor, text) {
199
+ const chars = codePoints(buffer);
200
+ const at = Math.max(0, Math.min(cursor, chars.length));
201
+ const next = [...chars.slice(0, at), ...codePoints(text), ...chars.slice(at)].join('');
202
+ return { buffer: next, cursor: at + codePoints(text).length };
203
+ }
204
+ export function textBackspace(buffer, cursor) {
205
+ if (cursor <= 0)
206
+ return { buffer, cursor };
207
+ const chars = codePoints(buffer);
208
+ return { buffer: [...chars.slice(0, cursor - 1), ...chars.slice(cursor)].join(''), cursor: cursor - 1 };
209
+ }
210
+ export function textDelete(buffer, cursor) {
211
+ const chars = codePoints(buffer);
212
+ if (cursor >= chars.length)
213
+ return { buffer, cursor };
214
+ return { buffer: [...chars.slice(0, cursor), ...chars.slice(cursor + 1)].join(''), cursor };
215
+ }
216
+ function lineBoundsAt(chars, cursor) {
217
+ let start = cursor;
218
+ while (start > 0 && chars[start - 1] !== '\n')
219
+ start--;
220
+ let end = cursor;
221
+ while (end < chars.length && chars[end] !== '\n')
222
+ end++;
223
+ return { start, end };
224
+ }
225
+ export function textHome(buffer, cursor) {
226
+ return lineBoundsAt(codePoints(buffer), cursor).start;
227
+ }
228
+ export function textEnd(buffer, cursor) {
229
+ return lineBoundsAt(codePoints(buffer), cursor).end;
230
+ }
231
+ export function textVertical(buffer, cursor, delta) {
232
+ const chars = codePoints(buffer);
233
+ const { start, end } = lineBoundsAt(chars, cursor);
234
+ const col = cursor - start;
235
+ if (delta < 0) {
236
+ if (start === 0)
237
+ return cursor;
238
+ const prevEnd = start - 1; // the '\n' just before this line
239
+ const prevStart = lineBoundsAt(chars, prevEnd).start;
240
+ return Math.min(prevEnd, prevStart + col);
241
+ }
242
+ if (end >= chars.length)
243
+ return cursor;
244
+ const nextStart = end + 1;
245
+ const nextEnd = lineBoundsAt(chars, nextStart).end;
246
+ return Math.min(nextEnd, nextStart + col);
247
+ }
248
+ /** Vertical motion by *visual* row (what up/down mean in a wrapped compose box):
249
+ * a long soft-wrapped comment has many rows even though it is one logical
250
+ * line. Shares `verticalCursor` with the frame renderer's own wrap. */
251
+ export function textVerticalWrapped(buffer, cursor, delta, width) {
252
+ return verticalCursor(buffer, cursor, delta, width);
253
+ }
254
+ /** Start of the word before the cursor (readline alt-b / alt+left). */
255
+ export function textWordLeft(buffer, cursor) {
256
+ const chars = codePoints(buffer);
257
+ let i = Math.max(0, Math.min(cursor, chars.length));
258
+ while (i > 0 && /\s/.test(chars[i - 1]))
259
+ i--;
260
+ while (i > 0 && !/\s/.test(chars[i - 1]))
261
+ i--;
262
+ return i;
263
+ }
264
+ /** Just past the end of the word after the cursor (readline alt-f / alt+right). */
265
+ export function textWordRight(buffer, cursor) {
266
+ const chars = codePoints(buffer);
267
+ let i = Math.max(0, Math.min(cursor, chars.length));
268
+ while (i < chars.length && /\s/.test(chars[i]))
269
+ i++;
270
+ while (i < chars.length && !/\s/.test(chars[i]))
271
+ i++;
272
+ return i;
273
+ }
274
+ /** Delete back to the start of the previous word (alt+backspace / ctrl+w). */
275
+ export function textWordBackspace(buffer, cursor) {
276
+ const chars = codePoints(buffer);
277
+ const at = Math.max(0, Math.min(cursor, chars.length));
278
+ const to = textWordLeft(buffer, at);
279
+ if (to === at)
280
+ return { buffer, cursor: at };
281
+ return { buffer: [...chars.slice(0, to), ...chars.slice(at)].join(''), cursor: to };
282
+ }
@@ -0,0 +1,29 @@
1
+ import type { TUI } from '@earendil-works/pi-tui';
2
+ import type { CanvasSource } from '../../core/canvas/source.js';
3
+ import type { SurfaceHost } from '../surfaces/host.js';
4
+ export interface ReviewAdapterOptions {
5
+ host: SurfaceHost;
6
+ dir: string;
7
+ /** Threaded from the attach session so the composed surface can attach the
8
+ * companion's transcript through the same terminal and canvas read authority
9
+ * the outer viewer already holds. */
10
+ tui: TUI;
11
+ canvasSource: CanvasSource;
12
+ }
13
+ /**
14
+ * Resolves a durable review ticket to its canonical daemon review and mounts
15
+ * the one composed terminal review surface. Approval flows entirely through
16
+ * `reviewClient.submit` inside that composition — this adapter owns only the
17
+ * bridge lookup and the mounted surface's lifecycle.
18
+ */
19
+ export declare class ReviewAdapter {
20
+ private readonly opts;
21
+ private running;
22
+ private stopped;
23
+ private mountedHandle;
24
+ constructor(opts: ReviewAdapterOptions);
25
+ start(): Promise<void>;
26
+ /** Toggle, cancellation, and controller teardown all take this same path. */
27
+ stop(): Promise<void>;
28
+ private run;
29
+ }
@@ -0,0 +1,92 @@
1
+ import { basename } from 'node:path';
2
+ import { ApiError } from '../../api/errors.js';
3
+ import { openComposedReview } from './review/launch.js';
4
+ import { createReviewClient } from './review/review-client.js';
5
+ /**
6
+ * Resolves a durable review ticket to its canonical daemon review and mounts
7
+ * the one composed terminal review surface. Approval flows entirely through
8
+ * `reviewClient.submit` inside that composition — this adapter owns only the
9
+ * bridge lookup and the mounted surface's lifecycle.
10
+ */
11
+ export class ReviewAdapter {
12
+ opts;
13
+ running = null;
14
+ stopped = false;
15
+ mountedHandle;
16
+ constructor(opts) {
17
+ this.opts = opts;
18
+ }
19
+ start() {
20
+ if (this.running !== null)
21
+ return this.running;
22
+ this.running = this.run();
23
+ return this.running;
24
+ }
25
+ /** Toggle, cancellation, and controller teardown all take this same path. */
26
+ async stop() {
27
+ if (this.stopped)
28
+ return;
29
+ this.stopped = true;
30
+ this.mountedHandle?.close();
31
+ if (this.running !== null)
32
+ await this.running;
33
+ }
34
+ async run() {
35
+ const bridgeNodeId = basename(this.opts.dir);
36
+ let reviewId;
37
+ try {
38
+ ({ reviewId } = await createReviewClient().byBridge(bridgeNodeId));
39
+ }
40
+ catch (error) {
41
+ if (!isReviewPredatesSystem(error))
42
+ throw error;
43
+ this.opts.host.notice('This review predates canonical review records — cancel it and re-file the review.');
44
+ return;
45
+ }
46
+ if (this.stopped)
47
+ return;
48
+ let resolveClosed;
49
+ const closed = new Promise((resolve) => { resolveClosed = resolve; });
50
+ const host = wrapHostForMount(this.opts.host, (handle) => {
51
+ this.mountedHandle = handle;
52
+ handle.onClose(() => {
53
+ this.mountedHandle = undefined;
54
+ resolveClosed();
55
+ });
56
+ });
57
+ await openComposedReview(host, {
58
+ reviewId,
59
+ tui: this.opts.tui,
60
+ canvasSource: this.opts.canvasSource,
61
+ });
62
+ // A remote refusal, a terminal-review notice, or a live-source failure
63
+ // reports through `host.notice` and returns without ever mounting.
64
+ if (this.mountedHandle === undefined)
65
+ return;
66
+ if (this.stopped) {
67
+ this.mountedHandle.close();
68
+ return;
69
+ }
70
+ await closed;
71
+ }
72
+ }
73
+ /** Observes the one surface `openComposedReview` mounts so this adapter can
74
+ * await its close and close it itself from `stop()`, without widening
75
+ * `SurfaceHost` or reaching into the real host's internals. */
76
+ function wrapHostForMount(host, onMount) {
77
+ return {
78
+ capabilities: host.capabilities,
79
+ mount: (component, opts) => {
80
+ const handle = host.mount(component, opts);
81
+ onMount(handle);
82
+ return handle;
83
+ },
84
+ notice: (text) => host.notice(text),
85
+ suspendForChild: () => host.suspendForChild(),
86
+ focusNode: (nodeId) => host.focusNode(nodeId),
87
+ pickReviewFile: (spec) => host.pickReviewFile(spec),
88
+ };
89
+ }
90
+ function isReviewPredatesSystem(error) {
91
+ return error instanceof ApiError && error.status === 409 && error.code === 'review_predates_system';
92
+ }
@@ -0,0 +1,5 @@
1
+ import type { TicketSummary } from '../../core/human/types.js';
2
+ /** Match the daemon's opaque inbox id: canonical tickets root, NUL, bridge id. */
3
+ export declare function opaqueTicketId(canonicalTicketsRoot: string, bridgeNodeId: string): string;
4
+ /** Retain local deck rows and only daemon-visible review rows. */
5
+ export declare function filterVisibleReviewTickets(tickets: readonly TicketSummary[], visibleIds: ReadonlySet<string>): TicketSummary[];
@@ -0,0 +1,19 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { realpathSync } from 'node:fs';
3
+ import { basename } from 'node:path';
4
+ import { ticketsRoot } from '../../core/human/root.js';
5
+ /** Match the daemon's opaque inbox id: canonical tickets root, NUL, bridge id. */
6
+ export function opaqueTicketId(canonicalTicketsRoot, bridgeNodeId) {
7
+ return createHash('sha256').update(`${canonicalTicketsRoot}\0${bridgeNodeId}`, 'utf8').digest('hex');
8
+ }
9
+ /** Retain local deck rows and only daemon-visible review rows. */
10
+ export function filterVisibleReviewTickets(tickets, visibleIds) {
11
+ let canonicalTicketsRoot;
12
+ try {
13
+ canonicalTicketsRoot = realpathSync(ticketsRoot());
14
+ }
15
+ catch {
16
+ return tickets.filter((ticket) => ticket.kind !== 'review');
17
+ }
18
+ return tickets.filter((ticket) => ticket.kind !== 'review' || visibleIds.has(opaqueTicketId(canonicalTicketsRoot, basename(ticket.dir))));
19
+ }
@@ -0,0 +1,19 @@
1
+ import type { TUI } from '@earendil-works/pi-tui';
2
+ import type { SurfaceHost } from '../surfaces/host.js';
3
+ import type { TicketSummary } from '../../core/human/types.js';
4
+ import type { CanvasSource } from '../../core/canvas/source.js';
5
+ export interface InboxSurfaceOptions {
6
+ host: SurfaceHost;
7
+ tui: TUI;
8
+ canvasSource: CanvasSource;
9
+ /** Injection seams for tests; production passes none. */
10
+ scan?: () => TicketSummary[];
11
+ }
12
+ export interface InboxSurfaceOwner {
13
+ /** Mount when closed and close when open. */
14
+ toggle(): void;
15
+ /** Idempotent surface and controller teardown. */
16
+ close(): void;
17
+ isOpen(): boolean;
18
+ }
19
+ export declare function createInboxSurface(opts: InboxSurfaceOptions): InboxSurfaceOwner;