@north-light/cli 0.3.561 → 0.3.563

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 (579) hide show
  1. package/dist/api/client.d.ts +27 -4
  2. package/dist/api/client.js +3 -3
  3. package/dist/api/contract.d.ts +1 -1
  4. package/dist/api/contract.js +1 -1
  5. package/dist/api/dto/bash-jobs.d.ts +5 -1
  6. package/dist/api/dto/broker-ops.d.ts +25 -1
  7. package/dist/api/dto/charges.d.ts +9 -2
  8. package/dist/api/dto/delivery.d.ts +26 -2
  9. package/dist/api/dto/execution-start.d.ts +57 -0
  10. package/dist/api/dto/execution-start.js +0 -0
  11. package/dist/api/dto/modelauth.d.ts +5 -0
  12. package/dist/api/dto/node-records.d.ts +16 -0
  13. package/dist/api/dto/objects.d.ts +1 -1
  14. package/dist/api/dto/reports.d.ts +0 -3
  15. package/dist/api/dto/run-events.d.ts +7 -1
  16. package/dist/api/dto/settings.d.ts +55 -0
  17. package/dist/api/dto/settings.js +0 -0
  18. package/dist/api/index.d.ts +2 -0
  19. package/dist/api/index.js +1 -1
  20. package/dist/api/routes.d.ts +11 -0
  21. package/dist/api/routes.js +1 -1
  22. package/dist/build-root.d.ts +1 -0
  23. package/dist/build-root.js +1 -1
  24. package/dist/builtin-memory/crouter-sdk/release-notes.md +4 -0
  25. package/dist/cli.js +7 -7
  26. package/dist/clients/attach/chrome/bash-jobs.d.ts +11 -1
  27. package/dist/clients/attach/chrome/bash-jobs.js +1 -1
  28. package/dist/clients/attach/chrome/canvas-panels.d.ts +1 -1
  29. package/dist/clients/attach/chrome/roster.js +6 -4
  30. package/dist/clients/attach/overlays/auth.js +2 -2
  31. package/dist/clients/attach/render/chat-view.js +1 -1
  32. package/dist/clients/attach/viewer.js +550 -567
  33. package/dist/commands/canvas-config.js +2 -2
  34. package/dist/commands/canvas-use.js +1 -1
  35. package/dist/commands/human.js +2 -2
  36. package/dist/commands/node/bash.js +3 -3
  37. package/dist/commands/node/create.js +2 -2
  38. package/dist/commands/person-settings.d.ts +1 -0
  39. package/dist/commands/person-settings.js +1 -0
  40. package/dist/commands/pkg/market-manage.d.ts +2 -2
  41. package/dist/commands/pkg/market-manage.js +1 -1
  42. package/dist/commands/pkg/plugin-manage.js +13 -13
  43. package/dist/commands/pkg/shared.js +1 -1
  44. package/dist/commands/profile/default.js +1 -1
  45. package/dist/commands/push.js +2 -3
  46. package/dist/commands/sys/config.js +1 -1
  47. package/dist/commands/sys/connect.js +1 -1
  48. package/dist/commands/sys/context/sysprompt.js +2 -2
  49. package/dist/commands/sys/doctor.js +1 -1
  50. package/dist/commands/sys/join.js +1 -1
  51. package/dist/commands/sys/panels/broker-limits-panel.js +1 -1
  52. package/dist/commands/sys/panels/keybindings-panel.js +1 -1
  53. package/dist/commands/sys/panels/models-panel.d.ts +8 -2
  54. package/dist/commands/sys/panels/models-panel.js +1 -1
  55. package/dist/commands/sys/panels/prefs-panel.d.ts +1 -0
  56. package/dist/commands/sys/panels/prefs-panel.js +1 -1
  57. package/dist/commands/sys/panels/profiles-panel.js +1 -1
  58. package/dist/commands/sys/panels/provider-panel.d.ts +4 -0
  59. package/dist/commands/sys/panels/provider-panel.js +1 -1
  60. package/dist/commands/sys/provider-login.js +5 -5
  61. package/dist/commands/sys/setup-core.js +3 -3
  62. package/dist/commands/sys/setup-settings-runner.js +1 -1
  63. package/dist/commands/sys/spend.js +3 -3
  64. package/dist/commands/sys/update.js +1 -1
  65. package/dist/core/auth-file.d.ts +11 -19
  66. package/dist/core/auth-file.js +1 -2
  67. package/dist/core/auto-update.d.ts +1 -1
  68. package/dist/core/auto-update.js +4 -4
  69. package/dist/core/bash-jobs.d.ts +29 -71
  70. package/dist/core/bash-jobs.js +9 -10
  71. package/dist/core/blobs/directory.d.ts +3 -0
  72. package/dist/core/blobs/directory.js +1 -0
  73. package/dist/core/blobs/fault.d.ts +3 -0
  74. package/dist/core/blobs/fault.js +1 -0
  75. package/dist/core/blobs/index.d.ts +21 -0
  76. package/dist/core/blobs/index.js +1 -0
  77. package/dist/core/blobs/r2.d.ts +9 -0
  78. package/dist/core/blobs/r2.js +4 -0
  79. package/dist/core/bootstrap.d.ts +1 -1
  80. package/dist/core/bootstrap.js +2 -2
  81. package/dist/core/canvas/canvas.d.ts +9 -7
  82. package/dist/core/canvas/canvas.js +8 -8
  83. package/dist/core/canvas/crons.d.ts +3 -2
  84. package/dist/core/canvas/crons.js +3 -3
  85. package/dist/core/canvas/daemon-owner.d.ts +5 -0
  86. package/dist/core/canvas/daemon-owner.js +1 -1
  87. package/dist/core/canvas/db.d.ts +10 -9
  88. package/dist/core/canvas/db.js +4 -4
  89. package/dist/core/canvas/executions.d.ts +100 -4
  90. package/dist/core/canvas/executions.js +1 -1
  91. package/dist/core/canvas/export-sqlite.js +1 -1
  92. package/dist/core/canvas/focuses.d.ts +4 -0
  93. package/dist/core/canvas/focuses.js +1 -1
  94. package/dist/core/canvas/history.js +9 -9
  95. package/dist/core/canvas/managed-worktree-sweep-candidates.d.ts +2 -1
  96. package/dist/core/canvas/managed-worktree-sweep-candidates.js +3 -2
  97. package/dist/core/canvas/node-tokens.d.ts +1 -4
  98. package/dist/core/canvas/node-tokens.js +3 -3
  99. package/dist/core/canvas/paths.d.ts +0 -1
  100. package/dist/core/canvas/paths.js +1 -1
  101. package/dist/core/canvas/person-state.d.ts +26 -0
  102. package/dist/core/canvas/person-state.js +1 -0
  103. package/dist/core/canvas/person.d.ts +3 -10
  104. package/dist/core/canvas/person.js +7 -7
  105. package/dist/core/canvas/reconciler-leases.d.ts +12 -0
  106. package/dist/core/canvas/reconciler-leases.js +8 -0
  107. package/dist/core/canvas/recovery.d.ts +4 -0
  108. package/dist/core/canvas/recovery.js +1 -1
  109. package/dist/core/canvas/schema-pg/003-fleet-removals.sql +1 -1
  110. package/dist/core/canvas/schema-pg/005-fleet-blobs.sql +13 -0
  111. package/dist/core/canvas/schema-pg/006-job-rows.sql +20 -0
  112. package/dist/core/canvas/schema-pg/007-ledger-check.sql +117 -0
  113. package/dist/core/canvas/schema-version.d.ts +1 -1
  114. package/dist/core/canvas/schema-version.js +1 -1
  115. package/dist/core/canvas/sessions.d.ts +8 -11
  116. package/dist/core/canvas/sessions.js +1 -4
  117. package/dist/core/canvas/tree.d.ts +4 -2
  118. package/dist/core/canvas/tree.js +6 -6
  119. package/dist/core/canvas/types.d.ts +7 -0
  120. package/dist/core/command-hooks/transport/exec-lifecycle.js +1 -1
  121. package/dist/core/command-plugins/bundle.d.ts +1 -1
  122. package/dist/core/command-plugins/bundle.js +1 -1
  123. package/dist/core/command-plugins/compose.d.ts +1 -1
  124. package/dist/core/command-plugins/discovery.d.ts +0 -1
  125. package/dist/core/command-plugins/discovery.js +1 -1
  126. package/dist/core/command-plugins/help-addenda.js +1 -1
  127. package/dist/core/command-plugins/presence.d.ts +2 -0
  128. package/dist/core/command-plugins/presence.js +1 -1
  129. package/dist/core/config.d.ts +16 -15
  130. package/dist/core/config.js +1 -1
  131. package/dist/core/conversation-store/client-worker.js +1 -1
  132. package/dist/core/conversation-store/client.js +2 -2
  133. package/dist/core/conversation-store/index.d.ts +9 -11
  134. package/dist/core/conversation-store/index.js +1 -1
  135. package/dist/core/conversation-store/patch.js +1 -1
  136. package/dist/core/conversation-store/row-store.d.ts +14 -0
  137. package/dist/core/conversation-store/row-store.js +13 -0
  138. package/dist/core/directory/join.d.ts +5 -3
  139. package/dist/core/directory/join.js +1 -1
  140. package/dist/core/env-name.d.ts +1 -0
  141. package/dist/core/env-name.js +1 -1
  142. package/dist/core/environment-recipe.d.ts +15 -0
  143. package/dist/core/environment-recipe.js +1 -0
  144. package/dist/core/environments.js +1 -1
  145. package/dist/core/events/emit.js +2 -2
  146. package/dist/core/events/run-event-chunks.d.ts +25 -0
  147. package/dist/core/events/run-event-chunks.js +5 -0
  148. package/dist/core/feed/messages.js +5 -5
  149. package/dist/core/grants/mirror.d.ts +15 -0
  150. package/dist/core/grants/mirror.js +15 -3
  151. package/dist/core/grants/on-sync.d.ts +9 -5
  152. package/dist/core/grants/on-sync.js +1 -1
  153. package/dist/core/grants/remove.d.ts +1 -6
  154. package/dist/core/grants/remove.js +1 -1
  155. package/dist/core/grants/sync.js +1 -1
  156. package/dist/core/grants/watch.d.ts +15 -9
  157. package/dist/core/grants/watch.js +1 -1
  158. package/dist/core/graph/custom.js +8 -8
  159. package/dist/core/graph/jobs.d.ts +83 -5
  160. package/dist/core/graph/jobs.js +11 -2
  161. package/dist/core/graph/kinds/job.js +2 -2
  162. package/dist/core/graph/names.js +7 -7
  163. package/dist/core/graph/objects.d.ts +5 -1
  164. package/dist/core/graph/objects.js +11 -11
  165. package/dist/core/graph/reader.d.ts +3 -0
  166. package/dist/core/graph/reader.js +3 -3
  167. package/dist/core/graph/repo-sync/identity.d.ts +3 -1
  168. package/dist/core/graph/repo-sync/identity.js +1 -1
  169. package/dist/core/graph/repo-sync/repos.d.ts +1 -1
  170. package/dist/core/graph/repo-sync/repos.js +2 -2
  171. package/dist/core/graph/repo-sync/sync.js +2 -2
  172. package/dist/core/installed-plugins.js +1 -1
  173. package/dist/core/keybindings/persistence.d.ts +1 -1
  174. package/dist/core/keybindings/persistence.js +1 -1
  175. package/dist/core/layout-migrate/loose-keys.d.ts +1 -1
  176. package/dist/core/layout-migrate/loose-keys.js +1 -1
  177. package/dist/core/ledger/account.d.ts +12 -0
  178. package/dist/core/ledger/account.js +2 -0
  179. package/dist/core/ledger/charges.d.ts +2 -2
  180. package/dist/core/ledger/charges.js +1 -1
  181. package/dist/core/ledger/check.d.ts +5 -1
  182. package/dist/core/ledger/check.js +1 -7
  183. package/dist/core/ledger/chunks.d.ts +8 -0
  184. package/dist/core/ledger/chunks.js +2 -0
  185. package/dist/core/ledger/index.d.ts +2 -1
  186. package/dist/core/ledger/index.js +1 -1
  187. package/dist/core/ledger/infra-allowance.d.ts +9 -0
  188. package/dist/core/ledger/infra-allowance.js +1 -0
  189. package/dist/core/ledger/limits.js +3 -3
  190. package/dist/core/ledger/payer.d.ts +1 -1
  191. package/dist/core/ledger/payer.js +1 -1
  192. package/dist/core/ledger/read.d.ts +14 -4
  193. package/dist/core/ledger/read.js +2 -3
  194. package/dist/core/ledger/totals.d.ts +5 -16
  195. package/dist/core/ledger/totals.js +4 -4
  196. package/dist/core/ledger/types.d.ts +12 -3
  197. package/dist/core/llm/run.js +2 -2
  198. package/dist/core/managed-providers.d.ts +72 -0
  199. package/dist/core/managed-providers.js +1 -0
  200. package/dist/core/model-auth/api-credential-store.d.ts +10 -0
  201. package/dist/core/model-auth/api-credential-store.js +1 -0
  202. package/dist/core/model-auth/daemon-login.d.ts +1 -1
  203. package/dist/core/model-auth/daemon-login.js +1 -1
  204. package/dist/core/model-auth/flows.d.ts +5 -4
  205. package/dist/core/model-auth/flows.js +1 -1
  206. package/dist/core/model-auth/handoff-jti.d.ts +3 -4
  207. package/dist/core/model-auth/handoff-jti.js +1 -1
  208. package/dist/core/model-auth/readiness.js +1 -1
  209. package/dist/core/model-config.d.ts +1 -1
  210. package/dist/core/model-config.js +1 -1
  211. package/dist/core/model-routes-pool.d.ts +14 -0
  212. package/dist/core/model-routes-pool.js +1 -0
  213. package/dist/core/model-routes.d.ts +11 -16
  214. package/dist/core/model-routes.js +1 -1
  215. package/dist/core/peer/ingest.d.ts +2 -0
  216. package/dist/core/peer/ingest.js +1 -1
  217. package/dist/core/peer/stubs.d.ts +8 -0
  218. package/dist/core/peer/stubs.js +1 -1
  219. package/dist/core/permissions/evaluator.d.ts +7 -2
  220. package/dist/core/permissions/evaluator.js +2 -2
  221. package/dist/core/plugin-env.js +1 -1
  222. package/dist/core/pool-credential-store.d.ts +2 -5
  223. package/dist/core/pool-credential-store.js +1 -1
  224. package/dist/core/profiles/app-env-store.d.ts +5 -5
  225. package/dist/core/profiles/app-env-store.js +1 -2
  226. package/dist/core/profiles/default-binding.d.ts +5 -5
  227. package/dist/core/profiles/default-binding.js +1 -1
  228. package/dist/core/profiles/env-store.d.ts +10 -21
  229. package/dist/core/profiles/env-store.js +1 -2
  230. package/dist/core/profiles/manifest.d.ts +14 -18
  231. package/dist/core/profiles/manifest.js +1 -1
  232. package/dist/core/profiles/relocate.js +1 -1
  233. package/dist/core/profiles/select.js +21 -21
  234. package/dist/core/provider-credential.d.ts +1 -1
  235. package/dist/core/provider-credential.js +1 -1
  236. package/dist/core/provider-management.d.ts +3 -4
  237. package/dist/core/provider-management.js +1 -1
  238. package/dist/core/providers/bundles.js +2 -2
  239. package/dist/core/providers/call.d.ts +3 -34
  240. package/dist/core/providers/description.d.ts +34 -0
  241. package/dist/core/providers/description.js +0 -0
  242. package/dist/core/providers/token-cache.d.ts +14 -14
  243. package/dist/core/providers/token-cache.js +1 -1
  244. package/dist/core/review/companion.js +1 -1
  245. package/dist/core/runs/activity.d.ts +1 -1
  246. package/dist/core/runs/activity.js +1 -1
  247. package/dist/core/runs/events.d.ts +7 -5
  248. package/dist/core/runs/events.js +2 -6
  249. package/dist/core/runs/operations.d.ts +1 -1
  250. package/dist/core/runs/operations.js +6 -6
  251. package/dist/core/runtime/bearings.js +1 -1
  252. package/dist/core/runtime/broker/attachments-fetch.d.ts +5 -0
  253. package/dist/core/runtime/broker/attachments-fetch.js +1 -0
  254. package/dist/core/runtime/broker/bash-job-launch.d.ts +4 -2
  255. package/dist/core/runtime/broker/bash-job-launch.js +1 -1
  256. package/dist/core/runtime/broker/boot-state.d.ts +9 -0
  257. package/dist/core/runtime/broker/boot-state.js +1 -0
  258. package/dist/core/runtime/broker/cli-relay.d.ts +2 -1
  259. package/dist/core/runtime/broker/cli-relay.js +1 -1
  260. package/dist/core/runtime/broker/client-registry.d.ts +3 -3
  261. package/dist/core/runtime/broker/daemon-ops.d.ts +10 -1
  262. package/dist/core/runtime/broker/daemon-ops.js +1 -1
  263. package/dist/core/runtime/broker/fault-retry.d.ts +2 -0
  264. package/dist/core/runtime/broker/fault-retry.js +1 -1
  265. package/dist/core/runtime/broker/frame-engine-control.js +1 -1
  266. package/dist/core/runtime/broker/held-deferred-inbox.d.ts +3 -0
  267. package/dist/core/runtime/broker/held-deferred-inbox.js +1 -1
  268. package/dist/core/runtime/broker/job-reporter.d.ts +18 -0
  269. package/dist/core/runtime/broker/job-reporter.js +2 -0
  270. package/dist/core/runtime/broker/model-adapter.d.ts +3 -0
  271. package/dist/core/runtime/broker/model-adapter.js +3 -2
  272. package/dist/core/runtime/broker/signal-stream.js +1 -1
  273. package/dist/core/runtime/broker/spilled-body.d.ts +5 -0
  274. package/dist/core/runtime/broker/spilled-body.js +1 -0
  275. package/dist/core/runtime/broker/summaries-post.d.ts +5 -0
  276. package/dist/core/runtime/broker/summaries-post.js +1 -0
  277. package/dist/core/runtime/broker/tool-groups.d.ts +3 -0
  278. package/dist/core/runtime/broker/tool-groups.js +1 -1
  279. package/dist/core/runtime/broker/turn-replies.d.ts +1 -0
  280. package/dist/core/runtime/broker/turn-replies.js +1 -1
  281. package/dist/core/runtime/broker-persona-guidance.js +2 -2
  282. package/dist/core/runtime/broker.js +1 -1
  283. package/dist/core/runtime/deliver-live.js +1 -1
  284. package/dist/core/runtime/first-boot-rows.d.ts +8 -0
  285. package/dist/core/runtime/first-boot-rows.js +2 -0
  286. package/dist/core/runtime/fleet.d.ts +13 -12
  287. package/dist/core/runtime/front-door-login.js +1 -1
  288. package/dist/core/runtime/front-door.js +6 -6
  289. package/dist/core/runtime/headless-pi.js +1 -1
  290. package/dist/core/runtime/host.d.ts +14 -3
  291. package/dist/core/runtime/host.js +3 -3
  292. package/dist/core/runtime/invocation.d.ts +6 -0
  293. package/dist/core/runtime/kickoff.d.ts +2 -14
  294. package/dist/core/runtime/kickoff.js +17 -19
  295. package/dist/core/runtime/launch-config-worker.js +1 -1
  296. package/dist/core/runtime/launch.js +2 -2
  297. package/dist/core/runtime/model-registry.js +1 -1
  298. package/dist/core/runtime/node-read.d.ts +4 -6
  299. package/dist/core/runtime/node-read.js +3 -3
  300. package/dist/core/runtime/nodes.js +1 -1
  301. package/dist/core/runtime/outcome-document.d.ts +0 -1
  302. package/dist/core/runtime/outcome-document.js +1 -1
  303. package/dist/core/runtime/output-result.d.ts +15 -0
  304. package/dist/core/runtime/output-result.js +5 -0
  305. package/dist/core/runtime/placement.d.ts +17 -1
  306. package/dist/core/runtime/placement.js +1 -1
  307. package/dist/core/runtime/provider-credential-gate.d.ts +6 -2
  308. package/dist/core/runtime/provider-credential-gate.js +2 -2
  309. package/dist/core/runtime/recovery-hold.d.ts +21 -2
  310. package/dist/core/runtime/recovery-hold.js +2 -1
  311. package/dist/core/runtime/recycle.js +1 -1
  312. package/dist/core/runtime/reset.js +1 -1
  313. package/dist/core/runtime/revive.d.ts +2 -2
  314. package/dist/core/runtime/revive.js +2 -2
  315. package/dist/core/runtime/runner/blaxel/client.d.ts +81 -0
  316. package/dist/core/runtime/runner/blaxel/client.js +1 -0
  317. package/dist/core/runtime/runner/blaxel/image-build.d.ts +74 -0
  318. package/dist/core/runtime/runner/blaxel/image-build.js +5 -0
  319. package/dist/core/runtime/runner/blaxel/runner.d.ts +41 -0
  320. package/dist/core/runtime/runner/blaxel/runner.js +3 -0
  321. package/dist/core/runtime/runner/index.d.ts +8 -0
  322. package/dist/core/runtime/runner/index.js +1 -0
  323. package/dist/core/runtime/runner/process.d.ts +11 -0
  324. package/dist/core/runtime/runner/process.js +1 -0
  325. package/dist/core/runtime/runner/types.d.ts +95 -0
  326. package/dist/core/runtime/runner/types.js +0 -0
  327. package/dist/core/runtime/situational-context.d.ts +3 -6
  328. package/dist/core/runtime/situational-context.js +2 -2
  329. package/dist/core/runtime/situational-live.js +1 -1
  330. package/dist/core/runtime/spawn-env-rows.d.ts +5 -0
  331. package/dist/core/runtime/spawn-env-rows.js +1 -0
  332. package/dist/core/runtime/spawn-env.d.ts +4 -18
  333. package/dist/core/runtime/spawn-env.js +1 -1
  334. package/dist/core/runtime/spawn.js +2 -2
  335. package/dist/core/runtime/stop-guard.d.ts +1 -1
  336. package/dist/core/runtime/stop-guard.js +2 -8
  337. package/dist/core/runtime/structured-output.d.ts +0 -67
  338. package/dist/core/runtime/structured-output.js +3 -8
  339. package/dist/core/runtime/tmux-driver.d.ts +8 -0
  340. package/dist/core/runtime/tmux-driver.js +6 -6
  341. package/dist/core/runtime/view-socket.d.ts +20 -0
  342. package/dist/core/runtime/view-socket.js +3 -1
  343. package/dist/core/runtime/warm-pool.d.ts +13 -1
  344. package/dist/core/runtime/warm-pool.js +1 -1
  345. package/dist/core/scoped-state/legacy-profiles.d.ts +11 -0
  346. package/dist/core/scoped-state/legacy-profiles.js +1 -0
  347. package/dist/core/scoped-state/materialized-plugins.d.ts +18 -0
  348. package/dist/core/scoped-state/materialized-plugins.js +1 -0
  349. package/dist/core/scoped-state/migrate.d.ts +8 -1
  350. package/dist/core/scoped-state/migrate.js +3 -3
  351. package/dist/core/scoped-state/person-rows.d.ts +10 -0
  352. package/dist/core/scoped-state/person-rows.js +6 -0
  353. package/dist/core/scoped-state/person-store.d.ts +72 -0
  354. package/dist/core/scoped-state/person-store.js +1 -0
  355. package/dist/core/secrets/blaxel-launch.d.ts +24 -0
  356. package/dist/core/secrets/blaxel-launch.js +4 -0
  357. package/dist/core/secrets/blaxel-register.d.ts +2 -0
  358. package/dist/core/secrets/blaxel-register.js +1 -0
  359. package/dist/core/secrets/env-rows.d.ts +17 -0
  360. package/dist/core/secrets/env-rows.js +4 -0
  361. package/dist/core/secrets/environment-owner.d.ts +8 -0
  362. package/dist/core/secrets/environment-owner.js +1 -0
  363. package/dist/core/secrets/environment-secrets.d.ts +14 -0
  364. package/dist/core/secrets/environment-secrets.js +1 -0
  365. package/dist/core/secrets/index.d.ts +2 -0
  366. package/dist/core/secrets/index.js +1 -0
  367. package/dist/core/secrets/key.d.ts +3 -0
  368. package/dist/core/secrets/key.js +2 -0
  369. package/dist/core/secrets/seal.d.ts +18 -0
  370. package/dist/core/secrets/seal.js +1 -0
  371. package/dist/core/spaces/mounts.d.ts +1 -1
  372. package/dist/core/spaces/mounts.js +1 -1
  373. package/dist/core/spaces/process.d.ts +1 -1
  374. package/dist/core/spaces/stop.d.ts +7 -5
  375. package/dist/core/spaces/stop.js +2 -2
  376. package/dist/core/spaces/users.d.ts +2 -1
  377. package/dist/core/spaces/users.js +1 -1
  378. package/dist/core/storage/attachments.d.ts +11 -8
  379. package/dist/core/storage/attachments.js +1 -1
  380. package/dist/core/storage/tables.d.ts +4 -0
  381. package/dist/core/storage/tables.js +3 -3
  382. package/dist/core/subscription-state.d.ts +34 -72
  383. package/dist/core/subscription-state.js +1 -4
  384. package/dist/core/substrate/delivery/plan.js +1 -1
  385. package/dist/core/user-settings.js +1 -1
  386. package/dist/daemon/api/app-listener.js +10 -10
  387. package/dist/daemon/api/auth/person-bearer.d.ts +14 -0
  388. package/dist/daemon/api/auth/person-bearer.js +1 -0
  389. package/dist/daemon/api/bridge.js +4 -4
  390. package/dist/daemon/api/document-listener.js +3 -3
  391. package/dist/daemon/api/environment-of.d.ts +18 -0
  392. package/dist/daemon/api/environment-of.js +5 -0
  393. package/dist/daemon/api/handlers/analytics.js +1 -1
  394. package/dist/daemon/api/handlers/app-profiles.d.ts +2 -2
  395. package/dist/daemon/api/handlers/app-profiles.js +1 -1
  396. package/dist/daemon/api/handlers/bash-jobs.js +1 -1
  397. package/dist/daemon/api/handlers/bash.js +1 -1
  398. package/dist/daemon/api/handlers/broker-ops.d.ts +3 -0
  399. package/dist/daemon/api/handlers/broker-ops.js +1 -1
  400. package/dist/daemon/api/handlers/broker-recovery.js +1 -1
  401. package/dist/daemon/api/handlers/broker-signals.d.ts +0 -3
  402. package/dist/daemon/api/handlers/broker-signals.js +2 -2
  403. package/dist/daemon/api/handlers/canvas.js +4 -4
  404. package/dist/daemon/api/handlers/charges.d.ts +1 -1
  405. package/dist/daemon/api/handlers/charges.js +1 -1
  406. package/dist/daemon/api/handlers/conversations.d.ts +2 -0
  407. package/dist/daemon/api/handlers/conversations.js +3 -0
  408. package/dist/daemon/api/handlers/crons.js +1 -1
  409. package/dist/daemon/api/handlers/daemon.js +1 -1
  410. package/dist/daemon/api/handlers/delivery.d.ts +1 -1
  411. package/dist/daemon/api/handlers/delivery.js +1 -1
  412. package/dist/daemon/api/handlers/docs.js +1 -1
  413. package/dist/daemon/api/handlers/exec.js +1 -1
  414. package/dist/daemon/api/handlers/execution-start.d.ts +2 -0
  415. package/dist/daemon/api/handlers/execution-start.js +2 -0
  416. package/dist/daemon/api/handlers/files.js +1 -1
  417. package/dist/daemon/api/handlers/git-credential.d.ts +11 -0
  418. package/dist/daemon/api/handlers/git-credential.js +1 -0
  419. package/dist/daemon/api/handlers/hook-exec.d.ts +1 -1
  420. package/dist/daemon/api/handlers/hook-exec.js +1 -1
  421. package/dist/daemon/api/handlers/human-requests.js +1 -1
  422. package/dist/daemon/api/handlers/inbox.js +1 -1
  423. package/dist/daemon/api/handlers/messages.js +1 -1
  424. package/dist/daemon/api/handlers/model-config.js +1 -1
  425. package/dist/daemon/api/handlers/modelauth.d.ts +1 -1
  426. package/dist/daemon/api/handlers/modelauth.js +1 -1
  427. package/dist/daemon/api/handlers/node-events.d.ts +6 -0
  428. package/dist/daemon/api/handlers/node-events.js +3 -3
  429. package/dist/daemon/api/handlers/node-outcomes.js +1 -1
  430. package/dist/daemon/api/handlers/node-records.js +3 -2
  431. package/dist/daemon/api/handlers/nodes.js +1 -1
  432. package/dist/daemon/api/handlers/objects.js +3 -3
  433. package/dist/daemon/api/handlers/profiles.js +1 -1
  434. package/dist/daemon/api/handlers/providers.js +1 -1
  435. package/dist/daemon/api/handlers/reports.js +9 -13
  436. package/dist/daemon/api/handlers/reviews.js +1 -1
  437. package/dist/daemon/api/handlers/runs.js +1 -1
  438. package/dist/daemon/api/handlers/settings.d.ts +2 -0
  439. package/dist/daemon/api/handlers/settings.js +1 -0
  440. package/dist/daemon/api/handlers/structured-requests.js +1 -1
  441. package/dist/daemon/api/handlers/vendor-status.d.ts +1 -1
  442. package/dist/daemon/api/handlers/vendor-status.js +1 -1
  443. package/dist/daemon/api/handlers/worktree.js +1 -1
  444. package/dist/daemon/api/map.d.ts +2 -2
  445. package/dist/daemon/api/map.js +2 -2
  446. package/dist/daemon/api/operations.js +1 -1
  447. package/dist/daemon/api/reader.d.ts +8 -1
  448. package/dist/daemon/api/reader.js +1 -1
  449. package/dist/daemon/api/router.d.ts +4 -2
  450. package/dist/daemon/api/router.js +1 -1
  451. package/dist/daemon/api/server.d.ts +15 -3
  452. package/dist/daemon/api/server.js +1 -1
  453. package/dist/daemon/api/vendor-signin.d.ts +2 -1
  454. package/dist/daemon/api/vendor-signin.js +19 -19
  455. package/dist/daemon/api/viewer-presence.d.ts +20 -6
  456. package/dist/daemon/api/viewer-presence.js +2 -1
  457. package/dist/daemon/boot-settings.d.ts +3 -0
  458. package/dist/daemon/boot-settings.js +1 -0
  459. package/dist/daemon/broker-signals/bus.d.ts +48 -11
  460. package/dist/daemon/broker-signals/bus.js +1 -1
  461. package/dist/daemon/cron/armed-context.js +1 -1
  462. package/dist/daemon/cron/lease-recovery.js +1 -1
  463. package/dist/daemon/cron/live-runs.d.ts +6 -0
  464. package/dist/daemon/cron/live-runs.js +1 -1
  465. package/dist/daemon/cron/run-socket.js +1 -1
  466. package/dist/daemon/cron-run.js +2 -2
  467. package/dist/daemon/crtrd-cli.js +1 -1
  468. package/dist/daemon/crtrd.d.ts +10 -0
  469. package/dist/daemon/crtrd.js +18 -17
  470. package/dist/daemon/delivery/run-delivery.d.ts +1 -1
  471. package/dist/daemon/delivery/run-delivery.js +1 -1
  472. package/dist/daemon/due-sources.d.ts +1 -1
  473. package/dist/daemon/due-sources.js +1 -1
  474. package/dist/daemon/due.js +7 -6
  475. package/dist/daemon/fleet.d.ts +6 -6
  476. package/dist/daemon/fleet.js +9 -9
  477. package/dist/daemon/park-activity.d.ts +2 -1
  478. package/dist/daemon/park-activity.js +1 -1
  479. package/dist/daemon/park-pending.d.ts +20 -13
  480. package/dist/daemon/park-pending.js +3 -1
  481. package/dist/daemon/profile-delete.js +1 -1
  482. package/dist/daemon/reconcilers/bash-deadline.d.ts +15 -10
  483. package/dist/daemon/reconcilers/bash-deadline.js +1 -3
  484. package/dist/daemon/reconcilers/broker-supervision.d.ts +13 -3
  485. package/dist/daemon/reconcilers/broker-supervision.js +4 -4
  486. package/dist/daemon/reconcilers/cron-lane.d.ts +0 -1
  487. package/dist/daemon/reconcilers/cron-lane.js +1 -1
  488. package/dist/daemon/reconcilers/fault-retry-backstop.d.ts +2 -9
  489. package/dist/daemon/reconcilers/fault-retry-backstop.js +1 -1
  490. package/dist/daemon/reconcilers/grant-effects.d.ts +8 -0
  491. package/dist/daemon/reconcilers/grant-effects.js +1 -0
  492. package/dist/daemon/reconcilers/grove-instance-sweep.d.ts +1 -3
  493. package/dist/daemon/reconcilers/grove-instance-sweep.js +1 -1
  494. package/dist/daemon/reconcilers/ledger-r2.d.ts +27 -0
  495. package/dist/daemon/reconcilers/ledger-r2.js +7 -0
  496. package/dist/daemon/reconcilers/ledger-sandbox.d.ts +55 -0
  497. package/dist/daemon/reconcilers/ledger-sandbox.js +9 -0
  498. package/dist/daemon/reconcilers/ledger-storage.d.ts +22 -0
  499. package/dist/daemon/reconcilers/ledger-storage.js +5 -0
  500. package/dist/daemon/reconcilers/live-obligation.d.ts +3 -2
  501. package/dist/daemon/reconcilers/live-obligation.js +1 -1
  502. package/dist/daemon/reconcilers/managed-worktree-sweep.d.ts +0 -5
  503. package/dist/daemon/reconcilers/managed-worktree-sweep.js +1 -1
  504. package/dist/daemon/reconcilers/node-deadline.d.ts +2 -1
  505. package/dist/daemon/reconcilers/node-deadline.js +1 -1
  506. package/dist/daemon/reconcilers/node-lifecycle/freeze-lane.d.ts +1 -2
  507. package/dist/daemon/reconcilers/node-lifecycle/freeze-lane.js +1 -1
  508. package/dist/daemon/reconcilers/node-lifecycle/remote-wake.d.ts +31 -0
  509. package/dist/daemon/reconcilers/node-lifecycle/remote-wake.js +1 -0
  510. package/dist/daemon/reconcilers/node-lifecycle/requested-stops.d.ts +5 -0
  511. package/dist/daemon/reconcilers/node-lifecycle/requested-stops.js +2 -0
  512. package/dist/daemon/reconcilers/node-lifecycle/tick.js +1 -1
  513. package/dist/daemon/reconcilers/pending-review-submit.js +1 -1
  514. package/dist/daemon/reconcilers/recipe-image.d.ts +49 -0
  515. package/dist/daemon/reconcilers/recipe-image.js +7 -0
  516. package/dist/daemon/reconcilers/row-claim.d.ts +19 -0
  517. package/dist/daemon/reconcilers/row-claim.js +2 -0
  518. package/dist/daemon/reconcilers/storage-due-work.d.ts +18 -3
  519. package/dist/daemon/reconcilers/storage-due-work.js +2 -1
  520. package/dist/daemon/reconcilers/storage-maintenance.d.ts +5 -13
  521. package/dist/daemon/reconcilers/storage-maintenance.js +1 -1
  522. package/dist/daemon/reconcilers/structured-request-lane.js +1 -1
  523. package/dist/daemon/reconcilers/throttled-lane.d.ts +11 -0
  524. package/dist/daemon/reconcilers/throttled-lane.js +1 -0
  525. package/dist/daemon/review/finish.js +1 -1
  526. package/dist/daemon/run-notices.d.ts +3 -0
  527. package/dist/daemon/run-notices.js +1 -1
  528. package/dist/daemon/runs/append-section.d.ts +4 -1
  529. package/dist/daemon/runs/append-section.js +2 -2
  530. package/dist/daemon/runs/observer.d.ts +3 -2
  531. package/dist/daemon/runs/observer.js +3 -2
  532. package/dist/daemon/runs/view-transport.d.ts +19 -0
  533. package/dist/daemon/runs/view-transport.js +1 -0
  534. package/dist/daemon/structured-requests/boot.d.ts +2 -1
  535. package/dist/daemon/structured-requests/boot.js +1 -1
  536. package/dist/daemon/structured-requests/effects.d.ts +4 -3
  537. package/dist/daemon/structured-requests/effects.js +1 -1
  538. package/dist/daemon/structured-requests/notifier.d.ts +2 -0
  539. package/dist/daemon/structured-requests/notifier.js +1 -1
  540. package/dist/daemon/structured-requests/sidecar.d.ts +4 -3
  541. package/dist/daemon/structured-requests/sidecar.js +1 -1
  542. package/dist/launcher/validate.js +1 -1
  543. package/dist/migrations/004-canvas-documents/index.js +2 -2
  544. package/dist/pi-extensions/broker-local.d.ts +3 -3
  545. package/dist/pi-extensions/broker-local.js +1 -2
  546. package/dist/pi-extensions/canvas-bash-valve.js +6 -6
  547. package/dist/pi-extensions/canvas-context-intro.js +2 -2
  548. package/dist/pi-extensions/canvas-elapsed.js +2 -2
  549. package/dist/pi-extensions/canvas-goal-capture.js +1 -1
  550. package/dist/pi-extensions/canvas-inbox-watcher.js +2 -2
  551. package/dist/pi-extensions/canvas-review-boundary.d.ts +11 -1
  552. package/dist/pi-extensions/canvas-review-boundary.js +3 -3
  553. package/dist/pi-extensions/canvas-stophook.js +1 -1
  554. package/dist/pi-extensions/canvas-structured-output.d.ts +5 -3
  555. package/dist/pi-extensions/canvas-structured-output.js +6 -11
  556. package/dist/pi-extensions/canvas-tool-guide.d.ts +9 -2
  557. package/dist/pi-extensions/canvas-tool-guide.js +6 -6
  558. package/dist/shared/inbox-entry-body.js +7 -7
  559. package/dist/types.d.ts +12 -0
  560. package/docs/sdk/release-notes.md +4 -0
  561. package/package.json +7 -4
  562. package/packages/crouter-identity/package.json +1 -1
  563. package/runtime.lock.json +13 -13
  564. package/scripts/git-credential-crtr +33 -0
  565. package/scripts/sandbox-bootstrap.sh +54 -0
  566. package/scripts/sandbox-start.mjs +320 -0
  567. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.d.ts +0 -78
  568. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.js +0 -1179
  569. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.ts +0 -1406
  570. package/dist/core/conversation-store/file-store.d.ts +0 -37
  571. package/dist/core/conversation-store/file-store.js +0 -9
  572. package/dist/core/conversation-store/listener.d.ts +0 -4
  573. package/dist/core/conversation-store/listener.js +0 -8
  574. package/dist/core/scoped-state/profiles.d.ts +0 -27
  575. package/dist/core/scoped-state/profiles.js +0 -1
  576. package/dist/core/scoped-state/providers.d.ts +0 -24
  577. package/dist/core/scoped-state/providers.js +0 -1
  578. package/dist/core/scoped-state/settings.d.ts +0 -28
  579. package/dist/core/scoped-state/settings.js +0 -1
