@north-light/cli 0.3.530 → 0.3.532

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 (495) hide show
  1. package/dist/clients/attach/session/connection.js +1 -1
  2. package/dist/clients/attach/session/reconnect.js +1 -1
  3. package/dist/clients/attach/viewer.js +508 -508
  4. package/dist/core/async-array.d.ts +7 -0
  5. package/dist/core/async-array.js +1 -0
  6. package/dist/core/audit.d.ts +1 -1
  7. package/dist/core/audit.js +2 -2
  8. package/dist/core/canvas/attention.d.ts +4 -4
  9. package/dist/core/canvas/attention.js +1 -1
  10. package/dist/core/canvas/boot.d.ts +4 -4
  11. package/dist/core/canvas/boot.js +1 -1
  12. package/dist/core/canvas/canvas.d.ts +59 -59
  13. package/dist/core/canvas/canvas.js +19 -19
  14. package/dist/core/canvas/context-strip.js +2 -2
  15. package/dist/core/canvas/crons.d.ts +27 -27
  16. package/dist/core/canvas/crons.js +11 -11
  17. package/dist/core/canvas/daemon-actions.d.ts +10 -10
  18. package/dist/core/canvas/daemon-actions.js +8 -8
  19. package/dist/core/canvas/daemon-owner.d.ts +3 -3
  20. package/dist/core/canvas/daemon-owner.js +2 -2
  21. package/dist/core/canvas/db.d.ts +19 -30
  22. package/dist/core/canvas/db.js +3 -2
  23. package/dist/core/canvas/deliveries.d.ts +16 -16
  24. package/dist/core/canvas/deliveries.js +24 -24
  25. package/dist/core/canvas/executions.d.ts +8 -8
  26. package/dist/core/canvas/executions.js +1 -1
  27. package/dist/core/canvas/focuses.d.ts +8 -8
  28. package/dist/core/canvas/focuses.js +1 -1
  29. package/dist/core/canvas/history.d.ts +3 -3
  30. package/dist/core/canvas/history.js +9 -9
  31. package/dist/core/canvas/install-id.d.ts +1 -1
  32. package/dist/core/canvas/install-id.js +1 -1
  33. package/dist/core/canvas/managed-worktree-sweep-candidates.d.ts +1 -1
  34. package/dist/core/canvas/managed-worktree-sweep-candidates.js +2 -2
  35. package/dist/core/canvas/memory-reads.d.ts +6 -6
  36. package/dist/core/canvas/memory-reads.js +1 -1
  37. package/dist/core/canvas/nav-model.d.ts +13 -13
  38. package/dist/core/canvas/nav-model.js +1 -1
  39. package/dist/core/canvas/node-agent-paths.d.ts +6 -6
  40. package/dist/core/canvas/node-agent-paths.js +1 -1
  41. package/dist/core/canvas/node-tokens.d.ts +7 -7
  42. package/dist/core/canvas/node-tokens.js +3 -3
  43. package/dist/core/canvas/outcome-actions.d.ts +5 -5
  44. package/dist/core/canvas/outcome-actions.js +3 -3
  45. package/dist/core/canvas/recovery.d.ts +26 -26
  46. package/dist/core/canvas/recovery.js +2 -2
  47. package/dist/core/canvas/render-source.d.ts +1 -1
  48. package/dist/core/canvas/render-source.js +1 -1
  49. package/dist/core/canvas/sessions.d.ts +10 -10
  50. package/dist/core/canvas/sessions.js +4 -4
  51. package/dist/core/canvas/source.js +1 -1
  52. package/dist/core/canvas/structured-requests.d.ts +15 -15
  53. package/dist/core/canvas/structured-requests.js +5 -5
  54. package/dist/core/canvas/tree.d.ts +9 -9
  55. package/dist/core/canvas/tree.js +5 -5
  56. package/dist/core/canvas/waits.d.ts +13 -13
  57. package/dist/core/canvas/waits.js +6 -6
  58. package/dist/core/canvas/worktrees.d.ts +15 -15
  59. package/dist/core/canvas/worktrees.js +1 -1
  60. package/dist/core/command-hooks/transport/exec-lifecycle.js +1 -1
  61. package/dist/core/conversation-store/file-store.d.ts +7 -7
  62. package/dist/core/conversation-store/file-store.js +9 -9
  63. package/dist/core/conversation-store/index.d.ts +16 -14
  64. package/dist/core/conversation-store/index.js +1 -1
  65. package/dist/core/conversation-store/listener.js +5 -5
  66. package/dist/core/conversation-store/patch.d.ts +3 -1
  67. package/dist/core/conversation-store/patch.js +1 -1
  68. package/dist/core/feed/feed.js +3 -3
  69. package/dist/core/feed/inbox.d.ts +2 -2
  70. package/dist/core/feed/inbox.js +1 -1
  71. package/dist/core/feed/messages.d.ts +11 -12
  72. package/dist/core/feed/messages.js +5 -5
  73. package/dist/core/feed/reports.d.ts +4 -4
  74. package/dist/core/feed/reports.js +2 -2
  75. package/dist/core/grants/cover.d.ts +1 -1
  76. package/dist/core/grants/cover.js +1 -1
  77. package/dist/core/grants/local.d.ts +1 -1
  78. package/dist/core/grants/local.js +1 -1
  79. package/dist/core/grants/mirror.d.ts +19 -19
  80. package/dist/core/grants/mirror.js +2 -2
  81. package/dist/core/grants/on-sync.d.ts +1 -1
  82. package/dist/core/grants/on-sync.js +1 -1
  83. package/dist/core/grants/remove.js +1 -1
  84. package/dist/core/grants/sync.js +1 -1
  85. package/dist/core/graph/access.d.ts +17 -17
  86. package/dist/core/graph/access.js +3 -3
  87. package/dist/core/graph/custom.d.ts +16 -16
  88. package/dist/core/graph/custom.js +9 -9
  89. package/dist/core/graph/deletion.d.ts +3 -7
  90. package/dist/core/graph/deletion.js +4 -4
  91. package/dist/core/graph/documents.d.ts +24 -27
  92. package/dist/core/graph/documents.js +7 -7
  93. package/dist/core/graph/edges.d.ts +13 -13
  94. package/dist/core/graph/edges.js +1 -1
  95. package/dist/core/graph/events.d.ts +7 -9
  96. package/dist/core/graph/events.js +8 -8
  97. package/dist/core/graph/exposures.d.ts +6 -6
  98. package/dist/core/graph/exposures.js +4 -4
  99. package/dist/core/graph/jobs.d.ts +6 -8
  100. package/dist/core/graph/jobs.js +2 -2
  101. package/dist/core/graph/kinds/action.js +1 -1
  102. package/dist/core/graph/kinds/custom.js +2 -2
  103. package/dist/core/graph/kinds/document.d.ts +1 -0
  104. package/dist/core/graph/kinds/document.js +4 -4
  105. package/dist/core/graph/kinds/dto.d.ts +2 -2
  106. package/dist/core/graph/kinds/dto.js +1 -1
  107. package/dist/core/graph/kinds/job.js +2 -2
  108. package/dist/core/graph/kinds/kind.d.ts +6 -8
  109. package/dist/core/graph/kinds/kind.js +1 -1
  110. package/dist/core/graph/kinds/node.js +5 -5
  111. package/dist/core/graph/kinds/owner.js +2 -2
  112. package/dist/core/graph/kinds/registry.d.ts +6 -9
  113. package/dist/core/graph/kinds/registry.js +1 -1
  114. package/dist/core/graph/names.d.ts +6 -6
  115. package/dist/core/graph/names.js +3 -3
  116. package/dist/core/graph/object-waits.d.ts +4 -7
  117. package/dist/core/graph/object-waits.js +1 -1
  118. package/dist/core/graph/objects.d.ts +14 -14
  119. package/dist/core/graph/objects.js +9 -9
  120. package/dist/core/graph/package-docs.d.ts +2 -7
  121. package/dist/core/graph/package-docs.js +5 -5
  122. package/dist/core/graph/package-kinds.d.ts +2 -5
  123. package/dist/core/graph/package-kinds.js +1 -1
  124. package/dist/core/graph/package-reconcile.d.ts +2 -5
  125. package/dist/core/graph/package-reconcile.js +1 -1
  126. package/dist/core/graph/reader.d.ts +18 -18
  127. package/dist/core/graph/reader.js +3 -3
  128. package/dist/core/graph/receivers.d.ts +4 -4
  129. package/dist/core/graph/receivers.js +5 -5
  130. package/dist/core/graph/repo-sync/exchange.d.ts +3 -7
  131. package/dist/core/graph/repo-sync/exchange.js +2 -2
  132. package/dist/core/graph/repo-sync/repos.d.ts +7 -5
  133. package/dist/core/graph/repo-sync/repos.js +3 -3
  134. package/dist/core/graph/repo-sync/sync.d.ts +3 -6
  135. package/dist/core/graph/repo-sync/sync.js +2 -2
  136. package/dist/core/graph/rules.d.ts +5 -5
  137. package/dist/core/graph/rules.js +3 -3
  138. package/dist/core/graph/spaces/app.js +1 -1
  139. package/dist/core/graph/spaces/index.d.ts +4 -5
  140. package/dist/core/graph/spaces/index.js +1 -1
  141. package/dist/core/graph/spaces/own-memory.d.ts +4 -4
  142. package/dist/core/graph/spaces/own-memory.js +1 -1
  143. package/dist/core/graph/spaces/person.js +3 -3
  144. package/dist/core/graph/spaces/repo.d.ts +1 -1
  145. package/dist/core/graph/spaces/repo.js +1 -1
  146. package/dist/core/graph/watches.d.ts +15 -15
  147. package/dist/core/graph/watches.js +10 -10
  148. package/dist/core/human/feedback-companion.d.ts +2 -2
  149. package/dist/core/human/feedback-companion.js +1 -1
  150. package/dist/core/human/feedback.d.ts +3 -3
  151. package/dist/core/human/feedback.js +1 -1
  152. package/dist/core/human/requests.d.ts +34 -33
  153. package/dist/core/human/requests.js +20 -20
  154. package/dist/core/human/scan.d.ts +2 -2
  155. package/dist/core/human/scan.js +1 -1
  156. package/dist/core/human/tickets.d.ts +9 -9
  157. package/dist/core/human/tickets.js +1 -1
  158. package/dist/core/llm/app-rungs.d.ts +1 -1
  159. package/dist/core/llm/app-rungs.js +1 -1
  160. package/dist/core/llm/run.js +2 -2
  161. package/dist/core/peer/directory.d.ts +1 -1
  162. package/dist/core/peer/directory.js +1 -1
  163. package/dist/core/peer/envelope.d.ts +3 -3
  164. package/dist/core/peer/envelope.js +1 -1
  165. package/dist/core/peer/home.d.ts +13 -7
  166. package/dist/core/peer/home.js +2 -2
  167. package/dist/core/peer/ingest.d.ts +6 -6
  168. package/dist/core/peer/ingest.js +1 -1
  169. package/dist/core/peer/outbox-store.d.ts +14 -14
  170. package/dist/core/peer/outbox-store.js +5 -5
  171. package/dist/core/peer/receiver.d.ts +2 -2
  172. package/dist/core/peer/receiver.js +1 -1
  173. package/dist/core/peer/stubs.d.ts +10 -10
  174. package/dist/core/peer/stubs.js +1 -1
  175. package/dist/core/providers/approval.d.ts +2 -2
  176. package/dist/core/providers/approval.js +2 -2
  177. package/dist/core/providers/audit.d.ts +3 -3
  178. package/dist/core/providers/audit.js +2 -2
  179. package/dist/core/providers/bundles.js +2 -2
  180. package/dist/core/providers/call.d.ts +2 -2
  181. package/dist/core/providers/call.js +1 -1
  182. package/dist/core/providers/files.d.ts +1 -1
  183. package/dist/core/providers/files.js +1 -1
  184. package/dist/core/providers/mint.js +1 -1
  185. package/dist/core/providers/receipts.d.ts +1 -1
  186. package/dist/core/providers/receipts.js +2 -2
  187. package/dist/core/review/birth.js +1 -1
  188. package/dist/core/review/comments.d.ts +19 -19
  189. package/dist/core/review/comments.js +5 -5
  190. package/dist/core/review/companion.d.ts +1 -1
  191. package/dist/core/review/companion.js +1 -1
  192. package/dist/core/review/document.d.ts +3 -3
  193. package/dist/core/review/document.js +2 -2
  194. package/dist/core/review/fork.js +2 -2
  195. package/dist/core/review/realize.js +1 -1
  196. package/dist/core/review/remap.d.ts +2 -2
  197. package/dist/core/review/remap.js +4 -4
  198. package/dist/core/review/stage.d.ts +1 -1
  199. package/dist/core/review/stage.js +1 -1
  200. package/dist/core/review/store.d.ts +21 -21
  201. package/dist/core/review/store.js +1 -1
  202. package/dist/core/runs/activity.d.ts +1 -1
  203. package/dist/core/runs/activity.js +5 -5
  204. package/dist/core/runs/confinement.d.ts +7 -7
  205. package/dist/core/runs/confinement.js +2 -2
  206. package/dist/core/runs/events.d.ts +12 -12
  207. package/dist/core/runs/events.js +4 -4
  208. package/dist/core/runs/operations.d.ts +11 -11
  209. package/dist/core/runs/operations.js +5 -5
  210. package/dist/core/runs/questions.d.ts +10 -10
  211. package/dist/core/runs/questions.js +3 -3
  212. package/dist/core/runtime/auth-reload.js +1 -1
  213. package/dist/core/runtime/bearings.d.ts +5 -5
  214. package/dist/core/runtime/bearings.js +6 -6
  215. package/dist/core/runtime/broker-inventory.js +1 -1
  216. package/dist/core/runtime/broker-request.js +1 -1
  217. package/dist/core/runtime/broker.js +1 -1
  218. package/dist/core/runtime/close.d.ts +3 -3
  219. package/dist/core/runtime/close.js +1 -1
  220. package/dist/core/runtime/deliver-live.js +1 -1
  221. package/dist/core/runtime/fleet.d.ts +2 -2
  222. package/dist/core/runtime/host.d.ts +3 -3
  223. package/dist/core/runtime/host.js +3 -3
  224. package/dist/core/runtime/kickoff.d.ts +12 -12
  225. package/dist/core/runtime/kickoff.js +17 -17
  226. package/dist/core/runtime/launch-target.d.ts +1 -1
  227. package/dist/core/runtime/launch-target.js +1 -1
  228. package/dist/core/runtime/ledger.d.ts +3 -3
  229. package/dist/core/runtime/ledger.js +3 -3
  230. package/dist/core/runtime/lifecycle.d.ts +1 -1
  231. package/dist/core/runtime/lifecycle.js +2 -2
  232. package/dist/core/runtime/memory-admission.js +1 -1
  233. package/dist/core/runtime/model-swap.d.ts +2 -2
  234. package/dist/core/runtime/model-swap.js +1 -1
  235. package/dist/core/runtime/node-read.d.ts +1 -1
  236. package/dist/core/runtime/node-read.js +2 -2
  237. package/dist/core/runtime/nodes.d.ts +6 -6
  238. package/dist/core/runtime/nodes.js +1 -1
  239. package/dist/core/runtime/outcome-document.d.ts +1 -1
  240. package/dist/core/runtime/outcome-document.js +1 -1
  241. package/dist/core/runtime/persona.d.ts +3 -3
  242. package/dist/core/runtime/persona.js +2 -2
  243. package/dist/core/runtime/placement.d.ts +11 -11
  244. package/dist/core/runtime/placement.js +1 -1
  245. package/dist/core/runtime/promote.d.ts +3 -3
  246. package/dist/core/runtime/promote.js +1 -1
  247. package/dist/core/runtime/recycle.js +1 -1
  248. package/dist/core/runtime/reopen.d.ts +5 -5
  249. package/dist/core/runtime/reopen.js +1 -1
  250. package/dist/core/runtime/reset.d.ts +4 -4
  251. package/dist/core/runtime/reset.js +1 -1
  252. package/dist/core/runtime/revive-all.d.ts +2 -2
  253. package/dist/core/runtime/revive-all.js +1 -1
  254. package/dist/core/runtime/revive.d.ts +4 -4
  255. package/dist/core/runtime/revive.js +2 -2
  256. package/dist/core/runtime/roadmap.d.ts +6 -6
  257. package/dist/core/runtime/roadmap.js +5 -5
  258. package/dist/core/runtime/session-branch.d.ts +1 -1
  259. package/dist/core/runtime/session-branch.js +1 -1
  260. package/dist/core/runtime/session-list-cache.js +1 -1
  261. package/dist/core/runtime/situational-live.js +1 -1
  262. package/dist/core/runtime/spawn.d.ts +2 -2
  263. package/dist/core/runtime/spawn.js +2 -2
  264. package/dist/core/runtime/stop-guard.d.ts +2 -2
  265. package/dist/core/runtime/stop-guard.js +3 -3
  266. package/dist/core/runtime/warm-pool.d.ts +2 -2
  267. package/dist/core/runtime/warm-pool.js +1 -1
  268. package/dist/core/spaces/mounts.d.ts +2 -2
  269. package/dist/core/spaces/mounts.js +1 -1
  270. package/dist/core/spaces/permissions.d.ts +1 -1
  271. package/dist/core/spaces/permissions.js +1 -1
  272. package/dist/core/spaces/process.d.ts +1 -1
  273. package/dist/core/spaces/process.js +1 -1
  274. package/dist/core/spaces/space.js +1 -1
  275. package/dist/core/spaces/stop.d.ts +3 -3
  276. package/dist/core/spaces/stop.js +2 -2
  277. package/dist/core/spaces/users.d.ts +6 -6
  278. package/dist/core/spaces/users.js +1 -1
  279. package/dist/core/storage/attachments.d.ts +2 -2
  280. package/dist/core/storage/attachments.js +1 -1
  281. package/dist/core/storage/shares.d.ts +2 -2
  282. package/dist/core/storage/shares.js +1 -1
  283. package/dist/core/storage/tables.d.ts +21 -21
  284. package/dist/core/storage/tables.js +3 -3
  285. package/dist/core/substrate/delivery/corpus.d.ts +5 -8
  286. package/dist/core/substrate/delivery/corpus.js +3 -3
  287. package/dist/core/substrate/delivery/deliver.d.ts +10 -15
  288. package/dist/core/substrate/delivery/deliver.js +3 -3
  289. package/dist/core/substrate/delivery/plan.d.ts +2 -12
  290. package/dist/core/substrate/delivery/plan.js +3 -3
  291. package/dist/core/substrate/delivery/render-boot.d.ts +4 -4
  292. package/dist/core/substrate/delivery/render-boot.js +18 -18
  293. package/dist/core/substrate/delivery/render-event.d.ts +7 -14
  294. package/dist/core/substrate/delivery/render-event.js +4 -4
  295. package/dist/core/substrate/subject.d.ts +2 -2
  296. package/dist/core/substrate/subject.js +1 -1
  297. package/dist/core/usage/ledger.d.ts +6 -6
  298. package/dist/core/usage/ledger.js +4 -4
  299. package/dist/core/worktree-close.js +4 -4
  300. package/dist/core/worktree-mutation-async.js +7 -7
  301. package/dist/core/worktree-quarantine.js +1 -1
  302. package/dist/core/worktree-sweep.d.ts +1 -1
  303. package/dist/core/worktree-sweep.js +6 -6
  304. package/dist/core/worktree.d.ts +5 -5
  305. package/dist/core/worktree.js +13 -13
  306. package/dist/daemon/analytics/compute.d.ts +2 -2
  307. package/dist/daemon/analytics/compute.js +1 -1
  308. package/dist/daemon/api/app-listener.d.ts +4 -4
  309. package/dist/daemon/api/app-listener.js +13 -13
  310. package/dist/daemon/api/bridge.js +5 -5
  311. package/dist/daemon/api/document-listener.js +6 -6
  312. package/dist/daemon/api/handlers/analytics.js +1 -1
  313. package/dist/daemon/api/handlers/attach.js +1 -1
  314. package/dist/daemon/api/handlers/bash-jobs.js +1 -1
  315. package/dist/daemon/api/handlers/bash.js +1 -1
  316. package/dist/daemon/api/handlers/broker-ops.d.ts +1 -1
  317. package/dist/daemon/api/handlers/broker-ops.js +1 -1
  318. package/dist/daemon/api/handlers/broker-recovery.d.ts +1 -1
  319. package/dist/daemon/api/handlers/broker-recovery.js +1 -1
  320. package/dist/daemon/api/handlers/broker-signals.d.ts +2 -2
  321. package/dist/daemon/api/handlers/broker-signals.js +2 -2
  322. package/dist/daemon/api/handlers/canvas.d.ts +1 -1
  323. package/dist/daemon/api/handlers/canvas.js +4 -4
  324. package/dist/daemon/api/handlers/chat-inventory.js +1 -1
  325. package/dist/daemon/api/handlers/crons.js +1 -1
  326. package/dist/daemon/api/handlers/custom-objects.d.ts +4 -4
  327. package/dist/daemon/api/handlers/custom-objects.js +3 -3
  328. package/dist/daemon/api/handlers/delivery-retry.js +1 -1
  329. package/dist/daemon/api/handlers/delivery.js +1 -1
  330. package/dist/daemon/api/handlers/docs.d.ts +4 -4
  331. package/dist/daemon/api/handlers/docs.js +1 -1
  332. package/dist/daemon/api/handlers/feedback-comments.js +3 -3
  333. package/dist/daemon/api/handlers/files.js +1 -1
  334. package/dist/daemon/api/handlers/focus.js +1 -1
  335. package/dist/daemon/api/handlers/health.js +3 -3
  336. package/dist/daemon/api/handlers/hook-exec.js +1 -1
  337. package/dist/daemon/api/handlers/human-requests.js +1 -1
  338. package/dist/daemon/api/handlers/inbox-page.d.ts +1 -1
  339. package/dist/daemon/api/handlers/inbox-page.js +1 -1
  340. package/dist/daemon/api/handlers/inbox.d.ts +1 -1
  341. package/dist/daemon/api/handlers/inbox.js +1 -1
  342. package/dist/daemon/api/handlers/llm.d.ts +1 -1
  343. package/dist/daemon/api/handlers/llm.js +3 -3
  344. package/dist/daemon/api/handlers/memory-reads.js +1 -1
  345. package/dist/daemon/api/handlers/memory.d.ts +5 -5
  346. package/dist/daemon/api/handlers/memory.js +5 -5
  347. package/dist/daemon/api/handlers/messages.js +2 -2
  348. package/dist/daemon/api/handlers/node-events.d.ts +2 -2
  349. package/dist/daemon/api/handlers/node-events.js +3 -3
  350. package/dist/daemon/api/handlers/node-outcomes.js +1 -1
  351. package/dist/daemon/api/handlers/node-records.js +2 -2
  352. package/dist/daemon/api/handlers/nodes.d.ts +1 -1
  353. package/dist/daemon/api/handlers/nodes.js +1 -1
  354. package/dist/daemon/api/handlers/objects.js +3 -3
  355. package/dist/daemon/api/handlers/package-docs.js +1 -1
  356. package/dist/daemon/api/handlers/plugin-app-token.d.ts +1 -1
  357. package/dist/daemon/api/handlers/plugin-app-token.js +1 -1
  358. package/dist/daemon/api/handlers/profiles.d.ts +3 -3
  359. package/dist/daemon/api/handlers/profiles.js +1 -1
  360. package/dist/daemon/api/handlers/providers.d.ts +1 -1
  361. package/dist/daemon/api/handlers/providers.js +1 -1
  362. package/dist/daemon/api/handlers/questions.js +1 -1
  363. package/dist/daemon/api/handlers/reports.d.ts +1 -1
  364. package/dist/daemon/api/handlers/reports.js +5 -5
  365. package/dist/daemon/api/handlers/review-comments.js +1 -1
  366. package/dist/daemon/api/handlers/reviews.js +1 -1
  367. package/dist/daemon/api/handlers/runs.js +1 -1
  368. package/dist/daemon/api/handlers/structured-requests.js +1 -1
  369. package/dist/daemon/api/handlers/subscriptions.js +1 -1
  370. package/dist/daemon/api/handlers/transfer.js +1 -1
  371. package/dist/daemon/api/map.d.ts +3 -3
  372. package/dist/daemon/api/map.js +1 -1
  373. package/dist/daemon/api/principal.d.ts +1 -1
  374. package/dist/daemon/api/principal.js +1 -1
  375. package/dist/daemon/api/reader.d.ts +5 -5
  376. package/dist/daemon/api/reader.js +1 -1
  377. package/dist/daemon/api/router.d.ts +5 -5
  378. package/dist/daemon/api/router.js +1 -1
  379. package/dist/daemon/api/server.js +1 -1
  380. package/dist/daemon/broker-signals/bus.d.ts +1 -1
  381. package/dist/daemon/broker-signals/bus.js +1 -1
  382. package/dist/daemon/companion-retire.js +1 -1
  383. package/dist/daemon/cron/armed-context.d.ts +2 -2
  384. package/dist/daemon/cron/armed-context.js +1 -1
  385. package/dist/daemon/cron/authority.d.ts +2 -2
  386. package/dist/daemon/cron/authority.js +1 -1
  387. package/dist/daemon/cron/disposition.js +1 -1
  388. package/dist/daemon/cron/ended.d.ts +1 -1
  389. package/dist/daemon/cron/ended.js +2 -2
  390. package/dist/daemon/cron/escalation.js +3 -3
  391. package/dist/daemon/cron/folders.d.ts +1 -1
  392. package/dist/daemon/cron/folders.js +1 -1
  393. package/dist/daemon/cron/held.d.ts +1 -1
  394. package/dist/daemon/cron/held.js +1 -1
  395. package/dist/daemon/cron/lease-recovery.d.ts +1 -1
  396. package/dist/daemon/cron/lease-recovery.js +1 -1
  397. package/dist/daemon/cron/passes.d.ts +2 -2
  398. package/dist/daemon/cron/passes.js +1 -1
  399. package/dist/daemon/cron/run-socket.d.ts +1 -1
  400. package/dist/daemon/cron/run-socket.js +1 -1
  401. package/dist/daemon/cron/settle.js +1 -1
  402. package/dist/daemon/cron/sinks.d.ts +1 -1
  403. package/dist/daemon/cron/sinks.js +2 -2
  404. package/dist/daemon/cron-run.d.ts +12 -3
  405. package/dist/daemon/cron-run.js +2 -2
  406. package/dist/daemon/crtrd.js +6 -6
  407. package/dist/daemon/delivery/run-delivery.js +1 -1
  408. package/dist/daemon/due-sources.d.ts +3 -3
  409. package/dist/daemon/due-sources.js +1 -1
  410. package/dist/daemon/due.d.ts +3 -3
  411. package/dist/daemon/due.js +7 -7
  412. package/dist/daemon/fleet.d.ts +2 -2
  413. package/dist/daemon/fleet.js +11 -11
  414. package/dist/daemon/human/finish.js +3 -3
  415. package/dist/daemon/human/settle.d.ts +1 -1
  416. package/dist/daemon/human/settle.js +1 -1
  417. package/dist/daemon/human/sweep.js +1 -1
  418. package/dist/daemon/joined-owner.d.ts +2 -2
  419. package/dist/daemon/joined-owner.js +1 -1
  420. package/dist/daemon/messaging/node-message.js +1 -1
  421. package/dist/daemon/park-activity.d.ts +2 -2
  422. package/dist/daemon/park-activity.js +1 -1
  423. package/dist/daemon/peer/authority.js +1 -1
  424. package/dist/daemon/peer/forward.d.ts +13 -6
  425. package/dist/daemon/peer/forward.js +1 -1
  426. package/dist/daemon/peer/handlers.js +1 -1
  427. package/dist/daemon/peer/ingress.d.ts +4 -4
  428. package/dist/daemon/peer/ingress.js +1 -1
  429. package/dist/daemon/peer/outbox.d.ts +2 -2
  430. package/dist/daemon/peer/outbox.js +1 -1
  431. package/dist/daemon/peer/relay-service.js +1 -1
  432. package/dist/daemon/plugin-objects/read-leaf.d.ts +2 -2
  433. package/dist/daemon/plugin-objects/read-leaf.js +2 -2
  434. package/dist/daemon/profile-delete.js +1 -1
  435. package/dist/daemon/readiness.d.ts +2 -2
  436. package/dist/daemon/readiness.js +1 -1
  437. package/dist/daemon/reconcilers/action-lane.d.ts +1 -1
  438. package/dist/daemon/reconcilers/action-lane.js +1 -1
  439. package/dist/daemon/reconcilers/bash-deadline.js +2 -2
  440. package/dist/daemon/reconcilers/broker-supervision.d.ts +1 -1
  441. package/dist/daemon/reconcilers/broker-supervision.js +4 -4
  442. package/dist/daemon/reconcilers/controller-death.d.ts +1 -1
  443. package/dist/daemon/reconcilers/controller-death.js +1 -1
  444. package/dist/daemon/reconcilers/cron-lane.d.ts +1 -1
  445. package/dist/daemon/reconcilers/cron-lane.js +1 -1
  446. package/dist/daemon/reconcilers/delivery-lane.d.ts +1 -1
  447. package/dist/daemon/reconcilers/delivery-lane.js +2 -2
  448. package/dist/daemon/reconcilers/fault-retry-backstop.d.ts +3 -3
  449. package/dist/daemon/reconcilers/fault-retry-backstop.js +1 -1
  450. package/dist/daemon/reconcilers/grove-instance-sweep.d.ts +2 -2
  451. package/dist/daemon/reconcilers/grove-instance-sweep.js +1 -1
  452. package/dist/daemon/reconcilers/live-obligation.d.ts +6 -6
  453. package/dist/daemon/reconcilers/live-obligation.js +1 -1
  454. package/dist/daemon/reconcilers/managed-worktree-sweep.js +1 -1
  455. package/dist/daemon/reconcilers/node-deadline.d.ts +1 -1
  456. package/dist/daemon/reconcilers/node-deadline.js +1 -1
  457. package/dist/daemon/reconcilers/node-lifecycle/freeze-lane.js +1 -1
  458. package/dist/daemon/reconcilers/node-lifecycle/respawn-policy.d.ts +3 -3
  459. package/dist/daemon/reconcilers/node-lifecycle/respawn-policy.js +1 -1
  460. package/dist/daemon/reconcilers/node-lifecycle/terminating.js +1 -1
  461. package/dist/daemon/reconcilers/node-lifecycle/tick.js +1 -1
  462. package/dist/daemon/reconcilers/node-lifecycle/wants-execution.d.ts +1 -1
  463. package/dist/daemon/reconcilers/node-lifecycle/wants-execution.js +1 -1
  464. package/dist/daemon/reconcilers/pending-review-submit.d.ts +1 -1
  465. package/dist/daemon/reconcilers/pending-review-submit.js +1 -1
  466. package/dist/daemon/reconcilers/storage-due-work.js +1 -1
  467. package/dist/daemon/reconcilers/storage-maintenance.d.ts +1 -1
  468. package/dist/daemon/reconcilers/storage-maintenance.js +2 -2
  469. package/dist/daemon/reconcilers/structured-request-lane.d.ts +1 -1
  470. package/dist/daemon/reconcilers/structured-request-lane.js +1 -1
  471. package/dist/daemon/review/comment-notify.js +2 -2
  472. package/dist/daemon/review/companion.d.ts +3 -3
  473. package/dist/daemon/review/companion.js +1 -1
  474. package/dist/daemon/review/finish.js +1 -1
  475. package/dist/daemon/review/sweep.js +1 -1
  476. package/dist/daemon/run-notices.d.ts +4 -4
  477. package/dist/daemon/run-notices.js +1 -1
  478. package/dist/daemon/runs/append-section.d.ts +2 -2
  479. package/dist/daemon/runs/append-section.js +2 -2
  480. package/dist/daemon/runs/observer.d.ts +2 -2
  481. package/dist/daemon/runs/observer.js +2 -2
  482. package/dist/daemon/structured-requests/boot.d.ts +1 -1
  483. package/dist/daemon/structured-requests/boot.js +1 -1
  484. package/dist/daemon/structured-requests/effects.js +1 -1
  485. package/dist/daemon/structured-requests/sidecar.d.ts +1 -1
  486. package/dist/daemon/structured-requests/sidecar.js +1 -1
  487. package/dist/migrations/004-canvas-documents/apply.d.ts +3 -3
  488. package/dist/migrations/004-canvas-documents/apply.js +1 -1
  489. package/dist/migrations/004-canvas-documents/index.d.ts +2 -2
  490. package/dist/migrations/004-canvas-documents/index.js +2 -2
  491. package/dist/migrations/activation.js +2 -2
  492. package/docs/public-api.md +11 -0
  493. package/package.json +3 -2
  494. package/packages/crouter-identity/package.json +1 -1
  495. package/runtime.lock.json +12 -12
