@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,54 +1,54 @@
1
- import type { DatabaseSync } from 'node:sqlite';
2
1
  import type { ObjectRow, Reader } from './types.js';
2
+ import type { CanvasDb } from '../canvas/db.js';
3
3
  /** The object's owners, nearest first, ending at its space; empty when the object is a space.
4
4
  * CROSS JOIN pins the chain as the outer loop: left to the planner, it scans every
5
5
  * object and probes the chain, which made each read check cost milliseconds. */
6
- export declare function ownerChain(db: DatabaseSync, object: ObjectRow): ObjectRow[];
7
- export declare function spaceOf(db: DatabaseSync, object: ObjectRow): ObjectRow;
6
+ export declare function ownerChain(db: CanvasDb, object: ObjectRow): Promise<ObjectRow[]>;
7
+ export declare function spaceOf(db: CanvasDb, object: ObjectRow): Promise<ObjectRow>;
8
8
  /** A shipped document: one a package reconciler owns, read from its package file
9
9
  * (`documents.source_path` is set). Only the reconciler writes it. */
10
- export declare function isShipped(db: DatabaseSync, object: ObjectRow): boolean;
10
+ export declare function isShipped(db: CanvasDb, object: ObjectRow): Promise<boolean>;
11
11
  /** The apps whose tools a run may use, `crtr` last. On a local runtime (v0) every
12
12
  * installed, enabled plugin's tools are usable by every run, and an installed
13
13
  * plugin is exactly an app holding live shipped documents. Hosted grants narrow
14
14
  * this per reader later; `mayUseTools` is the one question both ask. */
15
- export declare function toolApps(db: DatabaseSync, reader: Reader): ObjectRow[];
15
+ export declare function toolApps(db: CanvasDb, reader: Reader): Promise<ObjectRow[]>;
16
16
  /** May `reader` use any of `app`'s tool groups? v0: every run may use every installed plugin's tools. */
17
- export declare function mayUseTools(_db: DatabaseSync, _reader: Reader, app: ObjectRow): boolean;
17
+ export declare function mayUseTools(_db: CanvasDb, _reader: Reader, app: ObjectRow): boolean;
18
18
  /** Whether `scopes` hold a provider-group scope `<provider>:<group>` of `app`: what a run needs to call that app's provider commands
19
19
  * (`requireGroup`). The provider id is the app's client id. */
20
- export declare function holdsProviderGroup(db: DatabaseSync, scopes: readonly string[], app: ObjectRow): boolean;
20
+ export declare function holdsProviderGroup(db: CanvasDb, scopes: readonly string[], app: ObjectRow): Promise<boolean>;
21
21
  /** Whether this reader may register, publish or watch as an object owned by `owner`. */
22
- export declare function mayActAs(db: DatabaseSync, reader: Reader, owner: ObjectRow): boolean;
22
+ export declare function mayActAs(db: CanvasDb, reader: Reader, owner: ObjectRow): Promise<boolean>;
23
23
  /** Run confinement for a node acting on a custom object of its app (Silas, 2026-09-30):
24
24
  * a node reaches an object registered in its own run, or when neither run is isolated.
25
25
  * An object the person or the app's server registered is reached by nodes outside
26
26
  * isolation only. Any other reader is unchanged. */
27
- export declare function customReachable(db: DatabaseSync, reader: Reader, object: ObjectRow): boolean;
27
+ export declare function customReachable(db: CanvasDb, reader: Reader, object: ObjectRow): Promise<boolean>;
28
28
  /** The `crtr:objects:*` targets an object belongs to, from its owner chain (rulings R5):
29
29
  * person space → `user`; under an app's profile → `profile:<id>`; a node of an app or a custom
30
30
  * object → `app:<x>`; any node (local, or a stub of one of the account's nodes) → `node`.
31
31
  * App documents and the profile itself stay under the memory scopes; a repo has no target.
32
32
  * The app's own `app:<x>` is left out: its own objects need no scope. */
33
- export declare function objectsTargets(db: DatabaseSync, object: ObjectRow, appGrantee: string): string[];
33
+ export declare function objectsTargets(db: CanvasDb, object: ObjectRow, appGrantee: string): Promise<string[]>;
34
34
  /** Whether a non-person reader's scopes hold `crtr:objects:<verb>:<t>` for a target t of `object`.
35
35
  * False for a person and for a revoked grant (`scopes === null`). `covers` is exact equality here. */
36
- export declare function holdsObjectsScope(db: DatabaseSync, reader: Reader, verb: 'read' | 'watch' | 'link' | 'write', object: ObjectRow): boolean;
36
+ export declare function holdsObjectsScope(db: CanvasDb, reader: Reader, verb: 'read' | 'watch' | 'link' | 'write', object: ObjectRow): Promise<boolean>;
37
37
  /** Whether the watch `watcher` → `object` that `app` made through `link` still authorizes delivering `object`'s events to `watcher` past the
38
38
  * watcher's read gate: `app` owns `object` (directly, or through its profile: `mayActAs`) and, when its `scopes` are known, they hold
39
39
  * `crtr:objects:link:<t>` for the watcher. Null `scopes` (a stub of a remote object: the home already checked the link) skip the scope. It grants
40
40
  * delivery of this one object's events only; nothing about reading it. */
41
- export declare function linkAuthorizes(db: DatabaseSync, app: ObjectRow, scopes: readonly string[] | null, object: ObjectRow, watcher: ObjectRow): boolean;
41
+ export declare function linkAuthorizes(db: CanvasDb, app: ObjectRow, scopes: readonly string[] | null, object: ObjectRow, watcher: ObjectRow): Promise<boolean>;
42
42
  /** Callers turn `false` into `not_found`. A person reader reads everything. An app's
43
43
  * shipped documents are read by any run that may use that app's tools. */
44
- export declare function canRead(db: DatabaseSync, reader: Reader, object: ObjectRow): boolean;
44
+ export declare function canRead(db: CanvasDb, reader: Reader, object: ObjectRow): Promise<boolean>;
45
45
  /** `canRead` for many readers of one object: the owner chain is walked once. */
46
- export declare function readCheck(db: DatabaseSync, object: ObjectRow): (reader: Reader) => boolean;
46
+ export declare function readCheck(db: CanvasDb, object: ObjectRow): Promise<(reader: Reader) => Promise<boolean>>;
47
47
  /** Always asked of the space, also for a person: a repo never owns a non-public
48
48
  * document, whoever asks. A shipped document is changed by nobody, its own app
49
49
  * included — only the package reconciler writes it, and it asks no reader. */
50
- export declare function canChange(db: DatabaseSync, reader: Reader, object: ObjectRow): boolean;
50
+ export declare function canChange(db: CanvasDb, reader: Reader, object: ObjectRow): Promise<boolean>;
51
51
  /** The own-app memory scope a narrowed run lacks for `access` on a document, or null (see `missingOwnMemoryScope`). */
52
- export declare function missingMemoryScope(db: DatabaseSync, reader: Reader, object: ObjectRow, access: 'read' | 'rw'): string | null;
52
+ export declare function missingMemoryScope(db: CanvasDb, reader: Reader, object: ObjectRow, access: 'read' | 'rw'): Promise<string | null>;
53
53
  /** The same for a document about to be created under `owner`. */
