@north-light/cli 0.3.530 → 0.3.531

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 +3 -3
  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 +1 -1
  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 +7 -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 +6 -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 R=Object.defineProperty;var m=(a,t)=>R(a,"name",{value:t,configurable:!0});import{callerGrant as h}from"../principal.js";import{grantVersion as g,payerOfGrant as S}from"../../../core/grants/mirror.js";import{waitGrantChange as O}from"../../../core/grants/watch.js";import{RunError as n,idempotencyKeyOf as b,cancelRun as $,deleteRun as N,interruptRun as A,listRuns as j,messageRun as x,renameRun as B,requestedScopes as J,startRun as z,traceRun as C,waitRun as E}from"../../../core/runs/operations.js";import{canReadRun as v,requireRun as l,runCallerApp as G}from"../router.js";import{waitSeconds as y}from"../long-poll-wait.js";import{outputSchemaProblem as K}from"../../../core/runtime/structured-output.js";function f(a){if(!a||typeof a!="object"||Array.isArray(a))throw new n(400,"invalid_request","a JSON object is required");return a}m(f,"object");function q(a,t,i,d,u){if(a===null)return u;if(!/^(0|[1-9]\d*)$/.test(a)||!Number.isSafeInteger(Number(a))||Number(a)<i||Number(a)>d)throw new n(400,"invalid_request",`invalid ${t}`,t);return Number(a)}m(q,"integer");const T=256*1024;async function X(a,t,i,d,u,_){switch(a.name){case"grant.get":{if("class"in t)throw new n(403,"permission_error","an app token is required");const e=y("grant.get",d),s=d.get("since");if(s!==null&&!/^[A-Za-z0-9_-]{1,64}$/.test(s))throw new n(400,"invalid_request","invalid since","since");let o=h(t);return e&&s!==null&&g(o)===s&&(await O(t.grant,e),o=h(t)),{status:200,body:{sub:t.sub,grantee:t.grantee,client_id:t.client_id,grant:t.grant,rev:o.rev,resolved_scopes:o.resolved_scopes,spend_cap:o.spend_cap,exp:t.exp,payer:S(t.grant),dependencies:o.dependencies??{},version:g(o)}}}case"run.start":{if("class"in t)throw new n(403,"permission_error","an app token is required");const e=f(u),s=["mode","parent","fork_from","node_id","env","tools","system_prompt"];for(const r of s)if(e[r]!==void 0)throw new n(403,"owner_only",`${r} is owner-only`,r);const o=["payer","model_policy","kind"];for(const r of o)if(e[r]!==void 0)throw new n(400,"invalid_request",`${r} is not available`,r);for(const r of Object.keys(e))if(!["prompt","scopes","metadata","profile","isolated","cwd","worktree","output_schema","message","model","deadline"].includes(r))throw new n(400,"invalid_request",`unknown field ${r}`,r);if(e.model!==void 0&&(typeof e.model!="string"||!e.model.trim()))throw new n(400,"invalid_request","model must be a non-empty string","model");if(e.deadline!==void 0&&(typeof e.deadline!="string"||!e.deadline.trim()))throw new n(400,"invalid_request","deadline must be a duration string such as 10m","deadline");if(e.profile!==void 0&&(typeof e.profile!="string"||!e.profile))throw new n(400,"invalid_request","profile must be a profile id","profile");if(e.isolated!==void 0&&typeof e.isolated!="boolean")throw new n(400,"invalid_request","isolated must be a boolean","isolated");if(e.cwd!==void 0&&(e.isolated!==!0||typeof e.cwd!="string"||!e.cwd))throw new n(400,"invalid_request","cwd is available only for an isolated run and must be an absolute path inside its root folder","cwd");if(e.worktree!==void 0&&e.isolated!==!0)throw new n(400,"invalid_request","worktree is not available","worktree");if(e.isolated===!0&&e.worktree!==void 0)throw new n(400,"invalid_request","worktree is unavailable for an isolated run","worktree");if(typeof e.prompt!="string"||!e.prompt.trim())throw new n(400,"invalid_request","prompt is required","prompt");if(e.message!==void 0&&(typeof e.message!="string"||!e.message.trim()))throw new n(400,"invalid_request","message must be a non-empty string","message");const w=e.metadata===void 0?{}:f(e.metadata);if(Buffer.byteLength(JSON.stringify(w))>4096)throw new n(400,"invalid_request","metadata exceeds 4 KB","metadata");let c;if(e.output_schema!==void 0){const r=e.output_schema;if(!r||typeof r!="object"||Array.isArray(r))throw new n(400,"invalid_request","output_schema must be a JSON Schema object","output_schema");if(Buffer.byteLength(JSON.stringify(r))>T)throw new n(400,"invalid_request","output_schema exceeds 256 KB","output_schema");const p=await K(r);if(p!==null)throw new n(400,"invalid_request",`output_schema is not usable: ${p}`,"output_schema");c=r}const k=J(t.resolved,e.scopes,t.grantee);return{status:201,body:await z(t,{prompt:e.prompt,scopes:k,metadata:w,profile:e.profile,isolated:e.isolated,cwd:e.cwd,...e.model===void 0?{}:{model:e.model},...e.deadline===void 0?{}:{deadline:e.deadline},...c===void 0?{}:{output_schema:c},...e.message===void 0?{}:{message:e.message}},b(_))}}case"run.list":{const e=d.get("status")??void 0;if(e&&!["running","waiting_on_user","idle","settled"].includes(e))throw new n(400,"invalid_request","invalid status","status");const s=d.get("app");if(s!==null&&!/^(?:app:)?[a-z0-9][a-z0-9-]*$/.test(s))throw new n(400,"invalid_request","invalid app","app");const o=s===null?G(t):s.startsWith("app:")?s:`app:${s}`;if(o!==null&&!v(t,o))throw new n(404,"not_found","run not found");return{status:200,body:j(o,{status:e,after:d.get("after")??void 0,limit:q(d.get("limit"),"limit",1,100,50),..."class"in t&&(t.class==="broker"||t.class==="cron")&&o!==null?{visible:m(w=>v(t,o,w),"visible")}:{}})}}case"run.get":{const e=y("run.get",d),s=l(t,i),o=await E(i,s.grantee,e);return l(t,i),{status:200,body:o}}case"run.message":{const e=f(u);if(typeof e.message!="string"||!e.message.trim())throw new n(400,"invalid_request","message is required","message");if(e.start_turn!==void 0&&typeof e.start_turn!="boolean")throw new n(400,"invalid_request","start_turn must be a boolean","start_turn");return{status:202,body:await x(l(t,i,!0),e.message,void 0,e.start_turn,b(_))}}case"run.interrupt":{const e=f(u===void 0?{}:u);if(e.children!==void 0&&e.children!=="stop"&&e.children!=="continue")throw new n(400,"invalid_request","invalid children","children");return{status:200,body:await A(l(t,i,!0),e.children)}}case"run.cancel":{const e=f(u===void 0?{}:u);if(e.keep_schedules!==void 0&&typeof e.keep_schedules!="boolean")throw new n(400,"invalid_request","invalid keep_schedules","keep_schedules");return{status:200,body:await $(l(t,i,!0),{keepSchedules:e.keep_schedules})}}case"run.rename":{const e=f(u);for(const s of Object.keys(e))if(s!=="name")throw new n(400,"invalid_request",`unknown field ${s}`,s);return{status:200,body:B(l(t,i,!0),e.name)}}case"run.delete":{const{uploads_pending:e}=await N(l(t,i,!0,!0));return{status:200,body:{run_id:i,uploads_pending:e}}}case"trace.get":{const e=d.get("format")??void 0;if(e&&e!=="entries")throw new n(400,"invalid_request","unknown trace format","format");const s=l(t,i);return{status:200,body:C(i,s.grantee,e)}}default:throw new n(404,"not_found","unknown operation")}}m(X,"handleRunOperation");export{X as handleRunOperation,q as integer};
