@north-light/cli 0.3.529 → 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 (509) hide show
  1. package/dist/api/dto/lifecycle.d.ts +3 -1
  2. package/dist/api/dto/messages.d.ts +5 -3
  3. package/dist/builtin-memory/crouter-plugin/bundles-and-memory.md +1 -1
  4. package/dist/builtin-memory/crouter-plugin/commands.md +1 -1
  5. package/dist/clients/attach/session/connection.js +1 -1
  6. package/dist/clients/attach/session/reconnect.js +1 -1
  7. package/dist/clients/attach/viewer.js +508 -508
  8. package/dist/commands/node/message.js +1 -1
  9. package/dist/commands/sys/join.js +1 -1
  10. package/dist/core/async-array.d.ts +7 -0
  11. package/dist/core/async-array.js +1 -0
  12. package/dist/core/audit.d.ts +1 -1
  13. package/dist/core/audit.js +2 -2
  14. package/dist/core/canvas/attention.d.ts +4 -4
  15. package/dist/core/canvas/attention.js +1 -1
  16. package/dist/core/canvas/boot.d.ts +4 -4
  17. package/dist/core/canvas/boot.js +1 -1
  18. package/dist/core/canvas/canvas.d.ts +59 -59
  19. package/dist/core/canvas/canvas.js +19 -19
  20. package/dist/core/canvas/context-strip.js +2 -2
  21. package/dist/core/canvas/crons.d.ts +27 -27
  22. package/dist/core/canvas/crons.js +11 -11
  23. package/dist/core/canvas/daemon-actions.d.ts +10 -10
  24. package/dist/core/canvas/daemon-actions.js +8 -8
  25. package/dist/core/canvas/daemon-owner.d.ts +3 -3
  26. package/dist/core/canvas/daemon-owner.js +2 -2
  27. package/dist/core/canvas/db.d.ts +19 -30
  28. package/dist/core/canvas/db.js +3 -2
  29. package/dist/core/canvas/deliveries.d.ts +16 -16
  30. package/dist/core/canvas/deliveries.js +24 -24
  31. package/dist/core/canvas/executions.d.ts +8 -8
  32. package/dist/core/canvas/executions.js +1 -1
  33. package/dist/core/canvas/focuses.d.ts +8 -8
  34. package/dist/core/canvas/focuses.js +1 -1
  35. package/dist/core/canvas/history.d.ts +3 -3
  36. package/dist/core/canvas/history.js +9 -9
  37. package/dist/core/canvas/install-id.d.ts +1 -1
  38. package/dist/core/canvas/install-id.js +1 -1
  39. package/dist/core/canvas/managed-worktree-sweep-candidates.d.ts +1 -1
  40. package/dist/core/canvas/managed-worktree-sweep-candidates.js +2 -2
  41. package/dist/core/canvas/memory-reads.d.ts +6 -6
  42. package/dist/core/canvas/memory-reads.js +1 -1
  43. package/dist/core/canvas/nav-model.d.ts +13 -13
  44. package/dist/core/canvas/nav-model.js +1 -1
  45. package/dist/core/canvas/node-agent-paths.d.ts +6 -6
  46. package/dist/core/canvas/node-agent-paths.js +1 -1
  47. package/dist/core/canvas/node-tokens.d.ts +7 -7
  48. package/dist/core/canvas/node-tokens.js +3 -3
  49. package/dist/core/canvas/outcome-actions.d.ts +5 -5
  50. package/dist/core/canvas/outcome-actions.js +3 -3
  51. package/dist/core/canvas/recovery.d.ts +26 -26
  52. package/dist/core/canvas/recovery.js +2 -2
  53. package/dist/core/canvas/render-source.d.ts +1 -1
  54. package/dist/core/canvas/render-source.js +1 -1
  55. package/dist/core/canvas/sessions.d.ts +10 -10
  56. package/dist/core/canvas/sessions.js +4 -4
  57. package/dist/core/canvas/source.js +1 -1
  58. package/dist/core/canvas/structured-requests.d.ts +15 -15
  59. package/dist/core/canvas/structured-requests.js +5 -5
  60. package/dist/core/canvas/tree.d.ts +9 -9
  61. package/dist/core/canvas/tree.js +5 -5
  62. package/dist/core/canvas/waits.d.ts +13 -13
  63. package/dist/core/canvas/waits.js +6 -6
  64. package/dist/core/canvas/worktrees.d.ts +15 -15
  65. package/dist/core/canvas/worktrees.js +1 -1
  66. package/dist/core/command-hooks/lifecycle-catalog.d.ts +4 -4
  67. package/dist/core/command-hooks/lifecycle-catalog.js +1 -1
  68. package/dist/core/command-hooks/transport/exec-lifecycle.js +1 -1
  69. package/dist/core/command-plugins/bundle.d.ts +1 -1
  70. package/dist/core/command-plugins/bundle.js +1 -1
  71. package/dist/core/conversation-store/file-store.d.ts +7 -7
  72. package/dist/core/conversation-store/file-store.js +9 -9
  73. package/dist/core/conversation-store/index.d.ts +16 -14
  74. package/dist/core/conversation-store/index.js +1 -1
  75. package/dist/core/conversation-store/listener.js +5 -5
  76. package/dist/core/conversation-store/patch.d.ts +3 -1
  77. package/dist/core/conversation-store/patch.js +1 -1
  78. package/dist/core/directory/join.d.ts +1 -1
  79. package/dist/core/feed/feed.js +3 -3
  80. package/dist/core/feed/inbox.d.ts +2 -2
  81. package/dist/core/feed/inbox.js +1 -1
  82. package/dist/core/feed/messages.d.ts +11 -12
  83. package/dist/core/feed/messages.js +5 -5
  84. package/dist/core/feed/reports.d.ts +4 -4
  85. package/dist/core/feed/reports.js +2 -2
  86. package/dist/core/grants/cover.d.ts +1 -1
  87. package/dist/core/grants/cover.js +1 -1
  88. package/dist/core/grants/local.d.ts +1 -1
  89. package/dist/core/grants/local.js +1 -1
  90. package/dist/core/grants/mirror.d.ts +19 -19
  91. package/dist/core/grants/mirror.js +2 -2
  92. package/dist/core/grants/on-sync.d.ts +1 -1
  93. package/dist/core/grants/on-sync.js +1 -1
  94. package/dist/core/grants/remove.js +1 -1
  95. package/dist/core/grants/sync.js +1 -1
  96. package/dist/core/graph/access.d.ts +17 -17
  97. package/dist/core/graph/access.js +3 -3
  98. package/dist/core/graph/custom.d.ts +16 -16
  99. package/dist/core/graph/custom.js +9 -9
  100. package/dist/core/graph/deletion.d.ts +3 -7
  101. package/dist/core/graph/deletion.js +4 -4
  102. package/dist/core/graph/documents.d.ts +24 -27
  103. package/dist/core/graph/documents.js +7 -7
  104. package/dist/core/graph/edges.d.ts +13 -13
  105. package/dist/core/graph/edges.js +1 -1
  106. package/dist/core/graph/events.d.ts +7 -9
  107. package/dist/core/graph/events.js +8 -8
  108. package/dist/core/graph/exposures.d.ts +6 -6
  109. package/dist/core/graph/exposures.js +4 -4
  110. package/dist/core/graph/jobs.d.ts +6 -8
  111. package/dist/core/graph/jobs.js +2 -2
  112. package/dist/core/graph/kinds/action.js +1 -1
  113. package/dist/core/graph/kinds/custom.js +2 -2
  114. package/dist/core/graph/kinds/document.d.ts +1 -0
  115. package/dist/core/graph/kinds/document.js +4 -4
  116. package/dist/core/graph/kinds/dto.d.ts +2 -2
  117. package/dist/core/graph/kinds/dto.js +1 -1
  118. package/dist/core/graph/kinds/job.js +2 -2
  119. package/dist/core/graph/kinds/kind.d.ts +6 -8
  120. package/dist/core/graph/kinds/kind.js +1 -1
  121. package/dist/core/graph/kinds/node.js +5 -5
  122. package/dist/core/graph/kinds/owner.js +2 -2
  123. package/dist/core/graph/kinds/registry.d.ts +6 -9
  124. package/dist/core/graph/kinds/registry.js +1 -1
  125. package/dist/core/graph/names.d.ts +6 -6
  126. package/dist/core/graph/names.js +3 -3
  127. package/dist/core/graph/object-waits.d.ts +4 -7
  128. package/dist/core/graph/object-waits.js +1 -1
  129. package/dist/core/graph/objects.d.ts +14 -14
  130. package/dist/core/graph/objects.js +9 -9
  131. package/dist/core/graph/package-docs.d.ts +2 -7
  132. package/dist/core/graph/package-docs.js +5 -5
  133. package/dist/core/graph/package-kinds.d.ts +2 -5
  134. package/dist/core/graph/package-kinds.js +1 -1
  135. package/dist/core/graph/package-reconcile.d.ts +2 -5
  136. package/dist/core/graph/package-reconcile.js +1 -1
  137. package/dist/core/graph/reader.d.ts +18 -18
  138. package/dist/core/graph/reader.js +3 -3
  139. package/dist/core/graph/receivers.d.ts +4 -4
  140. package/dist/core/graph/receivers.js +5 -5
  141. package/dist/core/graph/repo-sync/exchange.d.ts +3 -7
  142. package/dist/core/graph/repo-sync/exchange.js +2 -2
  143. package/dist/core/graph/repo-sync/repos.d.ts +7 -5
  144. package/dist/core/graph/repo-sync/repos.js +3 -3
  145. package/dist/core/graph/repo-sync/sync.d.ts +3 -6
  146. package/dist/core/graph/repo-sync/sync.js +2 -2
  147. package/dist/core/graph/rules.d.ts +5 -5
  148. package/dist/core/graph/rules.js +3 -3
  149. package/dist/core/graph/spaces/app.js +1 -1
  150. package/dist/core/graph/spaces/index.d.ts +4 -5
  151. package/dist/core/graph/spaces/index.js +1 -1
  152. package/dist/core/graph/spaces/own-memory.d.ts +4 -4
  153. package/dist/core/graph/spaces/own-memory.js +1 -1
  154. package/dist/core/graph/spaces/person.js +3 -3
  155. package/dist/core/graph/spaces/repo.d.ts +1 -1
  156. package/dist/core/graph/spaces/repo.js +1 -1
  157. package/dist/core/graph/watches.d.ts +15 -15
  158. package/dist/core/graph/watches.js +10 -10
  159. package/dist/core/human/feedback-companion.d.ts +2 -2
  160. package/dist/core/human/feedback-companion.js +1 -1
  161. package/dist/core/human/feedback.d.ts +3 -3
  162. package/dist/core/human/feedback.js +1 -1
  163. package/dist/core/human/requests.d.ts +34 -33
  164. package/dist/core/human/requests.js +20 -20
  165. package/dist/core/human/scan.d.ts +2 -2
  166. package/dist/core/human/scan.js +1 -1
  167. package/dist/core/human/tickets.d.ts +9 -9
  168. package/dist/core/human/tickets.js +1 -1
  169. package/dist/core/llm/app-rungs.d.ts +1 -1
  170. package/dist/core/llm/app-rungs.js +1 -1
  171. package/dist/core/llm/run.js +1 -1
  172. package/dist/core/peer/directory.d.ts +1 -1
  173. package/dist/core/peer/directory.js +1 -1
  174. package/dist/core/peer/envelope.d.ts +3 -3
  175. package/dist/core/peer/envelope.js +1 -1
  176. package/dist/core/peer/home.d.ts +7 -7
  177. package/dist/core/peer/home.js +2 -2
  178. package/dist/core/peer/ingest.d.ts +6 -6
  179. package/dist/core/peer/ingest.js +1 -1
  180. package/dist/core/peer/outbox-store.d.ts +14 -14
  181. package/dist/core/peer/outbox-store.js +5 -5
  182. package/dist/core/peer/receiver.d.ts +2 -2
  183. package/dist/core/peer/receiver.js +1 -1
  184. package/dist/core/peer/stubs.d.ts +10 -10
  185. package/dist/core/peer/stubs.js +1 -1
  186. package/dist/core/providers/approval.d.ts +2 -2
  187. package/dist/core/providers/approval.js +2 -2
  188. package/dist/core/providers/audit.d.ts +3 -3
  189. package/dist/core/providers/audit.js +2 -2
  190. package/dist/core/providers/bundles.js +2 -2
  191. package/dist/core/providers/call.d.ts +2 -2
  192. package/dist/core/providers/call.js +1 -1
  193. package/dist/core/providers/files.d.ts +1 -1
  194. package/dist/core/providers/files.js +1 -1
  195. package/dist/core/providers/mint.js +1 -1
  196. package/dist/core/providers/receipts.d.ts +1 -1
  197. package/dist/core/providers/receipts.js +2 -2
  198. package/dist/core/review/birth.js +1 -1
  199. package/dist/core/review/comments.d.ts +19 -19
  200. package/dist/core/review/comments.js +5 -5
  201. package/dist/core/review/companion.d.ts +1 -1
  202. package/dist/core/review/companion.js +1 -1
  203. package/dist/core/review/document.d.ts +3 -3
  204. package/dist/core/review/document.js +2 -2
  205. package/dist/core/review/fork.js +2 -2
  206. package/dist/core/review/realize.js +1 -1
  207. package/dist/core/review/remap.d.ts +2 -2
  208. package/dist/core/review/remap.js +4 -4
  209. package/dist/core/review/stage.d.ts +1 -1
  210. package/dist/core/review/stage.js +1 -1
  211. package/dist/core/review/store.d.ts +21 -21
  212. package/dist/core/review/store.js +1 -1
  213. package/dist/core/runs/activity.d.ts +1 -1
  214. package/dist/core/runs/activity.js +5 -5
  215. package/dist/core/runs/confinement.d.ts +7 -7
  216. package/dist/core/runs/confinement.js +2 -2
  217. package/dist/core/runs/events.d.ts +12 -12
  218. package/dist/core/runs/events.js +4 -4
  219. package/dist/core/runs/operations.d.ts +11 -11
  220. package/dist/core/runs/operations.js +5 -5
  221. package/dist/core/runs/questions.d.ts +10 -10
  222. package/dist/core/runs/questions.js +3 -3
  223. package/dist/core/runtime/auth-reload.js +1 -1
  224. package/dist/core/runtime/bearings.d.ts +5 -5
  225. package/dist/core/runtime/bearings.js +6 -6
  226. package/dist/core/runtime/broker-inventory.js +1 -1
  227. package/dist/core/runtime/broker-request.js +1 -1
  228. package/dist/core/runtime/broker.js +1 -1
  229. package/dist/core/runtime/close.d.ts +3 -3
  230. package/dist/core/runtime/close.js +1 -1
  231. package/dist/core/runtime/deliver-live.js +1 -1
  232. package/dist/core/runtime/fleet.d.ts +2 -2
  233. package/dist/core/runtime/host.d.ts +3 -3
  234. package/dist/core/runtime/host.js +3 -3
  235. package/dist/core/runtime/kickoff.d.ts +12 -12
  236. package/dist/core/runtime/kickoff.js +17 -17
  237. package/dist/core/runtime/launch-target.d.ts +1 -1
  238. package/dist/core/runtime/launch-target.js +1 -1
  239. package/dist/core/runtime/ledger.d.ts +3 -3
  240. package/dist/core/runtime/ledger.js +3 -3
  241. package/dist/core/runtime/lifecycle.d.ts +1 -1
  242. package/dist/core/runtime/lifecycle.js +2 -2
  243. package/dist/core/runtime/memory-admission.js +1 -1
  244. package/dist/core/runtime/model-swap.d.ts +2 -2
  245. package/dist/core/runtime/model-swap.js +1 -1
  246. package/dist/core/runtime/node-read.d.ts +1 -1
  247. package/dist/core/runtime/node-read.js +2 -2
  248. package/dist/core/runtime/nodes.d.ts +6 -6
  249. package/dist/core/runtime/nodes.js +1 -1
  250. package/dist/core/runtime/outcome-document.d.ts +1 -1
  251. package/dist/core/runtime/outcome-document.js +1 -1
  252. package/dist/core/runtime/persona.d.ts +3 -3
  253. package/dist/core/runtime/persona.js +2 -2
  254. package/dist/core/runtime/placement.d.ts +11 -11
  255. package/dist/core/runtime/placement.js +1 -1
  256. package/dist/core/runtime/promote.d.ts +3 -3
  257. package/dist/core/runtime/promote.js +1 -1
  258. package/dist/core/runtime/recycle.js +1 -1
  259. package/dist/core/runtime/reopen.d.ts +21 -10
  260. package/dist/core/runtime/reopen.js +1 -1
  261. package/dist/core/runtime/reset.d.ts +4 -4
  262. package/dist/core/runtime/reset.js +1 -1
  263. package/dist/core/runtime/revive-all.d.ts +2 -2
  264. package/dist/core/runtime/revive-all.js +1 -1
  265. package/dist/core/runtime/revive.d.ts +4 -4
  266. package/dist/core/runtime/revive.js +2 -2
  267. package/dist/core/runtime/roadmap.d.ts +6 -6
  268. package/dist/core/runtime/roadmap.js +5 -5
  269. package/dist/core/runtime/session-branch.d.ts +1 -1
  270. package/dist/core/runtime/session-branch.js +1 -1
  271. package/dist/core/runtime/session-list-cache.js +1 -1
  272. package/dist/core/runtime/situational-live.js +1 -1
  273. package/dist/core/runtime/spawn.d.ts +2 -2
  274. package/dist/core/runtime/spawn.js +2 -2
  275. package/dist/core/runtime/stop-guard.d.ts +2 -2
  276. package/dist/core/runtime/stop-guard.js +3 -3
  277. package/dist/core/runtime/warm-pool.d.ts +2 -2
  278. package/dist/core/runtime/warm-pool.js +1 -1
  279. package/dist/core/spaces/mounts.d.ts +2 -2
  280. package/dist/core/spaces/mounts.js +1 -1
  281. package/dist/core/spaces/permissions.d.ts +1 -1
  282. package/dist/core/spaces/permissions.js +1 -1
  283. package/dist/core/spaces/process.d.ts +1 -1
  284. package/dist/core/spaces/process.js +1 -1
  285. package/dist/core/spaces/space.js +1 -1
  286. package/dist/core/spaces/stop.d.ts +3 -3
  287. package/dist/core/spaces/stop.js +2 -2
  288. package/dist/core/spaces/users.d.ts +6 -6
  289. package/dist/core/spaces/users.js +1 -1
  290. package/dist/core/storage/attachments.d.ts +2 -2
  291. package/dist/core/storage/attachments.js +1 -1
  292. package/dist/core/storage/shares.d.ts +2 -2
  293. package/dist/core/storage/shares.js +1 -1
  294. package/dist/core/storage/tables.d.ts +21 -21
  295. package/dist/core/storage/tables.js +3 -3
  296. package/dist/core/substrate/delivery/corpus.d.ts +5 -8
  297. package/dist/core/substrate/delivery/corpus.js +3 -3
  298. package/dist/core/substrate/delivery/deliver.d.ts +10 -15
  299. package/dist/core/substrate/delivery/deliver.js +3 -3
  300. package/dist/core/substrate/delivery/plan.d.ts +2 -12
  301. package/dist/core/substrate/delivery/plan.js +3 -3
  302. package/dist/core/substrate/delivery/render-boot.d.ts +4 -4
  303. package/dist/core/substrate/delivery/render-boot.js +18 -18
  304. package/dist/core/substrate/delivery/render-event.d.ts +7 -14
  305. package/dist/core/substrate/delivery/render-event.js +4 -4
  306. package/dist/core/substrate/subject.d.ts +2 -2
  307. package/dist/core/substrate/subject.js +1 -1
  308. package/dist/core/usage/ledger.d.ts +6 -6
  309. package/dist/core/usage/ledger.js +4 -4
  310. package/dist/core/worktree-close.js +4 -4
  311. package/dist/core/worktree-mutation-async.js +7 -7
  312. package/dist/core/worktree-quarantine.js +1 -1
  313. package/dist/core/worktree-sweep.d.ts +1 -1
  314. package/dist/core/worktree-sweep.js +6 -6
  315. package/dist/core/worktree.d.ts +5 -5
  316. package/dist/core/worktree.js +13 -13
  317. package/dist/daemon/analytics/compute.d.ts +2 -2
  318. package/dist/daemon/analytics/compute.js +1 -1
  319. package/dist/daemon/api/app-listener.d.ts +4 -4
  320. package/dist/daemon/api/app-listener.js +13 -13
  321. package/dist/daemon/api/bridge.js +5 -5
  322. package/dist/daemon/api/document-listener.js +6 -6
  323. package/dist/daemon/api/handlers/analytics.js +1 -1
  324. package/dist/daemon/api/handlers/attach.js +1 -1
  325. package/dist/daemon/api/handlers/bash-jobs.js +1 -1
  326. package/dist/daemon/api/handlers/bash.js +1 -1
  327. package/dist/daemon/api/handlers/broker-ops.d.ts +1 -1
  328. package/dist/daemon/api/handlers/broker-ops.js +1 -1
  329. package/dist/daemon/api/handlers/broker-recovery.d.ts +1 -1
  330. package/dist/daemon/api/handlers/broker-recovery.js +1 -1
  331. package/dist/daemon/api/handlers/broker-signals.d.ts +2 -2
  332. package/dist/daemon/api/handlers/broker-signals.js +2 -2
  333. package/dist/daemon/api/handlers/canvas.d.ts +1 -1
  334. package/dist/daemon/api/handlers/canvas.js +4 -4
  335. package/dist/daemon/api/handlers/chat-inventory.js +1 -1
  336. package/dist/daemon/api/handlers/crons.js +1 -1
  337. package/dist/daemon/api/handlers/custom-objects.d.ts +4 -4
  338. package/dist/daemon/api/handlers/custom-objects.js +3 -3
  339. package/dist/daemon/api/handlers/delivery-retry.js +1 -1
  340. package/dist/daemon/api/handlers/delivery.js +1 -1
  341. package/dist/daemon/api/handlers/docs.d.ts +4 -4
  342. package/dist/daemon/api/handlers/docs.js +1 -1
  343. package/dist/daemon/api/handlers/feedback-comments.js +3 -3
  344. package/dist/daemon/api/handlers/files.js +1 -1
  345. package/dist/daemon/api/handlers/focus.js +1 -1
  346. package/dist/daemon/api/handlers/health.js +3 -3
  347. package/dist/daemon/api/handlers/hook-exec.js +1 -1
  348. package/dist/daemon/api/handlers/human-requests.js +1 -1
  349. package/dist/daemon/api/handlers/inbox-page.d.ts +1 -1
  350. package/dist/daemon/api/handlers/inbox-page.js +1 -1
  351. package/dist/daemon/api/handlers/inbox.d.ts +1 -1
  352. package/dist/daemon/api/handlers/inbox.js +1 -1
  353. package/dist/daemon/api/handlers/llm.d.ts +1 -1
  354. package/dist/daemon/api/handlers/llm.js +3 -3
  355. package/dist/daemon/api/handlers/memory-reads.js +1 -1
  356. package/dist/daemon/api/handlers/memory.d.ts +5 -5
  357. package/dist/daemon/api/handlers/memory.js +5 -5
  358. package/dist/daemon/api/handlers/messages.js +2 -2
  359. package/dist/daemon/api/handlers/node-events.d.ts +2 -2
  360. package/dist/daemon/api/handlers/node-events.js +3 -3
  361. package/dist/daemon/api/handlers/node-outcomes.js +1 -1
  362. package/dist/daemon/api/handlers/node-records.js +2 -2
  363. package/dist/daemon/api/handlers/nodes.d.ts +1 -1
  364. package/dist/daemon/api/handlers/nodes.js +1 -1
  365. package/dist/daemon/api/handlers/objects.js +3 -3
  366. package/dist/daemon/api/handlers/package-docs.js +1 -1
  367. package/dist/daemon/api/handlers/plugin-app-token.d.ts +1 -1
  368. package/dist/daemon/api/handlers/plugin-app-token.js +1 -1
  369. package/dist/daemon/api/handlers/profiles.d.ts +3 -3
  370. package/dist/daemon/api/handlers/profiles.js +1 -1
  371. package/dist/daemon/api/handlers/providers.d.ts +1 -1
  372. package/dist/daemon/api/handlers/providers.js +1 -1
  373. package/dist/daemon/api/handlers/questions.js +1 -1
  374. package/dist/daemon/api/handlers/reports.d.ts +1 -1
  375. package/dist/daemon/api/handlers/reports.js +5 -5
  376. package/dist/daemon/api/handlers/review-comments.js +1 -1
  377. package/dist/daemon/api/handlers/reviews.js +1 -1
  378. package/dist/daemon/api/handlers/runs.js +1 -1
  379. package/dist/daemon/api/handlers/structured-requests.js +1 -1
  380. package/dist/daemon/api/handlers/subscriptions.js +1 -1
  381. package/dist/daemon/api/handlers/transfer.js +1 -1
  382. package/dist/daemon/api/map.d.ts +3 -3
  383. package/dist/daemon/api/map.js +1 -1
  384. package/dist/daemon/api/principal.d.ts +1 -1
  385. package/dist/daemon/api/principal.js +1 -1
  386. package/dist/daemon/api/reader.d.ts +5 -5
  387. package/dist/daemon/api/reader.js +1 -1
  388. package/dist/daemon/api/router.d.ts +5 -5
  389. package/dist/daemon/api/router.js +1 -1
  390. package/dist/daemon/api/server.js +1 -1
  391. package/dist/daemon/broker-signals/bus.d.ts +1 -1
  392. package/dist/daemon/broker-signals/bus.js +1 -1
  393. package/dist/daemon/companion-retire.js +1 -1
  394. package/dist/daemon/cron/armed-context.d.ts +2 -2
  395. package/dist/daemon/cron/armed-context.js +1 -1
  396. package/dist/daemon/cron/authority.d.ts +2 -2
  397. package/dist/daemon/cron/authority.js +1 -1
  398. package/dist/daemon/cron/disposition.js +1 -1
  399. package/dist/daemon/cron/ended.d.ts +1 -1
  400. package/dist/daemon/cron/ended.js +2 -2
  401. package/dist/daemon/cron/escalation.js +3 -3
  402. package/dist/daemon/cron/folders.d.ts +1 -1
  403. package/dist/daemon/cron/folders.js +1 -1
  404. package/dist/daemon/cron/held.d.ts +1 -1
  405. package/dist/daemon/cron/held.js +1 -1
  406. package/dist/daemon/cron/lease-recovery.d.ts +1 -1
  407. package/dist/daemon/cron/lease-recovery.js +1 -1
  408. package/dist/daemon/cron/passes.d.ts +2 -2
  409. package/dist/daemon/cron/passes.js +1 -1
  410. package/dist/daemon/cron/run-socket.d.ts +1 -1
  411. package/dist/daemon/cron/run-socket.js +1 -1
  412. package/dist/daemon/cron/settle.js +1 -1
  413. package/dist/daemon/cron/sinks.d.ts +1 -1
  414. package/dist/daemon/cron/sinks.js +2 -2
  415. package/dist/daemon/cron-run.d.ts +12 -3
  416. package/dist/daemon/cron-run.js +2 -2
  417. package/dist/daemon/crtrd.js +6 -6
  418. package/dist/daemon/delivery/run-delivery.js +1 -1
  419. package/dist/daemon/due-sources.d.ts +3 -3
  420. package/dist/daemon/due-sources.js +1 -1
  421. package/dist/daemon/due.d.ts +3 -3
  422. package/dist/daemon/due.js +7 -7
  423. package/dist/daemon/fleet.d.ts +2 -2
  424. package/dist/daemon/fleet.js +11 -11
  425. package/dist/daemon/human/finish.js +3 -3
  426. package/dist/daemon/human/settle.d.ts +1 -1
  427. package/dist/daemon/human/settle.js +1 -1
  428. package/dist/daemon/human/sweep.js +1 -1
  429. package/dist/daemon/joined-owner.d.ts +3 -3
  430. package/dist/daemon/joined-owner.js +1 -1
  431. package/dist/daemon/messaging/node-message.js +1 -1
  432. package/dist/daemon/park-activity.d.ts +2 -2
  433. package/dist/daemon/park-activity.js +1 -1
  434. package/dist/daemon/peer/authority.js +1 -1
  435. package/dist/daemon/peer/forward.d.ts +6 -6
  436. package/dist/daemon/peer/forward.js +1 -1
  437. package/dist/daemon/peer/handlers.js +1 -1
  438. package/dist/daemon/peer/ingress.d.ts +4 -4
  439. package/dist/daemon/peer/ingress.js +1 -1
  440. package/dist/daemon/peer/outbox.d.ts +2 -2
  441. package/dist/daemon/peer/outbox.js +1 -1
  442. package/dist/daemon/peer/relay-service.js +1 -1
  443. package/dist/daemon/plugin-objects/read-leaf.d.ts +2 -2
  444. package/dist/daemon/plugin-objects/read-leaf.js +2 -2
  445. package/dist/daemon/profile-delete.js +1 -1
  446. package/dist/daemon/readiness.d.ts +2 -2
  447. package/dist/daemon/readiness.js +1 -1
  448. package/dist/daemon/reconcilers/action-lane.d.ts +1 -1
  449. package/dist/daemon/reconcilers/action-lane.js +1 -1
  450. package/dist/daemon/reconcilers/bash-deadline.js +2 -2
  451. package/dist/daemon/reconcilers/broker-supervision.d.ts +1 -1
  452. package/dist/daemon/reconcilers/broker-supervision.js +4 -4
  453. package/dist/daemon/reconcilers/controller-death.d.ts +1 -1
  454. package/dist/daemon/reconcilers/controller-death.js +1 -1
  455. package/dist/daemon/reconcilers/cron-lane.d.ts +1 -1
  456. package/dist/daemon/reconcilers/cron-lane.js +1 -1
  457. package/dist/daemon/reconcilers/delivery-lane.d.ts +1 -1
  458. package/dist/daemon/reconcilers/delivery-lane.js +2 -2
  459. package/dist/daemon/reconcilers/fault-retry-backstop.d.ts +3 -3
  460. package/dist/daemon/reconcilers/fault-retry-backstop.js +1 -1
  461. package/dist/daemon/reconcilers/grove-instance-sweep.d.ts +2 -2
  462. package/dist/daemon/reconcilers/grove-instance-sweep.js +1 -1
  463. package/dist/daemon/reconcilers/live-obligation.d.ts +6 -6
  464. package/dist/daemon/reconcilers/live-obligation.js +1 -1
  465. package/dist/daemon/reconcilers/managed-worktree-sweep.js +1 -1
  466. package/dist/daemon/reconcilers/node-deadline.d.ts +1 -1
  467. package/dist/daemon/reconcilers/node-deadline.js +1 -1
  468. package/dist/daemon/reconcilers/node-lifecycle/freeze-lane.js +1 -1
  469. package/dist/daemon/reconcilers/node-lifecycle/respawn-policy.d.ts +3 -3
  470. package/dist/daemon/reconcilers/node-lifecycle/respawn-policy.js +1 -1
  471. package/dist/daemon/reconcilers/node-lifecycle/terminating.js +1 -1
  472. package/dist/daemon/reconcilers/node-lifecycle/tick.js +1 -1
  473. package/dist/daemon/reconcilers/node-lifecycle/wants-execution.d.ts +1 -1
  474. package/dist/daemon/reconcilers/node-lifecycle/wants-execution.js +1 -1
  475. package/dist/daemon/reconcilers/pending-review-submit.d.ts +1 -1
  476. package/dist/daemon/reconcilers/pending-review-submit.js +1 -1
  477. package/dist/daemon/reconcilers/storage-due-work.js +1 -1
  478. package/dist/daemon/reconcilers/storage-maintenance.d.ts +1 -1
  479. package/dist/daemon/reconcilers/storage-maintenance.js +2 -2
  480. package/dist/daemon/reconcilers/structured-request-lane.d.ts +1 -1
  481. package/dist/daemon/reconcilers/structured-request-lane.js +1 -1
  482. package/dist/daemon/review/comment-notify.js +2 -2
  483. package/dist/daemon/review/companion.d.ts +3 -3
  484. package/dist/daemon/review/companion.js +1 -1
  485. package/dist/daemon/review/finish.js +1 -1
  486. package/dist/daemon/review/sweep.js +1 -1
  487. package/dist/daemon/run-notices.d.ts +4 -4
  488. package/dist/daemon/run-notices.js +1 -1
  489. package/dist/daemon/runs/append-section.d.ts +2 -2
  490. package/dist/daemon/runs/append-section.js +2 -2
  491. package/dist/daemon/runs/observer.d.ts +2 -2
  492. package/dist/daemon/runs/observer.js +2 -2
  493. package/dist/daemon/structured-requests/boot.d.ts +1 -1
  494. package/dist/daemon/structured-requests/boot.js +1 -1
  495. package/dist/daemon/structured-requests/effects.js +1 -1
  496. package/dist/daemon/structured-requests/sidecar.d.ts +1 -1
  497. package/dist/daemon/structured-requests/sidecar.js +1 -1
  498. package/dist/launcher/run.js +1 -1
  499. package/dist/migrations/004-canvas-documents/apply.d.ts +3 -3
  500. package/dist/migrations/004-canvas-documents/apply.js +1 -1
  501. package/dist/migrations/004-canvas-documents/index.d.ts +2 -2
  502. package/dist/migrations/004-canvas-documents/index.js +2 -2
  503. package/dist/migrations/activation.js +2 -2
  504. package/docs/plugin/bundles-and-memory.md +1 -1
  505. package/docs/plugin/commands.md +1 -1
  506. package/docs/public-api.md +11 -0
  507. package/package.json +4 -3
  508. package/packages/crouter-identity/package.json +1 -1
  509. package/runtime.lock.json +12 -12