@@ -1 +1 @@
1
- var te=Object.defineProperty;var d=(e,t)=>te(e,"name",{value:t,configurable:!0});import{prepared as oe}from"../sqlite-statements.js";import{createHash as ne}from"node:crypto";import{closeSync as D,constants as re,createWriteStream as ie}from"node:fs";import{basename as ae,extname as se,isAbsolute as de,join as F}from"node:path";import{Transform as ue}from"node:stream";import{pipeline as le}from"node:stream/promises";import{appSpace as I}from"../layout.js";import{RunError as T}from"../runs/operations.js";import{createFileBeneath as ce,existsBeneath as M,openBeneath as fe,removeTreeBeneath as N,setModeBeneath as pe,unlinkBeneath as he,withDirBeneath as we}from"../spaces/open-beneath.js";import{ensureAppSpace as me}from"../spaces/space.js";import{invalidStorageName as H,storageClient as B,StorageRefused as U,UPLOAD_MAX_BYTES as C}from"../storage/client.js";import{contentTypeFor as _e,openCallerFile as ge}from"../storage/download.js";import{withCanvasWrite as ye}from"../canvas/db.js";import{deleteUploadUse as be,getUpload as $e,insertUpload as Se,insertUploadUses as ve,setUploadSize as Ue,uploadUseAt as ze}from"../storage/tables.js";import{ProviderError as l}from"./errors.js";const Ee=11e4,Ae="app:terminal";function P(e){if(e.class==="person")return e.grantee??Ae;if(!e.grantee)throw new l("server_error","provider caller has no grantee");return e.grantee}d(P,"grantee");function Fe(e){return e.class==="person"?null:{app:P(e),resolved:e.resolved??[],launched:e.class==="broker"?e.nodeScopes:null}}d(Fe,"fileCaller");function y(e){return e instanceof l?e:e instanceof U?new l("storage_unavailable",`storage refused: ${e.message}`):e instanceof T&&e.code==="storage_unavailable"?new l("storage_unavailable",e.message):e}d(y,"storageFailure");const b=d(e=>new l("provider_error",e,{origin:"provider"}),"providerError");function Te(e,t,n){if(typeof n!="string"||!n||!de(n)||n.includes("\0"))throw new l("invalid_request",`${t} must be an absolute runtime path`,{param:t});let i;try{i=ge(Fe(e),n)}catch(r){throw r instanceof T?r.code==="scope_missing"?new l("scope_missing",r.message,{param:t,...r.scope?{scope:r.scope}:{}}):r.code==="not_found"||r.code==="invalid_request"?new l("not_found",`no such file: ${n}`,{param:t}):r:r}try{if(i.size>C)throw new l("invalid_request",`${t} exceeds 100 MiB`,{param:t});const r=ae(i.path),o=H(r);if(o)throw new l("invalid_request",`${t}: file name cannot be sent: ${o}`,{param:t});return{param:t,file:i,name:r,mediaType:_e(i.path)}}catch(r){throw D(i.fd),r}}d(Te,"checkFileArgument");async function Be(e,t){try{const n=await e.createOutbound({name:t.name,size:t.file.size,media_type:t.mediaType});await e.putFileBytes(n.upload_link,t.file.fd,t.file.size,t.mediaType);const i=await e.signOutbound(n.object_id);return{param:t.param,path:t.file.path,name:t.name,object_id:n.object_id,url:i.url}}catch(n){throw y(n)}}d(Be,"copyOutbound");async function k(e,t,n,i){const r=[];try{for(const a of t)n[a]===void 0||n[a]===null||r.push(Te(e,a,n[a]));if(!r.length)return[];let o;try{o=i()}catch(a){throw y(a)}const c=[];for(const a of r)c.push(await Be(o,a));return c}finally{for(const o of r)D(o.file.fd)}}d(k,"copyArguments");function q(e){const t=H(e);if(t)throw new l("server_error",`file output ${e} cannot name an upload: ${t}`)}d(q,"checkOutputField");async function W(e,t,n){q(t);const i=P(e),r="application/octet-stream";let o;try{o=await n().createResultUpload({name:t,media_type:r,max_size:C})}catch(c){throw y(c)}return Se({upload_id:o.upload_id,grantee:i,name:t,media_type:r,size:C,created_at:new Date().toISOString()}),{field:t,upload_id:o.upload_id,upload_link:o.upload_link,grantee:i}}d(W,"createResultUpload");function X(e){return e?{"Crtr-Upload-Id":e.upload_id,"Crtr-Upload-Link":e.upload_link}:{}}d(X,"uploadHeaders");function Y(e,t){const n={...e};for(const i of t)n[i.param]=i.url;return n}d(Y,"withUrls");async function Je(e,t,n,i={}){const r=i.storage??B;t.output&&q(t.output);const o=await k(e,t.params,n,r),c=t.output?await W(e,t.output,r):null;return{arguments:Y(n,o),copies:o,upload:c,headers:X(c)}}d(Je,"prepareFileCall");async function Ke(e,t,n,i,r={}){const o=r.storage??B,c=[];for(const s of i.copies)try{const p=await o().signOutbound(s.object_id);c.push({...s,url:p.url})}catch(p){if(!(p instanceof U))throw y(p);c.push(...await k(e,[s.param],n,o))}let a=i.upload;if(a)try{const s=await o().signUploadLink(a.upload_id);a={...a,upload_link:s.upload_link}}catch(s){if(!(s instanceof U))throw y(s);s.status===404&&(a=await W(e,t.output??a.field,o))}return{arguments:Y(n,c),copies:c,upload:a,headers:X(a)}}d(Ke,"resignForRetry");const Ce=/^[0-9a-f]{64}$/i;function Oe(e,t){if(t===1)return e;const n=se(e);return n&&n!==e?`${e.slice(0,-n.length)}-${t}${n}`:`${e}-${t}`}d(Oe,"candidate");async function Qe(e,t,n,i={}){const r={result:n,file:null,cleanup:d(()=>{},"cleanup")},o=t.upload;if(!o||!n||typeof n!="object"||Array.isArray(n))return r;const c=n,a=c[o.field];if(a==null)return r;if(typeof a!="object"||Array.isArray(a))throw b(`${o.field} must be {upload_id, size, sha256}`);const s=a;if(typeof s.upload_id!="string"||typeof s.size!="number"||!Number.isSafeInteger(s.size)||s.size<0||typeof s.sha256!="string"||!Ce.test(s.sha256))throw b(`${o.field} must be {upload_id, size, sha256}`);if(s.upload_id!==o.upload_id)throw b(`${o.field} names an upload other than Crtr-Upload-Id`);const p=s.size,G=s.sha256.toLowerCase(),z=AbortSignal.timeout(i.budgetMs??Ee),O=i.signal?AbortSignal.any([z,i.signal]):z;let h;try{h=await(i.storage??B)().fetchUpload(o.upload_id,O)}catch(m){throw m instanceof U?b(`${o.field} names an upload with nothing stored`):y(m)}if(h.size===null)throw h.body.destroy(),new l("storage_unavailable",`storage did not say how many bytes ${o.field} holds`);if(h.size!==p)throw h.body.destroy(),b(`${o.field} claims ${p} bytes; storage holds ${h.size}`);const E=o.grantee,$=e.node_id!==null,J=await me(E),f=$?I(E).nodes:I(E).files,A=$?F(f,e.node_id):f,S=$?F(A,"attachments"):f,K={uid:process.getuid?.()??0,gid:J.gid},R=$&&!M(f,A),Q=$&&!R&&!M(f,S);let w=null,v=null,x=!1;const L=d(()=>{if(!x){if(x=!0,v)try{be(v)}catch{}if(w)try{he(f,w)}catch{}try{R?N(f,A):Q&&N(f,S)}catch{}}},"cleanup");try{we(f,S,()=>{},!0);for(let u=1;;u++){const _=F(S,Oe(o.field,u));if(!ze(_))try{ce(f,_,Buffer.alloc(0),432),w=_;break}catch(g){if(g.code!=="EEXIST")throw g}}let m=0;const j=ne("sha256"),V=new ue({transform(u,_,g){m+=u.length,j.update(u),g(null,u)}}),Z=fe(f,w,re.O_WRONLY);try{await le(h.body,V,ie("",{fd:Z,autoClose:!0}),{signal:O})}catch(u){throw z.aborted?new l("storage_unavailable","the file result could not be fetched within 110 s"):u instanceof T?y(u):new l("storage_unavailable",`storage stopped sending ${o.field}: ${u instanceof Error?u.message:String(u)}`)}if(m!==p)throw new l("storage_unavailable",`storage sent ${m} of ${p} bytes of ${o.field}`);if(j.digest("hex")!==G)throw b(`${o.field}: the stored bytes do not match sha256`);pe(f,w,432,K);const ee=w;ye(u=>{const _=$e(o.upload_id,u);if(!_||_.delete_pending_since)throw new l("not_found",`${o.field}: the upload was deleted while it was fetched`);if(Ue(o.upload_id,p,u),!e.run_id)return;const g=oe(u,"SELECT deleting_at FROM nodes WHERE node_id = ?").get(e.run_id);if(!g||g.deleting_at)throw new l("not_found",`run ${e.run_id} was deleted while its file result was fetched`);v={upload_id:o.upload_id,run_id:e.run_id,path:ee},ve([v],u)})}catch(m){throw h.body.destroy(),L(),m}return{result:{...c,[o.field]:w},file:{path:w,upload_id:o.upload_id},cleanup:L}}d(Qe,"resolveFileResult");export{Ee as FILE_RESULT_FETCH_BUDGET_MS,Je as prepareFileCall,Ke as resignForRetry,Qe as resolveFileResult};
1
+ var te=Object.defineProperty;var d=(e,t)=>te(e,"name",{value:t,configurable:!0});import{createHash as oe}from"node:crypto";import{closeSync as D,constants as ne,createWriteStream as ie}from"node:fs";import{basename as re,extname as ae,isAbsolute as se,join as F}from"node:path";import{Transform as de}from"node:stream";import{pipeline as ue}from"node:stream/promises";import{appSpace as I}from"../layout.js";import{RunError as T}from"../runs/operations.js";import{createFileBeneath as ce,existsBeneath as M,openBeneath as le,removeTreeBeneath as N,setModeBeneath as fe,unlinkBeneath as pe,withDirBeneath as he}from"../spaces/open-beneath.js";import{ensureAppSpace as we}from"../spaces/space.js";import{invalidStorageName as H,storageClient as B,StorageRefused as U,UPLOAD_MAX_BYTES as C}from"../storage/client.js";import{contentTypeFor as _e,openCallerFile as me}from"../storage/download.js";import{withCanvasWrite as ge}from"../canvas/db.js";import{deleteUploadUse as ye,getUpload as be,insertUpload as $e,insertUploadUses as Se,setUploadSize as ve,uploadUseAt as Ue}from"../storage/tables.js";import{ProviderError as c}from"./errors.js";const ze=11e4,Ee="app:terminal";function P(e){if(e.class==="person")return e.grantee??Ee;if(!e.grantee)throw new c("server_error","provider caller has no grantee");return e.grantee}d(P,"grantee");function Ae(e){return e.class==="person"?null:{app:P(e),resolved:e.resolved??[],launched:e.class==="broker"?e.nodeScopes:null}}d(Ae,"fileCaller");function y(e){return e instanceof c?e:e instanceof U?new c("storage_unavailable",`storage refused: ${e.message}`):e instanceof T&&e.code==="storage_unavailable"?new c("storage_unavailable",e.message):e}d(y,"storageFailure");const b=d(e=>new c("provider_error",e,{origin:"provider"}),"providerError");function Fe(e,t,n){if(typeof n!="string"||!n||!se(n)||n.includes("\0"))throw new c("invalid_request",`${t} must be an absolute runtime path`,{param:t});let r;try{r=me(Ae(e),n)}catch(i){throw i instanceof T?i.code==="scope_missing"?new c("scope_missing",i.message,{param:t,...i.scope?{scope:i.scope}:{}}):i.code==="not_found"||i.code==="invalid_request"?new c("not_found",`no such file: ${n}`,{param:t}):i:i}try{if(r.size>C)throw new c("invalid_request",`${t} exceeds 100 MiB`,{param:t});const i=re(r.path),o=H(i);if(o)throw new c("invalid_request",`${t}: file name cannot be sent: ${o}`,{param:t});return{param:t,file:r,name:i,mediaType:_e(r.path)}}catch(i){throw D(r.fd),i}}d(Fe,"checkFileArgument");async function Te(e,t){try{const n=await e.createOutbound({name:t.name,size:t.file.size,media_type:t.mediaType});await e.putFileBytes(n.upload_link,t.file.fd,t.file.size,t.mediaType);const r=await e.signOutbound(n.object_id);return{param:t.param,path:t.file.path,name:t.name,object_id:n.object_id,url:r.url}}catch(n){throw y(n)}}d(Te,"copyOutbound");async function k(e,t,n,r){const i=[];try{for(const a of t)n[a]===void 0||n[a]===null||i.push(Fe(e,a,n[a]));if(!i.length)return[];let o;try{o=r()}catch(a){throw y(a)}const l=[];for(const a of i)l.push(await Te(o,a));return l}finally{for(const o of i)D(o.file.fd)}}d(k,"copyArguments");function q(e){const t=H(e);if(t)throw new c("server_error",`file output ${e} cannot name an upload: ${t}`)}d(q,"checkOutputField");async function W(e,t,n){q(t);const r=P(e),i="application/octet-stream";let o;try{o=await n().createResultUpload({name:t,media_type:i,max_size:C})}catch(l){throw y(l)}return await $e({upload_id:o.upload_id,grantee:r,name:t,media_type:i,size:C,created_at:new Date().toISOString()}),{field:t,upload_id:o.upload_id,upload_link:o.upload_link,grantee:r}}d(W,"createResultUpload");function X(e){return e?{"Crtr-Upload-Id":e.upload_id,"Crtr-Upload-Link":e.upload_link}:{}}d(X,"uploadHeaders");function Y(e,t){const n={...e};for(const r of t)n[r.param]=r.url;return n}d(Y,"withUrls");async function Ye(e,t,n,r={}){const i=r.storage??B;t.output&&q(t.output);const o=await k(e,t.params,n,i),l=t.output?await W(e,t.output,i):null;return{arguments:Y(n,o),copies:o,upload:l,headers:X(l)}}d(Ye,"prepareFileCall");async function Ge(e,t,n,r,i={}){const o=i.storage??B,l=[];for(const s of r.copies)try{const p=await o().signOutbound(s.object_id);l.push({...s,url:p.url})}catch(p){if(!(p instanceof U))throw y(p);l.push(...await k(e,[s.param],n,o))}let a=r.upload;if(a)try{const s=await o().signUploadLink(a.upload_id);a={...a,upload_link:s.upload_link}}catch(s){if(!(s instanceof U))throw y(s);s.status===404&&(a=await W(e,t.output??a.field,o))}return{arguments:Y(n,l),copies:l,upload:a,headers:X(a)}}d(Ge,"resignForRetry");const Be=/^[0-9a-f]{64}$/i;function Ce(e,t){if(t===1)return e;const n=ae(e);return n&&n!==e?`${e.slice(0,-n.length)}-${t}${n}`:`${e}-${t}`}d(Ce,"candidate");async function Je(e,t,n,r={}){const i={result:n,file:null,cleanup:d(async()=>{},"cleanup")},o=t.upload;if(!o||!n||typeof n!="object"||Array.isArray(n))return i;const l=n,a=l[o.field];if(a==null)return i;if(typeof a!="object"||Array.isArray(a))throw b(`${o.field} must be {upload_id, size, sha256}`);const s=a;if(typeof s.upload_id!="string"||typeof s.size!="number"||!Number.isSafeInteger(s.size)||s.size<0||typeof s.sha256!="string"||!Be.test(s.sha256))throw b(`${o.field} must be {upload_id, size, sha256}`);if(s.upload_id!==o.upload_id)throw b(`${o.field} names an upload other than Crtr-Upload-Id`);const p=s.size,G=s.sha256.toLowerCase(),z=AbortSignal.timeout(r.budgetMs??ze),O=r.signal?AbortSignal.any([z,r.signal]):z;let h;try{h=await(r.storage??B)().fetchUpload(o.upload_id,O)}catch(_){throw _ instanceof U?b(`${o.field} names an upload with nothing stored`):y(_)}if(h.size===null)throw h.body.destroy(),new c("storage_unavailable",`storage did not say how many bytes ${o.field} holds`);if(h.size!==p)throw h.body.destroy(),b(`${o.field} claims ${p} bytes; storage holds ${h.size}`);const E=o.grantee,$=e.node_id!==null,J=await we(E),f=$?I(E).nodes:I(E).files,A=$?F(f,e.node_id):f,S=$?F(A,"attachments"):f,K={uid:process.getuid?.()??0,gid:J.gid},R=$&&!M(f,A),Q=$&&!R&&!M(f,S);let w=null,v=null,x=!1;const L=d(async()=>{if(!x){if(x=!0,v)try{await ye(v)}catch{}if(w)try{pe(f,w)}catch{}try{R?N(f,A):Q&&N(f,S)}catch{}}},"cleanup");try{he(f,S,()=>{},!0);for(let u=1;;u++){const m=F(S,Ce(o.field,u));if(!await Ue(m))try{ce(f,m,Buffer.alloc(0),432),w=m;break}catch(g){if(g.code!=="EEXIST")throw g}}let _=0;const j=oe("sha256"),V=new de({transform(u,m,g){_+=u.length,j.update(u),g(null,u)}}),Z=le(f,w,ne.O_WRONLY);try{await ue(h.body,V,ie("",{fd:Z,autoClose:!0}),{signal:O})}catch(u){throw z.aborted?new c("storage_unavailable","the file result could not be fetched within 110 s"):u instanceof T?y(u):new c("storage_unavailable",`storage stopped sending ${o.field}: ${u instanceof Error?u.message:String(u)}`)}if(_!==p)throw new c("storage_unavailable",`storage sent ${_} of ${p} bytes of ${o.field}`);if(j.digest("hex")!==G)throw b(`${o.field}: the stored bytes do not match sha256`);fe(f,w,432,K);const ee=w;await ge(async u=>{const m=await be(o.upload_id,u);if(!m||m.delete_pending_since)throw new c("not_found",`${o.field}: the upload was deleted while it was fetched`);if(await ve(o.upload_id,p,u),!e.run_id)return;const g=await u.prepare("SELECT deleting_at FROM nodes WHERE node_id = ?").get(e.run_id);if(!g||g.deleting_at)throw new c("not_found",`run ${e.run_id} was deleted while its file result was fetched`);v={upload_id:o.upload_id,run_id:e.run_id,path:ee},await Se([v],u)})}catch(_){throw h.body.destroy(),await L(),_}return{result:{...l,[o.field]:w},file:{path:w,upload_id:o.upload_id},cleanup:L}}d(Je,"resolveFileResult");export{ze as FILE_RESULT_FETCH_BUDGET_MS,Ye as prepareFileCall,Ge as resignForRetry,Je as resolveFileResult};
@@ -1 +1 @@
1
- var T=Object.defineProperty;var a=(r,e)=>T(r,"name",{value:e,configurable:!0});import{createHash as M}from"node:crypto";import{readConfig as E}from"../config.js";import{emitEvent as $}from"../events/emit.js";import{grantSyncStateFor as A}from"../grants/mirror.js";import{assertion as N,machineRevokedMessage as O,requestGrantSync as P,runtimeClient as I}from"../grants/sync.js";import{isUnsandboxedMachine as F}from"../runtime/unsandboxed.js";import{ProviderError as h}from"./errors.js";import{cacheKey as G,cachedToken as L,discardEpoch as U,storeToken as C}from"./token-cache.js";import{discardFile as ce}from"./token-cache.js";const D=1e4;function J(r){const e=r.issuer??E("user").runtime?.issuer;if(!e)throw new h("not_found","provider calls need a directory-connected runtime");return e.replace(/\/$/,"")}a(J,"issuerOf");function f(r,e,t){return new h(r,e,{origin:"directory",details:t})}a(f,"directoryError");function B(r,e,t,i){const n=typeof e.error=="string"?e.error:null,o=typeof e.error_description=="string"?e.error_description:void 0,c={directory_status:r,...n?{directory_error:n}:{},...o?{directory_description:o}:{}},u=o?`: ${o}`:"";switch(n){case"invalid_client":return F()?{error:f("machine_revoked",O(i),c),grantRefusal:!1}:{error:f("server_error",`the directory refused the outbound token request (${n})${u}`,c),grantRefusal:!1};case"invalid_request":return{error:f("server_error",`the directory refused the outbound token request (${n})${u}`,c),grantRefusal:!1};case"invalid_target":return{error:f("not_found",`the directory knows no provider at ${t.audience}${u}`,c),grantRefusal:!1};case"invalid_grant":return{error:f("grant_revoked",`the directory has no active grant for ${t.grantee}${u}`,c),grantRefusal:!0};case"provider_not_connected":return{error:f("provider_not_connected",o??"The user has not connected this provider.",c),grantRefusal:!1};case"invalid_scope":{const s=typeof e.scope=="string"&&e.scope?e.scope:t.scope.length===1?t.scope[0]:void 0,m=s?`missing scope ${s}`:`the grant does not cover ${t.scope.join(" ")}`;return{error:new h("scope_missing",m,{origin:"directory",details:c,...s?{scope:s}:{}}),grantRefusal:!0}}default:return{error:f("server_error",`the directory token endpoint answered ${r}${n?` ${n}`:""}${u}`,c),grantRefusal:!1}}}a(B,"refusal");function H(r){try{return JSON.parse(Buffer.from(r.split(".")[1]??"","base64url").toString("utf8"))}catch{return{}}}a(H,"claims");function K(r){const e=r.grant_rev,t=r.grant_status;return typeof e!="number"||!Number.isInteger(e)||e<0||typeof t!="string"?null:{rev:e,status:t}}a(K,"refusedGrantState");function z(r,e){const t=a(i=>i.status==="active"?0:1,"phase");return r.rev>e.rev||r.rev===e.rev&&t(r)>t(e)}a(z,"newer");function Q(r,e,t){if(!e)return;const i=A(r.grantee,r.sub)??{rev:0,status:"removed"};if(!z(e,i))return;const n=t.syncGrants??P;Promise.resolve().then(()=>n({fresh:!0})).catch(()=>{})}a(Q,"syncIfNewer");async function V(r,e={}){const t=J(e),i=`${t}/token`,n=I(),o=new URLSearchParams({grant_type:"client_credentials",client_id:n.client_id,client_assertion_type:"urn:ietf:params:oauth:client-assertion-type:jwt-bearer",client_assertion:N(n,i),audience:r.audience,sub:r.sub,grantee:r.grantee,scope:[...new Set(r.scope)].sort().join(" "),initiating_app:r.initiating_app}),c=AbortSignal.timeout(D),u=e.signal?AbortSignal.any([e.signal,c]):c;let s,m;try{s=await(e.fetch??fetch)(i,{method:"POST",body:o,signal:u,headers:{Accept:"application/json"}}),m=await s.text()}catch(l){throw e.signal?.aborted?e.signal.reason:new h("server_error",`the directory token endpoint could not be reached: ${l instanceof Error?l.message:String(l)}`,{origin:"directory"})}let p=null;try{p=m?JSON.parse(m):null}catch{p=null}const g=p&&typeof p=="object"&&!Array.isArray(p)?p:{};if(!s.ok){const{error:l,grantRefusal:j}=B(s.status,g,r,t);throw l.code==="machine_revoked"&&$({level:"error",event:"daemon.grants.machine_revoked",fields:{audience:r.audience}}),$({level:"info",event:"daemon.providers.mint_refused",fields:{audience:r.audience,grantee:r.grantee,code:l.code,directory_error:typeof g.error=="string"?g.error:null,status:s.status}}),j&&Q(r,K(g),e),l}const y=g.access_token;if(typeof y!="string"||!y)throw new h("server_error","the directory token response has no access_token",{origin:"directory"});const d=H(y),S=Math.floor((e.now?.()??Date.now())/1e3),_=g.expires_in,v=typeof _=="number"&&Number.isFinite(_)&&_>0?S+Math.floor(_):null,w=typeof d.exp=="number"?d.exp:null,b=v!==null&&w!==null?Math.min(v,w):v??w;if(b===null)throw new h("server_error","the directory token response names no expiry",{origin:"directory"});const x=typeof d.jti=="string"&&d.jti?d.jti:M("sha256").update(y).digest("hex"),R=typeof d.payer=="string"&&d.payer?d.payer:r.sub;return{access_token:y,jti:x,exp:b,payer:R}}a(V,"mintOutboundToken");const k=new Map;async function ie(r,e={}){const t=G(r),i=e.now??Date.now,n=L(t,i());if(n)return{...n,key:t};let o=k.get(t);if(!o){const u=U(t);o=V(r,{...e,signal:void 0}).then(s=>(C(t,s,u),s)).finally(()=>{k.delete(t)}),o.catch(()=>{}),k.set(t,o)}return{...e.signal?await W(o,e.signal):await o,key:t}}a(ie,"outboundToken");function W(r,e){return e.aborted?Promise.reject(e.reason):new Promise((t,i)=>{const n=a(()=>i(e.reason),"onAbort");e.addEventListener("abort",n,{once:!0}),r.then(t,i).finally(()=>e.removeEventListener("abort",n))})}a(W,"abortable");export{D as MINT_TIMEOUT_MS,ce as discardFile,V as mintOutboundToken,ie as outboundToken};
1
+ var T=Object.defineProperty;var a=(r,e)=>T(r,"name",{value:e,configurable:!0});import{createHash as M}from"node:crypto";import{readConfig as E}from"../config.js";import{emitEvent as $}from"../events/emit.js";import{grantSyncStateFor as A}from"../grants/mirror.js";import{assertion as N,machineRevokedMessage as O,requestGrantSync as P,runtimeClient as I}from"../grants/sync.js";import{isUnsandboxedMachine as F}from"../runtime/unsandboxed.js";import{ProviderError as h}from"./errors.js";import{cacheKey as G,cachedToken as L,discardEpoch as U,storeToken as C}from"./token-cache.js";import{discardFile as ce}from"./token-cache.js";const D=1e4;function J(r){const e=r.issuer??E("user").runtime?.issuer;if(!e)throw new h("not_found","provider calls need a directory-connected runtime");return e.replace(/\/$/,"")}a(J,"issuerOf");function f(r,e,t){return new h(r,e,{origin:"directory",details:t})}a(f,"directoryError");function B(r,e,t,i){const n=typeof e.error=="string"?e.error:null,o=typeof e.error_description=="string"?e.error_description:void 0,c={directory_status:r,...n?{directory_error:n}:{},...o?{directory_description:o}:{}},u=o?`: ${o}`:"";switch(n){case"invalid_client":return F()?{error:f("machine_revoked",O(i),c),grantRefusal:!1}:{error:f("server_error",`the directory refused the outbound token request (${n})${u}`,c),grantRefusal:!1};case"invalid_request":return{error:f("server_error",`the directory refused the outbound token request (${n})${u}`,c),grantRefusal:!1};case"invalid_target":return{error:f("not_found",`the directory knows no provider at ${t.audience}${u}`,c),grantRefusal:!1};case"invalid_grant":return{error:f("grant_revoked",`the directory has no active grant for ${t.grantee}${u}`,c),grantRefusal:!0};case"provider_not_connected":return{error:f("provider_not_connected",o??"The user has not connected this provider.",c),grantRefusal:!1};case"invalid_scope":{const s=typeof e.scope=="string"&&e.scope?e.scope:t.scope.length===1?t.scope[0]:void 0,m=s?`missing scope ${s}`:`the grant does not cover ${t.scope.join(" ")}`;return{error:new h("scope_missing",m,{origin:"directory",details:c,...s?{scope:s}:{}}),grantRefusal:!0}}default:return{error:f("server_error",`the directory token endpoint answered ${r}${n?` ${n}`:""}${u}`,c),grantRefusal:!1}}}a(B,"refusal");function H(r){try{return JSON.parse(Buffer.from(r.split(".")[1]??"","base64url").toString("utf8"))}catch{return{}}}a(H,"claims");function K(r){const e=r.grant_rev,t=r.grant_status;return typeof e!="number"||!Number.isInteger(e)||e<0||typeof t!="string"?null:{rev:e,status:t}}a(K,"refusedGrantState");function z(r,e){const t=a(i=>i.status==="active"?0:1,"phase");return r.rev>e.rev||r.rev===e.rev&&t(r)>t(e)}a(z,"newer");async function Q(r,e,t){if(!e)return;const i=await A(r.grantee,r.sub)??{rev:0,status:"removed"};if(!z(e,i))return;const n=t.syncGrants??P;Promise.resolve().then(()=>n({fresh:!0})).catch(()=>{})}a(Q,"syncIfNewer");async function V(r,e={}){const t=J(e),i=`${t}/token`,n=I(),o=new URLSearchParams({grant_type:"client_credentials",client_id:n.client_id,client_assertion_type:"urn:ietf:params:oauth:client-assertion-type:jwt-bearer",client_assertion:N(n,i),audience:r.audience,sub:r.sub,grantee:r.grantee,scope:[...new Set(r.scope)].sort().join(" "),initiating_app:r.initiating_app}),c=AbortSignal.timeout(D),u=e.signal?AbortSignal.any([e.signal,c]):c;let s,m;try{s=await(e.fetch??fetch)(i,{method:"POST",body:o,signal:u,headers:{Accept:"application/json"}}),m=await s.text()}catch(l){throw e.signal?.aborted?e.signal.reason:new h("server_error",`the directory token endpoint could not be reached: ${l instanceof Error?l.message:String(l)}`,{origin:"directory"})}let p=null;try{p=m?JSON.parse(m):null}catch{p=null}const g=p&&typeof p=="object"&&!Array.isArray(p)?p:{};if(!s.ok){const{error:l,grantRefusal:j}=B(s.status,g,r,t);throw l.code==="machine_revoked"&&$({level:"error",event:"daemon.grants.machine_revoked",fields:{audience:r.audience}}),$({level:"info",event:"daemon.providers.mint_refused",fields:{audience:r.audience,grantee:r.grantee,code:l.code,directory_error:typeof g.error=="string"?g.error:null,status:s.status}}),j&&await Q(r,K(g),e),l}const y=g.access_token;if(typeof y!="string"||!y)throw new h("server_error","the directory token response has no access_token",{origin:"directory"});const d=H(y),S=Math.floor((e.now?.()??Date.now())/1e3),_=g.expires_in,v=typeof _=="number"&&Number.isFinite(_)&&_>0?S+Math.floor(_):null,w=typeof d.exp=="number"?d.exp:null,b=v!==null&&w!==null?Math.min(v,w):v??w;if(b===null)throw new h("server_error","the directory token response names no expiry",{origin:"directory"});const x=typeof d.jti=="string"&&d.jti?d.jti:M("sha256").update(y).digest("hex"),R=typeof d.payer=="string"&&d.payer?d.payer:r.sub;return{access_token:y,jti:x,exp:b,payer:R}}a(V,"mintOutboundToken");const k=new Map;async function ie(r,e={}){const t=G(r),i=e.now??Date.now,n=L(t,i());if(n)return{...n,key:t};let o=k.get(t);if(!o){const u=U(t);o=V(r,{...e,signal:void 0}).then(s=>(C(t,s,u),s)).finally(()=>{k.delete(t)}),o.catch(()=>{}),k.set(t,o)}return{...e.signal?await W(o,e.signal):await o,key:t}}a(ie,"outboundToken");function W(r,e){return e.aborted?Promise.reject(e.reason):new Promise((t,i)=>{const n=a(()=>i(e.reason),"onAbort");e.addEventListener("abort",n,{once:!0}),r.then(t,i).finally(()=>e.removeEventListener("abort",n))})}a(W,"abortable");export{D as MINT_TIMEOUT_MS,ce as discardFile,V as mintOutboundToken,ie as outboundToken};
@@ -16,5 +16,5 @@ type ReceiptCall = {
16
16
  * own, and one that fails the check is dropped without dropping the others. Returns the first
17
17
  * accepted receipt id.
18
18
  */
19
- export declare function acceptProviderReceipt(value: string | string[] | undefined, call: ReceiptCall): string | undefined;
19
+ export declare function acceptProviderReceipt(value: string | string[] | undefined, call: ReceiptCall): Promise<string | undefined>;
20
20
  export {};
@@ -1,2 +1,2 @@
1
- var a=Object.defineProperty;var _=(t,r)=>a(t,"name",{value:r,configurable:!0});import{prepared as p}from"../sqlite-statements.js";import{withCanvasWrite as f}from"../canvas/db.js";import{addUsage as g}from"../usage/ledger.js";const y=8,c=65536;function v(t,r){if(!t||typeof t!="object"||Array.isArray(t))return!1;const e=t;return typeof e.receipt_id=="string"&&!!e.receipt_id&&e.receipt_id.length<=256&&e.provider===`app:${r.provider}`&&e.tool===r.tool&&e.request_id===r.request_id&&e.sub===r.sub&&e.grantee===r.grantee&&e.payer===r.payer&&(e.run_id??null)===r.run_id&&typeof e.unit=="string"&&!!e.unit&&typeof e.units=="number"&&Number.isFinite(e.units)&&e.units>=0&&typeof e.time=="string"&&Number.isFinite(Date.parse(e.time))&&typeof e.usd_equivalent=="number"&&Number.isFinite(e.usd_equivalent)&&e.usd_equivalent>=0}_(v,"belongsToCall");function q(t,r){const e=Array.isArray(t)?t[0]:t;if(!e||e.length>c)return;let n;try{n=JSON.parse(e)}catch{return}if(Array.isArray(n)&&n.length>y)return;const o=(Array.isArray(n)?n:[n]).filter(i=>v(i,r));if(o.length)return f(i=>{for(const s of o){if(!p(i,`INSERT OR IGNORE INTO provider_receipts
2
- (provider, receipt_id, grantee, run_id, usd_equivalent, received_at) VALUES (?, ?, ?, ?, ?, ?)`).run(r.provider,s.receipt_id,r.grantee,r.run_id,s.usd_equivalent,new Date().toISOString()).changes||(g(i,{grantee:r.ledger_grantee??r.grantee,payer:r.payer.startsWith("app:")?"app":"user",source:`provider:${r.provider}`,served_model:"",input_tokens:0,output_tokens:0,cached_tokens:0,usd_equivalent:s.usd_equivalent}),!r.run_id))continue;const d=p(i,"SELECT usage_json FROM nodes WHERE node_id = ? AND run_id = ?").get(r.run_id,r.run_id);if(!d)continue;const u=d.usage_json?JSON.parse(d.usage_json):{};u.cost_usd=(typeof u.cost_usd=="number"?u.cost_usd:0)+s.usd_equivalent,p(i,"UPDATE nodes SET usage_json = ? WHERE node_id = ?").run(JSON.stringify(u),r.run_id)}}),o[0].receipt_id}_(q,"acceptProviderReceipt");export{q as acceptProviderReceipt};
1
+ var p=Object.defineProperty;var a=(t,r)=>p(t,"name",{value:r,configurable:!0});import{withCanvasWrite as _}from"../canvas/db.js";import{addUsage as f}from"../usage/ledger.js";const g=8,y=65536;function c(t,r){if(!t||typeof t!="object"||Array.isArray(t))return!1;const e=t;return typeof e.receipt_id=="string"&&!!e.receipt_id&&e.receipt_id.length<=256&&e.provider===`app:${r.provider}`&&e.tool===r.tool&&e.request_id===r.request_id&&e.sub===r.sub&&e.grantee===r.grantee&&e.payer===r.payer&&(e.run_id??null)===r.run_id&&typeof e.unit=="string"&&!!e.unit&&typeof e.units=="number"&&Number.isFinite(e.units)&&e.units>=0&&typeof e.time=="string"&&Number.isFinite(Date.parse(e.time))&&typeof e.usd_equivalent=="number"&&Number.isFinite(e.usd_equivalent)&&e.usd_equivalent>=0}a(c,"belongsToCall");async function S(t,r){const e=Array.isArray(t)?t[0]:t;if(!e||e.length>y)return;let n;try{n=JSON.parse(e)}catch{return}if(Array.isArray(n)&&n.length>g)return;const o=(Array.isArray(n)?n:[n]).filter(i=>c(i,r));if(o.length)return await _(async i=>{for(const s of o){if(!(await i.prepare(`INSERT OR IGNORE INTO provider_receipts
2
+ (provider, receipt_id, grantee, run_id, usd_equivalent, received_at) VALUES (?, ?, ?, ?, ?, ?)`).run(r.provider,s.receipt_id,r.grantee,r.run_id,s.usd_equivalent,new Date().toISOString())).changes||(await f(i,{grantee:r.ledger_grantee??r.grantee,payer:r.payer.startsWith("app:")?"app":"user",source:`provider:${r.provider}`,served_model:"",input_tokens:0,output_tokens:0,cached_tokens:0,usd_equivalent:s.usd_equivalent}),!r.run_id))continue;const d=await i.prepare("SELECT usage_json FROM nodes WHERE node_id = ? AND run_id = ?").get(r.run_id,r.run_id);if(!d)continue;const u=d.usage_json?JSON.parse(d.usage_json):{};u.cost_usd=(typeof u.cost_usd=="number"?u.cost_usd:0)+s.usd_equivalent,await i.prepare("UPDATE nodes SET usage_json = ? WHERE node_id = ?").run(JSON.stringify(u),r.run_id)}}),o[0].receipt_id}a(S,"acceptProviderReceipt");export{S as acceptProviderReceipt};
@@ -1 +1 @@
1
- var s=Object.defineProperty;var n=(o,e)=>s(o,"name",{value:e,configurable:!0});import{commitBindingRequest as w}from"../human/requests.js";import{getReview as _}from"./store.js";import{discardStaging as a,stageReview as c}from"./stage.js";import{realizeReview as d}from"./realize.js";async function f(o){const e=await c(o);if(e.existing!==void 0){await d(e.existing.request_id);const r=_(e.existing.request_id);if(r===null)throw new Error(`realized review disappeared: ${e.existing.request_id}`);return r}let i;try{i=w({request_id:e.row.review_id,idempotency_key:e.row.idempotency_key,requester_node_id:e.row.origin_node_id,companion_node_id:e.row.companion_node_id,request_dir:e.row.review_dir,file:e.row.file,specification:{origin_kind:e.row.origin_kind,origin_session_file:e.row.origin_session_file,origin_session_id:e.row.origin_session_id,origin_leaf_id:e.row.origin_leaf_id,model_spec:e.row.model_spec,branch_file:e.row.branch_file,baseline_sha256:e.row.baseline_sha256,baseline_bytes:e.row.baseline_bytes,captured_at:e.row.captured_at,output_path:e.row.output_path,document_id:e.row.document_id,document_name:e.row.document_name,document_base:e.row.document_base},anchor_base_sha256:e.row.anchor_base_sha256,anchor_base_bytes:e.row.anchor_base_bytes,created_at:e.row.created,subtitle:e.row.subtitle,...e.row.document_name===null?{}:{title:e.row.document_name},inbox_listed:e.row.origin_kind==="ticket"})}catch(r){throw a(e.row.review_id,e.row.branch_file),r}i.won||a(e.row.review_id,e.row.branch_file),await d(i.request_id);const t=_(i.request_id);if(t===null)throw new Error(`realized review disappeared: ${i.request_id}`);return t}n(f,"createReview");export{f as createReview};
1
+ var s=Object.defineProperty;var n=(o,e)=>s(o,"name",{value:e,configurable:!0});import{commitBindingRequest as w}from"../human/requests.js";import{getReview as a}from"./store.js";import{discardStaging as _,stageReview as c}from"./stage.js";import{realizeReview as d}from"./realize.js";async function f(o){const e=await c(o);if(e.existing!==void 0){await d(e.existing.request_id);const r=await a(e.existing.request_id);if(r===null)throw new Error(`realized review disappeared: ${e.existing.request_id}`);return r}let i;try{i=await w({request_id:e.row.review_id,idempotency_key:e.row.idempotency_key,requester_node_id:e.row.origin_node_id,companion_node_id:e.row.companion_node_id,request_dir:e.row.review_dir,file:e.row.file,specification:{origin_kind:e.row.origin_kind,origin_session_file:e.row.origin_session_file,origin_session_id:e.row.origin_session_id,origin_leaf_id:e.row.origin_leaf_id,model_spec:e.row.model_spec,branch_file:e.row.branch_file,baseline_sha256:e.row.baseline_sha256,baseline_bytes:e.row.baseline_bytes,captured_at:e.row.captured_at,output_path:e.row.output_path,document_id:e.row.document_id,document_name:e.row.document_name,document_base:e.row.document_base},anchor_base_sha256:e.row.anchor_base_sha256,anchor_base_bytes:e.row.anchor_base_bytes,created_at:e.row.created,subtitle:e.row.subtitle,...e.row.document_name===null?{}:{title:e.row.document_name},inbox_listed:e.row.origin_kind==="ticket"})}catch(r){throw await _(e.row.review_id,e.row.branch_file),r}i.won||await _(e.row.review_id,e.row.branch_file),await d(i.request_id);const t=await a(i.request_id);if(t===null)throw new Error(`realized review disappeared: ${i.request_id}`);return t}n(f,"createReview");export{f as createReview};
@@ -1,4 +1,4 @@
1
- import type { DatabaseSync } from 'node:sqlite';
1
+ import { type CanvasDb } from '../canvas/db.js';
2
2
  import { type CommentAnchor, type CommentAuthorKind, type CommentStatus, type ReviewComment, type ReviewCommentEvent } from './types.js';
3
3
  interface Actor {
4
4
  kind: CommentAuthorKind;
@@ -17,53 +17,53 @@ export declare function createComment(args: {
17
17
  doc_hash: string;
18
18
  actor: Actor;
19
19
  operation_id: string;
20
- }): {
20
+ }): Promise<{
21
21
  comment: ReviewComment;
22
22
  changed: true;
23
- };
23
+ }>;
24
24
  export declare function editComment(commentIdValue: string, args: {
25
25
  text: string;
26
26
  actor: Actor;
27
27
  operation_id: string;
28
28
  if_revision?: number;
29
- }): {
29
+ }): Promise<{
30
30
  comment: ReviewComment;
31
31
  changed: boolean;
32
- };
33
- export declare function resolveComment(commentIdValue: string, args: CommentMutationArgs): {
32
+ }>;
33
+ export declare function resolveComment(commentIdValue: string, args: CommentMutationArgs): Promise<{
34
34
  comment: ReviewComment;
35
35
  changed: boolean;
36
- };
37
- export declare function reopenComment(commentIdValue: string, args: CommentMutationArgs): {
36
+ }>;
37
+ export declare function reopenComment(commentIdValue: string, args: CommentMutationArgs): Promise<{
38
38
  comment: ReviewComment;
39
39
  changed: boolean;
40
- };
41
- export declare function deleteComment(commentIdValue: string, args: CommentMutationArgs): {
40
+ }>;
41
+ export declare function deleteComment(commentIdValue: string, args: CommentMutationArgs): Promise<{
42
42
  comment: ReviewComment;
43
43
  changed: boolean;
44
- };
44
+ }>;
45
45
  export declare function listComments(reviewId: string, opts?: {
46
46
  status?: CommentStatus | 'all';
47
- }): ReviewComment[];
48
- export declare function getComment(commentIdValue: string): ReviewComment | null;
49
- export declare function listCommentEvents(commentIdValue: string): ReviewCommentEvent[];
47
+ }): Promise<ReviewComment[]>;
48
+ export declare function getComment(commentIdValue: string): Promise<ReviewComment | null>;
49
+ export declare function listCommentEvents(commentIdValue: string): Promise<ReviewCommentEvent[]>;
50
50
  export declare function listReviewEvents(reviewId: string, opts: {
51
51
  since_seq?: number;
52
52
  limit?: number;
53
- }): {
53
+ }): Promise<{
54
54
  events: ReviewCommentEvent[];
55
55
  next_since_seq: number;
56
- };
57
- export declare function snapshotCommentsLocked(db: DatabaseSync, reviewId: string): {
56
+ }>;
57
+ export declare function snapshotCommentsLocked(db: CanvasDb, reviewId: string): Promise<{
58
58
  comments: import('../human/types.js').FeedbackComment[];
59
59
  total: number;
60
60
  unresolved: number;
61
- };
61
+ }>;
62
62
  export declare function appendDeliveryEvent(args: {
63
63
  review_id: string;
64
64
  comment_id: string;
65
65
  kind: 'notified' | 'notify_failed';
66
66
  payload: unknown;
67
67
  operation_id: string;
68
- }): void;
68
+ }): Promise<void>;
69
69
  export {};