@@ -1,4 +1,4 @@
1
- var C=Object.defineProperty;var a=(n,t)=>C(n,"name",{value:t,configurable:!0});import{AsyncLocalStorage as R}from"node:async_hooks";import{randomBytes as x}from"node:crypto";import{appendFileSync as $,mkdirSync as P,readFileSync as k}from"node:fs";import{join as L}from"node:path";import m from"pg";import{resolveDatabaseUrl as D}from"../../daemon/postgres/supervisor.js";import{publishFileExclusive as M}from"../fs-utils.js";import{initializeEmptyLayout as N,runtimeRoot as h}from"../layout.js";import{translatePlaceholders as B,translateOnce as q}from"../statements.js";import{ensureHome as U}from"./paths.js";import{emitEvent as F}from"../events/emit.js";import{ensureSchema as T}from"./schema-chain.js";import{canvasDatabaseSchema as I,canvasSchemaDatabaseUrl as K,canvasSearchPathOptions as b}from"./schema-version.js";const G="crtr_test_template";class H extends Error{static{a(this,"CanvasConstraintError")}constraint;code="23505";constructor(t,e,r){super(t,r),this.name="CanvasConstraintError",this.constraint=e}}function _(n){const t=process.env.CRTR_DB_OPEN_LEDGER;if(t)try{const e=`${new Date().toISOString()} ${process.pid} ${process.argv[1]??"<unknown>"} ${n.replace(/\/\/([^:@/]*):[^@/]*@/,"//$1@")}
2
- `;$(t,e)}catch{}}a(_,"recordOpenLedger");const Y=4,z=/\b(?:FOR\s+(?:NO\s+KEY\s+)?(?:UPDATE|SHARE)|FOR\s+KEY\s+SHARE|INTO|nextval|setval|set_config|pg_notify|pg_advisory\w*|pg_try_advisory\w*|lo_\w+)\b/i;function J(n){return/^\s*SELECT\b/i.test(n)&&!z.test(n)}a(J,"isReadStatement");const V=1e3,f=new R;class W{static{a(this,"FifoLock")}tail=Promise.resolve();pending=0;get busy(){return this.pending>0}drained(){return this.tail}async acquire(){this.pending++;const t=this.tail;let e;return this.tail=new Promise(r=>{e=r}),await t,()=>{this.pending--,e()}}}const j=new Set([114,3802]),O={getTypeParser:a(((n,t)=>j.has(n)?e=>e:n===20||n===1700?e=>{const r=Number(e);if(n===20&&!Number.isSafeInteger(r))throw new Error(`canvas db: bigint ${e} does not fit a JS number`);return r}:m.types.getTypeParser(n,t)),"getTypeParser")};class X{static{a(this,"Handle")}url;lock=new W;db;client=null;pool=null;connecting=null;schemaChecked=!1;active=0;inFlight=new Set;constructor(t){this.url=t;const e=this;this.db={prepare:a(r=>this.statement(r,!0),"prepare"),prepareUncached:a(r=>this.statement(r,!1),"prepareUncached"),exec:a(r=>this.gated(async()=>{await this.send({text:r})}),"exec"),get inTransaction(){return w(e)}}}async connected(){return this.client!==null?this.client:(this.connecting??=this.connect().finally(()=>{this.connecting=null}),this.connecting)}async connect(){_(this.url);const t=new m.Client({connectionString:this.url,types:O,application_name:`crtr-${process.pid}`,connectionTimeoutMillis:1e4,options:b()});t.on("error",e=>{console.warn(`[canvas db] connection error: ${e.message}`),this.drop(t)}),t.on("end",()=>this.drop(t)),await t.connect();try{this.schemaChecked||(await Q(t),this.schemaChecked=!0)}catch(e){throw await t.end().catch(()=>{}),e}return t.connection.stream.unref(),this.client=t,t}readPool(){if(this.pool!==null)return this.pool;_(this.url);const t=new m.Pool({connectionString:this.url,types:O,application_name:`crtr-${process.pid}`,connectionTimeoutMillis:1e4,options:b(),max:Y,idleTimeoutMillis:1e4,allowExitOnIdle:!0});return t.on("error",e=>console.warn(`[canvas db] read connection error: ${e.message}`)),this.pool=t}async read(t){await this.lock.drained(),this.inFlight.size>0&&await Promise.all([...this.inFlight]);try{return await this.readPool().query(t)}catch(e){throw this.mapError(e,null)}}drop(t){this.client===t&&(this.client=null)}async send(t){const e=await this.connected(),r=f.getStore();if(r!==void 0&&r.open&&r.handle===this&&r.client!==e)throw new Error("canvas db: the connection was lost during this transaction; it was rolled back");return this.sendOn(e,t)}async sendOn(t,e){const r=t.connection.stream;this.active++===0&&r.ref();const o=t.query(e),i=o.then(()=>{},()=>{});this.inFlight.add(i),i.then(()=>this.inFlight.delete(i));try{return await o}catch(s){throw this.mapError(s,t)}finally{--this.active===0&&r.unref()}}mapError(t,e){const r=t;return r.code==="23505"?new H(r.message??"unique constraint violation",r.constraint,{cause:t}):((r.code==="57P01"||r.code==="ECONNRESET"||r.code==="EPIPE"||/Connection terminated|connection error|Client was closed/i.test(r.message??""))&&e!==null&&(this.drop(e),e.end().catch(()=>{})),t)}async gated(t){if(w(this)){const r=f.getStore(),o=performance.now();try{return await t()}finally{r.statementMs+=performance.now()-o}}if(!this.lock.busy)return t();const e=await this.lock.acquire();try{return await t()}finally{e()}}statement(t,e){const r=e?(()=>{const s=B(t);return{text:s.text,name:s.name}})():{text:q(t).text},o=J(r.text),i=a(s=>{const u={...r,values:s.map(Z)};return o&&!w(this)?this.read(u):this.gated(()=>this.send(u))},"query");return{get:a(async(...s)=>(await i(s)).rows[0],"get"),all:a(async(...s)=>(await i(s)).rows,"all"),run:a(async(...s)=>({changes:(await i(s)).rowCount??0}),"run")}}async close(){const t=this.pool;this.pool=null,await t?.end().catch(()=>{}),(await this.lock.acquire())();const e=this.client;this.client=null,e!==null&&(e.connection.stream.ref(),await e.end().catch(()=>{}))}}function Z(n){return ArrayBuffer.isView(n)&&!Buffer.isBuffer(n)?Buffer.from(n.buffer,n.byteOffset,n.byteLength):n}a(Z,"bindable");function w(n){const t=f.getStore();return t!==void 0&&t.open&&t.handle===n}a(w,"ownsTransaction");async function Q(n){const t=a((i,s,u)=>{F({level:i,event:s,fields:u})},"emit"),e=I(),r=K();if(r===void 0){await T(n,{schema:e,emit:t});return}const o=new m.Client({connectionString:r,application_name:`crtr-schema-${process.pid}`,connectionTimeoutMillis:1e4});await o.connect();try{await T(o,{schema:e,emit:t})}finally{await o.end().catch(()=>{})}}a(Q,"applySchema");function tt(){return process.env.NODE_TEST_CONTEXT!==void 0||process.execArgv.includes("--test")}a(tt,"runningUnderNodeTest");function y(n,t){const e=/^(postgres(?:ql)?:\/\/[^/?#]*)(\/[^?#]*)?(.*)$/s.exec(n);if(e===null)throw new Error(`not a postgres URL: ${n.replace(/\/\/[^@/]*@/,"//")}`);return`${e[1]}/${t}${e[3]}`}a(y,"withDatabase");async function et(n){const t=L(h(),"test-db"),e=a(()=>{try{return k(t,"utf8").trim()||void 0}catch(s){if(s.code==="ENOENT")return;throw s}},"recorded"),r=e();if(r!==void 0)return y(n,r);P(h(),{recursive:!0});const o=`t_${x(8).toString("hex")}`,i=new m.Client({connectionString:y(n,"postgres")});await i.connect();try{if(await i.query(`CREATE DATABASE ${o} TEMPLATE ${G} STRATEGY file_copy`),!M(t,`${o}
3
- `,384))return await i.query(`DROP DATABASE ${o}`),y(n,e())}finally{await i.end()}return y(n,o)}a(et,"testDatabaseUrl");async function nt(){const n=process.env.CRTR_TEST_PG_URL;if(n)return et(n);if(tt())throw new Error("CRTR_TEST_PG_URL is not set: a test must reach its own Postgres (run the suite through the lane runner); refusing to open a real canvas database");return D(h())}a(nt,"canvasDatabaseUrl");const p=new Map,g=new Map;async function v(){N(),U();const n=await nt();g.set(h(),n);let t=p.get(n);return t===void 0&&p.set(n,t=new X(n)),await t.connected(),t}a(v,"openHandle");async function gt(){return(await v()).db}a(gt,"openDb");async function Et(){const n=g.get(h());if(n===void 0)return;g.delete(h());const t=p.get(n);t!==void 0&&(p.delete(n),await t.close())}a(Et,"closeDb");async function St(){const n=[...p.values()];p.clear(),g.clear(),await Promise.all(n.map(t=>t.close()))}a(St,"closeAllDbs");function Tt(n){const t=f.getStore();if(t===void 0||!t.open){queueMicrotask(n);return}t.afterCommit.push(n)}a(Tt,"afterCommit");let rt=0;async function bt(n,t={}){const e=await v(),r=e.db;if(w(e)){if(!t.savepoint&&!t.rollback)return n(r);const c=`canvas_write_${++rt}`;await e.send({text:`SAVEPOINT ${c}`});const l=f.getStore()?.afterCommit,E=l?.length??0;let S;try{S=await n(r)}catch(A){throw await e.send({text:`ROLLBACK TO ${c}; RELEASE ${c}`}),l?.splice(E),A}return await e.send({text:t.rollback?`ROLLBACK TO ${c}; RELEASE ${c}`:`RELEASE ${c}`}),t.rollback&&l?.splice(E),S}const o=await e.lock.acquire(),i=performance.now(),s=new Error("canvas write transaction entered here");let u=!1;const d={handle:e,client:void 0,open:!0,afterCommit:[],statementMs:0};try{const c=await e.connected();await e.sendOn(c,{text:"BEGIN"}),d.client=c;try{const l=await f.run(d,()=>n(r));return await e.sendOn(c,{text:t.rollback?"ROLLBACK":"COMMIT"}),u=!t.rollback,l}catch(l){try{await e.sendOn(c,{text:"ROLLBACK"})}catch{}throw l}}finally{d.open=!1;const c=performance.now()-i;if(c-d.statementMs>V&&console.warn(`[canvas db] write transaction held ${Math.round(c)}ms (${Math.round(d.statementMs)}ms in its statements); its body did non-db work while every other db caller waited
4
- ${s.stack}`),o(),u)for(const l of d.afterCommit)queueMicrotask(l)}}a(bt,"withCanvasWrite");export{H as CanvasConstraintError,Tt as afterCommit,nt as canvasDatabaseUrl,St as closeAllDbs,Et as closeDb,J as isReadStatement,gt as openDb,bt as withCanvasWrite};
1
+ var v=Object.defineProperty;var o=(e,t)=>v(e,"name",{value:t,configurable:!0});import{AsyncLocalStorage as P}from"node:async_hooks";import{randomBytes as D}from"node:crypto";import{appendFileSync as M,mkdirSync as B,readFileSync as k}from"node:fs";import{join as N}from"node:path";import d from"pg";import{resolveDatabaseUrl as I}from"../../daemon/postgres/supervisor.js";import{publishFileExclusive as U}from"../fs-utils.js";import{initializeEmptyLayout as q,runtimeRoot as l}from"../layout.js";import{translatePlaceholders as G,translateOnce as K}from"../statements.js";import{ensureHome as X}from"./paths.js";import{emitEvent as F}from"../events/emit.js";import{ensureSchema as H}from"./schema-chain.js";import{canvasDatabaseSchema as J,canvasSchemaDatabaseUrl as V,canvasSearchPathOptions as b}from"./schema-version.js";const W="crtr_test_template";class Z extends Error{static{o(this,"CanvasConstraintError")}constraint;code="23505";constructor(t,n,a){super(t,a),this.name="CanvasConstraintError",this.constraint=n}}function A(e){const t=process.env.CRTR_DB_OPEN_LEDGER;if(t)try{const n=`${new Date().toISOString()} ${process.pid} ${process.argv[1]??"<unknown>"} ${e.replace(/\/\/([^:@/]*):[^@/]*@/,"//$1@")}
2
+ `;M(t,n)}catch{}}o(A,"recordOpenLedger");const z=6,j=12,O=2;function $(e=process.env){const t=e.CRTR_DATABASE_POOL_MAX?.trim();if(t){const n=Number(t);if(!Number.isInteger(n)||n<O)throw new Error(`CRTR_DATABASE_POOL_MAX must be an integer of at least ${O}; got ${JSON.stringify(t)}`);return n}return e.CRTR_DATABASE_URL?j:z}o($,"canvasPoolSize");const R=3e4,Y=1e3,p=new P,Q=new Set([114,3802]),tt={getTypeParser:o(((e,t)=>Q.has(e)?n=>n:e===20||e===1700?n=>{const a=Number(n);if(e===20&&!Number.isSafeInteger(a))throw new Error(`canvas db: bigint ${n} does not fit a JS number`);return a}:d.types.getTypeParser(e,t)),"getTypeParser")};class et{static{o(this,"Handle")}url;db;pool=null;schema=null;constructor(t){this.url=t;const n=this;this.db={prepare:o(a=>this.statement(a,!0),"prepare"),prepareUncached:o(a=>this.statement(a,!1),"prepareUncached"),exec:o(a=>this.run({text:a}).then(()=>{}),"exec"),get inTransaction(){return L(n)}}}ready(){return this.schema??=rt(this.url).catch(t=>{throw this.schema=null,t}),this.schema}connections(){if(this.pool!==null)return this.pool;const t=new d.Pool({connectionString:this.url,types:tt,application_name:`crtr-${process.pid}`,connectionTimeoutMillis:R,options:b(),max:$(),idleTimeoutMillis:1e4,allowExitOnIdle:!0});return t.on("connect",()=>A(this.url)),t.on("error",n=>console.warn(`[canvas db] pooled connection error: ${n.message}`)),this.pool=t}async checkout(){try{return await this.connections().connect()}catch(t){throw this.mapError(t)}}async run(t){const n=p.getStore();try{if(n!==void 0&&n.open&&n.handle===this){const a=performance.now();try{return await n.client.query(t)}finally{n.statementMs+=performance.now()-a}}return await this.connections().query(t)}catch(a){throw this.mapError(a)}}mapError(t){const n=t;return n.code==="23505"?new Z(n.message??"unique constraint violation",n.constraint,{cause:t}):/timeout exceeded when trying to connect/i.test(n.message??"")?new Error(`canvas db: no pooled connection became free within ${R} ms (pool of ${$()}); a transaction body is holding connections across a slow await`,{cause:t}):t}statement(t,n){const a=n?(()=>{const r=G(t);return{text:r.text,name:r.name}})():{text:K(t).text},s=o(r=>this.run({...a,values:r.map(nt)}),"query");return{get:o(async(...r)=>(await s(r)).rows[0],"get"),all:o(async(...r)=>(await s(r)).rows,"all"),run:o(async(...r)=>({changes:(await s(r)).rowCount??0}),"run")}}async close(){const t=this.pool;this.pool=null,await t?.end().catch(()=>{})}}function nt(e){return ArrayBuffer.isView(e)&&!Buffer.isBuffer(e)?Buffer.from(e.buffer,e.byteOffset,e.byteLength):e}o(nt,"bindable");function L(e){const t=p.getStore();return t!==void 0&&t.open&&t.handle===e}o(L,"ownsTransaction");async function rt(e){const t=o((u,h,y)=>{F({level:u,event:h,fields:y})},"emit"),n=J(),a=V(),s=a??e;A(s);const r=new d.Client({connectionString:s,application_name:`crtr-schema-${process.pid}`,connectionTimeoutMillis:1e4,...a===void 0?{options:b()}:{}});r.on("error",()=>{}),await r.connect();try{await H(r,{schema:n,emit:t})}finally{await r.end().catch(()=>{})}}o(rt,"applySchema");function ot(){return process.env.NODE_TEST_CONTEXT!==void 0||process.execArgv.includes("--test")}o(ot,"runningUnderNodeTest");function w(e,t){const n=/^(postgres(?:ql)?:\/\/[^/?#]*)(\/[^?#]*)?(.*)$/s.exec(e);if(n===null)throw new Error(`not a postgres URL: ${e.replace(/\/\/[^@/]*@/,"//")}`);return`${n[1]}/${t}${n[3]}`}o(w,"withDatabase");async function at(e){const t=N(l(),"test-db"),n=o(()=>{try{return k(t,"utf8").trim()||void 0}catch(u){if(u.code==="ENOENT")return;throw u}},"recorded"),a=n();if(a!==void 0)return w(e,a);B(l(),{recursive:!0});const s=`t_${D(8).toString("hex")}`,r=new d.Client({connectionString:w(e,"postgres")});r.on("error",()=>{}),await r.connect();try{if(await r.query(`CREATE DATABASE ${s} TEMPLATE ${W} STRATEGY file_copy`),!U(t,`${s}
3
+ `,384))return await r.query(`DROP DATABASE ${s}`),w(e,n())}finally{await r.end()}return w(e,s)}o(at,"testDatabaseUrl");async function st(){const e=process.env.CRTR_TEST_PG_URL;if(e)return at(e);if(ot())throw new Error("CRTR_TEST_PG_URL is not set: a test must reach its own Postgres (run the suite through the lane runner); refusing to open a real canvas database");return I(l())}o(st,"canvasDatabaseUrl");const f=new Map,E=new Map;async function C(){q(),X();const e=await st();E.set(l(),e);let t=f.get(e);return t===void 0&&f.set(e,t=new et(e)),await t.ready(),t}o(C,"openHandle");async function _t(){return(await C()).db}o(_t,"openDb");async function bt(){const e=E.get(l());if(e===void 0)return;E.delete(l());const t=f.get(e);t!==void 0&&(f.delete(e),await t.close())}o(bt,"closeDb");async function At(){const e=[...f.values()];f.clear(),E.clear(),await Promise.all(e.map(t=>t.close()))}o(At,"closeAllDbs");function Ot(e){const t=p.getStore();if(t===void 0||!t.open){queueMicrotask(e);return}t.afterCommit.push(e)}o(Ot,"afterCommit");let ct=0;async function $t(e,t={}){const n=await C(),a=n.db;if(L(n)){if(!t.savepoint&&!t.rollback)return e(a);const c=p.getStore(),i=`canvas_write_${++ct}`;await n.run({text:`SAVEPOINT ${i}`});const S=c.afterCommit,T=S.length;let _;try{_=await e(a)}catch(x){throw await n.run({text:`ROLLBACK TO ${i}; RELEASE ${i}`}),S.splice(T),x}return await n.run({text:t.rollback?`ROLLBACK TO ${i}; RELEASE ${i}`:`RELEASE ${i}`}),t.rollback&&S.splice(T),_}const s=new Error("canvas write transaction entered here"),r=await n.checkout();let u;const h=o(c=>{u??=c},"onConnectionError");r.on("error",h);const y=performance.now();let g=!1;const m={handle:n,client:r,open:!0,afterCommit:[],statementMs:0};try{await r.query("BEGIN");try{const c=await p.run(m,()=>e(a));return await r.query(t.rollback?"ROLLBACK":"COMMIT"),g=!t.rollback,c}catch(c){try{await r.query("ROLLBACK")}catch(i){u??=i}throw n.mapError(c)}}finally{m.open=!1;const c=performance.now()-y;if(c-m.statementMs>Y&&console.warn(`[canvas db] write transaction held its connection ${Math.round(c)}ms (${Math.round(m.statementMs)}ms in its statements); its body did non-db work while holding a pooled connection and its row locks
4
+ ${s.stack}`),r.removeListener("error",h),r.release(u),g)for(const i of m.afterCommit)queueMicrotask(i)}}o($t,"withCanvasWrite");export{Z as CanvasConstraintError,Ot as afterCommit,st as canvasDatabaseUrl,$ as canvasPoolSize,At as closeAllDbs,bt as closeDb,_t as openDb,$t as withCanvasWrite};
@@ -8,22 +8,118 @@ export interface Execution {
8
8
  startedAt: string;
9
9
  endedAt: string | null;
10
10
  exitReason: string | null;
11
+ runner: 'process' | 'blaxel';
12
+ sandboxName: string | null;
13
+ attempt: number;
14
+ /** The release the wake accepted. */
15
+ release: string | null;
16
+ heartbeatAt: string | null;
17
+ awakeSince: string | null;
18
+ idleAt: string | null;
19
+ exitedAt: string | null;
20
+ /** The launch recipe the wake wrote: invocation argv and env, config snapshot, system prompt text, scopes. */
21
+ launchJson: string | null;
22
+ stopRequestedAt: string | null;
23
+ stopAfterTurn: boolean;
24
+ stopReason: string | null;
11
25
  }
26
+ /** Reasons that end a launch the broker never reported `running` for; nothing the broker owned needs cleanup. */
27
+ export type ExecutionEndReason = 'launch_lost' | 'launch_timeout' | (string & {});
12
28
  export declare function liveExecutionForNode(nodeId: string): Promise<Execution | null>;
13
- export declare function beginExecution(nodeId: string, input: {
29
+ export interface BeginExecutionInput {
14
30
  daemonEpoch: string | null;
15
- }): Promise<string>;
31
+ runner?: Execution['runner'];
32
+ /** Defaults to one above the node's highest attempt. */
33
+ attempt?: number;
34
+ sandboxName?: string | null;
35
+ release?: string | null;
36
+ launchJson?: string | null;
37
+ /** The broker cap. The count of other nodes' live rows and this insert are one step under a database-wide lock,
38
+ * so two processes beginning at cap-1 cannot both take the last slot. */
39
+ cap?: number;
40
+ }
41
+ /** Thrown by `beginExecution` when `cap` other nodes already hold a live execution row. */
42
+ export declare class ExecutionCapReached extends Error {
43
+ readonly cap: number;
44
+ readonly live: number;
45
+ constructor(cap: number, live: number);
46
+ }
47
+ /** Thrown by `beginExecution` when the node already holds a live execution another caller owns: a remote one, or a process
48
+ * one this daemon epoch began. The holder keeps its row and token; the caller adopts it or backs off, never replaces it. */
49
+ export declare class ExecutionAlreadyLive extends Error {
50
+ readonly nodeId: string;
51
+ readonly executionId: string;
52
+ constructor(nodeId: string, executionId: string);
53
+ }
54
+ /** Inserts the `launching` row. It mints no token: the runner mints inside `start` (design D74). */
55
+ export declare function beginExecution(nodeId: string, input: BeginExecutionInput): Promise<string>;
56
+ /** Persist the complete launch recipe before handing the execution to a runner. */
57
+ export declare function setExecutionLaunchJson(executionId: string, launchJson: string): Promise<void>;
58
+ /** The broker went idle with nothing holding it (design D18): stamps `idle_at` on its running execution, once per awake period. */
59
+ export declare function recordExecutionIdle(executionId: string): Promise<boolean>;
60
+ /** A thawed resident broker starts a new awake period: `awake_since` is now and `idle_at` is cleared. */
61
+ export declare function recordExecutionAwake(executionId: string): Promise<void>;
16
62
  /** Returns shutdown when a late broker references an execution no longer live. */
17
63
  export declare function recordExecutionPid(executionId: string, nodeId: string, pid: number): Promise<'recorded' | 'shutdown'>;
64
+ /**
65
+ * Ends the execution, revokes its token and clears the node's supervision marks in one transaction.
66
+ * `launch_lost` and `launch_timeout` are the recovery ends of a `launching` row (design, Execution token hand-off).
67
+ */
18
68
  export declare function endExecution(executionId: string, input: {
19
- reason: string;
69
+ reason: ExecutionEndReason;
70
+ }): Promise<boolean>;
71
+ /** Ends the execution only while it is still `launching`: false when a `session.bound` already made it `running`, so a stale
72
+ * timeout decision never kills a broker that bound. The caller stops the external process only on true. */
73
+ export declare function endLaunchingExecution(executionId: string, input: {
74
+ reason: ExecutionEndReason;
20
75
  }): Promise<boolean>;
21
76
  export declare function abortExecution(executionId: string, input: {
22
77
  reason: string;
23
78
  }): Promise<boolean>;
24
79
  export declare function endLiveExecution(nodeId: string, input: {
25
- reason: string;
80
+ reason: ExecutionEndReason;
26
81
  }): Promise<boolean>;
27
82
  export declare function migrateLegacyExecutionIdentities(captureIdentity?: (pid: number) => string | undefined): Promise<{
28
83
  migrated: string[];
29
84
  }>;
85
+ /** Records a stop request on the node's live execution; the first request's time and reason stand. */
86
+ export declare function requestExecutionStop(nodeId: string, input: {
87
+ afterTurn: boolean;
88
+ reason: string;
89
+ }): Promise<boolean>;
90
+ /** Live executions with a stop requested at or before `requestedBefore` (ISO time). A request this old has outlived the
91
+ * process that queued it, whose own teardown runs within seconds. */
92
+ export declare function executionsWithStopRequestedBefore(requestedBefore: string): Promise<Execution[]>;
93
+ /** The node's most recent execution row, live or ended. */
94
+ export declare function latestExecutionForNode(nodeId: string): Promise<Execution | null>;
95
+ /** True when the node has a `running` execution on a runner other than the process runner: the row is its only liveness record. */
96
+ export declare function hasRunningRemoteExecution(nodeId: string): Promise<boolean>;
97
+ /** True when a `launching` execution is in flight: any runner's, or a process runner's started by this daemon epoch. */
98
+ export declare function hasLaunchingExecution(nodeId: string, epoch: string): Promise<boolean>;
99
+ /** Node ids with a live process-runner execution begun by this daemon epoch. */
100
+ export declare function liveProcessExecutionNodeIds(epoch: string): Promise<Set<string>>;
101
+ /** Every node with a live (not exited) execution row, whichever process or runner holds it. */
102
+ export declare function liveExecutionNodeIds(): Promise<Set<string>>;
103
+ export declare const PROFILE_PAUSE_STOP_REASON = "profile_pause";
104
+ /** Marks the node's live execution as stopped by a profile pause, so the exit it causes is not read as a crash. */
105
+ export declare function markProfilePauseStop(nodeId: string): Promise<void>;
106
+ export declare function hasProfilePauseStop(nodeId: string): Promise<boolean>;
107
+ /** Consumes the pause stop once: true for the single dead-row pass that must absorb it. */
108
+ export declare function absorbProfilePauseStop(nodeId: string): Promise<boolean>;
109
+ /** Whether the latest execution's profile-pause stop was absorbed by a policy pass, the exit it caused already forgiven. */
110
+ export declare function hasAbsorbedProfilePauseStop(nodeId: string): Promise<boolean>;
111
+ /** Records a child's observed exit status on its execution without ending it; the next dead-row pass reads it once. The first recorded reason stands. */
112
+ export declare function recordExecutionExit(executionId: string, status: {
113
+ code: number | null;
114
+ signal: string | null;
115
+ oomKilled?: boolean;
116
+ }): Promise<void>;
117
+ export interface ObservedExit {
118
+ code: number | null;
119
+ signal: NodeJS.Signals | null;
120
+ oomKilled?: boolean;
121
+ }
122
+ /** Whether the latest execution holds an observed exit no dead-row pass has consumed yet. */
123
+ export declare function hasObservedExit(nodeId: string): Promise<boolean>;
124
+ /** Reads and consumes the latest execution's unhandled observed exit, once. */
125
+ export declare function takeObservedExit(nodeId: string): Promise<ObservedExit | undefined>;
@@ -1 +1 @@
1
- var y=Object.defineProperty;var o=(e,t)=>y(e,"name",{value:t,configurable:!0});import{randomUUID as m}from"node:crypto";import{openDb as _,withCanvasWrite as u}from"./db.js";import{capturePidIdentities as f,captureLivenessSnapshot as g,identitiesMatch as h,isBootScopedIdentity as A,isLegacyTicksIdentity as T}from"./pid.js";import{existsSync as D,readFileSync as L}from"node:fs";import{LAUNCHER_SOCKET as S}from"../../launcher/spec.js";import{forgetNodeToken as w,mintNodeToken as U,revokeNodeTokens as p}from"./node-tokens.js";function x(){return new Date().toISOString()}o(x,"now");function R(e){return{executionId:e.execution_id,nodeId:e.node_id,daemonEpoch:e.daemon_epoch??null,pid:e.pid??null,processIdentity:e.process_identity??null,state:e.state,startedAt:e.started_at,endedAt:e.ended_at??null,exitReason:e.exit_reason??null}}o(R,"hydrate");async function F(e){const t=await(await _()).prepare("SELECT * FROM executions WHERE node_id = ? AND state != 'exited'").get(e);return t===void 0?null:R(t)}o(F,"liveExecutionForNode");async function M(e,t){return await u(async n=>{const i=x();await n.prepare("UPDATE executions SET state = 'exited', ended_at = ?, exit_reason = 'superseded' WHERE node_id = ? AND state != 'exited'").run(i,e),await p(n,"node_id",e,i);const r=m();return await n.prepare("INSERT INTO executions (execution_id, node_id, daemon_epoch, pid, process_identity, state, started_at, ended_at, exit_reason) VALUES (?, ?, ?, NULL, NULL, 'launching', ?, NULL, NULL)").run(r,e,t.daemonEpoch,i),await U(n,r,e,i),r})}o(M,"beginExecution");async function b(e,t,n){const i=f([n])?.get(n)??null;return await u(async r=>{if((await r.prepare("UPDATE executions SET pid = ?, process_identity = ?, state = 'running' WHERE execution_id = ? AND node_id = ? AND state = 'launching'").run(n,i,e,t)).changes>0)return"recorded";const s=await r.prepare("SELECT pid FROM executions WHERE execution_id = ? AND node_id = ? AND state = 'running'").get(e,t);if(s?.pid===n)return"recorded";if(process.platform==="linux"&&D(S)&&s?.pid!=null){const l=g(),c=[s.pid];for(let d=0;d<c.length;d++)c.push(...l?.childrenOf.get(c[d])??[]);if(c.includes(n))return"recorded";for(const d of c)try{const N=L(`/proc/${d}/status`,"utf8"),E=/^NSpid:\s*(.+)$/m.exec(N)?.[1]?.trim().split(/\s+/).map(Number)??[];if(E.length>1&&E.at(-1)===n)return"recorded"}catch{}}return"shutdown"})}o(b,"recordExecutionPid");async function H(e,t){return w(e),await u(async n=>{const i=x(),r=await n.prepare("UPDATE executions SET state = 'exited', ended_at = ?, exit_reason = ? WHERE execution_id = ? AND state != 'exited'").run(i,t.reason,e);return await p(n,"broker_process_id",e,i),Number(r.changes)===1})}o(H,"endExecution");async function $(e,t){return await H(e,t)}o($,"abortExecution");async function B(e,t){return await u(async n=>{const i=x(),r=await n.prepare("UPDATE executions SET state = 'exited', ended_at = ?, exit_reason = ? WHERE node_id = ? AND state != 'exited'").run(i,t.reason,e);return await p(n,"node_id",e,i),Number(r.changes)===1})}o(B,"endLiveExecution");async function K(e=t=>f([t])?.get(t)){const t=await _(),n=await t.prepare("SELECT execution_id, pid, process_identity FROM executions WHERE state = 'running' AND pid IS NOT NULL AND process_identity IS NOT NULL").all(),i=t.prepare("UPDATE executions SET process_identity = ? WHERE execution_id = ? AND pid = ? AND process_identity = ? AND state = 'running'"),r=[];for(const a of n){if(!T(a.process_identity))continue;const s=e(a.pid);s===void 0||!A(s)||!h(s,a.process_identity)||(await i.run(s,a.execution_id,a.pid,a.process_identity)).changes>0&&r.push(a.execution_id)}return{migrated:r}}o(K,"migrateLegacyExecutionIdentities");export{$ as abortExecution,M as beginExecution,H as endExecution,B as endLiveExecution,F as liveExecutionForNode,K as migrateLegacyExecutionIdentities,b as recordExecutionPid};
1
+ var T=Object.defineProperty;var a=(e,t)=>T(e,"name",{value:t,configurable:!0});import{randomUUID as g}from"node:crypto";import{openDb as r,withCanvasWrite as _}from"./db.js";import{capturePidIdentities as R,captureLivenessSnapshot as L,identitiesMatch as D,isBootScopedIdentity as y,isLegacyTicksIdentity as C}from"./pid.js";import{existsSync as O,readFileSync as P}from"node:fs";import{LAUNCHER_SOCKET as U}from"../../launcher/spec.js";import{revokeNodeTokens as x}from"./node-tokens.js";import{clearPendingParkIn as l}from"../../daemon/park-pending.js";function d(){return new Date().toISOString()}a(d,"now");function A(e){return{executionId:e.execution_id,nodeId:e.node_id,daemonEpoch:e.daemon_epoch??null,pid:e.pid??null,processIdentity:e.process_identity??null,state:e.state,startedAt:e.started_at,endedAt:e.ended_at??null,exitReason:e.exit_reason??null,runner:e.runner,sandboxName:e.sandbox_name??null,attempt:Number(e.attempt),release:e.release??null,heartbeatAt:e.heartbeat_at??null,awakeSince:e.awake_since??null,idleAt:e.idle_at??null,exitedAt:e.exited_at??null,launchJson:e.launch_json??null,stopRequestedAt:e.stop_requested_at??null,stopAfterTurn:Number(e.stop_after_turn)===1,stopReason:e.stop_reason??null}}a(A,"hydrate");async function X(e){const t=await(await r()).prepare("SELECT * FROM executions WHERE node_id = ? AND state != 'exited'").get(e);return t===void 0?null:A(t)}a(X,"liveExecutionForNode");class W extends Error{static{a(this,"ExecutionCapReached")}cap;live;constructor(t,n){super(`no broker slot is free \u2014 ${n} live executions at the cap of ${t}.`),this.cap=t,this.live=n,this.name="ExecutionCapReached"}}class H extends Error{static{a(this,"ExecutionAlreadyLive")}nodeId;executionId;constructor(t,n){super(`${t} already has a live execution ${n}.`),this.nodeId=t,this.executionId=n,this.name="ExecutionAlreadyLive"}}const b=7340001;async function Y(e,t){return await _(async n=>{const i=d();if(!await n.prepare("SELECT node_id FROM nodes WHERE node_id = ? FOR UPDATE").get(e))throw new Error(`cannot begin execution: missing node ${e}`);if(t.cap!==void 0){await n.prepare(`SELECT pg_advisory_xact_lock(${b})`).get();const u=Number((await n.prepare("SELECT COUNT(*) AS n FROM executions WHERE state != 'exited' AND node_id != ?").get(e)).n);if(u>=t.cap)throw new W(t.cap,u)}const s=(await n.prepare("SELECT execution_id, runner, daemon_epoch, state FROM executions WHERE node_id = ? AND state != 'exited'").all(e)).find(u=>u.state==="launching"?u.runner!=="process"||t.daemonEpoch!==null&&u.daemon_epoch===t.daemonEpoch:u.runner!=="process");if(s!==void 0)throw new H(e,s.execution_id);(await n.prepare("UPDATE executions SET state = 'exited', ended_at = ?, exited_at = ?, exit_reason = 'superseded' WHERE node_id = ? AND state != 'exited'").run(i,i,e)).changes>0&&await l(n,e),await x(n,"node_id",e,i);const p=g(),E=t.attempt??Number((await n.prepare("SELECT COALESCE(MAX(attempt), 0) + 1 AS next FROM executions WHERE node_id = ?").get(e)).next);return await n.prepare("INSERT INTO executions (execution_id, node_id, daemon_epoch, pid, process_identity, state, started_at, ended_at, exit_reason, runner, sandbox_name, attempt, release, launch_json) VALUES (?, ?, ?, NULL, NULL, 'launching', ?, NULL, NULL, ?, ?, ?, ?, ?)").run(p,e,t.daemonEpoch,i,t.runner??"process",t.sandboxName??null,E,t.release??null,t.launchJson??null),p})}a(Y,"beginExecution");async function j(e,t){const n=await(await r()).prepare("UPDATE executions SET launch_json = ? WHERE execution_id = ? AND state = 'launching'").run(t,e);if(Number(n.changes)!==1)throw new Error(`cannot set launch recipe for execution ${e}: no launching execution`)}a(j,"setExecutionLaunchJson");async function J(e){const t=await(await r()).prepare("UPDATE executions SET idle_at = ? WHERE execution_id = ? AND state = 'running' AND idle_at IS NULL").run(d(),e);return Number(t.changes)===1}a(J,"recordExecutionIdle");async function G(e){await(await r()).prepare("UPDATE executions SET awake_since = ?, idle_at = NULL WHERE execution_id = ? AND state = 'running'").run(d(),e)}a(G,"recordExecutionAwake");async function V(e,t,n){const i=R([n])?.get(n)??null;return await _(async o=>{if((await o.prepare("UPDATE executions SET pid = ?, process_identity = ?, state = 'running', awake_since = ? WHERE execution_id = ? AND node_id = ? AND state = 'launching'").run(n,i,d(),e,t)).changes>0)return"recorded";const s=await o.prepare("SELECT pid FROM executions WHERE execution_id = ? AND node_id = ? AND state = 'running'").get(e,t);if(s?.pid===n)return"recorded";if(process.platform==="linux"&&O(U)&&s?.pid!=null){const S=L(),p=[s.pid];for(let E=0;E<p.length;E++)p.push(...S?.childrenOf.get(p[E])??[]);if(p.includes(n))return"recorded";for(const E of p)try{const u=P(`/proc/${E}/status`,"utf8"),m=/^NSpid:\s*(.+)$/m.exec(u)?.[1]?.trim().split(/\s+/).map(Number)??[];if(m.length>1&&m.at(-1)===n)return"recorded"}catch{}}return"shutdown"})}a(V,"recordExecutionPid");async function F(e,t){return await _(async n=>{const i=d(),o=await n.prepare("UPDATE executions SET state = 'exited', ended_at = ?, exited_at = ?, exit_reason = COALESCE(exit_reason, ?) WHERE execution_id = ? AND state != 'exited' RETURNING node_id").get(i,i,t.reason,e);return await x(n,"broker_process_id",e,i),o!==void 0&&await l(n,o.node_id),o!==void 0})}a(F,"endExecution");async function z(e,t){return await _(async n=>{const i=d(),o=await n.prepare("UPDATE executions SET state = 'exited', ended_at = ?, exited_at = ?, exit_reason = COALESCE(exit_reason, ?) WHERE execution_id = ? AND state = 'launching' RETURNING node_id").get(i,i,t.reason,e);return o===void 0?!1:(await x(n,"broker_process_id",e,i),await l(n,o.node_id),!0)})}a(z,"endLaunchingExecution");async function Q(e,t){return await F(e,t)}a(Q,"abortExecution");async function Z(e,t){return await _(async n=>{const i=d(),o=await n.prepare("UPDATE executions SET state = 'exited', ended_at = ?, exited_at = ?, exit_reason = COALESCE(exit_reason, ?) WHERE node_id = ? AND state != 'exited'").run(i,i,t.reason,e);return await x(n,"node_id",e,i),Number(o.changes)>0&&await l(n,e),Number(o.changes)===1})}a(Z,"endLiveExecution");async function ee(e=t=>R([t])?.get(t)){const t=await r(),n=await t.prepare("SELECT execution_id, pid, process_identity FROM executions WHERE state = 'running' AND pid IS NOT NULL AND process_identity IS NOT NULL").all(),i=t.prepare("UPDATE executions SET process_identity = ? WHERE execution_id = ? AND pid = ? AND process_identity = ? AND state = 'running'"),o=[];for(const c of n){if(!C(c.process_identity))continue;const s=e(c.pid);s===void 0||!y(s)||!D(s,c.process_identity)||(await i.run(s,c.execution_id,c.pid,c.process_identity)).changes>0&&o.push(c.execution_id)}return{migrated:o}}a(ee,"migrateLegacyExecutionIdentities");async function te(e,t){const n=await(await r()).prepare("UPDATE executions SET stop_requested_at = COALESCE(stop_requested_at, ?), stop_after_turn = CASE WHEN stop_requested_at IS NULL THEN ? ELSE stop_after_turn END, stop_reason = COALESCE(stop_reason, ?) WHERE node_id = ? AND state != 'exited'").run(d(),t.afterTurn?1:0,t.reason,e);return Number(n.changes)>0}a(te,"requestExecutionStop");async function ne(e){return(await(await r()).prepare("SELECT * FROM executions WHERE state != 'exited' AND stop_requested_at IS NOT NULL AND stop_requested_at <= ? ORDER BY stop_requested_at").all(e)).map(A)}a(ne,"executionsWithStopRequestedBefore");async function f(e){const t=await(await r()).prepare("SELECT * FROM executions WHERE node_id = ? ORDER BY started_at DESC, attempt DESC LIMIT 1").get(e);return t===void 0?null:A(t)}a(f,"latestExecutionForNode");async function ae(e){return await(await r()).prepare("SELECT 1 AS x FROM executions WHERE node_id = ? AND state = 'running' AND runner != 'process'").get(e)!==void 0}a(ae,"hasRunningRemoteExecution");async function ie(e,t){return await(await r()).prepare("SELECT 1 AS x FROM executions WHERE node_id = ? AND state = 'launching' AND (runner != 'process' OR daemon_epoch = ?)").get(e,t)!==void 0}a(ie,"hasLaunchingExecution");async function oe(e){const t=await(await r()).prepare("SELECT node_id FROM executions WHERE state != 'exited' AND runner = 'process' AND daemon_epoch = ?").all(e);return new Set(t.map(n=>n.node_id))}a(oe,"liveProcessExecutionNodeIds");async function re(){const e=await(await r()).prepare("SELECT node_id FROM executions WHERE state != 'exited'").all();return new Set(e.map(t=>t.node_id))}a(re,"liveExecutionNodeIds");const h="profile_pause",w="profile_pause_absorbed";async function se(e){await(await r()).prepare("UPDATE executions SET stop_requested_at = COALESCE(stop_requested_at, ?), stop_reason = ? WHERE node_id = ? AND state != 'exited'").run(d(),h,e)}a(se,"markProfilePauseStop");async function ce(e){return(await f(e))?.stopReason===h}a(ce,"hasProfilePauseStop");async function ue(e){const t=await(await r()).prepare("UPDATE executions SET stop_reason = ? WHERE execution_id = (SELECT execution_id FROM executions WHERE node_id = ? ORDER BY started_at DESC, attempt DESC LIMIT 1) AND stop_reason = ?").run(w,e,h);return Number(t.changes)>0}a(ue,"absorbProfilePauseStop");async function de(e){return(await f(e))?.stopReason===w}a(de,"hasAbsorbedProfilePauseStop");const N="exited:";async function pe(e,t){const n=t.oomKilled===!0?"out_of_memory":`${N}${t.code??""}:${t.signal??""}`;await(await r()).prepare("UPDATE executions SET exit_reason = ? WHERE execution_id = ? AND exit_reason IS NULL").run(n,e)}a(pe,"recordExecutionExit");async function Ee(e){const t=(await f(e))?.exitReason;return t!=null&&(t==="out_of_memory"||t.startsWith(N))}a(Ee,"hasObservedExit");async function _e(e){const t=await f(e),n=t?.exitReason;if(t===null||n==null)return;const i=n==="out_of_memory";if(!i&&!n.startsWith(N))return;const o=await(await r()).prepare("UPDATE executions SET exit_reason = 'exit_handled' WHERE execution_id = ? AND exit_reason = ?").run(t.executionId,n);if(Number(o.changes)===0)return;if(i)return{code:null,signal:null,oomKilled:!0};const[c,s]=n.slice(N.length).split(":");return{code:c===""?null:Number(c),signal:s===""?null:s}}a(_e,"takeObservedExit");export{H as ExecutionAlreadyLive,W as ExecutionCapReached,h as PROFILE_PAUSE_STOP_REASON,Q as abortExecution,ue as absorbProfilePauseStop,Y as beginExecution,F as endExecution,z as endLaunchingExecution,Z as endLiveExecution,ne as executionsWithStopRequestedBefore,de as hasAbsorbedProfilePauseStop,ie as hasLaunchingExecution,Ee as hasObservedExit,ce as hasProfilePauseStop,ae as hasRunningRemoteExecution,f as latestExecutionForNode,X as liveExecutionForNode,re as liveExecutionNodeIds,oe as liveProcessExecutionNodeIds,se as markProfilePauseStop,ee as migrateLegacyExecutionIdentities,G as recordExecutionAwake,pe as recordExecutionExit,J as recordExecutionIdle,V as recordExecutionPid,te as requestExecutionStop,j as setExecutionLaunchJson,_e as takeObservedExit};
@@ -1,3 +1,3 @@
1
- var V=Object.defineProperty;var w=(i,a)=>V(i,"name",{value:a,configurable:!0});import{DatabaseSync as W}from"node:sqlite";import{existsSync as Y,mkdirSync as D,mkdtempSync as J,renameSync as X,rmSync as P}from"node:fs";import{tmpdir as Q}from"node:os";import{join as A}from"node:path";import j from"pg";import{migrate as z,MIGRATIONS as I}from"./migrations.js";import{canvasDbPath as Z}from"./paths.js";import{canvasSearchPathOptions as ee}from"./schema-version.js";import{EXPORT_MARK_KEY as F,IMPORT_MARK_KEY as te,OBJECT_COLUMNS as ne,pgColumns as se,quote as c,TABLE_ORDER as C}from"./import-sqlite.js";const re=5e3,oe=new Set(["environments","relations","schemas","charges","charge_totals","limits","viewer_attachments","reconciler_leases","environment_repos","conversation_entries","conversation_parts","charge_chunks","profiles","profile_projects","profile_defaults","scope_settings","scope_bookkeeping","scope_marketplaces","scope_plugins","person_settings","model_accounts","model_account_cooldowns","model_api_keys","model_settings","model_sign_in_flows","env_vars","usage","grantee_usage","provider_receipts"]),ae={exposures:"node, object, channel",rules:"object, position",edges:"type, src, dst",unresolved_links:"src, name",revision_parents:"child, parent",canvas_meta:"key",runtime_state:"key",message_causes:"message_id",peer_ingested:"key",peer_ingested_destinations:"key",message_sequence:"id",messages:"seq",review_comment_events:"seq",audit_rows:"id",peer_outbox:"id",app_users:"uid"},ie={objects:"id",revisions:"rev_id",watches:"watch_id"},H=new Set(["daemon_owner","schema_version","schema_min_reader","ledger_migrated",te,F]);function ce(i){const a=J(A(Q(),"crtr-export-")),s=process.env.CRTR_HOME;process.env.CRTR_HOME=a,D(A(a,"runtime","nodes"),{recursive:!0});try{const r=new W(i);return r.exec("PRAGMA journal_mode = DELETE;"),r.exec("PRAGMA foreign_keys = ON;"),z(r),r.exec("DELETE FROM canvas_meta; DELETE FROM message_sequence;"),r}finally{s===void 0?delete process.env.CRTR_HOME:process.env.CRTR_HOME=s,P(a,{recursive:!0,force:!0})}}w(ce,"createEmptyDatabase");async function Re(i,a=()=>{}){const s=Z();if(Y(s))throw new Error(`${s} already exists; refusing to overwrite it`);D(A(s,".."),{recursive:!0,mode:448});const r=`${s}.exporting-${process.pid}`,p=Date.now(),t=new j.Client({connectionString:i,application_name:`crtr-export-${process.pid}`,options:ee(),types:{getTypeParser:w(((d,o)=>d===20?f=>Number(f):j.types.getTypeParser(d,o)),"getTypeParser")}});await t.connect();let m;try{if((await t.query("SELECT value FROM canvas_meta WHERE key = 'schema_version'").catch(()=>({rows:[]}))).rows.length===0)throw new Error("the Postgres database has no canvas schema; nothing to export");m=ce(r);const o=m;o.exec("PRAGMA foreign_keys = OFF;");const f=await se(t),L=[...f.keys()].filter(e=>!oe.has(e)&&!C.includes(e));if(L.length>0)throw new Error(`export: Postgres tables with no export rule: ${L.join(", ")}`);await t.query("BEGIN READ ONLY ISOLATION LEVEL REPEATABLE READ");const E={};for(const[e,S]of Object.entries(ie)){const h=new Map;for(const _ of(await t.query(`SELECT ${S} AS id, seq FROM ${e}`)).rows)h.set(_.id,Number(_.seq));E[e]=h}const B=E.objects;let M=0;o.exec("BEGIN");for(const e of C){const S=Date.now(),h=new Set(o.prepare(`PRAGMA table_info(${c(e)})`).all().map(n=>n.name)),_=f.get(e);if(_===void 0)throw new Error(`export: Postgres has no table ${e}`);const G=_.some(n=>n.name==="seq"),O=_.filter(n=>h.has(n.name)),K=new Set(ne[e]??[]),g=e==="objects"||e==="revisions"||e==="watches"||e==="watch_subscriptions",$=O.map(n=>n.type==="jsonb"?`${c(n.name)}::text AS ${c(n.name)}`:c(n.name));e==="watches"&&$.push("watch_id AS _watch_id"),g&&$.push("seq AS _seq");const R=O.map(n=>c(n.name)),U=o.prepare(`INSERT INTO ${c(e)} (${g?["rowid",...R]:R}) VALUES (${(g?["?",...R]:R).map(()=>"?").join(", ")})`),q=G?"seq":ae[e],b=`export_${e}`;await t.query(`DECLARE ${b} NO SCROLL CURSOR FOR SELECT ${$.join(", ")} FROM ${c(e)}${e==="canvas_meta"?` WHERE key NOT IN (${[...H].map(n=>`'${n}'`).join(", ")})`:""}${q===void 0?"":` ORDER BY ${q}`}`);let T=0;for(;;){const n=await t.query(`FETCH ${re} FROM ${b}`);if(n.rows.length===0)break;for(const k of n.rows){const N=g?[Number(k._seq)]:[];for(const u of O){let l=k[u.name];e==="revision_parents"&&(u.name==="child"||u.name==="parent")?l=x(E.revisions,"revision",e,u.name,l):e==="watch_subscriptions"&&u.name==="watch"?l=x(E.watches,"watch",e,u.name,l):K.has(u.name)&&(l=x(B,"object",e,u.name,l)),N.push(l??null)}U.run(...N)}T+=n.rows.length}await t.query(`CLOSE ${b}`),M+=T,a(`export ${e}: ${T} rows in ${Date.now()-S} ms`)}o.exec("COMMIT"),await t.query("COMMIT");const v=o.prepare("PRAGMA foreign_key_check").all();if(v.length>0)throw new Error(`export: ${v.length} foreign key violation(s) in the exported canvas.db, first: ${JSON.stringify(v[0])}`);await pe(t,o);const y=o.prepare("PRAGMA user_version").get().user_version;if(y!==I.length)throw new Error(`export: exported canvas.db is at user_version ${y}, expected ${I.length}`);return o.close(),m=void 0,await t.query("INSERT INTO canvas_meta (key, value) VALUES ($1, $2) ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value",[F,JSON.stringify({at:new Date().toISOString(),path:s})]),X(r,s),{path:s,rows:M,ms:Date.now()-p,userVersion:y}}catch(d){await t.query("ROLLBACK").catch(()=>{});try{m?.close()}catch{}for(const o of["","-wal","-shm","-journal"])P(`${r}${o}`,{force:!0});throw d}finally{await t.end().catch(()=>{})}}w(Re,"exportPostgresToSqlite");function x(i,a,s,r,p){if(p==null)return null;const t=i.get(p);if(t===void 0)throw new Error(`export: ${s}.${r} references ${a} ${String(p)}, which was not exported (`);return t}w(x,"mapId");async function pe(i,a){const s=[];for(const r of C){const p=Number((await i.query(`SELECT count(*) AS n FROM ${c(r)}`)).rows[0].n);let t=Number(a.prepare(`SELECT count(*) AS n FROM ${c(r)}`).get().n),m=p;r==="canvas_meta"&&(m=Number((await i.query("SELECT count(*) AS n FROM canvas_meta WHERE key <> ALL($1)",[[...H]])).rows[0].n),t=Number(a.prepare("SELECT count(*) AS n FROM canvas_meta").get().n)),m!==t&&s.push(`${r}: Postgres ${m} rows, SQLite ${t}`)}if(s.length>0)throw new Error(`Postgres \u2192 SQLite export verification failed:
1
+ var V=Object.defineProperty;var w=(i,a)=>V(i,"name",{value:a,configurable:!0});import{DatabaseSync as W}from"node:sqlite";import{existsSync as Y,mkdirSync as D,mkdtempSync as J,renameSync as X,rmSync as P}from"node:fs";import{tmpdir as Q}from"node:os";import{join as A}from"node:path";import j from"pg";import{migrate as z,MIGRATIONS as I}from"./migrations.js";import{canvasDbPath as Z}from"./paths.js";import{canvasSearchPathOptions as ee}from"./schema-version.js";import{EXPORT_MARK_KEY as F,IMPORT_MARK_KEY as te,OBJECT_COLUMNS as ne,pgColumns as se,quote as m,TABLE_ORDER as C}from"./import-sqlite.js";const oe=5e3,re=new Set(["environments","relations","schemas","charges","charge_totals","limits","viewer_attachments","reconciler_leases","environment_repos","conversation_entries","conversation_parts","charge_chunks","profiles","profile_projects","profile_defaults","scope_settings","scope_bookkeeping","scope_marketplaces","scope_plugins","person_settings","model_accounts","model_account_cooldowns","model_api_keys","model_settings","model_sign_in_flows","env_vars","usage","grantee_usage","provider_receipts"]),ae={exposures:"node, object, channel",rules:"object, position",edges:"type, src, dst",unresolved_links:"src, name",revision_parents:"child, parent",canvas_meta:"key",runtime_state:"key",message_causes:"message_id",peer_ingested:"key",peer_ingested_destinations:"key",message_sequence:"id",messages:"seq",review_comment_events:"seq",audit_rows:"id",peer_outbox:"id",app_users:"uid"},ie={objects:"id",revisions:"rev_id",watches:"watch_id"},H=new Set(["daemon_owner","schema_version","schema_min_reader","ledger_migrated",te,F]);function ce(i){const a=J(A(Q(),"crtr-export-")),s=process.env.CRTR_HOME;process.env.CRTR_HOME=a,D(A(a,"runtime","nodes"),{recursive:!0});try{const o=new W(i);return o.exec("PRAGMA journal_mode = DELETE;"),o.exec("PRAGMA foreign_keys = ON;"),z(o),o.exec("DELETE FROM canvas_meta; DELETE FROM message_sequence;"),o}finally{s===void 0?delete process.env.CRTR_HOME:process.env.CRTR_HOME=s,P(a,{recursive:!0,force:!0})}}w(ce,"createEmptyDatabase");async function Re(i,a=()=>{}){const s=Z();if(Y(s))throw new Error(`${s} already exists; refusing to overwrite it`);D(A(s,".."),{recursive:!0,mode:448});const o=`${s}.exporting-${process.pid}`,u=Date.now(),t=new j.Client({connectionString:i,application_name:`crtr-export-${process.pid}`,options:ee(),types:{getTypeParser:w(((d,r)=>d===20?f=>Number(f):j.types.getTypeParser(d,r)),"getTypeParser")}});await t.connect();let l;try{if((await t.query("SELECT value FROM canvas_meta WHERE key = 'schema_version'").catch(()=>({rows:[]}))).rows.length===0)throw new Error("the Postgres database has no canvas schema; nothing to export");l=ce(o);const r=l;r.exec("PRAGMA foreign_keys = OFF;");const f=await se(t),L=[...f.keys()].filter(e=>!re.has(e)&&!C.includes(e));if(L.length>0)throw new Error(`export: Postgres tables with no export rule: ${L.join(", ")}`);await t.query("BEGIN READ ONLY ISOLATION LEVEL REPEATABLE READ");const E={};for(const[e,S]of Object.entries(ie)){const h=new Map;for(const _ of(await t.query(`SELECT ${S} AS id, seq FROM ${e}`)).rows)h.set(_.id,Number(_.seq));E[e]=h}const B=E.objects;let M=0;r.exec("BEGIN");for(const e of C){const S=Date.now(),h=new Set(r.prepare(`PRAGMA table_info(${m(e)})`).all().map(n=>n.name)),_=f.get(e);if(_===void 0)throw new Error(`export: Postgres has no table ${e}`);const G=_.some(n=>n.name==="seq"),O=_.filter(n=>h.has(n.name)),K=new Set(ne[e]??[]),g=e==="objects"||e==="revisions"||e==="watches"||e==="watch_subscriptions",$=O.map(n=>n.type==="jsonb"?`${m(n.name)}::text AS ${m(n.name)}`:m(n.name));e==="watches"&&$.push("watch_id AS _watch_id"),g&&$.push("seq AS _seq");const R=O.map(n=>m(n.name)),U=r.prepare(`INSERT INTO ${m(e)} (${g?["rowid",...R]:R}) VALUES (${(g?["?",...R]:R).map(()=>"?").join(", ")})`),q=G?"seq":ae[e],b=`export_${e}`;await t.query(`DECLARE ${b} NO SCROLL CURSOR FOR SELECT ${$.join(", ")} FROM ${m(e)}${e==="canvas_meta"?` WHERE key NOT IN (${[...H].map(n=>`'${n}'`).join(", ")})`:""}${q===void 0?"":` ORDER BY ${q}`}`);let T=0;for(;;){const n=await t.query(`FETCH ${oe} FROM ${b}`);if(n.rows.length===0)break;for(const k of n.rows){const N=g?[Number(k._seq)]:[];for(const c of O){let p=k[c.name];e==="revision_parents"&&(c.name==="child"||c.name==="parent")?p=x(E.revisions,"revision",e,c.name,p):e==="watch_subscriptions"&&c.name==="watch"?p=x(E.watches,"watch",e,c.name,p):K.has(c.name)?p=x(B,"object",e,c.name,p):e==="jobs"&&(c.name==="job_dir"||c.name==="log_path")&&(p=p??""),N.push(p??null)}U.run(...N)}T+=n.rows.length}await t.query(`CLOSE ${b}`),M+=T,a(`export ${e}: ${T} rows in ${Date.now()-S} ms`)}r.exec("COMMIT"),await t.query("COMMIT");const v=r.prepare("PRAGMA foreign_key_check").all();if(v.length>0)throw new Error(`export: ${v.length} foreign key violation(s) in the exported canvas.db, first: ${JSON.stringify(v[0])}`);await pe(t,r);const y=r.prepare("PRAGMA user_version").get().user_version;if(y!==I.length)throw new Error(`export: exported canvas.db is at user_version ${y}, expected ${I.length}`);return r.close(),l=void 0,await t.query("INSERT INTO canvas_meta (key, value) VALUES ($1, $2) ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value",[F,JSON.stringify({at:new Date().toISOString(),path:s})]),X(o,s),{path:s,rows:M,ms:Date.now()-u,userVersion:y}}catch(d){await t.query("ROLLBACK").catch(()=>{});try{l?.close()}catch{}for(const r of["","-wal","-shm","-journal"])P(`${o}${r}`,{force:!0});throw d}finally{await t.end().catch(()=>{})}}w(Re,"exportPostgresToSqlite");function x(i,a,s,o,u){if(u==null)return null;const t=i.get(u);if(t===void 0)throw new Error(`export: ${s}.${o} references ${a} ${String(u)}, which was not exported (`);return t}w(x,"mapId");async function pe(i,a){const s=[];for(const o of C){const u=Number((await i.query(`SELECT count(*) AS n FROM ${m(o)}`)).rows[0].n);let t=Number(a.prepare(`SELECT count(*) AS n FROM ${m(o)}`).get().n),l=u;o==="canvas_meta"&&(l=Number((await i.query("SELECT count(*) AS n FROM canvas_meta WHERE key <> ALL($1)",[[...H]])).rows[0].n),t=Number(a.prepare("SELECT count(*) AS n FROM canvas_meta").get().n)),l!==t&&s.push(`${o}: Postgres ${l} rows, SQLite ${t}`)}if(s.length>0)throw new Error(`Postgres \u2192 SQLite export verification failed:
2
2
  ${s.join(`
3
3
  `)}`)}w(pe,"verify");export{Re as exportPostgresToSqlite};
@@ -11,8 +11,12 @@ export declare function setFocusOccupant(focus_id: string, node_id: string): Pro
11
11
  export declare function setFocusPane(focus_id: string, pane: string | null, session: string | null): Promise<void>;
12
12
  /** DELETE a viewport. */
13
13
  export declare function closeFocusRow(focus_id: string): Promise<void>;
14
+ /** DELETE a viewport only while it still sits on `pane`: a row re-pointed to another pane since `pane` was probed is kept. */
15
+ export declare function closeFocusRowOnPane(focus_id: string, pane: string): Promise<boolean>;
14
16
  /** The focus a node occupies (≤1, UNIQUE node_id), or null. */
15
17
  export declare function getFocusByNode(node_id: string): Promise<FocusRow | null>;
18
+ /** {@link getFocusByNode} taking the row's lock: call inside `withCanvasWrite`, where a concurrent re-point or close of the row waits for the commit. */
19
+ export declare function getFocusByNodeForUpdate(node_id: string): Promise<FocusRow | null>;
16
20
  /** The focus realized by a given pane (`%id`), or null. */
17
21
  export declare function getFocusByPane(pane: string): Promise<FocusRow | null>;
18
22
  /** A focus by its stable id, or null. Used by placement to read a row back by id
@@ -1 +1 @@
1
- var c=Object.defineProperty;var n=(e,o)=>c(e,"name",{value:o,configurable:!0});import{openDb as s}from"./db.js";function a(e){return{focus_id:e.focus_id,pane:e.pane??null,session:e.session??null,node_id:e.node_id}}n(a,"focusFrom");async function p(e,o,t,u){await(await s()).prepare("INSERT INTO focuses (focus_id, pane, session, node_id) VALUES (?, ?, ?, ?)").run(e,o,t,u)}n(p,"openFocusRow");async function E(e,o){await(await s()).prepare("UPDATE focuses SET node_id = ? WHERE focus_id = ?").run(o,e)}n(E,"setFocusOccupant");async function f(e,o,t){await(await s()).prepare("UPDATE focuses SET pane = ?, session = ? WHERE focus_id = ?").run(o,t,e)}n(f,"setFocusPane");async function d(e){await(await s()).prepare("DELETE FROM focuses WHERE focus_id = ?").run(e)}n(d,"closeFocusRow");async function w(e){const o=await(await s()).prepare("SELECT * FROM focuses WHERE node_id = ?").get(e);return o?a(o):null}n(w,"getFocusByNode");async function R(e){const o=await(await s()).prepare("SELECT * FROM focuses WHERE pane = ?").get(e);return o?a(o):null}n(R,"getFocusByPane");async function l(e){const o=await(await s()).prepare("SELECT * FROM focuses WHERE focus_id = ?").get(e);return o?a(o):null}n(l,"getFocusById");async function F(){return(await(await s()).prepare("SELECT * FROM focuses ORDER BY focus_id").all()).map(a)}n(F,"listFocuses");export{d as closeFocusRow,l as getFocusById,w as getFocusByNode,R as getFocusByPane,F as listFocuses,p as openFocusRow,E as setFocusOccupant,f as setFocusPane};
1
+ var u=Object.defineProperty;var o=(e,n)=>u(e,"name",{value:n,configurable:!0});import{openDb as a}from"./db.js";function s(e){return{focus_id:e.focus_id,pane:e.pane??null,session:e.session??null,node_id:e.node_id}}o(s,"focusFrom");async function p(e,n,t,c){await(await a()).prepare("INSERT INTO focuses (focus_id, pane, session, node_id) VALUES (?, ?, ?, ?)").run(e,n,t,c)}o(p,"openFocusRow");async function E(e,n){await(await a()).prepare("UPDATE focuses SET node_id = ? WHERE focus_id = ?").run(n,e)}o(E,"setFocusOccupant");async function f(e,n,t){await(await a()).prepare("UPDATE focuses SET pane = ?, session = ? WHERE focus_id = ?").run(n,t,e)}o(f,"setFocusPane");async function d(e){await(await a()).prepare("DELETE FROM focuses WHERE focus_id = ?").run(e)}o(d,"closeFocusRow");async function w(e,n){return(await(await a()).prepare("DELETE FROM focuses WHERE focus_id = ? AND pane = ?").run(e,n)).changes>0}o(w,"closeFocusRowOnPane");async function R(e){const n=await(await a()).prepare("SELECT * FROM focuses WHERE node_id = ?").get(e);return n?s(n):null}o(R,"getFocusByNode");async function F(e){const n=await(await a()).prepare("SELECT * FROM focuses WHERE node_id = ? FOR UPDATE").get(e);return n?s(n):null}o(F,"getFocusByNodeForUpdate");async function l(e){const n=await(await a()).prepare("SELECT * FROM focuses WHERE pane = ?").get(e);return n?s(n):null}o(l,"getFocusByPane");async function _(e){const n=await(await a()).prepare("SELECT * FROM focuses WHERE focus_id = ?").get(e);return n?s(n):null}o(_,"getFocusById");async function y(){return(await(await a()).prepare("SELECT * FROM focuses ORDER BY focus_id").all()).map(s)}o(y,"listFocuses");export{d as closeFocusRow,w as closeFocusRowOnPane,_ as getFocusById,R as getFocusByNode,F as getFocusByNodeForUpdate,l as getFocusByPane,y as listFocuses,p as openFocusRow,E as setFocusOccupant,f as setFocusPane};
@@ -1,14 +1,14 @@
1
- var S=Object.defineProperty;var a=(n,s)=>S(n,"name",{value:s,configurable:!0});import{envNodeId as M}from"../../shared/env.js";import{getNode as p,listNodes as v,view as j}from"./canvas.js";import{openDb as E}from"./db.js";import{readTextIfExists as O}from"../fs-utils.js";import{conversationIdFromPath as y,conversationStore as g,ConversationNotFoundError as I}from"../conversation-store/index.js";import{reportBodyByName as C}from"../feed/reports.js";import{readStamps as A}from"../runtime/stamp/protocol.js";import{forEachAsync as B}from"../async-array.js";const nn=["human","inbox","wake","revive","restart-continuation","stop-guard","park","recovery","context-nudge","kickoff","unknown"],en=["user","assistant","toolResult"];async function R(){const n=M();if(n!==void 0&&n!==""){const s=await p(n);if(s!==null)return s.cwd}return process.cwd()}a(R,"callerCwd");function x(n){const s=Date.parse(n);return Number.isNaN(s)?0:s}a(x,"toMs");async function k(n){return(await(await E()).prepare(`SELECT m.created_at, m.sender_node_id, d.urgency, m.kind, m.label, m.body_ref, m.body_json
1
+ var S=Object.defineProperty;var d=(n,s)=>S(n,"name",{value:s,configurable:!0});import{envNodeId as M}from"../../shared/env.js";import{getNode as p,listNodes as j,view as v}from"./canvas.js";import{openDb as E}from"./db.js";import{readTextIfExists as O}from"../fs-utils.js";import{conversationIdFromPath as y,conversationStore as g,ConversationNotFoundError as I}from"../conversation-store/index.js";import{reportBodyByName as C}from"../feed/reports.js";import{readStamps as A}from"../runtime/stamp/protocol.js";import{forEachAsync as B}from"../async-array.js";const nn=["human","inbox","wake","revive","restart-continuation","stop-guard","park","recovery","context-nudge","kickoff","unknown"],en=["user","assistant","toolResult"];async function R(){const n=M();if(n!==void 0&&n!==""){const s=await p(n);if(s!==null)return s.cwd}return process.cwd()}d(R,"callerCwd");function x(n){const s=Date.parse(n);return Number.isNaN(s)?0:s}d(x,"toMs");async function k(n){return(await(await E()).prepare(`SELECT m.created_at, m.sender_node_id, d.urgency, m.kind, m.label, m.body_ref, m.body_json
2
2
  FROM deliveries d JOIN messages m ON m.message_id = d.message_id
3
3
  WHERE d.destination_id = ? AND d.wake = 1
4
- ORDER BY m.seq, d.created_at, d.delivery_id`).all(n)).map(e=>({ts:e.created_at,from:e.sender_node_id,tier:e.urgency,kind:e.kind,label:e.label,ref:e.body_ref,data:e.body_json===null?null:JSON.parse(e.body_json)}))}a(k,"allInboxEntries");async function _(n){const s=[`from: ${n.from??"system"}`,`tier: ${n.tier}`].join(`
5
- `),e=`[${n.kind}] ${n.label}`,t=typeof n.data=="object"&&n.data!==null&&!Array.isArray(n.data)?n.data.body:void 0,i=typeof t=="string"?t.trim():"",o=typeof t=="string",r=n.ref!==null?o?O(n.ref)??"":await C(n.ref)??"":i,c=r!==""&&r!==n.label,f=[s,e];return n.ref!==null&&f.push(`ref: ${n.ref}`),c&&f.push(r),f.join(`
4
+ ORDER BY m.seq, d.created_at, d.delivery_id`).all(n)).map(e=>({ts:e.created_at,from:e.sender_node_id,tier:e.urgency,kind:e.kind,label:e.label,ref:e.body_ref,data:e.body_json===null?null:JSON.parse(e.body_json)}))}d(k,"allInboxEntries");async function _(n){const s=[`from: ${n.from??"system"}`,`tier: ${n.tier}`].join(`
5
+ `),e=`[${n.kind}] ${n.label}`,t=typeof n.data=="object"&&n.data!==null&&!Array.isArray(n.data)?n.data.body:void 0,i=typeof t=="string"?t.trim():"",o=typeof t=="string",r=typeof n.data=="object"&&n.data!==null&&!Array.isArray(n.data)?n.data.body_full:void 0,c=n.ref!==null?o?typeof r=="string"?r:O(n.ref)??"":await C(n.ref)??"":i,u=c!==""&&c!==n.label,a=[s,e];return n.ref!==null&&a.push(`ref: ${n.ref}`),u&&a.push(c),a.join(`
6
6
 
7
- `)}a(_,"inboxEntryBody");async function D(n,s,e,t){const i=`inbox/${String(t).padStart(6,"0")}`,o=await _(e),r={ref:`${n.node_id}:${i}`,nodeId:n.node_id,relpath:i,source:"inbox",ts:e.ts,tsMs:x(e.ts),title:`[${e.kind}] from ${e.from??"system"}: ${e.label}`,nodeName:n.name,nodeKind:n.kind,nodeStatus:n.status,nodeCwd:n.cwd,nodeDesc:s,loadBody:a(()=>o,"loadBody"),origin:"inbox"};return typeof e.from=="string"&&e.from!==""&&(r.from=e.from),r}a(D,"inboxArtifact");async function N(n){const s=(await p(n))?.pi_session_file,e=typeof s=="string"?y(s):null;if(e===null)return null;try{return(await g().header(e)).path}catch(t){if(t instanceof I)return null;throw t}}a(N,"resolveSessionFile");function T(n){if(typeof n=="string")return n;if(!Array.isArray(n))return"";const s=[];for(const e of n){if(e===null||typeof e!="object")continue;const t=e;t.type==="text"&&typeof t.text=="string"?s.push(t.text):t.type==="toolCall"&&s.push(`Tool: ${typeof t.name=="string"?t.name:"call"}`)}return s.join(`
8
- `)}a(T,"textFromBlocks");function F(n){return n==null?"unknown":n.type==="human"?"human":n.kind}a(F,"originToken");function L(n){if(n==null||n.type!=="runtime")return;const s=n.entries;if(s===void 0||s.length===0)return;const e=new Set;for(const t of s){const i=t.fromName??t.from;typeof i=="string"&&i!==""&&e.add(i)}return e.size===0?void 0:[...e].join(", ")}a(L,"sendersOf");async function $(n){const s=await N(n);if(s===null)return[];const e=(await g().read(y(s))).entries,t=new Map;for(const o of A(e)){if(o.kind!=="message")continue;const r=o.payload;typeof r.msgTs=="number"&&t.set(r.msgTs,r.origin)}const i=[];for(const o of e){if(o===null||typeof o!="object")continue;const r=o;if(r.type!=="message")continue;const c=r.message;if(c===null||typeof c!="object")continue;const f=c,d=typeof f.role=="string"?f.role:"";if(d==="")continue;const u=typeof f.timestamp=="number"?f.timestamp:void 0,l=typeof r.timestamp=="string"?r.timestamp:u!==void 0?new Date(u).toISOString():"",m=T(f.content),w={index:i.length,role:d,text:m,ts:l,tsMs:u??x(l)};if(d==="user"){const b=u!==void 0&&t.has(u)?t.get(u):null;w.origin=F(b);const h=L(b);h!==void 0&&(w.from=h)}i.push(w)}return i}a($,"sessionMessages");async function J(n,s){const e=(await g().read(y(n))).entries;let t=0;for(const i of e){if(i.type!=="message")continue;const o=i.message;if(!(o===null||typeof o!="object"||typeof o.role!="string")){if(t===s)return JSON.stringify(i);t++}}return null}a(J,"rawSessionLine");function K(n,s,e){const t=`session/${String(e.index).padStart(6,"0")}`,i=e.text.split(`
9
- `).map(r=>r.trim()).find(r=>r!=="")??"",o={ref:`${n.node_id}:${t}`,nodeId:n.node_id,relpath:t,source:"transcript",ts:e.ts,tsMs:e.tsMs,title:`[${e.role}] ${i.length>80?`${i.slice(0,80)}\u2026`:i}`,nodeName:n.name,nodeKind:n.kind,nodeStatus:n.status,nodeCwd:n.cwd,nodeDesc:s,loadBody:a(()=>e.text,"loadBody"),role:e.role};return e.origin!==void 0&&(o.origin=e.origin),e.from!==void 0&&(o.from=e.from),o}a(K,"transcriptArtifact");async function W(n){return(await p(n))?.description??""}a(W,"nodeDescOf");async function tn(n,s){const e=await P(n),t=s.kinds,i=s.statuses,o=e.filter(d=>!(t!==void 0&&t.length>0&&!t.includes(d.kind)||i!==void 0&&i.length>0&&!i.includes(d.status))),r=s.types!==void 0&&s.types.length>0?s.types:["inbox"],c=new Set(r),f=[];for(const d of o){const u=await W(d.node_id);if(c.has("inbox")&&await B(await k(d.node_id),async(l,m)=>f.push(await D(d,u,l,m))),c.has("transcript"))for(const l of await $(d.node_id))f.push(K(d,u,l))}return f.filter(d=>s.sinceMs!==void 0&&d.tsMs<s.sinceMs||s.untilMs!==void 0&&d.tsMs>s.untilMs?!1:G(d,s))}a(tn,"buildCorpus");function G(n,s){const{origins:e,roles:t,from:i}=s;return!(e!==void 0&&e.length>0&&(n.origin===void 0||!e.includes(n.origin))||t!==void 0&&t.length>0&&(n.role===void 0||!t.includes(n.role))||i!==void 0&&i!==""&&(n.from===void 0||!n.from.toLowerCase().includes(i.toLowerCase())))}a(G,"matchesMessageFilters");function sn(n,s){const e=new Map;for(const t of n){let i;switch(s){case"origin":i=t.origin;break;case"role":i=t.role;break;case"node":i=`${t.nodeName} (${t.nodeId})`;break;case"kind":i=t.nodeKind;break;case"type":i=t.source;break;case"day":i=t.ts.slice(0,10)||void 0;break}i===void 0||i===""||e.set(i,(e.get(i)??0)+1)}return[...e.entries()].map(([t,i])=>({key:t,count:i})).sort((t,i)=>i.count-t.count||t.key.localeCompare(i.key))}a(sn,"groupCorpus");async function P(n){const s=await v(),e=new Map(s.map(i=>[i.node_id,i]));if(n.nodes!==void 0&&n.nodes.length>0)return n.nodes.map(i=>e.get(i)).filter(i=>i!==void 0);if(n.under!==void 0&&n.under!=="")return[n.under,...await j(n.under)].map(o=>e.get(o)).filter(o=>o!==void 0);if(n.allCwds===!0)return s;const t=n.cwd!==void 0&&n.cwd!==""?n.cwd:await R();return s.filter(i=>i.cwd===t)}a(P,"scopedRows");async function on(n){const s=n.indexOf(":");if(s===-1)return null;const e=n.slice(0,s),t=n.slice(s+1),i=await p(e);if(i===null)return null;if(t.startsWith("inbox/")){const o=Number(t.slice(6)),r=(await k(e))[o];return r===void 0?null:{nodeId:e,relpath:t,source:"inbox",ts:r.ts,nodeName:i.name,body:await _(r),raw:null,path:null}}if(t==="session"||t.startsWith("session/")){const o=await N(e);if(o===null)return null;const r=await $(e);if(t==="session"){const d=r.map(u=>`## ${u.role}${u.origin!==void 0?` (origin: ${u.origin})`:""}
7
+ `)}d(_,"inboxEntryBody");async function D(n,s,e,t){const i=`inbox/${String(t).padStart(6,"0")}`,o=await _(e),r={ref:`${n.node_id}:${i}`,nodeId:n.node_id,relpath:i,source:"inbox",ts:e.ts,tsMs:x(e.ts),title:`[${e.kind}] from ${e.from??"system"}: ${e.label}`,nodeName:n.name,nodeKind:n.kind,nodeStatus:n.status,nodeCwd:n.cwd,nodeDesc:s,loadBody:d(()=>o,"loadBody"),origin:"inbox"};return typeof e.from=="string"&&e.from!==""&&(r.from=e.from),r}d(D,"inboxArtifact");async function N(n){const s=(await p(n))?.pi_session_file,e=typeof s=="string"?y(s):null;if(e===null)return null;try{return(await g().header(e)).path}catch(t){if(t instanceof I)return null;throw t}}d(N,"resolveSessionFile");function T(n){if(typeof n=="string")return n;if(!Array.isArray(n))return"";const s=[];for(const e of n){if(e===null||typeof e!="object")continue;const t=e;t.type==="text"&&typeof t.text=="string"?s.push(t.text):t.type==="toolCall"&&s.push(`Tool: ${typeof t.name=="string"?t.name:"call"}`)}return s.join(`
8
+ `)}d(T,"textFromBlocks");function F(n){return n==null?"unknown":n.type==="human"?"human":n.kind}d(F,"originToken");function L(n){if(n==null||n.type!=="runtime")return;const s=n.entries;if(s===void 0||s.length===0)return;const e=new Set;for(const t of s){const i=t.fromName??t.from;typeof i=="string"&&i!==""&&e.add(i)}return e.size===0?void 0:[...e].join(", ")}d(L,"sendersOf");async function $(n){const s=await N(n);if(s===null)return[];const e=(await g().read(y(s))).entries,t=new Map;for(const o of A(e)){if(o.kind!=="message")continue;const r=o.payload;typeof r.msgTs=="number"&&t.set(r.msgTs,r.origin)}const i=[];for(const o of e){if(o===null||typeof o!="object")continue;const r=o;if(r.type!=="message")continue;const c=r.message;if(c===null||typeof c!="object")continue;const u=c,a=typeof u.role=="string"?u.role:"";if(a==="")continue;const f=typeof u.timestamp=="number"?u.timestamp:void 0,l=typeof r.timestamp=="string"?r.timestamp:f!==void 0?new Date(f).toISOString():"",m=T(u.content),b={index:i.length,role:a,text:m,ts:l,tsMs:f??x(l)};if(a==="user"){const w=f!==void 0&&t.has(f)?t.get(f):null;b.origin=F(w);const h=L(w);h!==void 0&&(b.from=h)}i.push(b)}return i}d($,"sessionMessages");async function J(n,s){const e=(await g().read(y(n))).entries;let t=0;for(const i of e){if(i.type!=="message")continue;const o=i.message;if(!(o===null||typeof o!="object"||typeof o.role!="string")){if(t===s)return JSON.stringify(i);t++}}return null}d(J,"rawSessionLine");function K(n,s,e){const t=`session/${String(e.index).padStart(6,"0")}`,i=e.text.split(`
9
+ `).map(r=>r.trim()).find(r=>r!=="")??"",o={ref:`${n.node_id}:${t}`,nodeId:n.node_id,relpath:t,source:"transcript",ts:e.ts,tsMs:e.tsMs,title:`[${e.role}] ${i.length>80?`${i.slice(0,80)}\u2026`:i}`,nodeName:n.name,nodeKind:n.kind,nodeStatus:n.status,nodeCwd:n.cwd,nodeDesc:s,loadBody:d(()=>e.text,"loadBody"),role:e.role};return e.origin!==void 0&&(o.origin=e.origin),e.from!==void 0&&(o.from=e.from),o}d(K,"transcriptArtifact");async function W(n){return(await p(n))?.description??""}d(W,"nodeDescOf");async function tn(n,s){const e=await P(n),t=s.kinds,i=s.statuses,o=e.filter(a=>!(t!==void 0&&t.length>0&&!t.includes(a.kind)||i!==void 0&&i.length>0&&!i.includes(a.status))),r=s.types!==void 0&&s.types.length>0?s.types:["inbox"],c=new Set(r),u=[];for(const a of o){const f=await W(a.node_id);if(c.has("inbox")&&await B(await k(a.node_id),async(l,m)=>u.push(await D(a,f,l,m))),c.has("transcript"))for(const l of await $(a.node_id))u.push(K(a,f,l))}return u.filter(a=>s.sinceMs!==void 0&&a.tsMs<s.sinceMs||s.untilMs!==void 0&&a.tsMs>s.untilMs?!1:G(a,s))}d(tn,"buildCorpus");function G(n,s){const{origins:e,roles:t,from:i}=s;return!(e!==void 0&&e.length>0&&(n.origin===void 0||!e.includes(n.origin))||t!==void 0&&t.length>0&&(n.role===void 0||!t.includes(n.role))||i!==void 0&&i!==""&&(n.from===void 0||!n.from.toLowerCase().includes(i.toLowerCase())))}d(G,"matchesMessageFilters");function sn(n,s){const e=new Map;for(const t of n){let i;switch(s){case"origin":i=t.origin;break;case"role":i=t.role;break;case"node":i=`${t.nodeName} (${t.nodeId})`;break;case"kind":i=t.nodeKind;break;case"type":i=t.source;break;case"day":i=t.ts.slice(0,10)||void 0;break}i===void 0||i===""||e.set(i,(e.get(i)??0)+1)}return[...e.entries()].map(([t,i])=>({key:t,count:i})).sort((t,i)=>i.count-t.count||t.key.localeCompare(i.key))}d(sn,"groupCorpus");async function P(n){const s=await j(),e=new Map(s.map(i=>[i.node_id,i]));if(n.nodes!==void 0&&n.nodes.length>0)return n.nodes.map(i=>e.get(i)).filter(i=>i!==void 0);if(n.under!==void 0&&n.under!=="")return[n.under,...await v(n.under)].map(o=>e.get(o)).filter(o=>o!==void 0);if(n.allCwds===!0)return s;const t=n.cwd!==void 0&&n.cwd!==""?n.cwd:await R();return s.filter(i=>i.cwd===t)}d(P,"scopedRows");async function on(n){const s=n.indexOf(":");if(s===-1)return null;const e=n.slice(0,s),t=n.slice(s+1),i=await p(e);if(i===null)return null;if(t.startsWith("inbox/")){const o=Number(t.slice(6)),r=(await k(e))[o];return r===void 0?null:{nodeId:e,relpath:t,source:"inbox",ts:r.ts,nodeName:i.name,body:await _(r),raw:null,path:null}}if(t==="session"||t.startsWith("session/")){const o=await N(e);if(o===null)return null;const r=await $(e);if(t==="session"){const a=r.map(f=>`## ${f.role}${f.origin!==void 0?` (origin: ${f.origin})`:""}
10
10
 
11
- ${u.text}`).join(`
11
+ ${f.text}`).join(`
12
12
 
13
- `);return{nodeId:e,relpath:t,source:"transcript",ts:r[r.length-1]?.ts??i.created,nodeName:i.name,body:d,raw:await(async()=>{const{header:u,entries:l}=await g().read(y(o));return[u,...l].map(m=>`${JSON.stringify(m)}
14
- `).join("")})(),path:o}}const c=Number(t.slice(8)),f=r[c];return f===void 0?null:{nodeId:e,relpath:t,source:"transcript",ts:f.ts,nodeName:i.name,body:f.text,raw:await J(o,c),path:o}}return null}a(on,"resolveRef");export{en as MESSAGE_ROLES,nn as ORIGIN_TOKENS,tn as buildCorpus,R as callerCwd,sn as groupCorpus,on as resolveRef};
13
+ `);return{nodeId:e,relpath:t,source:"transcript",ts:r[r.length-1]?.ts??i.created,nodeName:i.name,body:a,raw:await(async()=>{const{header:f,entries:l}=await g().read(y(o));return[f,...l].map(m=>`${JSON.stringify(m)}
14
+ `).join("")})(),path:o}}const c=Number(t.slice(8)),u=r[c];return u===void 0?null:{nodeId:e,relpath:t,source:"transcript",ts:u.ts,nodeName:i.name,body:u.text,raw:await J(o,c),path:o}}return null}d(on,"resolveRef");export{en as MESSAGE_ROLES,nn as ORIGIN_TOKENS,tn as buildCorpus,R as callerCwd,sn as groupCorpus,on as resolveRef};
@@ -1,4 +1,5 @@
1
- /** Find only terminal nodes with an unreconciled, explicitly disposable worktree.
1
+ /** Find only terminal nodes with an unreconciled, explicitly disposable worktree. A node that ever ran in a Blaxel sandbox
2
+ * is never a candidate: its sandbox is its worktree and the control plane has no checkout to sweep (D102).
2
3
  * Keep due-time parsing in JS: Date.parse accepts more than SQLite's date
3
4
  * functions, and malformed dates are due rather than permanently skipped. */
4
5
  export declare function managedWorktreeSweepCandidates(now: number): Promise<string[]>;
@@ -1,12 +1,13 @@
1
- var d=Object.defineProperty;var s=(t,o)=>d(t,"name",{value:o,configurable:!0});import{openDb as _}from"./db.js";async function w(t){const o=await(await _()).prepare(`
1
+ var d=Object.defineProperty;var s=(t,o)=>d(t,"name",{value:o,configurable:!0});import{openDb as _}from"./db.js";async function p(t){const o=await(await _()).prepare(`
2
2
  SELECT w.node_id, w.sweep_observed_json, w.next_attempt_at,
3
3
  w.abandoned_json, w.land_intent_json, w.disposal_json
4
4
  FROM worktrees w
5
5
  JOIN nodes n ON n.node_id = w.node_id
6
6
  WHERE n.status IN ('done', 'dead', 'canceled')
7
7
  AND n.node_id NOT IN (SELECT node_id FROM warm_pool)
8
+ AND NOT EXISTS (SELECT 1 FROM executions e WHERE e.node_id = n.node_id AND e.runner = 'blaxel')
8
9
  AND w.state IN ('open', 'closed')
9
10
  AND (w.state = 'open' OR w.cleanup_state IS NULL OR w.cleanup_state != 'complete')
10
11
  AND (w.state = 'closed' OR (n.status = 'done' AND n.final_report IS NOT NULL))
11
12
  ORDER BY n.created
12
- `).all(),a=[];for(const e of o){try{for(const n of[e.sweep_observed_json,e.abandoned_json,e.land_intent_json,e.disposal_json])n!==null&&JSON.parse(n)}catch{continue}if(e.sweep_observed_json!==null&&e.next_attempt_at!==null){const n=Date.parse(e.next_attempt_at);if(!Number.isNaN(n)&&n>t)continue}a.push(e.node_id)}return a}s(w,"managedWorktreeSweepCandidates");export{w as managedWorktreeSweepCandidates};
13
+ `).all(),a=[];for(const e of o){try{for(const n of[e.sweep_observed_json,e.abandoned_json,e.land_intent_json,e.disposal_json])n!==null&&JSON.parse(n)}catch{continue}if(e.sweep_observed_json!==null&&e.next_attempt_at!==null){const n=Date.parse(e.next_attempt_at);if(!Number.isNaN(n)&&n>t)continue}a.push(e.node_id)}return a}s(p,"managedWorktreeSweepCandidates");export{p as managedWorktreeSweepCandidates};
@@ -9,10 +9,7 @@ export interface NodePrincipal {
9
9
  client_id: string | null;
10
10
  scopes: string[] | null;
11
11
  }
12
- export declare function mintNodeToken(db: CanvasDb, executionId: string, nodeId: string, issuedAt: string): Promise<void>;
13
- /** Called exactly once by the host at spawn, never serialized into a launch recipe. */
14
- export declare function takeNodeToken(executionId: string): string;
15
- export declare function forgetNodeToken(executionId: string): void;
12
+ export declare function mintNodeToken(db: CanvasDb, executionId: string, nodeId: string, issuedAt: string): Promise<string>;
16
13
  /** A stopped or superseded execution can never authenticate, even after restart. */
17
14
  export declare function resolveNodeToken(token: string): Promise<NodePrincipal | null>;
18
15
  export declare function revokeExitedNodeToken(executionId: string): Promise<void>;
@@ -1,5 +1,5 @@
1
- var E=Object.defineProperty;var o=(e,n)=>E(e,"name",{value:n,configurable:!0});import{createHash as g,randomBytes as l}from"node:crypto";import{openDb as _}from"./db.js";import{terminalGrant as N}from"../grants/mirror.js";import{personId as w}from"./person.js";import{uidForApp as m}from"../spaces/users.js";const i=new Map,c=o(e=>g("sha256").update(e).digest("hex"),"hash");async function v(e,n,r,a){const t=await e.prepare("SELECT grantee, sub, grant_id, client_id, scopes_json, run_id FROM node_rows WHERE node_id = ?").get(r);if(!t)throw new Error(`cannot mint node token: missing node ${r}`);const s=t.run_id&&t.run_id!==r?await e.prepare("SELECT sub, grant_id, client_id FROM nodes WHERE node_id = ?").get(t.run_id):void 0,d=t.grantee==="app:terminal"?await N():null;if(t.grantee==="app:terminal"&&!d)throw new Error("cannot mint node token: terminal grant is not active");const u=d?.sub??s?.sub??t.sub??w(),k=d?.id??s?.grant_id??t.grant_id??null,p=l(32).toString("base64url");await e.prepare('INSERT INTO node_tokens (broker_process_id, node_id, token_hash, grantee, uid, sub, "grant", client_id, scopes_json, issued_at, revoked_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, NULL)').run(n,r,c(p),t.grantee,await m(t.grantee),u,k,s?.client_id??t.client_id,t.scopes_json,a),i.set(n,p)}o(v,"mintNodeToken");function x(e){const n=i.get(e);if(i.delete(e),!n)throw new Error(`missing node token for execution ${e}`);return n}o(x,"takeNodeToken");function f(e){i.delete(e)}o(f,"forgetNodeToken");async function D(e){if(!/^[A-Za-z0-9_-]{43}$/.test(e))return null;const n=await(await _()).prepare(`SELECT t.node_id, t.grantee, t.uid, t.sub, t."grant", t.client_id, t.scopes_json, n.run_id
1
+ var E=Object.defineProperty;var r=(n,e)=>E(n,"name",{value:e,configurable:!0});import{createHash as g,randomBytes as l}from"node:crypto";import{openDb as d}from"./db.js";import{terminalGrant as k}from"../grants/mirror.js";import{personId as N}from"./person.js";import{uidForApp as w}from"../spaces/users.js";const c=r(n=>g("sha256").update(n).digest("hex"),"hash");async function b(n,e,o,i){const t=await n.prepare("SELECT grantee, sub, grant_id, client_id, scopes_json, run_id FROM node_rows WHERE node_id = ?").get(o);if(!t)throw new Error(`cannot mint node token: missing node ${o}`);const a=t.run_id&&t.run_id!==o?await n.prepare("SELECT sub, grant_id, client_id FROM nodes WHERE node_id = ?").get(t.run_id):void 0,s=t.grantee==="app:terminal"?await k():null;if(t.grantee==="app:terminal"&&!s)throw new Error("cannot mint node token: terminal grant is not active");const u=s?.sub??a?.sub??t.sub??N(),p=s?.id??a?.grant_id??t.grant_id??null,_=l(32).toString("base64url");if(!await n.prepare("SELECT 1 AS ok FROM executions WHERE execution_id = ? AND node_id = ? AND state = 'launching'").get(e,o))throw new Error(`cannot mint node token: execution ${e} is not launching`);return await n.prepare('INSERT INTO node_tokens (broker_process_id, node_id, token_hash, grantee, uid, sub, "grant", client_id, scopes_json, issued_at, revoked_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, NULL)').run(e,o,c(_),t.grantee,await w(t.grantee),u,p,a?.client_id??t.client_id,t.scopes_json,i),_}r(b,"mintNodeToken");async function x(n){if(!/^[A-Za-z0-9_-]{43}$/.test(n))return null;const e=await(await d()).prepare(`SELECT t.node_id, t.grantee, t.uid, t.sub, t."grant", t.client_id, t.scopes_json, n.run_id
2
2
  FROM node_tokens t JOIN executions e ON e.execution_id = t.broker_process_id
3
3
  JOIN nodes n ON n.node_id = t.node_id
4
- WHERE t.token_hash = ? AND t.revoked_at IS NULL AND e.state != 'exited'`).get(c(e));return n?{app:n.grantee,node:n.node_id,run:n.run_id,uid:n.uid,sub:n.sub,grant:n.grant,client_id:n.client_id,scopes:n.scopes_json===null?null:JSON.parse(n.scopes_json)}:null}o(D,"resolveNodeToken");async function A(e){f(e),await S(await _(),"broker_process_id",e,new Date().toISOString())}o(A,"revokeExitedNodeToken");async function U(e){await(await _()).prepare(`UPDATE node_tokens SET revoked_at = ? WHERE revoked_at IS NULL
5
- AND broker_process_id IN (SELECT execution_id FROM executions WHERE daemon_epoch IS DISTINCT FROM ?)`).run(new Date().toISOString(),e)}o(U,"revokePriorEpochNodeTokens");async function S(e,n,r,a){await e.prepareUncached(`UPDATE node_tokens SET revoked_at = ? WHERE ${n} = ? AND revoked_at IS NULL`).run(a,r)}o(S,"revokeNodeTokens");export{f as forgetNodeToken,v as mintNodeToken,D as resolveNodeToken,A as revokeExitedNodeToken,S as revokeNodeTokens,U as revokePriorEpochNodeTokens,x as takeNodeToken};
4
+ WHERE t.token_hash = ? AND t.revoked_at IS NULL AND e.state != 'exited'`).get(c(n));return e?{app:e.grantee,node:e.node_id,run:e.run_id,uid:e.uid,sub:e.sub,grant:e.grant,client_id:e.client_id,scopes:e.scopes_json===null?null:JSON.parse(e.scopes_json)}:null}r(x,"resolveNodeToken");async function A(n){await m(await d(),"broker_process_id",n,new Date().toISOString())}r(A,"revokeExitedNodeToken");async function D(n){await(await d()).prepare(`UPDATE node_tokens SET revoked_at = ? WHERE revoked_at IS NULL
5
+ AND broker_process_id IN (SELECT execution_id FROM executions WHERE daemon_epoch IS DISTINCT FROM ?)`).run(new Date().toISOString(),n)}r(D,"revokePriorEpochNodeTokens");async function m(n,e,o,i){await n.prepareUncached(`UPDATE node_tokens SET revoked_at = ? WHERE ${e} = ? AND revoked_at IS NULL`).run(i,o)}r(m,"revokeNodeTokens");export{b as mintNodeToken,x as resolveNodeToken,A as revokeExitedNodeToken,m as revokeNodeTokens,D as revokePriorEpochNodeTokens};
@@ -71,7 +71,6 @@ export declare function inboxPath(nodeId: string): string;
71
71
  export declare function situationalContextPath(nodeId: string): string;
72
72
  export declare function passivePath(nodeId: string): string;
73
73
  export declare function transcriptPath(nodeId: string): string;
74
- export declare function sessionPtrPath(nodeId: string): string;
75
74
  /** Create the full directory skeleton for a node. Idempotent. The agent and
76
75
  * run folders are app-writable, so their subfolders are made beneath them. */
77
76
  export declare function ensureNodeDirs(nodeId: string, grantee: string): void;
@@ -1 +1 @@
1
- var v=Object.defineProperty;var e=(t,n)=>v(t,"name",{value:n,configurable:!0});import{join as r}from"node:path";import{mkdirSync as c}from"node:fs";import{appSpace as f,runtimeRoot as P,socketDir as m}from"../layout.js";import{envGrantee as k,envNodeId as E}from"../../shared/env.js";import{withDirBeneath as h}from"../spaces/open-beneath.js";function i(){return P()}e(i,"crtrHome");function B(){return r(i(),"canvas.db")}e(B,"canvasDbPath");function C(){return r(i(),"on-disk-migration.lock")}e(C,"onDiskMigrationLockPath");function L(){return r(i(),"on-disk-migrations.json")}e(L,"onDiskMigrationMarkerPath");function H(t){return r(u(t),"view.sock")}e(H,"viewSocketPath");function l(){return r(i(),"nodes")}e(l,"nodesRoot");function b(){return r(i(),"reviews")}e(b,"reviewsRoot");function D(t){return p(t),r(b(),t)}e(D,"reviewDir");function K(t){return r(D(t),"result.json")}e(K,"reviewResultPath");function $(t){c(D(t),{recursive:!0,mode:448})}e($,"ensureReviewDir");function F(){return r(m(),"api.sock")}e(F,"apiSocketPath");function G(){return r(i(),"session-list-cache.json")}e(G,"sessionListCachePath");const j=128;function w(t){return typeof t=="string"&&t!==""&&t!=="."&&t!==".."&&!/[\\/\0]/u.test(t)&&Buffer.byteLength(t,"utf8")<=j}e(w,"isSafeNodeId");function p(t){if(!w(t))throw new TypeError("node_id must be a non-empty path segment of at most 128 UTF-8 bytes")}e(p,"assertSafeNodeId");function a(t){return p(t),r(l(),t)}e(a,"nodeRecordDir");const s=a;function x(t,n){p(t);const o=n??(E()===t?k():void 0);if(!o)throw new Error(`node ${t} has no app assignment`);return r(f(o).nodes,t)}e(x,"nodeAgentDir");function _(t,n){return r(x(t,n),"home")}e(_,"isolatedNodeHome");function X(t,n,o){return o?_(t,n):f(n).home}e(X,"nodeHome");function u(t){return p(t),process.platform==="linux"?r(m(),"nodes",t):r(a(t),"run")}e(u,"nodeRunDir");const Y="broker-released",J="cli-relay-generation";function U(t){return r(u(t),"scopes.json")}e(U,"scopesFilePath");function g(t,n){return r(x(t,n),"context")}e(g,"contextDir");function q(t,n,o){return t.replaceAll("$CRTR_CONTEXT_DIR",g(n,o)).replaceAll("$CRTR_NODE_ID",n)}e(q,"interpolateNodePaths");function N(t){return r(a(t),"job")}e(N,"jobDir");function A(t){return r(u(t),"job")}e(A,"nodeRunJobDir");function z(t){return r(s(t),"messages")}e(z,"messagesDir");function Q(t){return r(s(t),"meta.json")}e(Q,"nodeMetaPath");function V(t){return r(s(t),"inbox.jsonl")}e(V,"inboxPath");function W(t){return r(u(t),"situational-context.md")}e(W,"situationalContextPath");function Z(t){return r(s(t),"passive.jsonl")}e(Z,"passivePath");function I(t){return r(s(t),"transcript.jsonl")}e(I,"transcriptPath");function tt(t){return r(s(t),"session.ptr")}e(tt,"sessionPtrPath");function et(t,n){const o=x(t,n);c(a(t),{recursive:!0}),c(N(t),{recursive:!0});for(const R of["context","reports","attachments","worktree"])h(f(n).nodes,r(o,R),()=>{},!0);h(u(t),A(t),()=>{},!0)}e(et,"ensureNodeDirs");function rt(){c(l(),{recursive:!0})}e(rt,"ensureHome");export{J as BROKER_RELAY_GENERATION,Y as BROKER_RELEASED_MARKER,F as apiSocketPath,B as canvasDbPath,g as contextDir,i as crtrHome,rt as ensureHome,et as ensureNodeDirs,$ as ensureReviewDir,V as inboxPath,q as interpolateNodePaths,w as isSafeNodeId,_ as isolatedNodeHome,N as jobDir,z as messagesDir,x as nodeAgentDir,s as nodeDir,X as nodeHome,Q as nodeMetaPath,a as nodeRecordDir,u as nodeRunDir,A as nodeRunJobDir,l as nodesRoot,C as onDiskMigrationLockPath,L as onDiskMigrationMarkerPath,Z as passivePath,D as reviewDir,K as reviewResultPath,b as reviewsRoot,U as scopesFilePath,G as sessionListCachePath,tt as sessionPtrPath,W as situationalContextPath,I as transcriptPath,H as viewSocketPath};
1
+ var v=Object.defineProperty;var e=(t,n)=>v(t,"name",{value:n,configurable:!0});import{join as r}from"node:path";import{mkdirSync as c}from"node:fs";import{appSpace as f,runtimeRoot as k,socketDir as m}from"../layout.js";import{envGrantee as E,envNodeId as P}from"../../shared/env.js";import{withDirBeneath as h}from"../spaces/open-beneath.js";function i(){return k()}e(i,"crtrHome");function B(){return r(i(),"canvas.db")}e(B,"canvasDbPath");function C(){return r(i(),"on-disk-migration.lock")}e(C,"onDiskMigrationLockPath");function L(){return r(i(),"on-disk-migrations.json")}e(L,"onDiskMigrationMarkerPath");function H(t){return r(s(t),"view.sock")}e(H,"viewSocketPath");function l(){return r(i(),"nodes")}e(l,"nodesRoot");function b(){return r(i(),"reviews")}e(b,"reviewsRoot");function D(t){return p(t),r(b(),t)}e(D,"reviewDir");function K(t){return r(D(t),"result.json")}e(K,"reviewResultPath");function $(t){c(D(t),{recursive:!0,mode:448})}e($,"ensureReviewDir");function F(){return r(m(),"api.sock")}e(F,"apiSocketPath");function G(){return r(i(),"session-list-cache.json")}e(G,"sessionListCachePath");const j=128;function w(t){return typeof t=="string"&&t!==""&&t!=="."&&t!==".."&&!/[\\/\0]/u.test(t)&&Buffer.byteLength(t,"utf8")<=j}e(w,"isSafeNodeId");function p(t){if(!w(t))throw new TypeError("node_id must be a non-empty path segment of at most 128 UTF-8 bytes")}e(p,"assertSafeNodeId");function a(t){return p(t),r(l(),t)}e(a,"nodeRecordDir");const u=a;function x(t,n){p(t);const o=n??(P()===t?E():void 0);if(!o)throw new Error(`node ${t} has no app assignment`);return r(f(o).nodes,t)}e(x,"nodeAgentDir");function _(t,n){return r(x(t,n),"home")}e(_,"isolatedNodeHome");function X(t,n,o){return o?_(t,n):f(n).home}e(X,"nodeHome");function s(t){return p(t),process.platform==="linux"?r(m(),"nodes",t):r(a(t),"run")}e(s,"nodeRunDir");const Y="broker-released",J="cli-relay-generation";function U(t){return r(s(t),"scopes.json")}e(U,"scopesFilePath");function g(t,n){return r(x(t,n),"context")}e(g,"contextDir");function q(t,n,o){return t.replaceAll("$CRTR_CONTEXT_DIR",g(n,o)).replaceAll("$CRTR_NODE_ID",n)}e(q,"interpolateNodePaths");function N(t){return r(a(t),"job")}e(N,"jobDir");function A(t){return r(s(t),"job")}e(A,"nodeRunJobDir");function z(t){return r(u(t),"messages")}e(z,"messagesDir");function Q(t){return r(u(t),"meta.json")}e(Q,"nodeMetaPath");function V(t){return r(u(t),"inbox.jsonl")}e(V,"inboxPath");function W(t){return r(s(t),"situational-context.md")}e(W,"situationalContextPath");function Z(t){return r(u(t),"passive.jsonl")}e(Z,"passivePath");function I(t){return r(u(t),"transcript.jsonl")}e(I,"transcriptPath");function tt(t,n){const o=x(t,n);c(a(t),{recursive:!0}),c(N(t),{recursive:!0});for(const R of["context","reports","attachments","worktree"])h(f(n).nodes,r(o,R),()=>{},!0);h(s(t),A(t),()=>{},!0)}e(tt,"ensureNodeDirs");function et(){c(l(),{recursive:!0})}e(et,"ensureHome");export{J as BROKER_RELAY_GENERATION,Y as BROKER_RELEASED_MARKER,F as apiSocketPath,B as canvasDbPath,g as contextDir,i as crtrHome,et as ensureHome,tt as ensureNodeDirs,$ as ensureReviewDir,V as inboxPath,q as interpolateNodePaths,w as isSafeNodeId,_ as isolatedNodeHome,N as jobDir,z as messagesDir,x as nodeAgentDir,u as nodeDir,X as nodeHome,Q as nodeMetaPath,a as nodeRecordDir,s as nodeRunDir,A as nodeRunJobDir,l as nodesRoot,C as onDiskMigrationLockPath,L as onDiskMigrationMarkerPath,Z as passivePath,D as reviewDir,K as reviewResultPath,b as reviewsRoot,U as scopesFilePath,G as sessionListCachePath,W as situationalContextPath,I as transcriptPath,H as viewSocketPath};
@@ -0,0 +1,26 @@
1
+ /** Thrown by `personId()` before the person is known (a hosted first boot, before its first grant snapshot). */
2
+ export declare class PersonUnresolvedError extends Error {
3
+ readonly code = "person_unresolved";
4
+ constructor();
5
+ }
6
+ /** Thrown by `personId()` on a cloud role (`crtrd --role api|reconcile`) outside a request: the control plane serves many people and
7
+ * has no install person to fall back to. A lane that works for a person takes the person from the row it claimed. */
8
+ export declare class PersonOutsideRequestError extends Error {
9
+ readonly code = "person_outside_request";
10
+ constructor();
11
+ }
12
+ /** crtrd sets this once at boot; it wins unconditionally. */
13
+ export declare function setPersonId(id: string): void;
14
+ /** crtrd calls this at boot on a cloud role, instead of resolving a person: from then on a person read outside a request throws. */
15
+ export declare function markCloudRole(): void;
16
+ /** Whether this process is a cloud role (`markCloudRole` ran at boot). */
17
+ export declare function isCloudRole(): boolean;
18
+ /** Run `fn` as `person` (`user:<id>`, the request token's `sub`): every `personId()` inside it, across awaits, answers `person`. */
19
+ export declare function runAsPerson<T>(person: string, fn: () => T): T;
20
+ /** The request's person; else, on a Mac, the boot-set person. Throws `PersonOutsideRequestError` on a cloud role outside a request and
21
+ * `PersonUnresolvedError` when a Mac's person is not bound. Tests and non-daemon processes use `personIdAsync()`. */
22
+ export declare function personId(): string;
23
+ /** The boot-set person, if any (for `personIdAsync`). */
24
+ export declare function bootPersonId(): string | undefined;
25
+ /** The request's person, if any (for `personIdAsync`). */
26
+ export declare function requestPersonId(): string | undefined;
@@ -0,0 +1 @@
1
+ var u=Object.defineProperty;var r=(e,n)=>u(e,"name",{value:n,configurable:!0});import{AsyncLocalStorage as d}from"node:async_hooks";class i extends Error{static{r(this,"PersonUnresolvedError")}code="person_unresolved";constructor(){super("the install's person is not resolved yet"),this.name="PersonUnresolvedError"}}class c extends Error{static{r(this,"PersonOutsideRequestError")}code="person_outside_request";constructor(){super("no person: a cloud role reads the person only inside a request, from its token"),this.name="PersonOutsideRequestError"}}let o,t=!1;const s=new d;function f(e){o=e}r(f,"setPersonId");function a(){t=!0}r(a,"markCloudRole");function x(){return t}r(x,"isCloudRole");function P(e,n){return s.run(e,n)}r(P,"runAsPerson");function m(){const e=s.getStore();if(e!==void 0)return e;if(t)throw new c;if(o===void 0)throw new i;return o}r(m,"personId");function q(){return o}r(q,"bootPersonId");function h(){return s.getStore()}r(h,"requestPersonId");export{c as PersonOutsideRequestError,i as PersonUnresolvedError,q as bootPersonId,x as isCloudRole,a as markCloudRole,m as personId,h as requestPersonId,P as runAsPerson,f as setPersonId};
@@ -1,17 +1,10 @@
1
+ import { PersonUnresolvedError, PersonOutsideRequestError, setPersonId, markCloudRole, isCloudRole, runAsPerson, personId } from './person-state.js';
1
2
  import { type CanvasDb } from './db.js';
2
3
  import { LEGACY_LOCAL_PERSON } from './legacy-person.js';
3
4
  export { LEGACY_LOCAL_PERSON };
4
- /** Thrown by `personId()` before the person is known (a hosted first boot, before its first grant snapshot). */
5
- export declare class PersonUnresolvedError extends Error {
6
- readonly code = "person_unresolved";
7
- constructor();
8
- }
9
5
  export type PersonSource = 'stored' | 'joined' | 'grants' | 'minted';
10
- /** crtrd sets this once at boot; it wins unconditionally. */
11
- export declare function setPersonId(id: string): void;
12
- /** The boot-set person. Throws `PersonUnresolvedError` when unset. Tests and non-daemon processes use `personIdAsync()`. */
13
- export declare function personId(): string;
14
- /** Lazy get-or-create keyed by the active canvas database, for processes that are not the daemon. */
6
+ export { PersonUnresolvedError, PersonOutsideRequestError, setPersonId, markCloudRole, isCloudRole, runAsPerson, personId };
7
+ /** As `personId()`, but a process that is not the daemon gets a lazy get-or-create keyed by the active canvas database. */
15
8
  export declare function personIdAsync(): Promise<string>;
16
9
  /** Get-or-create the person and say where it came from. Order: stored, the join file's owner, the single `sub` of the
17
10
  * mirrored grants (a runtime with an issuer and no join file), else a minted id on a runtime without an issuer.