54
- export declare function missingMemoryScopeUnder(db: DatabaseSync, reader: Reader, owner: ObjectRow, access: 'read' | 'rw'): string | null;
54
+ export declare function missingMemoryScopeUnder(db: CanvasDb, reader: Reader, owner: ObjectRow, access: 'read' | 'rw'): Promise<string | null>;
@@ -1,8 +1,8 @@
1
- var R=Object.defineProperty;var s=(n,t)=>R(n,"name",{value:t,configurable:!0});import{prepared as f}from"../sqlite-statements.js";import{covers as O}from"@north-light/identity";import{objectPlace as x,runPlace as N,runsSeeEachOther as g}from"../runs/confinement.js";import{missingOwnMemoryScope as E}from"./spaces/own-memory.js";import{SPACES as L,identityOf as u}from"./spaces/index.js";import{insideRepo as C}from"./spaces/repo.js";function T(n,t){return f(n,`WITH RECURSIVE chain(rowid, depth) AS (
1
+ var R=Object.defineProperty;var s=(n,t)=>R(n,"name",{value:t,configurable:!0});import{covers as S}from"@north-light/identity";import{objectPlace as O,runPlace as x,runsSeeEachOther as N}from"../runs/confinement.js";import{missingOwnMemoryScope as h}from"./spaces/own-memory.js";import{SPACES as g,identityOf as l}from"./spaces/index.js";import{insideRepo as L}from"./spaces/repo.js";async function C(n,t){return await n.prepare(`WITH RECURSIVE chain(rowid, depth) AS (
2
2
  SELECT owner, 1 FROM objects WHERE rowid = ? AND owner IS NOT NULL
3
3
  UNION ALL
4
4
  SELECT o.owner, c.depth + 1 FROM objects o JOIN chain c ON o.rowid = c.rowid WHERE o.owner IS NOT NULL
5
- ) SELECT o.* FROM chain c CROSS JOIN objects o WHERE o.rowid = c.rowid ORDER BY c.depth`).all(t.rowid)}s(T,"ownerChain");function J(n,t){return c(n,t).space}s(J,"spaceOf");function c(n,t){const e=T(n,t),p=e.length?e[e.length-1]:t,o=L[p.type];if(!o)throw new Error(`${t.type} ${t.id} has no space: its owner chain ends at ${p.type} ${p.id}`);const r=e.length?[...e.slice(0,-1).reverse(),t]:[];return{space:p,path:r,impl:o}}s(c,"locate");function m(n,t){return t.type!=="document"?!1:f(n,"SELECT source_path FROM documents WHERE object = ?").get(t.rowid)?.source_path!=null}s(m,"isShipped");function B(n,t){return f(n,`SELECT a.* FROM objects a WHERE a.type = 'app' AND a.deleted_at IS NULL AND EXISTS (
5
+ ) SELECT o.* FROM chain c CROSS JOIN objects o WHERE o.rowid = c.rowid ORDER BY c.depth`).all(t.rowid)}s(C,"ownerChain");async function P(n,t){return(await r(n,t)).space}s(P,"spaceOf");async function r(n,t){const a=await C(n,t),i=a.length?a[a.length-1]:t,e=g[i.type];if(!e)throw new Error(`${t.type} ${t.id} has no space: its owner chain ends at ${i.type} ${i.id}`);const o=a.length?[...a.slice(0,-1).reverse(),t]:[];return{space:i,path:o,impl:e}}s(r,"locate");async function y(n,t){return t.type!=="document"?!1:(await n.prepare("SELECT source_path FROM documents WHERE object = ?").get(t.rowid))?.source_path!=null}s(y,"isShipped");async function k(n,t){return(await n.prepare(`SELECT a.* FROM objects a WHERE a.type = 'app' AND a.deleted_at IS NULL AND EXISTS (
6
6
  SELECT 1 FROM objects o JOIN documents d ON d.object = o.rowid
7
7
  WHERE o.owner = a.rowid AND o.type = 'document' AND o.deleted_at IS NULL AND d.source_path IS NOT NULL)
8
- ORDER BY a.name = 'crtr', a.name`).all().filter(p=>h(n,t,p))}s(B,"toolApps");function h(n,t,e){return e.type==="app"}s(h,"mayUseTools");const A=s(n=>n.class!=="app"||n.place!==void 0,"isRun");function I(n,t,e){const p=`${u(n,e).external_id.replace(/^app:/,"")}:`;return t.some(o=>o.startsWith(p)&&!o.slice(p.length).includes(":"))}s(I,"holdsProviderGroup");function _(n,t,e){return t.class==="person"?!0:t.class==="object"?t.owner.rowid===e.rowid:t.class==="app"?t.app.rowid===e.rowid||e.type==="profile"&&e.owner===t.app.rowid:t.app.rowid===e.rowid||e.type==="profile"&&t.profile?.rowid===e.rowid||e.type==="repo"&&C(n,t,e,"rw")}s(_,"mayActAs");function M(n,t,e){if(t.class!=="node"&&!(t.class==="app"&&t.place!==void 0))return!0;const p=t.class==="app"?t.place:N(t.node.id,n);if(p===null)return!0;const o=x(e.rowid,n);return o===null?!p.isolated:g(p,o)}s(M,"customReachable");const w=s(n=>n.type.includes("."),"isCustom");function Y(n,t,e){return d(n,c(n,t),t,e)}s(Y,"objectsTargets");function d(n,{space:t,path:e},p,o){const r=[];if(t.type==="person")r.push("user");else if(t.type==="app"&&e.length>0){const i=e[0];if(i.type==="profile")e.length>1&&r.push(`profile:${u(n,i).external_id}`);else if(i.type==="node"||w(i)){const l=u(n,t).external_id;l!==o&&r.push(l)}}return p.type==="node"&&r.push("node"),r}s(d,"targetsOf");function a(n,t,e,p,o){if(t.class==="person"||t.scopes===null)return!1;const r=t.scopes;if(r.length===0||p.space.type==="app"&&t.app.rowid===p.space.rowid)return!1;const i=u(n,t.app).external_id;return d(n,p,o,i).some(l=>{const y=`crtr:objects:${e}:${l}`;return r.some(S=>O(S,y))})}s(a,"holdsInLocated");function U(n,t,e,p){return t.class==="person"||t.scopes===null?!1:a(n,t,e,c(n,p),p)}s(U,"holdsObjectsScope");function z(n,t,e,p,o){const r=p.owner===null?null:n.prepare("SELECT * FROM objects WHERE rowid = ?").get(p.owner)??null;if(r===null)return!1;const i={class:"app",app:t,scopes:e??[]};return _(n,i,r)?e===null||U(n,i,"link",o):!1}s(z,"linkAuthorizes");function G(n,t,e){return W(n,e)(t)}s(G,"canRead");function W(n,t){let e=null,p=null;return o=>{if(o.class==="person")return!0;if(e??=c(n,t),e.space.type==="app"&&e.path.length>0){if(p??=m(n,t),p&&h(n,o,e.space))return!0;if(w(t)){if(o.app.rowid===e.space.rowid&&!M(n,o,t))return!1;if(o.app.rowid!==e.space.rowid&&o.scopes!==null&&h(n,o,e.space)&&(t.privacy==="public"||A(o)&&I(n,o.scopes,e.space)))return!0}}return a(n,o,"read",e,t)||o.class==="object"&&w(o.object)&&a(n,o,"watch",e,t)?!0:e.impl.canRead(n,o,e.space,e.path,t)}}s(W,"readCheck");function V(n,t,e){if(m(n,e))return!1;const p=c(n,e);if(a(n,t,"write",p,e))return!0;const{space:o,path:r,impl:i}=p;return i.canChange(n,t,o,r,e)}s(V,"canChange");function X(n,t,e,p){if(t.class==="person")return null;const{space:o,path:r}=c(n,e);return o.type==="app"&&t.app.rowid===o.rowid?E(n,t,o,r,e,p):null}s(X,"missingMemoryScope");function q(n,t,e,p){if(t.class==="person")return null;const o=c(n,e),{space:r}=o;return r.type!=="app"||t.app.rowid!==r.rowid?null:E(n,t,r,o.path.length===0?[e]:[...o.path],null,p)}s(q,"missingMemoryScopeUnder");export{V as canChange,G as canRead,M as customReachable,U as holdsObjectsScope,I as holdsProviderGroup,m as isShipped,z as linkAuthorizes,_ as mayActAs,h as mayUseTools,X as missingMemoryScope,q as missingMemoryScopeUnder,Y as objectsTargets,T as ownerChain,W as readCheck,J as spaceOf,B as toolApps};
8
+ ORDER BY a.name = 'crtr', a.name`).all()).filter(i=>f(n,t,i))}s(k,"toolApps");function f(n,t,a){return a.type==="app"}s(f,"mayUseTools");const T=s(n=>n.class!=="app"||n.place!==void 0,"isRun");async function A(n,t,a){const i=`${(await l(n,a)).external_id.replace(/^app:/,"")}:`;return t.some(e=>e.startsWith(i)&&!e.slice(i.length).includes(":"))}s(A,"holdsProviderGroup");async function I(n,t,a){return t.class==="person"?!0:t.class==="object"?t.owner.rowid===a.rowid:t.class==="app"?t.app.rowid===a.rowid||a.type==="profile"&&a.owner===t.app.rowid:t.app.rowid===a.rowid||a.type==="profile"&&t.profile?.rowid===a.rowid||a.type==="repo"&&await L(n,t,a,"rw")}s(I,"mayActAs");async function _(n,t,a){if(t.class!=="node"&&!(t.class==="app"&&t.place!==void 0))return!0;const i=t.class==="app"?t.place:await x(t.node.id,n);if(i===null)return!0;const e=await O(a.rowid,n);return e===null?!i.isolated:N(i,e)}s(_,"customReachable");const w=s(n=>n.type.includes("."),"isCustom");async function J(n,t,a){return await E(n,await r(n,t),t,a)}s(J,"objectsTargets");async function E(n,{space:t,path:a},i,e){const o=[];if(t.type==="person")o.push("user");else if(t.type==="app"&&a.length>0){const p=a[0];if(p.type==="profile")a.length>1&&o.push(`profile:${(await l(n,p)).external_id}`);else if(p.type==="node"||w(p)){const c=(await l(n,t)).external_id;c!==e&&o.push(c)}}return i.type==="node"&&o.push("node"),o}s(E,"targetsOf");async function u(n,t,a,i,e){if(t.class==="person"||t.scopes===null)return!1;const o=t.scopes;if(o.length===0||i.space.type==="app"&&t.app.rowid===i.space.rowid)return!1;const p=(await l(n,t.app)).external_id;return(await E(n,i,e,p)).some(c=>{const m=`crtr:objects:${a}:${c}`;return o.some(d=>S(d,m))})}s(u,"holdsInLocated");async function M(n,t,a,i){return t.class==="person"||t.scopes===null?!1:await u(n,t,a,await r(n,i),i)}s(M,"holdsObjectsScope");async function B(n,t,a,i,e){const o=i.owner===null?null:await n.prepareUncached("SELECT * FROM objects WHERE rowid = ?").get(i.owner)??null;if(o===null)return!1;const p={class:"app",app:t,scopes:a??[]};return await I(n,p,o)?a===null||await M(n,p,"link",e):!1}s(B,"linkAuthorizes");async function Y(n,t,a){return(await U(n,a))(t)}s(Y,"canRead");async function U(n,t){let a=null,i=null;return async e=>{if(e.class==="person")return!0;if(a??=await r(n,t),a.space.type==="app"&&a.path.length>0){if(i??=await y(n,t),i&&f(n,e,a.space))return!0;if(w(t)){if(e.app.rowid===a.space.rowid&&!await _(n,e,t))return!1;if(e.app.rowid!==a.space.rowid&&e.scopes!==null&&f(n,e,a.space)&&(t.privacy==="public"||T(e)&&await A(n,e.scopes,a.space)))return!0}}return await u(n,e,"read",a,t)||e.class==="object"&&w(e.object)&&await u(n,e,"watch",a,t)?!0:await a.impl.canRead(n,e,a.space,a.path,t)}}s(U,"readCheck");async function z(n,t,a){if(await y(n,a))return!1;const i=await r(n,a);if(await u(n,t,"write",i,a))return!0;const{space:e,path:o,impl:p}=i;return await p.canChange(n,t,e,o,a)}s(z,"canChange");async function G(n,t,a,i){if(t.class==="person")return null;const{space:e,path:o}=await r(n,a);return e.type==="app"&&t.app.rowid===e.rowid?await h(n,t,e,o,a,i):null}s(G,"missingMemoryScope");async function V(n,t,a,i){if(t.class==="person")return null;const e=await r(n,a),{space:o}=e;return o.type!=="app"||t.app.rowid!==o.rowid?null:await h(n,t,o,e.path.length===0?[a]:[...e.path],null,i)}s(V,"missingMemoryScopeUnder");export{z as canChange,Y as canRead,_ as customReachable,M as holdsObjectsScope,A as holdsProviderGroup,y as isShipped,B as linkAuthorizes,I as mayActAs,f as mayUseTools,G as missingMemoryScope,V as missingMemoryScopeUnder,J as objectsTargets,C as ownerChain,U as readCheck,P as spaceOf,k as toolApps};
@@ -1,7 +1,7 @@
1
- import type { DatabaseSync } from 'node:sqlite';
2
1
  import type { Level, ObjectRow, Privacy, Reader } from './types.js';