1
+ var R=Object.defineProperty;var w=(o,t)=>R(o,"name",{value:t,configurable:!0});import{callerGrant as h}from"../principal.js";import{grantVersion as g,payerOfGrant as S}from"../../../core/grants/mirror.js";import{waitGrantChange as O}from"../../../core/grants/watch.js";import{RunError as n,idempotencyKeyOf as b,cancelRun as $,deleteRun as N,interruptRun as A,listRuns as j,messageRun as x,renameRun as B,requestedScopes as J,startRun as z,traceRun as C,waitRun as E}from"../../../core/runs/operations.js";import{canReadRun as v,requireRun as l,runCallerApp as G}from"../router.js";import{waitSeconds as y}from"../long-poll-wait.js";import{outputSchemaProblem as K}from"../../../core/runtime/structured-output.js";function f(o){if(!o||typeof o!="object"||Array.isArray(o))throw new n(400,"invalid_request","a JSON object is required");return o}w(f,"object");function q(o,t,i,d,u){if(o===null)return u;if(!/^(0|[1-9]\d*)$/.test(o)||!Number.isSafeInteger(Number(o))||Number(o)<i||Number(o)>d)throw new n(400,"invalid_request",`invalid ${t}`,t);return Number(o)}w(q,"integer");const T=256*1024;async function X(o,t,i,d,u,_){switch(o.name){case"grant.get":{if("class"in t)throw new n(403,"permission_error","an app token is required");const e=y("grant.get",d),s=d.get("since");if(s!==null&&!/^[A-Za-z0-9_-]{1,64}$/.test(s))throw new n(400,"invalid_request","invalid since","since");let a=await h(t);return e&&s!==null&&g(a)===s&&(await O(t.grant,e),a=await h(t)),{status:200,body:{sub:t.sub,grantee:t.grantee,client_id:t.client_id,grant:t.grant,rev:a.rev,resolved_scopes:a.resolved_scopes,spend_cap:a.spend_cap,exp:t.exp,payer:await S(t.grant),dependencies:a.dependencies??{},version:g(a)}}}case"run.start":{if("class"in t)throw new n(403,"permission_error","an app token is required");const e=f(u),s=["mode","parent","fork_from","node_id","env","tools","system_prompt"];for(const r of s)if(e[r]!==void 0)throw new n(403,"owner_only",`${r} is owner-only`,r);const a=["payer","model_policy","kind"];for(const r of a)if(e[r]!==void 0)throw new n(400,"invalid_request",`${r} is not available`,r);for(const r of Object.keys(e))if(!["prompt","scopes","metadata","profile","isolated","cwd","worktree","output_schema","message","model","deadline"].includes(r))throw new n(400,"invalid_request",`unknown field ${r}`,r);if(e.model!==void 0&&(typeof e.model!="string"||!e.model.trim()))throw new n(400,"invalid_request","model must be a non-empty string","model");if(e.deadline!==void 0&&(typeof e.deadline!="string"||!e.deadline.trim()))throw new n(400,"invalid_request","deadline must be a duration string such as 10m","deadline");if(e.profile!==void 0&&(typeof e.profile!="string"||!e.profile))throw new n(400,"invalid_request","profile must be a profile id","profile");if(e.isolated!==void 0&&typeof e.isolated!="boolean")throw new n(400,"invalid_request","isolated must be a boolean","isolated");if(e.cwd!==void 0&&(e.isolated!==!0||typeof e.cwd!="string"||!e.cwd))throw new n(400,"invalid_request","cwd is available only for an isolated run and must be an absolute path inside its root folder","cwd");if(e.worktree!==void 0&&e.isolated!==!0)throw new n(400,"invalid_request","worktree is not available","worktree");if(e.isolated===!0&&e.worktree!==void 0)throw new n(400,"invalid_request","worktree is unavailable for an isolated run","worktree");if(typeof e.prompt!="string"||!e.prompt.trim())throw new n(400,"invalid_request","prompt is required","prompt");if(e.message!==void 0&&(typeof e.message!="string"||!e.message.trim()))throw new n(400,"invalid_request","message must be a non-empty string","message");const m=e.metadata===void 0?{}:f(e.metadata);if(Buffer.byteLength(JSON.stringify(m))>4096)throw new n(400,"invalid_request","metadata exceeds 4 KB","metadata");let c;if(e.output_schema!==void 0){const r=e.output_schema;if(!r||typeof r!="object"||Array.isArray(r))throw new n(400,"invalid_request","output_schema must be a JSON Schema object","output_schema");if(Buffer.byteLength(JSON.stringify(r))>T)throw new n(400,"invalid_request","output_schema exceeds 256 KB","output_schema");const p=await K(r);if(p!==null)throw new n(400,"invalid_request",`output_schema is not usable: ${p}`,"output_schema");c=r}const k=J(t.resolved,e.scopes,t.grantee);return{status:201,body:await z(t,{prompt:e.prompt,scopes:k,metadata:m,profile:e.profile,isolated:e.isolated,cwd:e.cwd,...e.model===void 0?{}:{model:e.model},...e.deadline===void 0?{}:{deadline:e.deadline},...c===void 0?{}:{output_schema:c},...e.message===void 0?{}:{message:e.message}},b(_))}}case"run.list":{const e=d.get("status")??void 0;if(e&&!["running","waiting_on_user","idle","settled"].includes(e))throw new n(400,"invalid_request","invalid status","status");const s=d.get("app");if(s!==null&&!/^(?:app:)?[a-z0-9][a-z0-9-]*$/.test(s))throw new n(400,"invalid_request","invalid app","app");const a=s===null?G(t):s.startsWith("app:")?s:`app:${s}`;if(a!==null&&!await v(t,a))throw new n(404,"not_found","run not found");return{status:200,body:await j(a,{status:e,after:d.get("after")??void 0,limit:q(d.get("limit"),"limit",1,100,50),..."class"in t&&(t.class==="broker"||t.class==="cron")&&a!==null?{visible:w(async m=>await v(t,a,m),"visible")}:{}})}}case"run.get":{const e=y("run.get",d),s=await l(t,i),a=await E(i,s.grantee,e);return await l(t,i),{status:200,body:a}}case"run.message":{const e=f(u);if(typeof e.message!="string"||!e.message.trim())throw new n(400,"invalid_request","message is required","message");if(e.start_turn!==void 0&&typeof e.start_turn!="boolean")throw new n(400,"invalid_request","start_turn must be a boolean","start_turn");return{status:202,body:await x(await l(t,i,!0),e.message,void 0,e.start_turn,b(_))}}case"run.interrupt":{const e=f(u===void 0?{}:u);if(e.children!==void 0&&e.children!=="stop"&&e.children!=="continue")throw new n(400,"invalid_request","invalid children","children");return{status:200,body:await A(await l(t,i,!0),e.children)}}case"run.cancel":{const e=f(u===void 0?{}:u);if(e.keep_schedules!==void 0&&typeof e.keep_schedules!="boolean")throw new n(400,"invalid_request","invalid keep_schedules","keep_schedules");return{status:200,body:await $(await l(t,i,!0),{keepSchedules:e.keep_schedules})}}case"run.rename":{const e=f(u);for(const s of Object.keys(e))if(s!=="name")throw new n(400,"invalid_request",`unknown field ${s}`,s);return{status:200,body:await B(await l(t,i,!0),e.name)}}case"run.delete":{const{uploads_pending:e}=await N(await l(t,i,!0,!0));return{status:200,body:{run_id:i,uploads_pending:e}}}case"trace.get":{const e=d.get("format")??void 0;if(e&&e!=="entries")throw new n(400,"invalid_request","unknown trace format","format");const s=await l(t,i);return{status:200,body:await C(i,s.grantee,e)}}default:throw new n(404,"not_found","unknown operation")}}w(X,"handleRunOperation");export{X as handleRunOperation,q as integer};
@@ -1 +1 @@
1
- var P=Object.defineProperty;var i=(t,e)=>P(t,"name",{value:e,configurable:!0});import{isSafeNodeId as S}from"../../../core/canvas/paths.js";import{admitStructuredRequest as T,bindStructuredRequest as N,getPendingStructuredRequestForNode as D,getStructuredRequest as l,settleStructuredRequest as _,toStructuredRequestDTO as f}from"../../../core/canvas/structured-requests.js";import{getNode as k}from"../../../core/canvas/canvas.js";import{ApiError as j}from"../../../api/errors.js";import{handleCreate as E}from"./nodes.js";import{handleMessage as $}from"./messages.js";import{outputSchemaProblem as x,writeStructuredRequestSidecar as R}from"../../../core/runtime/structured-output.js";import{requestBrokerTeardown as C}from"../../../core/runtime/host.js";import{transition as I}from"../../../core/runtime/lifecycle.js";import{subscribeStructuredRequest as M}from"../../structured-requests/notifier.js";import{SYNC_WORK_BUDGET_MS as v}from"../../../api/index.js";import{waitSeconds as F}from"../long-poll-wait.js";function n(t,e,r){throw new j(t,e,r)}i(n,"fail");function B(t){(typeof t!="object"||t===null||Array.isArray(t))&&n(400,"invalid_request","a structured request requires a JSON object");const e=t;(typeof e.request_id!="string"||!S(e.request_id))&&n(400,"request_id_invalid","request_id must use the node-id character rule"),e.mode!=="sync"&&e.mode!=="async"&&n(400,"invalid_request","mode must be sync or async"),typeof e.prompt!="string"&&n(400,"invalid_request","prompt must be a string"),(typeof e.output_schema!="object"||e.output_schema===null||Array.isArray(e.output_schema))&&n(400,"invalid_request","output_schema must be a JSON Schema object");const r=e.target;(typeof r!="object"||r===null)&&n(400,"invalid_request","target is required");const u=r;if(u.kind==="node")(typeof u.node_id!="string"||!S(u.node_id))&&n(400,"invalid_request","target.node_id must use the node-id character rule");else if(u.kind==="new"){(typeof u.create!="object"||u.create===null||Array.isArray(u.create))&&n(400,"invalid_request","target.create must be an object");for(const s of["prompt","output_schema","deadline","root_lifecycle","no_kickoff"])Object.hasOwn(u.create,s)&&n(400,"create_field_forbidden",`target.create may not carry ${s}`)}else n(400,"invalid_request","target.kind must be new or node");return e.work_budget_ms!==void 0&&(!Number.isInteger(e.work_budget_ms)||e.work_budget_ms<=0)&&n(400,"work_budget_invalid","work_budget_ms must be a positive integer"),e.deadline_at!==void 0&&(typeof e.deadline_at!="string"||Number.isNaN(Date.parse(e.deadline_at)))&&n(400,"invalid_request","deadline_at must be an ISO timestamp"),e}i(B,"parseCreate");function L(t,e){const r=t.deadline_at===void 0?null:Date.parse(t.deadline_at),u=t.work_budget_ms===void 0?null:e+t.work_budget_ms,s=r===null?u:u===null?r:Math.min(r,u);return t.mode==="sync"?Math.min(s??e+v,e+v):s}i(L,"deadlineFor");function A(t,e,r=""){return{...t,method:"POST",path:"",params:r===""?{}:{id:r},query:new URLSearchParams,body:e}}i(A,"context");function q(t){return{status:200,body:{admitted:!0,request:f(t)}}}i(q,"terminalAdmission");function m(t){return t!==null&&Date.now()>=t}i(m,"deadlinePassed");function w(t){return q(_(t,{intended:"expired"}).row)}i(w,"expireAdmission");async function O(t,e){let r;const u=new Promise(d=>{r=d}),s=M(t,r);try{return l(t).state==="pending"&&e>0&&await Promise.race([u,new Promise(p=>setTimeout(p,e))]),f(l(t))}finally{s()}}i(O,"waitForRequest");async function Y(t,e){const r=await O(t,Math.max(0,e-Date.now()));return r.state==="pending"?f(_(t,{intended:"expired"}).row):r}i(Y,"waitForTerminal");async function G(t){const e=B(t.body),r=await x(e.output_schema);r!==null&&n(400,"invalid_request",`output_schema is not usable: ${r}`),e.mode==="sync"&&e.target.kind!=="new"&&n(400,"sync_requires_dedicated_node","sync requests require target.kind=new");const u=Date.now(),s=L(e,u);if(m(s))return{status:200,body:{admitted:!1,reason:"work_budget_exhausted"}};let d=null,p="terminal",y=!0;if(e.target.kind==="node"){d=e.target.node_id;const a=k(d);a===null&&n(404,"node_not_found",`unknown node: ${d}`),(a.final_report!==null||a.status==="done"||a.status==="canceled"||a.status==="dead")&&n(409,"node_terminal",`node ${d} is terminal`),D(d)!==null&&n(409,"structured_request_conflict",`node ${d} already has a pending structured request`),p="oneoff",y=!1}if(m(s))return{status:200,body:{admitted:!1,reason:"work_budget_exhausted"}};let b;try{b=T({requestId:e.request_id,mode:e.mode,submission:p,dedicated:y,schema:e.output_schema,deadlineAt:s,nodeId:d,now:Date.now()})}catch(a){const o=String(a);throw(a.code==="ERR_SQLITE_CONSTRAINT_PRIMARYKEY"||o.includes("structured_requests.request_id"))&&n(409,"request_id_in_use",`request_id ${e.request_id} is already in use`),(o.includes("idx_structured_requests_one_pending_node")||o.includes("structured_requests.node_id"))&&n(409,"structured_request_conflict","the target node already has a pending structured request"),a}if(m(s))return w(e.request_id);if(e.target.kind==="new")try{d=(await E(A(t,{...e.target.create,root:!0,root_lifecycle:"terminal",prompt:""}),{},{...s===null?{}:{deadlineAt:new Date(s).toISOString()},beforeBrokerLaunch:i(o=>{if(d=o,m(s))throw new Error("structured request deadline expired before binding");const c=N(e.request_id,o);if(!c.changed||c.row===null||c.row.state!=="pending")throw new Error("structured request bind did not remain pending");d=o,R(c.row)},"beforeBrokerLaunch")})).body.node_id}catch{const o=l(e.request_id),c=o.state==="pending"?_(e.request_id,{intended:"failed",failureReason:o.node_id===null?"node_create_failed":"bind_failed"}).row:o;if(d!==null&&c.node_id===null){const g=k(d);(g?.status==="active"||g?.status==="idle")&&I(d,"cancel",{reason:"stranded"}),await C(d)}return q(c)}else{if(m(s))return w(e.request_id);try{R(b)}catch{return q(_(e.request_id,{intended:"failed",failureReason:"bind_failed"}).row)}}const h=l(e.request_id);if(h.state!=="pending")return q(h);if(m(s))return w(e.request_id);try{await $(A(t,{body:e.prompt,tier:"normal"},d))}catch{return q(_(e.request_id,{intended:"failed",failureReason:"prompt_delivery_failed"}).row)}return e.mode==="async"?{status:202,body:{admitted:!0,request:f(l(e.request_id))}}:{status:200,body:{admitted:!0,request:await Y(e.request_id,s)}}}i(G,"handleCreateStructuredRequest");async function J(t){const e=t.params.request_id,r=F("structured-request.get",t.query),u=l(e);return u===null&&n(404,"structured_request_not_found",`unknown structured request: ${e}`),{status:200,body:r===0?f(u):await O(e,r*1e3)}}i(J,"handleReadStructuredRequest");async function K(t){const e=_(t.params.request_id,{intended:"canceled"});return e.row===null&&n(404,"structured_request_not_found",`unknown structured request: ${t.params.request_id}`),{status:200,body:f(e.row)}}i(K,"handleCancelStructuredRequest");const se=[{method:"POST",pattern:"/v1/structured-requests",handler:G},{method:"GET",pattern:"/v1/structured-requests/:request_id",handler:J},{method:"POST",pattern:"/v1/structured-requests/:request_id/cancel",handler:K}];export{se as structuredRequestRoutes};
1
+ var P=Object.defineProperty;var s=(t,e)=>P(t,"name",{value:e,configurable:!0});import{isSafeNodeId as S}from"../../../core/canvas/paths.js";import{admitStructuredRequest as T,bindStructuredRequest as N,getPendingStructuredRequestForNode as D,getStructuredRequest as l,settleStructuredRequest as _,toStructuredRequestDTO as f}from"../../../core/canvas/structured-requests.js";import{getNode as k}from"../../../core/canvas/canvas.js";import{ApiError as j}from"../../../api/errors.js";import{handleCreate as E}from"./nodes.js";import{handleMessage as $}from"./messages.js";import{outputSchemaProblem as x,writeStructuredRequestSidecar as R}from"../../../core/runtime/structured-output.js";import{requestBrokerTeardown as C}from"../../../core/runtime/host.js";import{transition as I}from"../../../core/runtime/lifecycle.js";import{subscribeStructuredRequest as M}from"../../structured-requests/notifier.js";import{SYNC_WORK_BUDGET_MS as v}from"../../../api/index.js";import{waitSeconds as F}from"../long-poll-wait.js";function n(t,e,r){throw new j(t,e,r)}s(n,"fail");function B(t){(typeof t!="object"||t===null||Array.isArray(t))&&n(400,"invalid_request","a structured request requires a JSON object");const e=t;(typeof e.request_id!="string"||!S(e.request_id))&&n(400,"request_id_invalid","request_id must use the node-id character rule"),e.mode!=="sync"&&e.mode!=="async"&&n(400,"invalid_request","mode must be sync or async"),typeof e.prompt!="string"&&n(400,"invalid_request","prompt must be a string"),(typeof e.output_schema!="object"||e.output_schema===null||Array.isArray(e.output_schema))&&n(400,"invalid_request","output_schema must be a JSON Schema object");const r=e.target;(typeof r!="object"||r===null)&&n(400,"invalid_request","target is required");const a=r;if(a.kind==="node")(typeof a.node_id!="string"||!S(a.node_id))&&n(400,"invalid_request","target.node_id must use the node-id character rule");else if(a.kind==="new"){(typeof a.create!="object"||a.create===null||Array.isArray(a.create))&&n(400,"invalid_request","target.create must be an object");for(const i of["prompt","output_schema","deadline","root_lifecycle","no_kickoff"])Object.hasOwn(a.create,i)&&n(400,"create_field_forbidden",`target.create may not carry ${i}`)}else n(400,"invalid_request","target.kind must be new or node");return e.work_budget_ms!==void 0&&(!Number.isInteger(e.work_budget_ms)||e.work_budget_ms<=0)&&n(400,"work_budget_invalid","work_budget_ms must be a positive integer"),e.deadline_at!==void 0&&(typeof e.deadline_at!="string"||Number.isNaN(Date.parse(e.deadline_at)))&&n(400,"invalid_request","deadline_at must be an ISO timestamp"),e}s(B,"parseCreate");function L(t,e){const r=t.deadline_at===void 0?null:Date.parse(t.deadline_at),a=t.work_budget_ms===void 0?null:e+t.work_budget_ms,i=r===null?a:a===null?r:Math.min(r,a);return t.mode==="sync"?Math.min(i??e+v,e+v):i}s(L,"deadlineFor");function A(t,e,r=""){return{...t,method:"POST",path:"",params:r===""?{}:{id:r},query:new URLSearchParams,body:e}}s(A,"context");async function w(t){return{status:200,body:{admitted:!0,request:f(t)}}}s(w,"terminalAdmission");function m(t){return t!==null&&Date.now()>=t}s(m,"deadlinePassed");async function p(t){return await w((await _(t,{intended:"expired"})).row)}s(p,"expireAdmission");async function O(t,e){let r;const a=new Promise(u=>{r=u}),i=M(t,r);try{return(await l(t)).state==="pending"&&e>0&&await Promise.race([a,new Promise(q=>setTimeout(q,e))]),f(await l(t))}finally{i()}}s(O,"waitForRequest");async function Y(t,e){const r=await O(t,Math.max(0,e-Date.now()));return r.state==="pending"?f((await _(t,{intended:"expired"})).row):r}s(Y,"waitForTerminal");async function G(t){const e=B(t.body),r=await x(e.output_schema);r!==null&&n(400,"invalid_request",`output_schema is not usable: ${r}`),e.mode==="sync"&&e.target.kind!=="new"&&n(400,"sync_requires_dedicated_node","sync requests require target.kind=new");const a=Date.now(),i=L(e,a);if(m(i))return{status:200,body:{admitted:!1,reason:"work_budget_exhausted"}};let u=null,q="terminal",y=!0;if(e.target.kind==="node"){u=e.target.node_id;const d=await k(u);d===null&&n(404,"node_not_found",`unknown node: ${u}`),(d.final_report!==null||d.status==="done"||d.status==="canceled"||d.status==="dead")&&n(409,"node_terminal",`node ${u} is terminal`),await D(u)!==null&&n(409,"structured_request_conflict",`node ${u} already has a pending structured request`),q="oneoff",y=!1}if(m(i))return{status:200,body:{admitted:!1,reason:"work_budget_exhausted"}};let b;try{b=await T({requestId:e.request_id,mode:e.mode,submission:q,dedicated:y,schema:e.output_schema,deadlineAt:i,nodeId:u,now:Date.now()})}catch(d){const o=String(d);throw(d.code==="ERR_SQLITE_CONSTRAINT_PRIMARYKEY"||o.includes("structured_requests.request_id"))&&n(409,"request_id_in_use",`request_id ${e.request_id} is already in use`),(o.includes("idx_structured_requests_one_pending_node")||o.includes("structured_requests.node_id"))&&n(409,"structured_request_conflict","the target node already has a pending structured request"),d}if(m(i))return await p(e.request_id);if(e.target.kind==="new")try{u=(await E(A(t,{...e.target.create,root:!0,root_lifecycle:"terminal",prompt:""}),{},{...i===null?{}:{deadlineAt:new Date(i).toISOString()},beforeBrokerLaunch:s(async o=>{if(u=o,m(i))throw new Error("structured request deadline expired before binding");const c=await N(e.request_id,o);if(!c.changed||c.row===null||c.row.state!=="pending")throw new Error("structured request bind did not remain pending");u=o,R(c.row)},"beforeBrokerLaunch")})).body.node_id}catch{const o=await l(e.request_id),c=o.state==="pending"?(await _(e.request_id,{intended:"failed",failureReason:o.node_id===null?"node_create_failed":"bind_failed"})).row:o;if(u!==null&&c.node_id===null){const g=await k(u);(g?.status==="active"||g?.status==="idle")&&await I(u,"cancel",{reason:"stranded"}),await C(u)}return await w(c)}else{if(m(i))return await p(e.request_id);try{R(b)}catch{return await w((await _(e.request_id,{intended:"failed",failureReason:"bind_failed"})).row)}}const h=await l(e.request_id);if(h.state!=="pending")return await w(h);if(m(i))return await p(e.request_id);try{await $(A(t,{body:e.prompt,tier:"normal"},u))}catch{return await w((await _(e.request_id,{intended:"failed",failureReason:"prompt_delivery_failed"})).row)}return e.mode==="async"?{status:202,body:{admitted:!0,request:f(await l(e.request_id))}}:{status:200,body:{admitted:!0,request:await Y(e.request_id,i)}}}s(G,"handleCreateStructuredRequest");async function J(t){const e=t.params.request_id,r=F("structured-request.get",t.query),a=await l(e);return a===null&&n(404,"structured_request_not_found",`unknown structured request: ${e}`),{status:200,body:r===0?f(a):await O(e,r*1e3)}}s(J,"handleReadStructuredRequest");async function K(t){const e=await _(t.params.request_id,{intended:"canceled"});return e.row===null&&n(404,"structured_request_not_found",`unknown structured request: ${t.params.request_id}`),{status:200,body:f(e.row)}}s(K,"handleCancelStructuredRequest");const ie=[{method:"POST",pattern:"/v1/structured-requests",handler:G},{method:"GET",pattern:"/v1/structured-requests/:request_id",handler:J},{method:"POST",pattern:"/v1/structured-requests/:request_id/cancel",handler:K}];export{ie as structuredRequestRoutes};
@@ -1 +1 @@
1
- var l=Object.defineProperty;var p=(n,i)=>l(n,"name",{value:i,configurable:!0});import{ApiError as e}from"../../../api/index.js";import{getNode as a,subscribe as b,subscriptionsOf as f,unsubscribe as h}from"../../../core/canvas/canvas.js";import{toSubscriptionDTO as g}from"../map.js";function u(n){if(a(n)===null)throw new e(404,"node_not_found",`unknown node: ${n}`)}p(u,"requireNode");function w(n){const i=n.params.id,t=n.body??{},r=t.target;if(typeof r!="string"||r==="")throw new e(400,"invalid_request","subscribe body requires a `target` node id");if(r===i)throw new e(422,"unprocessable","a node cannot subscribe to itself");if(u(i),u(r),n.principal.class==="broker"){const o=a(i),c=a(r);if(o.grantee!==n.principal.app||c.grantee!==n.principal.app||o.run_id!==c.run_id||n.principal.run!==null&&o.run_id!==n.principal.run)throw new e(403,"other_app_run","subscriptions must stay within the calling app run")}const s=t.active??!0;b(i,r,s);const d=f(i).find(o=>o.node_id===r);if(d===void 0)throw new e(500,"internal","subscription edge vanished after write");return{status:200,body:g(d)}}p(w,"handleSubscribe");function _(n){const i=n.params.id,t=n.params.target;if(u(i),n.principal.class==="broker"){const r=a(i),s=a(t);if(r.grantee!==n.principal.app||n.principal.run!==null&&r.run_id!==n.principal.run||s&&(s.grantee!==r.grantee||s.run_id!==r.run_id))throw new e(403,"other_app_run","subscriptions must stay within the calling app run")}return h(i,t),{status:204}}p(_,"handleUnsubscribe");const E=[{method:"POST",pattern:"/v1/nodes/:id/subscriptions",handler:w},{method:"DELETE",pattern:"/v1/nodes/:id/subscriptions/:target",handler:_}];export{E as subscriptionRoutes};
1
+ var l=Object.defineProperty;var p=(n,r)=>l(n,"name",{value:r,configurable:!0});import{ApiError as t}from"../../../api/index.js";import{getNode as o,subscribe as w,subscriptionsOf as b,unsubscribe as f}from"../../../core/canvas/canvas.js";import{toSubscriptionDTO as h}from"../map.js";async function u(n){if(await o(n)===null)throw new t(404,"node_not_found",`unknown node: ${n}`)}p(u,"requireNode");async function g(n){const r=n.params.id,a=n.body??{},i=a.target;if(typeof i!="string"||i==="")throw new t(400,"invalid_request","subscribe body requires a `target` node id");if(i===r)throw new t(422,"unprocessable","a node cannot subscribe to itself");if(await u(r),await u(i),n.principal.class==="broker"){const s=await o(r),c=await o(i);if(s.grantee!==n.principal.app||c.grantee!==n.principal.app||s.run_id!==c.run_id||n.principal.run!==null&&s.run_id!==n.principal.run)throw new t(403,"other_app_run","subscriptions must stay within the calling app run")}const e=a.active??!0;await w(r,i,e);const d=(await b(r)).find(s=>s.node_id===i);if(d===void 0)throw new t(500,"internal","subscription edge vanished after write");return{status:200,body:h(d)}}p(g,"handleSubscribe");async function _(n){const r=n.params.id,a=n.params.target;if(await u(r),n.principal.class==="broker"){const i=await o(r),e=await o(a);if(i.grantee!==n.principal.app||n.principal.run!==null&&i.run_id!==n.principal.run||e&&(e.grantee!==i.grantee||e.run_id!==i.run_id))throw new t(403,"other_app_run","subscriptions must stay within the calling app run")}return await f(r,a),{status:204}}p(_,"handleUnsubscribe");const E=[{method:"POST",pattern:"/v1/nodes/:id/subscriptions",handler:g},{method:"DELETE",pattern:"/v1/nodes/:id/subscriptions/:target",handler:_}];export{E as subscriptionRoutes};
@@ -1 +1 @@
1
- var h=Object.defineProperty;var s=(e,a)=>h(e,"name",{value:a,configurable:!0});import{isAbsolute as w,resolve as _}from"node:path";import{RunError as n}from"../../../core/runs/operations.js";import{invalidStorageName as m,storageClient as l,StorageRefused as y,UPLOAD_MAX_BYTES as g}from"../../../core/storage/client.js";import{serveDownload as b}from"../../../core/storage/download.js";import{createShare as q,deleteOwnShare as v,listOwnShares as A}from"../../../core/storage/shares.js";import{getUpload as S,insertUpload as k,uploadUseAt as x}from"../../../core/storage/tables.js";import{requireRun as z}from"../router.js";const C=new Set(["upload.create","attachment.link","file.download","share.create","share.list","share.delete"]);function c(e){if(!e||typeof e!="object"||Array.isArray(e))throw new n(400,"invalid_request","a JSON object is required");return e}s(c,"object");function f(e){return{app:e.grantee,resolved:e.resolved,launched:null}}s(f,"fileCaller");const O=/^[A-Za-z0-9][A-Za-z0-9!#$&^_.+-]{0,126}\/[A-Za-z0-9][A-Za-z0-9!#$&^_.+-]{0,126}(?:\s*;.{0,200})?$/;async function T(e,a){const i=c(a);for(const p of Object.keys(i))if(!["name","media_type","size"].includes(p))throw new n(400,"invalid_request",`unknown field ${p}`,p);const{name:r,media_type:o,size:t}=i;if(typeof t!="number"||!Number.isSafeInteger(t)||t<0)throw new n(400,"invalid_request","size must be a non-negative integer","size");if(t>g)throw new n(400,"invalid_request","size exceeds 100 MiB","size");if(typeof r!="string")throw new n(400,"invalid_request","name is required","name");const d=m(r);if(d)throw new n(400,"invalid_request",d,"name");if(typeof o!="string"||!O.test(o))throw new n(400,"invalid_request","media_type must be a media type","media_type");const u=await l().createUpload({name:r,media_type:o,size:t});return k({upload_id:u.upload_id,grantee:e.grantee,name:r,media_type:o,size:t,created_at:new Date().toISOString()}),{upload_id:u.upload_id,url:u.url,upload_link:u.upload_link,expires_at:u.expires_at}}s(T,"uploadCreate");async function D(e,a){if(!a)throw new n(400,"invalid_request","path is required","path");if(!w(a))throw new n(400,"invalid_request","path must be absolute","path");const i=x(_(a)),r=s(()=>new n(404,"not_found","no upload is recorded at that path"),"missing");if(!i)throw r();try{z(e,i.run_id)}catch(t){throw t instanceof n&&t.code==="not_found"?r():t}const o=S(i.upload_id);if(!o||o.delete_pending_since)throw r();try{return await l().signDownload(i.upload_id)}catch(t){throw t instanceof y?r():t}}s(D,"attachmentLink");async function M(e,a,i,r,o){switch(e.name){case"upload.create":return{status:201,body:await T(a,o)};case"attachment.link":return{status:200,body:await D(a,r.get("path"))};case"share.create":{const t=c(o);for(const d of Object.keys(t))if(!["path","expires_at"].includes(d))throw new n(400,"invalid_request",`unknown field ${d}`,d);return{status:201,body:await q(f(a),{path:t.path,expires_at:t.expires_at})}}case"share.list":return{status:200,body:A(a.grantee)};case"share.delete":return{status:200,body:await v(a.grantee,i.share_id)};default:throw new n(404,"not_found","unknown operation")}}s(M,"handleTransferOperation");function P(e,a,i,r){return b(e,a,f(i),r.get("path"))}s(P,"handleTransferDownload");export{C as TRANSFER_OPERATIONS,f as fileCaller,P as handleTransferDownload,M as handleTransferOperation};
1
+ var w=Object.defineProperty;var s=(e,a)=>w(e,"name",{value:a,configurable:!0});import{isAbsolute as h,resolve as _}from"node:path";import{RunError as n}from"../../../core/runs/operations.js";import{invalidStorageName as m,storageClient as l,StorageRefused as y,UPLOAD_MAX_BYTES as g}from"../../../core/storage/client.js";import{serveDownload as b}from"../../../core/storage/download.js";import{createShare as q,deleteOwnShare as v,listOwnShares as A}from"../../../core/storage/shares.js";import{getUpload as S,insertUpload as k,uploadUseAt as x}from"../../../core/storage/tables.js";import{requireRun as z}from"../router.js";const C=new Set(["upload.create","attachment.link","file.download","share.create","share.list","share.delete"]);function c(e){if(!e||typeof e!="object"||Array.isArray(e))throw new n(400,"invalid_request","a JSON object is required");return e}s(c,"object");function f(e){return{app:e.grantee,resolved:e.resolved,launched:null}}s(f,"fileCaller");const O=/^[A-Za-z0-9][A-Za-z0-9!#$&^_.+-]{0,126}\/[A-Za-z0-9][A-Za-z0-9!#$&^_.+-]{0,126}(?:\s*;.{0,200})?$/;async function T(e,a){const i=c(a);for(const p of Object.keys(i))if(!["name","media_type","size"].includes(p))throw new n(400,"invalid_request",`unknown field ${p}`,p);const{name:r,media_type:o,size:t}=i;if(typeof t!="number"||!Number.isSafeInteger(t)||t<0)throw new n(400,"invalid_request","size must be a non-negative integer","size");if(t>g)throw new n(400,"invalid_request","size exceeds 100 MiB","size");if(typeof r!="string")throw new n(400,"invalid_request","name is required","name");const d=m(r);if(d)throw new n(400,"invalid_request",d,"name");if(typeof o!="string"||!O.test(o))throw new n(400,"invalid_request","media_type must be a media type","media_type");const u=await l().createUpload({name:r,media_type:o,size:t});return await k({upload_id:u.upload_id,grantee:e.grantee,name:r,media_type:o,size:t,created_at:new Date().toISOString()}),{upload_id:u.upload_id,url:u.url,upload_link:u.upload_link,expires_at:u.expires_at}}s(T,"uploadCreate");async function D(e,a){if(!a)throw new n(400,"invalid_request","path is required","path");if(!h(a))throw new n(400,"invalid_request","path must be absolute","path");const i=await x(_(a)),r=s(()=>new n(404,"not_found","no upload is recorded at that path"),"missing");if(!i)throw r();try{await z(e,i.run_id)}catch(t){throw t instanceof n&&t.code==="not_found"?r():t}const o=await S(i.upload_id);if(!o||o.delete_pending_since)throw r();try{return await l().signDownload(i.upload_id)}catch(t){throw t instanceof y?r():t}}s(D,"attachmentLink");async function M(e,a,i,r,o){switch(e.name){case"upload.create":return{status:201,body:await T(a,o)};case"attachment.link":return{status:200,body:await D(a,r.get("path"))};case"share.create":{const t=c(o);for(const d of Object.keys(t))if(!["path","expires_at"].includes(d))throw new n(400,"invalid_request",`unknown field ${d}`,d);return{status:201,body:await q(f(a),{path:t.path,expires_at:t.expires_at})}}case"share.list":return{status:200,body:await A(a.grantee)};case"share.delete":return{status:200,body:await v(a.grantee,i.share_id)};default:throw new n(404,"not_found","unknown operation")}}s(M,"handleTransferOperation");function P(e,a,i,r){return b(e,a,f(i),r.get("path"))}s(P,"handleTransferDownload");export{C as TRANSFER_OPERATIONS,f as fileCaller,P as handleTransferDownload,M as handleTransferOperation};
@@ -52,7 +52,7 @@ export declare function toGraphNodeDTO(row: {
52
52
  fault: NodeRow['fault'];
53
53
  streaming: boolean;
54
54
  }): GraphNodeDTO;
55
- export declare function toNodeSummaryDTO(row: NodeRow, paused?: boolean): NodeSummaryDTO;
55
+ export declare function toNodeSummaryDTO(row: NodeRow, paused?: boolean): Promise<NodeSummaryDTO>;
56
56
  /** The subscription/child edges a detail projection needs. The handler gathers
57
57
  * these from `subscriptionsOf`/`subscribersOf` + a children query and passes
58
58
  * them in, so this module stays a pure projection with no db reach. */
@@ -68,14 +68,14 @@ export interface NodeEdgesInput {
68
68
  export declare function toNodeEdgesDTO(meta: NodeMeta, edges: NodeEdgesInput): NodeEdgesDTO;
69
69
  /** Absolute filesystem paths for a node (absorbs the `paths` read).
70
70
  * App assignment comes from the authoritative node row. */
71
- export declare function toNodePathsDTO(nodeId: string, grantee: string): NodePathsDTO;
71
+ export declare function toNodePathsDTO(nodeId: string, grantee: string): Promise<NodePathsDTO>;
72
72
  /** Project a node's managed git worktree, if any. */
73
73
  export declare function toNodeWorktreeDTO(w: ManagedWorktree): NodeWorktreeDTO;
74
74
  /** Project the hydrated node view (`getNode` → `NodeMeta`) into a detail DTO.
75
75
  * The summary fields come from the meta's runtime half (hydrated from the
76
76
  * authoritative row); the identity extras (description/cycles/session) come
77
77
  * from the meta's identity half. Edges are gathered by the handler. */
78
- export declare function toNodeDetailDTO(meta: NodeMeta, edges: NodeEdgesInput): NodeDetailDTO;
78
+ export declare function toNodeDetailDTO(meta: NodeMeta, edges: NodeEdgesInput): Promise<NodeDetailDTO>;
79
79
  /** Project a `reviveNode` result. `revived` is true only when a fresh launch
80
80
  * actually happened — the double-revive no-op (already-alive) returns without a
81
81
  * `launch` handle, so its absence is the "nothing relaunched" signal. `status`
@@ -1,2 +1,2 @@
1
- var g=Object.defineProperty;var r=(e,t)=>g(e,"name",{value:t,configurable:!0});import{join as b}from"node:path";import{readOutputResult as y}from"../../core/runtime/structured-output.js";import{ReviewOperationError as _}from"../../core/review/types.js";import{cronSinkDisplay as x}from"../../core/canvas/crons.js";import{isProfilePaused as c,profileDir as O,sanitizeProfileMetadata as D}from"../../core/profiles/manifest.js";import{nodeMetaPath as T,transcriptPath as E,viewSocketPath as S}from"../../core/canvas/paths.js";import{appForNode as f,contextDir as A,nodeAgentDir as R}from"../../core/canvas/node-agent-paths.js";import{readControllerWait as p}from"../../core/canvas/waits.js";import{FinalizationError as z}from"../../core/feed/feed.js";import{NodeIdConflictError as N}from"../../core/runtime/nodes.js";import{ScopeDeniedError as C}from"../../core/scopes.js";import{isBeneathRefusal as j}from"../../core/spaces/open-beneath.js";import{CrtrError as a}from"../../core/errors.js";import{WorktreeError as q}from"../../core/worktree.js";import{ApiError as I}from"../../api/errors.js";import{RunError as s}from"../../core/runs/operations.js";import{ExitCode as o}from"../../types.js";function pe(e,t){const{report:n}=e;return{stores:n.stores.map(i=>({root:i.root,owner:{...i.owner},docs:i.docs,...i.skipped===void 0?{}:{skipped:i.skipped}})),counts:n.counts,rewrites:n.rewrites,dropped_fields:n.droppedFields,skipped:n.skipped,resolutions:n.resolutions.map(i=>({kind:i.kind,message:i.message,paths:i.paths})),blockers:e.blockers.map(i=>({kind:i.kind,message:i.message,paths:i.paths})),dryRun:e.dryRun,pending:e.pending,resumed:t.resumed,...t.resumeError===void 0?{}:{resume_error:t.resumeError}}}r(pe,"toMigrateStateDTO");function F(e,t){try{return y(e,t)??null}catch{return null}}r(F,"readStructuredResult");function P(e){return e.outcome_at===null||e.outcome_at===void 0||e.outcome_kind===null||e.outcome_kind===void 0||e.outcome_reason===null||e.outcome_reason===void 0?null:{kind:e.outcome_kind,reason:e.outcome_reason,settled_at:e.outcome_at}}r(P,"toNodeOutcomeSummaryDTO");function m(e){if(e.outcome_at===null||e.outcome_at===void 0||e.outcome_kind===null||e.outcome_kind===void 0||e.outcome_reason===null||e.outcome_reason===void 0)return null;let t=null;if(e.outcome_detail_json!==null&&e.outcome_detail_json!==void 0)try{t=JSON.parse(e.outcome_detail_json)}catch{t=null}const n=e.final_report??null,i={node_id:e.node_id,revision:e.outcome_revision??1,settled_at:e.outcome_at,final_report:n===null?null:`${e.node_id}/${n}`,structured_result:e.outcome_kind==="result"?F(e.node_id,e.grantee):null,detail:t};return e.outcome_kind==="result"?{...i,kind:"result",reason:e.outcome_reason,declined:null}:e.outcome_reason==="declined"?{...i,kind:"failure",reason:"declined",declined:t?.declined??null}:{...i,kind:"failure",reason:e.outcome_reason,declined:null}}r(m,"toNodeOutcomeDTO");function me(e){const t=m(e);return t===null||t.reason==="parked"?null:t.kind==="result"||t.reason==="finished"?{...t,kind:"result",reason:"finalized",declined:null}:t.reason==="declined"?{...t,reason:"declined",details:t.declined}:t.reason==="deadline_exceeded"?{...t,reason:"deadline_exceeded",declined:null}:t.reason==="cap_exhausted"?{...t,reason:"cap_exhausted",declined:null}:t.reason==="closed"||t.reason==="stranded"||t.reason==="retired"?{...t,reason:"canceled",declined:null}:{...t,reason:"runtime_error",declined:null,details:{crouter_reason:t.reason}}}r(me,"toRunOutcomeDTO");function ve(e){const t=e.lastFailure;return{node_id:e.nodeId,state:e.state,action:e.actionName,attempt:e.attempt,next_attempt_at:e.nextAttemptAt===0?null:new Date(e.nextAttemptAt).toISOString(),accepted_at:e.acceptedAt===null?null:new Date(e.acceptedAt).toISOString(),permanent_failed_at:e.permanentFailedAt===null?null:new Date(e.permanentFailedAt).toISOString(),last_failure:t===null?null:{kind:t.kind,...t.exitCode===void 0?{}:{exit_code:t.exitCode},...t.signal===void 0?{}:{signal:t.signal},...t.message===void 0?{}:{message:t.message}},created_at:new Date(e.createdAt).toISOString(),updated_at:new Date(e.updatedAt).toISOString()}}r(ve,"toOutcomeDeliveryDTO");function ke(e){return{node_id:e.node_id,name:e.name,description:e.description,cycles:e.cycles,kind:e.kind,status:e.status,frozen_at:e.frozen_at,pi_pid:e.pi_pid,telemetry_context_tokens:e.telemetry_context_tokens,telemetry_last_activity:e.telemetry_last_activity,fault:e.fault&&e.fault.link!=="broker\u2194crtrd"?{...e.fault,link:e.fault.link}:null,streaming:e.streaming}}r(ke,"toGraphNodeDTO");function he(e,t=c(e.profile_id)){return{node_id:e.node_id,name:e.name,description:e.description,cycles:e.cycles,kind:e.kind,mode:e.mode,lifecycle:e.lifecycle,status:e.status,cwd:e.cwd,host_kind:e.host_kind,profile_id:e.profile_id,scopes:e.scopes,isolated:e.isolated,grantee:e.grantee??f(e.node_id),profile_paused:t,parent:e.parent,created:e.created,intent:e.intent,waiting_for:p(e.node_id)?.controllerId??null,frozen_at:e.frozen_at??null,terminal_reason:e.terminal_reason??null,pi_pid:e.pi_pid,pi_pid_identity:e.pi_pid_identity,window:e.window,tmux_session:e.tmux_session,pane:e.pane,final_report:e.final_report??null,finalized_at:e.finalized_at??null,deadline_at:e.deadline_at??null,telemetry_tokens_in:e.telemetry_tokens_in??null,telemetry_context_tokens:e.telemetry_context_tokens??null,telemetry_last_activity:e.telemetry_last_activity??null,telemetry_updated_at:e.telemetry_updated_at??null,outcome:P(e),fault:e.fault&&e.fault.link!=="broker\u2194crtrd"?{...e.fault,link:e.fault.link}:null,streaming:e.streaming??!1}}r(he,"toNodeSummaryDTO");function U(e,t){return{parent:e.parent??null,spawned_by:e.spawned_by??null,subscribes_to:t.subscribesTo.map(n=>n.node_id),subscribers:t.subscribers.map(n=>n.node_id),children:[...t.children]}}r(U,"toNodeEdgesDTO");function G(e,t){return{node_dir:R(e,t),context_dir:A(e,t),meta_path:T(e),transcript_path:E(e),view_socket:S(e)}}r(G,"toNodePathsDTO");function M(e){const t={state:e.state,path:e.path,branch:e.branch,repo_root:e.repo_root,base_ref:e.base_ref,base_sha:e.base_sha,created:e.created};return e.cleanup!==void 0&&(t.cleanup=e.cleanup),e.closed!==void 0&&(t.closed=e.closed),e.abandoned!==void 0&&(t.abandoned={...e.abandoned}),t}r(M,"toNodeWorktreeDTO");function ge(e,t){const n=f(e.node_id),i={node_id:e.node_id,name:e.name,kind:e.kind,mode:e.mode,lifecycle:e.lifecycle,status:e.status,cwd:e.cwd,host_kind:e.host_kind??null,profile_id:e.profile_id??null,scopes:e.scopes??null,isolated:e.isolated===!0,grantee:n,profile_paused:c(e.profile_id),parent:e.parent??null,created:e.created,intent:e.intent??null,waiting_for:p(e.node_id)?.controllerId??null,frozen_at:e.frozen_at??null,terminal_reason:e.terminal_reason??null,pi_pid:e.pi_pid??null,pi_pid_identity:e.pi_pid_identity??null,window:e.window??null,tmux_session:e.tmux_session??null,pane:e.pane??null,final_report:e.final_report??null,finalized_at:e.finalized_at??null,deadline_at:e.deadline_at??null,telemetry_tokens_in:e.telemetry_tokens_in??null,telemetry_context_tokens:e.telemetry_context_tokens??null,telemetry_last_activity:e.telemetry_last_activity??null,telemetry_updated_at:e.telemetry_updated_at??null,outcome:m(e),fault:e.fault&&e.fault.link!=="broker\u2194crtrd"?{...e.fault,link:e.fault.link}:null,streaming:e.streaming??!1,creator:e.creator??null,edges:U(e,t),paths:G(e.node_id,n)};return e.description!==void 0&&(i.description=e.description),e.title!==void 0&&(i.title=e.title),e.icon!==void 0&&(i.icon=e.icon),e.cycles!==void 0&&(i.cycles=e.cycles),i.context_tokens=e.telemetry_context_tokens??e.telemetry_tokens_in??null,e.pi_session_id!==void 0&&(i.pi_session_id=e.pi_session_id??null),i.model_override=e.model_override??null,e.pi_session_file!==void 0&&(i.pi_session_file=e.pi_session_file??null),e.review_binding!==void 0&&(i.review_binding=e.review_binding===null?null:{...e.review_binding.kind===void 0?{}:{kind:e.review_binding.kind},review_id:e.review_binding.review_id,origin_node_id:e.review_binding.origin_node_id,branch_file:e.review_binding.branch_file,target_file:e.review_binding.target_file}),e.managed_worktree!=null&&(i.worktree=M(e.managed_worktree)),i}r(ge,"toNodeDetailDTO");function be(e,t,n,i){return{node_id:e,revived:t.launch!==void 0,resumed:t.resumed,status:n,outcome:t.outcome,ready:i}}r(be,"toReviveResultDTO");function ye(e){return{root:e.root,closed:[...e.closed],spared:[...e.spared]}}r(ye,"toCloseResultDTO");function xe(e,t,n){const i={report:e.report,notified:[...e.deliveredTo]};return t!==void 0&&(i.transitioned=t),n!==void 0&&(i.worktree_auto_dropped=!0,i.worktree_auto_dropped_path=n),i}r(xe,"toReportResultDTO");function Oe(e){return{node_id:e.node_id,active:e.active,created:e.created}}r(Oe,"toSubscriptionDTO");function W(e){if(e===null||e==="")return[];try{const t=JSON.parse(e);return typeof t=="object"&&t!==null&&!Array.isArray(t)?Object.keys(t):[]}catch{return[]}}r(W,"envKeys");function De(e,t){return{cron_id:e.cron_id,name:e.name,created_by:e.created_by,command:e.command,grant_id:e.grant_id,scopes:e.scopes,origin_run_id:e.origin_run_id,isolated:e.isolated,fire_at:e.fire_at,recur:e.recur,tz:e.tz,expires_at:e.expires_at,anchor_node:e.anchor_node,cancel_on_wake:e.cancel_on_wake,cwd:e.cwd,profile:e.profile,scope:e.scope,env_keys:W(e.env_json),run_timeout_s:e.run_timeout_s,overlap:e.overlap,on_output:e.on_output,sink:x(e.sink),tier:e.tier,state:e.state,held:e.held,run_state:e.run_state,last_run:t==null?null:{finished:t.finished,exit_code:t.exit_code,delivered:t.delivered},created:e.created,updated:e.updated}}r(De,"toCronDTO");function Te(e){return{run_id:e.run_id,started:e.started,finished:e.finished,duration_ms:e.duration_ms,exit_code:e.exit_code,stdout_head:e.stdout_head,stderr_head:e.stderr_head,delivered:e.delivered}}r(Te,"toCronRunDTO");function Ee(e){return{id:e.profileId,app:e.manifest.grantee??"app:terminal",name:e.manifest.name,projects:e.manifest.projects.map(t=>({...t})),delivery_limits:{...e.manifest.delivery_limits},paused_at:e.manifest.paused_at,default_kind:e.manifest.default_kind??"general",metadata:D(e.manifest.metadata),default_dir:null,created_at:e.manifest.created_at,last_used_at:e.manifest.last_used_at,profile_path:O(e.profileId)}}r(Ee,"toProfileDTO");function v(e,t={}){const n={review_id:e.review_id,origin_kind:e.origin_kind,origin_node_id:e.origin_node_id,review_dir:e.review_dir,companion_node_id:e.companion_node_id,file:e.file,state:e.state,created:e.created,source_missing:e.source_missing,anchor_base_sha256:e.anchor_base_sha256};return e.document_name!==null&&(n.document=e.document_name),e.opened_at!==null&&(n.opened_at=e.opened_at),e.submit_requested_at!==null&&(n.submit_requested_at=e.submit_requested_at),e.approved_at!==null&&(n.approved_at=e.approved_at),e.changed!==null&&(n.changed=e.changed),e.comments_total!==null&&(n.comments_total=e.comments_total),e.comments_unresolved!==null&&(n.comments_unresolved=e.comments_unresolved),e.canceled_at!==null&&(n.canceled_at=e.canceled_at),e.cancel_reason!==null&&(n.cancel_reason=e.cancel_reason),e.cancel_actor!==null&&(n.cancel_actor=e.cancel_actor),t.result_path!==void 0&&(n.result_path=t.result_path),e.delivery_error!==null&&(n.delivery_error=e.delivery_error),e.projection_error!==null&&(n.projection_error=e.projection_error),n}r(v,"toReviewDTO");function Se(e){return{comment_id:e.comment_id,review_id:e.review_id,status:e.status,revision:e.revision,text:e.text,anchor:{...e.anchor},anchor_state:e.anchor_state,anchor_line_text:e.anchor_line_text,anchor_doc_hash:e.anchor_doc_hash,author:{kind:e.author.kind,...e.author.node_id===null?{}:{node_id:e.author.node_id}},updated_by:{kind:e.updated_by.kind,...e.updated_by.node_id===null?{}:{node_id:e.updated_by.node_id}},created_at:e.created_at,updated_at:e.updated_at,...e.resolved_at===null?{}:{resolved_at:e.resolved_at},...e.deleted_at===null?{}:{deleted_at:e.deleted_at},created_seq:e.created_seq}}r(Se,"toReviewCommentDTO");function B(e){return{id:e.id,quote:e.quote,...e.context===void 0?{}:{context:e.context},note:e.note,status:e.status,created_at:e.createdAt,...e.resolvedAt===void 0?{}:{resolved_at:e.resolvedAt}}}r(B,"toPageFeedbackCommentDTO");function Ae(e){return{companion_node_id:e.companionNodeId??null,open_count:e.comments.filter(t=>t.status==="open").length,comments:e.comments.map(B)}}r(Ae,"toPageFeedbackDTO");function Re(e){return{seq:e.seq,review_id:e.review_id,comment_id:e.comment_id,kind:e.kind,state_change:e.state_change===1,revision_after:e.revision_after,actor:{kind:e.actor.kind,...e.actor.node_id===null?{}:{node_id:e.actor.node_id}},at:e.at,operation_id:e.operation_id,...e.payload===void 0?{}:{payload:e.payload}}}r(Re,"toReviewCommentEventDTO");function ze(e){return{file:e.file,submitted:e.submitted,approved:e.approved,comments:e.comments.map(n=>({...n})),submittedAt:e.submittedAt,savedAt:e.savedAt,reviewId:e.review_id,changed:e.changed,baselineSha256:e.baseline_sha256,approvedSha256:e.approved_sha256,companionNodeId:e.companion_node_id,commentsTotal:e.comments_total,commentsUnresolved:e.comments_unresolved}}r(ze,"toFeedbackResultDTO");const L=!0,$=Object.freeze({review_origin_missing:{status:400,code:"review_origin_unavailable"},review_origin_unforkable:{status:400,code:"review_origin_unavailable"},review_branch_unavailable:{status:409,code:"review_branch_unavailable"},branch_lost:{status:409,code:"review_branch_unavailable"},review_companion_unbound:{status:409,code:"review_companion_unbound"},review_bridge_unsubscribed:{status:409,code:"review_bridge_unavailable"},review_target_unreviewable:{status:400,code:"review_file_unreadable"},source_unreadable:{status:409,code:"review_source_unreadable"},delivery_unroutable:{status:409,code:"review_delivery_unroutable"},unknown_review:{status:404,code:"unknown_review"},review_terminal:{status:409,code:"review_terminal_conflict"},review_required:{status:400,code:"review_required"},stale_document:{status:409,code:"stale_document"},stale_revision:{status:409,code:"stale_revision"},unknown_comment:{status:404,code:"unknown_comment"},comment_deleted:{status:409,code:"comment_deleted"},invalid_anchor:{status:400,code:"invalid_anchor"},anchor_out_of_range:{status:400,code:"anchor_out_of_range"},text_too_long:{status:400,code:"text_too_long"},comment_limit_reached:{status:409,code:"comment_limit_reached"},stale_comment:{status:409,code:"stale_comment"},range_batch_incomplete:{status:409,code:"range_batch_incomplete"},range_batch_stale:{status:409,code:"range_batch_stale"}});function K(e){const t=k(e);if(typeof t=="object"&&t!==null&&typeof t.status=="number"&&typeof t.code=="string")return{status:t.status,code:t.code};if(t instanceof z)return t.code==="unknown_node"?{status:404,code:"node_not_found"}:t.code==="already_finalized"?{status:409,code:"already_finalized"}:{status:409,code:"finalization_forbidden"};if(t instanceof N)return{status:409,code:"node_id_exists"};if(t instanceof C)return{status:403,code:"scope_denied"};if(j(t))return{status:400,code:"invalid_request"};if(t instanceof _)return $[t.code];if(t instanceof a)return["kind_owned","name_taken","hop_limit","not_a_queue"].includes(t.code)?{status:409,code:t.code}:t.code==="invalid_publish_token"?{status:401,code:t.code}:t.code==="forbidden"||t.code==="argv_forbidden"||t.code==="scope_missing"?{status:403,code:t.code}:{status:J(t.exitCode),code:t.code};if(t instanceof Error){const n=t.message;if(/unknown node/i.test(n))return{status:404,code:"node_not_found"};if(/finalization latch/i.test(n))return{status:409,code:"already_finalized"};if(/illegal lifecycle transition/i.test(n))return{status:409,code:"illegal_transition"}}return{status:500,code:"internal"}}r(K,"errorToStatus");function k(e){if(!(e instanceof q))return e;const t=e.code==="unknown_node"?o.NOT_FOUND:o.GENERAL,n={error:e.code,message:e.message,next:e.next};return e.detail!==void 0&&(n.received=e.detail),new a(e.code,e.message,t,n)}r(k,"normalizeThrow");function V(e){if(e.code!=="review_terminal")return e.detail;const{review:t,...n}=e.detail;return{...n,review:H(t)}}r(V,"reviewErrorDetails");function H(e){return e.state!=="approved"?v(e):v(e,{result_path:b(e.review_dir,"result.json")})}r(H,"terminalConflictReviewDTO");function J(e){switch(e){case o.NOT_FOUND:return 404;case o.USAGE:return 400;case o.AMBIGUOUS:return 400;case o.NETWORK:return 503;case o.GENERAL:return 400;default:return 500}}r(J,"statusForExitCode");function Q(e){const n=(e instanceof Error?e.message:String(e)).split(`
1
+ var g=Object.defineProperty;var r=(e,t)=>g(e,"name",{value:t,configurable:!0});import{join as b}from"node:path";import{readOutputResult as y}from"../../core/runtime/structured-output.js";import{ReviewOperationError as _}from"../../core/review/types.js";import{cronSinkDisplay as x}from"../../core/canvas/crons.js";import{isProfilePaused as c,profileDir as O,sanitizeProfileMetadata as D}from"../../core/profiles/manifest.js";import{nodeMetaPath as T,transcriptPath as E,viewSocketPath as S}from"../../core/canvas/paths.js";import{appForNode as f,contextDir as A,nodeAgentDir as R}from"../../core/canvas/node-agent-paths.js";import{readControllerWait as p}from"../../core/canvas/waits.js";import{FinalizationError as z}from"../../core/feed/feed.js";import{NodeIdConflictError as N}from"../../core/runtime/nodes.js";import{ScopeDeniedError as C}from"../../core/scopes.js";import{isBeneathRefusal as j}from"../../core/spaces/open-beneath.js";import{CrtrError as a}from"../../core/errors.js";import{WorktreeError as q}from"../../core/worktree.js";import{ApiError as I}from"../../api/errors.js";import{RunError as s}from"../../core/runs/operations.js";import{ExitCode as o}from"../../types.js";function pe(e,t){const{report:n}=e;return{stores:n.stores.map(i=>({root:i.root,owner:{...i.owner},docs:i.docs,...i.skipped===void 0?{}:{skipped:i.skipped}})),counts:n.counts,rewrites:n.rewrites,dropped_fields:n.droppedFields,skipped:n.skipped,resolutions:n.resolutions.map(i=>({kind:i.kind,message:i.message,paths:i.paths})),blockers:e.blockers.map(i=>({kind:i.kind,message:i.message,paths:i.paths})),dryRun:e.dryRun,pending:e.pending,resumed:t.resumed,...t.resumeError===void 0?{}:{resume_error:t.resumeError}}}r(pe,"toMigrateStateDTO");function F(e,t){try{return y(e,t)??null}catch{return null}}r(F,"readStructuredResult");function P(e){return e.outcome_at===null||e.outcome_at===void 0||e.outcome_kind===null||e.outcome_kind===void 0||e.outcome_reason===null||e.outcome_reason===void 0?null:{kind:e.outcome_kind,reason:e.outcome_reason,settled_at:e.outcome_at}}r(P,"toNodeOutcomeSummaryDTO");function m(e){if(e.outcome_at===null||e.outcome_at===void 0||e.outcome_kind===null||e.outcome_kind===void 0||e.outcome_reason===null||e.outcome_reason===void 0)return null;let t=null;if(e.outcome_detail_json!==null&&e.outcome_detail_json!==void 0)try{t=JSON.parse(e.outcome_detail_json)}catch{t=null}const n=e.final_report??null,i={node_id:e.node_id,revision:e.outcome_revision??1,settled_at:e.outcome_at,final_report:n===null?null:`${e.node_id}/${n}`,structured_result:e.outcome_kind==="result"?F(e.node_id,e.grantee):null,detail:t};return e.outcome_kind==="result"?{...i,kind:"result",reason:e.outcome_reason,declined:null}:e.outcome_reason==="declined"?{...i,kind:"failure",reason:"declined",declined:t?.declined??null}:{...i,kind:"failure",reason:e.outcome_reason,declined:null}}r(m,"toNodeOutcomeDTO");function me(e){const t=m(e);return t===null||t.reason==="parked"?null:t.kind==="result"||t.reason==="finished"?{...t,kind:"result",reason:"finalized",declined:null}:t.reason==="declined"?{...t,reason:"declined",details:t.declined}:t.reason==="deadline_exceeded"?{...t,reason:"deadline_exceeded",declined:null}:t.reason==="cap_exhausted"?{...t,reason:"cap_exhausted",declined:null}:t.reason==="closed"||t.reason==="stranded"||t.reason==="retired"?{...t,reason:"canceled",declined:null}:{...t,reason:"runtime_error",declined:null,details:{crouter_reason:t.reason}}}r(me,"toRunOutcomeDTO");function ve(e){const t=e.lastFailure;return{node_id:e.nodeId,state:e.state,action:e.actionName,attempt:e.attempt,next_attempt_at:e.nextAttemptAt===0?null:new Date(e.nextAttemptAt).toISOString(),accepted_at:e.acceptedAt===null?null:new Date(e.acceptedAt).toISOString(),permanent_failed_at:e.permanentFailedAt===null?null:new Date(e.permanentFailedAt).toISOString(),last_failure:t===null?null:{kind:t.kind,...t.exitCode===void 0?{}:{exit_code:t.exitCode},...t.signal===void 0?{}:{signal:t.signal},...t.message===void 0?{}:{message:t.message}},created_at:new Date(e.createdAt).toISOString(),updated_at:new Date(e.updatedAt).toISOString()}}r(ve,"toOutcomeDeliveryDTO");function ke(e){return{node_id:e.node_id,name:e.name,description:e.description,cycles:e.cycles,kind:e.kind,status:e.status,frozen_at:e.frozen_at,pi_pid:e.pi_pid,telemetry_context_tokens:e.telemetry_context_tokens,telemetry_last_activity:e.telemetry_last_activity,fault:e.fault&&e.fault.link!=="broker\u2194crtrd"?{...e.fault,link:e.fault.link}:null,streaming:e.streaming}}r(ke,"toGraphNodeDTO");async function he(e,t=c(e.profile_id)){return{node_id:e.node_id,name:e.name,description:e.description,cycles:e.cycles,kind:e.kind,mode:e.mode,lifecycle:e.lifecycle,status:e.status,cwd:e.cwd,host_kind:e.host_kind,profile_id:e.profile_id,scopes:e.scopes,isolated:e.isolated,grantee:e.grantee??await f(e.node_id),profile_paused:t,parent:e.parent,created:e.created,intent:e.intent,waiting_for:(await p(e.node_id))?.controllerId??null,frozen_at:e.frozen_at??null,terminal_reason:e.terminal_reason??null,pi_pid:e.pi_pid,pi_pid_identity:e.pi_pid_identity,window:e.window,tmux_session:e.tmux_session,pane:e.pane,final_report:e.final_report??null,finalized_at:e.finalized_at??null,deadline_at:e.deadline_at??null,telemetry_tokens_in:e.telemetry_tokens_in??null,telemetry_context_tokens:e.telemetry_context_tokens??null,telemetry_last_activity:e.telemetry_last_activity??null,telemetry_updated_at:e.telemetry_updated_at??null,outcome:P(e),fault:e.fault&&e.fault.link!=="broker\u2194crtrd"?{...e.fault,link:e.fault.link}:null,streaming:e.streaming??!1}}r(he,"toNodeSummaryDTO");function U(e,t){return{parent:e.parent??null,spawned_by:e.spawned_by??null,subscribes_to:t.subscribesTo.map(n=>n.node_id),subscribers:t.subscribers.map(n=>n.node_id),children:[...t.children]}}r(U,"toNodeEdgesDTO");async function G(e,t){return{node_dir:await R(e,t),context_dir:await A(e,t),meta_path:T(e),transcript_path:E(e),view_socket:S(e)}}r(G,"toNodePathsDTO");function M(e){const t={state:e.state,path:e.path,branch:e.branch,repo_root:e.repo_root,base_ref:e.base_ref,base_sha:e.base_sha,created:e.created};return e.cleanup!==void 0&&(t.cleanup=e.cleanup),e.closed!==void 0&&(t.closed=e.closed),e.abandoned!==void 0&&(t.abandoned={...e.abandoned}),t}r(M,"toNodeWorktreeDTO");async function ge(e,t){const n=await f(e.node_id),i={node_id:e.node_id,name:e.name,kind:e.kind,mode:e.mode,lifecycle:e.lifecycle,status:e.status,cwd:e.cwd,host_kind:e.host_kind??null,profile_id:e.profile_id??null,scopes:e.scopes??null,isolated:e.isolated===!0,grantee:n,profile_paused:c(e.profile_id),parent:e.parent??null,created:e.created,intent:e.intent??null,waiting_for:(await p(e.node_id))?.controllerId??null,frozen_at:e.frozen_at??null,terminal_reason:e.terminal_reason??null,pi_pid:e.pi_pid??null,pi_pid_identity:e.pi_pid_identity??null,window:e.window??null,tmux_session:e.tmux_session??null,pane:e.pane??null,final_report:e.final_report??null,finalized_at:e.finalized_at??null,deadline_at:e.deadline_at??null,telemetry_tokens_in:e.telemetry_tokens_in??null,telemetry_context_tokens:e.telemetry_context_tokens??null,telemetry_last_activity:e.telemetry_last_activity??null,telemetry_updated_at:e.telemetry_updated_at??null,outcome:m(e),fault:e.fault&&e.fault.link!=="broker\u2194crtrd"?{...e.fault,link:e.fault.link}:null,streaming:e.streaming??!1,creator:e.creator??null,edges:U(e,t),paths:await G(e.node_id,n)};return e.description!==void 0&&(i.description=e.description),e.title!==void 0&&(i.title=e.title),e.icon!==void 0&&(i.icon=e.icon),e.cycles!==void 0&&(i.cycles=e.cycles),i.context_tokens=e.telemetry_context_tokens??e.telemetry_tokens_in??null,e.pi_session_id!==void 0&&(i.pi_session_id=e.pi_session_id??null),i.model_override=e.model_override??null,e.pi_session_file!==void 0&&(i.pi_session_file=e.pi_session_file??null),e.review_binding!==void 0&&(i.review_binding=e.review_binding===null?null:{...e.review_binding.kind===void 0?{}:{kind:e.review_binding.kind},review_id:e.review_binding.review_id,origin_node_id:e.review_binding.origin_node_id,branch_file:e.review_binding.branch_file,target_file:e.review_binding.target_file}),e.managed_worktree!=null&&(i.worktree=M(e.managed_worktree)),i}r(ge,"toNodeDetailDTO");function be(e,t,n,i){return{node_id:e,revived:t.launch!==void 0,resumed:t.resumed,status:n,outcome:t.outcome,ready:i}}r(be,"toReviveResultDTO");function ye(e){return{root:e.root,closed:[...e.closed],spared:[...e.spared]}}r(ye,"toCloseResultDTO");function xe(e,t,n){const i={report:e.report,notified:[...e.deliveredTo]};return t!==void 0&&(i.transitioned=t),n!==void 0&&(i.worktree_auto_dropped=!0,i.worktree_auto_dropped_path=n),i}r(xe,"toReportResultDTO");function Oe(e){return{node_id:e.node_id,active:e.active,created:e.created}}r(Oe,"toSubscriptionDTO");function W(e){if(e===null||e==="")return[];try{const t=JSON.parse(e);return typeof t=="object"&&t!==null&&!Array.isArray(t)?Object.keys(t):[]}catch{return[]}}r(W,"envKeys");function De(e,t){return{cron_id:e.cron_id,name:e.name,created_by:e.created_by,command:e.command,grant_id:e.grant_id,scopes:e.scopes,origin_run_id:e.origin_run_id,isolated:e.isolated,fire_at:e.fire_at,recur:e.recur,tz:e.tz,expires_at:e.expires_at,anchor_node:e.anchor_node,cancel_on_wake:e.cancel_on_wake,cwd:e.cwd,profile:e.profile,scope:e.scope,env_keys:W(e.env_json),run_timeout_s:e.run_timeout_s,overlap:e.overlap,on_output:e.on_output,sink:x(e.sink),tier:e.tier,state:e.state,held:e.held,run_state:e.run_state,last_run:t==null?null:{finished:t.finished,exit_code:t.exit_code,delivered:t.delivered},created:e.created,updated:e.updated}}r(De,"toCronDTO");function Te(e){return{run_id:e.run_id,started:e.started,finished:e.finished,duration_ms:e.duration_ms,exit_code:e.exit_code,stdout_head:e.stdout_head,stderr_head:e.stderr_head,delivered:e.delivered}}r(Te,"toCronRunDTO");function Ee(e){return{id:e.profileId,app:e.manifest.grantee??"app:terminal",name:e.manifest.name,projects:e.manifest.projects.map(t=>({...t})),delivery_limits:{...e.manifest.delivery_limits},paused_at:e.manifest.paused_at,default_kind:e.manifest.default_kind??"general",metadata:D(e.manifest.metadata),default_dir:null,created_at:e.manifest.created_at,last_used_at:e.manifest.last_used_at,profile_path:O(e.profileId)}}r(Ee,"toProfileDTO");function v(e,t={}){const n={review_id:e.review_id,origin_kind:e.origin_kind,origin_node_id:e.origin_node_id,review_dir:e.review_dir,companion_node_id:e.companion_node_id,file:e.file,state:e.state,created:e.created,source_missing:e.source_missing,anchor_base_sha256:e.anchor_base_sha256};return e.document_name!==null&&(n.document=e.document_name),e.opened_at!==null&&(n.opened_at=e.opened_at),e.submit_requested_at!==null&&(n.submit_requested_at=e.submit_requested_at),e.approved_at!==null&&(n.approved_at=e.approved_at),e.changed!==null&&(n.changed=e.changed),e.comments_total!==null&&(n.comments_total=e.comments_total),e.comments_unresolved!==null&&(n.comments_unresolved=e.comments_unresolved),e.canceled_at!==null&&(n.canceled_at=e.canceled_at),e.cancel_reason!==null&&(n.cancel_reason=e.cancel_reason),e.cancel_actor!==null&&(n.cancel_actor=e.cancel_actor),t.result_path!==void 0&&(n.result_path=t.result_path),e.delivery_error!==null&&(n.delivery_error=e.delivery_error),e.projection_error!==null&&(n.projection_error=e.projection_error),n}r(v,"toReviewDTO");function Se(e){return{comment_id:e.comment_id,review_id:e.review_id,status:e.status,revision:e.revision,text:e.text,anchor:{...e.anchor},anchor_state:e.anchor_state,anchor_line_text:e.anchor_line_text,anchor_doc_hash:e.anchor_doc_hash,author:{kind:e.author.kind,...e.author.node_id===null?{}:{node_id:e.author.node_id}},updated_by:{kind:e.updated_by.kind,...e.updated_by.node_id===null?{}:{node_id:e.updated_by.node_id}},created_at:e.created_at,updated_at:e.updated_at,...e.resolved_at===null?{}:{resolved_at:e.resolved_at},...e.deleted_at===null?{}:{deleted_at:e.deleted_at},created_seq:e.created_seq}}r(Se,"toReviewCommentDTO");function B(e){return{id:e.id,quote:e.quote,...e.context===void 0?{}:{context:e.context},note:e.note,status:e.status,created_at:e.createdAt,...e.resolvedAt===void 0?{}:{resolved_at:e.resolvedAt}}}r(B,"toPageFeedbackCommentDTO");function Ae(e){return{companion_node_id:e.companionNodeId??null,open_count:e.comments.filter(t=>t.status==="open").length,comments:e.comments.map(B)}}r(Ae,"toPageFeedbackDTO");function Re(e){return{seq:e.seq,review_id:e.review_id,comment_id:e.comment_id,kind:e.kind,state_change:e.state_change===1,revision_after:e.revision_after,actor:{kind:e.actor.kind,...e.actor.node_id===null?{}:{node_id:e.actor.node_id}},at:e.at,operation_id:e.operation_id,...e.payload===void 0?{}:{payload:e.payload}}}r(Re,"toReviewCommentEventDTO");function ze(e){return{file:e.file,submitted:e.submitted,approved:e.approved,comments:e.comments.map(n=>({...n})),submittedAt:e.submittedAt,savedAt:e.savedAt,reviewId:e.review_id,changed:e.changed,baselineSha256:e.baseline_sha256,approvedSha256:e.approved_sha256,companionNodeId:e.companion_node_id,commentsTotal:e.comments_total,commentsUnresolved:e.comments_unresolved}}r(ze,"toFeedbackResultDTO");const L=!0,$=Object.freeze({review_origin_missing:{status:400,code:"review_origin_unavailable"},review_origin_unforkable:{status:400,code:"review_origin_unavailable"},review_branch_unavailable:{status:409,code:"review_branch_unavailable"},branch_lost:{status:409,code:"review_branch_unavailable"},review_companion_unbound:{status:409,code:"review_companion_unbound"},review_bridge_unsubscribed:{status:409,code:"review_bridge_unavailable"},review_target_unreviewable:{status:400,code:"review_file_unreadable"},source_unreadable:{status:409,code:"review_source_unreadable"},delivery_unroutable:{status:409,code:"review_delivery_unroutable"},unknown_review:{status:404,code:"unknown_review"},review_terminal:{status:409,code:"review_terminal_conflict"},review_required:{status:400,code:"review_required"},stale_document:{status:409,code:"stale_document"},stale_revision:{status:409,code:"stale_revision"},unknown_comment:{status:404,code:"unknown_comment"},comment_deleted:{status:409,code:"comment_deleted"},invalid_anchor:{status:400,code:"invalid_anchor"},anchor_out_of_range:{status:400,code:"anchor_out_of_range"},text_too_long:{status:400,code:"text_too_long"},comment_limit_reached:{status:409,code:"comment_limit_reached"},stale_comment:{status:409,code:"stale_comment"},range_batch_incomplete:{status:409,code:"range_batch_incomplete"},range_batch_stale:{status:409,code:"range_batch_stale"}});function K(e){const t=k(e);if(typeof t=="object"&&t!==null&&typeof t.status=="number"&&typeof t.code=="string")return{status:t.status,code:t.code};if(t instanceof z)return t.code==="unknown_node"?{status:404,code:"node_not_found"}:t.code==="already_finalized"?{status:409,code:"already_finalized"}:{status:409,code:"finalization_forbidden"};if(t instanceof N)return{status:409,code:"node_id_exists"};if(t instanceof C)return{status:403,code:"scope_denied"};if(j(t))return{status:400,code:"invalid_request"};if(t instanceof _)return $[t.code];if(t instanceof a)return["kind_owned","name_taken","hop_limit","not_a_queue"].includes(t.code)?{status:409,code:t.code}:t.code==="invalid_publish_token"?{status:401,code:t.code}:t.code==="forbidden"||t.code==="argv_forbidden"||t.code==="scope_missing"?{status:403,code:t.code}:{status:J(t.exitCode),code:t.code};if(t instanceof Error){const n=t.message;if(/unknown node/i.test(n))return{status:404,code:"node_not_found"};if(/finalization latch/i.test(n))return{status:409,code:"already_finalized"};if(/illegal lifecycle transition/i.test(n))return{status:409,code:"illegal_transition"}}return{status:500,code:"internal"}}r(K,"errorToStatus");function k(e){if(!(e instanceof q))return e;const t=e.code==="unknown_node"?o.NOT_FOUND:o.GENERAL,n={error:e.code,message:e.message,next:e.next};return e.detail!==void 0&&(n.received=e.detail),new a(e.code,e.message,t,n)}r(k,"normalizeThrow");function V(e){if(e.code!=="review_terminal")return e.detail;const{review:t,...n}=e.detail;return{...n,review:H(t)}}r(V,"reviewErrorDetails");function H(e){return e.state!=="approved"?v(e):v(e,{result_path:b(e.review_dir,"result.json")})}r(H,"terminalConflictReviewDTO");function J(e){switch(e){case o.NOT_FOUND:return 404;case o.USAGE:return 400;case o.AMBIGUOUS:return 400;case o.NETWORK:return 503;case o.GENERAL:return 400;default:return 500}}r(J,"statusForExitCode");function Q(e){const n=(e instanceof Error?e.message:String(e)).split(`
2
2
  `,1)[0].trim();return n===""?"internal error":n.length>500?`${n.slice(0,497)}\u2026`:n}r(Q,"boundedCause");function Ne(e){const t=k(e),{status:n,code:i}=K(t);if(n>=500){const u={error:{code:i,message:Q(t),origin:"runtime"}};return t instanceof s&&(u.error.retryable=t.retryable),{status:n,body:u}}const h=t instanceof Error?t.message:String(t),l=t instanceof _?V(t):(t instanceof a||t instanceof I||t instanceof s)&&t.details!==void 0?t.details:void 0,d={error:{code:i,message:h,origin:"runtime"}};return l!==void 0&&(d.error.details=l),t instanceof s&&(t.param&&(d.error.param=t.param),t.scope&&(d.error.scope=t.scope),d.error.retryable=t.retryable),{status:n,body:d}}r(Ne,"toErrorBody");export{$ as REVIEW_ERROR_MAP,K as errorToStatus,ye as toCloseResultDTO,De as toCronDTO,Te as toCronRunDTO,Ne as toErrorBody,ze as toFeedbackResultDTO,ke as toGraphNodeDTO,pe as toMigrateStateDTO,ge as toNodeDetailDTO,U as toNodeEdgesDTO,m as toNodeOutcomeDTO,P as toNodeOutcomeSummaryDTO,G as toNodePathsDTO,he as toNodeSummaryDTO,M as toNodeWorktreeDTO,ve as toOutcomeDeliveryDTO,B as toPageFeedbackCommentDTO,Ae as toPageFeedbackDTO,Ee as toProfileDTO,xe as toReportResultDTO,Se as toReviewCommentDTO,Re as toReviewCommentEventDTO,v as toReviewDTO,be as toReviveResultDTO,me as toRunOutcomeDTO,Oe as toSubscriptionDTO};
@@ -62,4 +62,4 @@ export declare class AppPrincipalResolver {
62
62
  * caller's: active, the same `sub` and `grantee`, and not past `expires_at`.
63
63
  * Otherwise 401 `grant_revoked`. `resolve()` and every later re-read during a
64
64
  * request (a `grant.get` long-poll waking) apply this one check. */
65
- export declare function callerGrant(caller: Pick<AppPrincipal, 'grant' | 'sub' | 'grantee'>): ActiveGrant;
65
+ export declare function callerGrant(caller: Pick<AppPrincipal, 'grant' | 'sub' | 'grantee'>): Promise<ActiveGrant>;
@@ -1 +1 @@
1
- var g=Object.defineProperty;var d=(c,e)=>g(c,"name",{value:e,configurable:!0});import{covers as v,JwksCache as m,MissingRevClaimError as p,verifyCallToken as _}from"@north-light/identity";import{createLocalJWKSet as l,decodeProtectedHeader as h,jwtVerify as f}from"jose";import{callerGrantOf as b,coverGrant as k}from"../../core/grants/cover.js";import{RunError as n}from"../../core/runs/operations.js";import{NoticeLedger as E}from"./sync-notice.js";class W{static{d(this,"AppPrincipalResolver")}issuer;audience;syncGrants;cache;ready=!1;timer;constructor(e,t,r,i){this.issuer=e,this.audience=t,this.syncGrants=r,this.cache=new m(e,fetch,i),this.load(),this.timer=setInterval(()=>{this.ready||this.load()},5e3),this.timer.unref()}async load(){try{await this.cache.load(),this.ready=!0}catch{}}isReady(){return this.ready}get jwks(){return this.cache}close(){this.timer&&clearInterval(this.timer)}ledger=new E;async verifySyncNotice(e){if(!this.ready)throw new n(503,"runtime_starting","runtime_starting");return this.ledger.accept(e,this.cache,this.issuer,this.audience)}async verifyHandoff(e){if(!this.ready)throw new n(503,"runtime_starting","runtime_starting");const t=d(()=>new n(401,"unauthorized","invalid vendor sign-in handoff"),"refuse");if(!e)throw t();let r;try{const u=h(e);if(u.alg!=="ES256")throw t();const y=await this.cache.forKid(u.kid);({payload:r}=await f(e,l(y),{issuer:this.issuer,audience:this.audience,algorithms:["ES256"],requiredClaims:["exp","jti","sub"]}))}catch{throw t()}const{sub:i,jti:s,exp:a,purpose:o,aud:w}=r;if(o!=="vendor_sign_in"||w!==this.audience||typeof i!="string"||typeof s!="string"||s===""||typeof a!="number")throw t();return{sub:i,jti:s,exp:a}}async verifyDirectoryRead(e,t){if(!this.ready)throw new n(503,"runtime_starting","runtime_starting");const r=d(()=>new n(401,"unauthorized","invalid directory token"),"refuse");if(!e?.startsWith("Bearer ")||e.length<=7)throw r();const i=e.slice(7);let s;try{const a=h(i);if(a.alg!=="ES256")throw r();const o=await this.cache.forKid(a.kid);({payload:s}=await f(i,l(o),{issuer:this.issuer,audience:this.audience,algorithms:["ES256"],requiredClaims:["exp"]}))}catch{throw r()}if(s.purpose!==t||s.aud!==this.audience)throw r()}async verifyCall(e){if(!this.ready)throw new n(503,"runtime_starting","runtime_starting");if(!e?.startsWith("Bearer ")||e.length<=7)throw new n(401,"unauthorized","a directory access token is required");const t=e.slice(7);try{if(h(t).alg!=="ES256")throw new Error("Invalid call token header");return await _({token:t,jwks:this.cache,issuer:this.issuer,audience:this.audience})}catch(r){throw r instanceof p?new n(401,"unauthorized",r.message):new n(401,"unauthorized","invalid directory access token")}}async resolve(e,t){return this.resolveVerified(await this.verifyCall(e),t)}async resolveVerified(e,t){const r=e.chain[0],i=e.claims;if(e.chain.length!==1||!r||!r.sub.startsWith("app:")||r.grant===void 0||r.rev===void 0||!/^[A-Za-z0-9_-]{1,64}$/.test(i.client_id)||i.grantee!==void 0&&i.grantee!==r.sub||i.rev!==void 0&&i.rev!==r.rev)throw new n(401,"unauthorized","invalid directory access token");const s=await k(r.grant,r.rev,e.sub,r.sub,this.syncGrants);if(t&&!s.resolved.some(a=>v(a,t)))throw new n(403,"scope_missing",`missing scope ${t}`,void 0,void 0,t);return{sub:e.sub,grantee:r.sub,client_id:i.client_id,grant:r.grant,rev:s.rev,resolved:s.resolved,resolved_scopes:s.resolved_scopes,spend_cap:s.spend_cap,dependencies:s.dependencies??{},exp:i.exp}}}function q(c){return b(c.grant,c.sub,c.grantee)}d(q,"callerGrant");export{W as AppPrincipalResolver,q as callerGrant};
1
+ var g=Object.defineProperty;var d=(c,e)=>g(c,"name",{value:e,configurable:!0});import{covers as v,JwksCache as m,MissingRevClaimError as p,verifyCallToken as _}from"@north-light/identity";import{createLocalJWKSet as l,decodeProtectedHeader as h,jwtVerify as f}from"jose";import{callerGrantOf as b,coverGrant as k}from"../../core/grants/cover.js";import{RunError as n}from"../../core/runs/operations.js";import{NoticeLedger as E}from"./sync-notice.js";class W{static{d(this,"AppPrincipalResolver")}issuer;audience;syncGrants;cache;ready=!1;timer;constructor(e,t,r,i){this.issuer=e,this.audience=t,this.syncGrants=r,this.cache=new m(e,fetch,i),this.load(),this.timer=setInterval(()=>{this.ready||this.load()},5e3),this.timer.unref()}async load(){try{await this.cache.load(),this.ready=!0}catch{}}isReady(){return this.ready}get jwks(){return this.cache}close(){this.timer&&clearInterval(this.timer)}ledger=new E;async verifySyncNotice(e){if(!this.ready)throw new n(503,"runtime_starting","runtime_starting");return this.ledger.accept(e,this.cache,this.issuer,this.audience)}async verifyHandoff(e){if(!this.ready)throw new n(503,"runtime_starting","runtime_starting");const t=d(()=>new n(401,"unauthorized","invalid vendor sign-in handoff"),"refuse");if(!e)throw t();let r;try{const u=h(e);if(u.alg!=="ES256")throw t();const y=await this.cache.forKid(u.kid);({payload:r}=await f(e,l(y),{issuer:this.issuer,audience:this.audience,algorithms:["ES256"],requiredClaims:["exp","jti","sub"]}))}catch{throw t()}const{sub:i,jti:s,exp:a,purpose:o,aud:w}=r;if(o!=="vendor_sign_in"||w!==this.audience||typeof i!="string"||typeof s!="string"||s===""||typeof a!="number")throw t();return{sub:i,jti:s,exp:a}}async verifyDirectoryRead(e,t){if(!this.ready)throw new n(503,"runtime_starting","runtime_starting");const r=d(()=>new n(401,"unauthorized","invalid directory token"),"refuse");if(!e?.startsWith("Bearer ")||e.length<=7)throw r();const i=e.slice(7);let s;try{const a=h(i);if(a.alg!=="ES256")throw r();const o=await this.cache.forKid(a.kid);({payload:s}=await f(i,l(o),{issuer:this.issuer,audience:this.audience,algorithms:["ES256"],requiredClaims:["exp"]}))}catch{throw r()}if(s.purpose!==t||s.aud!==this.audience)throw r()}async verifyCall(e){if(!this.ready)throw new n(503,"runtime_starting","runtime_starting");if(!e?.startsWith("Bearer ")||e.length<=7)throw new n(401,"unauthorized","a directory access token is required");const t=e.slice(7);try{if(h(t).alg!=="ES256")throw new Error("Invalid call token header");return await _({token:t,jwks:this.cache,issuer:this.issuer,audience:this.audience})}catch(r){throw r instanceof p?new n(401,"unauthorized",r.message):new n(401,"unauthorized","invalid directory access token")}}async resolve(e,t){return this.resolveVerified(await this.verifyCall(e),t)}async resolveVerified(e,t){const r=e.chain[0],i=e.claims;if(e.chain.length!==1||!r||!r.sub.startsWith("app:")||r.grant===void 0||r.rev===void 0||!/^[A-Za-z0-9_-]{1,64}$/.test(i.client_id)||i.grantee!==void 0&&i.grantee!==r.sub||i.rev!==void 0&&i.rev!==r.rev)throw new n(401,"unauthorized","invalid directory access token");const s=await k(r.grant,r.rev,e.sub,r.sub,this.syncGrants);if(t&&!s.resolved.some(a=>v(a,t)))throw new n(403,"scope_missing",`missing scope ${t}`,void 0,void 0,t);return{sub:e.sub,grantee:r.sub,client_id:i.client_id,grant:r.grant,rev:s.rev,resolved:s.resolved,resolved_scopes:s.resolved_scopes,spend_cap:s.spend_cap,dependencies:s.dependencies??{},exp:i.exp}}}async function q(c){return await b(c.grant,c.sub,c.grantee)}d(q,"callerGrant");export{W as AppPrincipalResolver,q as callerGrant};
@@ -1,17 +1,17 @@
1
- import type { DatabaseSync } from 'node:sqlite';
2
1
  import type { DocOwnerFlag } from '../../api/dto/docs.js';
3
2
  import type { ObjectRow, Reader } from '../../core/graph/types.js';
4
3
  import type { RequestContext } from './router.js';
4
+ import type { CanvasDb } from '../../core/canvas/db.js';
5
5
  /** The graph reader for a request's principal; repos come from the node's cwd. */
6
- export declare function readerFor(db: DatabaseSync, ctx: Pick<RequestContext, 'principal'>): Reader;
6
+ export declare function readerFor(db: CanvasDb, ctx: Pick<RequestContext, 'principal'>): Promise<Reader>;
7
7
  /** A ref (`[[ ]]`-wrapped or not, raw id, name, `<owner>/<name>`, or an old
8
8
  * `<node-id>:reports/<basename>[.md]`) → the object, or a deleted/remote answer.
9
9
  * Anything unreadable is `not_found`. */
10
- export declare function resolveRef(db: DatabaseSync, reader: Reader, raw: string): ObjectRow | {
10
+ export declare function resolveRef(db: CanvasDb, reader: Reader, raw: string): Promise<ObjectRow | {
11
11
  deleted: ObjectRow;
12
12
  } | {
13
13
  remote: string;
14
- };
14
+ }>;
15
15
  /** The owner object a `--owner` value names. `cwd` is the caller's directory,
16
16
  * used for `repo` when the reader is a person (who has no cwd of its own). */
17
- export declare function ownerFromFlag(db: DatabaseSync, reader: Reader, value: DocOwnerFlag | undefined, cwd?: string): ObjectRow;
17
+ export declare function ownerFromFlag(db: CanvasDb, reader: Reader, value: DocOwnerFlag | undefined, cwd?: string): Promise<ObjectRow>;
@@ -1 +1 @@
1
- var E=Object.defineProperty;var c=(n,e)=>E(n,"name",{value:e,configurable:!0});import{prepared as h}from"../../core/sqlite-statements.js";import{ApiError as d}from"../../api/index.js";import{readerFor as R}from"../../core/graph/reader.js";import{canRead as v}from"../../core/graph/access.js";import{ownersByHandle as y,resolveName as x,viewOf as F}from"../../core/graph/names.js";import{ensureOwner as $}from"../../core/graph/objects.js";import{checkoutsForCwd as N,reposForCwd as j}from"../../core/graph/repo-sync/repos.js";import{lookupProfile as L}from"../../core/profiles/manifest.js";function M(n,e){return R(n,e.principal,o=>N(n,o))}c(M,"readerFor");function T(n,e,o){const t=x(n,e,o);if("object"in t)return t.object;if("deleted"in t||"remote"in t)return t;if("ambiguous"in t){const p=t.ambiguous.map(m=>`${_(n,m)}/${m.name}`);throw new d(409,"ambiguous_name",`'${o}' names more than one object: ${p.join(", ")}`,{candidates:p,next:"Read one of them by its full `<type>:<owner>/<name>`."})}const r=o.replace(/^\s*\[\[(.*)\]\]\s*$/,"$1").trim(),i=/^(person|app|repo|profile):([^/]+)$/.exec(r),s=(i?y(n,i[2],i[1]):y(n,r).filter(p=>p.type!=="node")).filter(p=>v(n,e,p));if(s.length>0){const p=F(n,e),m=c(u=>{const f=p.findIndex(g=>g.rowid===u.rowid);return f<0?1/0:f},"rank"),w=[...s].sort((u,f)=>m(u)-m(f))[0];if(m(w)===1/0&&s.length>1){const u=s.map(f=>`${f.type}:${f.name}`);throw new d(409,"ambiguous_name",`'${o}' names more than one owner: ${u.join(", ")}`,{candidates:u,next:"Name one as `<type>:<handle>`."})}return w.deleted_at?{deleted:w}:w}const a=`'${o}' not found: no object by that name in your view`,l=`Search for it with \`crtr canvas search ${r}\`.`;throw new d(404,"not_found",a,{error:"not_found",message:a,next:l})}c(T,"resolveRef");function _(n,e){if(e.owner===null)return"";const o=h(n,"SELECT type, id, name FROM objects WHERE rowid = ?").get(e.owner);return o.type==="node"?o.id:`${o.type}:${o.name}`}c(_,"typedOwnerHandle");function U(n,e,o,t){const r=o??(e.class==="node"?"node":e.class==="person"?"user":"app"),i=c(s=>new d(400,"invalid_owner",s,{next:"Run `crtr doc write --owner -h`."}),"refuse");if(r==="node"){if(e.class!=="node")throw i("`--owner node` needs a node; you are not running as one");return e.node}if(r==="user")return $(n,"person","local-user","user:local","user");if(r==="app"){if(e.class==="person")throw i("`--owner app` needs an app; a person has none \u2014 use `--owner user`");return e.app}if(r==="profile"){if(e.class!=="node"||!e.profile)throw i("`--owner profile` needs a profile; you have none");return e.profile}if(r==="repo"){const s=t?j(n,t):[],a=s[0]?s:e.class==="node"?e.repos:[];if(!a[0])throw i(`\`--owner repo\` needs a repo; ${t??(e.class==="node"?e.cwd:"your directory")} is not inside one`);return a[0]}if(r.startsWith("repo:"))return S(n,"repo",r.slice(5),i);if(r.startsWith("profile:")){const s=r.slice(8),a=h(n,"SELECT * FROM objects WHERE type = 'profile' AND name = ? AND home_machine IS NULL").get(s);if(a)return a;const l=L(s);if(l.kind!=="resolved")throw i(`no profile named '${s}'`);const p=e.class==="person"?e.person:e.app;return $(n,"profile","profile",l.entry.profileId,l.entry.manifest.name,p)}throw i(`unknown --owner value '${r}'`)}c(U,"ownerFromFlag");function S(n,e,o,t){const r=h(n,"SELECT * FROM objects WHERE type = ? AND name = ? AND deleted_at IS NULL AND home_machine IS NULL").get(e,o);if(!r)throw t(`no ${e} named '${o}'`);return r}c(S,"namedOwner");export{U as ownerFromFlag,M as readerFor,T as resolveRef};
1
+ var g=Object.defineProperty;var c=(n,e)=>g(n,"name",{value:e,configurable:!0});import{ApiError as d}from"../../api/index.js";import{readerFor as E}from"../../core/graph/reader.js";import{canRead as R}from"../../core/graph/access.js";import{ownersByHandle as y,resolveName as v,viewOf as x}from"../../core/graph/names.js";import{ensureOwner as h}from"../../core/graph/objects.js";import{checkoutsForCwd as F,reposForCwd as N}from"../../core/graph/repo-sync/repos.js";import{lookupProfile as j}from"../../core/profiles/manifest.js";import{filterAsync as L,mapAsync as _}from"../../core/async-array.js";async function T(n,e){return await E(n,e.principal,async o=>await F(n,o))}c(T,"readerFor");async function U(n,e,o){const r=await v(n,e,o);if("object"in r)return r.object;if("deleted"in r||"remote"in r)return r;if("ambiguous"in r){const s=await _(r.ambiguous,async w=>`${await A(n,w)}/${w.name}`);throw new d(409,"ambiguous_name",`'${o}' names more than one object: ${s.join(", ")}`,{candidates:s,next:"Read one of them by its full `<type>:<owner>/<name>`."})}const t=o.replace(/^\s*\[\[(.*)\]\]\s*$/,"$1").trim(),i=/^(person|app|repo|profile):([^/]+)$/.exec(t),a=await L(i?await y(n,i[2],i[1]):(await y(n,t)).filter(s=>s.type!=="node"),async s=>await R(n,e,s));if(a.length>0){const s=await x(n,e),w=c(m=>{const f=s.findIndex($=>$.rowid===m.rowid);return f<0?1/0:f},"rank"),l=[...a].sort((m,f)=>w(m)-w(f))[0];if(w(l)===1/0&&a.length>1){const m=a.map(f=>`${f.type}:${f.name}`);throw new d(409,"ambiguous_name",`'${o}' names more than one owner: ${m.join(", ")}`,{candidates:m,next:"Name one as `<type>:<handle>`."})}return l.deleted_at?{deleted:l}:l}const p=`'${o}' not found: no object by that name in your view`,u=`Search for it with \`crtr canvas search ${t}\`.`;throw new d(404,"not_found",p,{error:"not_found",message:p,next:u})}c(U,"resolveRef");async function A(n,e){if(e.owner===null)return"";const o=await n.prepare("SELECT type, id, name FROM objects WHERE rowid = ?").get(e.owner);return o.type==="node"?o.id:`${o.type}:${o.name}`}c(A,"typedOwnerHandle");async function B(n,e,o,r){const t=o??(e.class==="node"?"node":e.class==="person"?"user":"app"),i=c(a=>new d(400,"invalid_owner",a,{next:"Run `crtr doc write --owner -h`."}),"refuse");if(t==="node"){if(e.class!=="node")throw i("`--owner node` needs a node; you are not running as one");return e.node}if(t==="user")return await h(n,"person","local-user","user:local","user");if(t==="app"){if(e.class==="person")throw i("`--owner app` needs an app; a person has none \u2014 use `--owner user`");return e.app}if(t==="profile"){if(e.class!=="node"||!e.profile)throw i("`--owner profile` needs a profile; you have none");return e.profile}if(t==="repo"){const a=r?await N(n,r):[],p=a[0]?a:e.class==="node"?e.repos:[];if(!p[0])throw i(`\`--owner repo\` needs a repo; ${r??(e.class==="node"?e.cwd:"your directory")} is not inside one`);return p[0]}if(t.startsWith("repo:"))return await I(n,"repo",t.slice(5),i);if(t.startsWith("profile:")){const a=t.slice(8),p=await n.prepare("SELECT * FROM objects WHERE type = 'profile' AND name = ? AND home_machine IS NULL").get(a);if(p)return p;const u=j(a);if(u.kind!=="resolved")throw i(`no profile named '${a}'`);const s=e.class==="person"?e.person:e.app;return await h(n,"profile","profile",u.entry.profileId,u.entry.manifest.name,s)}throw i(`unknown --owner value '${t}'`)}c(B,"ownerFromFlag");async function I(n,e,o,r){const t=await n.prepare("SELECT * FROM objects WHERE type = ? AND name = ? AND deleted_at IS NULL AND home_machine IS NULL").get(e,o);if(!t)throw r(`no ${e} named '${o}'`);return t}c(I,"namedOwner");export{B as ownerFromFlag,T as readerFor,U as resolveRef};
@@ -75,15 +75,15 @@ export type CronPrincipalClass = {
75
75
  export declare function appOf(principal: RequestPrincipal): string | null;
76
76
  /** Whether the caller is the person (a local person, or a forwarded call the envelope makes for the person). */
77
77
  export declare function actsAsPerson(principal: RequestPrincipal): boolean;
78
- export declare function resolvedScopes(principal: RequestPrincipal): readonly string[];
78
+ export declare function resolvedScopes(principal: RequestPrincipal): Promise<readonly string[]>;
79
79
  export declare function runCallerApp(principal: RequestPrincipal | AppPrincipal): string | null;
80
80
  /** Run confinement (Silas, 2026-09-30): a broker caller reaches a same-app node or
81
81
  * run only when it is in the caller's run, or neither run is isolated. `target`
82
82
  * omitted means no particular node (an app-wide question), which passes. */
83
- export declare function brokerMayReach(principal: RequestPrincipal | AppPrincipal, target: string | undefined, grantee: string): boolean;
84
- export declare function canReadRun(principal: RequestPrincipal | AppPrincipal, grantee: string, target?: string): boolean;
85
- export declare function requireRun(principal: RequestPrincipal | AppPrincipal, id: string, acting?: boolean, allowDeleting?: boolean): import("../../index.js").NodeMeta;
86
- export declare function canReadNode(principal: RequestPrincipal, grantee: string, target?: string): boolean;
83
+ export declare function brokerMayReach(principal: RequestPrincipal | AppPrincipal, target: string | undefined, grantee: string): Promise<boolean>;
84
+ export declare function canReadRun(principal: RequestPrincipal | AppPrincipal, grantee: string, target?: string): Promise<boolean>;
85
+ export declare function requireRun(principal: RequestPrincipal | AppPrincipal, id: string, acting?: boolean, allowDeleting?: boolean): Promise<import("../../index.js").NodeMeta>;
86
+ export declare function canReadNode(principal: RequestPrincipal, grantee: string, target?: string): Promise<boolean>;
87
87
  /** Throw the 403 `scope_denied` a scoped bearer earns when its ceiling lacks
88
88
  * `scope`. The owner (`null`) always passes. */
89
89
  export declare function assertCeiling(ceiling: Ceiling, scope: string): void;
@@ -1 +1 @@
1
- var W=Object.defineProperty;var a=(e,t)=>W(e,"name",{value:t,configurable:!0});import{toErrorBody as j}from"./map.js";import{emitEvent as p}from"../../core/events/emit.js";import{scopeAllowed as f,ScopeDeniedError as N}from"../../core/scopes.js";import{coveredByAny as J}from"../../shared/env.js";import{ApiError as c}from"../../api/errors.js";import{activeGrant as B,grantFor as x}from"../../core/grants/mirror.js";import{getNode as _}from"../../core/canvas/canvas.js";import{ownedRun as z,RunError as g}from"../../core/runs/operations.js";import{nodeMayReach as H,placeMayReach as S}from"../../core/runs/confinement.js";import{checkCronFire as M}from"../cron/authority.js";import{readConfig as P}from"../../core/config.js";import{SCOPE_VOCABULARY as I}from"../../core/scopes.js";import{operationFor as L}from"./operations.js";import{CONTROL_BODY_MAX_BYTES as F}from"../../core/llm/body-limits.js";import{getRequest as Y,getRequestByInboxTicket as V}from"../../core/human/requests.js";import{requireVisibleReview as R}from"../../core/review/store.js";import{getComment as O}from"../../core/review/comments.js";function D(e,t,o,s,n){const r=e.path,u=n&&typeof n=="object"&&!Array.isArray(n)?n:{};if(r==="/v1/human/requests"||r==="/v1/human/reviews"){const d=r.endsWith("/reviews")?u.origin_node_id:u.requester_node_id,m=r==="/v1/human/requests"&&d==null;if(d!==t.node&&!m)throw new c(403,"other_app_run","a broker may create a human request only for its own node");const h=u.source;if(h&&typeof h=="object"&&"nodeId"in h&&h.nodeId!==t.node)throw new c(403,"other_app_run","request source must name the calling node")}if(r==="/v1/human/reviews/self/comments"&&e.method==="GET"&&s.get("actor_node_id")!==t.node)throw new c(403,"other_app_run","self review requires the calling node");if(r.includes("/comments")&&e.method!=="GET"&&u.actor_node_id!==t.node)throw new c(403,"other_app_run","comment author must be the calling node");if(o.comment_id&&!O(o.comment_id))throw new c(404,"not_found","comment not found")}a(D,"authorizeHumanBody");function y(e){return e.class==="broker"||e.class==="cron"}a(y,"boundedByStoredScopes");function b(e){return e.class==="person"||e.class==="anonymous"||e.class==="machine"?null:e.class==="forwarded"?e.actor.kind==="app"?e.actor.app:null:e.app}a(b,"appOf");function q(e){return e.class==="person"||e.class==="forwarded"&&e.actor.kind==="person"}a(q,"actsAsPerson");function $(e){const t=x(e.actor.app,e.sub);if(!t)throw new c(403,"app_not_granted",`${e.actor.app} holds no active grant for ${e.sub} on this machine`);return t}a($,"forwardedGrant");function v(e){if(e.class==="person"||e.class==="anonymous"||e.class==="machine")return[];if(e.class==="forwarded"){if(e.actor.kind==="person")return[];const{resolved:o}=$(e),s=e.actor.node_scopes;return s===null?o:s.filter(n=>J(o,n))}if(e.class==="app")return e.scopes;if(e.class==="cron"){const o=M({grantee:e.app,sub:e.sub,grant_id:e.grant,scopes:e.scopes});if(o.allowed)return o.effectiveScopes;throw o.reason==="grant_missing"||o.reason==="grant_revoked"?new c(401,"grant_revoked",o.message):new c(403,"scope_missing",o.message)}const t=e.grant?B(e.grant):x(e.app,e.sub);if(t&&t.grantee===e.app&&t.sub===e.sub)return t.resolved;if(e.app==="app:terminal"&&!P("user").runtime?.issuer)return I;throw new c(401,"grant_revoked","the node grant is not active")}a(v,"resolvedScopes");function k(e){return"class"in e?b(e):e.grantee}a(k,"runCallerApp");function l(e,t,o){return t===void 0||!("class"in e)?!0:e.class==="cron"?S({run:e.origin_run??"",isolated:e.isolated},e.app,t,o):e.class==="forwarded"?e.actor.kind!=="app"||S(e.actor.place,e.actor.app,t,o):e.class!=="broker"?!0:H(e.node,e.app,t,o)}a(l,"brokerMayReach");function X(e,t,o){const s=k(e);if(s===t)return l(e,o,t);if(s===null)return!0;const n="class"in e?null:B(e.grant),r="class"in e?v(e):n?.sub===e.sub&&n.grantee===e.grantee?n.resolved:[];return f(r,`crtr:conversations:read:${t}`)&&(!("class"in e)||!y(e)||f(e.scopes,`crtr:conversations:read:${t}`))}a(X,"canReadRun");function Be(e,t,o=!1,s=!1){const n=_(t);if(!n||n.parent!==null||n.run_id!==t||!n.grantee||n.deleting_at&&!s)throw new g(404,"not_found","run not found");if(!X(e,n.grantee,t))throw new g(404,"not_found","run not found");if(o&&k(e)!==null&&k(e)!==n.grantee)throw new g(403,"other_app_run","cannot change another app's run");return z(t,n.grantee,s)}a(Be,"requireRun");function C(e,t,o){return q(e)?!0:e.class==="anonymous"||e.class==="machine"?!1:b(e)===t?l(e,o,t):f(v(e),`crtr:objects:read:${t}`)&&(!y(e)||f(e.scopes,`crtr:objects:read:${t}`))}a(C,"canReadNode");const K=new Set(["messages.post.58","messages.post.59"]);function Q(e,t,o){if(!e.classes.includes(t.class)&&!(t.class!=="anonymous"&&t.class!=="machine"&&t.class!=="forwarded"&&e.classes.includes("anonymous")))throw new c(403,"permission_error","this operation is not available to the caller");if(t.class==="forwarded"&&t.actor.kind==="app"&&$(t),t.class==="person"||t.class==="anonymous"||t.class==="machine"||q(t))return;const s=v(t);if(e.scope&&(!f(s,e.scope)||y(t)&&!f(t.scopes,e.scope)))throw new c(403,"scope_missing",`missing scope ${e.scope}`);if(t.class==="app")return;const n=b(t);t.class==="broker"&&Z(e,t,o,s);const r=o.id;if((e.resource==="node-read"||e.resource==="node-write")&&r!==void 0){const u=_(r);if(!u)return;if(e.resource==="node-write"&&u.grantee!==n&&!(K.has(e.name)&&f(s,`crtr:objects:message:${u.grantee??"app:terminal"}`)))throw new c(403,"other_app_run","cannot change another app's node");if(e.resource==="node-write"&&!l(t,r,u.grantee??"app:terminal"))throw new c(404,"not_found","node not found");if(e.resource==="node-read"&&!C(t,u.grantee??"app:terminal",r))throw new c(404,"not_found","node not found")}}a(Q,"authorizeOperation");function Z(e,t,o,s){if(e.resource==="daemon-bash"&&(!f(s,"crtr:files:rw:user:.")||!f(t.scopes,"crtr:files:rw:user:.")))throw new c(403,"scope_missing","missing scope crtr:files:rw:user:.");if(e.resource==="human"){const r=e.path,u=e.method==="GET";if(!u&&(r.endsWith("/respond")||r.endsWith("/submit")||r.endsWith("/dismiss")||r.endsWith("/progress")||r.endsWith("/comment-ranges")||r.includes("/feedback-comments")))throw new c(403,"permission_error","only the person may answer or edit the human inbox");const d=o.request_id?Y(o.request_id):o.ticket_id?V(o.ticket_id):null,m=o.comment_id?O(o.comment_id):null,h=o.review_id?R(o.review_id):m?R(m.review_id):null,w=d?.requester_node_id??h?.origin_node_id;if(w!=null){const i=_(w);if(i&&(u?!C(t,i.grantee??"app:terminal",w):i.grantee!==t.app))throw new c(u?404:403,u?"not_found":"other_app_run","human request belongs to another app");if(i&&!u&&!l(t,w,i.grantee??"app:terminal"))throw new c(404,"not_found","human request not found")}else if(d||h)throw new c(403,"permission_error","only the person may access a request without a node")}const n=o.id;if(e.resource==="node-own"&&n!==void 0&&n!==t.node)throw new c(403,"other_app_run","the operation requires the calling node")}a(Z,"authorizeBrokerOnly");function ee(e,t){if(!f(e,t))throw new N("the bearer token",t)}a(ee,"assertCeiling");function te(){return new c(403,"owner_only","this operation is owner-only; a scoped token does not reach it")}a(te,"ownerOnlyError");function xe(e){return e.map(t=>({...t,ownerOnly:!0}))}a(xe,"ownerOnly");class Se{static{a(this,"Router")}routes=[];register(t){const o=L(t.method,t.pattern);if(!o)throw new Error(`route has no operation row: ${t.method} ${t.pattern}`);if(this.routes.some(s=>s.method===t.method.toUpperCase()&&s.operation.path===t.pattern))throw new Error(`duplicate route: ${t.method} ${t.pattern}`);return this.routes.push({operation:o,method:t.method.toUpperCase(),segments:A(t.pattern),handler:t.handler,maxBodyBytes:t.maxBodyBytes??F}),this}registerAll(t){for(const o of t)this.register(o);return this}match(t,o){const s=t.toUpperCase(),n=A(o);for(const r of this.routes){if(r.method!==s)continue;const u=oe(r.segments,n);if(u!==null)return{handler:r.handler,params:u,operation:r.operation,maxBodyBytes:r.maxBodyBytes}}return null}async handle(t,o,s,n={class:"person"}){try{const r=new URL(t.url??"/","http://127.0.0.1"),u=(t.method??"GET").toUpperCase(),d=this.match(u,r.pathname);if(d===null){U(o,404,"not_found",`no route for ${u} ${r.pathname}`);return}if(Q(d.operation,n,d.params),s!==null){if(d.operation.classes.length===1&&d.operation.classes[0]==="person")throw te();d.operation.scope&&ee(s,d.operation.scope)}let m;try{m=await ne(t,d.maxBodyBytes)}catch(i){const E=i instanceof T?"payload_too_large":"invalid_request";U(o,E==="payload_too_large"?413:400,E,i.message);return}n.class==="broker"&&d.operation.resource==="human"&&D(d.operation,n,d.params,r.searchParams,m);const h={method:u,path:r.pathname,params:d.params,query:r.searchParams,body:m,ceiling:s,principal:n,...n.class==="anonymous"&&typeof t.headers.authorization=="string"?{publishToken:t.headers.authorization.slice(7)}:{},req:t,res:o},w=await d.handler(h);o.writableEnded||re(o,w)}catch(r){const{status:u,body:d}=j(r);u>=500&&p({event:"api.request.failed",level:"error",error:r instanceof Error?r:new Error(String(r)),...n.class==="broker"?{node_id:n.node}:{},fields:{method:(t.method??"GET").toUpperCase(),path:t.url??""}}),G(o,u,d)}}}function A(e){return e.split("/").filter(t=>t.length>0)}a(A,"splitPath");function oe(e,t){if(e.length!==t.length)return null;const o={};for(let s=0;s<e.length;s++){const n=e[s],r=t[s];if(n.startsWith(":"))o[n.slice(1)]=decodeURIComponent(r);else if(n!==r)return null}return o}a(oe,"matchSegments");class T extends Error{static{a(this,"BodyTooLargeError")}}async function ne(e,t){const o=[];let s=0;for await(const r of e){const u=r;if(s+=u.length,s>t)throw new T(`request body exceeds ${t} bytes`);o.push(u)}if(s===0)return;const n=Buffer.concat(o).toString("utf8").trim();if(n!=="")try{return JSON.parse(n)}catch{throw new Error("request body is not valid JSON")}}a(ne,"readJsonBody");function re(e,t){if(e.headersSent)return;const o={...t.headers??{}};if(t.rawBody!==void 0){e.writeHead(t.status,o),e.end(t.rawBody);return}if(t.status===204||t.body===void 0){e.writeHead(t.status,o),e.end();return}o["content-type"]===void 0&&(o["content-type"]="application/json; charset=utf-8"),e.writeHead(t.status,o),e.end(JSON.stringify(t.body))}a(re,"writeResult");function G(e,t,o){if(e.headersSent){e.end();return}e.writeHead(t,{"content-type":"application/json; charset=utf-8"}),e.end(JSON.stringify(o))}a(G,"writeJson");function U(e,t,o,s){G(e,t,{error:{code:o,message:s,origin:"runtime"}})}a(U,"writeError");export{Se as Router,q as actsAsPerson,b as appOf,ee as assertCeiling,l as brokerMayReach,C as canReadNode,X as canReadRun,xe as ownerOnly,te as ownerOnlyError,Be as requireRun,v as resolvedScopes,k as runCallerApp};
1
+ var W=Object.defineProperty;var u=(e,t)=>W(e,"name",{value:t,configurable:!0});import{toErrorBody as j}from"./map.js";import{emitEvent as p}from"../../core/events/emit.js";import{scopeAllowed as f,ScopeDeniedError as N}from"../../core/scopes.js";import{coveredByAny as J}from"../../shared/env.js";import{ApiError as c}from"../../api/errors.js";import{activeGrant as B,grantFor as x}from"../../core/grants/mirror.js";import{getNode as y}from"../../core/canvas/canvas.js";import{ownedRun as z,RunError as _}from"../../core/runs/operations.js";import{nodeMayReach as H,placeMayReach as S}from"../../core/runs/confinement.js";import{checkCronFire as M}from"../cron/authority.js";import{readConfig as P}from"../../core/config.js";import{SCOPE_VOCABULARY as I}from"../../core/scopes.js";import{operationFor as L}from"./operations.js";import{CONTROL_BODY_MAX_BYTES as F}from"../../core/llm/body-limits.js";import{getRequest as Y,getRequestByInboxTicket as V}from"../../core/human/requests.js";import{requireVisibleReview as R}from"../../core/review/store.js";import{getComment as O}from"../../core/review/comments.js";async function D(e,t,o,s,n){const r=e.path,a=n&&typeof n=="object"&&!Array.isArray(n)?n:{};if(r==="/v1/human/requests"||r==="/v1/human/reviews"){const d=r.endsWith("/reviews")?a.origin_node_id:a.requester_node_id,h=r==="/v1/human/requests"&&d==null;if(d!==t.node&&!h)throw new c(403,"other_app_run","a broker may create a human request only for its own node");const i=a.source;if(i&&typeof i=="object"&&"nodeId"in i&&i.nodeId!==t.node)throw new c(403,"other_app_run","request source must name the calling node")}if(r==="/v1/human/reviews/self/comments"&&e.method==="GET"&&s.get("actor_node_id")!==t.node)throw new c(403,"other_app_run","self review requires the calling node");if(r.includes("/comments")&&e.method!=="GET"&&a.actor_node_id!==t.node)throw new c(403,"other_app_run","comment author must be the calling node");if(o.comment_id&&!await O(o.comment_id))throw new c(404,"not_found","comment not found")}u(D,"authorizeHumanBody");function g(e){return e.class==="broker"||e.class==="cron"}u(g,"boundedByStoredScopes");function b(e){return e.class==="person"||e.class==="anonymous"||e.class==="machine"?null:e.class==="forwarded"?e.actor.kind==="app"?e.actor.app:null:e.app}u(b,"appOf");function q(e){return e.class==="person"||e.class==="forwarded"&&e.actor.kind==="person"}u(q,"actsAsPerson");async function $(e){const t=await x(e.actor.app,e.sub);if(!t)throw new c(403,"app_not_granted",`${e.actor.app} holds no active grant for ${e.sub} on this machine`);return t}u($,"forwardedGrant");async function v(e){if(e.class==="person"||e.class==="anonymous"||e.class==="machine")return[];if(e.class==="forwarded"){if(e.actor.kind==="person")return[];const{resolved:o}=await $(e),s=e.actor.node_scopes;return s===null?o:s.filter(n=>J(o,n))}if(e.class==="app")return e.scopes;if(e.class==="cron"){const o=await M({grantee:e.app,sub:e.sub,grant_id:e.grant,scopes:e.scopes});if(o.allowed)return o.effectiveScopes;throw o.reason==="grant_missing"||o.reason==="grant_revoked"?new c(401,"grant_revoked",o.message):new c(403,"scope_missing",o.message)}const t=e.grant?await B(e.grant):await x(e.app,e.sub);if(t&&t.grantee===e.app&&t.sub===e.sub)return t.resolved;if(e.app==="app:terminal"&&!P("user").runtime?.issuer)return I;throw new c(401,"grant_revoked","the node grant is not active")}u(v,"resolvedScopes");function k(e){return"class"in e?b(e):e.grantee}u(k,"runCallerApp");async function l(e,t,o){return t===void 0||!("class"in e)?!0:e.class==="cron"?await S({run:e.origin_run??"",isolated:e.isolated},e.app,t,o):e.class==="forwarded"?e.actor.kind!=="app"||await S(e.actor.place,e.actor.app,t,o):e.class!=="broker"?!0:await H(e.node,e.app,t,o)}u(l,"brokerMayReach");async function X(e,t,o){const s=k(e);if(s===t)return await l(e,o,t);if(s===null)return!0;const n="class"in e?null:await B(e.grant),r="class"in e?await v(e):n?.sub===e.sub&&n.grantee===e.grantee?n.resolved:[];return f(r,`crtr:conversations:read:${t}`)&&(!("class"in e)||!g(e)||f(e.scopes,`crtr:conversations:read:${t}`))}u(X,"canReadRun");async function Be(e,t,o=!1,s=!1){const n=await y(t);if(!n||n.parent!==null||n.run_id!==t||!n.grantee||n.deleting_at&&!s)throw new _(404,"not_found","run not found");if(!await X(e,n.grantee,t))throw new _(404,"not_found","run not found");if(o&&k(e)!==null&&k(e)!==n.grantee)throw new _(403,"other_app_run","cannot change another app's run");return await z(t,n.grantee,s)}u(Be,"requireRun");async function C(e,t,o){return q(e)?!0:e.class==="anonymous"||e.class==="machine"?!1:b(e)===t?await l(e,o,t):f(await v(e),`crtr:objects:read:${t}`)&&(!g(e)||f(e.scopes,`crtr:objects:read:${t}`))}u(C,"canReadNode");const K=new Set(["messages.post.58","messages.post.59"]);async function Q(e,t,o){if(!e.classes.includes(t.class)&&!(t.class!=="anonymous"&&t.class!=="machine"&&t.class!=="forwarded"&&e.classes.includes("anonymous")))throw new c(403,"permission_error","this operation is not available to the caller");if(t.class==="forwarded"&&t.actor.kind==="app"&&await $(t),t.class==="person"||t.class==="anonymous"||t.class==="machine"||q(t))return;const s=await v(t);if(e.scope&&(!f(s,e.scope)||g(t)&&!f(t.scopes,e.scope)))throw new c(403,"scope_missing",`missing scope ${e.scope}`);if(t.class==="app")return;const n=b(t);t.class==="broker"&&await Z(e,t,o,s);const r=o.id;if((e.resource==="node-read"||e.resource==="node-write")&&r!==void 0){const a=await y(r);if(!a)return;if(e.resource==="node-write"&&a.grantee!==n&&!(K.has(e.name)&&f(s,`crtr:objects:message:${a.grantee??"app:terminal"}`)))throw new c(403,"other_app_run","cannot change another app's node");if(e.resource==="node-write"&&!await l(t,r,a.grantee??"app:terminal"))throw new c(404,"not_found","node not found");if(e.resource==="node-read"&&!await C(t,a.grantee??"app:terminal",r))throw new c(404,"not_found","node not found")}}u(Q,"authorizeOperation");async function Z(e,t,o,s){if(e.resource==="daemon-bash"&&(!f(s,"crtr:files:rw:user:.")||!f(t.scopes,"crtr:files:rw:user:.")))throw new c(403,"scope_missing","missing scope crtr:files:rw:user:.");if(e.resource==="human"){const r=e.path,a=e.method==="GET";if(!a&&(r.endsWith("/respond")||r.endsWith("/submit")||r.endsWith("/dismiss")||r.endsWith("/progress")||r.endsWith("/comment-ranges")||r.includes("/feedback-comments")))throw new c(403,"permission_error","only the person may answer or edit the human inbox");const d=o.request_id?await Y(o.request_id):o.ticket_id?await V(o.ticket_id):null,h=o.comment_id?await O(o.comment_id):null,i=o.review_id?await R(o.review_id):h?await R(h.review_id):null,w=d?.requester_node_id??i?.origin_node_id;if(w!=null){const m=await y(w);if(m&&(a?!await C(t,m.grantee??"app:terminal",w):m.grantee!==t.app))throw new c(a?404:403,a?"not_found":"other_app_run","human request belongs to another app");if(m&&!a&&!await l(t,w,m.grantee??"app:terminal"))throw new c(404,"not_found","human request not found")}else if(d||i)throw new c(403,"permission_error","only the person may access a request without a node")}const n=o.id;if(e.resource==="node-own"&&n!==void 0&&n!==t.node)throw new c(403,"other_app_run","the operation requires the calling node")}u(Z,"authorizeBrokerOnly");function ee(e,t){if(!f(e,t))throw new N("the bearer token",t)}u(ee,"assertCeiling");function te(){return new c(403,"owner_only","this operation is owner-only; a scoped token does not reach it")}u(te,"ownerOnlyError");function xe(e){return e.map(t=>({...t,ownerOnly:!0}))}u(xe,"ownerOnly");class Se{static{u(this,"Router")}routes=[];register(t){const o=L(t.method,t.pattern);if(!o)throw new Error(`route has no operation row: ${t.method} ${t.pattern}`);if(this.routes.some(s=>s.method===t.method.toUpperCase()&&s.operation.path===t.pattern))throw new Error(`duplicate route: ${t.method} ${t.pattern}`);return this.routes.push({operation:o,method:t.method.toUpperCase(),segments:A(t.pattern),handler:t.handler,maxBodyBytes:t.maxBodyBytes??F}),this}registerAll(t){for(const o of t)this.register(o);return this}match(t,o){const s=t.toUpperCase(),n=A(o);for(const r of this.routes){if(r.method!==s)continue;const a=oe(r.segments,n);if(a!==null)return{handler:r.handler,params:a,operation:r.operation,maxBodyBytes:r.maxBodyBytes}}return null}async handle(t,o,s,n={class:"person"}){try{const r=new URL(t.url??"/","http://127.0.0.1"),a=(t.method??"GET").toUpperCase(),d=this.match(a,r.pathname);if(d===null){U(o,404,"not_found",`no route for ${a} ${r.pathname}`);return}if(await Q(d.operation,n,d.params),s!==null){if(d.operation.classes.length===1&&d.operation.classes[0]==="person")throw te();d.operation.scope&&ee(s,d.operation.scope)}let h;try{h=await ne(t,d.maxBodyBytes)}catch(m){const E=m instanceof T?"payload_too_large":"invalid_request";U(o,E==="payload_too_large"?413:400,E,m.message);return}n.class==="broker"&&d.operation.resource==="human"&&await D(d.operation,n,d.params,r.searchParams,h);const i={method:a,path:r.pathname,params:d.params,query:r.searchParams,body:h,ceiling:s,principal:n,...n.class==="anonymous"&&typeof t.headers.authorization=="string"?{publishToken:t.headers.authorization.slice(7)}:{},req:t,res:o},w=await d.handler(i);o.writableEnded||re(o,w)}catch(r){const{status:a,body:d}=j(r);a>=500&&p({event:"api.request.failed",level:"error",error:r instanceof Error?r:new Error(String(r)),...n.class==="broker"?{node_id:n.node}:{},fields:{method:(t.method??"GET").toUpperCase(),path:t.url??""}}),G(o,a,d)}}}function A(e){return e.split("/").filter(t=>t.length>0)}u(A,"splitPath");function oe(e,t){if(e.length!==t.length)return null;const o={};for(let s=0;s<e.length;s++){const n=e[s],r=t[s];if(n.startsWith(":"))o[n.slice(1)]=decodeURIComponent(r);else if(n!==r)return null}return o}u(oe,"matchSegments");class T extends Error{static{u(this,"BodyTooLargeError")}}async function ne(e,t){const o=[];let s=0;for await(const r of e){const a=r;if(s+=a.length,s>t)throw new T(`request body exceeds ${t} bytes`);o.push(a)}if(s===0)return;const n=Buffer.concat(o).toString("utf8").trim();if(n!=="")try{return JSON.parse(n)}catch{throw new Error("request body is not valid JSON")}}u(ne,"readJsonBody");function re(e,t){if(e.headersSent)return;const o={...t.headers??{}};if(t.rawBody!==void 0){e.writeHead(t.status,o),e.end(t.rawBody);return}if(t.status===204||t.body===void 0){e.writeHead(t.status,o),e.end();return}o["content-type"]===void 0&&(o["content-type"]="application/json; charset=utf-8"),e.writeHead(t.status,o),e.end(JSON.stringify(t.body))}u(re,"writeResult");function G(e,t,o){if(e.headersSent){e.end();return}e.writeHead(t,{"content-type":"application/json; charset=utf-8"}),e.end(JSON.stringify(o))}u(G,"writeJson");function U(e,t,o,s){G(e,t,{error:{code:o,message:s,origin:"runtime"}})}u(U,"writeError");export{Se as Router,q as actsAsPerson,b as appOf,ee as assertCeiling,l as brokerMayReach,C as canReadNode,X as canReadRun,xe as ownerOnly,te as ownerOnlyError,Be as requireRun,v as resolvedScopes,k as runCallerApp};
@@ -1 +1 @@
1
- var le=Object.defineProperty;var a=(r,o)=>le(r,"name",{value:o,configurable:!0});import{createServer as D}from"node:http";import{chmodSync as ae,existsSync as N,unlinkSync as F}from"node:fs";import{MINIMUM_RUNTIME_VERSION_HEADER as G,RUNTIME_VERSION_HEADER as z,minimumRuntimeRefusal as ue}from"../../api/runtime-version.js";import{CONTRACT_HEADER as P,CONTRACT_LEVEL as J,REQUIRED_CONTRACT_HEADER as V,contractRefusal as ce}from"../../api/contract.js";import{crtrVersion as I}from"../../shared/crtr-version.js";import{apiSocketPath as pe}from"../../core/canvas/paths.js";import{resolveNodeToken as de}from"../../core/canvas/node-tokens.js";import{grantFor as me,hasSyncedGrants as fe}from"../../core/grants/mirror.js";import{readConfig as x}from"../../core/config.js";import{peerUid as ge}from"../../native/linux.js";import{findScopedApiToken as he,getApiToken as Ae,listScopedApiTokens as Re}from"../../core/secrets.js";import{emitEvent as g}from"../../core/events/emit.js";import{envCrtrdTcp as ye,envCrtrdToken as ve}from"../../shared/env.js";import{Router as K}from"./router.js";import{handleAttachUpgrade as be,refuseUpgrade as h}from"./bridge.js";import{boundDaemonControl as Ee}from"../control.js";import{attachRoutes as we}from"./handlers/attach.js";import{peerRoutes as Te}from"../peer/handlers.js";import{bashJobRoutes as _e}from"./handlers/bash-jobs.js";import{bashRoutes as Se}from"./handlers/bash.js";import{hookExecRoutes as Ce}from"./handlers/hook-exec.js";import{brokerOperationRoutes as Q}from"./handlers/broker-ops.js";import{brokerSignalRoutes as ke,brokerSignalStreams as Oe}from"./handlers/broker-signals.js";import{brokerRecoveryRoutes as X,nodeFaultRoutes as Ue}from"./handlers/broker-recovery.js";import{canvasRoutes as He}from"./handlers/canvas.js";import{chatInventoryRoutes as Ne}from"./handlers/chat-inventory.js";import{daemonRoutes as ze}from"./handlers/daemon.js";import{fileRoutes as Pe}from"./handlers/files.js";import{focusRoutes as Ie}from"./handlers/focus.js";import{analyticsRoutes as xe}from"./handlers/analytics.js";import{memoryReadsRoutes as Be}from"./handlers/memory-reads.js";import{memoryRoutes as We}from"./handlers/memory.js";import{healthRoutes as $e}from"./handlers/health.js";import{humanRequestRoutes as Le}from"./handlers/human-requests.js";import{inboxRoutes as Me}from"./handlers/inbox.js";import{feedbackCommentRoutes as je}from"./handlers/feedback-comments.js";import{objectRoutes as De}from"./handlers/objects.js";import{customObjectRoutes as Fe}from"./handlers/custom-objects.js";import{docRoutes as Ge}from"./handlers/docs.js";import{deliveryRoutes as Y}from"./handlers/delivery.js";import{deliveryRetryRoutes as Je}from"./handlers/delivery-retry.js";import{packageDocRoutes as Ve}from"./handlers/package-docs.js";import{documentAccessRoutes as Ke}from"./handlers/document-access.js";import{pluginAppRoutes as Qe}from"./handlers/plugin-app-token.js";import{brokerMailRoutes as Z,messageRoutes as Xe}from"./handlers/messages.js";import{modelAuthRoutes as Ye}from"./handlers/modelauth.js";import{llmRoutes as Ze}from"./handlers/llm.js";import{providerRoutes as qe}from"./handlers/providers.js";import{modelConfigRoutes as er}from"./handlers/model-config.js";import{nodeRoutes as rr}from"./handlers/nodes.js";import{nodeRecordRoutes as tr}from"./handlers/node-records.js";import{nodeOutcomeRoutes as or}from"./handlers/node-outcomes.js";import{nodeEventRoutes as nr}from"./handlers/node-events.js";import{profileRoutes as ir}from"./handlers/profiles.js";import{prospectiveChatInventoryRoutes as sr}from"./handlers/prospective-chat-inventory.js";import{reportRoutes as lr}from"./handlers/reports.js";import{runRoutes as ar}from"./handlers/run-routes.js";import{reviewCommentRoutes as ur}from"./handlers/review-comments.js";import{reviewRoutes as cr}from"./handlers/reviews.js";import{subscriptionRoutes as pr}from"./handlers/subscriptions.js";import{structuredRequestRoutes as dr}from"./handlers/structured-requests.js";import{cronRoutes as mr}from"./handlers/crons.js";import{setCronRequestHandler as q}from"../cron/run-socket.js";import{worktreeRoutes as fr}from"./handlers/worktree.js";import{limitsRoutes as gr}from"./handlers/limits.js";function hr(r){return new K().registerAll($e(r)).registerAll(ze).registerAll(rr).registerAll(tr).registerAll(or).registerAll(Je).registerAll(nr).registerAll(_e).registerAll(Se).registerAll(Ce).registerAll(Q).registerAll(ke).registerAll(Y).registerAll(X).registerAll(Ue).registerAll(fr).registerAll(gr).registerAll(Z).registerAll(Xe).registerAll(lr).registerAll(ar).registerAll(dr).registerAll(we).registerAll(He).registerAll(xe).registerAll(Be).registerAll(We).registerAll(Pe).registerAll(De).registerAll(Fe).registerAll(Ge).registerAll(Ve).registerAll(Ke).registerAll(Qe).registerAll(Ie).registerAll(pr).registerAll(mr).registerAll(ir).registerAll(Ye).registerAll(Ze).registerAll(qe).registerAll(er).registerAll(cr).registerAll(ur).registerAll(Me).registerAll(Le).registerAll(Ne).registerAll(sr).registerAll(je).registerAll(Te)}a(hr,"buildRouter");function Ar(r,o){if(r.toUpperCase()!=="GET")return null;const l=o.split("/").filter(f=>f.length>0);if(l.length!==4||l[0]!=="v1"||l[1]!=="nodes"||l[3]!=="attach")return null;const p=l[2];return p===void 0||p===""?null:decodeURIComponent(p)}a(Ar,"attachNodeId");function Rr(r){const o=r.trim();if(o==="")return null;const l=o.lastIndexOf(":");if(l<0)return null;const p=o.slice(0,l),f=o.slice(l+1),m=Number(f);return!Number.isInteger(m)||m<0||m>65535?null:{host:p===""?"0.0.0.0":p,port:m}}a(Rr,"parseTcp");function yr(r,o){return`${r.includes(":")?`[${r}]`:r}:${o}`}a(yr,"formatTcpAddress");const R={code:"unauthorized",message:"missing or invalid bearer token"},v={code:"owner_only",message:"attach is owner-only; a scoped token does not reach it"},B={class:"anonymous",app:"",node:"",run:null,uid:-1,sub:"",grant:null,client_id:null,scopes:[]},b=new WeakMap;function ee(r){return b.get(r)}a(ee,"socketPrincipal");function re(r,o){const l=process.platform==="linux"?ge(r.socket):null,p=r.headers.authorization;if(p===void 0)return l===null||o.has(l)?{class:"person"}:"unauthorized";if(typeof p!="string"||!p.startsWith("Bearer "))return"unauthorized";if(p.slice(7).startsWith("crtr_pub_"))return B;if(p.slice(7).startsWith(W)){const A=O(p.slice(7));return A!==void 0&&(l===null||o.has(l))?A.principal:"unauthorized"}const f=de(p.slice(7));if(!f||l!==null&&l!==f.uid)return"unauthorized";const m=x("user").runtime?.issuer;if(m&&!fe(m.replace(/\/$/,"")))return"runtime_starting";const C=f.grant??me("app:terminal",f.sub)?.id??null;return{class:"broker",...f,grant:C}}a(re,"resolveSocketPrincipal");const W="crtr_app_";function O(r){const o=r.startsWith(W)?he(r):void 0;return o===void 0?void 0:{principal:{class:"app",app:o.grantee,scopes:o.scopes},ceiling:o.scopes}}a(O,"appBearer");function vr(r){const o=new Map;for(const l of Re("user"))o.set(l.token,{principal:{class:"app",app:l.grantee,scopes:l.scopes},ceiling:l.scopes});return o.set(r,{principal:{class:"person"},ceiling:null}),o}a(vr,"resolveBearers");function te(r,o){const l=r.headers.authorization;if(typeof l!="string"||!l.startsWith("Bearer "))return;const p=l.slice(7);return p.startsWith(W)?O(p):o.get(p)}a(te,"authorize");function U(r){r.setHeader(z,I()),r.setHeader(P,J)}a(U,"advertiseRuntime");function _(r){r.setHeader("Access-Control-Allow-Origin","*"),r.setHeader("Access-Control-Expose-Headers",`${z}, ${P}`)}a(_,"exposeRuntimeHeaders");function oe(r,o){return(r.method??"GET").toUpperCase()!=="OPTIONS"?!1:(U(o),o.writeHead(204,{"Access-Control-Allow-Origin":"*","Access-Control-Expose-Headers":`${z}, ${P}`,"Access-Control-Allow-Headers":`authorization, content-type, ${G.toLowerCase()}, ${V.toLowerCase()}`,"Access-Control-Allow-Methods":"GET, POST, PATCH, PUT, DELETE, OPTIONS","Access-Control-Max-Age":"600"}),o.end(),!0)}a(oe,"answerPreflight");function S(r,o=!1){U(r),o&&_(r),r.writeHead(401,{"content-type":"application/json; charset=utf-8"}),r.end(JSON.stringify({error:{...R,origin:"runtime"}}))}a(S,"writeUnauthorized");function br(r,o){r.writeHead(503,{"content-type":"application/json; charset=utf-8"}),r.end(JSON.stringify({error:{code:"startup_blocked",message:o,origin:"runtime"}}))}a(br,"writeStartupBlocked");function ne(r){return new Promise(o=>{try{r.closeAllConnections()}catch{}r.close(()=>o())})}a(ne,"closeServer");function It(r={}){let o=null;const l=hr(()=>o),p=new K().registerAll(Q).registerAll(Y).registerAll(X).registerAll(Z),f=a((e,t)=>{const i=Ee()?.startupBlock()??null;return i===null||e==="GET"&&(t==="/healthz"||t==="/v1/status"||t==="/v1/ready")||e==="POST"&&(t==="/v1/daemon/migrate"||t==="/v1/daemon/admit")||i.phase==="recovering"&&p.match(e,t)!==null?null:i},"startupBlockFor"),m=pe(),C=new Set([process.getuid?.()??0,...x("user").runtime?.person_uids??[]]),A=a((e,t,i)=>{U(t);const c=a(u=>Array.isArray(u)?u[0]:u,"first"),E=c(e.headers[G.toLowerCase()]),n=ue(E,I())??ce(c(e.headers[V.toLowerCase()]),J,{legacyMinimum:E,runtimeVersion:I()});if(n!==null){t.writeHead(n.status,{"content-type":"application/json; charset=utf-8"}),t.end(JSON.stringify({error:{code:n.code,message:n.message,type:"invalid_request_error",origin:"runtime",retryable:!1,..."param"in n?{param:n.param}:{details:n.details}}}));return}const s=a(u=>{const w=ee(e);g({event:"api.request.failed",level:"error",...w?.class==="broker"?{node_id:w.node}:{},error:u instanceof Error?u:new Error(String(u))});try{t.headersSent||t.writeHead(500,{"content-type":"application/json; charset=utf-8"}),t.end(JSON.stringify({error:{code:"internal",message:"internal error",origin:"runtime"}}))}catch{}},"internalFailure");let d;try{d=new URL(e.url??"/","http://127.0.0.1")}catch{try{t.writeHead(400,{"content-type":"application/json; charset=utf-8"}),t.end(JSON.stringify({error:{code:"invalid_request",message:"request URL is invalid",origin:"runtime"}}))}catch{}return}try{const u=f((e.method??"GET").toUpperCase(),d.pathname);if(u!==null){br(t,u.message);return}l.handle(e,t,i,ee(e)??{class:"person"}).catch(s)}catch(u){s(u)}},"onRequest"),H=a((e,t,i)=>{t.on("error",()=>{});try{const c=new URL(e.url??"/","http://127.0.0.1"),E=f((e.method??"GET").toUpperCase(),c.pathname);if(E!==null){h(t,503,"Service Unavailable","startup_blocked",E.message);return}const n=Ar(e.method??"GET",c.pathname);if(n===null){t.destroy();return}be(e,t,i,n).catch(()=>{try{t.destroy()}catch{}})}catch{try{t.destroy()}catch{}}},"onUpgrade"),ie=a(e=>{e.on("error",t=>{g({event:"api.server.failed",level:"error",error:t})})},"bindErrorHandler"),T=D((e,t)=>{try{const i=re(e,C);if(i==="unauthorized"){g({event:"api.principal.denied",level:"warn",fields:{method:e.method}}),S(t);return}if(i==="runtime_starting"){U(t),t.writeHead(503,{"content-type":"application/json; charset=utf-8"}),t.end(JSON.stringify({error:{code:"runtime_starting",message:"grant sync is not ready",type:"server_error",origin:"runtime",retryable:!0}}));return}b.set(e,i),i.class==="broker"&&g({event:"api.request.principal",level:i.app==="app:terminal"?"debug":"info",node_id:i.node,fields:{principal:`${i.app} node:${i.node}`,method:e.method,path:e.url}}),A(e,t,i.class==="app"?i.scopes:null)}catch(i){g({event:"api.principal.failed",level:"error",error:i instanceof Error?i:new Error(String(i))}),S(t)}});T.on("upgrade",(e,t,i)=>{try{const c=re(e,C);if(c==="unauthorized"||c==="runtime_starting"){c==="unauthorized"&&g({event:"api.principal.denied",level:"warn",fields:{method:e.method}}),h(t,c==="unauthorized"?401:503,"Unauthorized",c,"socket principal unavailable");return}if(c.class!=="person"&&c.class!=="broker"){h(t,403,"Forbidden",v.code,v.message);return}b.set(e,c),H(e,t,i)}catch(c){g({event:"api.principal.failed",level:"error",error:c instanceof Error?c:new Error(String(c))}),h(t,401,"Unauthorized",R.code,R.message)}}),q((e,t,i)=>{b.set(e,i),A(e,t,null)});let $=!1,L,M;const se=new Promise((e,t)=>{L=e,M=t});T.once("listening",()=>{$=!0,L()}),T.on("error",e=>{g({event:"api.server.failed",level:"error",error:e}),$||M(e)});try{N(m)&&F(m)}catch{}T.listen(m,()=>{try{ae(m,process.platform==="linux"&&N("/run/crtr/launcher.sock")?438:384)}catch(e){g({event:"api.socket.chmod_failed",level:"error",error:e instanceof Error?e:new Error(String(e))})}});let y;const k=r.tcp??ye()??x("user").api.tcp;if(k!==void 0&&k!==""){const e=Rr(k);if(e===null)g({event:"api.tcp.invalid",level:"error",error:new Error(`invalid CRTRD_TCP/--tcp spec: ${k}`)});else{const t=r.token??ve()??Ae("user"),i=t===void 0?void 0:vr(t),c=i===void 0?(n,s)=>{if(oe(n,s))return;const d=n.headers.authorization;if(typeof d=="string"&&d.startsWith("Bearer crtr_pub_"))b.set(n,B),_(s);else if(n.headers.origin!==void 0){S(s,!0);return}else if(d!==void 0){const w=typeof d=="string"&&d.startsWith("Bearer ")?O(d.slice(7)):void 0;if(w===void 0){S(s,!0);return}b.set(n,w.principal),_(s),A(n,s,w.ceiling);return}A(n,s,null)}:(n,s)=>{if(oe(n,s))return;const d=te(n,i);if(d===void 0&&n.headers.authorization?.startsWith("Bearer crtr_pub_")){b.set(n,B),_(s),A(n,s,null);return}if(d===void 0){S(s,!0);return}b.set(n,d.principal),_(s),A(n,s,d.ceiling)},E=i===void 0?(n,s,d)=>{if(n.headers.origin!==void 0){h(s,401,"Unauthorized",R.code,R.message);return}const u=n.headers.authorization;if(u!==void 0){if(typeof u=="string"&&u.startsWith("Bearer crtr_pub_")){h(s,403,"Forbidden",v.code,v.message);return}(typeof u=="string"&&u.startsWith("Bearer ")?O(u.slice(7)):void 0)===void 0?h(s,401,"Unauthorized",R.code,R.message):h(s,403,"Forbidden",v.code,v.message);return}H(n,s,d)}:(n,s,d)=>{const u=te(n,i);if(u===void 0){h(s,401,"Unauthorized",R.code,R.message);return}if(u.ceiling!==null){h(s,403,"Forbidden",v.code,v.message);return}H(n,s,d)};y=D(c),y.on("upgrade",E),ie(y),y.once("listening",()=>{const n=y?.address();if(n!==null&&typeof n=="object"){const{address:s,port:d}=n;o=yr(s,d)}}),y.listen(e.port,e.host)}}let j=!1;return{ready:se,tcpAddress:a(()=>o,"tcpAddress"),close:a(async()=>{if(!j){j=!0,q(null),Oe.close(),await Promise.all([ne(T),y!==void 0?ne(y):Promise.resolve()]);try{N(m)&&F(m)}catch{}}},"close")}}a(It,"createApiServer");export{hr as buildRouter,It as createApiServer,ee as socketPrincipal};
1
+ var ce=Object.defineProperty;var a=(t,o)=>ce(t,"name",{value:o,configurable:!0});import{createServer as D}from"node:http";import{chmodSync as ue,existsSync as N,unlinkSync as F}from"node:fs";import{MINIMUM_RUNTIME_VERSION_HEADER as G,RUNTIME_VERSION_HEADER as z,minimumRuntimeRefusal as pe}from"../../api/runtime-version.js";import{CONTRACT_HEADER as P,CONTRACT_LEVEL as J,REQUIRED_CONTRACT_HEADER as V,contractRefusal as de}from"../../api/contract.js";import{crtrVersion as I}from"../../shared/crtr-version.js";import{apiSocketPath as me}from"../../core/canvas/paths.js";import{resolveNodeToken as fe}from"../../core/canvas/node-tokens.js";import{grantFor as ge,hasSyncedGrants as he}from"../../core/grants/mirror.js";import{readConfig as x}from"../../core/config.js";import{peerUid as Ae}from"../../native/linux.js";import{findScopedApiToken as Re,getApiToken as ye,listScopedApiTokens as ve}from"../../core/secrets.js";import{emitEvent as g}from"../../core/events/emit.js";import{envCrtrdTcp as be,envCrtrdToken as Ee}from"../../shared/env.js";import{Router as K}from"./router.js";import{handleAttachUpgrade as we,refuseUpgrade as h}from"./bridge.js";import{boundDaemonControl as Se}from"../control.js";import{attachRoutes as Te}from"./handlers/attach.js";import{peerRoutes as _e}from"../peer/handlers.js";import{bashJobRoutes as Ce}from"./handlers/bash-jobs.js";import{bashRoutes as ke}from"./handlers/bash.js";import{hookExecRoutes as Oe}from"./handlers/hook-exec.js";import{brokerOperationRoutes as Q}from"./handlers/broker-ops.js";import{brokerSignalRoutes as Ue,brokerSignalStreams as He}from"./handlers/broker-signals.js";import{brokerRecoveryRoutes as X,nodeFaultRoutes as Ne}from"./handlers/broker-recovery.js";import{canvasRoutes as ze}from"./handlers/canvas.js";import{chatInventoryRoutes as Pe}from"./handlers/chat-inventory.js";import{daemonRoutes as Ie}from"./handlers/daemon.js";import{fileRoutes as xe}from"./handlers/files.js";import{focusRoutes as Be}from"./handlers/focus.js";import{analyticsRoutes as We}from"./handlers/analytics.js";import{memoryReadsRoutes as $e}from"./handlers/memory-reads.js";import{memoryRoutes as Le}from"./handlers/memory.js";import{healthRoutes as Me}from"./handlers/health.js";import{humanRequestRoutes as je}from"./handlers/human-requests.js";import{inboxRoutes as De}from"./handlers/inbox.js";import{feedbackCommentRoutes as Fe}from"./handlers/feedback-comments.js";import{objectRoutes as Ge}from"./handlers/objects.js";import{customObjectRoutes as Je}from"./handlers/custom-objects.js";import{docRoutes as Ve}from"./handlers/docs.js";import{deliveryRoutes as Y}from"./handlers/delivery.js";import{deliveryRetryRoutes as Ke}from"./handlers/delivery-retry.js";import{packageDocRoutes as Qe}from"./handlers/package-docs.js";import{documentAccessRoutes as Xe}from"./handlers/document-access.js";import{pluginAppRoutes as Ye}from"./handlers/plugin-app-token.js";import{brokerMailRoutes as Z,messageRoutes as Ze}from"./handlers/messages.js";import{modelAuthRoutes as qe}from"./handlers/modelauth.js";import{llmRoutes as er}from"./handlers/llm.js";import{providerRoutes as rr}from"./handlers/providers.js";import{modelConfigRoutes as tr}from"./handlers/model-config.js";import{nodeRoutes as or}from"./handlers/nodes.js";import{nodeRecordRoutes as nr}from"./handlers/node-records.js";import{nodeOutcomeRoutes as ir}from"./handlers/node-outcomes.js";import{nodeEventRoutes as sr}from"./handlers/node-events.js";import{profileRoutes as lr}from"./handlers/profiles.js";import{prospectiveChatInventoryRoutes as ar}from"./handlers/prospective-chat-inventory.js";import{reportRoutes as cr}from"./handlers/reports.js";import{runRoutes as ur}from"./handlers/run-routes.js";import{reviewCommentRoutes as pr}from"./handlers/review-comments.js";import{reviewRoutes as dr}from"./handlers/reviews.js";import{subscriptionRoutes as mr}from"./handlers/subscriptions.js";import{structuredRequestRoutes as fr}from"./handlers/structured-requests.js";import{cronRoutes as gr}from"./handlers/crons.js";import{setCronRequestHandler as q}from"../cron/run-socket.js";import{worktreeRoutes as hr}from"./handlers/worktree.js";import{limitsRoutes as Ar}from"./handlers/limits.js";function Rr(t){return new K().registerAll(Me(t)).registerAll(Ie).registerAll(or).registerAll(nr).registerAll(ir).registerAll(Ke).registerAll(sr).registerAll(Ce).registerAll(ke).registerAll(Oe).registerAll(Q).registerAll(Ue).registerAll(Y).registerAll(X).registerAll(Ne).registerAll(hr).registerAll(Ar).registerAll(Z).registerAll(Ze).registerAll(cr).registerAll(ur).registerAll(fr).registerAll(Te).registerAll(ze).registerAll(We).registerAll($e).registerAll(Le).registerAll(xe).registerAll(Ge).registerAll(Je).registerAll(Ve).registerAll(Qe).registerAll(Xe).registerAll(Ye).registerAll(Be).registerAll(mr).registerAll(gr).registerAll(lr).registerAll(qe).registerAll(er).registerAll(rr).registerAll(tr).registerAll(dr).registerAll(pr).registerAll(De).registerAll(je).registerAll(Pe).registerAll(ar).registerAll(Fe).registerAll(_e)}a(Rr,"buildRouter");function yr(t,o){if(t.toUpperCase()!=="GET")return null;const l=o.split("/").filter(f=>f.length>0);if(l.length!==4||l[0]!=="v1"||l[1]!=="nodes"||l[3]!=="attach")return null;const p=l[2];return p===void 0||p===""?null:decodeURIComponent(p)}a(yr,"attachNodeId");function vr(t){const o=t.trim();if(o==="")return null;const l=o.lastIndexOf(":");if(l<0)return null;const p=o.slice(0,l),f=o.slice(l+1),m=Number(f);return!Number.isInteger(m)||m<0||m>65535?null:{host:p===""?"0.0.0.0":p,port:m}}a(vr,"parseTcp");function br(t,o){return`${t.includes(":")?`[${t}]`:t}:${o}`}a(br,"formatTcpAddress");const R={code:"unauthorized",message:"missing or invalid bearer token"},v={code:"owner_only",message:"attach is owner-only; a scoped token does not reach it"},B={class:"anonymous",app:"",node:"",run:null,uid:-1,sub:"",grant:null,client_id:null,scopes:[]},b=new WeakMap;function ee(t){return b.get(t)}a(ee,"socketPrincipal");async function re(t,o){const l=process.platform==="linux"?Ae(t.socket):null,p=t.headers.authorization;if(p===void 0)return l===null||o.has(l)?{class:"person"}:"unauthorized";if(typeof p!="string"||!p.startsWith("Bearer "))return"unauthorized";if(p.slice(7).startsWith("crtr_pub_"))return B;if(p.slice(7).startsWith(W)){const A=O(p.slice(7));return A!==void 0&&(l===null||o.has(l))?A.principal:"unauthorized"}const f=await fe(p.slice(7));if(!f||l!==null&&l!==f.uid)return"unauthorized";const m=x("user").runtime?.issuer;if(m&&!await he(m.replace(/\/$/,"")))return"runtime_starting";const C=f.grant??(await ge("app:terminal",f.sub))?.id??null;return{class:"broker",...f,grant:C}}a(re,"resolveSocketPrincipal");const W="crtr_app_";function O(t){const o=t.startsWith(W)?Re(t):void 0;return o===void 0?void 0:{principal:{class:"app",app:o.grantee,scopes:o.scopes},ceiling:o.scopes}}a(O,"appBearer");function Er(t){const o=new Map;for(const l of ve("user"))o.set(l.token,{principal:{class:"app",app:l.grantee,scopes:l.scopes},ceiling:l.scopes});return o.set(t,{principal:{class:"person"},ceiling:null}),o}a(Er,"resolveBearers");function te(t,o){const l=t.headers.authorization;if(typeof l!="string"||!l.startsWith("Bearer "))return;const p=l.slice(7);return p.startsWith(W)?O(p):o.get(p)}a(te,"authorize");function U(t){t.setHeader(z,I()),t.setHeader(P,J)}a(U,"advertiseRuntime");function T(t){t.setHeader("Access-Control-Allow-Origin","*"),t.setHeader("Access-Control-Expose-Headers",`${z}, ${P}`)}a(T,"exposeRuntimeHeaders");function oe(t,o){return(t.method??"GET").toUpperCase()!=="OPTIONS"?!1:(U(o),o.writeHead(204,{"Access-Control-Allow-Origin":"*","Access-Control-Expose-Headers":`${z}, ${P}`,"Access-Control-Allow-Headers":`authorization, content-type, ${G.toLowerCase()}, ${V.toLowerCase()}`,"Access-Control-Allow-Methods":"GET, POST, PATCH, PUT, DELETE, OPTIONS","Access-Control-Max-Age":"600"}),o.end(),!0)}a(oe,"answerPreflight");function _(t,o=!1){U(t),o&&T(t),t.writeHead(401,{"content-type":"application/json; charset=utf-8"}),t.end(JSON.stringify({error:{...R,origin:"runtime"}}))}a(_,"writeUnauthorized");function wr(t,o){t.writeHead(503,{"content-type":"application/json; charset=utf-8"}),t.end(JSON.stringify({error:{code:"startup_blocked",message:o,origin:"runtime"}}))}a(wr,"writeStartupBlocked");function ne(t){return new Promise(o=>{try{t.closeAllConnections()}catch{}t.close(()=>o())})}a(ne,"closeServer");function Bt(t={}){let o=null;const l=Rr(()=>o),p=new K().registerAll(Q).registerAll(Y).registerAll(X).registerAll(Z),f=a((e,r)=>{const n=Se()?.startupBlock()??null;return n===null||e==="GET"&&(r==="/healthz"||r==="/v1/status"||r==="/v1/ready")||e==="POST"&&(r==="/v1/daemon/migrate"||r==="/v1/daemon/admit")||n.phase==="recovering"&&p.match(e,r)!==null?null:n},"startupBlockFor"),m=me(),C=new Set([process.getuid?.()??0,...x("user").runtime?.person_uids??[]]),A=a((e,r,n)=>{U(r);const c=a(u=>Array.isArray(u)?u[0]:u,"first"),E=c(e.headers[G.toLowerCase()]),i=pe(E,I())??de(c(e.headers[V.toLowerCase()]),J,{legacyMinimum:E,runtimeVersion:I()});if(i!==null){r.writeHead(i.status,{"content-type":"application/json; charset=utf-8"}),r.end(JSON.stringify({error:{code:i.code,message:i.message,type:"invalid_request_error",origin:"runtime",retryable:!1,..."param"in i?{param:i.param}:{details:i.details}}}));return}const s=a(u=>{const w=ee(e);g({event:"api.request.failed",level:"error",...w?.class==="broker"?{node_id:w.node}:{},error:u instanceof Error?u:new Error(String(u))});try{r.headersSent||r.writeHead(500,{"content-type":"application/json; charset=utf-8"}),r.end(JSON.stringify({error:{code:"internal",message:"internal error",origin:"runtime"}}))}catch{}},"internalFailure");let d;try{d=new URL(e.url??"/","http://127.0.0.1")}catch{try{r.writeHead(400,{"content-type":"application/json; charset=utf-8"}),r.end(JSON.stringify({error:{code:"invalid_request",message:"request URL is invalid",origin:"runtime"}}))}catch{}return}try{const u=f((e.method??"GET").toUpperCase(),d.pathname);if(u!==null){wr(r,u.message);return}l.handle(e,r,n,ee(e)??{class:"person"}).catch(s)}catch(u){s(u)}},"onRequest"),H=a((e,r,n)=>{r.on("error",()=>{});try{const c=new URL(e.url??"/","http://127.0.0.1"),E=f((e.method??"GET").toUpperCase(),c.pathname);if(E!==null){h(r,503,"Service Unavailable","startup_blocked",E.message);return}const i=yr(e.method??"GET",c.pathname);if(i===null){r.destroy();return}we(e,r,n,i).catch(()=>{try{r.destroy()}catch{}})}catch{try{r.destroy()}catch{}}},"onUpgrade"),ie=a(e=>{e.on("error",r=>{g({event:"api.server.failed",level:"error",error:r})})},"bindErrorHandler"),se=a(async(e,r)=>{try{const n=await re(e,C);if(n==="unauthorized"){g({event:"api.principal.denied",level:"warn",fields:{method:e.method}}),_(r);return}if(n==="runtime_starting"){U(r),r.writeHead(503,{"content-type":"application/json; charset=utf-8"}),r.end(JSON.stringify({error:{code:"runtime_starting",message:"grant sync is not ready",type:"server_error",origin:"runtime",retryable:!0}}));return}b.set(e,n),n.class==="broker"&&g({event:"api.request.principal",level:n.app==="app:terminal"?"debug":"info",node_id:n.node,fields:{principal:`${n.app} node:${n.node}`,method:e.method,path:e.url}}),A(e,r,n.class==="app"?n.scopes:null)}catch(n){g({event:"api.principal.failed",level:"error",error:n instanceof Error?n:new Error(String(n))}),_(r)}},"onSocketRequest"),S=D((e,r)=>{se(e,r).catch(n=>g({event:"api.principal.failed",level:"error",error:n instanceof Error?n:new Error(String(n))}))}),le=a(async(e,r,n)=>{try{const c=await re(e,C);if(c==="unauthorized"||c==="runtime_starting"){c==="unauthorized"&&g({event:"api.principal.denied",level:"warn",fields:{method:e.method}}),h(r,c==="unauthorized"?401:503,"Unauthorized",c,"socket principal unavailable");return}if(c.class!=="person"&&c.class!=="broker"){h(r,403,"Forbidden",v.code,v.message);return}b.set(e,c),H(e,r,n)}catch(c){g({event:"api.principal.failed",level:"error",error:c instanceof Error?c:new Error(String(c))}),h(r,401,"Unauthorized",R.code,R.message)}},"onSocketUpgrade");S.on("upgrade",(e,r,n)=>{le(e,r,n).catch(c=>g({event:"api.principal.failed",level:"error",error:c instanceof Error?c:new Error(String(c))}))}),q((e,r,n)=>{b.set(e,n),A(e,r,null)});let $=!1,L,M;const ae=new Promise((e,r)=>{L=e,M=r});S.once("listening",()=>{$=!0,L()}),S.on("error",e=>{g({event:"api.server.failed",level:"error",error:e}),$||M(e)});try{N(m)&&F(m)}catch{}S.listen(m,()=>{try{ue(m,process.platform==="linux"&&N("/run/crtr/launcher.sock")?438:384)}catch(e){g({event:"api.socket.chmod_failed",level:"error",error:e instanceof Error?e:new Error(String(e))})}});let y;const k=t.tcp??be()??x("user").api.tcp;if(k!==void 0&&k!==""){const e=vr(k);if(e===null)g({event:"api.tcp.invalid",level:"error",error:new Error(`invalid CRTRD_TCP/--tcp spec: ${k}`)});else{const r=t.token??Ee()??ye("user"),n=r===void 0?void 0:Er(r),c=n===void 0?(i,s)=>{if(oe(i,s))return;const d=i.headers.authorization;if(typeof d=="string"&&d.startsWith("Bearer crtr_pub_"))b.set(i,B),T(s);else if(i.headers.origin!==void 0){_(s,!0);return}else if(d!==void 0){const w=typeof d=="string"&&d.startsWith("Bearer ")?O(d.slice(7)):void 0;if(w===void 0){_(s,!0);return}b.set(i,w.principal),T(s),A(i,s,w.ceiling);return}A(i,s,null)}:(i,s)=>{if(oe(i,s))return;const d=te(i,n);if(d===void 0&&i.headers.authorization?.startsWith("Bearer crtr_pub_")){b.set(i,B),T(s),A(i,s,null);return}if(d===void 0){_(s,!0);return}b.set(i,d.principal),T(s),A(i,s,d.ceiling)},E=n===void 0?(i,s,d)=>{if(i.headers.origin!==void 0){h(s,401,"Unauthorized",R.code,R.message);return}const u=i.headers.authorization;if(u!==void 0){if(typeof u=="string"&&u.startsWith("Bearer crtr_pub_")){h(s,403,"Forbidden",v.code,v.message);return}(typeof u=="string"&&u.startsWith("Bearer ")?O(u.slice(7)):void 0)===void 0?h(s,401,"Unauthorized",R.code,R.message):h(s,403,"Forbidden",v.code,v.message);return}H(i,s,d)}:(i,s,d)=>{const u=te(i,n);if(u===void 0){h(s,401,"Unauthorized",R.code,R.message);return}if(u.ceiling!==null){h(s,403,"Forbidden",v.code,v.message);return}H(i,s,d)};y=D(c),y.on("upgrade",E),ie(y),y.once("listening",()=>{const i=y?.address();if(i!==null&&typeof i=="object"){const{address:s,port:d}=i;o=br(s,d)}}),y.listen(e.port,e.host)}}let j=!1;return{ready:ae,tcpAddress:a(()=>o,"tcpAddress"),close:a(async()=>{if(!j){j=!0,q(null),He.close(),await Promise.all([ne(S),y!==void 0?ne(y):Promise.resolve()]);try{N(m)&&F(m)}catch{}}},"close")}}a(Bt,"createApiServer");export{Rr as buildRouter,Bt as createApiServer,ee as socketPrincipal};
@@ -16,7 +16,7 @@ export declare class BrokerSignalBus {
16
16
  private readonly dirty;
17
17
  private readonly subscribers;
18
18
  private scheduled;
19
- subscribe(listener: BrokerSignalSubscriber): () => void;
19
+ subscribe(listener: BrokerSignalSubscriber): Promise<() => void>;
20
20
  markMail(nodeId: string): void;
21
21
  markNode(nodeId: string): void;
22
22
  private mark;
@@ -1,4 +1,4 @@
1
- var a=Object.defineProperty;var r=(t,e)=>a(t,"name",{value:e,configurable:!0});const d=["description","title","icon","mode","lifecycle","status","cwd","parent","fork_from","profile_id","review_binding_json","persona_ack_json","intent"],c=r(t=>t==="review_binding_json"?"review_binding":t==="persona_ack_json"?"persona_ack":t,"nodeField");function l(t){const e={};for(const i of d){const s=c(i);e[s]=t[s]}return e}r(l,"cachedBrokerNodeFields");class o{static{r(this,"BrokerSignalBus")}dirty=new Map;subscribers=new Set;scheduled;subscribe(e){return this.subscribers.add(e),()=>{this.subscribers.delete(e)}}markMail(e){this.mark(e,1)}markNode(e){this.mark(e,2)}mark(e,i){this.dirty.set(e,(this.dirty.get(e)??0)|i),this.scheduled??=setImmediate(()=>this.flush())}flush(){this.scheduled=void 0;const e=[...this.dirty];this.dirty.clear();for(const[i,s]of e)for(const n of this.subscribers)try{s&1&&n(i,"mail"),s&2&&n(i,"node")}catch{}}install(e){e.function("crtr_signal",{deterministic:!1},(i,s)=>{try{typeof s=="string"&&(i==="mail"&&this.markMail(s),i==="node"&&this.markNode(s))}catch{}return null}),e.exec(`
1
+ var a=Object.defineProperty;var r=(t,e)=>a(t,"name",{value:e,configurable:!0});const d=["description","title","icon","mode","lifecycle","status","cwd","parent","fork_from","profile_id","review_binding_json","persona_ack_json","intent"],c=r(t=>t==="review_binding_json"?"review_binding":t==="persona_ack_json"?"persona_ack":t,"nodeField");function l(t){const e={};for(const i of d){const s=c(i);e[s]=t[s]}return e}r(l,"cachedBrokerNodeFields");class o{static{r(this,"BrokerSignalBus")}dirty=new Map;subscribers=new Set;scheduled;async subscribe(e){return this.subscribers.add(e),()=>{this.subscribers.delete(e)}}markMail(e){this.mark(e,1)}markNode(e){this.mark(e,2)}mark(e,i){this.dirty.set(e,(this.dirty.get(e)??0)|i),this.scheduled??=setImmediate(()=>this.flush())}flush(){this.scheduled=void 0;const e=[...this.dirty];this.dirty.clear();for(const[i,s]of e)for(const n of this.subscribers)try{s&1&&n(i,"mail"),s&2&&n(i,"node")}catch{}}install(e){e.function("crtr_signal",{deterministic:!1},(i,s)=>{try{typeof s=="string"&&(i==="mail"&&this.markMail(s),i==="node"&&this.markNode(s))}catch{}return null}),e.exec(`
2
2
  CREATE TEMP TRIGGER crtr_sig_deliv_ins AFTER INSERT ON main.deliveries
3
3
  WHEN NEW.wake = 1 BEGIN SELECT crtr_signal('mail', NEW.destination_id); END;
4
4
  CREATE TEMP TRIGGER crtr_sig_deliv_upd AFTER UPDATE OF state, canceled_at, claim_owner ON main.deliveries
@@ -1 +1 @@
1
- var d=Object.defineProperty;var o=(i,r)=>d(i,"name",{value:r,configurable:!0});import{childrenOf as f,getNode as s}from"../core/canvas/canvas.js";import{FinalizationError as l,pushFinal as u}from"../core/feed/feed.js";import{transition as p}from"../core/runtime/lifecycle.js";import{requestBrokerTeardown as c}from"../core/runtime/host.js";async function m(i,r){const e=s(i);if(e===null)return"missing";const a=e.review_binding?.review_id;if(a!==void 0)for(const t of f(i))s(t)?.review_binding?.review_id===a&&await m(t,r);if(e.status==="canceled"||r==="canceled"&&e.status==="done")return"already";if(r==="approved"&&(e.status==="active"||e.status==="idle"||e.status==="done")){let t="retired";try{await u(i,"The companion conversation is complete.")}catch(n){if(!(n instanceof l)||n.code!=="already_finalized")throw n;t="already"}return c(i),t}return p(i,"cancel",{reason:"retired"}),(e.status==="active"||e.status==="idle")&&c(i),"retired"}o(m,"retireCompanion");export{m as retireCompanion};
1
+ var d=Object.defineProperty;var o=(e,r)=>d(e,"name",{value:r,configurable:!0});import{childrenOf as f,getNode as s}from"../core/canvas/canvas.js";import{FinalizationError as l,pushFinal as u}from"../core/feed/feed.js";import{transition as w}from"../core/runtime/lifecycle.js";import{requestBrokerTeardown as c}from"../core/runtime/host.js";async function p(e,r){const i=await s(e);if(i===null)return"missing";const n=i.review_binding?.review_id;if(n!==void 0)for(const t of await f(e))(await s(t))?.review_binding?.review_id===n&&await p(t,r);if(i.status==="canceled"||r==="canceled"&&i.status==="done")return"already";if(r==="approved"&&(i.status==="active"||i.status==="idle"||i.status==="done")){let t="retired";try{await u(e,"The companion conversation is complete.")}catch(a){if(!(a instanceof l)||a.code!=="already_finalized")throw a;t="already"}return c(e),t}return await w(e,"cancel",{reason:"retired"}),(i.status==="active"||i.status==="idle")&&c(e),"retired"}o(p,"retireCompanion");export{p as retireCompanion};
@@ -27,7 +27,7 @@ export declare function cronBirthPrincipalOf(c: Cron): CronBirthPrincipal;
27
27
  * existing parentless terminal root). It never takes a parent from another app, run or grant,
28
28
  * never takes the terminal's identity for an app cron, and never throws for a missing creator. */
29
29
  export type CronBirthPlacement = Pick<SpawnChildOpts, 'parent' | 'root' | 'rootLifecycle' | 'scopes' | 'run' | 'withinCreate'>;
30
- export declare function cronBirthPlacement(p: CronBirthPrincipal, nodeId: string): CronBirthPlacement;
30
+ export declare function cronBirthPlacement(p: CronBirthPrincipal, nodeId: string): Promise<CronBirthPlacement>;
31
31
  export declare function resolveLiveProfileOrRoot(c: Cron): string | null;
32
32
  export declare function resolveLiveProfileName(c: Cron): string | undefined;
33
33
  /** A stored context cannot be rebuilt; the run fails rather than running under a context nobody armed. */
@@ -39,4 +39,4 @@ export interface ArmedRunContext {
39
39
  env: NodeJS.ProcessEnv;
40
40
  }
41
41
  /** Rebuild the armed context. Corrupt snapshots and unreadable profiles fail rather than silently changing its identity or environment. */
42
- export declare function buildArmedRunContext(c: Cron, runId: string): ArmedRunContext;
42
+ export declare function buildArmedRunContext(c: Cron, runId: string): Promise<ArmedRunContext>;