@@ -1,4 +1,4 @@
1
- var D=Object.defineProperty;var r=(n,t)=>D(n,"name",{value:t,configurable:!0});import{prepared as d}from"../../core/sqlite-statements.js";import{randomUUID as O}from"node:crypto";import{openDb as l}from"../../core/canvas/db.js";import{getNode as f}from"../../core/canvas/canvas.js";import{BrokerClient as T,SocketTransport as I}from"../../core/broker-client/client.js";import{emitRunEvent as c,emitRunSettlement as m}from"../../core/runs/events.js";import{cancelOpenQuestions as R}from"../../core/runs/questions.js";import{emitEvent as p}from"../../core/events/emit.js";import{toRunOutcomeDTO as v}from"../api/map.js";import{readOutputResult as N}from"../../core/runtime/structured-output.js";const A=JSON.stringify({input_tokens:0,output_tokens:0,cache_read_tokens:0,cache_write_tokens:0,cost_usd:0}),h=new Map,y=250;class b{static{r(this,"RunObserver")}nodeId;runId;client;timer;status;piPid=null;outcomeRevision;openAssistant=!1;assistantStartSequence=0;block=null;thinking="";output="";pendingThinking="";pendingOutput="";flushTimer;closed=!1;constructor(t,e){this.nodeId=t,this.runId=e;const i=l(),s=d(i,"SELECT body_json FROM run_events WHERE node_id = ? AND type = ? ORDER BY sequence_number DESC LIMIT 1").get(t,t===e?"node.settled":"child.settled");s&&(this.outcomeRevision=JSON.parse(s.body_json).outcome.revision);const o=d(i,"SELECT body_json FROM run_events WHERE node_id = ? AND type = 'node.status.changed' ORDER BY sequence_number DESC LIMIT 1").get(t);o&&(this.status=JSON.parse(o.body_json).status),this.timer=setInterval(()=>this.pollOrClose(),250),this.timer.unref(),h.set(t,this),this.poll()}pollOrClose(){try{this.poll()}catch(t){this.close(),p({level:"error",event:"daemon.runs.observer_failed",node_id:this.nodeId,error:t})}}poll(){const t=f(this.nodeId);if(!t||t.run_id!==this.runId||!g(this.runId)){this.close();return}this.piPid=t.pi_pid??null;const e=t.pi_pid===null?"dormant":t.status;this.status!==e&&c(this.runId,this.nodeId,"node.status.changed",{status:e,reason:t.intent??null}),this.status=e;const i=v(t);if(i&&i.revision!==this.outcomeRevision&&Date.now()-Date.parse(i.settled_at)<720*60*6e4){if(this.nodeId===this.runId){const s=d(l(),"SELECT node_id FROM nodes WHERE run_id = ? AND node_id != ? ORDER BY created DESC").all(this.runId,this.runId);for(const o of s)E(o.node_id,this.runId),h.get(o.node_id)?.poll()}if(this.outcomeRevision=i.revision,this.nodeId===this.runId){const s=i.kind==="result"?N(this.nodeId,t.grantee):void 0;m(this.runId,this.nodeId,"node.settled",{outcome:i,usage:JSON.parse(t.usage_json??A),...s===void 0?{}:{result:s}})}else m(this.runId,this.nodeId,"child.settled",{child_node_id:this.nodeId,outcome:i});if(t.grantee&&t.grantee!=="app:terminal"){const s=this.nodeId===this.runId?{run_id:this.runId}:{node_id:this.nodeId};R(s,this.nodeId===this.runId?"the run settled":"the asking node was closed").catch(o=>p({level:"error",event:"daemon.runs.question_cancel_failed",node_id:this.nodeId,error:o}))}}t.pi_pid===null?this.close():this.connect()}get assistantMessageStartSequence(){return this.openAssistant&&this.client&&this.piPid!==null?this.assistantStartSequence:null}get openBlock(){return this.assistantMessageStartSequence===null?null:this.block}connect(){if(this.client||this.closed)return;const t=new T(this.nodeId,{transport:new I(this.nodeId,{recordsViewerFaults:!1})});this.client=t,t.on("connect",()=>t.send({type:"hello",role:"observer",client_id:O(),attends:!1})),t.on("frame",e=>{if(e.type==="message_start"&&e.message.role==="assistant"&&(this.discardDeltas(),this.openAssistant=!0,this.block=null,this.thinking="",this.output="",this.assistantStartSequence=d(l(),"SELECT event_cursor FROM nodes WHERE node_id = ?").get(this.runId).event_cursor),e.type==="message_update"&&e.message.role==="assistant"&&this.openAssistant){const i=e.message.content;if(!Array.isArray(i))return;const s=i.at(-1);s&&typeof s=="object"&&"type"in s&&(s.type==="toolCall"?this.block={kind:"tool_call",name:"name"in s&&typeof s.name=="string"?s.name:""}:(s.type==="text"||s.type==="thinking")&&(this.block={kind:s.type}));const o=i.filter(u=>u?.type==="thinking").map(u=>u.thinking).join(""),a=i.filter(u=>u?.type==="text").map(u=>u.text).join(""),S=o.startsWith(this.thinking)?o.slice(this.thinking.length):o,k=a.startsWith(this.output)?a.slice(this.output.length):a;this.thinking=o,this.output=a,this.pendingThinking+=S,this.pendingOutput+=k,(this.pendingThinking||this.pendingOutput)&&!this.flushTimer&&(this.flushTimer=setTimeout(()=>this.flushDeltas(),y),this.flushTimer.unref())}e.type==="message_end"&&e.message.role==="assistant"&&(this.flushDeltas(),this.openAssistant=!1,this.block=null)}),t.on("error",()=>{}),t.on("close",()=>{this.client===t&&(this.client=void 0,this.discardDeltas(),this.openAssistant=!1,this.block=null)}),t.connect()}flushDeltas(){this.flushTimer&&clearTimeout(this.flushTimer),this.flushTimer=void 0;const t=this.pendingThinking,e=this.pendingOutput;if(this.pendingThinking="",this.pendingOutput="",!this.openAssistant||!t&&!e)return;if(d(l(),"SELECT 1 FROM run_events WHERE run_id = ? AND node_id = ? AND sequence_number >= ? AND type IN ('node.output_text.done', 'node.thinking.done', 'usage') LIMIT 1").get(this.runId,this.nodeId,this.assistantStartSequence)){this.openAssistant=!1;return}t&&c(this.runId,this.nodeId,"node.thinking.delta",{delta:t}),e&&c(this.runId,this.nodeId,"node.output_text.delta",{delta:e})}discardDeltas(){this.flushTimer&&clearTimeout(this.flushTimer),this.flushTimer=void 0,this.pendingThinking="",this.pendingOutput=""}close(){this.closed=!0,this.discardDeltas(),clearInterval(this.timer),h.delete(this.nodeId);const t=this.client;this.client=void 0,t?.close()}}function J(n){return h.get(n)?.assistantMessageStartSequence??null}r(J,"openAssistantMessageStartSequence");function P(n){return h.get(n)?.openBlock??null}r(P,"openAssistantBlock");function g(n){return d(l(),"SELECT 1 FROM nodes WHERE node_id = ? AND run_id = ? AND event_cursor IS NOT NULL").get(n,n)!==void 0}r(g,"runRootExists");function E(n,t){if(!h.has(n)&&g(t)){if(n!==t){const e=f(n);!d(l(),"SELECT 1 FROM run_events WHERE run_id = ? AND node_id = ? AND type = 'child.started' LIMIT 1").get(t,n)&&e&&Date.now()-Date.parse(e.created)<720*60*6e4&&c(t,n,"child.started",{child_node_id:n,kind:e.kind})}new b(n,t)}}r(E,"ensureRunObserver");function Y(){const n=new Date(Date.now()-2592e6).toISOString(),t=d(l(),`SELECT n.node_id, n.run_id FROM node_rows n WHERE n.run_id IS NOT NULL AND (n.pi_pid IS NOT NULL OR (n.outcome_at IS NOT NULL AND n.outcome_at > ?
1
+ var k=Object.defineProperty;var r=(i,t)=>k(i,"name",{value:t,configurable:!0});import{randomUUID as D}from"node:crypto";import{openDb as l}from"../../core/canvas/db.js";import{getNode as m}from"../../core/canvas/canvas.js";import{BrokerClient as T,SocketTransport as y}from"../../core/broker-client/client.js";import{emitRunEvent as p,emitRunSettlement as E}from"../../core/runs/events.js";import{cancelOpenQuestions as I}from"../../core/runs/questions.js";import{emitEvent as h}from"../../core/events/emit.js";import{toRunOutcomeDTO as R}from"../api/map.js";import{readOutputResult as N}from"../../core/runtime/structured-output.js";const A=JSON.stringify({input_tokens:0,output_tokens:0,cache_read_tokens:0,cache_write_tokens:0,cost_usd:0}),u=new Map,b=250;class g{static{r(this,"RunObserver")}nodeId;runId;client;timer;status;piPid=null;outcomeRevision;openAssistant=!1;assistantStartSequence=0;block=null;thinking="";output="";pendingThinking="";pendingOutput="";flushTimer;closed=!1;polling;frames=Promise.resolve();constructor(t,e,n,s){this.nodeId=t,this.runId=e,this.status=n,this.outcomeRevision=s,this.timer=setInterval(()=>{this.pollOrClose()},250),this.timer.unref(),u.set(t,this)}static async start(t,e){const n=await l(),s=await n.prepare("SELECT body_json FROM run_events WHERE node_id = ? AND type = ? ORDER BY sequence_number DESC LIMIT 1").get(t,t===e?"node.settled":"child.settled"),o=await n.prepare("SELECT body_json FROM run_events WHERE node_id = ? AND type = 'node.status.changed' ORDER BY sequence_number DESC LIMIT 1").get(t),d=new g(t,e,o?JSON.parse(o.body_json).status:void 0,s?JSON.parse(s.body_json).outcome.revision:void 0);return await d.poll(),d}async pollOrClose(){try{await this.poll()}catch(t){this.close(),h({level:"error",event:"daemon.runs.observer_failed",node_id:this.nodeId,error:t})}}poll(){return this.polling===void 0&&(this.polling=this.pollOnce().finally(()=>{this.polling=void 0})),this.polling}async pollOnce(){const t=await m(this.nodeId);if(!t||t.run_id!==this.runId||!await S(this.runId)){this.close();return}this.piPid=t.pi_pid??null;const e=t.pi_pid===null?"dormant":t.status;this.status!==e&&await p(this.runId,this.nodeId,"node.status.changed",{status:e,reason:t.intent??null}),this.status=e;const n=R(t);if(n&&n.revision!==this.outcomeRevision&&Date.now()-Date.parse(n.settled_at)<720*60*6e4){if(this.nodeId===this.runId){const s=await(await l()).prepare("SELECT node_id FROM nodes WHERE run_id = ? AND node_id != ? ORDER BY created DESC").all(this.runId,this.runId);for(const o of s)await w(o.node_id,this.runId),await u.get(o.node_id)?.poll()}if(this.outcomeRevision=n.revision,this.nodeId===this.runId){const s=n.kind==="result"?N(this.nodeId,t.grantee):void 0;await E(this.runId,this.nodeId,"node.settled",{outcome:n,usage:JSON.parse(t.usage_json??A),...s===void 0?{}:{result:s}})}else await E(this.runId,this.nodeId,"child.settled",{child_node_id:this.nodeId,outcome:n});if(t.grantee&&t.grantee!=="app:terminal"){const s=this.nodeId===this.runId?{run_id:this.runId}:{node_id:this.nodeId};I(s,this.nodeId===this.runId?"the run settled":"the asking node was closed").catch(o=>h({level:"error",event:"daemon.runs.question_cancel_failed",node_id:this.nodeId,error:o}))}}t.pi_pid===null?this.close():await this.connect()}get assistantMessageStartSequence(){return this.openAssistant&&this.client&&this.piPid!==null?this.assistantStartSequence:null}get openBlock(){return this.assistantMessageStartSequence===null?null:this.block}async connect(){if(this.client||this.closed)return;const t=new T(this.nodeId,{transport:new y(this.nodeId,{recordsViewerFaults:!1})});this.client=t,t.on("connect",()=>t.send({type:"hello",role:"observer",client_id:D(),attends:!1}));const e=r(async n=>{if(!(this.closed||this.client!==t)){if(n.type==="message_start"&&n.message.role==="assistant"&&(this.discardDeltas(),this.openAssistant=!0,this.block=null,this.thinking="",this.output="",this.assistantStartSequence=(await(await l()).prepare("SELECT event_cursor FROM nodes WHERE node_id = ?").get(this.runId)).event_cursor),n.type==="message_update"&&n.message.role==="assistant"&&this.openAssistant){const s=n.message.content;if(!Array.isArray(s))return;const o=s.at(-1);o&&typeof o=="object"&&"type"in o&&(o.type==="toolCall"?this.block={kind:"tool_call",name:"name"in o&&typeof o.name=="string"?o.name:""}:(o.type==="text"||o.type==="thinking")&&(this.block={kind:o.type}));const d=s.filter(a=>a?.type==="thinking").map(a=>a.thinking).join(""),c=s.filter(a=>a?.type==="text").map(a=>a.text).join(""),v=d.startsWith(this.thinking)?d.slice(this.thinking.length):d,O=c.startsWith(this.output)?c.slice(this.output.length):c;this.thinking=d,this.output=c,this.pendingThinking+=v,this.pendingOutput+=O,(this.pendingThinking||this.pendingOutput)&&!this.flushTimer&&(this.flushTimer=setTimeout(()=>{this.flushDeltas().catch(a=>h({level:"error",event:"daemon.runs.observer_failed",node_id:this.nodeId,error:a}))},b),this.flushTimer.unref())}n.type==="message_end"&&n.message.role==="assistant"&&(await this.flushDeltas(),this.openAssistant=!1,this.block=null)}},"handleFrame");t.on("frame",n=>{this.frames=this.frames.then(()=>e(n)).catch(s=>{this.close(),h({level:"error",event:"daemon.runs.observer_failed",node_id:this.nodeId,error:s})})}),t.on("error",()=>{}),t.on("close",()=>{this.client===t&&(this.client=void 0,this.discardDeltas(),this.openAssistant=!1,this.block=null)}),t.connect()}async flushDeltas(){this.flushTimer&&clearTimeout(this.flushTimer),this.flushTimer=void 0;const t=this.pendingThinking,e=this.pendingOutput;if(this.pendingThinking="",this.pendingOutput="",!this.openAssistant||!t&&!e)return;if(await(await l()).prepare("SELECT 1 FROM run_events WHERE run_id = ? AND node_id = ? AND sequence_number >= ? AND type IN ('node.output_text.done', 'node.thinking.done', 'usage') LIMIT 1").get(this.runId,this.nodeId,this.assistantStartSequence)){this.openAssistant=!1;return}t&&await p(this.runId,this.nodeId,"node.thinking.delta",{delta:t}),e&&await p(this.runId,this.nodeId,"node.output_text.delta",{delta:e})}discardDeltas(){this.flushTimer&&clearTimeout(this.flushTimer),this.flushTimer=void 0,this.pendingThinking="",this.pendingOutput=""}close(){this.closed=!0,this.discardDeltas(),clearInterval(this.timer),u.delete(this.nodeId);const t=this.client;this.client=void 0,t?.close()}}function P(i){return u.get(i)?.assistantMessageStartSequence??null}r(P,"openAssistantMessageStartSequence");function Y(i){return u.get(i)?.openBlock??null}r(Y,"openAssistantBlock");async function S(i){return await(await l()).prepare("SELECT 1 FROM nodes WHERE node_id = ? AND run_id = ? AND event_cursor IS NOT NULL").get(i,i)!==void 0}r(S,"runRootExists");const f=new Map;async function w(i,t){const e=f.get(i);if(e)return e;if(u.has(i))return;const n=L(i,t).finally(()=>f.delete(i));return f.set(i,n),n}r(w,"ensureRunObserver");async function L(i,t){if(await S(t)){if(i!==t){const e=await m(i);!await(await l()).prepare("SELECT 1 FROM run_events WHERE run_id = ? AND node_id = ? AND type = 'child.started' LIMIT 1").get(t,i)&&e&&Date.now()-Date.parse(e.created)<720*60*6e4&&await p(t,i,"child.started",{child_node_id:i,kind:e.kind})}await g.start(i,t)}}r(L,"startRunObserver");async function G(){const i=new Date(Date.now()-2592e6).toISOString(),t=await(await l()).prepare(`SELECT n.node_id, n.run_id FROM node_rows n WHERE n.run_id IS NOT NULL AND (n.pi_pid IS NOT NULL OR (n.outcome_at IS NOT NULL AND n.outcome_at > ?
2
2
  AND n.outcome_reason != 'parked' AND NOT EXISTS (
3
3
  SELECT 1 FROM run_events e WHERE e.run_id = n.run_id AND e.node_id = n.node_id AND e.type = CASE WHEN n.node_id = n.run_id THEN 'node.settled' ELSE 'child.settled' END
4
- AND json_extract(e.body_json, '$.outcome.revision') = COALESCE(n.outcome_revision, 1))))`).all(n);for(const e of t)try{E(e.node_id,e.run_id),_.delete(e.node_id)}catch(i){L(e.node_id,i)}}r(Y,"pollRunObservers");const _=new Map;function L(n,t){const e=t instanceof Error?t.message:String(t);_.get(n)!==e&&(_.set(n,e),p({level:"error",event:"daemon.runs.observer_failed",node_id:n,error:t}))}r(L,"reportObserverFailure");export{E as ensureRunObserver,P as openAssistantBlock,J as openAssistantMessageStartSequence,Y as pollRunObservers};
4
+ AND json_extract(e.body_json, '$.outcome.revision') = COALESCE(n.outcome_revision, 1))))`).all(i);for(const e of t)try{await w(e.node_id,e.run_id),_.delete(e.node_id)}catch(n){M(e.node_id,n)}}r(G,"pollRunObservers");const _=new Map;function M(i,t){const e=t instanceof Error?t.message:String(t);_.get(i)!==e&&(_.set(i,e),h({level:"error",event:"daemon.runs.observer_failed",node_id:i,error:t}))}r(M,"reportObserverFailure");export{w as ensureRunObserver,Y as openAssistantBlock,P as openAssistantMessageStartSequence,G as pollRunObservers};
@@ -1,2 +1,2 @@
1
1
  /** Rebuild pending sidecars, settle pending requests on terminal nodes, and adopt pre-request-id sidecars. */
