@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,69 @@
1
+ import type { DatabaseSync } from 'node:sqlite';
2
+ import { type CommentAnchor, type CommentAuthorKind, type CommentStatus, type ReviewComment, type ReviewCommentEvent } from './types.js';
3
+ interface Actor {
4
+ kind: CommentAuthorKind;
5
+ node_id: string | null;
6
+ }
7
+ interface CommentMutationArgs {
8
+ actor: Actor;
9
+ operation_id: string;
10
+ if_revision?: number;
11
+ }
12
+ export declare function createComment(args: {
13
+ review_id: string;
14
+ text: string;
15
+ anchor: CommentAnchor;
16
+ line_text: string;
17
+ doc_hash: string;
18
+ actor: Actor;
19
+ operation_id: string;
20
+ }): {
21
+ comment: ReviewComment;
22
+ changed: true;
23
+ };
24
+ export declare function editComment(commentIdValue: string, args: {
25
+ text: string;
26
+ actor: Actor;
27
+ operation_id: string;
28
+ if_revision?: number;
29
+ }): {
30
+ comment: ReviewComment;
31
+ changed: boolean;
32
+ };
33
+ export declare function resolveComment(commentIdValue: string, args: CommentMutationArgs): {
34
+ comment: ReviewComment;
35
+ changed: boolean;
36
+ };
37
+ export declare function reopenComment(commentIdValue: string, args: CommentMutationArgs): {
38
+ comment: ReviewComment;
39
+ changed: boolean;
40
+ };
41
+ export declare function deleteComment(commentIdValue: string, args: CommentMutationArgs): {
42
+ comment: ReviewComment;
43
+ changed: boolean;
44
+ };
45
+ export declare function listComments(reviewId: string, opts?: {
46
+ status?: CommentStatus | 'all';
47
+ }): ReviewComment[];
48
+ export declare function getComment(commentIdValue: string): ReviewComment | null;
49
+ export declare function listCommentEvents(commentIdValue: string): ReviewCommentEvent[];
50
+ export declare function listReviewEvents(reviewId: string, opts: {
51
+ since_seq?: number;
52
+ limit?: number;
53
+ }): {
54
+ events: ReviewCommentEvent[];
55
+ next_since_seq: number;
56
+ };
57
+ export declare function snapshotCommentsLocked(db: DatabaseSync, reviewId: string): {
58
+ comments: import('../human/types.js').FeedbackComment[];
59
+ total: number;
60
+ unresolved: number;
61
+ };
62
+ export declare function appendDeliveryEvent(args: {
63
+ review_id: string;
64
+ comment_id: string;
65
+ kind: 'notified' | 'notify_failed';
66
+ payload: unknown;
67
+ operation_id: string;
68
+ }): void;
69
+ export {};
@@ -0,0 +1,295 @@
1
+ import { randomBytes } from 'node:crypto';
2
+ import { openDb, withCanvasWrite } from '../canvas/db.js';
3
+ import { nowIso } from '../fs-utils.js';
4
+ import { signalReviewActivity } from './signal.js';
5
+ import { COMMENT_EVENTS_PAGE_DEFAULT, COMMENT_EVENTS_PAGE_MAX, COMMENT_LINE_TEXT_MAX, COMMENT_TEXT_MAX, LIVE_COMMENTS_MAX, ReviewOperationError, } from './types.js';
6
+ function commentFromRow(row) {
7
+ return {
8
+ comment_id: row.comment_id,
9
+ review_id: row.review_id,
10
+ status: row.status,
11
+ revision: row.revision,
12
+ text: row.text,
13
+ anchor: {
14
+ line: row.anchor_line,
15
+ end_line: row.anchor_end_line,
16
+ ...(row.anchor_col_start === null ? {} : { col_start: row.anchor_col_start }),
17
+ ...(row.anchor_col_end === null ? {} : { col_end: row.anchor_col_end }),
18
+ ...(row.anchor_quote === null ? {} : { quote: row.anchor_quote }),
19
+ },
20
+ anchor_state: row.anchor_state,
21
+ anchor_line_text: row.anchor_line_text,
22
+ anchor_doc_hash: row.anchor_doc_hash,
23
+ author: { kind: row.author_kind, node_id: row.author_node_id },
24
+ updated_by: { kind: row.updated_by_kind, node_id: row.updated_by_node_id },
25
+ created_at: row.created_at,
26
+ updated_at: row.updated_at,
27
+ resolved_at: row.resolved_at,
28
+ deleted_at: row.deleted_at,
29
+ created_seq: row.created_seq,
30
+ };
31
+ }
32
+ function eventFromRow(row) {
33
+ return {
34
+ seq: row.seq,
35
+ review_id: row.review_id,
36
+ comment_id: row.comment_id,
37
+ kind: row.kind,
38
+ state_change: row.state_change === 0 ? 0 : 1,
39
+ revision_after: row.revision_after,
40
+ actor: { kind: row.actor_kind, node_id: row.actor_node_id },
41
+ at: row.at,
42
+ operation_id: row.operation_id,
43
+ ...(row.payload === null ? {} : { payload: JSON.parse(row.payload) }),
44
+ };
45
+ }
46
+ function json(value) {
47
+ return JSON.stringify(value);
48
+ }
49
+ function commentId() {
50
+ let id;
51
+ do
52
+ id = randomBytes(16).toString('hex');
53
+ while (/^0+$/.test(id));
54
+ return id;
55
+ }
56
+ function trimText(text) {
57
+ const trimmed = text.trim();
58
+ if (trimmed === '')
59
+ throw new Error('comment text must not be empty');
60
+ const received = Buffer.byteLength(trimmed, 'utf8');
61
+ if (received > COMMENT_TEXT_MAX) {
62
+ throw new ReviewOperationError('text_too_long', 'comment text exceeds the maximum length', {
63
+ limit: COMMENT_TEXT_MAX,
64
+ received,
65
+ });
66
+ }
67
+ return trimmed;
68
+ }
69
+ function truncateUtf8(text, maxBytes) {
70
+ if (Buffer.byteLength(text, 'utf8') <= maxBytes)
71
+ return text;
72
+ const marker = '… [truncated]';
73
+ const markerBytes = Buffer.byteLength(marker, 'utf8');
74
+ const bytes = Buffer.from(text, 'utf8');
75
+ let end = Math.max(0, maxBytes - markerBytes);
76
+ while (end > 0 && (bytes[end] & 0xc0) === 0x80)
77
+ end -= 1;
78
+ return `${bytes.subarray(0, end).toString('utf8')}${marker}`;
79
+ }
80
+ function getStoredComment(db, commentIdValue) {
81
+ return db.prepare('SELECT * FROM review_comments WHERE comment_id = ?').get(commentIdValue) ?? null;
82
+ }
83
+ function requireStoredComment(db, commentIdValue) {
84
+ const row = getStoredComment(db, commentIdValue);
85
+ if (row === null) {
86
+ throw new ReviewOperationError('unknown_comment', 'comment was not found', { received: commentIdValue });
87
+ }
88
+ return row;
89
+ }
90
+ function assertReviewExists(db, reviewId) {
91
+ const row = db.prepare('SELECT review_id FROM reviews WHERE review_id = ?').get(reviewId);
92
+ if (row === undefined) {
93
+ throw new ReviewOperationError('unknown_review', 'review was not found', { received: reviewId });
94
+ }
95
+ }
96
+ function assertRevision(row, expected) {
97
+ if (expected !== undefined && expected !== row.revision) {
98
+ throw new ReviewOperationError('stale_comment', 'comment revision is stale', {
99
+ revision: row.revision,
100
+ text: row.text,
101
+ });
102
+ }
103
+ }
104
+ function appendStateEvent(db, args) {
105
+ const result = db.prepare(`
106
+ INSERT INTO review_comment_events
107
+ (review_id, comment_id, kind, state_change, revision_after, actor_kind, actor_node_id, at, operation_id, payload)
108
+ VALUES (?, ?, ?, 1, ?, ?, ?, ?, ?, ?)
109
+ `).run(args.row.review_id, args.row.comment_id, args.kind, args.row.revision, args.actor.kind, args.actor.node_id, args.at, args.operation_id, json(args.payload));
110
+ return Number(result.lastInsertRowid);
111
+ }
112
+ function updateComment(db, row, fields, actor, at) {
113
+ const revision = row.revision + 1;
114
+ db.prepare(`
115
+ UPDATE review_comments
116
+ SET status = ?, revision = ?, text = ?, updated_by_kind = ?, updated_by_node_id = ?,
117
+ updated_at = ?, resolved_at = ?, deleted_at = ?
118
+ WHERE comment_id = ?
119
+ `).run(fields.status ?? row.status, revision, fields.text ?? row.text, actor.kind, actor.node_id, at, fields.resolved_at === undefined ? row.resolved_at : fields.resolved_at, fields.deleted_at === undefined ? row.deleted_at : fields.deleted_at, row.comment_id);
120
+ return { ...row, ...fields, revision, updated_by_kind: actor.kind, updated_by_node_id: actor.node_id, updated_at: at };
121
+ }
122
+ function completeMutation(result) {
123
+ if (result.changed)
124
+ signalReviewActivity();
125
+ return result;
126
+ }
127
+ export function createComment(args) {
128
+ const result = withCanvasWrite((db) => {
129
+ assertReviewExists(db, args.review_id);
130
+ const live = db.prepare("SELECT COUNT(*) AS count FROM review_comments WHERE review_id = ? AND status != 'deleted'").get(args.review_id);
131
+ if (Number(live.count) >= LIVE_COMMENTS_MAX) {
132
+ throw new ReviewOperationError('comment_limit_reached', 'review comment limit reached', {
133
+ limit: LIVE_COMMENTS_MAX,
134
+ live: Number(live.count),
135
+ });
136
+ }
137
+ const text = trimText(args.text);
138
+ const lineText = truncateUtf8(args.line_text, COMMENT_LINE_TEXT_MAX);
139
+ const at = nowIso();
140
+ let id = commentId();
141
+ while (getStoredComment(db, id) !== null)
142
+ id = commentId();
143
+ const inserted = db.prepare(`
144
+ INSERT INTO review_comments
145
+ (comment_id, review_id, status, revision, text, anchor_line, anchor_end_line,
146
+ anchor_col_start, anchor_col_end, anchor_quote, anchor_line_text, anchor_doc_hash, anchor_state,
147
+ author_kind, author_node_id, updated_by_kind, updated_by_node_id, created_at,
148
+ updated_at, resolved_at, deleted_at, created_seq)
149
+ VALUES (?, ?, 'open', 1, ?, ?, ?, ?, ?, ?, ?, ?, 'live', ?, ?, ?, ?, ?, ?, NULL, NULL, 0)
150
+ `).run(id, args.review_id, text, args.anchor.line, args.anchor.end_line, args.anchor.col_start ?? null, args.anchor.col_end ?? null, args.anchor.quote ?? null, lineText, args.doc_hash, args.actor.kind, args.actor.node_id, args.actor.kind, args.actor.node_id, at, at);
151
+ if (inserted.changes !== 1)
152
+ throw new Error('failed to insert review comment');
153
+ const row = getStoredComment(db, id);
154
+ const seq = appendStateEvent(db, {
155
+ row,
156
+ kind: 'created',
157
+ actor: args.actor,
158
+ operation_id: args.operation_id,
159
+ at,
160
+ payload: { text, anchor: args.anchor, line_text: lineText, doc_hash: args.doc_hash },
161
+ });
162
+ db.prepare('UPDATE review_comments SET created_seq = ? WHERE comment_id = ?').run(seq, id);
163
+ return { comment: commentFromRow({ ...row, created_seq: seq }), changed: true };
164
+ });
165
+ signalReviewActivity();
166
+ return result;
167
+ }
168
+ export function editComment(commentIdValue, args) {
169
+ const result = withCanvasWrite((db) => {
170
+ const row = requireStoredComment(db, commentIdValue);
171
+ if (row.status === 'deleted')
172
+ throw new ReviewOperationError('comment_deleted', 'comment is a deleted tombstone', { comment_id: row.comment_id, deleted_at: row.deleted_at });
173
+ const text = trimText(args.text);
174
+ if (row.text === text)
175
+ return { comment: commentFromRow(row), changed: false };
176
+ assertRevision(row, args.if_revision);
177
+ const at = nowIso();
178
+ const previousAnchor = commentFromRow(row).anchor;
179
+ const updated = updateComment(db, row, { text }, args.actor, at);
180
+ appendStateEvent(db, {
181
+ row: updated,
182
+ kind: 'edited',
183
+ actor: args.actor,
184
+ operation_id: args.operation_id,
185
+ at,
186
+ payload: {
187
+ previous_text: row.text,
188
+ text,
189
+ previous_anchor: previousAnchor,
190
+ anchor: commentFromRow(updated).anchor,
191
+ },
192
+ });
193
+ return { comment: commentFromRow(updated), changed: true };
194
+ });
195
+ return completeMutation(result);
196
+ }
197
+ function transitionComment(commentIdValue, args, target, kind) {
198
+ const result = withCanvasWrite((db) => {
199
+ const row = requireStoredComment(db, commentIdValue);
200
+ if (row.status === 'deleted') {
201
+ if (target === 'deleted')
202
+ return { comment: commentFromRow(row), changed: false };
203
+ throw new ReviewOperationError('comment_deleted', 'comment is a deleted tombstone', { comment_id: row.comment_id, deleted_at: row.deleted_at });
204
+ }
205
+ if (row.status === target)
206
+ return { comment: commentFromRow(row), changed: false };
207
+ assertRevision(row, args.if_revision);
208
+ const at = nowIso();
209
+ const updated = updateComment(db, row, {
210
+ status: target,
211
+ resolved_at: target === 'resolved' ? at : target === 'open' ? null : undefined,
212
+ deleted_at: target === 'deleted' ? at : undefined,
213
+ }, args.actor, at);
214
+ appendStateEvent(db, {
215
+ row: updated,
216
+ kind,
217
+ actor: args.actor,
218
+ operation_id: args.operation_id,
219
+ at,
220
+ payload: {
221
+ previous_status: row.status,
222
+ status: target,
223
+ previous_text: row.text,
224
+ text: updated.text,
225
+ previous_anchor: commentFromRow(row).anchor,
226
+ anchor: commentFromRow(updated).anchor,
227
+ },
228
+ });
229
+ return { comment: commentFromRow(updated), changed: true };
230
+ });
231
+ return completeMutation(result);
232
+ }
233
+ export function resolveComment(commentIdValue, args) {
234
+ return transitionComment(commentIdValue, args, 'resolved', 'resolved');
235
+ }
236
+ export function reopenComment(commentIdValue, args) {
237
+ return transitionComment(commentIdValue, args, 'open', 'reopened');
238
+ }
239
+ export function deleteComment(commentIdValue, args) {
240
+ return transitionComment(commentIdValue, args, 'deleted', 'deleted');
241
+ }
242
+ export function listComments(reviewId, opts) {
243
+ const db = openDb();
244
+ const status = opts?.status;
245
+ const rows = status === undefined
246
+ ? db.prepare("SELECT * FROM review_comments WHERE review_id = ? AND status != 'deleted' ORDER BY anchor_line, created_seq").all(reviewId)
247
+ : status === 'all'
248
+ ? db.prepare('SELECT * FROM review_comments WHERE review_id = ? ORDER BY anchor_line, created_seq').all(reviewId)
249
+ : db.prepare('SELECT * FROM review_comments WHERE review_id = ? AND status = ? ORDER BY anchor_line, created_seq').all(reviewId, status);
250
+ return rows.map(commentFromRow);
251
+ }
252
+ export function getComment(commentIdValue) {
253
+ const row = getStoredComment(openDb(), commentIdValue);
254
+ return row === null ? null : commentFromRow(row);
255
+ }
256
+ export function listCommentEvents(commentIdValue) {
257
+ const rows = openDb().prepare('SELECT * FROM review_comment_events WHERE comment_id = ? ORDER BY seq').all(commentIdValue);
258
+ return rows.map(eventFromRow);
259
+ }
260
+ export function listReviewEvents(reviewId, opts) {
261
+ const since = opts.since_seq ?? 0;
262
+ const limit = Math.min(Math.max(opts.limit ?? COMMENT_EVENTS_PAGE_DEFAULT, 1), COMMENT_EVENTS_PAGE_MAX);
263
+ const rows = openDb().prepare('SELECT * FROM review_comment_events WHERE review_id = ? AND seq > ? ORDER BY seq LIMIT ?').all(reviewId, since, limit);
264
+ const events = rows.map(eventFromRow);
265
+ return { events, next_since_seq: events.length === 0 ? since : events[events.length - 1].seq };
266
+ }
267
+ export function snapshotCommentsLocked(db, reviewId) {
268
+ const rows = db.prepare("SELECT * FROM review_comments WHERE review_id = ? AND status != 'deleted' ORDER BY anchor_line, created_seq").all(reviewId);
269
+ const comments = rows.map((row) => ({
270
+ id: row.comment_id,
271
+ line: row.anchor_line,
272
+ endLine: row.anchor_end_line,
273
+ ...(row.anchor_quote === null ? {} : { quote: row.anchor_quote }),
274
+ ...(row.anchor_col_start === null ? {} : { colStart: row.anchor_col_start }),
275
+ ...(row.anchor_col_end === null ? {} : { colEnd: row.anchor_col_end }),
276
+ lineText: row.anchor_line_text,
277
+ comment: row.text,
278
+ createdAt: row.created_at,
279
+ }));
280
+ return { comments, total: rows.length, unresolved: rows.filter((row) => row.status === 'open').length };
281
+ }
282
+ export function appendDeliveryEvent(args) {
283
+ withCanvasWrite((db) => {
284
+ assertReviewExists(db, args.review_id);
285
+ const row = requireStoredComment(db, args.comment_id);
286
+ if (row.review_id !== args.review_id)
287
+ throw new ReviewOperationError('unknown_comment', 'comment was not found', { received: args.comment_id });
288
+ db.prepare(`
289
+ INSERT INTO review_comment_events
290
+ (review_id, comment_id, kind, state_change, revision_after, actor_kind, actor_node_id, at, operation_id, payload)
291
+ VALUES (?, ?, ?, 0, NULL, 'system', NULL, ?, ?, ?)
292
+ `).run(args.review_id, args.comment_id, args.kind, nowIso(), args.operation_id, json(args.payload));
293
+ });
294
+ signalReviewActivity();
295
+ }
@@ -0,0 +1,35 @@
1
+ import { type InitialModelRegistryLike } from '../model-routes.js';
2
+ export interface OriginCapture {
3
+ sourceFile: string;
4
+ sourceSessionId: string;
5
+ leafId: string;
6
+ modelSpec: string;
7
+ }
8
+ export interface ReviewCompanionSpec {
9
+ nodeId: string;
10
+ reviewId: string;
11
+ originNodeId: string;
12
+ branchFile: string;
13
+ targetFile: string;
14
+ modelSpec: string;
15
+ cwd: string;
16
+ profileId: string | null;
17
+ }
18
+ type ExactModel = {
19
+ provider: string;
20
+ id: string;
21
+ };
22
+ type ExactModelRegistry = InitialModelRegistryLike<ExactModel>;
23
+ /** Capture an origin without launching it or acquiring its broker's writer role. */
24
+ export declare function captureOrigin(originNodeId: string, deps?: {
25
+ registry?: ExactModelRegistry;
26
+ }): Promise<OriginCapture>;
27
+ /** Materialize the immutable review fork, reusing only an already-valid branch. */
28
+ export declare function materializeReviewBranch(reviewId: string, capture: OriginCapture): string;
29
+ /** Create the ordinary, promptless companion node. Realization owns its launch. */
30
+ export declare function spawnReviewCompanion(spec: ReviewCompanionSpec): void;
31
+ /** A companion is bound only when its session coordinates and visible boundary are durable. */
32
+ export declare function isReviewCompanionBound(nodeId: string): boolean;
33
+ /** Wait for the durable companion bind without owning companion liveness. */
34
+ export declare function awaitCompanionBind(nodeId: string, deadlineMs: number): Promise<boolean>;
35
+ export {};
@@ -0,0 +1,205 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ import { existsSync } from 'node:fs';
3
+ import { basename, isAbsolute, resolve } from 'node:path';
4
+ import { BrokerClient } from '../broker-client/index.js';
5
+ import { getNode } from '../canvas/index.js';
6
+ import { ensureReviewDir, reviewBranchPath } from '../canvas/paths.js';
7
+ import { expandModelCandidates, selectInitialModelRoute } from '../model-routes.js';
8
+ import { buildLaunchSpec } from '../runtime/launch.js';
9
+ import { openModelRegistry } from '../runtime/model-registry.js';
10
+ import { isBrokerLive } from '../runtime/model-swap.js';
11
+ import { spawnNode } from '../runtime/nodes.js';
12
+ import { SessionManager } from '../runtime/broker-sdk.js';
13
+ import { materializeSessionBranchAt } from '../runtime/session-branch.js';
14
+ import { isReviewBoundary } from '../runtime/session-visibility.js';
15
+ import { ReviewOperationError } from './types.js';
16
+ const EXACT_MODEL_SPEC = /^[^/\s:]+\/[^/\s:]+:(?:off|minimal|low|medium|high|xhigh|max)$/;
17
+ const BIND_POLL_MS = 100;
18
+ function originMissing(originNodeId) {
19
+ return new ReviewOperationError('review_origin_missing', 'review origin was not found', { origin_node_id: originNodeId });
20
+ }
21
+ function originUnforkable(originNodeId, reason, detail = {}) {
22
+ return new ReviewOperationError('review_origin_unforkable', 'review origin has no forkable exact session', {
23
+ origin_node_id: originNodeId,
24
+ reason,
25
+ ...detail,
26
+ });
27
+ }
28
+ async function validateCapture(originNodeId, value, registry) {
29
+ if (!isAbsolute(value.sourceFile) || !existsSync(value.sourceFile) || value.sourceSessionId === '' || value.leafId === null || value.leafId === '') {
30
+ throw originUnforkable(originNodeId, 'no_forkable_session');
31
+ }
32
+ if (value.modelSpec === null || !EXACT_MODEL_SPEC.test(value.modelSpec)) {
33
+ throw originUnforkable(originNodeId, 'model_unresolvable');
34
+ }
35
+ const selection = selectInitialModelRoute({ kind: 'exact', spec: value.modelSpec }, registry ?? await openModelRegistry(), { cwd: value.cwd, profileId: value.profileId });
36
+ if (selection.selected === undefined) {
37
+ throw originUnforkable(originNodeId, 'model_unresolvable', {
38
+ model_reason: selection.rejected[0]?.reason,
39
+ });
40
+ }
41
+ return {
42
+ sourceFile: value.sourceFile,
43
+ sourceSessionId: value.sourceSessionId,
44
+ leafId: value.leafId,
45
+ modelSpec: value.modelSpec,
46
+ };
47
+ }
48
+ /** Read the broker's fork coordinate through its observer-only protocol path.
49
+ * This connection can inspect a streaming origin but has no writer authority. */
50
+ function captureLiveOrigin(originNodeId) {
51
+ return new Promise((resolveCapture, reject) => {
52
+ const client = new BrokerClient(originNodeId);
53
+ let settled = false;
54
+ function finish(action) {
55
+ if (settled)
56
+ return;
57
+ settled = true;
58
+ client.close();
59
+ action();
60
+ }
61
+ client.on('error', (error) => finish(() => reject(error)));
62
+ client.on('close', () => finish(() => reject(new Error('origin broker closed before fork coordinates were read'))));
63
+ client.on('connect', () => {
64
+ client.send({ type: 'hello', role: 'observer', client_id: randomUUID() });
65
+ void client.request({ type: 'get_human_fork_coordinates' })
66
+ .then((frame) => {
67
+ if (frame.kind !== 'human_fork_coordinates') {
68
+ finish(() => reject(new Error('origin broker returned an unexpected fork-coordinate response')));
69
+ return;
70
+ }
71
+ finish(() => resolveCapture(frame));
72
+ })
73
+ .catch((error) => finish(() => reject(error)));
74
+ });
75
+ client.connect();
76
+ });
77
+ }
78
+ /** Capture an origin without launching it or acquiring its broker's writer role. */
79
+ export async function captureOrigin(originNodeId, deps = {}) {
80
+ const node = getNode(originNodeId);
81
+ if (node === null)
82
+ throw originMissing(originNodeId);
83
+ if (isBrokerLive(node)) {
84
+ const coordinates = await captureLiveOrigin(originNodeId);
85
+ return validateCapture(originNodeId, {
86
+ ...coordinates,
87
+ cwd: node.cwd,
88
+ profileId: node.profile_id,
89
+ }, deps.registry);
90
+ }
91
+ const sourceFile = typeof node.pi_session_file === 'string' ? node.pi_session_file : '';
92
+ let sourceSessionId = '';
93
+ let leafId = null;
94
+ let modelSpec = null;
95
+ if (isAbsolute(sourceFile) && existsSync(sourceFile)) {
96
+ let session;
97
+ try {
98
+ session = SessionManager.open(sourceFile);
99
+ }
100
+ catch {
101
+ return validateCapture(originNodeId, {
102
+ sourceFile,
103
+ sourceSessionId,
104
+ leafId,
105
+ modelSpec,
106
+ cwd: node.cwd,
107
+ profileId: node.profile_id,
108
+ }, deps.registry);
109
+ }
110
+ sourceSessionId = session.getSessionId();
111
+ leafId = session.getLeafId();
112
+ const launchSpec = node.launch?.model;
113
+ const parsed = typeof launchSpec === 'string'
114
+ ? expandModelCandidates({ kind: 'exact', spec: launchSpec }, node.cwd, node.profile_id)[0]
115
+ : undefined;
116
+ if (parsed !== undefined) {
117
+ const thinking = parsed.thinkingLevel ?? (session.buildSessionContext().thinkingLevel || 'off');
118
+ modelSpec = `${parsed.providerId}/${parsed.modelId}:${thinking}`;
119
+ }
120
+ }
121
+ return validateCapture(originNodeId, {
122
+ sourceFile,
123
+ sourceSessionId,
124
+ leafId,
125
+ modelSpec,
126
+ cwd: node.cwd,
127
+ profileId: node.profile_id,
128
+ }, deps.registry);
129
+ }
130
+ /** Materialize the immutable review fork, reusing only an already-valid branch. */
131
+ export function materializeReviewBranch(reviewId, capture) {
132
+ ensureReviewDir(reviewId);
133
+ const branchFile = reviewBranchPath(reviewId);
134
+ if (existsSync(branchFile)) {
135
+ const branch = SessionManager.open(branchFile);
136
+ if (branch.getSessionFile() === resolve(branchFile) && branch.getSessionId() !== '')
137
+ return branchFile;
138
+ }
139
+ materializeSessionBranchAt(capture, branchFile);
140
+ return branchFile;
141
+ }
142
+ /** Create the ordinary, promptless companion node. Realization owns its launch. */
143
+ export function spawnReviewCompanion(spec) {
144
+ if (!isAbsolute(spec.branchFile) || !isAbsolute(spec.targetFile)) {
145
+ throw new Error('review companion requires absolute branch and target paths');
146
+ }
147
+ if (!EXACT_MODEL_SPEC.test(spec.modelSpec)) {
148
+ throw new Error('review companion requires an exact model spec');
149
+ }
150
+ const { launch } = buildLaunchSpec('review/companion', 'base', {
151
+ lifecycle: 'resident',
152
+ hasManager: false,
153
+ model: spec.modelSpec,
154
+ modelExact: true,
155
+ cwd: spec.cwd,
156
+ profileId: spec.profileId,
157
+ });
158
+ spawnNode({
159
+ nodeId: spec.nodeId,
160
+ kind: 'review/companion',
161
+ mode: 'base',
162
+ lifecycle: 'resident',
163
+ cwd: spec.cwd,
164
+ profile_id: spec.profileId,
165
+ parent: spec.originNodeId,
166
+ subscribe: false,
167
+ forkFrom: spec.branchFile,
168
+ modelOverride: spec.modelSpec,
169
+ reviewBinding: {
170
+ review_id: spec.reviewId,
171
+ origin_node_id: spec.originNodeId,
172
+ branch_file: spec.branchFile,
173
+ target_file: spec.targetFile,
174
+ },
175
+ name: `review ${basename(spec.targetFile)}`,
176
+ launch,
177
+ });
178
+ }
179
+ /** A companion is bound only when its session coordinates and visible boundary are durable. */
180
+ export function isReviewCompanionBound(nodeId) {
181
+ const node = getNode(nodeId);
182
+ const binding = node?.review_binding;
183
+ const sessionFile = node?.pi_session_file;
184
+ if (binding == null || node?.pi_session_id == null || typeof sessionFile !== 'string' || !existsSync(sessionFile)) {
185
+ return false;
186
+ }
187
+ try {
188
+ return SessionManager.open(sessionFile).getEntries().some((entry) => isReviewBoundary(entry, binding.review_id));
189
+ }
190
+ catch {
191
+ return false;
192
+ }
193
+ }
194
+ /** Wait for the durable companion bind without owning companion liveness. */
195
+ export async function awaitCompanionBind(nodeId, deadlineMs) {
196
+ const deadline = Date.now() + Math.max(0, deadlineMs);
197
+ for (;;) {
198
+ if (isReviewCompanionBound(nodeId))
199
+ return true;
200
+ const remaining = deadline - Date.now();
201
+ if (remaining <= 0)
202
+ return false;
203
+ await new Promise((resolveWait) => setTimeout(resolveWait, Math.min(BIND_POLL_MS, remaining)));
204
+ }
205
+ }
@@ -0,0 +1,27 @@
1
+ import type { DatabaseSync } from 'node:sqlite';
2
+ import type { ReviewRecord } from './types.js';
3
+ import { type CommentAnchor } from './types.js';
4
+ type SourcePhase = 'submit' | 'comment';
5
+ /** Read the reviewed document once, preserving the exact bytes used for its digest. */
6
+ export declare function readReviewSource(file: string, phase?: SourcePhase): {
7
+ bytes: Buffer;
8
+ sha256: string;
9
+ lines: string[];
10
+ };
11
+ /** Require both the caller's rendered source and the persisted range coordinate base to be current. */
12
+ export declare function requireCurrentDocument(review: ReviewRecord, expected_doc_hash: string): {
13
+ bytes: Buffer;
14
+ sha256: string;
15
+ lines: string[];
16
+ };
17
+ /** Verify a create-time source precondition from the review row held by the caller's canvas write transaction. */
18
+ export declare function requireCurrentDocumentLocked(db: DatabaseSync, review_id: string, expected_doc_hash: string): {
19
+ bytes: Buffer;
20
+ sha256: string;
21
+ lines: string[];
22
+ };
23
+ /** Reject malformed ranges rather than normalizing them into a different anchor. */
24
+ export declare function validateAnchorShape(anchor: CommentAnchor): void;
25
+ /** Capture the full source range used to render an anchor, without silently clamping it. */
26
+ export declare function captureAnchorText(lines: string[], anchor: CommentAnchor): string;
27
+ export {};