@@ -1,21 +1,21 @@
1
- var D=Object.defineProperty;var i=(e,t)=>D(e,"name",{value:t,configurable:!0});import{prepared as _}from"../sqlite-statements.js";import{randomBytes as F}from"node:crypto";import{openDb as l,withCanvasWrite as h}from"../canvas/db.js";import{nowIso as v}from"../fs-utils.js";import{signalReviewActivity as E}from"./signal.js";import{COMMENT_EVENTS_PAGE_DEFAULT as U,COMMENT_EVENTS_PAGE_MAX as W,COMMENT_LINE_TEXT_MAX as B,COMMENT_TEXT_MAX as k,LIVE_COMMENTS_MAX as N,ReviewOperationError as u}from"./types.js";function m(e){return{comment_id:e.comment_id,review_id:e.review_id,status:e.status,revision:e.revision,text:e.text,anchor:{line:e.anchor_line,end_line:e.anchor_end_line,...e.anchor_col_start===null?{}:{col_start:e.anchor_col_start},...e.anchor_col_end===null?{}:{col_end:e.anchor_col_end},...e.anchor_quote===null?{}:{quote:e.anchor_quote}},anchor_state:e.anchor_state,anchor_line_text:e.anchor_line_text,anchor_doc_hash:e.anchor_doc_hash,author:{kind:e.author_kind,node_id:e.author_node_id},updated_by:{kind:e.updated_by_kind,node_id:e.updated_by_node_id},created_at:e.created_at,updated_at:e.updated_at,resolved_at:e.resolved_at,deleted_at:e.deleted_at,created_seq:e.created_seq}}i(m,"commentFromRow");function q(e){return{seq:e.seq,review_id:e.review_id,comment_id:e.comment_id,kind:e.kind,state_change:e.state_change===0?0:1,revision_after:e.revision_after,actor:{kind:e.actor_kind,node_id:e.actor_node_id},at:e.at,operation_id:e.operation_id,...e.payload===null?{}:{payload:JSON.parse(e.payload)}}}i(q,"eventFromRow");function y(e){return JSON.stringify(e)}i(y,"json");function S(){let e;do e=F(16).toString("hex");while(/^0+$/.test(e));return e}i(S,"commentId");function C(e){const t=e.trim();if(t==="")throw new Error("comment text must not be empty");const n=Buffer.byteLength(t,"utf8");if(n>k)throw new u("text_too_long","comment text exceeds the maximum length",{limit:k,received:n});return t}i(C,"trimText");function H(e,t){if(Buffer.byteLength(e,"utf8")<=t)return e;const n="\u2026 [truncated]",r=Buffer.byteLength(n,"utf8"),o=Buffer.from(e,"utf8");let d=Math.max(0,t-r);for(;d>0&&(o[d]&192)===128;)d-=1;return`${o.subarray(0,d).toString("utf8")}${n}`}i(H,"truncateUtf8");function p(e,t){return _(e,"SELECT * FROM review_comments WHERE comment_id = ?").get(t)??null}i(p,"getStoredComment");function f(e,t){const n=p(e,t);if(n===null)throw new u("unknown_comment","comment was not found",{received:t});return n}i(f,"requireStoredComment");function L(e,t){if(_(e,"SELECT request_id FROM human_requests WHERE request_id = ? AND kind = 'review' AND state = 'open'").get(t)===void 0)throw new u("unknown_review","review was not found",{received:t})}i(L,"assertReviewExists");function M(e,t){if(t!==void 0&&t!==e.revision)throw new u("stale_comment","comment revision is stale",{revision:e.revision,text:e.text})}i(M,"assertRevision");function x(e,t){const n=_(e,`
1
+ var A=Object.defineProperty;var i=(e,t)=>A(e,"name",{value:t,configurable:!0});import{randomBytes as D}from"node:crypto";import{withCanvasWrite as u,openDb as l}from"../canvas/db.js";import{nowIso as h}from"../fs-utils.js";import{signalReviewActivity as v}from"./signal.js";import{COMMENT_EVENTS_PAGE_DEFAULT as F,COMMENT_EVENTS_PAGE_MAX as U,COMMENT_LINE_TEXT_MAX as W,COMMENT_TEXT_MAX as R,LIVE_COMMENTS_MAX as T,ReviewOperationError as m}from"./types.js";function _(e){return{comment_id:e.comment_id,review_id:e.review_id,status:e.status,revision:e.revision,text:e.text,anchor:{line:e.anchor_line,end_line:e.anchor_end_line,...e.anchor_col_start===null?{}:{col_start:e.anchor_col_start},...e.anchor_col_end===null?{}:{col_end:e.anchor_col_end},...e.anchor_quote===null?{}:{quote:e.anchor_quote}},anchor_state:e.anchor_state,anchor_line_text:e.anchor_line_text,anchor_doc_hash:e.anchor_doc_hash,author:{kind:e.author_kind,node_id:e.author_node_id},updated_by:{kind:e.updated_by_kind,node_id:e.updated_by_node_id},created_at:e.created_at,updated_at:e.updated_at,resolved_at:e.resolved_at,deleted_at:e.deleted_at,created_seq:e.created_seq}}i(_,"commentFromRow");function k(e){return{seq:e.seq,review_id:e.review_id,comment_id:e.comment_id,kind:e.kind,state_change:e.state_change===0?0:1,revision_after:e.revision_after,actor:{kind:e.actor_kind,node_id:e.actor_node_id},at:e.at,operation_id:e.operation_id,...e.payload===null?{}:{payload:JSON.parse(e.payload)}}}i(k,"eventFromRow");function N(e){return JSON.stringify(e)}i(N,"json");function q(){let e;do e=D(16).toString("hex");while(/^0+$/.test(e));return e}i(q,"commentId");function C(e){const t=e.trim();if(t==="")throw new Error("comment text must not be empty");const n=Buffer.byteLength(t,"utf8");if(n>R)throw new m("text_too_long","comment text exceeds the maximum length",{limit:R,received:n});return t}i(C,"trimText");function B(e,t){if(Buffer.byteLength(e,"utf8")<=t)return e;const n="\u2026 [truncated]",r=Buffer.byteLength(n,"utf8"),o=Buffer.from(e,"utf8");let a=Math.max(0,t-r);for(;a>0&&(o[a]&192)===128;)a-=1;return`${o.subarray(0,a).toString("utf8")}${n}`}i(B,"truncateUtf8");async function p(e,t){return await e.prepare("SELECT * FROM review_comments WHERE comment_id = ?").get(t)??null}i(p,"getStoredComment");async function E(e,t){const n=await p(e,t);if(n===null)throw new m("unknown_comment","comment was not found",{received:t});return n}i(E,"requireStoredComment");async function L(e,t){if(await e.prepare("SELECT request_id FROM human_requests WHERE request_id = ? AND kind = 'review' AND state = 'open'").get(t)===void 0)throw new m("unknown_review","review was not found",{received:t})}i(L,"assertReviewExists");function S(e,t){if(t!==void 0&&t!==e.revision)throw new m("stale_comment","comment revision is stale",{revision:e.revision,text:e.text})}i(S,"assertRevision");async function w(e,t){const n=await e.prepare(`
2
2
  INSERT INTO review_comment_events
3
3
  (review_id, comment_id, kind, state_change, revision_after, actor_kind, actor_node_id, at, operation_id, payload)
4
4
  VALUES (?, ?, ?, 1, ?, ?, ?, ?, ?, ?)
5
- `).run(t.row.review_id,t.row.comment_id,t.kind,t.row.revision,t.actor.kind,t.actor.node_id,t.at,t.operation_id,y(t.payload));return Number(n.lastInsertRowid)}i(x,"appendStateEvent");function O(e,t,n,r,o){const d=t.revision+1;return _(e,`
5
+ `).run(t.row.review_id,t.row.comment_id,t.kind,t.row.revision,t.actor.kind,t.actor.node_id,t.at,t.operation_id,N(t.payload));return Number(n.lastInsertRowid)}i(w,"appendStateEvent");async function M(e,t,n,r,o){const a=t.revision+1;return await e.prepare(`
6
6
  UPDATE review_comments
7
7
  SET status = ?, revision = ?, text = ?, updated_by_kind = ?, updated_by_node_id = ?,
8
8
  updated_at = ?, resolved_at = ?, deleted_at = ?
9
9
  WHERE comment_id = ?
10
- `).run(n.status??t.status,d,n.text??t.text,r.kind,r.node_id,o,n.resolved_at===void 0?t.resolved_at:n.resolved_at,n.deleted_at===void 0?t.deleted_at:n.deleted_at,t.comment_id),{...t,...n,revision:d,updated_by_kind:r.kind,updated_by_node_id:r.node_id,updated_at:o}}i(O,"updateComment");function A(e){return e.changed&&E(),e}i(A,"completeMutation");function G(e){const t=h(n=>{L(n,e.review_id);const r=_(n,"SELECT COUNT(*) AS count FROM review_comments WHERE review_id = ? AND status != 'deleted'").get(e.review_id);if(Number(r.count)>=N)throw new u("comment_limit_reached","review comment limit reached",{limit:N,live:Number(r.count)});const o=C(e.text),d=H(e.line_text,B),c=v();let a=S();for(;p(n,a)!==null;)a=S();if(_(n,`
10
+ `).run(n.status??t.status,a,n.text??t.text,r.kind,r.node_id,o,n.resolved_at===void 0?t.resolved_at:n.resolved_at,n.deleted_at===void 0?t.deleted_at:n.deleted_at,t.comment_id),{...t,...n,revision:a,updated_by_kind:r.kind,updated_by_node_id:r.node_id,updated_at:o}}i(M,"updateComment");function O(e){return e.changed&&v(),e}i(O,"completeMutation");async function P(e){const t=await u(async n=>{await L(n,e.review_id);const r=await n.prepare("SELECT COUNT(*) AS count FROM review_comments WHERE review_id = ? AND status != 'deleted'").get(e.review_id);if(Number(r.count)>=T)throw new m("comment_limit_reached","review comment limit reached",{limit:T,live:Number(r.count)});const o=C(e.text),a=B(e.line_text,W),d=h();let c=q();for(;await p(n,c)!==null;)c=q();if((await n.prepare(`
11
11
  INSERT INTO review_comments
12
12
  (comment_id, review_id, status, revision, text, anchor_line, anchor_end_line,
13
13
  anchor_col_start, anchor_col_end, anchor_quote, anchor_line_text, anchor_doc_hash, anchor_state,
14
14
  author_kind, author_node_id, updated_by_kind, updated_by_node_id, created_at,
15
15
  updated_at, resolved_at, deleted_at, created_seq)
16
16
  VALUES (?, ?, 'open', 1, ?, ?, ?, ?, ?, ?, ?, ?, 'live', ?, ?, ?, ?, ?, ?, NULL, NULL, 0)
17
- `).run(a,e.review_id,o,e.anchor.line,e.anchor.end_line,e.anchor.col_start??null,e.anchor.col_end??null,e.anchor.quote??null,d,e.doc_hash,e.actor.kind,e.actor.node_id,e.actor.kind,e.actor.node_id,c,c).changes!==1)throw new Error("failed to insert review comment");const w=p(n,a),T=x(n,{row:w,kind:"created",actor:e.actor,operation_id:e.operation_id,at:c,payload:{text:o,anchor:e.anchor,line_text:d,doc_hash:e.doc_hash}});return _(n,"UPDATE review_comments SET created_seq = ? WHERE comment_id = ?").run(T,a),{comment:m({...w,created_seq:T}),changed:!0}});return E(),t}i(G,"createComment");function J(e,t){const n=h(r=>{const o=f(r,e);if(o.status==="deleted")throw new u("comment_deleted","comment is a deleted tombstone",{comment_id:o.comment_id,deleted_at:o.deleted_at});const d=C(t.text);if(o.text===d)return{comment:m(o),changed:!1};M(o,t.if_revision);const c=v(),a=m(o).anchor,s=O(r,o,{text:d},t.actor,c);return x(r,{row:s,kind:"edited",actor:t.actor,operation_id:t.operation_id,at:c,payload:{previous_text:o.text,text:d,previous_anchor:a,anchor:m(s).anchor}}),{comment:m(s),changed:!0}});return A(n)}i(J,"editComment");function R(e,t,n,r){const o=h(d=>{const c=f(d,e);if(c.status==="deleted"){if(n==="deleted")return{comment:m(c),changed:!1};throw new u("comment_deleted","comment is a deleted tombstone",{comment_id:c.comment_id,deleted_at:c.deleted_at})}if(c.status===n)return{comment:m(c),changed:!1};M(c,t.if_revision);const a=v(),s=O(d,c,{status:n,resolved_at:n==="resolved"?a:n==="open"?null:void 0,deleted_at:n==="deleted"?a:void 0},t.actor,a);return x(d,{row:s,kind:r,actor:t.actor,operation_id:t.operation_id,at:a,payload:{previous_status:c.status,status:n,previous_text:c.text,text:s.text,previous_anchor:m(c).anchor,anchor:m(s).anchor}}),{comment:m(s),changed:!0}});return A(o)}i(R,"transitionComment");function j(e,t){return R(e,t,"resolved","resolved")}i(j,"resolveComment");function z(e,t){return R(e,t,"open","reopened")}i(z,"reopenComment");function K(e,t){return R(e,t,"deleted","deleted")}i(K,"deleteComment");function Q(e,t){const n=l(),r=t?.status;return(r===void 0?_(n,"SELECT * FROM review_comments WHERE review_id = ? AND status != 'deleted' ORDER BY anchor_line, created_seq").all(e):r==="all"?_(n,"SELECT * FROM review_comments WHERE review_id = ? ORDER BY anchor_line, created_seq").all(e):_(n,"SELECT * FROM review_comments WHERE review_id = ? AND status = ? ORDER BY anchor_line, created_seq").all(e,r)).map(m)}i(Q,"listComments");function Z(e){const t=p(l(),e);return t===null?null:m(t)}i(Z,"getComment");function g(e){return _(l(),"SELECT * FROM review_comment_events WHERE comment_id = ? ORDER BY seq").all(e).map(q)}i(g,"listCommentEvents");function ee(e,t){const n=t.since_seq??0,r=Math.min(Math.max(t.limit??U,1),W),d=_(l(),"SELECT * FROM review_comment_events WHERE review_id = ? AND seq > ? ORDER BY seq LIMIT ?").all(e,n,r).map(q);return{events:d,next_since_seq:d.length===0?n:d[d.length-1].seq}}i(ee,"listReviewEvents");function te(e,t){const n=_(e,"SELECT * FROM review_comments WHERE review_id = ? AND status != 'deleted' ORDER BY anchor_line, created_seq").all(t);return{comments:n.map(o=>({id:o.comment_id,line:o.anchor_line,endLine:o.anchor_end_line,...o.anchor_quote===null?{}:{quote:o.anchor_quote},...o.anchor_col_start===null?{}:{colStart:o.anchor_col_start},...o.anchor_col_end===null?{}:{colEnd:o.anchor_col_end},lineText:o.anchor_line_text,comment:o.text,createdAt:o.created_at})),total:n.length,unresolved:n.filter(o=>o.status==="open").length}}i(te,"snapshotCommentsLocked");function ne(e){h(t=>{if(L(t,e.review_id),f(t,e.comment_id).review_id!==e.review_id)throw new u("unknown_comment","comment was not found",{received:e.comment_id});_(t,`
17
+ `).run(c,e.review_id,o,e.anchor.line,e.anchor.end_line,e.anchor.col_start??null,e.anchor.col_end??null,e.anchor.quote??null,a,e.doc_hash,e.actor.kind,e.actor.node_id,e.actor.kind,e.actor.node_id,d,d)).changes!==1)throw new Error("failed to insert review comment");const y=await p(n,c),x=await w(n,{row:y,kind:"created",actor:e.actor,operation_id:e.operation_id,at:d,payload:{text:o,anchor:e.anchor,line_text:a,doc_hash:e.doc_hash}});return await n.prepare("UPDATE review_comments SET created_seq = ? WHERE comment_id = ?").run(x,c),{comment:_({...y,created_seq:x}),changed:!0}});return v(),t}i(P,"createComment");async function $(e,t){const n=await u(async r=>{const o=await E(r,e);if(o.status==="deleted")throw new m("comment_deleted","comment is a deleted tombstone",{comment_id:o.comment_id,deleted_at:o.deleted_at});const a=C(t.text);if(o.text===a)return{comment:_(o),changed:!1};S(o,t.if_revision);const d=h(),c=_(o).anchor,s=await M(r,o,{text:a},t.actor,d);return await w(r,{row:s,kind:"edited",actor:t.actor,operation_id:t.operation_id,at:d,payload:{previous_text:o.text,text:a,previous_anchor:c,anchor:_(s).anchor}}),{comment:_(s),changed:!0}});return O(n)}i($,"editComment");async function f(e,t,n,r){const o=await u(async a=>{const d=await E(a,e);if(d.status==="deleted"){if(n==="deleted")return{comment:_(d),changed:!1};throw new m("comment_deleted","comment is a deleted tombstone",{comment_id:d.comment_id,deleted_at:d.deleted_at})}if(d.status===n)return{comment:_(d),changed:!1};S(d,t.if_revision);const c=h(),s=await M(a,d,{status:n,resolved_at:n==="resolved"?c:n==="open"?null:void 0,deleted_at:n==="deleted"?c:void 0},t.actor,c);return await w(a,{row:s,kind:r,actor:t.actor,operation_id:t.operation_id,at:c,payload:{previous_status:d.status,status:n,previous_text:d.text,text:s.text,previous_anchor:_(d).anchor,anchor:_(s).anchor}}),{comment:_(s),changed:!0}});return O(o)}i(f,"transitionComment");async function G(e,t){return await f(e,t,"resolved","resolved")}i(G,"resolveComment");async function J(e,t){return await f(e,t,"open","reopened")}i(J,"reopenComment");async function j(e,t){return await f(e,t,"deleted","deleted")}i(j,"deleteComment");async function z(e,t){const n=await l(),r=t?.status;return(r===void 0?await n.prepare("SELECT * FROM review_comments WHERE review_id = ? AND status != 'deleted' ORDER BY anchor_line, created_seq").all(e):r==="all"?await n.prepare("SELECT * FROM review_comments WHERE review_id = ? ORDER BY anchor_line, created_seq").all(e):await n.prepare("SELECT * FROM review_comments WHERE review_id = ? AND status = ? ORDER BY anchor_line, created_seq").all(e,r)).map(_)}i(z,"listComments");async function K(e){const t=await p(await l(),e);return t===null?null:_(t)}i(K,"getComment");async function Q(e){return(await(await l()).prepare("SELECT * FROM review_comment_events WHERE comment_id = ? ORDER BY seq").all(e)).map(k)}i(Q,"listCommentEvents");async function Z(e,t){const n=t.since_seq??0,r=Math.min(Math.max(t.limit??F,1),U),a=(await(await l()).prepare("SELECT * FROM review_comment_events WHERE review_id = ? AND seq > ? ORDER BY seq LIMIT ?").all(e,n,r)).map(k);return{events:a,next_since_seq:a.length===0?n:a[a.length-1].seq}}i(Z,"listReviewEvents");async function g(e,t){const n=await e.prepare("SELECT * FROM review_comments WHERE review_id = ? AND status != 'deleted' ORDER BY anchor_line, created_seq").all(t);return{comments:n.map(o=>({id:o.comment_id,line:o.anchor_line,endLine:o.anchor_end_line,...o.anchor_quote===null?{}:{quote:o.anchor_quote},...o.anchor_col_start===null?{}:{colStart:o.anchor_col_start},...o.anchor_col_end===null?{}:{colEnd:o.anchor_col_end},lineText:o.anchor_line_text,comment:o.text,createdAt:o.created_at})),total:n.length,unresolved:n.filter(o=>o.status==="open").length}}i(g,"snapshotCommentsLocked");async function ee(e){await u(async t=>{if(await L(t,e.review_id),(await E(t,e.comment_id)).review_id!==e.review_id)throw new m("unknown_comment","comment was not found",{received:e.comment_id});await t.prepare(`
18
18
  INSERT INTO review_comment_events
19
19
  (review_id, comment_id, kind, state_change, revision_after, actor_kind, actor_node_id, at, operation_id, payload)
20
20
  VALUES (?, ?, ?, 0, NULL, 'system', NULL, ?, ?, ?)
21
- `).run(e.review_id,e.comment_id,e.kind,v(),e.operation_id,y(e.payload))}),E()}i(ne,"appendDeliveryEvent");export{ne as appendDeliveryEvent,G as createComment,K as deleteComment,J as editComment,Z as getComment,g as listCommentEvents,Q as listComments,ee as listReviewEvents,z as reopenComment,j as resolveComment,te as snapshotCommentsLocked};
21
+ `).run(e.review_id,e.comment_id,e.kind,h(),e.operation_id,N(e.payload))}),v()}i(ee,"appendDeliveryEvent");export{ee as appendDeliveryEvent,P as createComment,j as deleteComment,$ as editComment,K as getComment,Q as listCommentEvents,z as listComments,Z as listReviewEvents,J as reopenComment,G as resolveComment,g as snapshotCommentsLocked};
@@ -27,7 +27,7 @@ export declare function captureOrigin(originNodeId: string, deps?: {
27
27
  /** Create the ordinary, promptless companion node. Realization owns its launch. */
28
28
  export declare function spawnReviewCompanion(spec: ReviewCompanionSpec): Promise<void>;
29
29
  /** A companion is bound only when its session coordinates and visible boundary are durable. */
30
- export declare function isReviewCompanionBound(nodeId: string): boolean;
30
+ export declare function isReviewCompanionBound(nodeId: string): Promise<boolean>;
31
31
  /** Wait for the durable companion bind without owning companion liveness. */
32
32
  export declare function awaitCompanionBind(nodeId: string, deadlineMs: number): Promise<boolean>;
33
33
  export {};
@@ -1 +1 @@
1
- var y=Object.defineProperty;var s=(e,o)=>y(e,"name",{value:o,configurable:!0});import{randomUUID as v}from"node:crypto";import{conversationIdFromPath as u,conversationStore as w,ConversationNotFoundError as p}from"../conversation-store/index.js";import{basename as F,isAbsolute as c}from"node:path";import{BrokerClient as x}from"../broker-client/index.js";import{deleteNode as M,getNode as g}from"../canvas/index.js";import{expandModelCandidates as C,selectInitialModelRoute as E}from"../model-routes.js";import{buildLaunchSpec as L}from"../runtime/launch.js";import{openModelRegistry as B}from"../runtime/model-registry.js";import{isBrokerLive as O}from"../runtime/model-swap.js";import{spawnNode as R}from"../runtime/nodes.js";import{SessionManager as D}from"../runtime/broker-sdk.js";import{isReviewBoundary as P}from"../runtime/session-visibility.js";import{forkNodeLedger as $}from"../runtime/ledger.js";import{ReviewOperationError as b}from"./types.js";const I=/^[^/\s:]+\/[^/\s:]+:(?:off|minimal|low|medium|high|xhigh|max)$/,q=100;function N(e){return new b("review_origin_missing","review origin was not found",{origin_node_id:e})}s(N,"originMissing");function f(e,o,r={}){return new b("review_origin_unforkable","review origin has no forkable exact session",{origin_node_id:e,reason:o,...r})}s(f,"originUnforkable");async function k(e,o,r){const n=u(o.sourceFile);if(!c(o.sourceFile)||n===null||n!==o.sourceSessionId||o.leafId===null||o.leafId==="")throw f(e,"no_forkable_session");try{w().header(n)}catch(i){throw i instanceof p?f(e,"no_forkable_session"):i}if(o.modelSpec===null||!I.test(o.modelSpec))throw f(e,"model_unresolvable");const t=E({kind:"exact",spec:o.modelSpec},r??await B(),{cwd:o.cwd,profileId:o.profileId});if(t.selected===void 0)throw f(e,"model_unresolvable",{model_reason:t.rejected[0]?.reason});return{sourceFile:o.sourceFile,sourceSessionId:o.sourceSessionId,leafId:o.leafId,modelSpec:o.modelSpec}}s(k,"validateCapture");function U(e){return new Promise((o,r)=>{const n=new x(e);let t=!1;function i(d){t||(t=!0,n.close(),d())}s(i,"finish"),n.on("error",d=>i(()=>r(d))),n.on("close",()=>i(()=>r(new Error("origin broker closed before fork coordinates were read")))),n.on("connect",()=>{n.send({type:"hello",role:"observer",client_id:v()}),n.request({type:"get_human_fork_coordinates"}).then(d=>{if(d.kind!=="human_fork_coordinates"){i(()=>r(new Error("origin broker returned an unexpected fork-coordinate response")));return}i(()=>o(d))}).catch(d=>i(()=>r(d)))}),n.connect()})}s(U,"captureLiveOrigin");async function re(e,o={}){const r=g(e);if(r===null)throw N(e);if(O(r)){const a=await U(e);return k(e,{...a,cwd:r.cwd,profileId:r.profile_id},o.registry)}const n=typeof r.pi_session_file=="string"?r.pi_session_file:"";let t="",i=null,d=null;const h=u(n);if(c(n)&&h!==null)try{const a=w().read(h),m=D.inMemory(a.header.cwd,void 0,[a.header,...a.entries]);t=m.getSessionId(),i=m.getLeafId();const _=r.launch?.model,l=typeof _=="string"?C({kind:"exact",spec:_},r.cwd,r.profile_id)[0]:void 0;if(l!==void 0){const S=l.thinkingLevel??(m.buildSessionContext().thinkingLevel||"off");d=`${l.providerId}/${l.modelId}:${S}`}}catch(a){if(!(a instanceof p))throw a}return k(e,{sourceFile:n,sourceSessionId:t,leafId:i,modelSpec:d,cwd:r.cwd,profileId:r.profile_id},o.registry)}s(re,"captureOrigin");async function ne(e){if(!c(e.branchFile)||!c(e.targetFile))throw new Error("review companion requires absolute branch and target paths");if(!I.test(e.modelSpec))throw new Error("review companion requires an exact model spec");const{launch:o}=L("review/companion","base",{lifecycle:"resident",hasManager:!1,model:e.modelSpec,modelExact:!0,cwd:e.cwd,profileId:e.profileId}),r=await R({nodeId:e.nodeId,kind:"review/companion",mode:"base",lifecycle:"resident",cwd:e.cwd,profile_id:e.profileId,parent:e.originNodeId,creator:e.originNodeId,subscribe:!1,forkFrom:e.branchFile,forkSourceFile:e.branchFile,modelOverride:e.modelSpec,reviewBinding:{review_id:e.reviewId,origin_node_id:e.originNodeId,branch_file:e.branchFile,target_file:e.targetFile},name:`review ${F(e.targetFile)}`,launch:o});try{$(r.node_id,e.originNodeId)}catch(n){throw M(r.node_id),n}}s(ne,"spawnReviewCompanion");function A(e){const o=g(e),r=o?.review_binding,n=o?.pi_session_file,t=typeof n=="string"?u(n):null;if(r==null||o?.pi_session_id==null||t===null)return!1;try{return w().read(t).entries.some(i=>P(i,r.review_id))}catch(i){if(i instanceof p)return!1;throw i}}s(A,"isReviewCompanionBound");async function ie(e,o){const r=Date.now()+Math.max(0,o);for(;;){if(A(e))return!0;const n=r-Date.now();if(n<=0)return!1;await new Promise(t=>setTimeout(t,Math.min(q,n)))}}s(ie,"awaitCompanionBind");export{ie as awaitCompanionBind,re as captureOrigin,A as isReviewCompanionBound,ne as spawnReviewCompanion};
1
+ var S=Object.defineProperty;var d=(e,o)=>S(e,"name",{value:o,configurable:!0});import{randomUUID as v}from"node:crypto";import{conversationIdFromPath as w,conversationStore as u,ConversationNotFoundError as p}from"../conversation-store/index.js";import{basename as F,isAbsolute as c}from"node:path";import{BrokerClient as x}from"../broker-client/index.js";import{deleteNode as M,getNode as g}from"../canvas/index.js";import{expandModelCandidates as C,selectInitialModelRoute as E}from"../model-routes.js";import{buildLaunchSpec as L}from"../runtime/launch.js";import{openModelRegistry as B}from"../runtime/model-registry.js";import{isBrokerLive as O}from"../runtime/model-swap.js";import{spawnNode as R}from"../runtime/nodes.js";import{SessionManager as D}from"../runtime/broker-sdk.js";import{isReviewBoundary as P}from"../runtime/session-visibility.js";import{forkNodeLedger as $}from"../runtime/ledger.js";import{ReviewOperationError as b}from"./types.js";const I=/^[^/\s:]+\/[^/\s:]+:(?:off|minimal|low|medium|high|xhigh|max)$/,q=100;function N(e){return new b("review_origin_missing","review origin was not found",{origin_node_id:e})}d(N,"originMissing");function f(e,o,r={}){return new b("review_origin_unforkable","review origin has no forkable exact session",{origin_node_id:e,reason:o,...r})}d(f,"originUnforkable");async function k(e,o,r){const i=w(o.sourceFile);if(!c(o.sourceFile)||i===null||i!==o.sourceSessionId||o.leafId===null||o.leafId==="")throw f(e,"no_forkable_session");try{await u().header(i)}catch(n){throw n instanceof p?f(e,"no_forkable_session"):n}if(o.modelSpec===null||!I.test(o.modelSpec))throw f(e,"model_unresolvable");const t=E({kind:"exact",spec:o.modelSpec},r??await B(),{cwd:o.cwd,profileId:o.profileId});if(t.selected===void 0)throw f(e,"model_unresolvable",{model_reason:t.rejected[0]?.reason});return{sourceFile:o.sourceFile,sourceSessionId:o.sourceSessionId,leafId:o.leafId,modelSpec:o.modelSpec}}d(k,"validateCapture");function U(e){return new Promise(async(o,r)=>{const i=new x(e);let t=!1;function n(s){t||(t=!0,i.close(),s())}d(n,"finish"),i.on("error",s=>n(()=>r(s))),i.on("close",()=>n(()=>r(new Error("origin broker closed before fork coordinates were read")))),i.on("connect",()=>{i.send({type:"hello",role:"observer",client_id:v()}),i.request({type:"get_human_fork_coordinates"}).then(s=>{if(s.kind!=="human_fork_coordinates"){n(()=>r(new Error("origin broker returned an unexpected fork-coordinate response")));return}n(()=>o(s))}).catch(s=>n(()=>r(s)))}),i.connect()})}d(U,"captureLiveOrigin");async function re(e,o={}){const r=await g(e);if(r===null)throw N(e);if(O(r)){const a=await U(e);return k(e,{...a,cwd:r.cwd,profileId:r.profile_id},o.registry)}const i=typeof r.pi_session_file=="string"?r.pi_session_file:"";let t="",n=null,s=null;const h=w(i);if(c(i)&&h!==null)try{const a=await u().read(h),m=D.inMemory(a.header.cwd,void 0,[a.header,...a.entries]);t=m.getSessionId(),n=m.getLeafId();const _=r.launch?.model,l=typeof _=="string"?C({kind:"exact",spec:_},r.cwd,r.profile_id)[0]:void 0;if(l!==void 0){const y=l.thinkingLevel??(m.buildSessionContext().thinkingLevel||"off");s=`${l.providerId}/${l.modelId}:${y}`}}catch(a){if(!(a instanceof p))throw a}return k(e,{sourceFile:i,sourceSessionId:t,leafId:n,modelSpec:s,cwd:r.cwd,profileId:r.profile_id},o.registry)}d(re,"captureOrigin");async function ie(e){if(!c(e.branchFile)||!c(e.targetFile))throw new Error("review companion requires absolute branch and target paths");if(!I.test(e.modelSpec))throw new Error("review companion requires an exact model spec");const{launch:o}=L("review/companion","base",{lifecycle:"resident",hasManager:!1,model:e.modelSpec,modelExact:!0,cwd:e.cwd,profileId:e.profileId}),r=await R({nodeId:e.nodeId,kind:"review/companion",mode:"base",lifecycle:"resident",cwd:e.cwd,profile_id:e.profileId,parent:e.originNodeId,creator:e.originNodeId,subscribe:!1,forkFrom:e.branchFile,forkSourceFile:e.branchFile,modelOverride:e.modelSpec,reviewBinding:{review_id:e.reviewId,origin_node_id:e.originNodeId,branch_file:e.branchFile,target_file:e.targetFile},name:`review ${F(e.targetFile)}`,launch:o});try{await $(r.node_id,e.originNodeId)}catch(i){throw await M(r.node_id),i}}d(ie,"spawnReviewCompanion");async function A(e){const o=await g(e),r=o?.review_binding,i=o?.pi_session_file,t=typeof i=="string"?w(i):null;if(r==null||o?.pi_session_id==null||t===null)return!1;try{return(await u().read(t)).entries.some(n=>P(n,r.review_id))}catch(n){if(n instanceof p)return!1;throw n}}d(A,"isReviewCompanionBound");async function ne(e,o){const r=Date.now()+Math.max(0,o);for(;;){if(await A(e))return!0;const i=r-Date.now();if(i<=0)return!1;await new Promise(t=>setTimeout(t,Math.min(q,i)))}}d(ne,"awaitCompanionBind");export{ne as awaitCompanionBind,re as captureOrigin,A as isReviewCompanionBound,ie as spawnReviewCompanion};
@@ -1,6 +1,6 @@
1
- import type { DatabaseSync } from 'node:sqlite';
2
1
  import type { ReviewRecord } from './types.js';
3
2
  import { type CommentAnchor } from './types.js';
3
+ import type { CanvasDb } from '../canvas/db.js';
4
4
  type SourcePhase = 'submit' | 'comment';
5
5
  /** Read the reviewed document once, preserving the exact bytes used for its digest. */
6
6
  export declare function readReviewSource(file: string, phase?: SourcePhase): {
@@ -15,11 +15,11 @@ export declare function requireCurrentDocument(review: ReviewRecord, expected_do
15
15
  lines: string[];
16
16
  };
17
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): {
18
+ export declare function requireCurrentDocumentLocked(db: CanvasDb, review_id: string, expected_doc_hash: string): Promise<{
19
19
  bytes: Buffer;
20
20
  sha256: string;
21
21
  lines: string[];
22
- };
22
+ }>;
23
23
  /** Reject malformed ranges rather than normalizing them into a different anchor. */
24
24
  export declare function validateAnchorShape(anchor: CommentAnchor): void;
25
25
  /** Capture the full source range used to render an anchor, without silently clamping it. */
@@ -1,2 +1,2 @@
1
- var f=Object.defineProperty;var i=(e,t)=>f(e,"name",{value:t,configurable:!0});import{prepared as m}from"../sqlite-statements.js";import{createHash as g}from"node:crypto";import{readFileSync as b,statSync as p}from"node:fs";import{documentLines as w}from"../document-lines.js";import{COMMENT_QUOTE_MAX as a,ReviewOperationError as u}from"./types.js";const l=2*1024*1024;function o(e,t,n){throw new u("source_unreadable","review source is unreadable",{phase:t,reason:n,file:e})}i(o,"sourceUnreadable");function h(e,t="submit"){let n;try{const s=p(e);if(!s.isFile())return o(e,t,"unreadable");n=s.size}catch(s){return o(e,t,s.code==="ENOENT"?"missing":"unreadable")}if(n>l)return o(e,t,"too_large");let r;try{r=b(e)}catch(s){return o(e,t,s.code==="ENOENT"?"missing":"unreadable")}if(r.length>l)return o(e,t,"too_large");if(r.includes(0))return o(e,t,"binary");let d;try{d=new TextDecoder("utf-8",{fatal:!0}).decode(r)}catch{return o(e,t,"binary")}return{bytes:r,sha256:g("sha256").update(r).digest("hex"),lines:w(d)}}i(h,"readReviewSource");function c(e,t){const n=h(e.file,"comment");if(n.sha256!==t)throw new u("stale_document","review document changed since it was rendered",{reason:"document_changed",expected_sha256:t,actual_sha256:n.sha256});if(n.sha256!==e.anchor_base_sha256)throw new u("stale_document","review comment ranges have not been remapped to the current document",{reason:"anchor_base_stale",expected_sha256:e.anchor_base_sha256,actual_sha256:n.sha256});return n}i(c,"requireDocumentSource");function I(e,t){return c(e,t)}i(I,"requireCurrentDocument");function T(e,t,n){const r=m(e,"SELECT file, anchor_base_sha256 FROM human_requests WHERE request_id = ? AND kind = 'review' AND state = 'open'").get(t);if(r===void 0)throw new u("unknown_review","review was not found",{received:t});return c(r,n)}i(T,"requireCurrentDocumentLocked");function v(e){const t=[],n=e.col_start!==void 0,r=e.col_end!==void 0;if((!Number.isSafeInteger(e.line)||e.line<1)&&t.push("line must be a positive integer"),(!Number.isSafeInteger(e.end_line)||e.end_line<1)&&t.push("end_line must be a positive integer"),Number.isSafeInteger(e.line)&&Number.isSafeInteger(e.end_line)&&e.end_line<e.line&&t.push("end_line must be greater than or equal to line"),n!==r&&t.push("col_start and col_end must be provided together"),n&&(!Number.isSafeInteger(e.col_start)||e.col_start<0)&&t.push("col_start must be a non-negative integer"),r&&(!Number.isSafeInteger(e.col_end)||e.col_end<0)&&t.push("col_end must be a non-negative integer"),n&&r&&e.line===e.end_line&&Number.isSafeInteger(e.col_start)&&Number.isSafeInteger(e.col_end)&&e.col_end<=e.col_start&&t.push("col_end must be greater than col_start for a single-line anchor"),e.quote!==void 0&&typeof e.quote!="string"&&t.push("quote must be a string"),typeof e.quote=="string"&&Buffer.byteLength(e.quote,"utf8")>a&&t.push(`quote exceeds ${a} bytes`),t.length>0)throw new u("invalid_anchor","comment anchor is invalid",{violations:t})}i(v,"validateAnchorShape");function _(e,t){return t===e.length||(e[t]&192)!==128}i(_,"isUtf8Boundary");function O(e,t){if(v(t),t.line>e.length||t.end_line>e.length)throw new u("anchor_out_of_range","comment anchor exceeds the reviewed document",{line_count:e.length,requested:{line:t.line,end_line:t.end_line}});if(t.col_start!==void 0&&t.col_end!==void 0){const n=Buffer.from(e[t.line-1],"utf8"),r=Buffer.from(e[t.end_line-1],"utf8");if(t.col_start>n.length||t.col_end>r.length||!_(n,t.col_start)||!_(r,t.col_end))throw new u("anchor_out_of_range","comment anchor columns exceed the reviewed document",{line_count:e.length,requested:{line:t.line,end_line:t.end_line}})}return e.slice(t.line-1,t.end_line).join(`
2
- `)}i(O,"captureAnchorText");export{O as captureAnchorText,h as readReviewSource,I as requireCurrentDocument,T as requireCurrentDocumentLocked,v as validateAnchorShape};
1
+ var f=Object.defineProperty;var i=(e,t)=>f(e,"name",{value:t,configurable:!0});import{createHash as m}from"node:crypto";import{readFileSync as g,statSync as b}from"node:fs";import{documentLines as p}from"../document-lines.js";import{COMMENT_QUOTE_MAX as a,ReviewOperationError as u}from"./types.js";const l=2*1024*1024;function o(e,t,n){throw new u("source_unreadable","review source is unreadable",{phase:t,reason:n,file:e})}i(o,"sourceUnreadable");function w(e,t="submit"){let n;try{const s=b(e);if(!s.isFile())return o(e,t,"unreadable");n=s.size}catch(s){return o(e,t,s.code==="ENOENT"?"missing":"unreadable")}if(n>l)return o(e,t,"too_large");let r;try{r=g(e)}catch(s){return o(e,t,s.code==="ENOENT"?"missing":"unreadable")}if(r.length>l)return o(e,t,"too_large");if(r.includes(0))return o(e,t,"binary");let d;try{d=new TextDecoder("utf-8",{fatal:!0}).decode(r)}catch{return o(e,t,"binary")}return{bytes:r,sha256:m("sha256").update(r).digest("hex"),lines:p(d)}}i(w,"readReviewSource");function _(e,t){const n=w(e.file,"comment");if(n.sha256!==t)throw new u("stale_document","review document changed since it was rendered",{reason:"document_changed",expected_sha256:t,actual_sha256:n.sha256});if(n.sha256!==e.anchor_base_sha256)throw new u("stale_document","review comment ranges have not been remapped to the current document",{reason:"anchor_base_stale",expected_sha256:e.anchor_base_sha256,actual_sha256:n.sha256});return n}i(_,"requireDocumentSource");function q(e,t){return _(e,t)}i(q,"requireCurrentDocument");async function y(e,t,n){const r=await e.prepare("SELECT file, anchor_base_sha256 FROM human_requests WHERE request_id = ? AND kind = 'review' AND state = 'open'").get(t);if(r===void 0)throw new u("unknown_review","review was not found",{received:t});return _(r,n)}i(y,"requireCurrentDocumentLocked");function h(e){const t=[],n=e.col_start!==void 0,r=e.col_end!==void 0;if((!Number.isSafeInteger(e.line)||e.line<1)&&t.push("line must be a positive integer"),(!Number.isSafeInteger(e.end_line)||e.end_line<1)&&t.push("end_line must be a positive integer"),Number.isSafeInteger(e.line)&&Number.isSafeInteger(e.end_line)&&e.end_line<e.line&&t.push("end_line must be greater than or equal to line"),n!==r&&t.push("col_start and col_end must be provided together"),n&&(!Number.isSafeInteger(e.col_start)||e.col_start<0)&&t.push("col_start must be a non-negative integer"),r&&(!Number.isSafeInteger(e.col_end)||e.col_end<0)&&t.push("col_end must be a non-negative integer"),n&&r&&e.line===e.end_line&&Number.isSafeInteger(e.col_start)&&Number.isSafeInteger(e.col_end)&&e.col_end<=e.col_start&&t.push("col_end must be greater than col_start for a single-line anchor"),e.quote!==void 0&&typeof e.quote!="string"&&t.push("quote must be a string"),typeof e.quote=="string"&&Buffer.byteLength(e.quote,"utf8")>a&&t.push(`quote exceeds ${a} bytes`),t.length>0)throw new u("invalid_anchor","comment anchor is invalid",{violations:t})}i(h,"validateAnchorShape");function c(e,t){return t===e.length||(e[t]&192)!==128}i(c,"isUtf8Boundary");function I(e,t){if(h(t),t.line>e.length||t.end_line>e.length)throw new u("anchor_out_of_range","comment anchor exceeds the reviewed document",{line_count:e.length,requested:{line:t.line,end_line:t.end_line}});if(t.col_start!==void 0&&t.col_end!==void 0){const n=Buffer.from(e[t.line-1],"utf8"),r=Buffer.from(e[t.end_line-1],"utf8");if(t.col_start>n.length||t.col_end>r.length||!c(n,t.col_start)||!c(r,t.col_end))throw new u("anchor_out_of_range","comment anchor columns exceed the reviewed document",{line_count:e.length,requested:{line:t.line,end_line:t.end_line}})}return e.slice(t.line-1,t.end_line).join(`
2
+ `)}i(I,"captureAnchorText");export{I as captureAnchorText,w as readReviewSource,q as requireCurrentDocument,y as requireCurrentDocumentLocked,h as validateAnchorShape};
@@ -1,5 +1,5 @@
1
- var m=Object.defineProperty;var d=(o,n)=>m(o,"name",{value:n,configurable:!0});import{basename as c}from"node:path";import{getNode as s}from"../canvas/index.js";import{materializeSessionBranch as p}from"../runtime/session-branch.js";import{spawnChildPrepared as w}from"../runtime/spawn.js";import{getComment as l}from"./comments.js";import{captureOrigin as _}from"./companion.js";import{requireVisibleReview as f}from"./store.js";import{ReviewOperationError as a}from"./types.js";function h(o,n){const{line:e,end_line:i}=n.anchor,t=i>e?`lines ${e}-${i}`:`line ${e}`,r=n.anchor_line_text===""?"":`
1
+ var m=Object.defineProperty;var d=(o,n)=>m(o,"name",{value:n,configurable:!0});import{basename as c}from"node:path";import{getNode as s}from"../canvas/index.js";import{materializeSessionBranch as w}from"../runtime/session-branch.js";import{spawnChildPrepared as p}from"../runtime/spawn.js";import{getComment as l}from"./comments.js";import{captureOrigin as _}from"./companion.js";import{requireVisibleReview as f}from"./store.js";import{ReviewOperationError as a}from"./types.js";function h(o,n){const{line:e,end_line:i}=n.anchor,t=i>e?`lines ${e}-${i}`:`line ${e}`,r=n.anchor_line_text===""?"":`
2
2
  > ${n.anchor_line_text}
3
3
  `;return[`The person handed you this one comment on \`${o.file}\` so it can be worked in parallel. The review companion you were forked from keeps the rest of the document.`,`${t}:${r}`,n.text,`Address it by editing only the lines this comment is about \u2014 other forks may be editing the same file \u2014 then resolve it with \`crtr human review comment resolve ${n.comment_id}\`, and tell the companion what changed with \`crtr push update\`.`].join(`
4
4
 
5
- `)}d(h,"forkTask");async function R(o){const n=l(o);if(n===null)throw new a("unknown_comment","comment was not found",{received:o});if(n.status!=="open")throw new a("comment_deleted","only an open comment can be forked",{comment_id:o,status:n.status});const e=f(n.review_id);if(e.state!=="open")throw new a("review_terminal","review already has a terminal outcome",{state:e.state,requested:"fork",review:e});const i=s(e.companion_node_id);if(i===null)throw new a("review_companion_unbound","review companion is gone",{companion_node_id:e.companion_node_id});const t=await _(e.companion_node_id),r=p(t);return{node_id:(await w({kind:"review/companion",mode:"base",cwd:i.cwd,parent:e.companion_node_id,creator:e.companion_node_id,rootLifecycle:"resident",prompt:h(e,n),forkFrom:r,model:t.modelSpec,name:`comment on ${c(e.file)}`,reviewBinding:{review_id:e.review_id,origin_node_id:e.origin_node_id,branch_file:r,target_file:e.file}})).node.node_id,cwd:i.cwd}}d(R,"forkReviewComment");export{R as forkReviewComment};
5
+ `)}d(h,"forkTask");async function R(o){const n=await l(o);if(n===null)throw new a("unknown_comment","comment was not found",{received:o});if(n.status!=="open")throw new a("comment_deleted","only an open comment can be forked",{comment_id:o,status:n.status});const e=await f(n.review_id);if(e.state!=="open")throw new a("review_terminal","review already has a terminal outcome",{state:e.state,requested:"fork",review:e});const i=await s(e.companion_node_id);if(i===null)throw new a("review_companion_unbound","review companion is gone",{companion_node_id:e.companion_node_id});const t=await _(e.companion_node_id),r=await w(t);return{node_id:(await p({kind:"review/companion",mode:"base",cwd:i.cwd,parent:e.companion_node_id,creator:e.companion_node_id,rootLifecycle:"resident",prompt:h(e,n),forkFrom:r,model:t.modelSpec,name:`comment on ${c(e.file)}`,reviewBinding:{review_id:e.review_id,origin_node_id:e.origin_node_id,branch_file:r,target_file:e.file}})).node.node_id,cwd:i.cwd}}d(R,"forkReviewComment");export{R as forkReviewComment};
@@ -1 +1 @@
1
- var m=Object.defineProperty;var r=(i,e)=>m(i,"name",{value:e,configurable:!0});import{conversationIdFromPath as v,conversationStore as h,ConversationNotFoundError as g}from"../conversation-store/index.js";import{getNode as s}from"../canvas/index.js";import{openRequest as q,cancelBindingRequest as b,getRequest as y}from"../human/requests.js";import{NodeIdConflictError as I}from"../runtime/nodes.js";import{reviveNode as N}from"../runtime/revive.js";import{awaitCompanionBind as E,spawnReviewCompanion as S}from"./companion.js";import{signalReviewActivity as l}from"./signal.js";import{COMPANION_BIND_DEADLINE_MS as f,ReviewOperationError as o}from"./types.js";function p(i){const e=y(i);if(e===null||e.kind!=="review")throw new o("unknown_review","review was not found",{received:i});return e}r(p,"requireBinding");function R(i){try{const e=JSON.parse(i.specification_json);if(typeof e!="object"||e===null)throw new Error("not an object");return e}catch(e){throw new Error(`corrupt review specification: ${i.request_id}`,{cause:e})}}r(R,"specification");async function k(i){let e=p(i);if(e.state!=="binding")return e;const w=R(e),t=w.branch_file,d=typeof t=="string"?v(t):null;let u=d===null;if(d!==null)try{h().header(d)}catch(n){if(!(n instanceof g))throw n;u=!0}if(u)throw b(e.request_id,new Date().toISOString(),"branch_lost")&&l(),new o("branch_lost","review branch was lost before realization",{review_id:e.request_id});if(e.file===null||e.requester_node_id===null||e.companion_node_id===null)throw new Error(`binding review has incomplete identity: ${e.request_id}`);const a=s(e.requester_node_id);if(a===null)throw new o("review_origin_missing","review origin was not found",{origin_node_id:e.requester_node_id});if(s(e.companion_node_id)===null){const n=w.model_spec;if(typeof n!="string")throw new Error(`binding review has no model spec: ${e.request_id}`);try{await S({nodeId:e.companion_node_id,reviewId:e.request_id,originNodeId:e.requester_node_id,branchFile:t,targetFile:e.file,modelSpec:n,cwd:a.cwd,profileId:a.profile_id??null})}catch(_){if(!(_ instanceof I))throw _}}const c=s(e.companion_node_id);if(c===null)throw new o("review_companion_unbound","review companion was not created",{review_id:e.request_id});if(c.pi_session_id===null&&await N(c.node_id,{resume:!1,capacity:"refuse"}),!await E(e.companion_node_id,f))throw new o("review_companion_unbound","review companion did not bind in time",{review_id:e.request_id,waited_ms:f});return q(e.request_id,new Date().toISOString())&&l(),e=p(i),e}r(k,"realizeReview");export{k as realizeReview};
1
+ var m=Object.defineProperty;var r=(i,e)=>m(i,"name",{value:e,configurable:!0});import{conversationIdFromPath as v,conversationStore as h,ConversationNotFoundError as g}from"../conversation-store/index.js";import{getNode as s}from"../canvas/index.js";import{openRequest as q,cancelBindingRequest as b,getRequest as y}from"../human/requests.js";import{NodeIdConflictError as I}from"../runtime/nodes.js";import{reviveNode as N}from"../runtime/revive.js";import{awaitCompanionBind as E,spawnReviewCompanion as S}from"./companion.js";import{signalReviewActivity as l}from"./signal.js";import{COMPANION_BIND_DEADLINE_MS as f,ReviewOperationError as o}from"./types.js";async function p(i){const e=await y(i);if(e===null||e.kind!=="review")throw new o("unknown_review","review was not found",{received:i});return e}r(p,"requireBinding");function R(i){try{const e=JSON.parse(i.specification_json);if(typeof e!="object"||e===null)throw new Error("not an object");return e}catch(e){throw new Error(`corrupt review specification: ${i.request_id}`,{cause:e})}}r(R,"specification");async function k(i){let e=await p(i);if(e.state!=="binding")return e;const w=R(e),t=w.branch_file,a=typeof t=="string"?v(t):null;let u=a===null;if(a!==null)try{await h().header(a)}catch(n){if(!(n instanceof g))throw n;u=!0}if(u)throw await b(e.request_id,new Date().toISOString(),"branch_lost")&&l(),new o("branch_lost","review branch was lost before realization",{review_id:e.request_id});if(e.file===null||e.requester_node_id===null||e.companion_node_id===null)throw new Error(`binding review has incomplete identity: ${e.request_id}`);const d=await s(e.requester_node_id);if(d===null)throw new o("review_origin_missing","review origin was not found",{origin_node_id:e.requester_node_id});if(await s(e.companion_node_id)===null){const n=w.model_spec;if(typeof n!="string")throw new Error(`binding review has no model spec: ${e.request_id}`);try{await S({nodeId:e.companion_node_id,reviewId:e.request_id,originNodeId:e.requester_node_id,branchFile:t,targetFile:e.file,modelSpec:n,cwd:d.cwd,profileId:d.profile_id??null})}catch(_){if(!(_ instanceof I))throw _}}const c=await s(e.companion_node_id);if(c===null)throw new o("review_companion_unbound","review companion was not created",{review_id:e.request_id});if(c.pi_session_id===null&&await N(c.node_id,{resume:!1,capacity:"refuse"}),!await E(e.companion_node_id,f))throw new o("review_companion_unbound","review companion did not bind in time",{review_id:e.request_id,waited_ms:f});return await q(e.request_id,new Date().toISOString())&&l(),e=await p(i),e}r(k,"realizeReview");export{k as realizeReview};
@@ -16,9 +16,9 @@ export declare function applyRangeBatch(args: {
16
16
  entries: RangeBatchEntry[];
17
17
  actor: Actor;
18
18
  operation_id: string;
19
- }): {
19
+ }): Promise<{
20
20
  updated: number;
21
21
  detached: number;
22
22
  anchor_base_sha256: string;
23
- };
23
+ }>;
24
24
  export {};
@@ -1,19 +1,19 @@
1
- var q=Object.defineProperty;var i=(e,n)=>q(e,"name",{value:n,configurable:!0});import{prepared as u}from"../sqlite-statements.js";import{withCanvasWrite as A}from"../canvas/db.js";import{nowIso as k}from"../fs-utils.js";import{signalReviewActivity as T}from"./signal.js";import{replaceAnchorBaseLocked as b}from"./store.js";import{ReviewOperationError as h}from"./types.js";import{captureAnchorText as O,readReviewSource as N,validateAnchorShape as D}from"./document.js";function I(e){return{line:e.anchor_line,end_line:e.anchor_end_line,...e.anchor_col_start===null?{}:{col_start:e.anchor_col_start},...e.anchor_col_end===null?{}:{col_end:e.anchor_col_end},...e.anchor_quote===null?{}:{quote:e.anchor_quote}}}i(I,"anchorFromRow");function f(e,n,c,_){throw new h("range_batch_stale","review comment ranges are stale",{reason:e,expected:n,actual:c,..._===void 0?{}:{comment_id:_}})}i(f,"rangeBatchStale");function L(e){if(typeof e.comment_id!="string"||e.comment_id==="")throw new h("invalid_anchor","comment anchor is invalid",{violations:["comment_id must be a non-empty string"]});const n=e.anchor!==void 0,c=e.detached===!0;if(n===c)throw new h("invalid_anchor","comment anchor is invalid",{violations:["each range batch entry must provide exactly one of anchor or detached"]});n&&D(e.anchor)}i(L,"validateEntry");function W(e,n){u(e,`
1
+ var q=Object.defineProperty;var r=(e,o)=>q(e,"name",{value:o,configurable:!0});import{withCanvasWrite as A}from"../canvas/db.js";import{nowIso as S}from"../fs-utils.js";import{signalReviewActivity as k}from"./signal.js";import{replaceAnchorBaseLocked as T}from"./store.js";import{ReviewOperationError as h}from"./types.js";import{captureAnchorText as b,readReviewSource as O,validateAnchorShape as N}from"./document.js";function D(e){return{line:e.anchor_line,end_line:e.anchor_end_line,...e.anchor_col_start===null?{}:{col_start:e.anchor_col_start},...e.anchor_col_end===null?{}:{col_end:e.anchor_col_end},...e.anchor_quote===null?{}:{quote:e.anchor_quote}}}r(D,"anchorFromRow");function p(e,o,c,i){throw new h("range_batch_stale","review comment ranges are stale",{reason:e,expected:o,actual:c,...i===void 0?{}:{comment_id:i}})}r(p,"rangeBatchStale");function I(e){if(typeof e.comment_id!="string"||e.comment_id==="")throw new h("invalid_anchor","comment anchor is invalid",{violations:["comment_id must be a non-empty string"]});const o=e.anchor!==void 0,c=e.detached===!0;if(o===c)throw new h("invalid_anchor","comment anchor is invalid",{violations:["each range batch entry must provide exactly one of anchor or detached"]});o&&N(e.anchor)}r(I,"validateEntry");async function L(e,o){await e.prepare(`
2
2
  INSERT INTO review_comment_events
3
3
  (review_id, comment_id, kind, state_change, revision_after, actor_kind, actor_node_id, at, operation_id, payload)
4
4
  SELECT review_id, ?, 'reanchored', 1, ?, ?, ?, ?, ?, ?
5
5
  FROM review_comments WHERE comment_id = ?
6
- `).run(n.row.comment_id,n.row.revision+1,n.actor.kind,n.actor.node_id,n.at,n.operation_id,JSON.stringify({previous_anchor:n.previous_anchor,anchor:n.anchor,previous_anchor_state:n.previous_anchor_state,anchor_state:n.anchor_state,previous_doc_hash:n.previous_doc_hash,doc_hash:n.doc_hash,line_text:n.line_text}),n.row.comment_id)}i(W,"appendReanchorEvent");function j(e){const n=A(c=>{const _=u(c,"SELECT file, anchor_base_sha256 FROM human_requests WHERE request_id = ? AND kind = 'review' AND state = 'open'").get(e.review_id);if(_===void 0)throw new h("unknown_review","review was not found",{received:e.review_id});const a=N(_.file,"comment");a.sha256!==e.to_doc_hash&&f("to_doc_hash",e.to_doc_hash,a.sha256),_.anchor_base_sha256!==e.from_doc_hash&&f("from_doc_hash",_.anchor_base_sha256,e.from_doc_hash);const d=u(c,`
6
+ `).run(o.row.comment_id,o.row.revision+1,o.actor.kind,o.actor.node_id,o.at,o.operation_id,JSON.stringify({previous_anchor:o.previous_anchor,anchor:o.anchor,previous_anchor_state:o.previous_anchor_state,anchor_state:o.anchor_state,previous_doc_hash:o.previous_doc_hash,doc_hash:o.doc_hash,line_text:o.line_text}),o.row.comment_id)}r(L,"appendReanchorEvent");async function U(e){const o=await A(async c=>{const i=await c.prepare("SELECT file, anchor_base_sha256 FROM human_requests WHERE request_id = ? AND kind = 'review' AND state = 'open'").get(e.review_id);if(i===void 0)throw new h("unknown_review","review was not found",{received:e.review_id});const a=O(i.file,"comment");a.sha256!==e.to_doc_hash&&p("to_doc_hash",e.to_doc_hash,a.sha256),i.anchor_base_sha256!==e.from_doc_hash&&p("from_doc_hash",i.anchor_base_sha256,e.from_doc_hash);const d=await c.prepare(`
7
7
  SELECT comment_id, status, revision, text, anchor_line, anchor_end_line,
8
8
  anchor_col_start, anchor_col_end, anchor_quote, anchor_line_text,
9
9
  anchor_doc_hash, anchor_state
10
10
  FROM review_comments
11
11
  WHERE review_id = ? AND status != 'deleted'
12
12
  ORDER BY created_seq
13
- `).all(e.review_id);for(const o of d)o.anchor_doc_hash!==e.from_doc_hash&&f("comment_hash",e.from_doc_hash,o.anchor_doc_hash,o.comment_id);const r=new Map,s=[];for(const o of e.entries)L(o),r.has(o.comment_id)?s.push(o.comment_id):r.set(o.comment_id,o);const y=new Set(d.map(o=>o.comment_id));for(const o of r.keys())y.has(o)||s.push(o);const p=d.filter(o=>!r.has(o.comment_id)).map(o=>o.comment_id);if(p.length>0||s.length>0)throw new h("range_batch_incomplete","range batch must cover every non-deleted comment exactly once",{missing:p,extra:s});let w=0,E=0;const x=k();for(const o of d){const m=r.get(o.comment_id),R=I(o),t=m.detached===!0?R:m.anchor,l=m.detached===!0?"detached":"live",v=m.detached===!0?o.anchor_line_text:O(a.lines,t);if(!(o.anchor_state!==l||o.anchor_doc_hash!==a.sha256||o.anchor_line!==t.line||o.anchor_end_line!==t.end_line||o.anchor_col_start!==(t.col_start??null)||o.anchor_col_end!==(t.col_end??null)||o.anchor_quote!==(t.quote??null)||o.anchor_line_text!==v))continue;const S=o.revision+1;u(c,`
13
+ `).all(e.review_id);for(const n of d)n.anchor_doc_hash!==e.from_doc_hash&&p("comment_hash",e.from_doc_hash,n.anchor_doc_hash,n.comment_id);const _=new Map,s=[];for(const n of e.entries)I(n),_.has(n.comment_id)?s.push(n.comment_id):_.set(n.comment_id,n);const y=new Set(d.map(n=>n.comment_id));for(const n of _.keys())y.has(n)||s.push(n);const v=d.filter(n=>!_.has(n.comment_id)).map(n=>n.comment_id);if(v.length>0||s.length>0)throw new h("range_batch_incomplete","range batch must cover every non-deleted comment exactly once",{missing:v,extra:s});let f=0,w=0;const E=S();for(const n of d){const m=_.get(n.comment_id),x=D(n),t=m.detached===!0?x:m.anchor,l=m.detached===!0?"detached":"live",u=m.detached===!0?n.anchor_line_text:b(a.lines,t);if(!(n.anchor_state!==l||n.anchor_doc_hash!==a.sha256||n.anchor_line!==t.line||n.anchor_end_line!==t.end_line||n.anchor_col_start!==(t.col_start??null)||n.anchor_col_end!==(t.col_end??null)||n.anchor_quote!==(t.quote??null)||n.anchor_line_text!==u))continue;const R=n.revision+1;await c.prepare(`
14
14
  UPDATE review_comments
15
15
  SET revision = ?, anchor_line = ?, anchor_end_line = ?, anchor_col_start = ?, anchor_col_end = ?,
16
16
  anchor_quote = ?, anchor_line_text = ?, anchor_doc_hash = ?, anchor_state = ?,
17
17
  updated_by_kind = ?, updated_by_node_id = ?, updated_at = ?
18
18
  WHERE comment_id = ?
19
- `).run(S,t.line,t.end_line,t.col_start??null,t.col_end??null,t.quote??null,v,a.sha256,l,e.actor.kind,e.actor.node_id,x,o.comment_id),W(c,{row:o,actor:e.actor,operation_id:e.operation_id,at:x,previous_anchor:R,anchor:t,previous_anchor_state:o.anchor_state,anchor_state:l,previous_doc_hash:o.anchor_doc_hash,doc_hash:a.sha256,line_text:v}),w+=1,l==="detached"&&(E+=1)}return b(c,e.review_id,a.bytes,a.sha256),{updated:w,detached:E,anchor_base_sha256:a.sha256}});return T(),n}i(j,"applyRangeBatch");export{j as applyRangeBatch};
19
+ `).run(R,t.line,t.end_line,t.col_start??null,t.col_end??null,t.quote??null,u,a.sha256,l,e.actor.kind,e.actor.node_id,E,n.comment_id),await L(c,{row:n,actor:e.actor,operation_id:e.operation_id,at:E,previous_anchor:x,anchor:t,previous_anchor_state:n.anchor_state,anchor_state:l,previous_doc_hash:n.anchor_doc_hash,doc_hash:a.sha256,line_text:u}),f+=1,l==="detached"&&(w+=1)}return await T(c,e.review_id,a.bytes,a.sha256),{updated:f,detached:w,anchor_base_sha256:a.sha256}});return k(),o}r(U,"applyRangeBatch");export{U as applyRangeBatch};
@@ -30,7 +30,7 @@ export type StagedReview = {
30
30
  review_dir: string;
31
31
  };
32
32
  /** Remove only review-directory state that was never committed to a review row. */
33
- export declare function discardStaging(reviewId: string, branchFile?: string): void;
33
+ export declare function discardStaging(reviewId: string, branchFile?: string): Promise<void>;
34
34
  /**
35
35
  * Capture an existing origin and write its immutable branch without creating a
36
36
  * canvas node or review row. The caller alone commits or discards this stage.
@@ -1 +1 @@
1
- var v=Object.defineProperty;var o=(e,n)=>v(e,"name",{value:n,configurable:!0});import{createHash as g}from"node:crypto";import{existsSync as y,readFileSync as b,realpathSync as S,rmSync as F,statSync as I,writeFileSync as k}from"node:fs";import{isAbsolute as x,join as R}from"node:path";import{getNode as O}from"../canvas/index.js";import{conversationIdFromPath as j,conversationStore as z,ConversationNotFoundError as D}from"../conversation-store/index.js";import{ensureReviewDir as E,reviewDir as l}from"../canvas/paths.js";import{checkReviewableFile as B}from"../human/visible-paths.js";import{newNodeId as w}from"../runtime/nodes.js";import{captureOrigin as N}from"./companion.js";import{materializeSessionBranch as q}from"../runtime/session-branch.js";import{getRequestByIdempotencyKey as A}from"../human/requests.js";import{ReviewOperationError as r}from"./types.js";function a(e,n){return new r("review_target_unreviewable","review target cannot be staged",{phase:"create",file:e,reason:n})}o(a,"targetError");function h(e){if(!x(e))throw a(e,"not_absolute");if(!y(e))throw a(e,"missing");try{if(!I(e).isFile())throw a(e,"not_a_file")}catch(i){throw i instanceof r?i:a(e,"missing")}const n=B(e);if(!n.ok){const i=n.reason==="file is not UTF-8 text"?"binary":n.reason==="file is too large to review (2 MB limit)"?"too_large":n.reason==="file is too long to review (5,000 line limit)"?"too_many_lines":"not_a_file";throw a(e,i)}try{return S(e)}catch{throw a(e,"missing")}}o(h,"validateReviewFile");function U(e){return new r("review_branch_unavailable","review branch could not be materialized",{reason:"materialize_failed",origin_node_id:e})}o(U,"branchUnavailable");async function C(e){try{return await N(e)}catch(n){throw n instanceof r&&n.code==="review_origin_missing"?new r("review_origin_missing","review origin was not found",{origin_node_id:e,reason:"origin_missing"}):n}}o(C,"captureStagedOrigin");function H(e,n){try{return q(n)}catch{throw U(e)}}o(H,"materialize");function K(e,n){if(n!==void 0){const i=j(n);if(i===null)throw new Error(`invalid staged conversation path: ${n}`);try{z().delete(i)}catch(c){if(!(c instanceof D))throw c}}try{F(l(e),{recursive:!0,force:!0})}catch{}}o(K,"discardStaging");async function ee(e){const n=A(e.idempotency_key);if(n!==null)return{existing:n};if(O(e.origin_node_id)===null)throw new r("review_origin_missing","review origin was not found",{origin_node_id:e.origin_node_id,reason:"origin_missing"});const i=w(),c=w();let d,s=e.document===void 0?h(e.file??""):"";try{if(E(i),e.document!==void 0){const m=R(l(i),"document.md");k(m,e.document.body),s=h(m)}const t=await C(e.origin_node_id),p=new Date().toISOString(),_=b(s),u=g("sha256").update(_).digest("hex");d=H(e.origin_node_id,t);const f=new Date().toISOString();return{row:{review_id:i,idempotency_key:e.idempotency_key,origin_kind:e.origin_kind,origin_node_id:e.origin_node_id,companion_node_id:c,review_dir:l(i),file:s,origin_session_file:t.sourceFile,origin_session_id:t.sourceSessionId,origin_leaf_id:t.leafId,model_spec:t.modelSpec,branch_file:d,baseline_sha256:u,baseline_bytes:_.length,anchor_base_sha256:u,anchor_base_bytes:_,state:"binding",created:f,captured_at:p,opened_at:null,submit_requested_at:null,output_path:e.output_path??null,document_id:e.document?.id??null,document_name:e.document?.name??null,document_base:e.document?.base??null,subtitle:e.subtitle??null,approved_at:null,approved_sha256:null,changed:null,comments_total:null,comments_unresolved:null,result_json:null,canceled_at:null,cancel_reason:null,cancel_actor:null,delivery_entry_id:null,delivered_at:null,delivery_error:null,projected_at:null,projection_error:null},review_dir:l(i)}}catch(t){throw K(i,d),t}}o(ee,"stageReview");export{K as discardStaging,ee as stageReview};
1
+ var v=Object.defineProperty;var t=(e,n)=>v(e,"name",{value:n,configurable:!0});import{createHash as g}from"node:crypto";import{existsSync as y,readFileSync as b,realpathSync as S,rmSync as F,statSync as I,writeFileSync as k}from"node:fs";import{isAbsolute as x,join as R}from"node:path";import{getNode as O}from"../canvas/index.js";import{conversationIdFromPath as j,conversationStore as z,ConversationNotFoundError as D}from"../conversation-store/index.js";import{ensureReviewDir as E,reviewDir as l}from"../canvas/paths.js";import{checkReviewableFile as B}from"../human/visible-paths.js";import{newNodeId as w}from"../runtime/nodes.js";import{captureOrigin as N}from"./companion.js";import{materializeSessionBranch as q}from"../runtime/session-branch.js";import{getRequestByIdempotencyKey as A}from"../human/requests.js";import{ReviewOperationError as r}from"./types.js";function a(e,n){return new r("review_target_unreviewable","review target cannot be staged",{phase:"create",file:e,reason:n})}t(a,"targetError");function h(e){if(!x(e))throw a(e,"not_absolute");if(!y(e))throw a(e,"missing");try{if(!I(e).isFile())throw a(e,"not_a_file")}catch(i){throw i instanceof r?i:a(e,"missing")}const n=B(e);if(!n.ok){const i=n.reason==="file is not UTF-8 text"?"binary":n.reason==="file is too large to review (2 MB limit)"?"too_large":n.reason==="file is too long to review (5,000 line limit)"?"too_many_lines":"not_a_file";throw a(e,i)}try{return S(e)}catch{throw a(e,"missing")}}t(h,"validateReviewFile");function U(e){return new r("review_branch_unavailable","review branch could not be materialized",{reason:"materialize_failed",origin_node_id:e})}t(U,"branchUnavailable");async function C(e){try{return await N(e)}catch(n){throw n instanceof r&&n.code==="review_origin_missing"?new r("review_origin_missing","review origin was not found",{origin_node_id:e,reason:"origin_missing"}):n}}t(C,"captureStagedOrigin");async function H(e,n){try{return await q(n)}catch{throw U(e)}}t(H,"materialize");async function K(e,n){if(n!==void 0){const i=j(n);if(i===null)throw new Error(`invalid staged conversation path: ${n}`);try{await z().delete(i)}catch(c){if(!(c instanceof D))throw c}}try{F(l(e),{recursive:!0,force:!0})}catch{}}t(K,"discardStaging");async function ee(e){const n=await A(e.idempotency_key);if(n!==null)return{existing:n};if(await O(e.origin_node_id)===null)throw new r("review_origin_missing","review origin was not found",{origin_node_id:e.origin_node_id,reason:"origin_missing"});const i=await w(),c=await w();let d,s=e.document===void 0?h(e.file??""):"";try{if(E(i),e.document!==void 0){const m=R(l(i),"document.md");k(m,e.document.body),s=h(m)}const o=await C(e.origin_node_id),p=new Date().toISOString(),_=b(s),u=g("sha256").update(_).digest("hex");d=await H(e.origin_node_id,o);const f=new Date().toISOString();return{row:{review_id:i,idempotency_key:e.idempotency_key,origin_kind:e.origin_kind,origin_node_id:e.origin_node_id,companion_node_id:c,review_dir:l(i),file:s,origin_session_file:o.sourceFile,origin_session_id:o.sourceSessionId,origin_leaf_id:o.leafId,model_spec:o.modelSpec,branch_file:d,baseline_sha256:u,baseline_bytes:_.length,anchor_base_sha256:u,anchor_base_bytes:_,state:"binding",created:f,captured_at:p,opened_at:null,submit_requested_at:null,output_path:e.output_path??null,document_id:e.document?.id??null,document_name:e.document?.name??null,document_base:e.document?.base??null,subtitle:e.subtitle??null,approved_at:null,approved_sha256:null,changed:null,comments_total:null,comments_unresolved:null,result_json:null,canceled_at:null,cancel_reason:null,cancel_actor:null,delivery_entry_id:null,delivered_at:null,delivery_error:null,projected_at:null,projection_error:null},review_dir:l(i)}}catch(o){throw await K(i,d),o}}t(ee,"stageReview");export{K as discardStaging,ee as stageReview};
@@ -1,4 +1,4 @@
1
- import type { DatabaseSync } from 'node:sqlite';
1
+ import { type CanvasDb } from '../canvas/db.js';
2
2
  import { type ReviewRecord, type ReviewState } from './types.js';
3
3
  export interface ApproveReviewArgs {
4
4
  review_id: string;
@@ -9,36 +9,36 @@ export interface ApproveReviewArgs {
9
9
  comments_unresolved: number;
10
10
  result_json: string;
11
11
  }
12
- export declare function getReview(reviewId: string): ReviewRecord | null;
13
- export declare function requireVisibleReview(reviewId: string): ReviewRecord;
14
- export declare function getReviewByIdempotencyKey(key: string): ReviewRecord | null;
15
- export declare function getReviewByCompanion(nodeId: string): ReviewRecord | null;
12
+ export declare function getReview(reviewId: string): Promise<ReviewRecord | null>;
13
+ export declare function requireVisibleReview(reviewId: string): Promise<ReviewRecord>;
14
+ export declare function getReviewByIdempotencyKey(key: string): Promise<ReviewRecord | null>;
15
+ export declare function getReviewByCompanion(nodeId: string): Promise<ReviewRecord | null>;
16
16
  export declare function listReviews(filter: {
17
17
  state?: ReviewState;
18
18
  origin_node_id?: string;
19
19
  file?: string;
20
- }): ReviewRecord[];
21
- export declare function reviewIdsByOriginNodes(nodeIds: readonly string[]): string[];
22
- export declare function deleteReviewsByOriginNodes(nodeIds: readonly string[]): string[];
23
- export declare function listBindingReviews(): ReviewRecord[];
24
- export declare function listSubmitRequestedReviews(): ReviewRecord[];
25
- export declare function listUnprojectedTerminalReviews(): ReviewRecord[];
26
- export declare function openReviewRow(reviewId: string, openedAt: string): boolean;
20
+ }): Promise<ReviewRecord[]>;
21
+ export declare function reviewIdsByOriginNodes(nodeIds: readonly string[]): Promise<string[]>;
22
+ export declare function deleteReviewsByOriginNodes(nodeIds: readonly string[]): Promise<string[]>;
23
+ export declare function listBindingReviews(): Promise<ReviewRecord[]>;
24
+ export declare function listSubmitRequestedReviews(): Promise<ReviewRecord[]>;
25
+ export declare function listUnprojectedTerminalReviews(): Promise<ReviewRecord[]>;
26
+ export declare function openReviewRow(reviewId: string, openedAt: string): Promise<boolean>;
27
27
  /** Put a deferred submit back to not-requested, so the person sees the review open again. */
28
- export declare function clearReviewSubmit(reviewId: string): void;
29
- export declare function requestReviewSubmit(reviewId: string, at: string): boolean;
30
- export declare function approveReviewLocked(db: DatabaseSync, args: ApproveReviewArgs): boolean;
28
+ export declare function clearReviewSubmit(reviewId: string): Promise<void>;
29
+ export declare function requestReviewSubmit(reviewId: string, at: string): Promise<boolean>;
30
+ export declare function approveReviewLocked(db: CanvasDb, args: ApproveReviewArgs): Promise<boolean>;
31
31
  export declare function cancelReviewRow(reviewId: string, args: {
32
32
  at: string;
33
33
  reason: string;
34
34
  actor: string | null;
35
- }): boolean;
36
- export declare function markProjected(reviewId: string, at: string): void;
37
- export declare function markProjectionError(reviewId: string, error: string): void;
35
+ }): Promise<boolean>;
36
+ export declare function markProjected(reviewId: string, at: string): Promise<void>;
37
+ export declare function markProjectionError(reviewId: string, error: string): Promise<void>;
38
38
  export declare function markDelivered(_reviewId: string, _receipt: string | null, _at: string): void;
39
39
  export declare function markDeliveryError(_reviewId: string, _error: string): void;
40
- export declare function readAnchorBase(reviewId: string): {
40
+ export declare function readAnchorBase(reviewId: string): Promise<{
41
41
  bytes: Buffer;
42
42
  sha256: string;
43
- } | null;
44
- export declare function replaceAnchorBaseLocked(db: DatabaseSync, reviewId: string, bytes: Buffer, sha256: string): void;
43
+ } | null>;
44
+ export declare function replaceAnchorBaseLocked(db: CanvasDb, reviewId: string, bytes: Buffer, sha256: string): Promise<void>;