2
- export declare function reconcileStructuredRequestSidecars(): void;
2
+ export declare function reconcileStructuredRequestSidecars(): Promise<void>;
@@ -1 +1 @@
1
- var o=Object.defineProperty;var n=(e,t)=>o(e,"name",{value:t,configurable:!0});import{listNodes as u}from"../../core/canvas/index.js";import{getPendingStructuredRequestForNode as s,registerLegacyStructuredRequest as c,settlePendingStructuredRequestForNode as a}from"../../core/canvas/structured-requests.js";import{readLegacyOutputRequest as l,readOutputRequest as f,writeStructuredRequestSidecar as i}from"../../core/runtime/structured-output.js";import{emitEvent as m}from"../../core/events/emit.js";function _(e){return e.status!=="done"&&e.status!=="dead"&&e.status!=="canceled"?null:e.terminal_reason==="deadline_exceeded"?{intended:"expired",failureReason:"node_deadline_exceeded"}:{intended:"failed",failureReason:e.terminal_reason??"finished"}}n(_,"terminalSettlement");function x(){for(const e of u())try{const t=_(e);t!==null&&a(e.node_id,t);const d=s(e.node_id);if(d!==null){i(d);continue}if(f(e.node_id).state==="valid"||t!==null)continue;const r=l(e.node_id);r!==null&&i(c(e.node_id,r.mode,r.schema))}catch(t){m({level:"error",event:"structured_request.boot_reconcile_failed",node_id:e.node_id,error:t})}}n(x,"reconcileStructuredRequestSidecars");export{x as reconcileStructuredRequestSidecars};
1
+ var o=Object.defineProperty;var n=(e,t)=>o(e,"name",{value:t,configurable:!0});import{listNodes as a}from"../../core/canvas/index.js";import{getPendingStructuredRequestForNode as u,registerLegacyStructuredRequest as s,settlePendingStructuredRequestForNode as c}from"../../core/canvas/structured-requests.js";import{readLegacyOutputRequest as l,readOutputRequest as f,writeStructuredRequestSidecar as d}from"../../core/runtime/structured-output.js";import{emitEvent as m}from"../../core/events/emit.js";function _(e){return e.status!=="done"&&e.status!=="dead"&&e.status!=="canceled"?null:e.terminal_reason==="deadline_exceeded"?{intended:"expired",failureReason:"node_deadline_exceeded"}:{intended:"failed",failureReason:e.terminal_reason??"finished"}}n(_,"terminalSettlement");async function y(){for(const e of await a())try{const t=_(e);t!==null&&await c(e.node_id,t);const i=await u(e.node_id);if(i!==null){d(i);continue}if(f(e.node_id).state==="valid"||t!==null)continue;const r=l(e.node_id);r!==null&&d(await s(e.node_id,r.mode,r.schema))}catch(t){m({level:"error",event:"structured_request.boot_reconcile_failed",node_id:e.node_id,error:t})}}n(y,"reconcileStructuredRequestSidecars");export{y as reconcileStructuredRequestSidecars};
@@ -1 +1 @@
1
- var o=Object.defineProperty;var n=(e,d)=>o(e,"name",{value:d,configurable:!0});import{markStructuredRequestEffectsDone as l,ownsStructuredRequestDeclineProjection as _,ownsStructuredRequestResultProjection as f,registerStructuredRequestEffectRunner as m}from"../../core/canvas/structured-requests.js";import{getNode as s}from"../../core/canvas/index.js";import{emitEvent as p}from"../../core/events/emit.js";import{requestBrokerTeardown as q}from"../../core/runtime/host.js";import{transition as S}from"../../core/runtime/lifecycle.js";import{expireNodeDeadline as y}from"../reconcilers/node-deadline.js";import{installStagedStructuredProjection as c,readOutputRequest as g,removeOutputSchema as h,stageStructuredResult as x,writeOutputDeclined as D}from"../../core/runtime/structured-output.js";import{enqueueNodeMail as R}from"../../core/feed/messages.js";import{notifyStructuredRequest as v}from"./notifier.js";function b(e){if(e.node_id===null)return!1;const d=g(e.node_id);return d.state==="valid"&&d.request.request_id===e.request_id}n(b,"ownsCurrentSidecar");async function j(e,d){v(e.request_id);let a=!1,u=null;const i=n((t,r)=>{a=!0,p({level:"error",event:t,node_id:e.node_id??void 0,error:r,fields:{request_id:e.request_id}})},"report");if(e.node_id!==null&&e.state==="completed")try{const t=e.submission,r=s(e.node_id)?.grantee;f(e)&&(u=d===void 0?c(x(e.node_id,e.request_id,t,e.result,r)):c(d))}catch(t){i("structured_request.projection_failed",t)}if(e.node_id!==null&&e.state==="declined"&&_(e)&&e.declined!==null)try{u=D(e.node_id,{mode:e.submission,...e.declined,at:new Date(e.settled_at??Date.now()).toISOString()},s(e.node_id)?.grantee)}catch(t){i("structured_request.decline_projection_failed",t)}if(e.node_id!==null&&b(e))try{h(e.node_id,e.request_id)}catch(t){i("structured_request.sidecar_remove_failed",t)}if(e.node_id!==null&&!e.dedicated&&e.state==="expired")try{R(e.node_id,{kind:"urgent",label:`Structured request ${e.request_id} expired`,bodyJson:{body:`Structured request ${e.request_id} expired. Stop trying to answer it; this request can no longer accept a result.`},urgency:"urgent",wake:1,idempotencyKey:`structured-request-expiry:${e.request_id}`})}catch(t){i("structured_request.expiry_notice_failed",t)}if(e.node_id!==null&&e.dedicated&&(e.state==="expired"||e.state==="canceled"||e.state==="failed"))try{if(e.state==="expired")await y(e.node_id,new Date(e.deadline_at??Date.now()).toISOString(),Date.now());else{const t=s(e.node_id);t!==null&&(t.status==="active"||t.status==="idle")&&S(e.node_id,"cancel",{reason:"stranded"});const r=await q(e.node_id);if(!r.confirmed)throw r.error??new Error("broker teardown was not confirmed")}}catch(t){i("structured_request.teardown_failed",t)}a||l(e.request_id,u)}n(j,"applySettlementEffects"),m(e=>{j(e)});export{j as applySettlementEffects};
1
+ var o=Object.defineProperty;var n=(e,d)=>o(e,"name",{value:d,configurable:!0});import{markStructuredRequestEffectsDone as l,ownsStructuredRequestDeclineProjection as _,ownsStructuredRequestResultProjection as f,registerStructuredRequestEffectRunner as m}from"../../core/canvas/structured-requests.js";import{getNode as a}from"../../core/canvas/index.js";import{emitEvent as p}from"../../core/events/emit.js";import{requestBrokerTeardown as q}from"../../core/runtime/host.js";import{transition as S}from"../../core/runtime/lifecycle.js";import{expireNodeDeadline as y}from"../reconcilers/node-deadline.js";import{installStagedStructuredProjection as c,readOutputRequest as g,removeOutputSchema as h,stageStructuredResult as x,writeOutputDeclined as D}from"../../core/runtime/structured-output.js";import{enqueueNodeMail as R}from"../../core/feed/messages.js";import{notifyStructuredRequest as v}from"./notifier.js";function b(e){if(e.node_id===null)return!1;const d=g(e.node_id);return d.state==="valid"&&d.request.request_id===e.request_id}n(b,"ownsCurrentSidecar");async function j(e,d){v(e.request_id);let s=!1,u=null;const r=n((t,i)=>{s=!0,p({level:"error",event:t,node_id:e.node_id??void 0,error:i,fields:{request_id:e.request_id}})},"report");if(e.node_id!==null&&e.state==="completed")try{const t=e.submission,i=(await a(e.node_id))?.grantee;await f(e)&&(u=d===void 0?c(x(e.node_id,e.request_id,t,e.result,i)):c(d))}catch(t){r("structured_request.projection_failed",t)}if(e.node_id!==null&&e.state==="declined"&&await _(e)&&e.declined!==null)try{u=D(e.node_id,{mode:e.submission,...e.declined,at:new Date(e.settled_at??Date.now()).toISOString()},(await a(e.node_id))?.grantee)}catch(t){r("structured_request.decline_projection_failed",t)}if(e.node_id!==null&&b(e))try{h(e.node_id,e.request_id)}catch(t){r("structured_request.sidecar_remove_failed",t)}if(e.node_id!==null&&!e.dedicated&&e.state==="expired")try{await R(e.node_id,{kind:"urgent",label:`Structured request ${e.request_id} expired`,bodyJson:{body:`Structured request ${e.request_id} expired. Stop trying to answer it; this request can no longer accept a result.`},urgency:"urgent",wake:1,idempotencyKey:`structured-request-expiry:${e.request_id}`})}catch(t){r("structured_request.expiry_notice_failed",t)}if(e.node_id!==null&&e.dedicated&&(e.state==="expired"||e.state==="canceled"||e.state==="failed"))try{if(e.state==="expired")await y(e.node_id,new Date(e.deadline_at??Date.now()).toISOString(),Date.now());else{const t=await a(e.node_id);t!==null&&(t.status==="active"||t.status==="idle")&&await S(e.node_id,"cancel",{reason:"stranded"});const i=await q(e.node_id);if(!i.confirmed)throw i.error??new Error("broker teardown was not confirmed")}}catch(t){r("structured_request.teardown_failed",t)}s||await l(e.request_id,u)}n(j,"applySettlementEffects"),m(e=>{j(e)});export{j as applySettlementEffects};
@@ -1,3 +1,3 @@
1
1
  import { type StructuredOutputMode } from '../../core/runtime/structured-output.js';