3
2
  import { customReachable, mayActAs } from './access.js';
4
3
  import { onQueueSignal } from './receivers.js';
4
+ import type { CanvasDb } from '../canvas/db.js';
5
5
  export { customReachable, mayActAs, onQueueSignal };
6
6
  export type CustomReceiver = 'queue' | {
7
7
  url: string;
@@ -35,7 +35,7 @@ export interface QueueLine {
35
35
  created_at: string;
36
36
  }
37
37
  /** Register a kind and a named instance in the caller's write transaction. */
38
- export declare function registerCustomObject(db: DatabaseSync, reader: Reader, input: {
38
+ export declare function registerCustomObject(db: CanvasDb, reader: Reader, input: {
39
39
  kind: string;
40
40
  name: string;
41
41
  owner: ObjectRow;
@@ -45,12 +45,12 @@ export declare function registerCustomObject(db: DatabaseSync, reader: Reader, i
45
45
  receiver?: CustomReceiver | null;
46
46
  rotateToken?: boolean;
47
47
  privacy?: Privacy;
48
- }): {
48
+ }): Promise<{
49
49
  object: ObjectRow;
50
50
  token?: string;
51
51
  created: boolean;
52
52
  changed: string[];
53
- };
53
+ }>;
54
54
  export type KindSource = 'register' | 'manifest' | 'peer';
55
55
  export type KindChange = 'events' | 'description' | 'read';
56
56
  /**
@@ -61,7 +61,7 @@ export type KindChange = 'events' | 'description' | 'read';
61
61
  * `manifest` or `register` row is `kind_owned`. `read_json` is written only by `manifest`. A catalog is replaced,
62
62
  * never merged. Runs in the caller's write transaction.
63
63
  */
64
- export declare function upsertKind(db: DatabaseSync, input: {
64
+ export declare function upsertKind(db: CanvasDb, input: {
65
65
  name: string;
66
66
  owner: ObjectRow;
67
67
  description: string;
@@ -70,26 +70,26 @@ export declare function upsertKind(db: DatabaseSync, input: {
70
70
  command: string[];
71
71
  } | null;
72
72
  source: KindSource;
73
- }): {
73
+ }): Promise<{
74
74
  outcome: 'inserted' | 'updated' | 'unchanged' | 'skipped';
75
75
  changed: KindChange[];
76
- };
77
- export declare function publishCustom(db: DatabaseSync, object: ObjectRow, actor: ObjectRow | null, input: {
76
+ }>;
77
+ export declare function publishCustom(db: CanvasDb, object: ObjectRow, actor: ObjectRow | null, input: {
78
78
  event: string;
79
79
  summary: string;
80
80
  state?: unknown;
81
81
  cause?: string;
82
- }): {
82
+ }): Promise<{
83
83
  message_id: string | null;
84
84
  delivered: number;
85
85
  depth: number;
86
- };
87
- export declare function unregisterCustomObject(db: DatabaseSync, object: ObjectRow, actor: ObjectRow | null): void;
88
- export declare function pendingFor(db: DatabaseSync, object: ObjectRow, afterSeq?: number): QueueLine[];
86
+ }>;
87
+ export declare function unregisterCustomObject(db: CanvasDb, object: ObjectRow, actor: ObjectRow | null): Promise<void>;
88
+ export declare function pendingFor(db: CanvasDb, object: ObjectRow, afterSeq?: number): Promise<QueueLine[]>;
89
89
  /** A claimed push delivery has the identical document as a pending queue delivery. */
90
- export declare function pushLineFor(db: DatabaseSync, deliveryId: string): QueueLine | null;
91
- export declare function acknowledge(db: DatabaseSync, object: ObjectRow, deliveryIds: string[]): {
90
+ export declare function pushLineFor(db: CanvasDb, deliveryId: string): Promise<QueueLine | null>;
91
+ export declare function acknowledge(db: CanvasDb, object: ObjectRow, deliveryIds: string[]): Promise<{
92
92
  acknowledged: number;
93
93
  unknown?: string[];
94
- };
95
- export declare function verifyPublishToken(db: DatabaseSync, object: ObjectRow, token: string): boolean;
94
+ }>;
95
+ export declare function verifyPublishToken(db: CanvasDb, object: ObjectRow, token: string): Promise<boolean>;
@@ -1,12 +1,12 @@
1
- var x=Object.defineProperty;var m=(e,t)=>x(e,"name",{value:t,configurable:!0});import{prepared as a}from"../sqlite-statements.js";import{createHash as J,randomBytes as P,timingSafeEqual as q}from"node:crypto";import{CrtrError as j,usage as p}from"../errors.js";import{ExitCode as O}from"../../types.js";import{createObject as F,liveDocumentNamed as M}from"./objects.js";import{invalidateCustomKind as D}from"./kinds/registry.js";import{customReachable as k,mayActAs as L}from"./access.js";import{publish as N,HOP_LIMIT as B,HopLimitError as K}from"./events.js";import{checkoutsForCwd as T}from"./repo-sync/repos.js";import{onQueueSignal as V,signalQueue as R}from"./receivers.js";import{receiverEndpoint as G,isPublicReceiverAddress as Q}from"./receiver-url.js";import{isIP as Y}from"node:net";import{KIND as H,LOCAL as I,MAX_KIND_EVENTS as z,RESERVED_KIND_ROOTS as X,eventCatalogReasons as Z}from"../plugin-objects-manifest.js";const ee=["public","friends","private"];function w(e,t){throw new j(e,t,O.GENERAL)}m(w,"conflict");function A(e){return J("sha256").update(e).digest("hex")}m(A,"hash");function W(){return`crtr_pub_${P(32).toString("base64url")}`}m(W,"issueToken");function te(e){if(e==null)return null;if(e==="queue")return JSON.stringify(e);if(typeof e!="object"||Array.isArray(e))throw p("invalid custom receiver; expected queue, an https url, or argv and absolute cwd");if("url"in e&&typeof e.url=="string")try{const s=G(e.url).hostname.replace(/^\[|\]$/g,"");if(Y(s)&&!Q(s))throw new Error("non-public IP address");return JSON.stringify({url:e.url})}catch(t){throw p(`invalid custom receiver: ${String(t)}`)}if("argv"in e&&Array.isArray(e.argv)&&e.argv.length>0&&e.argv.every(t=>typeof t=="string")&&typeof e.cwd=="string"&&e.cwd.startsWith("/"))return JSON.stringify(e);throw p("invalid custom receiver; url must be https and argv requires a command and absolute cwd")}m(te,"receiverJson");function ge(e,t,s){const{kind:n,name:i,owner:o,description:d,events:l,receiver:c,rotateToken:h,privacy:f}=s;if(f!==void 0&&!ee.includes(f))throw p(`invalid privacy ${JSON.stringify(f)}`);if(L(e,t,o)||w("forbidden",`cannot act as ${o.id}`),!H.test(n)||X.includes(n.split(".")[0]))throw p(`invalid or reserved kind ${n}`);if(!i.trim()||i!==i.trim()||i.includes("\0"))throw p(`invalid object name ${JSON.stringify(i)}`);const E=te(c);if(c!=="queue"&&c!==null&&c!==void 0&&"argv"in c&&t.class!=="person"&&t.class!=="node"&&w("argv_forbidden","argv receiver requires a person or node principal"),l===void 0){const u=a(e,"SELECT source FROM object_kinds WHERE name = ?").get(n);if(u?.source!=="manifest"&&u?.source!=="peer")throw p("events is required unless the kind is declared by an installed plugin")}else if(Object.keys(l).length>z||Object.entries(l).some(([u,g])=>!I.test(u)||!Number.isInteger(g?.level)||g.level<1||g.level>10||g.supersedes!==void 0&&typeof g.supersedes!="boolean"||g.ends_wait!==void 0&&typeof g.ends_wait!="boolean"))throw p("invalid custom event catalog");const r=M(e,o.rowid,i);if(r&&!k(e,t,r)&&w("forbidden",`cannot act as ${o.id}`),r&&t.class!=="person"&&t.class!=="node"){const u=a(e,"SELECT receiver_json FROM custom_objects WHERE object = ?").get(r.rowid)?.receiver_json;u&&typeof JSON.parse(u)=="object"&&"argv"in JSON.parse(u)&&w("argv_forbidden","argv receiver requires a person or node principal")}r&&r.type!==n&&w("name_taken",`${o.name}/${i} is already held by ${r.id}`);const v=l===void 0?null:ne(e,{name:n,owner:o,description:d,events:l,read:null,source:"register"});if(!r){const u=F(e,{type:n,kind:null,owner:o.rowid,privacy:f??"public",name:i,preview:""}),g=W();return a(e,`INSERT INTO custom_objects (object, description, receiver_json, token_hash)
2
- VALUES (?, ?, ?, ?)`).run(u.rowid,d,E,A(g)),t.class==="node"&&a(e,"UPDATE custom_objects SET registered_by = ? WHERE object = ?").run(t.node.id,u.rowid),E!==null&&a(e,"UPDATE objects SET reception = 2 WHERE rowid = ?").run(u.rowid),N(e,{event:"created",object:u,actor:t.class==="object"?t.object:t.class==="person"?t.person:t.class==="app"?t.app:t.node,attrs:{}},$=>T(e,$)),{object:u,token:g,created:!0,changed:[]}}const y=a(e,"SELECT description, receiver_json FROM custom_objects WHERE object = ?").get(r.rowid);y||w("name_taken",`${o.name}/${i} is not a custom object`);const _=[];if(y.description!==d&&_.push("description"),y.receiver_json!==E&&_.push("receiver"),v?.changed.includes("events")&&_.push("events"),v?.changed.includes("description")&&!_.includes("description")&&_.push("description"),f!==void 0&&r.privacy!==f&&_.push("privacy"),h&&_.push("token"),_.length===0)return{object:r,created:!1,changed:_};const S=h?W():void 0,b=_.includes("privacy")?{...r,privacy:f}:r;if(b!==r&&a(e,"UPDATE objects SET privacy = ? WHERE rowid = ?").run(f,r.rowid),a(e,"UPDATE custom_objects SET description = ?, receiver_json = ?, token_hash = COALESCE(?, token_hash) WHERE object = ?").run(d,E,S===void 0?null:A(S),r.rowid),a(e,"UPDATE objects SET reception = ? WHERE rowid = ?").run(E===null?0:2,r.rowid),y.receiver_json!==E){const u=Date.now();if(E===null){const g=a(e,`UPDATE deliveries SET canceled_at = ?, updated_at = ?
3
- WHERE destination_id = ? AND state = 'pending' AND canceled_at IS NULL`).run(u,u,r.id);a(e,"UPDATE custom_objects SET dropped = dropped + ? WHERE object = ?").run(g.changes,r.rowid)}else a(e,`UPDATE deliveries SET next_attempt_at = ?, updated_at = ?
4
- WHERE destination_id = ? AND state = 'pending' AND canceled_at IS NULL`).run(E==='"queue"'?null:u,u,r.id);R(r.id)}return h&&R(r.id),N(e,{event:"configured",object:b,actor:t.class==="object"?t.object:t.class==="person"?t.person:t.class==="app"?t.app:t.node,attrs:{changed:_.join(",")}},u=>T(e,u)),{object:b,...S===void 0?{}:{token:S},created:!1,changed:_}}m(ge,"registerCustomObject");function ne(e,t){const{name:s,owner:n,description:i,events:o,read:d,source:l}=t;if(!H.test(s))throw p(`invalid kind ${s}`);if(Z(o,s).length>0)throw p("invalid custom event catalog");const c=a(e,"SELECT owner, description, events_json, read_json, source, declared FROM object_kinds WHERE name = ?").get(s),h=U(o),f=l==="manifest"&&d!==null?JSON.stringify({command:d.command}):null,E=new Date().toISOString();if(!c)return a(e,`INSERT INTO object_kinds (name, owner, description, events_json, created_at, updated_at, read_json, source, declared)
5
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, 1)`).run(s,n.rowid,i,h,E,E,f,l),D(e,s),{outcome:"inserted",changed:[]};const r=c.owner===n.rowid;if(l==="peer"){if(c.source!=="peer")return{outcome:"skipped",changed:[]}}else if(c.source!=="peer"&&(r||w("kind_owned",`${s} belongs to another owner`),l==="register"&&c.source==="manifest"))return{outcome:"skipped",changed:[]};const v=[];return U(JSON.parse(c.events_json))!==h&&v.push("events"),c.description!==i&&v.push("description"),(c.read_json??null)!==f&&v.push("read"),v.length===0&&r&&c.source===l&&c.declared===1?{outcome:"unchanged",changed:v}:(a(e,"UPDATE object_kinds SET owner = ?, description = ?, events_json = ?, read_json = ?, source = ?, declared = 1, updated_at = ? WHERE name = ?").run(n.rowid,i,h,f,l,E,s),D(e,s),{outcome:"updated",changed:v})}m(ne,"upsertKind");function he(e,t,s,n){const i=a(e,"SELECT events_json FROM object_kinds WHERE name = ?").get(t.type);if(!i||t.deleted_at!==null)throw p(`${t.id} is not a live custom object`);const o=JSON.parse(i.events_json);if(!I.test(n.event)||!Object.hasOwn(o,n.event))throw new j("unknown_event",`${t.type} declares ${Object.keys(o).join(", ")}, not ${n.event}`,O.USAGE,{declared:Object.keys(o),event:n.event});if(typeof n.summary!="string")throw p("summary must be text");const d=n.state===void 0?null:JSON.stringify(n.state);if(n.state!==void 0&&d===void 0)throw p("state must be JSON-serializable");if(Buffer.byteLength(JSON.stringify({summary:n.summary,...n.state===void 0?{}:{state:n.state}}))>64*1024)throw new j("body_too_large","custom event summary and state exceed 64 KiB",O.USAGE);if(d!==null&&Buffer.byteLength(d)>64*1024)throw p("state exceeds 64 KiB");const l=n.cause??null,c=l===null?null:a(e,`SELECT depth FROM messages WHERE message_id = ?
6
- UNION ALL SELECT depth FROM message_causes WHERE message_id = ? LIMIT 1`).get(l,l);if(l!==null&&c===void 0)throw new j("unknown_cause",`no message ${l}`,O.USAGE);if(c&&c.depth>=B)throw new K(c.depth+1);const h=new Date().toISOString();return a(e,"UPDATE custom_objects SET summary = ?, state_json = ?, published_at = ? WHERE object = ?").run(n.summary,d,h,t.rowid),a(e,"UPDATE objects SET preview = ? WHERE rowid = ?").run(n.summary.split(`
7
- `)[0],t.rowid),N(e,{event:`${t.type}.${n.event}`,object:t,actor:s,attrs:{},messageBody:{summary:n.summary,...n.state===void 0?{}:{state:n.state}},...n.cause===void 0?{}:{cause:n.cause}},f=>T(e,f))}m(he,"publishCustom");function ve(e,t,s){if(t.deleted_at!==null)return;N(e,{event:"deleted",object:t,actor:s,attrs:{}},i=>T(e,i));const n=new Date().toISOString();a(e,"UPDATE objects SET deleted_at = ?, reception = 0 WHERE rowid = ?").run(n,t.rowid),a(e,"UPDATE deliveries SET canceled_at = ?, updated_at = ? WHERE destination_id = ? AND state = 'pending' AND canceled_at IS NULL").run(Date.now(),Date.now(),t.id),R(t.id)}m(ve,"unregisterCustomObject");function U(e){return JSON.stringify(Object.fromEntries(Object.entries(e).sort(([t],[s])=>t.localeCompare(s)).map(([t,s])=>[t,{level:s.level,...s.supersedes===void 0?{}:{supersedes:s.supersedes},...s.ends_wait===void 0?{}:{ends_wait:s.ends_wait}}])))}m(U,"canonicalEvents");function we(e,t,s=0){return C(e,t.id,s,"pending")}m(we,"pendingFor");function ye(e,t){const s=a(e,"SELECT destination_id FROM deliveries WHERE delivery_id = ?").get(t);return s?C(e,s.destination_id,-1,"handed_off").find(n=>n.delivery_id===t)??null:null}m(ye,"pushLineFor");function C(e,t,s,n){return a(e,`SELECT d.delivery_id, m.message_id, m.seq, m.event, m.level, m.object_id, m.actor_id, m.body_json, m.body_ref, m.depth, m.created_at,
1
+ var $=Object.defineProperty;var l=(e,t)=>$(e,"name",{value:t,configurable:!0});import{createHash as x,randomBytes as J,timingSafeEqual as P}from"node:crypto";import{CrtrError as j,usage as f}from"../errors.js";import{ExitCode as S}from"../../types.js";import{createObject as q,liveDocumentNamed as F}from"./objects.js";import{invalidateCustomKind as A}from"./kinds/registry.js";import{customReachable as D,mayActAs as k}from"./access.js";import{publish as O,HOP_LIMIT as M,HopLimitError as B}from"./events.js";import{checkoutsForCwd as N}from"./repo-sync/repos.js";import{onQueueSignal as K,signalQueue as b}from"./receivers.js";import{receiverEndpoint as V,isPublicReceiverAddress as G}from"./receiver-url.js";import{isIP as Q}from"node:net";import{KIND as L,LOCAL as H,MAX_KIND_EVENTS as Y,RESERVED_KIND_ROOTS as z,eventCatalogReasons as X}from"../plugin-objects-manifest.js";const Z=["public","friends","private"];function h(e,t){throw new j(e,t,S.GENERAL)}l(h,"conflict");function R(e){return x("sha256").update(e).digest("hex")}l(R,"hash");function I(){return`crtr_pub_${J(32).toString("base64url")}`}l(I,"issueToken");function ee(e){if(e==null)return null;if(e==="queue")return JSON.stringify(e);if(typeof e!="object"||Array.isArray(e))throw f("invalid custom receiver; expected queue, an https url, or argv and absolute cwd");if("url"in e&&typeof e.url=="string")try{const i=V(e.url).hostname.replace(/^\[|\]$/g,"");if(Q(i)&&!G(i))throw new Error("non-public IP address");return JSON.stringify({url:e.url})}catch(t){throw f(`invalid custom receiver: ${String(t)}`)}if("argv"in e&&Array.isArray(e.argv)&&e.argv.length>0&&e.argv.every(t=>typeof t=="string")&&typeof e.cwd=="string"&&e.cwd.startsWith("/"))return JSON.stringify(e);throw f("invalid custom receiver; url must be https and argv requires a command and absolute cwd")}l(ee,"receiverJson");async function we(e,t,i){const{kind:n,name:r,owner:s,description:o,events:u,receiver:d,rotateToken:_,privacy:p}=i;if(p!==void 0&&!Z.includes(p))throw f(`invalid privacy ${JSON.stringify(p)}`);if(await k(e,t,s)||h("forbidden",`cannot act as ${s.id}`),!L.test(n)||z.includes(n.split(".")[0]))throw f(`invalid or reserved kind ${n}`);if(!r.trim()||r!==r.trim()||r.includes("\0"))throw f(`invalid object name ${JSON.stringify(r)}`);const m=ee(d);if(d!=="queue"&&d!==null&&d!==void 0&&"argv"in d&&t.class!=="person"&&t.class!=="node"&&h("argv_forbidden","argv receiver requires a person or node principal"),u===void 0){const c=await e.prepare("SELECT source FROM object_kinds WHERE name = ?").get(n);if(c?.source!=="manifest"&&c?.source!=="peer")throw f("events is required unless the kind is declared by an installed plugin")}else if(Object.keys(u).length>Y||Object.entries(u).some(([c,E])=>!H.test(c)||!Number.isInteger(E?.level)||E.level<1||E.level>10||E.supersedes!==void 0&&typeof E.supersedes!="boolean"||E.ends_wait!==void 0&&typeof E.ends_wait!="boolean"))throw f("invalid custom event catalog");const a=await F(e,s.rowid,r);if(a&&!await D(e,t,a)&&h("forbidden",`cannot act as ${s.id}`),a&&t.class!=="person"&&t.class!=="node"){const c=(await e.prepare("SELECT receiver_json FROM custom_objects WHERE object = ?").get(a.rowid))?.receiver_json;c&&typeof JSON.parse(c)=="object"&&"argv"in JSON.parse(c)&&h("argv_forbidden","argv receiver requires a person or node principal")}a&&a.type!==n&&h("name_taken",`${s.name}/${r} is already held by ${a.id}`);const g=u===void 0?null:await te(e,{name:n,owner:s,description:o,events:u,read:null,source:"register"});if(!a){const c=await q(e,{type:n,kind:null,owner:s.rowid,privacy:p??"public",name:r,preview:""}),E=I();return await e.prepare(`INSERT INTO custom_objects (object, description, receiver_json, token_hash)
2
+ VALUES (?, ?, ?, ?)`).run(c.rowid,o,m,R(E)),t.class==="node"&&await e.prepare("UPDATE custom_objects SET registered_by = ? WHERE object = ?").run(t.node.id,c.rowid),m!==null&&await e.prepare("UPDATE objects SET reception = 2 WHERE rowid = ?").run(c.rowid),await O(e,{event:"created",object:c,actor:t.class==="object"?t.object:t.class==="person"?t.person:t.class==="app"?t.app:t.node,attrs:{}},async C=>await N(e,C)),{object:c,token:E,created:!0,changed:[]}}const v=await e.prepare("SELECT description, receiver_json FROM custom_objects WHERE object = ?").get(a.rowid);v||h("name_taken",`${s.name}/${r} is not a custom object`);const w=[];if(v.description!==o&&w.push("description"),v.receiver_json!==m&&w.push("receiver"),g?.changed.includes("events")&&w.push("events"),g?.changed.includes("description")&&!w.includes("description")&&w.push("description"),p!==void 0&&a.privacy!==p&&w.push("privacy"),_&&w.push("token"),w.length===0)return{object:a,created:!1,changed:w};const y=_?I():void 0,T=w.includes("privacy")?{...a,privacy:p}:a;if(T!==a&&await e.prepare("UPDATE objects SET privacy = ? WHERE rowid = ?").run(p,a.rowid),await e.prepare("UPDATE custom_objects SET description = ?, receiver_json = ?, token_hash = COALESCE(?, token_hash) WHERE object = ?").run(o,m,y===void 0?null:R(y),a.rowid),await e.prepare("UPDATE objects SET reception = ? WHERE rowid = ?").run(m===null?0:2,a.rowid),v.receiver_json!==m){const c=Date.now();if(m===null){const E=await e.prepare(`UPDATE deliveries SET canceled_at = ?, updated_at = ?
3
+ WHERE destination_id = ? AND state = 'pending' AND canceled_at IS NULL`).run(c,c,a.id);await e.prepare("UPDATE custom_objects SET dropped = dropped + ? WHERE object = ?").run(E.changes,a.rowid)}else await e.prepare(`UPDATE deliveries SET next_attempt_at = ?, updated_at = ?
4
+ WHERE destination_id = ? AND state = 'pending' AND canceled_at IS NULL`).run(m==='"queue"'?null:c,c,a.id);b(a.id)}return _&&b(a.id),await O(e,{event:"configured",object:T,actor:t.class==="object"?t.object:t.class==="person"?t.person:t.class==="app"?t.app:t.node,attrs:{changed:w.join(",")}},async c=>await N(e,c)),{object:T,...y===void 0?{}:{token:y},created:!1,changed:w}}l(we,"registerCustomObject");async function te(e,t){const{name:i,owner:n,description:r,events:s,read:o,source:u}=t;if(!L.test(i))throw f(`invalid kind ${i}`);if(X(s,i).length>0)throw f("invalid custom event catalog");const d=await e.prepare("SELECT owner, description, events_json, read_json, source, declared FROM object_kinds WHERE name = ?").get(i),_=W(s),p=u==="manifest"&&o!==null?JSON.stringify({command:o.command}):null,m=new Date().toISOString();if(!d)return await e.prepare(`INSERT INTO object_kinds (name, owner, description, events_json, created_at, updated_at, read_json, source, declared)
5
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, 1)`).run(i,n.rowid,r,_,m,m,p,u),A(e,i),{outcome:"inserted",changed:[]};const a=d.owner===n.rowid;if(u==="peer"){if(d.source!=="peer")return{outcome:"skipped",changed:[]}}else if(d.source!=="peer"&&(a||h("kind_owned",`${i} belongs to another owner`),u==="register"&&d.source==="manifest"))return{outcome:"skipped",changed:[]};const g=[];return W(JSON.parse(d.events_json))!==_&&g.push("events"),d.description!==r&&g.push("description"),(d.read_json??null)!==p&&g.push("read"),g.length===0&&a&&d.source===u&&d.declared===1?{outcome:"unchanged",changed:g}:(await e.prepare("UPDATE object_kinds SET owner = ?, description = ?, events_json = ?, read_json = ?, source = ?, declared = 1, updated_at = ? WHERE name = ?").run(n.rowid,r,_,p,u,m,i),A(e,i),{outcome:"updated",changed:g})}l(te,"upsertKind");async function Ee(e,t,i,n){const r=await e.prepare("SELECT events_json FROM object_kinds WHERE name = ?").get(t.type);if(!r||t.deleted_at!==null)throw f(`${t.id} is not a live custom object`);const s=JSON.parse(r.events_json);if(!H.test(n.event)||!Object.hasOwn(s,n.event))throw new j("unknown_event",`${t.type} declares ${Object.keys(s).join(", ")}, not ${n.event}`,S.USAGE,{declared:Object.keys(s),event:n.event});if(typeof n.summary!="string")throw f("summary must be text");const o=n.state===void 0?null:JSON.stringify(n.state);if(n.state!==void 0&&o===void 0)throw f("state must be JSON-serializable");if(Buffer.byteLength(JSON.stringify({summary:n.summary,...n.state===void 0?{}:{state:n.state}}))>64*1024)throw new j("body_too_large","custom event summary and state exceed 64 KiB",S.USAGE);if(o!==null&&Buffer.byteLength(o)>64*1024)throw f("state exceeds 64 KiB");const u=n.cause??null,d=u===null?null:await e.prepare(`SELECT depth FROM messages WHERE message_id = ?
6
+ UNION ALL SELECT depth FROM message_causes WHERE message_id = ? LIMIT 1`).get(u,u);if(u!==null&&d===void 0)throw new j("unknown_cause",`no message ${u}`,S.USAGE);if(d&&d.depth>=M)throw new B(d.depth+1);const _=new Date().toISOString();return await e.prepare("UPDATE custom_objects SET summary = ?, state_json = ?, published_at = ? WHERE object = ?").run(n.summary,o,_,t.rowid),await e.prepare("UPDATE objects SET preview = ? WHERE rowid = ?").run(n.summary.split(`
7
+ `)[0],t.rowid),await O(e,{event:`${t.type}.${n.event}`,object:t,actor:i,attrs:{},messageBody:{summary:n.summary,...n.state===void 0?{}:{state:n.state}},...n.cause===void 0?{}:{cause:n.cause}},async p=>await N(e,p))}l(Ee,"publishCustom");async function _e(e,t,i){if(t.deleted_at!==null)return;await O(e,{event:"deleted",object:t,actor:i,attrs:{}},async r=>await N(e,r));const n=new Date().toISOString();await e.prepare("UPDATE objects SET deleted_at = ?, reception = 0 WHERE rowid = ?").run(n,t.rowid),await e.prepare("UPDATE deliveries SET canceled_at = ?, updated_at = ? WHERE destination_id = ? AND state = 'pending' AND canceled_at IS NULL").run(Date.now(),Date.now(),t.id),b(t.id)}l(_e,"unregisterCustomObject");function W(e){return JSON.stringify(Object.fromEntries(Object.entries(e).sort(([t],[i])=>t.localeCompare(i)).map(([t,i])=>[t,{level:i.level,...i.supersedes===void 0?{}:{supersedes:i.supersedes},...i.ends_wait===void 0?{}:{ends_wait:i.ends_wait}}])))}l(W,"canonicalEvents");async function ge(e,t,i=0){return await U(e,t.id,i,"pending")}l(ge,"pendingFor");async function he(e,t){const i=await e.prepare("SELECT destination_id FROM deliveries WHERE delivery_id = ?").get(t);return i?(await U(e,i.destination_id,-1,"handed_off")).find(n=>n.delivery_id===t)??null:null}l(he,"pushLineFor");async function U(e,t,i,n){return(await e.prepare(`SELECT d.delivery_id, m.message_id, m.seq, m.event, m.level, m.object_id, m.actor_id, m.body_json, m.body_ref, m.depth, m.created_at,
8
8
  o.type, o.name, owner.id AS owner_id
9
9
  FROM deliveries d JOIN messages m ON m.message_id = d.message_id JOIN objects o ON o.id = m.object_id
10
10
  LEFT JOIN objects owner ON owner.rowid = o.owner
11
- WHERE d.destination_id = ? AND d.state = ? AND d.canceled_at IS NULL AND m.seq > ? ORDER BY m.seq`).all(t,n,s).map(o=>{const d=o.body_json?JSON.parse(o.body_json):{};return{delivery_id:o.delivery_id,message_id:o.message_id,seq:o.seq,event:o.event,level:o.level,object:{id:o.object_id,type:o.type,name:o.name,owner:o.owner_id},actor:o.actor_id,attrs:d.push?.attrs??{},...d.summary===void 0?{}:{summary:d.summary},...d.state===void 0?{}:{state:d.state},...d.push?.pointer===void 0?{}:{pointer:d.push.pointer},depth:o.depth,created_at:o.created_at}})}m(C,"queueLines");function Se(e,t,s){const n=Date.now(),i=[];let o=0;for(const d of s){const l=a(e,`UPDATE deliveries SET state = 'acknowledged', acknowledged_at = ?, updated_at = ?
12
- WHERE delivery_id = ? AND destination_id = ? AND state = 'pending' AND canceled_at IS NULL`).run(n,n,d,t.id);Number(l.changes)?o++:i.push(d)}return{acknowledged:o,...i.length?{unknown:i}:{}}}m(Se,"acknowledge");function je(e,t,s){const n=a(e,"SELECT token_hash FROM custom_objects WHERE object = ?").get(t.rowid),i=Buffer.from(n?.token_hash??"".padEnd(64,"0"),"hex"),o=Buffer.from(A(s),"hex");return s.startsWith("crtr_pub_")&&t.deleted_at===null&&i.length===o.length&&q(i,o)&&n?.token_hash!=null}m(je,"verifyPublishToken");export{Se as acknowledge,k as customReachable,L as mayActAs,V as onQueueSignal,we as pendingFor,he as publishCustom,ye as pushLineFor,ge as registerCustomObject,ve as unregisterCustomObject,ne as upsertKind,je as verifyPublishToken};
11
+ WHERE d.destination_id = ? AND d.state = ? AND d.canceled_at IS NULL AND m.seq > ? ORDER BY m.seq`).all(t,n,i)).map(s=>{const o=s.body_json?JSON.parse(s.body_json):{};return{delivery_id:s.delivery_id,message_id:s.message_id,seq:s.seq,event:s.event,level:s.level,object:{id:s.object_id,type:s.type,name:s.name,owner:s.owner_id},actor:s.actor_id,attrs:o.push?.attrs??{},...o.summary===void 0?{}:{summary:o.summary},...o.state===void 0?{}:{state:o.state},...o.push?.pointer===void 0?{}:{pointer:o.push.pointer},depth:s.depth,created_at:s.created_at}})}l(U,"queueLines");async function ve(e,t,i){const n=Date.now(),r=[];let s=0;for(const o of i){const u=await e.prepare(`UPDATE deliveries SET state = 'acknowledged', acknowledged_at = ?, updated_at = ?
12
+ WHERE delivery_id = ? AND destination_id = ? AND state = 'pending' AND canceled_at IS NULL`).run(n,n,o,t.id);Number(u.changes)?s++:r.push(o)}return{acknowledged:s,...r.length?{unknown:r}:{}}}l(ve,"acknowledge");async function ye(e,t,i){const n=await e.prepare("SELECT token_hash FROM custom_objects WHERE object = ?").get(t.rowid),r=Buffer.from(n?.token_hash??"".padEnd(64,"0"),"hex"),s=Buffer.from(R(i),"hex");return i.startsWith("crtr_pub_")&&t.deleted_at===null&&r.length===s.length&&P(r,s)&&n?.token_hash!=null}l(ye,"verifyPublishToken");export{ve as acknowledge,D as customReachable,k as mayActAs,K as onQueueSignal,ge as pendingFor,Ee as publishCustom,he as pushLineFor,we as registerCustomObject,_e as unregisterCustomObject,te as upsertKind,ye as verifyPublishToken};
@@ -1,17 +1,13 @@
1
- /** Deleting a node with what it owns (spec §6 "Deletion follows the owner", A9). Rows are kept
2
- * with `deleted_at` so every pointer resolves to "deleted" with the last preview. A document a
3
- * live document outside the deletion links to is kept: it stays owned by the deleted node, under
4
- * its name and rules, and is collected when its last link goes (`collectUnlinked`). */
5
- import type { DatabaseSync } from 'node:sqlite';
6
1
  import type { ObjectRow } from './types.js';
2
+ import { type CanvasDb } from '../canvas/db.js';
7
3
  /** Mark the node and everything it owns deleted except kept documents, which stay owned by the
8
4
  * deleted node; drop the node's watches (both ends) and its `nodes` row. One savepoint, so it runs as one
9
5
  * transaction or inside the caller's. Refuses a node whose managed worktree is unreconciled. */
10
- export declare function deleteNodeWithOwned(db: DatabaseSync, node: ObjectRow): void;
6
+ export declare function deleteNodeWithOwned(db: CanvasDb, node: ObjectRow): Promise<void>;
11
7
  /** Delete a profile object with what it owns, in the same flow as the profile's own deletion
12
8
  * (`crtr profile delete`): its documents follow the node rule — deleted, except one a live document
13
9
  * outside the deletion links to, which stays owned by the deleted profile until its last link goes.
14
10
  * The object row stays with `deleted_at` (kept documents still name it); its handle is released so
15
11
  * a new profile can take the name, and its identity row stays so a kept document's permission
16
12
  * string still names the profile id. Returns whether a profile object existed for `profileId`. */
17
- export declare function deleteProfileWithOwned(db: DatabaseSync, profileId: string): boolean;
13
+ export declare function deleteProfileWithOwned(db: CanvasDb, profileId: string): Promise<boolean>;
@@ -1,6 +1,6 @@
1
- var R=Object.defineProperty;var E=(e,t)=>R(e,"name",{value:t,configurable:!0});import{prepared as n}from"../sqlite-statements.js";import{hasUnreconciledWorktree as f}from"../canvas/worktrees.js";import{deleteDocument as p}from"./documents.js";import{publish as s}from"./events.js";import{getByRowid as w}from"./objects.js";import{rememberDeletedIsolated as S}from"../runs/confinement.js";let a=0;function I(e,t){if(t.type!=="node")throw new Error(`deleteNodeWithOwned: ${t.id} is a ${t.type}, not a node`);if(f(t.id))throw new Error(`refusing to delete node ${t.id}: its managed worktree is not reconciled`);const o=`graph_delete_${++a}`;e.exec(`SAVEPOINT ${o}`);try{h(e,t),e.exec(`RELEASE ${o}`)}catch(i){throw e.exec(`ROLLBACK TO ${o}`),e.exec(`RELEASE ${o}`),i}}E(I,"deleteNodeWithOwned");function j(e,t){const o=n(e,`SELECT o.* FROM identities i JOIN objects o ON o.rowid = i.object
2
- WHERE i.scheme = 'profile' AND i.external_id = ? AND o.type = 'profile' AND o.deleted_at IS NULL`).get(t);if(!o)return!1;const i=`graph_delete_${++a}`;e.exec(`SAVEPOINT ${i}`);try{u(e,o),n(e,"UPDATE objects SET deleted_at = ?, name = ? WHERE rowid = ?").run(new Date().toISOString(),`${o.name}.deleted-${o.rowid}`,o.rowid),s(e,{event:"deleted",object:w(e,o.rowid),actor:null,attrs:{}}),n(e,"DELETE FROM watches WHERE object = ? OR watcher = ?").run(o.rowid,o.rowid),e.exec(`RELEASE ${i}`)}catch(d){throw e.exec(`ROLLBACK TO ${i}`),e.exec(`RELEASE ${i}`),d}return!0}E(j,"deleteProfileWithOwned");function h(e,t){const o=u(e,t);n(e,"UPDATE objects SET deleted_at = ? WHERE rowid = ?").run(o,t.rowid),s(e,{event:"deleted",object:w(e,t.rowid),actor:null,attrs:{}}),n(e,"DELETE FROM watches WHERE object = ? OR watcher = ?").run(t.rowid,t.rowid),S(t.id,e),n(e,"UPDATE nodes SET run_id = NULL WHERE run_id = ? AND node_id != ? AND isolated = 0").run(t.id,t.id),n(e,"DELETE FROM nodes WHERE node_id = ?").run(t.id)}E(h,"deleteInside");function u(e,t){const o=n(e,`WITH RECURSIVE sub(rowid) AS (
1
+ var u=Object.defineProperty;var i=(e,t)=>u(e,"name",{value:t,configurable:!0});import{hasUnreconciledWorktree as f}from"../canvas/worktrees.js";import{deleteDocument as O}from"./documents.js";import{publish as w}from"./events.js";import{getByRowid as d}from"./objects.js";import{rememberDeletedIsolated as R}from"../runs/confinement.js";import{withCanvasWrite as E}from"../canvas/db.js";async function j(e,t){if(t.type!=="node")throw new Error(`deleteNodeWithOwned: ${t.id} is a ${t.type}, not a node`);if(await f(t.id))throw new Error(`refusing to delete node ${t.id}: its managed worktree is not reconciled`);await E(async()=>await m(e,t),{savepoint:!0})}i(j,"deleteNodeWithOwned");async function I(e,t){const r=await e.prepare(`SELECT o.* FROM identities i JOIN objects o ON o.rowid = i.object
2
+ WHERE i.scheme = 'profile' AND i.external_id = ? AND o.type = 'profile' AND o.deleted_at IS NULL`).get(t);return r?(await E(async()=>{await c(e,r),await e.prepare("UPDATE objects SET deleted_at = ?, name = ? WHERE rowid = ?").run(new Date().toISOString(),`${r.name}.deleted-${r.rowid}`,r.rowid),await w(e,{event:"deleted",object:await d(e,r.rowid),actor:null,attrs:{}}),await e.prepare("DELETE FROM watches WHERE object = ? OR watcher = ?").run(r.rowid,r.rowid)},{savepoint:!0}),!0):!1}i(I,"deleteProfileWithOwned");async function m(e,t){const r=await c(e,t);await e.prepare("UPDATE objects SET deleted_at = ? WHERE rowid = ?").run(r,t.rowid),await w(e,{event:"deleted",object:await d(e,t.rowid),actor:null,attrs:{}}),await e.prepare("DELETE FROM watches WHERE object = ? OR watcher = ?").run(t.rowid,t.rowid),await R(t.id,e),await e.prepare("UPDATE nodes SET run_id = NULL WHERE run_id = ? AND node_id != ? AND isolated = 0").run(t.id,t.id),await e.prepare("DELETE FROM nodes WHERE node_id = ?").run(t.id)}i(m,"deleteInside");async function c(e,t){const r=await e.prepare(`WITH RECURSIVE sub(rowid) AS (
3
3
  SELECT rowid FROM objects WHERE owner = ?
4
4
  UNION SELECT o.rowid FROM objects o JOIN sub ON o.owner = sub.rowid)
5
- SELECT o.* FROM objects o JOIN sub ON sub.rowid = o.rowid WHERE o.deleted_at IS NULL`).all(t.rowid),i=new Set(o.map(r=>r.rowid)),d=n(e,`SELECT e.src FROM edges e JOIN objects s ON s.rowid = e.src
6
- WHERE e.type = 'links-to' AND e.dst = ? AND s.deleted_at IS NULL`);for(let r=!0;r;){r=!1;for(const c of o)c.type!=="document"||!i.has(c.rowid)||d.all(c.rowid).some(({src:O})=>!i.has(O))&&(i.delete(c.rowid),r=!0)}const l=new Date().toISOString();for(const r of o)if(i.has(r.rowid)){if(r.type==="document"){p(e,null,r);continue}n(e,"UPDATE objects SET deleted_at = ? WHERE rowid = ?").run(l,r.rowid),s(e,{event:"deleted",object:w(e,r.rowid),actor:null,attrs:{}}),n(e,"DELETE FROM watches WHERE object = ? OR watcher = ?").run(r.rowid,r.rowid)}return l}E(u,"deleteOwned");export{I as deleteNodeWithOwned,j as deleteProfileWithOwned};
5
+ SELECT o.* FROM objects o JOIN sub ON sub.rowid = o.rowid WHERE o.deleted_at IS NULL`).all(t.rowid),a=new Set(r.map(o=>o.rowid)),l=e.prepare(`SELECT e.src FROM edges e JOIN objects s ON s.rowid = e.src
6
+ WHERE e.type = 'links-to' AND e.dst = ? AND s.deleted_at IS NULL`);for(let o=!0;o;){o=!1;for(const n of r)n.type!=="document"||!a.has(n.rowid)||(await l.all(n.rowid)).some(({src:p})=>!a.has(p))&&(a.delete(n.rowid),o=!0)}const s=new Date().toISOString();for(const o of r)if(a.has(o.rowid)){if(o.type==="document"){await O(e,null,o);continue}await e.prepare("UPDATE objects SET deleted_at = ? WHERE rowid = ?").run(s,o.rowid),await w(e,{event:"deleted",object:await d(e,o.rowid),actor:null,attrs:{}}),await e.prepare("DELETE FROM watches WHERE object = ? OR watcher = ?").run(o.rowid,o.rowid)}return s}i(c,"deleteOwned");export{j as deleteNodeWithOwned,I as deleteProfileWithOwned};
@@ -1,9 +1,6 @@
1
- /** Documents: write, CAS edit, revisions and heads, links per revision, record fields, move,
2
- * delete, history, read, and the two import paths (migration, repo sync). Every act records
3
- * its actor's `acted-on` edge and watch and publishes its event in the caller's transaction. */
4
- import type { DatabaseSync } from 'node:sqlite';
5
1
  import { type ReposFn } from './reader.js';
6
2
  import type { ObjectRow, Privacy, Reader, Revision, RuleSpec } from './types.js';
3
+ import { type CanvasDb } from '../canvas/db.js';
7
4
  export interface DocumentFields {
8
5
  preview?: string;
9
6
  summary?: string | null;
@@ -59,31 +56,31 @@ export interface DocumentRead {
59
56
  /** The object a reader acts as: its node, its app, or the person. */
60
57
  export declare function actorOf(reader: Reader): ObjectRow;
61
58
  /** Head revisions (no child), highest number first. More than one means the document needs a merge. */
62
- export declare function heads(db: DatabaseSync, doc: ObjectRow): Revision[];
63
- export declare function documentRecord(db: DatabaseSync, doc: ObjectRow): DocumentRecord;
59
+ export declare function heads(db: CanvasDb, doc: ObjectRow): Promise<Revision[]>;
60
+ export declare function documentRecord(db: CanvasDb, doc: ObjectRow): Promise<DocumentRecord>;
64
61
  /** The `[[name]]` links a body names, in order, each once. */
65
62
  export declare function linksIn(body: string): string[];
66
63
  /** Derive the document's `links-to` edges from `body`, resolving each name in the writer's
67
64
  * view. A name that resolves to nothing or to several objects stays text and is returned,
68
65
  * and remembered so {@link linkNewlyNamed} can link it when a document by that name appears;
69
66
  * one that may live on another runtime is neither linked nor reported. */
70
- export declare function setRevisionLinks(db: DatabaseSync, reader: Reader, doc: ObjectRow, body: string): string[];
67
+ export declare function setRevisionLinks(db: CanvasDb, reader: Reader, doc: ObjectRow, body: string): Promise<string[]>;
71
68
  /** `body` with each `[[link]]` the document's `links-to` edges resolved shown under its target's
72
69
  * current name, so a rename rewrites no stored body yet every read shows the new name (spec §4).
73
70
  * A link written as the target's id, or to a deleted target, stays as written. */
74
- export declare function withCurrentNames(db: DatabaseSync, doc: ObjectRow, body: string): string;
71
+ export declare function withCurrentNames(db: CanvasDb, doc: ObjectRow, body: string): Promise<string>;
75
72
  /** Write the record fields that are present; `null` clears a nullable one. Rules are
76
73
  * replaced when given. Does not publish; callers publish the act the fields belong to. */
77
- export declare function applyDocumentFields(db: DatabaseSync, doc: ObjectRow, fields: DocumentFields): ObjectRow;
74
+ export declare function applyDocumentFields(db: CanvasDb, doc: ObjectRow, fields: DocumentFields): Promise<ObjectRow>;
78
75
  /** Create a document with its first revision. The actor becomes a watcher whose read base is
79
76
  * the new revision; `created` is published. Returns the names that stayed text. */
80
- export declare function writeDocument(db: DatabaseSync, reader: Reader, spec: WriteSpec, body: string, reposFn?: ReposFn): {
77
+ export declare function writeDocument(db: CanvasDb, reader: Reader, spec: WriteSpec, body: string, reposFn?: ReposFn): Promise<{
81
78
  object: ObjectRow;
82
79
  revision: number;
83
80
  unresolved: string[];
84
- };
81
+ }>;
85
82
  /** The base of the reader's next edit: the heads it last read or wrote, or null when it never has. */
86
- export declare function readBase(db: DatabaseSync, reader: Reader, doc: ObjectRow): string | null;
83
+ export declare function readBase(db: CanvasDb, reader: Reader, doc: ObjectRow): Promise<string | null>;
87
84
  /** Apply exact-text replacements to one head's body; each `old` must occur exactly once. */
88
85
  export declare function applyReplacements(body: string, replace: ReadonlyArray<{
89
86
  old: string;
@@ -96,7 +93,7 @@ export declare function applyReplacements(body: string, replace: ReadonlyArray<{
96
93
  * head, so an edit from a read that showed several heads merges them. `fields` are record
97
94
  * changes applied with the edit.
98
95
  */
99
- export declare function editDocument(db: DatabaseSync, reader: Reader, doc: ObjectRow, change: DocumentChange, rationale: string, base: string | null, fields?: DocumentFields, reposFn?: ReposFn): {
96
+ export declare function editDocument(db: CanvasDb, reader: Reader, doc: ObjectRow, change: DocumentChange, rationale: string, base: string | null, fields?: DocumentFields, reposFn?: ReposFn): Promise<{
100
97
  revision: number;
101
98
  heads_key: string;
102
99
  unresolved: string[];
@@ -105,37 +102,37 @@ export declare function editDocument(db: DatabaseSync, reader: Reader, doc: Obje
105
102
  heads_key: string;
106
103
  revision: number;
107
104
  };
108
- };
105
+ }>;
109
106
  /** Change record fields (preview, summary, privacy, rules, …) without a new revision. A null
110
107
  * reader is repo sync, which carries no reader and checks no access. */
111
- export declare function setDocumentRecord(db: DatabaseSync, reader: Reader | null, doc: ObjectRow, fields: DocumentFields): ObjectRow;
108
+ export declare function setDocumentRecord(db: CanvasDb, reader: Reader | null, doc: ObjectRow, fields: DocumentFields): Promise<ObjectRow>;
112
109
  /** Record that the reader holds the document's current heads: a `read` watch with that read
113
110
  * base, and a `read` push. Delivery's content load calls this without reading the body. */
114
- export declare function recordRead(db: DatabaseSync, reader: Reader, doc: ObjectRow, reposFn?: ReposFn): void;
111
+ export declare function recordRead(db: CanvasDb, reader: Reader, doc: ObjectRow, reposFn?: ReposFn): Promise<void>;
115
112
  /** The document's record, each head with its body (several = needs merge) and its links under
116
113
  * their current names; records the read. */
117
- export declare function readDocument(db: DatabaseSync, reader: Reader, doc: ObjectRow, reposFn?: ReposFn): DocumentRead;
114
+ export declare function readDocument(db: CanvasDb, reader: Reader, doc: ObjectRow, reposFn?: ReposFn): Promise<DocumentRead>;
118
115
  /** Every revision, newest first, with authors, rationales and parents. Records nothing. */
119
- export declare function history(db: DatabaseSync, reader: Reader, doc: ObjectRow): Revision[];
116
+ export declare function history(db: CanvasDb, reader: Reader, doc: ObjectRow): Promise<Revision[]>;
120
117
  /** Rename and/or re-own a document. Only `objects` changes: links point at the id, so no body is
121
118
  * rewritten. A null actor is repo sync, which carries no reader and checks no access. */
122
- export declare function moveDocument(db: DatabaseSync, reader: Reader | null, doc: ObjectRow, to: {
119
+ export declare function moveDocument(db: CanvasDb, reader: Reader | null, doc: ObjectRow, to: {
123
120
  name?: string;
124
121
  owner?: ObjectRow;
125
- }, reposFn?: ReposFn): ObjectRow;
122
+ }, reposFn?: ReposFn): Promise<ObjectRow>;
126
123
  /** Mark the document deleted; the row stays with its last preview. Publishes `deleted`
127
124
  * (level 8), then ends the watches on it and drops its rules. A null actor is repo sync or
128
125
  * node deletion; `deletedAt` is the tombstone's own time when sync imports one. What it linked to is re-checked by {@link collectUnlinked}. */
129
- export declare function deleteDocument(db: DatabaseSync, reader: Reader | null, doc: ObjectRow, reposFn?: ReposFn, deletedAt?: string): ObjectRow;
126
+ export declare function deleteDocument(db: CanvasDb, reader: Reader | null, doc: ObjectRow, reposFn?: ReposFn, deletedAt?: string): Promise<ObjectRow>;
130
127
  /** Repo sync: bring a deleted document back under `name` (checked free first). Revisions, record
131
128
  * and links are untouched; the watches and rules deletion dropped are not recreated here. */
132
- export declare function restoreDocument(db: DatabaseSync, doc: ObjectRow, name: string, reposFn?: ReposFn): ObjectRow;
129
+ export declare function restoreDocument(db: CanvasDb, doc: ObjectRow, name: string, reposFn?: ReposFn): Promise<ObjectRow>;
133
130
  /** Delete each of `targets` that is a kept document nothing links to any more: a live document
134
131
  * whose owner is deleted (node deletion kept it because a live document linked to it) and that
135
132
  * no other live document links to. Each one deleted re-checks what it linked to, so chains of
136
133
  * kept documents collapse; a cycle of kept documents keeps itself. Call it after a document
137
134
  * stops linking to `targets` — it was deleted, or an edit dropped the links. */
138
- export declare function collectUnlinked(db: DatabaseSync, targets: Iterable<number>, reposFn?: ReposFn): void;
135
+ export declare function collectUnlinked(db: CanvasDb, targets: Iterable<number>, reposFn?: ReposFn): Promise<void>;
139
136
  export interface ImportedRevision {
140
137
  rev_id?: string;
141
138
  body_hash: string;
@@ -151,7 +148,7 @@ export interface ImportSpec extends WriteSpec {
151
148
  /** Migration: a document with its linear history (oldest first; bodies already in the body
152
149
  * store). Explicit authors and times; records no edge or watch and publishes nothing — the
153
150
  * caller adds links (`setRevisionLinks`), acted-on edges and watches. */
154
- export declare function importDocument(db: DatabaseSync, spec: ImportSpec, reposFn?: ReposFn): ObjectRow;
151
+ export declare function importDocument(db: CanvasDb, spec: ImportSpec, reposFn?: ReposFn): Promise<ObjectRow>;
155
152
  export interface SyncedRevision {
156
153
  rev_id: string;
157
154
  parents: readonly string[];
@@ -163,9 +160,9 @@ export interface SyncedRevision {
163
160
  /** Repo sync: add revisions that arrived from another runtime, skipping known `rev_id`s. No
164
161
  * CAS, author NULL, publishes nothing; the caller publishes `edited` (with `needs_merge`
165
162
  * when `headCount > 1`) and re-derives links from the head it trusts. */
166
- export declare function insertImportedRevisions(db: DatabaseSync, doc: ObjectRow, revs: readonly SyncedRevision[]): {
163
+ export declare function insertImportedRevisions(db: CanvasDb, doc: ObjectRow, revs: readonly SyncedRevision[]): Promise<{
167
164
  heads_key: string;
168
165
  headCount: number;
169
- };
166
+ }>;
170
167
  /** Look up a live document by id (convenience for handlers and importers). */
171
- export declare function documentById(db: DatabaseSync, id: string): ObjectRow;
168
+ export declare function documentById(db: CanvasDb, id: string): Promise<ObjectRow>;