2
2
  /** Admit legacy node/message schema requests before publishing their sidecar. */
3
- export declare function admitLegacyStructuredOutput(nodeId: string, submission: StructuredOutputMode, schema: Record<string, unknown>, requestMessageId?: string): string;
3
+ export declare function admitLegacyStructuredOutput(nodeId: string, submission: StructuredOutputMode, schema: Record<string, unknown>, requestMessageId?: string): Promise<string>;
@@ -1 +1 @@
1
- var i=Object.defineProperty;var e=(t,r)=>i(t,"name",{value:r,configurable:!0});import{registerLegacyStructuredRequest as o}from"../../core/canvas/structured-requests.js";import{writeStructuredRequestSidecar as d}from"../../core/runtime/structured-output.js";function S(t,r,u,c){return d(o(t,r,u,c))}e(S,"admitLegacyStructuredOutput");export{S as admitLegacyStructuredOutput};
1
+ var i=Object.defineProperty;var e=(t,r)=>i(t,"name",{value:r,configurable:!0});import{registerLegacyStructuredRequest as a}from"../../core/canvas/structured-requests.js";import{writeStructuredRequestSidecar as o}from"../../core/runtime/structured-output.js";async function p(t,r,u,c){return o(await a(t,r,u,c))}e(p,"admitLegacyStructuredOutput");export{p as admitLegacyStructuredOutput};
@@ -1,3 +1,3 @@
1
- var Q=Object.defineProperty;var h=(_,k)=>Q(_,"name",{value:k,configurable:!0});import{spawn as W}from"node:child_process";import{createHash as X}from"node:crypto";import{chownSync as K,chmodSync as H,closeSync as Y,existsSync as Z,mkdirSync as $,readFileSync as ee,rmSync as te,statSync as re}from"node:fs";import{createServer as ne}from"node:net";import{dirname as F,join as E}from"node:path";import{fileURLToPath as oe}from"node:url";import{loadLinuxNative as se}from"../native/linux.js";import{envHomeOverride as ie}from"../shared/env.js";import{launchSandbox as ae}from"./bwrap.js";import{LaunchGate as de}from"./launch-gate.js";import{serveAccepted as ce}from"./accepted-socket.js";import{installNetworkRule as ue}from"./netrule.js";import{LAUNCHER_SOCKET as S,LaunchRefused as u}from"./spec.js";import{systemIdentity as pe,AppUsers as le}from"./users.js";import{SourceValidator as fe}from"./validate.js";import{prepareDaemonScopeDirectories as me}from"./scope-directories.js";import{LimitsManager as he}from"./limits/manager.js";import{CRTRD_OOM_SCORE_ADJ as we}from"./limits/policy.js";import{writeLimitsLog as ge}from"./limits/log.js";const P=se();function J(_){const k=_._handle?.fd;if(k===void 0||k<0)throw new Error("launcher socket fd unavailable");return k}h(J,"socketFd");async function Pe(_={}){const k=_.superviseDaemon??!0;if(process.platform!=="linux"||process.getuid?.()!==0||!P)throw new Error("launcher requires Linux root and its native addon");const{daemonUid:L,daemonGid:x,dataGid:M}=pe(),T=F(S);if($(T,{recursive:!0,mode:493}),(re(T).mode&511)!==493)throw new Error(`${T} must be mode 0755`);K(T,L,x),process.umask(7);const N=E(T,"nodes");$(N,{recursive:!0,mode:504}),K(N,0,x),H(N,504);const v=new fe(ie()||"/",x);me(E(v.root,"runtime"),L,x);const b=new le(M);ue();const d=new he({runtimeRoot:v.runtime,appsRoot:E(v.root,"apps"),stateDir:E(v.runtime,"limits-state"),dataGid:M,users:b});d.init();const G=new Map,j=h(r=>{const p=d.takeEvents();for(const o of p)ge(o);return p.length===0?r:{...r,events:p}},"reply_"),B=new de,I=new Map,R=new Map,q=h((r,p)=>{const o=p.capture,c=X("sha256"),w=h((l,i)=>{let f=0,a=!1;const m=[];return{take(y){i?.update(y);const D=Math.max(0,Math.min(y.length,l-f));D&&(m.push(y.subarray(0,D)),f+=D),D!==y.length&&(a=!0)},result:h(()=>({text:Buffer.concat(m).toString("utf8"),truncated:a}),"result")}},"chunks"),e=w(o.stdoutBytes,c),s=w(o.stderrBytes);let t=Buffer.alloc(0),n=0;return r.stdout?.on("data",l=>e.take(l)),r.stderr?.on("data",l=>{const i=l;o.stderrTail?(n+=i.length,t=i.length>=o.stderrBytes?i.subarray(i.length-o.stderrBytes):Buffer.concat([t,i]).subarray(Math.max(0,t.length+i.length-o.stderrBytes))):s.take(i)}),new Promise(l=>r.once("close",(i,f)=>{const a=e.result(),m=o.stderrTail?{text:t.toString("utf8"),truncated:n>o.stderrBytes}:s.result();l({exitCode:i,signal:f,stdout:a.text,stderr:m.text,stdoutTruncated:a.truncated,stderrTruncated:m.truncated,stdoutSha256:c.digest("hex")})}))},"captureExit"),V=h(r=>{const p=new Set;for(;r>1&&!p.has(r);){const o=I.get(r);if(o)return o;p.add(r);try{const c=ee(`/proc/${r}/status`,"utf8");r=Number(/^PPid:\s*(\d+)/m.exec(c)?.[1]??0)}catch{return null}}return null},"sandboxForPid");let g,C=!1;const z=E(F(oe(import.meta.url)),"../daemon/crtrd-cli.js"),U=h(()=>{C||(g=W("/bin/setpriv",["--reuid",String(L),"--regid",String(x),"--groups",String(M),"--",process.execPath,z,...process.argv.slice(2)],{stdio:"inherit",env:{...process.env,CRTR_LAUNCHER_SOCKET:S,CRTR_HOME:v.root}}),g.pid&&d.protectDaemon(g.pid,we),g.once("exit",()=>{g=void 0,C||U()}),g.once("error",r=>{console.error("crtrd spawn failed:",r),process.exitCode=1,C=!0}))},"startDaemon");Z(S)&&te(S);const O=ne({pauseOnConnect:!0},r=>ce(r,p=>{const o=[];return(async()=>{try{const c=P.peerCred(J(r)).uid;if(c!==L&&c!==0)throw new u("invalid_spec","launcher peer is not crtrd or root");let w;for(;;)try{w=P.recvFds(J(r));break}catch(t){if(t.code!=="EINTR")throw t}p(),o.push(...w.fds);const e=JSON.parse(w.data);let s;switch(e.operation){case"launch":{if(o.length>1)throw new u("invalid_uid","app uid is not registered");let t,n,l;try{n=await B.launch(async()=>{if(!b.has(e.spec.uid))throw new u("invalid_uid","app uid is not registered");const i=l=d.prepareRun(e.spec.uid,e.spec.nodeId,e.spec.broker===!0);return ae(e.spec,o[0],v,M,f=>{if(!f.pid)throw new u("launch_failed","bwrap has no pid");t=f.pid;const a=f.pid;if(I.set(a,{child:f,uid:e.spec.uid,nodeId:e.spec.nodeId,mounts:e.spec.mounts,plan:i}),f.once("exit",()=>{I.delete(a);const m=d.finishRun(i);G.set(a,m.oomKilled),setTimeout(()=>G.delete(a),5*6e4).unref()}),e.spec.capture){const m=q(f,e.spec).then(y=>({...y,oomKilled:G.get(a)===!0}));R.set(a,m),m.then(()=>{setTimeout(()=>{R.get(a)===m&&R.delete(a)},3e5).unref()})}},i)})}catch(i){throw t!==void 0?R.delete(t):l&&d.finishRun(l),i}if(!n.pid)throw new u("launch_failed","bwrap has no pid");d.confirmStarted(l,n.pid),s={pid:n.pid};break}case"wait":{const t=R.get(e.pid);if(!t)throw new u("invalid_spec","unknown captured sandbox pid");const n=await t;R.delete(e.pid),s={result:n};break}case"stop":{const t=Number.isInteger(e.pid)?V(e.pid):null;if(!t||e.nodeId!==void 0&&t.nodeId!==e.nodeId)throw new u("invalid_spec","unknown sandbox pid");if(e.signal!==void 0&&e.signal!=="SIGTERM"&&e.signal!=="SIGKILL")throw new u("invalid_spec","invalid stop signal");const n=e.signal??"SIGKILL";t.child.kill(n),n==="SIGKILL"&&d.killRun(t.plan),s={ok:!0};break}case"user.create":s={uid:await B.write(()=>b.create(e.app,e.uid))};break;case"user.delete":{await B.write(()=>{if([...I.values()].some(t=>t.uid===e.uid))throw new u("invalid_spec","stop this app\u2019s sandboxes before deleting its user");b.delete(e.uid)}),s={ok:!0};break}case"users.sync":await B.write(()=>b.sync(e.users)),s={ok:!0};break;case"list":s={sandboxes:[...I].map(([t,n])=>({pid:t,uid:n.uid,nodeId:n.nodeId,mounts:n.mounts}))};break;case"limits.apply":{const t=b.entries().find(n=>n.app===e.app.replace(/^app:/,""));if(!t)throw new u("invalid_uid","app is not registered");d.applyApp(t.app,t.uid,!0),s={ok:!0};break}case"memory.admit":{const t=b.entries().find(n=>n.app===e.app.replace(/^app:/,""));if(!t)throw new u("invalid_uid","app is not registered");s=d.admitBroker(t.app,e.nodeId);break}case"limits.show":s={limits:d.show()};break;case"disk.usage":s={disk:await d.diskUsageReport()};break;case"cache.purge":s={purged:await d.cachePass()};break;case"exit.status":s={oomKilled:G.get(e.pid)===!0};break;case"daemon.handover":g?.kill("SIGTERM"),s={ok:!0};break;default:throw new u("invalid_spec","unknown launcher operation")}return`${JSON.stringify(j(s))}
1
+ var Q=Object.defineProperty;var h=(_,k)=>Q(_,"name",{value:k,configurable:!0});import{spawn as W}from"node:child_process";import{createHash as X}from"node:crypto";import{chownSync as K,chmodSync as H,closeSync as Y,existsSync as Z,mkdirSync as $,readFileSync as ee,rmSync as te,statSync as re}from"node:fs";import{createServer as ne}from"node:net";import{dirname as F,join as E}from"node:path";import{fileURLToPath as oe}from"node:url";import{loadLinuxNative as se}from"../native/linux.js";import{envHomeOverride as ie}from"../shared/env.js";import{launchSandbox as ae}from"./bwrap.js";import{LaunchGate as de}from"./launch-gate.js";import{serveAccepted as ce}from"./accepted-socket.js";import{installNetworkRule as ue}from"./netrule.js";import{LAUNCHER_SOCKET as S,LaunchRefused as u}from"./spec.js";import{systemIdentity as pe,AppUsers as le}from"./users.js";import{SourceValidator as fe}from"./validate.js";import{prepareDaemonScopeDirectories as me}from"./scope-directories.js";import{LimitsManager as he}from"./limits/manager.js";import{CRTRD_OOM_SCORE_ADJ as we}from"./limits/policy.js";import{writeLimitsLog as ge}from"./limits/log.js";const P=se();function J(_){const k=_._handle?.fd;if(k===void 0||k<0)throw new Error("launcher socket fd unavailable");return k}h(J,"socketFd");async function Pe(_={}){const k=_.superviseDaemon??!0;if(process.platform!=="linux"||process.getuid?.()!==0||!P)throw new Error("launcher requires Linux root and its native addon");const{daemonUid:L,daemonGid:x,dataGid:M}=pe(),T=F(S);if($(T,{recursive:!0,mode:493}),(re(T).mode&511)!==493)throw new Error(`${T} must be mode 0755`);K(T,L,x),process.umask(7);const N=E(T,"nodes");$(N,{recursive:!0,mode:504}),K(N,0,x),H(N,504);const v=new fe(ie()||"/",x);me(E(v.root,"runtime"),L,x);const b=new le(M);ue();const d=new he({runtimeRoot:v.runtime,appsRoot:E(v.root,"apps"),stateDir:E(v.runtime,"limits-state"),dataGid:M,users:b});d.init();const G=new Map,j=h(r=>{const p=d.takeEvents();for(const o of p)ge(o);return p.length===0?r:{...r,events:p}},"reply_"),B=new de,I=new Map,R=new Map,q=h((r,p)=>{const o=p.capture,c=X("sha256"),w=h((l,i)=>{let f=0,a=!1;const m=[];return{take(y){i?.update(y);const D=Math.max(0,Math.min(y.length,l-f));D&&(m.push(y.subarray(0,D)),f+=D),D!==y.length&&(a=!0)},result:h(()=>({text:Buffer.concat(m).toString("utf8"),truncated:a}),"result")}},"chunks"),e=w(o.stdoutBytes,c),s=w(o.stderrBytes);let t=Buffer.alloc(0),n=0;return r.stdout?.on("data",l=>e.take(l)),r.stderr?.on("data",l=>{const i=l;o.stderrTail?(n+=i.length,t=i.length>=o.stderrBytes?i.subarray(i.length-o.stderrBytes):Buffer.concat([t,i]).subarray(Math.max(0,t.length+i.length-o.stderrBytes))):s.take(i)}),new Promise(l=>r.once("close",(i,f)=>{const a=e.result(),m=o.stderrTail?{text:t.toString("utf8"),truncated:n>o.stderrBytes}:s.result();l({exitCode:i,signal:f,stdout:a.text,stderr:m.text,stdoutTruncated:a.truncated,stderrTruncated:m.truncated,stdoutSha256:c.digest("hex")})}))},"captureExit"),V=h(r=>{const p=new Set;for(;r>1&&!p.has(r);){const o=I.get(r);if(o)return o;p.add(r);try{const c=ee(`/proc/${r}/status`,"utf8");r=Number(/^PPid:\s*(\d+)/m.exec(c)?.[1]??0)}catch{return null}}return null},"sandboxForPid");let g,C=!1;const z=E(F(oe(import.meta.url)),"../daemon/crtrd-cli.js"),U=h(()=>{C||(g=W("/bin/setpriv",["--reuid",String(L),"--regid",String(x),"--groups",String(M),"--",process.execPath,z,...process.argv.slice(2)],{stdio:"inherit",env:{...process.env,CRTR_LAUNCHER_SOCKET:S,CRTR_HOME:v.root}}),g.pid&&d.protectDaemon(g.pid,we),g.once("exit",()=>{g=void 0,C||U()}),g.once("error",r=>{console.error("crtrd spawn failed:",r),process.exitCode=1,C=!0}))},"startDaemon");Z(S)&&te(S);const O=ne({pauseOnConnect:!0},r=>ce(r,p=>{const o=[];return(async()=>{try{const c=P.peerCred(J(r)).uid;if(c!==L&&c!==0)throw new u("invalid_spec","launcher peer is not crtrd or root");let w;for(;;)try{w=P.recvFds(J(r));break}catch(t){if(t.code!=="EINTR")throw t}p(),o.push(...w.fds);const e=JSON.parse(w.data);let s;switch(e.operation){case"launch":{if(o.length>1)throw new u("invalid_uid","app uid is not registered");let t,n,l;try{n=await B.launch(async()=>{if(!b.has(e.spec.uid))throw new u("invalid_uid","app uid is not registered");const i=l=d.prepareRun(e.spec.uid,e.spec.nodeId,e.spec.broker===!0);return ae(e.spec,o[0],v,M,f=>{if(!f.pid)throw new u("launch_failed","bwrap has no pid");t=f.pid;const a=f.pid;if(I.set(a,{child:f,uid:e.spec.uid,nodeId:e.spec.nodeId,mounts:e.spec.mounts,plan:i}),f.once("exit",()=>{I.delete(a);const m=d.finishRun(i);G.set(a,m.oomKilled),setTimeout(()=>G.delete(a),5*6e4).unref()}),e.spec.capture){const m=q(f,e.spec).then(y=>({...y,oomKilled:G.get(a)===!0}));R.set(a,m),m.then(()=>{setTimeout(()=>{R.get(a)===m&&R.delete(a)},3e5).unref()})}},i)})}catch(i){throw t!==void 0?R.delete(t):l&&d.finishRun(l),i}if(!n.pid)throw new u("launch_failed","bwrap has no pid");d.confirmStarted(l,n.pid),s={pid:n.pid};break}case"wait":{const t=R.get(e.pid);if(!t)throw new u("invalid_spec","unknown captured sandbox pid");const n=await t;r.writable&&R.delete(e.pid),s={result:n};break}case"stop":{const t=Number.isInteger(e.pid)?V(e.pid):null;if(!t||e.nodeId!==void 0&&t.nodeId!==e.nodeId)throw new u("invalid_spec","unknown sandbox pid");if(e.signal!==void 0&&e.signal!=="SIGTERM"&&e.signal!=="SIGKILL")throw new u("invalid_spec","invalid stop signal");const n=e.signal??"SIGKILL";t.child.kill(n),n==="SIGKILL"&&d.killRun(t.plan),s={ok:!0};break}case"user.create":s={uid:await B.write(()=>b.create(e.app,e.uid))};break;case"user.delete":{await B.write(()=>{if([...I.values()].some(t=>t.uid===e.uid))throw new u("invalid_spec","stop this app\u2019s sandboxes before deleting its user");b.delete(e.uid)}),s={ok:!0};break}case"users.sync":await B.write(()=>b.sync(e.users)),s={ok:!0};break;case"list":s={sandboxes:[...I].map(([t,n])=>({pid:t,uid:n.uid,nodeId:n.nodeId,mounts:n.mounts}))};break;case"limits.apply":{const t=b.entries().find(n=>n.app===e.app.replace(/^app:/,""));if(!t)throw new u("invalid_uid","app is not registered");d.applyApp(t.app,t.uid,!0),s={ok:!0};break}case"memory.admit":{const t=b.entries().find(n=>n.app===e.app.replace(/^app:/,""));if(!t)throw new u("invalid_uid","app is not registered");s=d.admitBroker(t.app,e.nodeId);break}case"limits.show":s={limits:d.show()};break;case"disk.usage":s={disk:await d.diskUsageReport()};break;case"cache.purge":s={purged:await d.cachePass()};break;case"exit.status":s={oomKilled:G.get(e.pid)===!0};break;case"daemon.handover":g?.kill("SIGTERM"),s={ok:!0};break;default:throw new u("invalid_spec","unknown launcher operation")}return`${JSON.stringify(j(s))}
2
2
  `}catch(c){const w=c instanceof u?c.refusal:"launch_failed";return console.error(`launcher refusal ${w}:`,c),`${JSON.stringify({refusal:w})}
3
3
  `}finally{for(const c of o)Y(c)}})()}));await new Promise((r,p)=>{O.once("error",p),O.listen(S,r)}),K(S,L,x),H(S,384);const A=h(()=>{C=!0,g?.kill("SIGTERM");for(const{child:r}of I.values())r.kill("SIGKILL");O.close(),v.close()},"shutdown");process.once("SIGTERM",A),process.once("SIGINT",A),k&&U()}h(Pe,"runLauncher");export{Pe as runLauncher};
@@ -1,10 +1,10 @@
1
- import type { DatabaseSync } from 'node:sqlite';
2
1
  import type { ImportPlan, ImportReport } from './plan.js';
2
+ import type { CanvasDb } from '../../core/canvas/db.js';
3
3
  /** The canvas_meta key whose presence means this home's legacy stores were imported. */
4
4
  export declare const IMPORT_DONE_KEY = "canvas-import";
5
5
  export declare const IMPORT_ID = "004-canvas-documents";
6
- export declare function readImportRecord(db: DatabaseSync): ImportReport | null;
6
+ export declare function readImportRecord(db: CanvasDb): Promise<ImportReport | null>;
7
7
  /** Store every revision body. Call before `applyPlan`, outside its transaction. */
8
8
  export declare function storePlanBodies(plan: ImportPlan): Map<string, string>;
9
9
  /** Run inside the caller's write transaction. Throws on any divergence from the plan. */
10
- export declare function applyPlan(db: DatabaseSync, plan: ImportPlan, hashes: ReadonlyMap<string, string>): void;
10
+ export declare function applyPlan(db: CanvasDb, plan: ImportPlan, hashes: ReadonlyMap<string, string>): Promise<void>;
@@ -1 +1 @@
1
- var x=Object.defineProperty;var d=(n,t)=>x(n,"name",{value:t,configurable:!0});import{put as N}from"../../core/graph/bodies.js";import{importDocument as O}from"../../core/graph/documents.js";import{linksIn as _}from"../../core/graph/documents.js";import{recordActedOn as M,setLinks as R}from"../../core/graph/edges.js";import{resolveName as $}from"../../core/graph/names.js";import{ensureOwner as y,nodeObject as k,ownerForGrantee as b}from"../../core/graph/objects.js";import{ensureRepo as S}from"../../core/graph/repo-sync/repos.js";import{recordWatch as T}from"../../core/graph/watches.js";const v="canvas-import",K="004-canvas-documents";function C(n){const t=n.prepare("SELECT value FROM canvas_meta WHERE key = ?").get(v);if(t===void 0)return null;const p=JSON.parse(t.value).report;return{...p,resolutions:p.resolutions??[]}}d(C,"readImportRecord");function G(n){const t=new Map;for(const p of n.documents)for(const i of p.revisions)t.has(i.body)||t.set(i.body,N(i.body));return t}d(G,"storePlanBodies");function U(n,t,p){const i=new Map(t.owners.map(e=>[e.key,e])),f=new Map,u=d(e=>{const o=f.get(e.key);if(o)return o;let r;switch(e.type){case"person":r=b(n,"user:local");break;case"app":r=y(n,"app","app",`app:${e.handle}`,e.handle);break;case"profile":{const c=i.get(e.ownerKey);if(!c)throw new Error(`import: profile ${e.key} names unplanned app ${e.ownerKey}`);r=y(n,"profile","profile",e.key.slice(8),e.handle,u(c));break}case"repo":r=S(n,{scheme:e.scheme,externalId:e.externalId,handleHint:e.handle},e.handle);break;case"node":r=k(n,e.handle);break}if(e.type!=="node"&&r.name!==e.handle)throw new Error(`import: owner ${e.key} holds handle ${r.name}, planned ${e.handle}`);return f.set(e.key,r),r},"ownerRow"),I={class:"person",person:u(i.get("person")??{key:"person",type:"person",handle:"user"})},h=new Map,m=d(e=>{let o=h.get(e);return o||h.set(e,o=k(n,e)),o},"node"),w=[];for(const e of t.documents){const o=u(i.get(e.ownerKey)),r=O(n,{owner:o,name:e.name,kind:e.kind,preview:e.preview,privacy:e.privacy,summary:e.summary,whyItExists:e.whyItExists,unlisted:e.unlisted,rules:e.rules,lintIgnore:e.lintIgnore,extensions:e.extensions,revisions:e.revisions.map(s=>({body_hash:p.get(s.body),author:s.authorNodeId===null?null:m(s.authorNodeId),rationale:s.rationale,created_at:s.createdAt}))}),c=new Set(e.revisions.flatMap(s=>s.authorNodeId===null?[]:[s.authorNodeId]));w.push({doc:r,owner:o,body:e.revisions[e.revisions.length-1].body,authors:c})}for(const{doc:e,owner:o,body:r,authors:c}of w){const s=[];for(const a of _(r)){const g=a.includes("/")?[a]:[`${o.type==="node"?o.id:o.name}/${a}`,a];for(const E of g){const l=$(n,I,E);if("object"in l){s.push({written_as:a,dst:l.object});break}if("deleted"in l){s.push({written_as:a,dst:l.deleted});break}}}R(n,e,s);for(const a of c)M(n,m(a),e),T(n,m(a),e,"write")}n.prepare("INSERT INTO canvas_meta (key, value) VALUES (?, ?)").run(v,JSON.stringify({id:K,report:t.report}))}d(U,"applyPlan");export{v as IMPORT_DONE_KEY,K as IMPORT_ID,U as applyPlan,C as readImportRecord,G as storePlanBodies};
1
+ var x=Object.defineProperty;var d=(n,r)=>x(n,"name",{value:r,configurable:!0});import{put as N}from"../../core/graph/bodies.js";import{importDocument as O}from"../../core/graph/documents.js";import{linksIn as _}from"../../core/graph/documents.js";import{recordActedOn as M,setLinks as R}from"../../core/graph/edges.js";import{resolveName as $}from"../../core/graph/names.js";import{ensureOwner as y,nodeObject as k,ownerForGrantee as b}from"../../core/graph/objects.js";import{ensureRepo as S}from"../../core/graph/repo-sync/repos.js";import{recordWatch as T}from"../../core/graph/watches.js";import{mapAsync as A}from"../../core/async-array.js";const v="canvas-import",K="004-canvas-documents";async function G(n){const r=await n.prepareUncached("SELECT value FROM canvas_meta WHERE key = ?").get(v);if(r===void 0)return null;const p=JSON.parse(r.value).report;return{...p,resolutions:p.resolutions??[]}}d(G,"readImportRecord");function V(n){const r=new Map;for(const p of n.documents)for(const i of p.revisions)r.has(i.body)||r.set(i.body,N(i.body));return r}d(V,"storePlanBodies");async function Y(n,r,p){const i=new Map(r.owners.map(e=>[e.key,e])),m=new Map,w=d(async e=>{const t=m.get(e.key);if(t)return t;let o;switch(e.type){case"person":o=await b(n,"user:local");break;case"app":o=await y(n,"app","app",`app:${e.handle}`,e.handle);break;case"profile":{const c=i.get(e.ownerKey);if(!c)throw new Error(`import: profile ${e.key} names unplanned app ${e.ownerKey}`);o=await y(n,"profile","profile",e.key.slice(8),e.handle,await w(c));break}case"repo":o=await S(n,{scheme:e.scheme,externalId:e.externalId,handleHint:e.handle},e.handle);break;case"node":o=await k(n,e.handle);break}if(e.type!=="node"&&o.name!==e.handle)throw new Error(`import: owner ${e.key} holds handle ${o.name}, planned ${e.handle}`);return m.set(e.key,o),o},"ownerRow"),I={class:"person",person:await w(i.get("person")??{key:"person",type:"person",handle:"user"})},f=new Map,u=d(async e=>{let t=f.get(e);return t||f.set(e,t=await k(n,e)),t},"node"),h=[];for(const e of r.documents){const t=await w(i.get(e.ownerKey)),o=await O(n,{owner:t,name:e.name,kind:e.kind,preview:e.preview,privacy:e.privacy,summary:e.summary,whyItExists:e.whyItExists,unlisted:e.unlisted,rules:e.rules,lintIgnore:e.lintIgnore,extensions:e.extensions,revisions:await A(e.revisions,async a=>({body_hash:p.get(a.body),author:a.authorNodeId===null?null:await u(a.authorNodeId),rationale:a.rationale,created_at:a.createdAt}))}),c=new Set(e.revisions.flatMap(a=>a.authorNodeId===null?[]:[a.authorNodeId]));h.push({doc:o,owner:t,body:e.revisions[e.revisions.length-1].body,authors:c})}for(const{doc:e,owner:t,body:o,authors:c}of h){const a=[];for(const s of _(o)){const g=s.includes("/")?[s]:[`${t.type==="node"?t.id:t.name}/${s}`,s];for(const E of g){const l=await $(n,I,E);if("object"in l){a.push({written_as:s,dst:l.object});break}if("deleted"in l){a.push({written_as:s,dst:l.deleted});break}}}await R(n,e,a);for(const s of c)await M(n,await u(s),e),await T(n,await u(s),e,"write")}await n.prepareUncached("INSERT INTO canvas_meta (key, value) VALUES (?, ?)").run(v,JSON.stringify({id:K,report:r.report}))}d(Y,"applyPlan");export{v as IMPORT_DONE_KEY,K as IMPORT_ID,Y as applyPlan,G as readImportRecord,V as storePlanBodies};
@@ -8,9 +8,9 @@ export interface CanvasImportResult {
8
8
  pending: boolean;
9
9
  }
10
10
  /** Whether this home's import has already been recorded. */
11
- export declare function canvasImportDone(): boolean;
11
+ export declare function canvasImportDone(): Promise<boolean>;
12
12
  /** Plan and (unless `dryRun` or blocked) apply the import. On an imported home a dry run
13
13
  * returns the recorded report; a write run does nothing and returns empty counts. */
14
14
  export declare function runCanvasImport(opts: {
15
15
  dryRun: boolean;
16
- }): CanvasImportResult;
16
+ }): Promise<CanvasImportResult>;
@@ -1,2 +1,2 @@
1
- var g=Object.defineProperty;var a=(r,n)=>g(r,"name",{value:n,configurable:!0});import{existsSync as f}from"node:fs";import{join as l}from"node:path";import{openDb as c,withCanvasWrite as w}from"../../core/canvas/db.js";import{nodeAgentDir as k,nodeRecordDir as S,onDiskMigrationMarkerPath as C}from"../../core/canvas/paths.js";import{identifyCheckout as j}from"../../core/graph/repo-sync/identity.js";import{profileSpace as I,userRoot as b}from"../../core/layout.js";import{commitConvertedProjectCaps as E,listLegacyProjectCaps as P,listStoredProfiles as x}from"../../core/scoped-state/profiles.js";import{userStore as L}from"../../core/scoped-state/paths.js";import{userScopeRoot as y}from"../../core/scope.js";import{applyPlan as M,readImportRecord as h,storePlanBodies as _}from"./apply.js";import{readLegacyCorpus as v,readMarkerIds as D}from"./legacy/discover.js";import{planImport as O}from"./plan.js";const F=a(()=>({stores:[],counts:{},rewrites:[],droppedFields:[],skipped:[],resolutions:[]}),"emptyReport");function A(){const r=y(),n=x(r),o=P(r),d=L(r).path,i=n.map(({profileId:e,manifest:s})=>{const p=s.grantee??"app:terminal",m=new Map(o.filter(t=>t.profileId===e).map(t=>[t.path,t.memory]));return{id:e,name:s.name,app:p,memory:I(p,e).dir,projects:s.projects.map(t=>t.path),raw:{projects:s.projects.map(t=>m.has(t.path)?{path:t.path,memory:m.get(t.path)}:{path:t.path})},manifestPath:`${d}#${e}`}}),u=c().prepare("SELECT node_id, cwd, grantee FROM node_rows ORDER BY created").all(),R=u.map(e=>{const s=e.grantee==="user:local"?"app:terminal":e.grantee,p=s?.startsWith("app:")?k(e.node_id,s):null,m=p!==null&&(f(l(p,"context"))||f(l(p,"reports")))?p:S(e.node_id);return{id:e.node_id,dir:m}});return{roots:{userMemory:l(b(),"memory"),profiles:i,nodeCwds:[...new Set(u.map(e=>e.cwd))],nodes:R},stored:n}}a(A,"legacyRoots");function N(){const{roots:r,stored:n}=A(),o=v(r),d=c().prepare(`SELECT o.type, o.name AS handle, i.external_id AS externalId FROM objects o
2
- LEFT JOIN identities i ON i.object = o.rowid WHERE o.type IN ('person','app','repo','profile')`).all();return O(o,{roots:r,markerIds:D(C()),repoIdentity:j,existingOwners:d,storedProfiles:n.map(i=>({id:i.profileId,deliveryLimits:{...i.manifest.delivery_limits??{}}}))})}a(N,"plan");function V(){return h(c())!==null}a(V,"canvasImportDone");function X(r){const n=h(c());if(n!==null)return{report:r.dryRun?n:F(),blockers:[],dryRun:r.dryRun,pending:!1};const o=N();if(r.dryRun||o.blockers.length>0)return{report:o.report,blockers:o.blockers,dryRun:r.dryRun,pending:!0};const d=_(o);return E(y(),o.profileLimits),w(i=>M(i,o,d)),{report:o.report,blockers:[],dryRun:!1,pending:!1}}a(X,"runCanvasImport");export{V as canvasImportDone,X as runCanvasImport};
1
+ var R=Object.defineProperty;var p=(e,n)=>R(e,"name",{value:n,configurable:!0});import{existsSync as y}from"node:fs";import{join as l}from"node:path";import{openDb as m,withCanvasWrite as g}from"../../core/canvas/db.js";import{nodeAgentDir as k,nodeRecordDir as S,onDiskMigrationMarkerPath as C}from"../../core/canvas/paths.js";import{identifyCheckout as j}from"../../core/graph/repo-sync/identity.js";import{profileSpace as I,userRoot as b}from"../../core/layout.js";import{commitConvertedProjectCaps as E,listLegacyProjectCaps as P,listStoredProfiles as x}from"../../core/scoped-state/profiles.js";import{userStore as L}from"../../core/scoped-state/paths.js";import{userScopeRoot as f}from"../../core/scope.js";import{applyPlan as M,readImportRecord as w,storePlanBodies as _}from"./apply.js";import{readLegacyCorpus as v,readMarkerIds as D}from"./legacy/discover.js";import{planImport as O}from"./plan.js";const F=p(()=>({stores:[],counts:{},rewrites:[],droppedFields:[],skipped:[],resolutions:[]}),"emptyReport");async function A(){const e=f(),n=x(e),t=P(e),c=L(e).path,i=n.map(({profileId:r,manifest:a})=>{const s=a.grantee??"app:terminal",d=new Map(t.filter(o=>o.profileId===r).map(o=>[o.path,o.memory]));return{id:r,name:a.name,app:s,memory:I(s,r).dir,projects:a.projects.map(o=>o.path),raw:{projects:a.projects.map(o=>d.has(o.path)?{path:o.path,memory:d.get(o.path)}:{path:o.path})},manifestPath:`${c}#${r}`}}),u=await(await m()).prepareUncached("SELECT node_id, cwd, grantee FROM node_rows ORDER BY created").all(),h=u.map(r=>{const a=r.grantee==="user:local"?"app:terminal":r.grantee,s=a?.startsWith("app:")?k(r.node_id,a):null,d=s!==null&&(y(l(s,"context"))||y(l(s,"reports")))?s:S(r.node_id);return{id:r.node_id,dir:d}});return{roots:{userMemory:l(b(),"memory"),profiles:i,nodeCwds:[...new Set(u.map(r=>r.cwd))],nodes:h},stored:n}}p(A,"legacyRoots");async function N(){const{roots:e,stored:n}=await A(),t=v(e),c=await(await m()).prepareUncached(`SELECT o.type, o.name AS handle, i.external_id AS externalId FROM objects o
2
+ LEFT JOIN identities i ON i.object = o.rowid WHERE o.type IN ('person','app','repo','profile')`).all();return O(t,{roots:e,markerIds:D(C()),repoIdentity:j,existingOwners:c,storedProfiles:n.map(i=>({id:i.profileId,deliveryLimits:{...i.manifest.delivery_limits??{}}}))})}p(N,"plan");async function V(){return await w(await m())!==null}p(V,"canvasImportDone");async function X(e){const n=await w(await m());if(n!==null)return{report:e.dryRun?n:F(),blockers:[],dryRun:e.dryRun,pending:!1};const t=await N();if(e.dryRun||t.blockers.length>0)return{report:t.report,blockers:t.blockers,dryRun:e.dryRun,pending:!0};const c=_(t);return E(f(),t.profileLimits),await g(async i=>await M(i,t,c)),{report:t.report,blockers:[],dryRun:!1,pending:!1}}p(X,"runCanvasImport");export{V as canvasImportDone,X as runCanvasImport};
@@ -1,2 +1,2 @@
1
- var a=Object.defineProperty;var o=(r,t)=>a(r,"name",{value:t,configurable:!0});import{mkdirSync as c}from"node:fs";import{dirname as m}from"node:path";import{onDiskMigrationLockPath as u}from"../core/canvas/paths.js";import{withExclusiveDirectoryLockAsync as p}from"../core/exclusive-lock.js";import{DAEMON_STARTUP_WINDOW_MS as l}from"../daemon/startup-policy.js";import{canvasImportDone as h,runCanvasImport as s}from"./004-canvas-documents/index.js";class d extends Error{static{o(this,"MigrationBlockedError")}blockerPaths;constructor(t,n){super(t),this.name="MigrationBlockedError",this.blockerPaths=n}}function i(r){const t=u();return c(m(t),{recursive:!0,mode:448}),p(t,async()=>r(),{timeoutMs:l,timeoutError:o(()=>new Error(`timed out waiting for the canvas import lock: ${t}`),"timeoutError")})}o(i,"coordinate");async function M(){return i(()=>{if(h())return null;const r=s({dryRun:!1});if(r.blockers.length>0){const t=[...new Set(r.blockers.flatMap(e=>e.paths))],n=[`canvas import (004-canvas-documents) blocked by ${r.blockers.length} finding(s)`,...r.blockers.map(e=>`${e.kind}: ${e.message}`)];throw n.push("Repair each finding, then: crtr sys migrate --dry-run, then crtr sys migrate"),new d(n.join(`
2
- `),t)}return r})}o(M,"activateCanvasImport");async function w(r){return i(()=>s(r))}o(w,"runForcedCanvasImport");export{d as MigrationBlockedError,M as activateCanvasImport,w as runForcedCanvasImport};
1
+ var s=Object.defineProperty;var o=(r,t)=>s(r,"name",{value:t,configurable:!0});import{mkdirSync as c}from"node:fs";import{dirname as m}from"node:path";import{onDiskMigrationLockPath as u}from"../core/canvas/paths.js";import{withExclusiveDirectoryLockAsync as p}from"../core/exclusive-lock.js";import{DAEMON_STARTUP_WINDOW_MS as l}from"../daemon/startup-policy.js";import{canvasImportDone as h,runCanvasImport as e}from"./004-canvas-documents/index.js";class d extends Error{static{o(this,"MigrationBlockedError")}blockerPaths;constructor(t,n){super(t),this.name="MigrationBlockedError",this.blockerPaths=n}}function i(r){const t=u();return c(m(t),{recursive:!0,mode:448}),p(t,async()=>r(),{timeoutMs:l,timeoutError:o(()=>new Error(`timed out waiting for the canvas import lock: ${t}`),"timeoutError")})}o(i,"coordinate");async function E(){return await i(async()=>{if(await h())return null;const r=await e({dryRun:!1});if(r.blockers.length>0){const t=[...new Set(r.blockers.flatMap(a=>a.paths))],n=[`canvas import (004-canvas-documents) blocked by ${r.blockers.length} finding(s)`,...r.blockers.map(a=>`${a.kind}: ${a.message}`)];throw n.push("Repair each finding, then: crtr sys migrate --dry-run, then crtr sys migrate"),new d(n.join(`
2
+ `),t)}return r})}o(E,"activateCanvasImport");async function M(r){return await i(async()=>await e(r))}o(M,"runForcedCanvasImport");export{d as MigrationBlockedError,E as activateCanvasImport,M as runForcedCanvasImport};
@@ -19,7 +19,7 @@ await writeFile('acme.tar', bundle.tar);
19
19
 
20
20
  `buildBundle` returns `commandsJson`, `bundleJson`, generated `memory/` members, uncompressed tar bytes, and an ETag. It runs the manifest validator and throws `ManifestInvalidError` when the generated command manifest is invalid. `buildCommandManifest(plugin, { mountPath })` returns the manifest object when archive bytes are not needed.
21
21
 
22
- The tar has exactly `bundle.json`, `commands.json`, and `memory/<name>.md` members for the documents declared in the `memory` array of `definePlugin`. `bundle.json` carries `bundleVersion`, plus `version` when the plugin declares one, `object_kinds` when it declares object kinds, and `groups` when a provider declares its tool groups (the directory refuses a provider archive without them). `groups` is keyed by group id, each value `{"consent_line": string, "who"?: "own" | "user" | "allowlist" | "any", "allowlist"?: string[]}`, with `who` and `allowlist` written only when declared:
22
+ The tar has exactly `bundle.json`, `commands.json`, and `memory/<name>.md` members for the documents declared in the `memory` array of `definePlugin`. `bundle.json` carries `bundleVersion`, plus `version` when the plugin declares one, `object_kinds` when it declares object kinds, and `groups` when a provider declares its tool groups (the directory refuses a provider archive without them). `groups` is keyed by group id, each value `{"consent_line": string, "who"?: "own" | "user" | "allowlist" | "any" | "team:<id>", "allowlist"?: string[]}`, with `who` and `allowlist` written only when declared:
23
23
 
24
24
  ```json
25
25
  {"bundleVersion":1,"version":1,"groups":{"read":{"consent_line":"Read your Acme apps and deployments."},"deploy":{"consent_line":"Start deployments on your Acme apps.","who":"allowlist","allowlist":["app:k3x9"]}}}
@@ -30,7 +30,7 @@ definePlugin({
30
30
  });
31
31
  ```
32
32
 
33
- Each group has `consentLine`, the line the directory's consent page shows, and optionally `who` (`own`, `user`, `allowlist` or `any`; the directory treats an omitted `who` as `user`) and `allowlist` (app principals `app:<id>`, required with `who: 'allowlist'` and refused otherwise). `buildBundle` writes the block into `bundle.json` as `groups`, and the directory applies it when it refreshes the provider's manifest. The directory refuses a provider archive whose `bundle.json` has no `groups` (`bundle.json groups: is required`), and a provider's groups come only from this declaration: the directory's console and CLI do not edit groups. `definePlugin` itself accepts a provider without `groups`, but once declared every leaf's `group` must name a declared group and every declared group must be used by at least one leaf; `definePlugin` throws `PluginDefinitionError` otherwise. A plugin that is not `provider: true` must not declare `groups`.
33
+ Each group has `consentLine`, the line the directory's consent page shows, and optionally `who` (`own`, `user`, `allowlist`, `any` or `team:<id>`; the directory treats an omitted `who` as `user`) and `allowlist` (app principals `app:<id>`, required with `who: 'allowlist'` and refused otherwise). `buildBundle` writes the block into `bundle.json` as `groups`, and the directory applies it when it refreshes the provider's manifest. The directory refuses a provider archive whose `bundle.json` has no `groups` (`bundle.json groups: is required`), and a provider's groups come only from this declaration: the directory's console and CLI do not edit groups. `definePlugin` itself accepts a provider without `groups`, but once declared every leaf's `group` must name a declared group and every declared group must be used by at least one leaf; `definePlugin` throws `PluginDefinitionError` otherwise. A plugin that is not `provider: true` must not declare `groups`.
34
34
 
35
35
  A branch or leaf may set `tier` to `common` or `important` to be promoted into its parent's `-h`. A command with more than 40 children lists only its promoted children in its own `-h`, followed by the count of the rest; the others still run and answer `-h` by name. Use this when a plugin mounts one command per entry of a large catalog. On such a command only promoted leaves reach the top-level `crtr -h`; a promoted branch shows in the command's own `-h`.
36
36
 
@@ -20,6 +20,17 @@ break without notice across versions.
20
20
  The library barrels declare no load-time side effects and no circular imports —
21
21
  importing them is safe to do speculatively.
22
22
 
23
+ ## Stability
24
+
25
+ The root barrel is server-facing and may change between versions. **Since this version, canvas reads and runtime control return Promises; await them.** The canvas database is now reached through an async handle, so these root-barrel exports changed from synchronous to `Promise`-returning with no synchronous wrapper and no `*Async` alias:
26
+
27
+ - Runtime control: `closeNode`, `enqueueNodeMail`.
28
+ - Canvas reads: `getNode`, `listNodes`, `ticketCountsForNodes`, `ticketsAcrossCanvas`.
29
+
30
+ `reviveNode` was already asynchronous. `appendSituationalContext`, `readTelemetry`, `readContextTokens`, `nodeDir` and `isTurnInternal` are unchanged and stay synchronous.
31
+
32
+ A caller that has not been updated gets a Promise where it expected a value: `getNode(id) === null` is never true, `listNodes().filter(...)` throws, and `closeNode` errors become rejections instead of thrown exceptions. The `/v1` HTTP contract and the CLI are unchanged.
33
+
23
34
  ## Root-barrel surface, by area
24
35
 
25
36
  Read `src/index.ts` for the exact current export list (it is short and
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@north-light/cli",
3
- "version": "0.3.529",
3
+ "version": "0.3.531",
4
4
  "description": "crtr — agent runtime with memory, plugins, and marketplaces",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -107,6 +107,7 @@
107
107
  "check:cli-cold-start": "node scripts/check-cli-cold-start.mjs",
108
108
  "check:cli-leaf-load": "node scripts/check-cli-leaf-load.mjs",
109
109
  "check:daemon-no-barrel": "node scripts/check-daemon-no-barrel.mjs",
110
+ "check:promise-discard": "node scripts/check-promise-discard.mjs",
110
111
  "check:quote-style": "node scripts/check-quote-style.mjs",
111
112
  "postinstall": "node scripts/postinstall.mjs",
112
113
  "install-runtime": "node scripts/install-runtime.mjs",
@@ -116,7 +117,7 @@
116
117
  "link": "npm link",
117
118
  "prepublishOnly": "npm run build",
118
119
  "test": "CRTR_NO_DAEMON_AUTOSTART=1 node --conditions=crtr-src --import tsx/esm --import ./scripts/test-env-scrub.mjs --test --test-concurrency=$(node -p 'Math.max(4, require(`node:os`).availableParallelism() - 1)') --test-timeout=10000 ${CRTR_TEST_SHARD:+--test-shard=$CRTR_TEST_SHARD} 'src/**/__tests__/*.test.ts'",
119
- "test:integration": "npm run build:api && CRTR_NO_DAEMON_AUTOSTART=1 node --conditions=crtr-src --import tsx/esm --import ./scripts/test-env-scrub.mjs --test --test-concurrency=$(node -p 'Math.min(8, Math.max(2, require(`node:os`).availableParallelism() - 1))') --test-timeout=60000 ${CRTR_TEST_SHARD:+--test-shard=$CRTR_TEST_SHARD} 'src/**/__tests__/integration/*.test.ts' 'packages/crouter-sdk/src/**/__tests__/integration/*.test.ts' 'packages/crouter-plugin/src/**/__tests__/integration/*.test.ts'",
120
+ "test:integration": "npm run build:sdk && CRTR_NO_DAEMON_AUTOSTART=1 node --conditions=crtr-src --import tsx/esm --import ./scripts/test-env-scrub.mjs --test --test-concurrency=$(node -p 'Math.min(8, Math.max(2, require(`node:os`).availableParallelism() - 1))') --test-timeout=60000 ${CRTR_TEST_SHARD:+--test-shard=$CRTR_TEST_SHARD} 'src/**/__tests__/integration/*.test.ts' 'packages/crouter-sdk/src/**/__tests__/integration/*.test.ts' 'packages/crouter-plugin/src/**/__tests__/integration/*.test.ts'",
120
121
  "test:seam": "npm run build && npm run test:seam:built",
121
122
  "test:sdk": "npm run build:api && npm run build:identity && node --conditions=crtr-src --import tsx/esm --test --test-timeout=60000 'packages/crouter-sdk/src/__tests__/*.test.ts' 'packages/crouter-sdk/src/__tests__/integration/*.test.ts'",
122
123
  "test:sdk:pg": "node -e \"if (!process.env.TEST_DATABASE_URL) { console.error('test:sdk:pg needs TEST_DATABASE_URL (a disposable PostgreSQL), e.g. docker run --rm -d -e POSTGRES_PASSWORD=pw -p 127.0.0.1:55432:5432 postgres:18-alpine; TEST_DATABASE_URL=postgres://postgres:pw@127.0.0.1:55432/postgres'); process.exit(1) }\" && node --conditions=crtr-src --import tsx/esm --test --test-timeout=60000 'packages/crouter-sdk/src/**/__tests__/**/*.pg.test.ts'",
@@ -139,7 +140,7 @@
139
140
  },
140
141
  "license": "UNLICENSED",
141
142
  "dependencies": {
142
- "@north-light/identity": "0.3.529",
143
+ "@north-light/identity": "0.3.531",
143
144
  "@earendil-works/pi-agent-core": "1.1.0",
144
145
  "@earendil-works/pi-ai": "1.1.0",
145
146
  "@earendil-works/pi-coding-agent": "1.1.0",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@north-light/identity",
3
- "version": "0.3.529",
3
+ "version": "0.3.531",
4
4
  "description": "Northlight access-token verification and scope rules",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
package/runtime.lock.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@north-light/cli",
3
- "version": "0.3.529",
3
+ "version": "0.3.531",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@north-light/cli",
9
- "version": "0.3.529",
9
+ "version": "0.3.531",
10
10
  "hasInstallScript": true,
11
11
  "license": "UNLICENSED",
12
12
  "workspaces": [
@@ -24,7 +24,7 @@
24
24
  "@milkdown/preset-gfm": "^7.22.3",
25
25
  "@milkdown/prose": "^7.22.3",
26
26
  "@milkdown/utils": "^7.22.3",
27
- "@north-light/identity": "0.3.529",
27
+ "@north-light/identity": "0.3.531",
28
28
  "cron-parser": "^5.6.0",
29
29
  "esbuild": "^0.27.7",
30
30
  "jose": "^6.2.12",
@@ -12468,17 +12468,17 @@
12468
12468
  },
12469
12469
  "packages/crouter-api": {
12470
12470
  "name": "@north-light/api",
12471
- "version": "0.3.529",
12471
+ "version": "0.3.531",
12472
12472
  "license": "UNLICENSED"
12473
12473
  },
12474
12474
  "packages/crouter-env-docker": {
12475
12475
  "name": "@north-light/env-docker",
12476
- "version": "0.3.529",
12476
+ "version": "0.3.531",
12477
12477
  "license": "UNLICENSED"
12478
12478
  },
12479
12479
  "packages/crouter-identity": {
12480
12480
  "name": "@north-light/identity",
12481
- "version": "0.3.529",
12481
+ "version": "0.3.531",
12482
12482
  "license": "UNLICENSED",
12483
12483
  "dependencies": {
12484
12484
  "jose": "^6.2.1"
@@ -12486,20 +12486,20 @@
12486
12486
  },
12487
12487
  "packages/crouter-plugin": {
12488
12488
  "name": "@north-light/plugin",
12489
- "version": "0.3.529",
12489
+ "version": "0.3.531",
12490
12490
  "license": "UNLICENSED",
12491
12491
  "dependencies": {
12492
- "@north-light/api": "0.3.529",
12493
- "@north-light/identity": "0.3.529"
12492
+ "@north-light/api": "0.3.531",
12493
+ "@north-light/identity": "0.3.531"
12494
12494
  }
12495
12495
  },
12496
12496
  "packages/crouter-sdk": {
12497
12497
  "name": "@north-light/sdk",
12498
- "version": "0.3.529",
12498
+ "version": "0.3.531",
12499
12499
  "license": "UNLICENSED",
12500
12500
  "dependencies": {
12501
- "@north-light/api": "0.3.529",
12502
- "@north-light/identity": "0.3.529",
12501
+ "@north-light/api": "0.3.531",
12502
+ "@north-light/identity": "0.3.531",
12503
12503
  "jose": "^6.2.1"
12504
12504
  },
12505
12505
  "bin": {