@north-light/crouter 0.3.349 → 0.3.350

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 (629) hide show
  1. package/bin/crtr-launcher +4 -0
  2. package/bin/runtime-generation-manifest.mjs +12 -2
  3. package/dist/api/client.d.ts +50 -7
  4. package/dist/api/client.js +2 -2
  5. package/dist/api/dto/analytics.d.ts +184 -0
  6. package/dist/api/dto/analytics.js +0 -0
  7. package/dist/api/dto/broker-ops.d.ts +43 -1
  8. package/dist/api/dto/config.d.ts +11 -0
  9. package/dist/api/dto/grants.d.ts +14 -0
  10. package/dist/api/dto/grants.js +0 -0
  11. package/dist/api/dto/human-requests.d.ts +14 -0
  12. package/dist/api/dto/memory.d.ts +6 -0
  13. package/dist/api/dto/modelauth.d.ts +35 -0
  14. package/dist/api/dto/node-records.d.ts +35 -0
  15. package/dist/api/dto/node-records.js +0 -0
  16. package/dist/api/dto/nodes.d.ts +5 -0
  17. package/dist/api/dto/profiles.d.ts +38 -3
  18. package/dist/api/dto/worktree.d.ts +11 -0
  19. package/dist/api/errors.d.ts +23 -1
  20. package/dist/api/errors.js +1 -1
  21. package/dist/api/index.d.ts +2 -0
  22. package/dist/api/index.js +1 -1
  23. package/dist/api/node-transport.js +1 -1
  24. package/dist/api/routes.d.ts +22 -0
  25. package/dist/api/routes.js +1 -1
  26. package/dist/build-root.d.ts +6 -1
  27. package/dist/build-root.js +1 -1
  28. package/dist/builtin-memory/crouter-sdk/client.md +34 -0
  29. package/dist/builtin-memory/crouter-sdk/errors.md +2 -0
  30. package/dist/builtin-memory/crouter-sdk/memory.md +2 -2
  31. package/dist/builtin-memory/crouter-sdk/streaming.md +21 -0
  32. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/claude-plugin-commands.ts +8 -4
  33. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/memory-slash-commands.ts +39 -118
  34. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.d.ts +6 -1
  35. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.js +41 -27
  36. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.ts +52 -29
  37. package/dist/cli.js +9 -8
  38. package/dist/clients/attach/chrome/inbox-strip.js +1 -1
  39. package/dist/clients/attach/chrome/roster.js +1 -1
  40. package/dist/clients/attach/config.js +1 -1
  41. package/dist/clients/attach/overlays/auth.js +2 -2
  42. package/dist/clients/attach/overlays/graph.js +1 -1
  43. package/dist/clients/attach/render/tool-calls.js +3 -3
  44. package/dist/clients/attach/session/connection.js +1 -1
  45. package/dist/clients/attach/session/profile-files.js +1 -1
  46. package/dist/clients/attach/viewer.js +1569 -816
  47. package/dist/commands/api-client.js +3 -3
  48. package/dist/commands/broker-permissions.d.ts +2 -0
  49. package/dist/commands/broker-permissions.js +1 -0
  50. package/dist/commands/canvas-analytics/chart.d.ts +52 -0
  51. package/dist/commands/canvas-analytics/chart.js +1 -0
  52. package/dist/commands/canvas-analytics/drilldown.d.ts +34 -0
  53. package/dist/commands/canvas-analytics/drilldown.js +1 -0
  54. package/dist/commands/canvas-analytics/format.d.ts +29 -0
  55. package/dist/commands/canvas-analytics/format.js +1 -0
  56. package/dist/commands/canvas-analytics/graph-detail.d.ts +2 -0
  57. package/dist/commands/canvas-analytics/graph-detail.js +2 -0
  58. package/dist/commands/canvas-analytics/graphs.d.ts +9 -0
  59. package/dist/commands/canvas-analytics/graphs.js +1 -0
  60. package/dist/commands/canvas-analytics/memory.d.ts +2 -0
  61. package/dist/commands/canvas-analytics/memory.js +1 -0
  62. package/dist/commands/canvas-analytics/overview.d.ts +2 -0
  63. package/dist/commands/canvas-analytics/overview.js +1 -0
  64. package/dist/commands/canvas-analytics/shell.d.ts +60 -0
  65. package/dist/commands/canvas-analytics/shell.js +2 -0
  66. package/dist/commands/canvas-analytics/time.d.ts +2 -0
  67. package/dist/commands/canvas-analytics/time.js +1 -0
  68. package/dist/commands/canvas-analytics/usage.d.ts +2 -0
  69. package/dist/commands/canvas-analytics/usage.js +1 -0
  70. package/dist/commands/canvas-analytics/view.d.ts +85 -0
  71. package/dist/commands/canvas-analytics/view.js +1 -0
  72. package/dist/commands/canvas-analytics.d.ts +2 -0
  73. package/dist/commands/canvas-analytics.js +1 -0
  74. package/dist/commands/canvas-prune.js +1 -1
  75. package/dist/commands/canvas.js +1 -1
  76. package/dist/commands/cron.js +5 -5
  77. package/dist/commands/human/components.d.ts +2 -0
  78. package/dist/commands/human/components.js +2 -2
  79. package/dist/commands/human/prompts.js +1 -1
  80. package/dist/commands/human/queue.js +1 -1
  81. package/dist/commands/memory/client.d.ts +11 -0
  82. package/dist/commands/memory/client.js +1 -0
  83. package/dist/commands/memory/delete.js +1 -1
  84. package/dist/commands/memory/edit.js +3 -3
  85. package/dist/commands/memory/find.js +1 -1
  86. package/dist/commands/memory/history.js +4 -4
  87. package/dist/commands/memory/lint.js +1 -1
  88. package/dist/commands/memory/list.d.ts +0 -2
  89. package/dist/commands/memory/list.js +1 -1
  90. package/dist/commands/memory/move.js +1 -1
  91. package/dist/commands/memory/origin.js +1 -1
  92. package/dist/commands/memory/read.d.ts +0 -5
  93. package/dist/commands/memory/read.js +3 -3
  94. package/dist/commands/memory/shared.d.ts +0 -178
  95. package/dist/commands/memory/shared.js +1 -12
  96. package/dist/commands/memory/write.js +5 -5
  97. package/dist/commands/node/bash.js +5 -5
  98. package/dist/commands/node/create.d.ts +0 -17
  99. package/dist/commands/node/create.js +2 -3
  100. package/dist/commands/node/inspect.js +6 -6
  101. package/dist/commands/node/lifecycle.js +2 -2
  102. package/dist/commands/node-context.js +2 -2
  103. package/dist/commands/node-inspect-artifacts.js +6 -6
  104. package/dist/commands/pkg/browse/catalog.js +1 -1
  105. package/dist/commands/pkg/browse/model.d.ts +1 -1
  106. package/dist/commands/pkg/market-manage.js +1 -1
  107. package/dist/commands/pkg/plugin-manage.js +10 -10
  108. package/dist/commands/profile/daemon-profiles.d.ts +13 -0
  109. package/dist/commands/profile/daemon-profiles.js +4 -0
  110. package/dist/commands/profile/delete.js +1 -1
  111. package/dist/commands/profile/env.d.ts +6 -0
  112. package/dist/commands/profile/env.js +2 -2
  113. package/dist/commands/profile/kind.js +1 -2
  114. package/dist/commands/profile/list.js +1 -1
  115. package/dist/commands/profile/meta.js +1 -1
  116. package/dist/commands/profile/new.js +1 -1
  117. package/dist/commands/profile/pause.js +1 -1
  118. package/dist/commands/profile/project.js +1 -1
  119. package/dist/commands/profile/rename.js +1 -1
  120. package/dist/commands/profile/show.js +1 -1
  121. package/dist/commands/profile.js +1 -1
  122. package/dist/commands/push.js +3 -3
  123. package/dist/commands/surface-inspect.js +1 -1
  124. package/dist/commands/sys/branch.js +1 -1
  125. package/dist/commands/sys/config.js +1 -1
  126. package/dist/commands/sys/connect.js +3 -3
  127. package/dist/commands/sys/context/admin/actions.js +1 -1
  128. package/dist/commands/sys/context/admin/model.d.ts +1 -0
  129. package/dist/commands/sys/context/admin/model.js +1 -1
  130. package/dist/commands/sys/context/admin.js +1 -1
  131. package/dist/commands/sys/context/expose.js +2 -1
  132. package/dist/commands/sys/context/prompt-review.js +2 -2
  133. package/dist/commands/sys/context/resolve.js +7 -7
  134. package/dist/commands/sys/context/sysprompt.js +1 -1
  135. package/dist/commands/sys/join.d.ts +1 -0
  136. package/dist/commands/sys/join.js +1 -0
  137. package/dist/commands/sys/migrate.js +1 -1
  138. package/dist/commands/sys/panels/models-panel.js +1 -1
  139. package/dist/commands/sys/panels/profiles-panel.d.ts +0 -1
  140. package/dist/commands/sys/panels/profiles-panel.js +1 -1
  141. package/dist/commands/sys/provider-login.js +6 -6
  142. package/dist/commands/sys/setup-core.d.ts +1 -1
  143. package/dist/commands/sys/setup-core.js +6 -6
  144. package/dist/commands/sys/setup-settings-runner.js +1 -1
  145. package/dist/commands/sys/setup.js +1 -1
  146. package/dist/commands/sys/spaces.d.ts +1 -0
  147. package/dist/commands/sys/spaces.js +2 -0
  148. package/dist/commands/sys/sync-deps.js +2 -2
  149. package/dist/commands/sys/sync-project-guidance.js +4 -4
  150. package/dist/commands/sys/sync-skills.js +2 -2
  151. package/dist/commands/sys/worktrees.d.ts +1 -0
  152. package/dist/commands/sys/worktrees.js +1 -1
  153. package/dist/commands/sys.js +1 -1
  154. package/dist/core/auth-file.js +2 -2
  155. package/dist/core/bash-job-supervisor.d.ts +6 -0
  156. package/dist/core/bash-job-supervisor.js +4 -0
  157. package/dist/core/bash-jobs.d.ts +13 -6
  158. package/dist/core/bash-jobs.js +8 -7
  159. package/dist/core/broker-client/transport-relay.d.ts +6 -3
  160. package/dist/core/broker-client/transport-relay.js +1 -1
  161. package/dist/core/broker-client/transport-socket.d.ts +6 -1
  162. package/dist/core/broker-client/transport-socket.js +1 -1
  163. package/dist/core/canvas/canvas.d.ts +39 -18
  164. package/dist/core/canvas/canvas.js +21 -20
  165. package/dist/core/canvas/context-strip.d.ts +20 -0
  166. package/dist/core/canvas/context-strip.js +5 -0
  167. package/dist/core/canvas/crons.d.ts +12 -20
  168. package/dist/core/canvas/crons.js +15 -13
  169. package/dist/core/canvas/db.js +2 -2
  170. package/dist/core/canvas/deliveries.d.ts +4 -1
  171. package/dist/core/canvas/deliveries.js +1 -1
  172. package/dist/core/canvas/executions.js +1 -1
  173. package/dist/core/canvas/history.d.ts +2 -1
  174. package/dist/core/canvas/history.js +17 -18
  175. package/dist/core/canvas/memory-reads.d.ts +19 -0
  176. package/dist/core/canvas/memory-reads.js +1 -0
  177. package/dist/core/canvas/migrations.d.ts +0 -4
  178. package/dist/core/canvas/migrations.js +99 -32
  179. package/dist/core/canvas/nav-render.js +1 -1
  180. package/dist/core/canvas/node-agent-paths.d.ts +8 -0
  181. package/dist/core/canvas/node-agent-paths.js +1 -0
  182. package/dist/core/canvas/node-recap.d.ts +2 -2
  183. package/dist/core/canvas/node-recap.js +2 -2
  184. package/dist/core/canvas/node-tokens.d.ts +24 -0
  185. package/dist/core/canvas/node-tokens.js +5 -0
  186. package/dist/core/canvas/paths.d.ts +16 -19
  187. package/dist/core/canvas/paths.js +1 -1
  188. package/dist/core/canvas/render-source.d.ts +2 -2
  189. package/dist/core/canvas/render-source.js +6 -9
  190. package/dist/core/canvas/sessions.d.ts +18 -0
  191. package/dist/core/canvas/sessions.js +4 -1
  192. package/dist/core/canvas/types.d.ts +22 -6
  193. package/dist/core/command-hooks/compose.js +1 -1
  194. package/dist/core/command-hooks/discovery.d.ts +15 -1
  195. package/dist/core/command-hooks/discovery.js +1 -1
  196. package/dist/core/command-hooks/help.d.ts +2 -2
  197. package/dist/core/command-hooks/lifecycle-create.d.ts +1 -1
  198. package/dist/core/command-hooks/lifecycle-create.js +1 -1
  199. package/dist/core/command-hooks/transport/exec-invoke.d.ts +2 -0
  200. package/dist/core/command-hooks/transport/exec-invoke.js +1 -1
  201. package/dist/core/command-hooks/transport/exec-lifecycle.d.ts +1 -0
  202. package/dist/core/command-hooks/transport/exec-lifecycle.js +1 -1
  203. package/dist/core/command-hooks/transport/plan.d.ts +3 -0
  204. package/dist/core/command-hooks/transport/plan.js +1 -0
  205. package/dist/core/command-plugins/discovery.js +1 -1
  206. package/dist/core/command.d.ts +6 -2
  207. package/dist/core/command.js +6 -6
  208. package/dist/core/config.d.ts +8 -5
  209. package/dist/core/config.js +1 -1
  210. package/dist/core/conversation-store/client-worker.d.ts +1 -0
  211. package/dist/core/conversation-store/client-worker.js +1 -0
  212. package/dist/core/conversation-store/client.d.ts +2 -0
  213. package/dist/core/conversation-store/client.js +2 -0
  214. package/dist/core/conversation-store/file-store.d.ts +37 -0
  215. package/dist/core/conversation-store/file-store.js +9 -0
  216. package/dist/core/conversation-store/index.d.ts +50 -0
  217. package/dist/core/conversation-store/index.js +1 -0
  218. package/dist/core/conversation-store/listener.d.ts +4 -0
  219. package/dist/core/conversation-store/listener.js +3 -0
  220. package/dist/core/conversation-store/patch.d.ts +1 -0
  221. package/dist/core/conversation-store/patch.js +1 -0
  222. package/dist/core/directory/join.d.ts +27 -0
  223. package/dist/core/directory/join.js +1 -0
  224. package/dist/core/disk-usage.d.ts +4 -0
  225. package/dist/core/disk-usage.js +1 -0
  226. package/dist/core/events/emit.d.ts +2 -0
  227. package/dist/core/events/emit.js +3 -1
  228. package/dist/core/feed/feed.js +4 -4
  229. package/dist/core/feed/messages.d.ts +3 -0
  230. package/dist/core/feed/messages.js +6 -6
  231. package/dist/core/fs-utils.d.ts +2 -0
  232. package/dist/core/fs-utils.js +3 -3
  233. package/dist/core/grants/local.d.ts +4 -0
  234. package/dist/core/grants/local.js +1 -0
  235. package/dist/core/grants/mirror.d.ts +44 -0
  236. package/dist/core/grants/mirror.js +4 -0
  237. package/dist/core/grants/on-sync.d.ts +22 -0
  238. package/dist/core/grants/on-sync.js +1 -0
  239. package/dist/core/grants/remove.d.ts +7 -0
  240. package/dist/core/grants/remove.js +1 -0
  241. package/dist/core/grants/sandboxes.d.ts +7 -0
  242. package/dist/core/grants/sandboxes.js +1 -0
  243. package/dist/core/grants/sync.d.ts +12 -0
  244. package/dist/core/grants/sync.js +1 -0
  245. package/dist/core/help/memory-extensions.d.ts +3 -0
  246. package/dist/core/help/memory-extensions.js +2 -0
  247. package/dist/core/help.d.ts +14 -0
  248. package/dist/core/help.js +7 -7
  249. package/dist/core/host-exports/builtins.js +3 -3
  250. package/dist/core/host-exports/export.js +3 -3
  251. package/dist/core/human/action-binding.d.ts +2 -0
  252. package/dist/core/human/action-binding.js +1 -1
  253. package/dist/core/human/feedback-companion.d.ts +0 -1
  254. package/dist/core/human/feedback-companion.js +1 -1
  255. package/dist/core/human/page-schema.d.ts +1 -1
  256. package/dist/core/inspector/core.d.ts +2 -0
  257. package/dist/core/inspector/core.js +1 -1
  258. package/dist/core/inspector/tui.js +2 -2
  259. package/dist/core/installed-plugins.js +1 -1
  260. package/dist/core/io.js +6 -6
  261. package/dist/core/keybindings/catalog.d.ts +1 -1
  262. package/dist/core/keybindings/catalog.js +1 -1
  263. package/dist/core/layout-migrate/index.d.ts +15 -0
  264. package/dist/core/layout-migrate/index.js +4 -0
  265. package/dist/core/layout-migrate/paths.d.ts +26 -0
  266. package/dist/core/layout-migrate/paths.js +1 -0
  267. package/dist/core/layout-migrate/stored-paths.d.ts +2 -0
  268. package/dist/core/layout-migrate/stored-paths.js +11 -0
  269. package/dist/core/layout-migrate/stores.d.ts +17 -0
  270. package/dist/core/layout-migrate/stores.js +4 -0
  271. package/dist/core/layout.d.ts +26 -0
  272. package/dist/core/layout.js +2 -0
  273. package/dist/core/llm/run.d.ts +60 -0
  274. package/dist/core/llm/run.js +4 -0
  275. package/dist/core/memory/cli-selector.d.ts +13 -0
  276. package/dist/core/memory/cli-selector.js +1 -0
  277. package/dist/core/memory/history.d.ts +5 -4
  278. package/dist/core/memory/history.js +6 -6
  279. package/dist/core/memory/inline-ref-inventory.d.ts +2 -1
  280. package/dist/core/memory/inline-ref-inventory.js +1 -1
  281. package/dist/core/memory/lint.js +2 -2
  282. package/dist/core/memory/mutation-domain.d.ts +2 -2
  283. package/dist/core/memory/mutation-domain.js +8 -7
  284. package/dist/core/memory/mutations.js +1 -1
  285. package/dist/core/memory/service.d.ts +5 -0
  286. package/dist/core/memory/service.js +2 -2
  287. package/dist/core/memory-resolver.d.ts +11 -7
  288. package/dist/core/memory-resolver.js +2 -2
  289. package/dist/core/model-auth/daemon-login.d.ts +13 -0
  290. package/dist/core/model-auth/daemon-login.js +1 -0
  291. package/dist/core/model-auth/flows.d.ts +45 -0
  292. package/dist/core/model-auth/flows.js +1 -0
  293. package/dist/core/model-auth/handoff-jti.d.ts +4 -0
  294. package/dist/core/model-auth/handoff-jti.js +1 -0
  295. package/dist/core/model-routes.js +1 -1
  296. package/dist/core/nested-stores.d.ts +2 -1
  297. package/dist/core/nested-stores.js +1 -2
  298. package/dist/core/preview-registry.js +2 -2
  299. package/dist/core/profiles/env-store.js +2 -2
  300. package/dist/core/profiles/manifest.d.ts +16 -5
  301. package/dist/core/profiles/manifest.js +1 -1
  302. package/dist/core/provider-management.js +1 -1
  303. package/dist/core/review/birth.js +1 -1
  304. package/dist/core/review/companion.d.ts +0 -2
  305. package/dist/core/review/companion.js +1 -1
  306. package/dist/core/review/fork.js +2 -2
  307. package/dist/core/review/realize.js +1 -1
  308. package/dist/core/review/stage.d.ts +1 -1
  309. package/dist/core/review/stage.js +1 -1
  310. package/dist/core/review/types.d.ts +1 -1
  311. package/dist/core/runs/events.d.ts +34 -0
  312. package/dist/core/runs/events.js +1 -0
  313. package/dist/core/runs/operations.d.ts +43 -0
  314. package/dist/core/runs/operations.js +12 -0
  315. package/dist/core/runtime/bearings-render.d.ts +2 -2
  316. package/dist/core/runtime/bearings-render.js +11 -11
  317. package/dist/core/runtime/bearings.js +2 -2
  318. package/dist/core/runtime/broker/cli-relay.d.ts +5 -0
  319. package/dist/core/runtime/broker/cli-relay.js +1 -0
  320. package/dist/core/runtime/broker/client-registry.d.ts +0 -5
  321. package/dist/core/runtime/broker/client-registry.js +1 -1
  322. package/dist/core/runtime/broker/daemon-ops.d.ts +28 -1
  323. package/dist/core/runtime/broker/daemon-ops.js +1 -1
  324. package/dist/core/runtime/broker/engine-drive.d.ts +0 -2
  325. package/dist/core/runtime/broker/engine-drive.js +1 -1
  326. package/dist/core/runtime/broker/fault-retry.d.ts +9 -0
  327. package/dist/core/runtime/broker/fault-retry.js +1 -1
  328. package/dist/core/runtime/broker/frame-dispatch.d.ts +5 -9
  329. package/dist/core/runtime/broker/frame-dispatch.js +1 -1
  330. package/dist/core/runtime/broker/frame-engine-control.d.ts +3 -2
  331. package/dist/core/runtime/broker/frame-engine-control.js +1 -1
  332. package/dist/core/runtime/broker/frame-memory-refs.d.ts +4 -3
  333. package/dist/core/runtime/broker/frame-memory-refs.js +1 -1
  334. package/dist/core/runtime/broker/frame-read.js +1 -1
  335. package/dist/core/runtime/broker/frame-session.js +1 -1
  336. package/dist/core/runtime/broker/held-deferred-inbox.d.ts +3 -1
  337. package/dist/core/runtime/broker/held-deferred-inbox.js +1 -1
  338. package/dist/core/runtime/broker/inbox.d.ts +1 -2
  339. package/dist/core/runtime/broker/inbox.js +7 -10
  340. package/dist/core/runtime/broker/model-adapter.d.ts +9 -0
  341. package/dist/core/runtime/broker/model-adapter.js +2 -0
  342. package/dist/core/runtime/broker/node-token.d.ts +3 -0
  343. package/dist/core/runtime/broker/node-token.js +1 -0
  344. package/dist/core/runtime/broker/read-ops.js +1 -1
  345. package/dist/core/runtime/broker/rebind.d.ts +2 -0
  346. package/dist/core/runtime/broker/rebind.js +1 -1
  347. package/dist/core/runtime/broker/tool-groups.js +1 -1
  348. package/dist/core/runtime/broker/turn-ignition.d.ts +3 -3
  349. package/dist/core/runtime/broker/turn-ignition.js +1 -1
  350. package/dist/core/runtime/broker-cli.js +3 -3
  351. package/dist/core/runtime/broker-extension-render.d.ts +2 -5
  352. package/dist/core/runtime/broker-extension-render.js +4 -4
  353. package/dist/core/runtime/broker-persona-guidance.js +3 -3
  354. package/dist/core/runtime/broker-protocol.d.ts +7 -8
  355. package/dist/core/runtime/broker.js +1 -1
  356. package/dist/core/runtime/canvas-extensions.d.ts +1 -0
  357. package/dist/core/runtime/canvas-extensions.js +1 -1
  358. package/dist/core/runtime/close.d.ts +9 -0
  359. package/dist/core/runtime/close.js +1 -1
  360. package/dist/core/runtime/deliver-live.js +1 -1
  361. package/dist/core/runtime/fleet.d.ts +1 -1
  362. package/dist/core/runtime/front-door-login.js +1 -1
  363. package/dist/core/runtime/front-door.js +2 -2
  364. package/dist/core/runtime/headless-pi.d.ts +1 -1
  365. package/dist/core/runtime/headless-pi.js +1 -1
  366. package/dist/core/runtime/host.d.ts +1 -1
  367. package/dist/core/runtime/host.js +3 -1
  368. package/dist/core/runtime/invocation.d.ts +3 -0
  369. package/dist/core/runtime/kickoff.d.ts +1 -0
  370. package/dist/core/runtime/kickoff.js +16 -16
  371. package/dist/core/runtime/launch-target.d.ts +1 -1
  372. package/dist/core/runtime/launch-target.js +1 -1
  373. package/dist/core/runtime/launch.d.ts +10 -35
  374. package/dist/core/runtime/launch.js +1 -1
  375. package/dist/core/runtime/lifecycle.js +2 -2
  376. package/dist/core/runtime/memory.d.ts +1 -1
  377. package/dist/core/runtime/memory.js +1 -1
  378. package/dist/core/runtime/model-registry.js +1 -1
  379. package/dist/core/runtime/model-swap.d.ts +17 -19
  380. package/dist/core/runtime/model-swap.js +1 -1
  381. package/dist/core/runtime/node-read.js +3 -2
  382. package/dist/core/runtime/nodes.d.ts +7 -0
  383. package/dist/core/runtime/nodes.js +1 -1
  384. package/dist/core/runtime/outcome-document.js +1 -1
  385. package/dist/core/runtime/package-health.js +2 -2
  386. package/dist/core/runtime/persona.js +2 -2
  387. package/dist/core/runtime/pi-vendored.js +1 -1
  388. package/dist/core/runtime/placement-tmux.d.ts +1 -1
  389. package/dist/core/runtime/placement-tmux.js +1 -1
  390. package/dist/core/runtime/placement.js +1 -1
  391. package/dist/core/runtime/promote.js +1 -1
  392. package/dist/core/runtime/provider-credential-gate.js +2 -2
  393. package/dist/core/runtime/recovery-hold.d.ts +2 -0
  394. package/dist/core/runtime/recovery-hold.js +1 -0
  395. package/dist/core/runtime/recycle.js +1 -1
  396. package/dist/core/runtime/reopen.js +1 -1
  397. package/dist/core/runtime/reset.js +1 -1
  398. package/dist/core/runtime/revive.d.ts +1 -1
  399. package/dist/core/runtime/revive.js +2 -3
  400. package/dist/core/runtime/roadmap.js +4 -4
  401. package/dist/core/runtime/run-command.d.ts +6 -0
  402. package/dist/core/runtime/run-command.js +1 -1
  403. package/dist/core/runtime/session-branch.d.ts +2 -8
  404. package/dist/core/runtime/session-branch.js +1 -1
  405. package/dist/core/runtime/session-list-cache.d.ts +6 -22
  406. package/dist/core/runtime/session-list-cache.js +1 -1
  407. package/dist/core/runtime/situational-context.js +2 -2
  408. package/dist/core/runtime/spawn-env.d.ts +6 -6
  409. package/dist/core/runtime/spawn-env.js +1 -1
  410. package/dist/core/runtime/spawn.d.ts +5 -0
  411. package/dist/core/runtime/spawn.js +2 -2
  412. package/dist/core/runtime/stop-guard.js +2 -2
  413. package/dist/core/runtime/stop-signals.d.ts +2 -2
  414. package/dist/core/runtime/stop-signals.js +1 -1
  415. package/dist/core/runtime/structured-output.d.ts +10 -4
  416. package/dist/core/runtime/structured-output.js +4 -4
  417. package/dist/core/runtime/tmux-bindings.js +3 -3
  418. package/dist/core/runtime/tmux-driver.d.ts +4 -0
  419. package/dist/core/runtime/tmux-driver.js +7 -7
  420. package/dist/core/runtime/view-socket.d.ts +9 -2
  421. package/dist/core/runtime/view-socket.js +1 -1
  422. package/dist/core/runtime/warm-pool.js +1 -1
  423. package/dist/core/scope.d.ts +3 -2
  424. package/dist/core/scope.js +1 -1
  425. package/dist/core/scoped-state/db.js +1 -1
  426. package/dist/core/scoped-state/migrate.js +3 -3
  427. package/dist/core/scoped-state/profiles.d.ts +2 -1
  428. package/dist/core/scoped-state/profiles.js +1 -1
  429. package/dist/core/scoped-state/schema.d.ts +2 -1
  430. package/dist/core/scoped-state/schema.js +4 -4
  431. package/dist/core/scopes.d.ts +2 -2
  432. package/dist/core/scopes.js +1 -1
  433. package/dist/core/secrets.d.ts +1 -0
  434. package/dist/core/secrets.js +2 -2
  435. package/dist/core/spaces/mounts.d.ts +32 -0
  436. package/dist/core/spaces/mounts.js +1 -0
  437. package/dist/core/spaces/open-beneath.d.ts +71 -0
  438. package/dist/core/spaces/open-beneath.js +1 -0
  439. package/dist/core/spaces/permissions.d.ts +46 -0
  440. package/dist/core/spaces/permissions.js +1 -0
  441. package/dist/core/spaces/process.d.ts +27 -0
  442. package/dist/core/spaces/process.js +1 -0
  443. package/dist/core/spaces/space.d.ts +8 -0
  444. package/dist/core/spaces/space.js +2 -0
  445. package/dist/core/spaces/stop.d.ts +8 -0
  446. package/dist/core/spaces/stop.js +2 -0
  447. package/dist/core/spaces/users.d.ts +19 -0
  448. package/dist/core/spaces/users.js +1 -0
  449. package/dist/core/subscription-state.d.ts +2 -0
  450. package/dist/core/subscription-state.js +3 -3
  451. package/dist/core/substrate/frontmatter-validation.js +1 -1
  452. package/dist/core/substrate/injected-store.d.ts +28 -3
  453. package/dist/core/substrate/injected-store.js +2 -1
  454. package/dist/core/substrate/listings.js +1 -1
  455. package/dist/core/substrate/memory-events.d.ts +6 -0
  456. package/dist/core/substrate/memory-events.js +1 -0
  457. package/dist/core/substrate/on-read-node.js +1 -1
  458. package/dist/core/substrate/on-read.d.ts +6 -6
  459. package/dist/core/substrate/on-read.js +5 -5
  460. package/dist/core/substrate/plan.js +1 -1
  461. package/dist/core/substrate/render-node.js +1 -1
  462. package/dist/core/substrate/render.d.ts +4 -3
  463. package/dist/core/substrate/render.js +38 -38
  464. package/dist/core/substrate/schema.d.ts +6 -0
  465. package/dist/core/substrate/schema.js +1 -1
  466. package/dist/core/tui/panel.js +1 -1
  467. package/dist/core/user-settings.d.ts +12 -0
  468. package/dist/core/user-settings.js +1 -1
  469. package/dist/core/worktree-mutation-async.js +5 -5
  470. package/dist/core/worktree-quarantine.js +1 -1
  471. package/dist/core/worktree-remove.d.ts +15 -0
  472. package/dist/core/worktree-remove.js +1 -0
  473. package/dist/core/worktree-sweep.js +6 -6
  474. package/dist/daemon/analytics/compute.d.ts +37 -0
  475. package/dist/daemon/analytics/compute.js +1 -0
  476. package/dist/daemon/analytics/scan-worker.d.ts +1 -0
  477. package/dist/daemon/analytics/scan-worker.js +2 -0
  478. package/dist/daemon/analytics/scan.d.ts +37 -0
  479. package/dist/daemon/analytics/scan.js +1 -0
  480. package/dist/daemon/api/app-listener.d.ts +11 -0
  481. package/dist/daemon/api/app-listener.js +21 -0
  482. package/dist/daemon/api/bridge.js +5 -5
  483. package/dist/daemon/api/handlers/analytics.d.ts +2 -0
  484. package/dist/daemon/api/handlers/analytics.js +1 -0
  485. package/dist/daemon/api/handlers/attach.js +1 -1
  486. package/dist/daemon/api/handlers/bash-jobs.js +2 -2
  487. package/dist/daemon/api/handlers/bash.js +1 -1
  488. package/dist/daemon/api/handlers/broker-ops.js +1 -1
  489. package/dist/daemon/api/handlers/canvas.d.ts +1 -1
  490. package/dist/daemon/api/handlers/canvas.js +6 -6
  491. package/dist/daemon/api/handlers/crons.js +1 -1
  492. package/dist/daemon/api/handlers/files.d.ts +1 -1
  493. package/dist/daemon/api/handlers/files.js +1 -1
  494. package/dist/daemon/api/handlers/health.js +2 -2
  495. package/dist/daemon/api/handlers/hook-exec.d.ts +2 -0
  496. package/dist/daemon/api/handlers/hook-exec.js +1 -0
  497. package/dist/daemon/api/handlers/human-requests.js +1 -1
  498. package/dist/daemon/api/handlers/inbox.js +1 -1
  499. package/dist/daemon/api/handlers/llm.d.ts +2 -0
  500. package/dist/daemon/api/handlers/llm.js +3 -0
  501. package/dist/daemon/api/handlers/memory-reads.d.ts +4 -0
  502. package/dist/daemon/api/handlers/memory-reads.js +1 -0
  503. package/dist/daemon/api/handlers/memory.js +5 -1
  504. package/dist/daemon/api/handlers/messages.js +2 -2
  505. package/dist/daemon/api/handlers/modelauth.js +1 -1
  506. package/dist/daemon/api/handlers/node-outcomes.js +1 -1
  507. package/dist/daemon/api/handlers/node-records.d.ts +2 -0
  508. package/dist/daemon/api/handlers/node-records.js +3 -0
  509. package/dist/daemon/api/handlers/nodes.d.ts +1 -1
  510. package/dist/daemon/api/handlers/nodes.js +1 -1
  511. package/dist/daemon/api/handlers/profiles.d.ts +4 -1
  512. package/dist/daemon/api/handlers/profiles.js +1 -1
  513. package/dist/daemon/api/handlers/reports.js +5 -3
  514. package/dist/daemon/api/handlers/reviews.d.ts +1 -1
  515. package/dist/daemon/api/handlers/reviews.js +1 -1
  516. package/dist/daemon/api/handlers/run-routes.d.ts +2 -0
  517. package/dist/daemon/api/handlers/run-routes.js +1 -0
  518. package/dist/daemon/api/handlers/runs.d.ts +9 -0
  519. package/dist/daemon/api/handlers/runs.js +1 -0
  520. package/dist/daemon/api/handlers/subscriptions.js +1 -1
  521. package/dist/daemon/api/handlers/worktree.js +1 -1
  522. package/dist/daemon/api/map.d.ts +10 -4
  523. package/dist/daemon/api/map.js +2 -2
  524. package/dist/daemon/api/operations.d.ts +18 -0
  525. package/dist/daemon/api/operations.js +1 -0
  526. package/dist/daemon/api/principal.d.ts +42 -0
  527. package/dist/daemon/api/principal.js +1 -0
  528. package/dist/daemon/api/router.d.ts +27 -3
  529. package/dist/daemon/api/router.js +1 -1
  530. package/dist/daemon/api/server.d.ts +4 -0
  531. package/dist/daemon/api/server.js +1 -1
  532. package/dist/daemon/api/vendor-signin.d.ts +7 -0
  533. package/dist/daemon/api/vendor-signin.js +77 -0
  534. package/dist/daemon/api/viewer-presence.d.ts +3 -0
  535. package/dist/daemon/api/viewer-presence.js +1 -0
  536. package/dist/daemon/cron/armed-context.d.ts +4 -0
  537. package/dist/daemon/cron/armed-context.js +1 -1
  538. package/dist/daemon/cron/escalation.js +3 -3
  539. package/dist/daemon/cron/lease-recovery.js +1 -1
  540. package/dist/daemon/cron/sinks.js +2 -2
  541. package/dist/daemon/cron-run.d.ts +5 -5
  542. package/dist/daemon/cron-run.js +1 -1
  543. package/dist/daemon/crtrd.js +8 -7
  544. package/dist/daemon/delivery/run-delivery.d.ts +4 -0
  545. package/dist/daemon/delivery/run-delivery.js +1 -1
  546. package/dist/daemon/fleet.d.ts +1 -1
  547. package/dist/daemon/fleet.js +6 -6
  548. package/dist/daemon/human/finish.js +7 -7
  549. package/dist/daemon/joined-owner.d.ts +5 -0
  550. package/dist/daemon/joined-owner.js +1 -0
  551. package/dist/daemon/manage.js +2 -2
  552. package/dist/daemon/messaging/node-message.js +1 -1
  553. package/dist/daemon/park-activity.js +1 -1
  554. package/dist/daemon/reconcilers/bash-deadline.js +1 -1
  555. package/dist/daemon/reconcilers/broker-supervision.d.ts +1 -1
  556. package/dist/daemon/reconcilers/broker-supervision.js +4 -4
  557. package/dist/daemon/reconcilers/delivery-lane.js +1 -1
  558. package/dist/daemon/reconcilers/live-obligation.d.ts +7 -0
  559. package/dist/daemon/reconcilers/live-obligation.js +1 -1
  560. package/dist/daemon/reconcilers/node-lifecycle/tick.js +1 -1
  561. package/dist/daemon/reconcilers/storage-maintenance.d.ts +20 -1
  562. package/dist/daemon/reconcilers/storage-maintenance.js +1 -1
  563. package/dist/daemon/runs/append-section.d.ts +6 -0
  564. package/dist/daemon/runs/append-section.js +2 -0
  565. package/dist/daemon/runs/observer.d.ts +5 -0
  566. package/dist/daemon/runs/observer.js +4 -0
  567. package/dist/launcher/bwrap.d.ts +4 -0
  568. package/dist/launcher/bwrap.js +2 -0
  569. package/dist/launcher/client.d.ts +2 -0
  570. package/dist/launcher/client.js +3 -0
  571. package/dist/launcher/main.d.ts +1 -0
  572. package/dist/launcher/main.js +3 -0
  573. package/dist/launcher/netrule.d.ts +1 -0
  574. package/dist/launcher/netrule.js +1 -0
  575. package/dist/launcher/seccomp.d.ts +1 -0
  576. package/dist/launcher/seccomp.js +1 -0
  577. package/dist/launcher/spec.d.ts +88 -0
  578. package/dist/launcher/spec.js +1 -0
  579. package/dist/launcher/users.d.ts +18 -0
  580. package/dist/launcher/users.js +7 -0
  581. package/dist/launcher/validate.d.ts +22 -0
  582. package/dist/launcher/validate.js +1 -0
  583. package/dist/migrations/corpus.js +3 -3
  584. package/dist/migrations/runner.js +1 -1
  585. package/dist/native/linux/addon.node +0 -0
  586. package/dist/native/linux.d.ts +29 -0
  587. package/dist/native/linux.js +1 -0
  588. package/dist/pi-extensions/broker-local.js +2 -2
  589. package/dist/pi-extensions/canvas-bash-valve.d.ts +1 -3
  590. package/dist/pi-extensions/canvas-bash-valve.js +4 -7
  591. package/dist/pi-extensions/canvas-context-intro.d.ts +1 -2
  592. package/dist/pi-extensions/canvas-context-intro.js +2 -2
  593. package/dist/pi-extensions/canvas-doc-substrate.js +6 -6
  594. package/dist/pi-extensions/canvas-inbox-watcher.d.ts +2 -1
  595. package/dist/pi-extensions/canvas-inbox-watcher.js +2 -1
  596. package/dist/pi-extensions/canvas-passive-context.d.ts +1 -1
  597. package/dist/pi-extensions/canvas-passive-context.js +11 -11
  598. package/dist/pi-extensions/canvas-recap.js +6 -6
  599. package/dist/pi-extensions/canvas-stophook.js +1 -1
  600. package/dist/pi-extensions/canvas-structured-output.js +4 -4
  601. package/dist/pi-extensions/canvas-tool-guide.js +1 -1
  602. package/dist/pi-extensions/system-prompt-entry.d.ts +15 -0
  603. package/dist/pi-extensions/system-prompt-entry.js +1 -0
  604. package/dist/shared/env.d.ts +5 -1
  605. package/dist/shared/env.js +1 -1
  606. package/dist/shared/strip-cd-prefix.d.ts +1 -0
  607. package/dist/shared/strip-cd-prefix.js +1 -0
  608. package/dist/types.d.ts +31 -15
  609. package/docs/cli/memory-and-preferences.md +3 -1
  610. package/docs/sdk/client.md +34 -0
  611. package/docs/sdk/errors.md +2 -0
  612. package/docs/sdk/memory.md +2 -2
  613. package/docs/sdk/streaming.md +21 -0
  614. package/package.json +18 -4
  615. package/packages/crouter-identity/dist/index.d.ts +54 -0
  616. package/packages/crouter-identity/dist/index.js +166 -0
  617. package/packages/crouter-identity/package.json +33 -0
  618. package/runtime.lock.json +34 -8
  619. package/scripts/build-native-linux.mjs +16 -0
  620. package/scripts/install-runtime.mjs +9 -7
  621. package/scripts/lib/isolation-env.mjs +42 -0
  622. package/scripts/runtime-smoke.mjs +49 -0
  623. package/src/native/linux/addon.c +249 -0
  624. package/dist/core/profiles/state-block.d.ts +0 -4
  625. package/dist/core/profiles/state-block.js +0 -3
  626. package/dist/core/runtime/broker/auth-reload.d.ts +0 -41
  627. package/dist/core/runtime/broker/auth-reload.js +0 -1
  628. package/dist/core/substrate/cli-context-delivery.d.ts +0 -22
  629. package/dist/core/substrate/cli-context-delivery.js +0 -1
@@ -1,14 +1,14 @@
1
- var j=Object.defineProperty;var o=(e,n)=>j(e,"name",{value:n,configurable:!0});import{envNodeId as O}from"../../shared/env.js";import{existsSync as F,realpathSync as H,rmSync as R,statSync as I}from"node:fs";import{join as U,resolve as M}from"node:path";import{openDb as a,withCanvasWrite as _}from"./db.js";import{activateArmedExternalActionDelivery as P,armExternalActionDelivery as C}from"./deliveries.js";import{findNodeBySessionFileSql as $}from"./sessions.js";import{hydrateFault as B}from"./recovery.js";import{hasUnreconciledWorktree as z,openWorktree as J,readWorktree as Y,worktreeFromRow as q}from"./worktrees.js";import{isPidAlive as y,recordedPidLiveness as V}from"./pid.js";import{ensureHome as G,ensureNodeDirs as K,jobDir as Q,nodeDir as S}from"./paths.js";function p(e,n){if(e==null)return null;const t=JSON.stringify(e);if(t===void 0)throw new TypeError(`${n} must be JSON-serializable`);return t}o(p,"jsonValue");function h(e,n,t){C(e,{destinationId:t.actionName,adapter:{adapter:"subprocess",argv:t.argv,cwd:t.cwd,config_origin:t.configOrigin,payload:t.payload??null},idempotencyKey:`node-outcome:${n}`})}o(h,"insertArmedOutcomeDelivery");function X(e,n){n.prepare('INSERT INTO nodes (node_id, name, description, title, icon, cycles, kind, mode, lifecycle, cwd, host_kind, profile_id, parent, spawned_by, creator, fork_from, fork_source_file, created, passive_default, cycle_pending, model_override, persona_ack_json, review_binding_json, launch_config_json, scopes_json, status, intent, waiting_for, final_report, finalized_at, deadline_at, "window", tmux_session, pane) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)').run(e.node_id,e.name,e.description??null,e.title??null,e.icon??null,e.cycles??null,e.kind,e.mode,e.lifecycle,e.cwd,e.host_kind??null,e.profile_id??null,e.parent??null,e.spawned_by??null,e.creator??null,e.fork_from??null,e.fork_source_file??null,e.created,e.passive_default===!0?1:0,e.cycle_pending===!0?1:0,e.model_override??null,p(e.persona_ack,"persona_ack"),p(e.review_binding,"review_binding"),p(e.launch,"launch"),p(e.scopes,"scopes"),e.status??"active",e.intent??null,e.waiting_for??null,e.final_report??null,e.finalized_at??null,e.deadline_at??null,e.window??null,e.tmux_session??null,e.pane??null)}o(X,"seedRow");function T(e){if(e.fault_id==null)return null;const n=Object.entries(e).filter(([t])=>t.startsWith("fault_")).map(([t,r])=>[t==="fault_id"?t:t.slice(6),r]);return B(Object.fromEntries(n))}o(T,"faultFrom");function f(e){const n={node_id:e.node_id,name:e.name,description:e.description??void 0,cycles:e.cycles??void 0,kind:e.kind,mode:e.mode,lifecycle:e.lifecycle,status:e.status,cwd:e.cwd,host_kind:e.host_kind??null,profile_id:e.profile_id??null,scopes:e.scopes_json==null?null:JSON.parse(e.scopes_json),parent:e.parent??null,created:e.created,intent:e.intent??null,waiting_for:e.waiting_for??null,frozen_at:e.frozen_at??null,respawn_failures:e.respawn_failures??0,respawn_not_before:e.respawn_not_before??null,launched_at:e.launched_at??null,last_settled_at:e.last_settled_at??null,terminal_reason:e.terminal_reason??null,final_report:e.final_report??null,finalized_at:e.finalized_at??null,outcome_kind:e.outcome_kind??null,outcome_reason:e.outcome_reason??null,outcome_at:e.outcome_at??null,outcome_revision:e.outcome_revision??0,outcome_detail_json:e.outcome_detail_json??null,deadline_at:e.deadline_at??null,telemetry_tokens_in:e.telemetry_tokens_in??null,telemetry_context_tokens:e.telemetry_context_tokens??null,telemetry_last_activity:e.telemetry_last_activity??null,telemetry_updated_at:e.telemetry_updated_at??null,pi_pid:e.pi_pid??null,pi_pid_identity:e.pi_pid_identity??null,window:e.window??null,tmux_session:e.tmux_session??null,pane:e.pane??null,fault:null,streaming:!1},t=n.pi_pid===null?!1:y(n.pi_pid),r=T(e);return n.fault=r?.link==="pi\u2192provider"&&r.retry.by==="daemon"&&r.retry.disposition==="auto"&&!t?null:r,n.streaming=e.turn_open_at!==null&&e.turn_closed_at===null&&t,n}o(f,"rowFrom");function D(e,n=Y(e.node_id)){return{...f(e),title:e.title??void 0,icon:e.icon??void 0,spawned_by:e.spawned_by??null,creator:e.creator??null,fork_from:e.fork_from??null,fork_source_file:e.fork_source_file??null,passive_default:e.passive_default===1,cycle_pending:e.cycle_pending===1,model_override:e.model_override??null,scopes:e.scopes_json==null?null:JSON.parse(e.scopes_json),persona_ack:e.persona_ack_json==null?void 0:JSON.parse(e.persona_ack_json),review_binding:e.review_binding_json==null?void 0:JSON.parse(e.review_binding_json),launch:e.launch_config_json==null?void 0:JSON.parse(e.launch_config_json),pi_session_id:e.pi_session_id??null,pi_session_file:e.pi_session_file??null,...n===null?{}:{managed_worktree:n}}}o(D,"metaFrom");function Ee(e,n={}){return G(),_(t=>{X(e,t),e.managed_worktree!==void 0&&e.managed_worktree!==null&&J(e.node_id,e.managed_worktree,t),n.outcomeDelivery!==void 0&&h(t,e.node_id,n.outcomeDelivery)}),K(e.node_id),E(e.node_id)}o(Ee,"createNode");function E(e){const n=a().prepare("SELECT * FROM node_rows WHERE node_id = ?").get(e);return n===void 0?null:D(n)}o(E,"getNode");function me(e){const n=M(e);return F(n)?H(n):n}o(me,"canonicalSessionFile");function we(e){const n=$(e);return n===null?null:E(n)}o(we,"findNodeBySessionFile");function Ne(e){const n=a().prepare("SELECT * FROM node_rows WHERE node_id = ?").get(e);return n?f(n):null}o(Ne,"getRow");function Re(e){const n=a().prepare("SELECT * FROM node_rows WHERE pane = ?").get(e);return n?f(n):null}o(Re,"getRowByPane");function ye(e){return a().prepare(`SELECT * FROM node_rows
1
+ var Y=Object.defineProperty;var r=(e,n)=>Y(e,"name",{value:n,configurable:!0});import{envNodeId as L}from"../../shared/env.js";import{rmdirSync as q,rmSync as V,statSync as K}from"node:fs";import{dirname as G,join as v,resolve as Q}from"node:path";import{removeTreeBeneath as A}from"../spaces/open-beneath.js";import{emitEvent as X}from"../events/emit.js";import{openDb as a,withCanvasWrite as _}from"./db.js";import{conversationStore as Z,ConversationNotFoundError as ee}from"../conversation-store/index.js";import{activateArmedExternalActionDelivery as ne,armExternalActionDelivery as te,hasUnseenWakeMail as oe}from"./deliveries.js";import{findNodeBySessionFileSql as re}from"./sessions.js";import{hydrateFault as ie}from"./recovery.js";import{hasUnreconciledWorktree as se,openWorktree as ae,readWorktree as de,worktreeFromRow as le}from"./worktrees.js";import{isPidAlive as ue,isPidPresent as b,recordedPidLiveness as ce}from"./pid.js";import{ensureHome as _e,jobDir as pe,nodeDir as fe,nodeRunDir as k}from"./paths.js";import{appForNode as Ee,ensureNodeDirs as me,nodeAgentDir as Ne}from"./node-agent-paths.js";import{memoryDir as ge}from"../runtime/memory.js";import{appSpace as x}from"../layout.js";function f(e,n){if(e==null)return null;const t=JSON.stringify(e);if(t===void 0)throw new TypeError(`${n} must be JSON-serializable`);return t}r(f,"jsonValue");function W(e,n,t){te(e,{destinationId:t.actionName,adapter:{adapter:"subprocess",argv:t.argv,cwd:t.cwd,config_origin:t.configOrigin,payload:t.payload??null},idempotencyKey:`node-outcome:${n}`})}r(W,"insertArmedOutcomeDelivery");function Ue(e,n){if(e.prepare("SELECT deleting_at FROM nodes WHERE node_id = ?").get(n)?.deleting_at)throw new Error("run is deleting")}r(Ue,"assertRunNotDeleting");function Re(e,n){n.prepare(`INSERT INTO nodes (node_id, name, description, title, icon, cycles, kind, mode, lifecycle, cwd, host_kind, profile_id, parent, spawned_by, creator, fork_from, fork_source_file, created, passive_default, cycle_pending, model_override, persona_ack_json, review_binding_json, launch_config_json, scopes_json, status, intent, waiting_for, final_report, finalized_at, deadline_at, "window", tmux_session, pane, grantee, sub, grant_id, client_id, metadata_json, run_id, event_cursor, usage_json, deleting_at) VALUES (${Array(43).fill("?").join(", ")})`).run(e.node_id,e.name,e.description??null,e.title??null,e.icon??null,e.cycles??null,e.kind,e.mode,e.lifecycle,e.cwd,e.host_kind??null,e.profile_id??null,e.parent??null,e.spawned_by??null,e.creator??null,e.fork_from??null,e.fork_source_file??null,e.created,e.passive_default===!0?1:0,e.cycle_pending===!0?1:0,e.model_override??null,f(e.persona_ack,"persona_ack"),f(e.review_binding,"review_binding"),f(e.launch,"launch"),f(e.scopes,"scopes"),e.status??"active",e.intent??null,e.waiting_for??null,e.final_report??null,e.finalized_at??null,e.deadline_at??null,e.window??null,e.tmux_session??null,e.pane??null,e.grantee??"app:terminal",e.sub??null,e.grant_id??null,e.client_id??null,e.metadata_json??null,e.run_id??null,e.event_cursor??null,e.usage_json??null,e.deleting_at??null)}r(Re,"seedRow");function j(e){if(e.fault_id==null)return null;const n=Object.entries(e).filter(([t])=>t.startsWith("fault_")).map(([t,o])=>[t==="fault_id"?t:t.slice(6),o]);return ie(Object.fromEntries(n))}r(j,"faultFrom");function p(e){const n={node_id:e.node_id,name:e.name,description:e.description??void 0,cycles:e.cycles??void 0,kind:e.kind,mode:e.mode,lifecycle:e.lifecycle,status:e.status,cwd:e.cwd,host_kind:e.host_kind??null,profile_id:e.profile_id??null,scopes:e.scopes_json==null?null:JSON.parse(e.scopes_json),grantee:e.grantee,sub:e.sub??null,grant_id:e.grant_id??null,client_id:e.client_id??null,metadata_json:e.metadata_json??null,run_id:e.run_id??null,event_cursor:e.event_cursor??null,last_activity_at:e.last_activity_at??null,usage_json:e.usage_json??null,deleting_at:e.deleting_at??null,parent:e.parent??null,created:e.created,intent:e.intent??null,waiting_for:e.waiting_for??null,frozen_at:e.frozen_at??null,respawn_failures:e.respawn_failures??0,respawn_not_before:e.respawn_not_before??null,launched_at:e.launched_at??null,last_settled_at:e.last_settled_at??null,terminal_reason:e.terminal_reason??null,final_report:e.final_report??null,finalized_at:e.finalized_at??null,outcome_kind:e.outcome_kind??null,outcome_reason:e.outcome_reason??null,outcome_at:e.outcome_at??null,outcome_revision:e.outcome_revision??0,outcome_detail_json:e.outcome_detail_json??null,deadline_at:e.deadline_at??null,telemetry_tokens_in:e.telemetry_tokens_in??null,telemetry_context_tokens:e.telemetry_context_tokens??null,telemetry_last_activity:e.telemetry_last_activity??null,telemetry_updated_at:e.telemetry_updated_at??null,pi_pid:e.pi_pid??null,pi_pid_identity:e.pi_pid_identity??null,window:e.window??null,tmux_session:e.tmux_session??null,pane:e.pane??null,fault:null,streaming:!1},t=b(n.pi_pid),o=j(e);return n.fault=o?.link==="pi\u2192provider"&&o.retry.by==="daemon"&&o.retry.disposition==="auto"&&!t?null:o,n.streaming=e.turn_open_at!==null&&e.turn_closed_at===null&&t,n}r(p,"rowFrom");function F(e,n=de(e.node_id)){return{...p(e),title:e.title??void 0,icon:e.icon??void 0,spawned_by:e.spawned_by??null,creator:e.creator??null,fork_from:e.fork_from??null,fork_source_file:e.fork_source_file??null,passive_default:e.passive_default===1,cycle_pending:e.cycle_pending===1,model_override:e.model_override??null,scopes:e.scopes_json==null?null:JSON.parse(e.scopes_json),persona_ack:e.persona_ack_json==null?void 0:JSON.parse(e.persona_ack_json),review_binding:e.review_binding_json==null?void 0:JSON.parse(e.review_binding_json),launch:e.launch_config_json==null?void 0:JSON.parse(e.launch_config_json),pi_session_id:e.pi_session_id??null,pi_session_file:e.pi_session_file??null,...n===null?{}:{managed_worktree:n}}}r(F,"metaFrom");function Pe(e,n={}){return _e(),_(t=>{Re(e,t),e.managed_worktree!==void 0&&e.managed_worktree!==null&&ae(e.node_id,e.managed_worktree,t),n.outcomeDelivery!==void 0&&W(t,e.node_id,n.outcomeDelivery),n.withinCreate?.(t,e)}),me(e.node_id),E(e.node_id)}r(Pe,"createNode");function E(e){const n=a().prepare("SELECT * FROM node_rows WHERE node_id = ?").get(e);return n===void 0?null:F(n)}r(E,"getNode");function $e(e){return Q(e)}r($e,"canonicalSessionFile");function Be(e){const n=re(e);return n===null?null:E(n)}r(Be,"findNodeBySessionFile");function ze(e){const n=a().prepare("SELECT * FROM node_rows WHERE node_id = ?").get(e);return n?p(n):null}r(ze,"getRow");function Je(e){const n=a().prepare("SELECT * FROM node_rows WHERE pane = ?").get(e);return n?p(n):null}r(Je,"getRowByPane");function Ye(e){return a().prepare(`SELECT * FROM node_rows
2
2
  WHERE deadline_at IS NOT NULL AND outcome_at IS NULL
3
3
  AND deadline_at <= ? AND status IN ('active','idle') AND kind != 'human'
4
- ORDER BY deadline_at, created, node_id`).all(e).map(f)}o(ye,"dueNodeDeadlines");function Se(e,n){return Number(a().prepare("UPDATE nodes SET deadline_at = ? WHERE node_id = ?").run(n,e).changes)===1}o(Se,"setNodeDeadline");function ge(e,n){return!Number.isFinite(n)||n<=0?0:_(t=>{const r=t.prepare(`SELECT node_id, deadline_at FROM nodes
5
- WHERE profile_id = ? AND deadline_at IS NOT NULL AND status IN ('active', 'idle')`).all(e),i=t.prepare("UPDATE nodes SET deadline_at = ? WHERE node_id = ? AND deadline_at = ?");let s=0;for(const d of r){const u=Date.parse(d.deadline_at);Number.isNaN(u)||(s+=Number(i.run(new Date(u+n).toISOString(),d.node_id,d.deadline_at).changes))}return s})}o(ge,"shiftProfileNodeDeadlines");function Z(e,n){if(e==null)return null;if(typeof e=="string"||typeof e=="number"||typeof e=="bigint"||e instanceof Uint8Array)return e;throw new TypeError(`${n} must be a SQLite scalar`)}o(Z,"sqlInput");function Oe(e,n){const t=[],r=o((s,d=s)=>{Object.prototype.hasOwnProperty.call(n,s)&&t.push([d,Z(n[s],s)])},"add");if(r("name"),r("description"),r("title"),r("icon"),r("cycles"),r("kind"),r("mode"),r("lifecycle"),r("cwd"),r("host_kind"),r("profile_id"),r("parent"),r("spawned_by"),r("creator"),r("fork_from"),r("fork_source_file"),r("model_override"),Object.prototype.hasOwnProperty.call(n,"passive_default")&&t.push(["passive_default",n.passive_default===!0?1:0]),Object.prototype.hasOwnProperty.call(n,"cycle_pending")&&t.push(["cycle_pending",n.cycle_pending===!0?1:0]),Object.prototype.hasOwnProperty.call(n,"persona_ack")&&t.push(["persona_ack_json",p(n.persona_ack,"persona_ack")]),Object.prototype.hasOwnProperty.call(n,"review_binding")&&t.push(["review_binding_json",p(n.review_binding,"review_binding")]),Object.prototype.hasOwnProperty.call(n,"scopes")&&t.push(["scopes_json",p(n.scopes,"scopes")]),Object.prototype.hasOwnProperty.call(n,"launch")&&t.push(["launch_config_json",p(n.launch,"launch")]),t.length===0){const s=E(e);if(s===null)throw new Error(`unknown node: ${e}`);return s}if(a().prepare(`UPDATE nodes SET ${t.map(([s])=>`${s} = ?`).join(", ")} WHERE node_id = ?`).run(...t.map(([,s])=>s),e).changes!==1)throw new Error(`unknown node: ${e}`);return E(e)}o(Oe,"updateNode");function he(e,n){a().prepare("UPDATE nodes SET status = ? WHERE node_id = ?").run(n,e)}o(he,"setStatus");function Te(e,n){a().prepare("UPDATE nodes SET intent = ? WHERE node_id = ?").run(n??null,e)}o(Te,"setIntent");function De(e,n,t={}){if(t.outcome===void 0){const i=[],s=[];Object.prototype.hasOwnProperty.call(n,"status")&&(i.push("status = ?"),s.push(n.status??null)),Object.prototype.hasOwnProperty.call(n,"intent")&&(i.push("intent = ?"),s.push(n.intent??null)),Object.prototype.hasOwnProperty.call(n,"terminal_reason")&&(i.push("terminal_reason = ?"),s.push(n.terminal_reason??null));const d=["node_id = ?"];s.push(e),t.fromStatuses!==void 0&&(d.push(`status IN (${t.fromStatuses.map(()=>"?").join(", ")})`),s.push(...t.fromStatuses)),t.requireNoFinalReport===!0&&d.push("final_report IS NULL");const u=a().prepare(`UPDATE nodes SET ${i.join(", ")} WHERE ${d.join(" AND ")}`).run(...s);return Number(u.changes)}const r=t.outcome;return _(i=>{const s=[],d=[];Object.prototype.hasOwnProperty.call(n,"status")&&(s.push("status = ?"),d.push(n.status??null)),Object.prototype.hasOwnProperty.call(n,"intent")&&(s.push("intent = ?"),d.push(n.intent??null)),Object.prototype.hasOwnProperty.call(n,"terminal_reason")&&(s.push("terminal_reason = ?"),d.push(n.terminal_reason??null));const u=o((re,W)=>r.supersede===!0?"?":`CASE WHEN outcome_at IS NULL THEN ? ELSE ${W} END`,"outcomeValue");s.push(`outcome_kind = ${u(r.kind,"outcome_kind")}`,`outcome_reason = ${u(r.reason,"outcome_reason")}`,`outcome_detail_json = ${u(r.detailJson,"outcome_detail_json")}`,`outcome_revision = ${r.supersede===!0?"outcome_revision + 1":"CASE WHEN outcome_at IS NULL THEN outcome_revision + 1 ELSE outcome_revision END"}`,`outcome_at = ${u(r.at,"outcome_at")}`),d.push(r.kind,r.reason,r.detailJson,r.at);const c=["node_id = ?"];d.push(e),t.fromStatuses!==void 0&&(c.push(`status IN (${t.fromStatuses.map(()=>"?").join(", ")})`),d.push(...t.fromStatuses)),t.requireNoFinalReport===!0&&c.push("final_report IS NULL");const l=i.prepare(`UPDATE nodes SET ${s.join(", ")} WHERE ${c.join(" AND ")}`).run(...d);if(Number(l.changes)===0)return 0;const N=i.prepare("SELECT outcome_at FROM nodes WHERE node_id = ?").get(e);return(r.supersede===!0||N.outcome_at===r.at)&&r.documentJson!==null&&r.documentJson!==void 0&&P(i,{idempotencyKey:`node-outcome:${e}`,label:e,bodyJson:r.documentJson,supersede:r.supersede===!0}),Number(l.changes)})}o(De,"transitionStatusIntent");function Ae(e){return a().prepare("SELECT final_report FROM nodes WHERE node_id = ?").get(e)?.final_report??null}o(Ae,"getFinalReport");function Le(e,n){return a().prepare("UPDATE nodes SET final_report = NULL, finalized_at = NULL WHERE node_id = ? AND final_report = ?").run(e,n).changes>0}o(Le,"clearFinalReportIfMatches");function ke(e,n){a().prepare('UPDATE nodes SET tmux_session = ?, "window" = ?, pane = ? WHERE node_id = ?').run(n.tmux_session??null,n.window??null,n.pane??null,e)}o(ke,"setPresence");function ve(e,n){a().prepare("UPDATE nodes SET launched_at = ?, frozen_at = NULL, respawn_not_before = NULL WHERE node_id = ?").run(n,e)}o(ve,"recordLaunch");function be(e,n){a().prepare("UPDATE nodes SET last_settled_at = ? WHERE node_id = ?").run(n,e)}o(be,"recordSettledTurn");function xe(e,n){a().prepare("UPDATE nodes SET frozen_at = ? WHERE node_id = ?").run(n,e)}o(xe,"setFrozen");function We(e){a().prepare("UPDATE nodes SET frozen_at = NULL WHERE node_id = ?").run(e)}o(We,"clearFrozen");function je(e,n){a().prepare("UPDATE nodes SET respawn_failures = ?, respawn_not_before = ? WHERE node_id = ?").run(n.failures,n.notBefore,e)}o(je,"recordRespawnAttempt");const m="node_id NOT IN (SELECT node_id FROM warm_pool)",A=["state","cleanup_state","path","branch","repo_root","base_ref","base_sha","created_at","closed_at","next_attempt_at","attempts","quarantined","sweep_reason","sweep_detail","sweep_last_at","sweep_observed_json","abandoned_json","land_intent_json","disposal_json"];function ee(e){return e.worktree_state===null?null:q(Object.fromEntries(A.map(n=>[n,e[`worktree_${n}`]])))}o(ee,"worktreeFromProjection");function Fe(e){const n=A.map(r=>`w.${r} AS worktree_${r}`).join(", ");return a().prepare(`SELECT n.*, ${n} FROM node_rows n LEFT JOIN worktrees w ON w.node_id = n.node_id WHERE n.profile_id = ? ORDER BY n.created`).all(e).map(r=>D(r,ee(r)))}o(Fe,"listNodesByProfile");function He(){return a().prepare("SELECT node_id, cwd, profile_id FROM nodes ORDER BY created").all().map(e=>{const n=e;return{nodeId:n.node_id,cwd:n.cwd,profileId:n.profile_id}})}o(He,"listNodeMemoryTargets");function Ie(e,n){a().prepare(`UPDATE nodes
4
+ ORDER BY deadline_at, created, node_id`).all(e).map(p)}r(Ye,"dueNodeDeadlines");function qe(e,n){return Number(a().prepare("UPDATE nodes SET deadline_at = ? WHERE node_id = ?").run(n,e).changes)===1}r(qe,"setNodeDeadline");function Ve(e,n){return!Number.isFinite(n)||n<=0?0:_(t=>{const o=t.prepare(`SELECT node_id, deadline_at FROM nodes
5
+ WHERE profile_id = ? AND deadline_at IS NOT NULL AND status IN ('active', 'idle')`).all(e),i=t.prepare("UPDATE nodes SET deadline_at = ? WHERE node_id = ? AND deadline_at = ?");let s=0;for(const d of o){const l=Date.parse(d.deadline_at);Number.isNaN(l)||(s+=Number(i.run(new Date(l+n).toISOString(),d.node_id,d.deadline_at).changes))}return s})}r(Ve,"shiftProfileNodeDeadlines");function Ke(e,n,t){return Number(e.prepare("UPDATE nodes SET sub = ? WHERE sub = 'user:local'").run(n).changes)+Number(e.prepare("UPDATE nodes SET grantee = 'app:terminal' WHERE grantee = 'user:local'").run().changes)+Number(e.prepare("UPDATE nodes SET sub = ? WHERE sub IS NULL AND grantee = 'app:terminal'").run(n).changes)+Number(e.prepare("UPDATE nodes SET grant_id = NULL WHERE grant_id = ?").run(t).changes)}r(Ke,"rewriteLocalNodeIdentity");function ye(e,n){if(e==null)return null;if(typeof e=="string"||typeof e=="number"||typeof e=="bigint"||e instanceof Uint8Array)return e;throw new TypeError(`${n} must be a SQLite scalar`)}r(ye,"sqlInput");function Ge(e,n){const t=[],o=r((s,d=s)=>{Object.prototype.hasOwnProperty.call(n,s)&&t.push([d,ye(n[s],s)])},"add");if(o("name"),o("description"),o("title"),o("icon"),o("cycles"),o("kind"),o("mode"),o("lifecycle"),o("cwd"),o("host_kind"),o("profile_id"),o("parent"),o("spawned_by"),o("creator"),o("fork_from"),o("fork_source_file"),o("model_override"),Object.prototype.hasOwnProperty.call(n,"passive_default")&&t.push(["passive_default",n.passive_default===!0?1:0]),Object.prototype.hasOwnProperty.call(n,"cycle_pending")&&t.push(["cycle_pending",n.cycle_pending===!0?1:0]),Object.prototype.hasOwnProperty.call(n,"persona_ack")&&t.push(["persona_ack_json",f(n.persona_ack,"persona_ack")]),Object.prototype.hasOwnProperty.call(n,"review_binding")&&t.push(["review_binding_json",f(n.review_binding,"review_binding")]),Object.prototype.hasOwnProperty.call(n,"scopes")&&t.push(["scopes_json",f(n.scopes,"scopes")]),Object.prototype.hasOwnProperty.call(n,"launch")&&t.push(["launch_config_json",f(n.launch,"launch")]),t.length===0){const s=E(e);if(s===null)throw new Error(`unknown node: ${e}`);return s}if(a().prepare(`UPDATE nodes SET ${t.map(([s])=>`${s} = ?`).join(", ")} WHERE node_id = ?`).run(...t.map(([,s])=>s),e).changes!==1)throw new Error(`unknown node: ${e}`);return E(e)}r(Ge,"updateNode");function Qe(e,n){a().prepare("UPDATE nodes SET status = ? WHERE node_id = ?").run(n,e)}r(Qe,"setStatus");function Xe(e,n){a().prepare("UPDATE nodes SET intent = ? WHERE node_id = ?").run(n??null,e)}r(Xe,"setIntent");function Ze(e,n,t={}){if(t.outcome===void 0){const i=[],s=[];Object.prototype.hasOwnProperty.call(n,"status")&&(i.push("status = ?"),s.push(n.status??null)),Object.prototype.hasOwnProperty.call(n,"intent")&&(i.push("intent = ?"),s.push(n.intent??null)),Object.prototype.hasOwnProperty.call(n,"terminal_reason")&&(i.push("terminal_reason = ?"),s.push(n.terminal_reason??null));const d=["node_id = ?"];s.push(e),t.fromStatuses!==void 0&&(d.push(`status IN (${t.fromStatuses.map(()=>"?").join(", ")})`),s.push(...t.fromStatuses)),t.requireNoFinalReport===!0&&d.push("final_report IS NULL");const l=a().prepare(`UPDATE nodes SET ${i.join(", ")} WHERE ${d.join(" AND ")}`).run(...s);return Number(l.changes)}const o=t.outcome;return _(i=>{const s=[],d=[];Object.prototype.hasOwnProperty.call(n,"status")&&(s.push("status = ?"),d.push(n.status??null)),Object.prototype.hasOwnProperty.call(n,"intent")&&(s.push("intent = ?"),d.push(n.intent??null)),Object.prototype.hasOwnProperty.call(n,"terminal_reason")&&(s.push("terminal_reason = ?"),d.push(n.terminal_reason??null));const l=r((g,u)=>o.supersede===!0?"?":`CASE WHEN outcome_at IS NULL THEN ? ELSE ${u} END`,"outcomeValue");s.push(`outcome_kind = ${l(o.kind,"outcome_kind")}`,`outcome_reason = ${l(o.reason,"outcome_reason")}`,`outcome_detail_json = ${l(o.detailJson,"outcome_detail_json")}`,`outcome_revision = ${o.supersede===!0?"outcome_revision + 1":"CASE WHEN outcome_at IS NULL THEN outcome_revision + 1 ELSE outcome_revision END"}`,`outcome_at = ${l(o.at,"outcome_at")}`),d.push(o.kind,o.reason,o.detailJson,o.at);const c=["node_id = ?"];d.push(e),t.fromStatuses!==void 0&&(c.push(`status IN (${t.fromStatuses.map(()=>"?").join(", ")})`),d.push(...t.fromStatuses)),t.requireNoFinalReport===!0&&c.push("final_report IS NULL");const m=i.prepare(`UPDATE nodes SET ${s.join(", ")} WHERE ${c.join(" AND ")}`).run(...d);if(Number(m.changes)===0)return 0;const y=i.prepare("SELECT outcome_at FROM nodes WHERE node_id = ?").get(e);return(o.supersede===!0||y.outcome_at===o.at)&&o.documentJson!==null&&o.documentJson!==void 0&&ne(i,{idempotencyKey:`node-outcome:${e}`,label:e,bodyJson:o.documentJson,supersede:o.supersede===!0}),Number(m.changes)})}r(Ze,"transitionStatusIntent");function en(e){return a().prepare("SELECT final_report FROM nodes WHERE node_id = ?").get(e)?.final_report??null}r(en,"getFinalReport");function nn(e,n){return a().prepare("UPDATE nodes SET final_report = NULL, finalized_at = NULL WHERE node_id = ? AND final_report = ?").run(e,n).changes>0}r(nn,"clearFinalReportIfMatches");function tn(e,n){a().prepare('UPDATE nodes SET tmux_session = ?, "window" = ?, pane = ? WHERE node_id = ?').run(n.tmux_session??null,n.window??null,n.pane??null,e)}r(tn,"setPresence");function on(e,n){a().prepare("UPDATE nodes SET launched_at = ?, frozen_at = NULL, respawn_not_before = NULL WHERE node_id = ?").run(n,e)}r(on,"recordLaunch");function rn(e,n){a().prepare("UPDATE nodes SET last_settled_at = ? WHERE node_id = ?").run(n,e)}r(rn,"recordSettledTurn");function sn(e,n){a().prepare("UPDATE nodes SET frozen_at = ? WHERE node_id = ?").run(n,e)}r(sn,"setFrozen");function an(e){a().prepare("UPDATE nodes SET frozen_at = NULL WHERE node_id = ?").run(e)}r(an,"clearFrozen");function dn(e,n){a().prepare("UPDATE nodes SET respawn_failures = ?, respawn_not_before = ? WHERE node_id = ?").run(n.failures,n.notBefore,e)}r(dn,"recordRespawnAttempt");const N="node_id NOT IN (SELECT node_id FROM warm_pool)",H=["state","cleanup_state","path","branch","repo_root","base_ref","base_sha","created_at","closed_at","next_attempt_at","attempts","quarantined","sweep_reason","sweep_detail","sweep_last_at","sweep_observed_json","abandoned_json","land_intent_json","disposal_json"];function Se(e){return e.worktree_state===null?null:le(Object.fromEntries(H.map(n=>[n,e[`worktree_${n}`]])))}r(Se,"worktreeFromProjection");function ln(e){const n=H.map(o=>`w.${o} AS worktree_${o}`).join(", ");return a().prepare(`SELECT n.*, ${n} FROM node_rows n LEFT JOIN worktrees w ON w.node_id = n.node_id WHERE n.profile_id = ? ORDER BY n.created`).all(e).map(o=>F(o,Se(o)))}r(ln,"listNodesByProfile");function un(){return a().prepare("SELECT node_id, cwd, profile_id, grantee FROM nodes ORDER BY created").all().map(e=>{const n=e;return{nodeId:n.node_id,cwd:n.cwd,profileId:n.profile_id,grantee:n.grantee}})}r(un,"listNodeMemoryTargets");function cn(e,n){a().prepare(`UPDATE nodes
6
6
  SET telemetry_tokens_in = ?,
7
7
  telemetry_context_tokens = COALESCE(?, telemetry_context_tokens),
8
8
  telemetry_last_activity = COALESCE(?, telemetry_last_activity),
9
9
  telemetry_updated_at = ?
10
10
  WHERE node_id = ?
11
- AND (telemetry_updated_at IS NULL OR telemetry_updated_at < ?)`).run(n.tokensIn,n.contextTokens,n.lastActivity,n.updatedAt,e,n.updatedAt)}o(Ie,"updateNodeTelemetry");function Ue(){return a().prepare(`SELECT
11
+ AND (telemetry_updated_at IS NULL OR telemetry_updated_at < ?)`).run(n.tokensIn,n.contextTokens,n.lastActivity,n.updatedAt,e,n.updatedAt)}r(cn,"updateNodeTelemetry");function _n(){return a().prepare(`SELECT
12
12
  node_id, name, description, cycles, kind, status, frozen_at,
13
13
  telemetry_context_tokens, telemetry_last_activity,
14
14
  pi_pid, turn_open_at, turn_closed_at,
@@ -16,28 +16,29 @@ var j=Object.defineProperty;var o=(e,n)=>j(e,"name",{value:n,configurable:!0});i
16
16
  fault_operation_id, fault_anchor_entry_id, fault_retry_disposition,
17
17
  fault_retry_by, fault_retry_attempt, fault_retry_max, fault_retry_next_at,
18
18
  fault_provider_error_json
19
- FROM node_rows WHERE ${m} ORDER BY created`).all().map(n=>{const t=n.pi_pid??null,r=y(t),i=T(n);return{node_id:n.node_id,name:n.name,description:n.description??null,cycles:n.cycles??null,kind:n.kind,status:n.status,frozen_at:n.frozen_at??null,pi_pid:t,telemetry_context_tokens:n.telemetry_context_tokens??null,telemetry_last_activity:n.telemetry_last_activity??null,fault:i?.link==="pi\u2192provider"&&i.retry.by==="daemon"&&i.retry.disposition==="auto"&&!r?null:i,streaming:n.turn_open_at!==null&&n.turn_closed_at===null&&r}})}o(Ue,"graphNodes");function ne(e){const n=[m],t=[];if(e?.status!==void 0){const i=Array.isArray(e.status)?e.status:[e.status];n.push(`status IN (${i.map(()=>"?").join(",")})`),t.push(...i)}return e?.withRecordedPid===!0&&n.push("pi_pid IS NOT NULL"),e?.withRecordedPidOrFrozen===!0&&n.push("(pi_pid IS NOT NULL OR frozen_at IS NOT NULL)"),a().prepare(`SELECT * FROM node_rows WHERE ${n.join(" AND ")} ORDER BY created`).all(...t).map(f)}o(ne,"listNodes");function Me(){return a().prepare(`SELECT * FROM node_rows
20
- WHERE ${m} AND kind != 'human'
19
+ FROM node_rows WHERE ${N} ORDER BY created`).all().map(n=>{const t=n.pi_pid??null,o=b(t),i=j(n);return{node_id:n.node_id,name:n.name,description:n.description??null,cycles:n.cycles??null,kind:n.kind,status:n.status,frozen_at:n.frozen_at??null,pi_pid:t,telemetry_context_tokens:n.telemetry_context_tokens??null,telemetry_last_activity:n.telemetry_last_activity??null,fault:i?.link==="pi\u2192provider"&&i.retry.by==="daemon"&&i.retry.disposition==="auto"&&!o?null:i,streaming:n.turn_open_at!==null&&n.turn_closed_at===null&&o}})}r(_n,"graphNodes");function we(e){const n=[N],t=[];if(e?.status!==void 0){const i=Array.isArray(e.status)?e.status:[e.status];n.push(`status IN (${i.map(()=>"?").join(",")})`),t.push(...i)}return e?.withRecordedPid===!0&&n.push("pi_pid IS NOT NULL"),e?.withRecordedPidOrFrozen===!0&&n.push("(pi_pid IS NOT NULL OR frozen_at IS NOT NULL)"),a().prepare(`SELECT * FROM node_rows WHERE ${n.join(" AND ")} ORDER BY created`).all(...t).map(p)}r(we,"listNodes");function pn(){return a().prepare(`SELECT * FROM node_rows
20
+ WHERE ${N} AND kind != 'human'
21
21
  AND (status IN ('active', 'idle') OR (status IN ('done', 'canceled', 'dead') AND (pi_pid IS NOT NULL OR frozen_at IS NOT NULL)))
22
- ORDER BY created`).all().map(f)}o(Me,"listNodesForSupervision");function Pe(){return a().prepare(`SELECT node_id, name, created FROM nodes WHERE ${m} ORDER BY created`).all()}o(Pe,"listNodeIdentities");function Ce(e,n){_(t=>{t.prepare("INSERT OR REPLACE INTO warm_pool (node_id, recipe_key, created) VALUES (?, ?, ?)").run(e,n,new Date().toISOString())})}o(Ce,"registerWarmSpare");function $e(e){return _(n=>n.prepare("DELETE FROM warm_pool WHERE node_id = ?").run(e).changes>0)}o($e,"unregisterWarmSpare");function g(e,n){const t=`SELECT w.node_id AS node_id, w.recipe_key AS recipe_key, w.created AS created,
22
+ ORDER BY created`).all().map(p)}r(pn,"listNodesForSupervision");function fn(){return a().prepare(`SELECT node_id, name, created FROM nodes WHERE ${N} ORDER BY created`).all()}r(fn,"listNodeIdentities");function En(e,n){_(t=>{t.prepare("INSERT OR REPLACE INTO warm_pool (node_id, recipe_key, created) VALUES (?, ?, ?)").run(e,n,new Date().toISOString())})}r(En,"registerWarmSpare");function mn(e){return _(n=>n.prepare("DELETE FROM warm_pool WHERE node_id = ?").run(e).changes>0)}r(mn,"unregisterWarmSpare");function S(e,n){const t=`SELECT w.node_id AS node_id, w.recipe_key AS recipe_key, w.created AS created,
23
23
  n.status AS status, n.pi_pid AS pi_pid, n.pi_pid_identity AS pi_pid_identity
24
- FROM warm_pool w JOIN node_rows n ON n.node_id = w.node_id`+(n===void 0?"":" WHERE w.recipe_key = ?")+" ORDER BY w.created";return(n===void 0?e.prepare(t).all():e.prepare(t).all(n)).map(i=>({node_id:i.node_id,recipe_key:i.recipe_key,created:i.created,status:i.status,pi_pid:i.pi_pid??null,pi_pid_identity:i.pi_pid_identity??null}))}o(g,"warmSpareRowsFor");function Be(){return g(a())}o(Be,"listWarmSpares");function ze(e){return a().prepare("SELECT 1 FROM warm_pool WHERE node_id = ?").get(e)!==void 0}o(ze,"isWarmSpare");function L(e){return e.status!=="active"&&e.status!=="idle"?!1:V(e.pi_pid,e.pi_pid_identity)==="alive"}o(L,"spareIsClaimable");function Je(e,n,t={}){return _(r=>{const i=g(r,e).find(L);return i===void 0||r.prepare("DELETE FROM warm_pool WHERE node_id = ?").run(i.node_id).changes===0?null:(r.prepare("UPDATE nodes SET created = ?, deadline_at = ? WHERE node_id = ?").run(n,t.deadlineAt??null,i.node_id),t.outcomeDelivery!==void 0&&h(r,i.node_id,t.outcomeDelivery),i.node_id)})}o(Je,"claimWarmSpare");function Ye(e){return g(a(),e).filter(L).length}o(Ye,"warmSpareCount");function qe(e){return a().prepare("SELECT node_id FROM nodes WHERE parent = ? ORDER BY created").all(e).map(n=>n.node_id)}o(qe,"childrenOf");function Ve(){return a().prepare(`SELECT node_id, name, kind, mode, lifecycle, status, cwd, host_kind, parent, created
25
- FROM nodes WHERE ${m} ORDER BY created`).all().map(e=>({node_id:e.node_id,name:e.name,kind:e.kind,mode:e.mode,lifecycle:e.lifecycle,status:e.status,cwd:e.cwd,host_kind:e.host_kind??null,parent:e.parent??null,created:e.created}))}o(Ve,"rosterNodes");function Ge(){return a().prepare("SELECT from_id, to_id, active, created FROM edges WHERE type = 'subscribes_to' ORDER BY created").all().map(e=>({from_id:e.from_id,to_id:e.to_id,active:e.active===1,created:e.created}))}o(Ge,"rosterEdges");function Ke(e){return a().prepare(`SELECT * FROM node_rows
24
+ FROM warm_pool w JOIN node_rows n ON n.node_id = w.node_id`+(n===void 0?"":" WHERE w.recipe_key = ?")+" ORDER BY w.created";return(n===void 0?e.prepare(t).all():e.prepare(t).all(n)).map(i=>({node_id:i.node_id,recipe_key:i.recipe_key,created:i.created,status:i.status,pi_pid:i.pi_pid??null,pi_pid_identity:i.pi_pid_identity??null}))}r(S,"warmSpareRowsFor");function Nn(){return S(a())}r(Nn,"listWarmSpares");function gn(e){return a().prepare("SELECT 1 FROM warm_pool WHERE node_id = ?").get(e)!==void 0}r(gn,"isWarmSpare");function M(e){return e.status!=="active"&&e.status!=="idle"?!1:ce(e.pi_pid,e.pi_pid_identity)==="alive"}r(M,"spareIsClaimable");function Rn(e,n,t={}){return _(o=>{const i=S(o,e).find(M);return i===void 0||o.prepare("DELETE FROM warm_pool WHERE node_id = ?").run(i.node_id).changes===0?null:(o.prepare("UPDATE nodes SET created = ?, deadline_at = ? WHERE node_id = ?").run(n,t.deadlineAt??null,i.node_id),t.outcomeDelivery!==void 0&&W(o,i.node_id,t.outcomeDelivery),i.node_id)})}r(Rn,"claimWarmSpare");function yn(e){return S(a(),e).filter(M).length}r(yn,"warmSpareCount");function Sn(e){return a().prepare("SELECT node_id FROM nodes WHERE parent = ? ORDER BY created").all(e).map(n=>n.node_id)}r(Sn,"childrenOf");function wn(){return a().prepare(`SELECT node_id, name, kind, mode, lifecycle, status, cwd, host_kind, parent, created
25
+ FROM nodes WHERE ${N} ORDER BY created`).all().map(e=>({node_id:e.node_id,name:e.name,kind:e.kind,mode:e.mode,lifecycle:e.lifecycle,status:e.status,cwd:e.cwd,host_kind:e.host_kind??null,parent:e.parent??null,created:e.created}))}r(wn,"rosterNodes");function On(){return a().prepare("SELECT from_id, to_id, active, created FROM edges WHERE type = 'subscribes_to' ORDER BY created").all().map(e=>({from_id:e.from_id,to_id:e.to_id,active:e.active===1,created:e.created}))}r(On,"rosterEdges");function hn(e){return a().prepare(`SELECT * FROM node_rows
26
26
  WHERE parent IS NULL AND kind != 'human'
27
27
  AND status IN ('active','idle') AND cwd = ?
28
- AND ${m}
29
- ORDER BY created DESC`).all(e).map(f)}o(Ke,"listResumableRoots");function k(e,n,t,r){a().prepare(`INSERT INTO edges (type, from_id, to_id, active, created)
28
+ AND ${N}
29
+ ORDER BY created DESC`).all(e).map(p)}r(hn,"listResumableRoots");function C(e,n,t,o){a().prepare(`INSERT INTO edges (type, from_id, to_id, active, created)
30
30
  VALUES (?, ?, ?, ?, ?)
31
- ON CONFLICT(type, from_id, to_id) DO UPDATE SET active=excluded.active`).run(e,n,t,r?1:0,new Date().toISOString())}o(k,"addEdge");function Qe(e,n,t=!0){k("subscribes_to",e,n,t)}o(Qe,"subscribe");function Xe(e,n){a().prepare("DELETE FROM edges WHERE type = ? AND from_id = ? AND to_id = ?").run("subscribes_to",e,n)}o(Xe,"unsubscribe");function Ze(e,n,t){a().prepare("UPDATE edges SET active = ? WHERE type = ? AND from_id = ? AND to_id = ?").run(t?1:0,"subscribes_to",e,n)}o(Ze,"setSubscriptionActive");function en(e,n){k("spawned_by",e,n,!0)}o(en,"recordSpawn");function nn(e){return a().prepare(`SELECT from_id AS node_id, active, created FROM edges
32
- WHERE type = 'subscribes_to' AND to_id = ? ORDER BY created`).all(e).map(n=>({node_id:n.node_id,active:n.active===1,created:n.created}))}o(nn,"subscribersOf");function v(e){return a().prepare(`SELECT to_id AS node_id, active, created FROM edges
33
- WHERE type = 'subscribes_to' AND from_id = ? ORDER BY created`).all(e).map(n=>({node_id:n.node_id,active:n.active===1,created:n.created}))}o(v,"subscriptionsOf");function tn(e){const n=new Set([e]),t=[],r=v(e).map(i=>i.node_id);for(;r.length>0;){const i=r.shift();if(!n.has(i)){n.add(i),t.push(i);for(const s of v(i))n.has(s.node_id)||r.push(s.node_id)}}return t}o(tn,"view");function rn(e){return a().prepare(`SELECT 1 FROM edges e JOIN nodes n ON n.node_id = e.to_id
31
+ ON CONFLICT(type, from_id, to_id) DO UPDATE SET active=excluded.active`).run(e,n,t,o?1:0,new Date().toISOString())}r(C,"addEdge");function Tn(e,n,t=!0){C("subscribes_to",e,n,t)}r(Tn,"subscribe");function Dn(e,n){a().prepare("DELETE FROM edges WHERE type = ? AND from_id = ? AND to_id = ?").run("subscribes_to",e,n)}r(Dn,"unsubscribe");function Ln(e,n,t){a().prepare("UPDATE edges SET active = ? WHERE type = ? AND from_id = ? AND to_id = ?").run(t?1:0,"subscribes_to",e,n)}r(Ln,"setSubscriptionActive");function vn(e,n){C("spawned_by",e,n,!0)}r(vn,"recordSpawn");function An(e){return a().prepare(`SELECT from_id AS node_id, active, created FROM edges
32
+ WHERE type = 'subscribes_to' AND to_id = ? ORDER BY created`).all(e).map(n=>({node_id:n.node_id,active:n.active===1,created:n.created}))}r(An,"subscribersOf");function I(e){return a().prepare(`SELECT to_id AS node_id, active, created FROM edges
33
+ WHERE type = 'subscribes_to' AND from_id = ? ORDER BY created`).all(e).map(n=>({node_id:n.node_id,active:n.active===1,created:n.created}))}r(I,"subscriptionsOf");function bn(e){const n=new Set([e]),t=[],o=I(e).map(i=>i.node_id);for(;o.length>0;){const i=o.shift();if(!n.has(i)){n.add(i),t.push(i);for(const s of I(i))n.has(s.node_id)||o.push(s.node_id)}}return t}r(bn,"view");function kn(e){return a().prepare(`SELECT 1 FROM edges e JOIN nodes n ON n.node_id = e.to_id
34
34
  WHERE e.type = 'subscribes_to' AND e.from_id = ? AND e.active = 1
35
- AND n.status IN ('active', 'idle') LIMIT 1`).get(e)!==void 0}o(rn,"hasActiveLiveSubscription");function on(e){return a().prepare(`SELECT 1 FROM edges e JOIN nodes n ON n.node_id = e.from_id
35
+ AND n.status IN ('active', 'idle') LIMIT 1`).get(e)!==void 0}r(kn,"hasActiveLiveSubscription");function xn(e){return a().prepare(`SELECT 1 FROM edges e JOIN nodes n ON n.node_id = e.from_id
36
36
  WHERE e.type = 'subscribes_to' AND e.to_id = ? AND e.active = 1
37
- AND n.status IN ('active', 'idle') LIMIT 1`).get(e)!==void 0}o(on,"hasLiveSubscriber");function sn(e){const n=E(e)?.waiting_for;if(n==null)return!1;const t=E(n);return t!==null&&(t.status==="active"||t.status==="idle")}o(sn,"hasLiveMessageWait");function an(e,n){a().prepare("UPDATE nodes SET waiting_for = ?, waiting_for_generation = waiting_for_generation + 1 WHERE node_id = ?").run(n,e)}o(an,"setMessageWait");function dn(e,n,t){return _(r=>{const i=r.prepare("SELECT waiting_for_generation FROM nodes WHERE node_id = ? AND waiting_for = ?").get(e,n),s=t();return n!==null&&i!==void 0&&r.prepare("UPDATE nodes SET waiting_for = NULL WHERE node_id = ? AND waiting_for = ? AND waiting_for_generation = ?").run(e,n,i.waiting_for_generation),s})}o(dn,"deliverAndSettleMessageWait");function un(e,n,t){return _(r=>{const i=r.prepare(`SELECT waiter.waiting_for, waiter.waiting_for_generation, target.status AS controller_status
37
+ AND n.status IN ('active', 'idle') LIMIT 1`).get(e)!==void 0}r(xn,"hasLiveSubscriber");function Wn(e){const n=E(e)?.waiting_for;if(n==null)return!1;const t=E(n);return t!==null&&(t.status==="active"||t.status==="idle")}r(Wn,"hasLiveMessageWait");function jn(e,n){a().prepare("UPDATE nodes SET waiting_for = ?, waiting_for_generation = waiting_for_generation + 1 WHERE node_id = ?").run(n,e)}r(jn,"setMessageWait");function Fn(e,n,t){return _(o=>{const i=o.prepare("SELECT waiting_for_generation FROM nodes WHERE node_id = ? AND waiting_for = ?").get(e,n),s=t();return n!==null&&i!==void 0&&o.prepare("UPDATE nodes SET waiting_for = NULL WHERE node_id = ? AND waiting_for = ? AND waiting_for_generation = ?").run(e,n,i.waiting_for_generation),s})}r(Fn,"deliverAndSettleMessageWait");function Hn(e,n,t){return _(o=>{const i=o.prepare(`SELECT waiter.waiting_for, waiter.waiting_for_generation, target.status AS controller_status
38
38
  FROM nodes AS waiter LEFT JOIN nodes AS target ON target.node_id = waiter.waiting_for
39
- WHERE waiter.node_id = ?`).get(e),s=i?.controller_status==="active"||i?.controller_status==="idle";if(i?.waiting_for!==n||s)return null;const d=t();return r.prepare("UPDATE nodes SET waiting_for = NULL WHERE node_id = ? AND waiting_for = ? AND waiting_for_generation = ?").run(e,n,i.waiting_for_generation),d})}o(un,"settleDeadMessageWait");function ln(e,n,t){return _(r=>{const i=r.prepare("SELECT status, final_report, frozen_at FROM nodes WHERE node_id = ?").get(e);return i===void 0?{kind:"missing"}:n(i)?{kind:"terminal",status:i.status,final_report:i.final_report}:{kind:"ran",result:t()}})}o(ln,"withFreshTerminalGuard");function w(e){return z(e)}o(w,"hasUnreconciledManagedWorktree");function b(e,n={}){return!["done","dead","canceled"].includes(e.status)||e.pi_pid!==null||e.frozen_at!==null||w(e.node_id)||e.node_id===O()?!1:n.pastTtl===!0||!["crashed","stranded",null].includes(e.terminal_reason??null)}o(b,"isCollectible");function cn(e){if(w(e))return{deleted:!1};const n=_(t=>(t.prepare("DELETE FROM nodes WHERE node_id = ?").run(e),{deleted:!0}));return R(S(e),{recursive:!0,force:!0}),n}o(cn,"deleteNode");function _n(e){const n=[...new Set(e)];if(n.length===0)return[];const t=n.filter(w);if(t.length>0)throw new Error(`refusing to delete nodes with unreconciled managed worktrees: ${t.join(", ")}`);const r=n.map(()=>"?").join(","),i=_(s=>{const d=s.prepare(`SELECT node_id FROM nodes WHERE node_id IN (${r}) ORDER BY created`).all(...n).map(({node_id:u})=>u);return s.prepare(`DELETE FROM nodes WHERE node_id IN (${r})`).run(...n),d});for(const s of i)R(S(s),{recursive:!0,force:!0});return i}o(_n,"deleteNodes");function pn(e){const n=e.dryRun??!1,t=e.includeStale??!1,r=new Date(Date.now()-e.ttlDays*864e5).toISOString(),i=O()??"",s=a(),d=s.prepare(`SELECT * FROM node_rows
39
+ WHERE waiter.node_id = ?`).get(e),s=i?.controller_status==="active"||i?.controller_status==="idle";if(i?.waiting_for!==n||s)return null;const d=t();return o.prepare("UPDATE nodes SET waiting_for = NULL WHERE node_id = ? AND waiting_for = ? AND waiting_for_generation = ?").run(e,n,i.waiting_for_generation),d})}r(Hn,"settleDeadMessageWait");function Mn(e,n,t){return _(o=>{const i=o.prepare("SELECT status, final_report, frozen_at FROM nodes WHERE node_id = ?").get(e);return i===void 0?{kind:"missing"}:n(i)?{kind:"terminal",status:i.status,final_report:i.final_report}:{kind:"ran",result:t()}})}r(Mn,"withFreshTerminalGuard");function R(e){return se(e)}r(R,"hasUnreconciledManagedWorktree");function U(e,n={}){return!["done","dead","canceled"].includes(e.status)||e.pi_pid!==null||e.frozen_at!==null||R(e.node_id)||e.node_id===L()||(e.run_id??null)!==null?!1:n.pastTtl===!0||!["crashed","stranded",null].includes(e.terminal_reason??null)}r(U,"isCollectible");function w(e){if(e.length===0)return[];const n=e.map(()=>"?").join(",");return a().prepare(`SELECT DISTINCT session_id FROM sessions WHERE node_id IN (${n}) AND session_id IS NOT NULL`).all(...e).map(({session_id:o})=>o)}r(w,"nodeConversationIds");function O(e){const n=a(),t=n.prepare("SELECT 1 FROM sessions WHERE session_id = ? LIMIT 1"),o=n.prepare(`SELECT 1 FROM nodes n WHERE n.fork_source_file LIKE '%\\_' || ? || '.jsonl' ESCAPE '\\'
40
+ AND NOT EXISTS (SELECT 1 FROM sessions s WHERE s.node_id = n.node_id) LIMIT 1`);for(const i of e)if(!(t.get(i)!==void 0||o.get(i)!==void 0))try{Z().delete(i)}catch(s){if(!(s instanceof ee))throw s}}r(O,"deleteNodeConversations");function h(e){return{nodeId:e,app:E(e)===null?null:Ee(e)}}r(h,"nodeFiles");function P({nodeId:e,app:n}){n!==null&&A(x(n).nodes,Ne(e,n)),A(G(k(e)),k(e))}r(P,"removeNodeAppTrees");function $({nodeId:e,app:n}){return[...n===null?[]:[ge(e,n)],fe(e)]}r($,"nodeOwnedDirs");function B({nodeId:e,app:n}){if(n!==null)try{q(v(x(n).conversations,e))}catch(t){if(!["ENOENT","ENOTEMPTY"].includes(t.code??""))throw t}}r(B,"removeNodeConversationDir");function T(e){P(e);for(const n of $(e))V(n,{recursive:!0,force:!0});B(e)}r(T,"removeNodeFiles");function Cn(e){if(R(e))return{deleted:!1};const n=h(e),t=w([e]),o=_(i=>(i.prepare("DELETE FROM nodes WHERE node_id = ?").run(e),{deleted:!0}));return O(t),T(n),o}r(Cn,"deleteNode");function In(e){const n=[...new Set(e)];if(n.length===0)return[];const t=n.filter(R);if(t.length>0)throw new Error(`refusing to delete nodes with unreconciled managed worktrees: ${t.join(", ")}`);const o=n.map(h),i=w(n),s=n.map(()=>"?").join(","),d=_(l=>{const c=l.prepare(`SELECT node_id FROM nodes WHERE node_id IN (${s}) ORDER BY created`).all(...n).map(({node_id:m})=>m);return l.prepare(`DELETE FROM nodes WHERE node_id IN (${s})`).run(...n),c});O(i);for(const l of d){const c=o[n.indexOf(l)];D(c,()=>T(c))}return d}r(In,"deleteNodes");function Un(e){const n=e.dryRun??!1,t=e.includeStale??!1,o=Date.now()-e.ttlDays*864e5,i=new Date(o).toISOString(),s=L()??"",d=a(),l=r(u=>J(u)<o,"quiet"),c=r(u=>({node_id:u.node_id,status:u.status,created:u.created}),"toPruned"),m=d.prepare(`SELECT * FROM node_rows
40
41
  WHERE status IN ('dead', 'done', 'canceled') AND created < ?
41
- ORDER BY created`).all(r).map(f).filter(l=>b(l,{pastTtl:!0})).map(l=>({node_id:l.node_id,status:l.status,created:l.created})),u=t?s.prepare(`SELECT node_id, status, created, pi_pid FROM node_rows
42
- WHERE status IN ('active', 'idle') AND created < ?
43
- ORDER BY created`).all(r).filter(l=>{if(l.node_id===i)return!1;const N=l.pi_pid;return!y(N)}).map(l=>({node_id:l.node_id,status:l.status,created:l.created})).filter(l=>!w(l.node_id)):[],c=[...d,...u];return n||c.length===0?{pruned:c,dryRun:n}:(x(c),{pruned:c,dryRun:n})}o(pn,"pruneNodes");function x(e){if(e.length!==0){_(n=>{const t=n.prepare("DELETE FROM nodes WHERE node_id = ?");for(const r of e)t.run(r.node_id)});for(const n of e)R(S(n.node_id),{recursive:!0,force:!0})}}o(x,"deletePrunedNodes");function te(e,n){try{const r=I(U(Q(e),"telemetry.json"),{throwIfNoEntry:!1});if(r!==void 0)return r.mtimeMs}catch{}const t=Date.parse(n);return Number.isNaN(t)?0:t}o(te,"recencyMs");function fn(e){const n=e.dryRun??!1,r=ne().map(u=>({row:u,recency:te(u.node_id,u.created),retained:!b(u)})).sort((u,c)=>c.recency-u.recency),i=r.filter(u=>u.retained).length,s=Math.max(e.maxNodes,i),d=r.filter((u,c)=>c>=s&&!u.retained).map(({row:u})=>({node_id:u.node_id,status:u.status,created:u.created}));return n||d.length===0?{pruned:d,dryRun:n}:(x(d),{pruned:d,dryRun:n})}o(fn,"pruneToLimit");export{me as canonicalSessionFile,qe as childrenOf,Je as claimWarmSpare,Le as clearFinalReportIfMatches,We as clearFrozen,Ee as createNode,cn as deleteNode,_n as deleteNodes,dn as deliverAndSettleMessageWait,ye as dueNodeDeadlines,we as findNodeBySessionFile,Ae as getFinalReport,E as getNode,Ne as getRow,Re as getRowByPane,Ue as graphNodes,rn as hasActiveLiveSubscription,sn as hasLiveMessageWait,on as hasLiveSubscriber,b as isCollectible,ze as isWarmSpare,Pe as listNodeIdentities,He as listNodeMemoryTargets,ne as listNodes,Fe as listNodesByProfile,Me as listNodesForSupervision,Ke as listResumableRoots,Be as listWarmSpares,pn as pruneNodes,fn as pruneToLimit,ve as recordLaunch,je as recordRespawnAttempt,be as recordSettledTurn,en as recordSpawn,Ce as registerWarmSpare,Ge as rosterEdges,Ve as rosterNodes,xe as setFrozen,Te as setIntent,an as setMessageWait,Se as setNodeDeadline,ke as setPresence,he as setStatus,Ze as setSubscriptionActive,un as settleDeadMessageWait,ge as shiftProfileNodeDeadlines,Qe as subscribe,nn as subscribersOf,v as subscriptionsOf,De as transitionStatusIntent,$e as unregisterWarmSpare,Xe as unsubscribe,Oe as updateNode,Ie as updateNodeTelemetry,tn as view,Ye as warmSpareCount,ln as withFreshTerminalGuard};
42
+ ORDER BY created`).all(i).map(p).filter(u=>U(u,{pastTtl:!0})&&l(u)&&!e.held(u.node_id)).map(c),y=t?d.prepare(`SELECT * FROM node_rows
43
+ WHERE status IN ('active', 'idle') AND created < ?
44
+ ORDER BY created`).all(i).map(p).filter(u=>u.node_id!==s&&!ue(u.pi_pid??null)&&(u.frozen_at??null)===null&&(u.respawn_not_before??null)===null&&u.intent!=="idle-release"&&(u.run_id??null)===null&&!oe(u.node_id)&&!R(u.node_id)&&l(u)&&!e.held(u.node_id)).map(c):[],g=[...m,...y];return n||g.length===0?{pruned:g,dryRun:n}:(z(g,e.removeDirs),{pruned:g,dryRun:n})}r(Un,"pruneNodes");function z(e,n){if(e.length===0)return;const t=e.map(i=>h(i.node_id)),o=w(e.map(i=>i.node_id));if(_(i=>{const s=i.prepare("DELETE FROM nodes WHERE node_id = ?");for(const d of e)s.run(d.node_id)}),O(o),n!==void 0){for(const i of t)D(i,()=>{P(i),B(i)});n(t.flatMap($));return}for(const i of t)D(i,()=>T(i))}r(z,"deletePrunedNodes");function D(e,n){try{n()}catch(t){X({level:"error",event:"canvas.node_files.remove_failed",error:t,fields:{node_id:e.nodeId}})}}r(D,"eachNodeBestEffort");function J(e){let n=0;for(const t of[e.created,e.launched_at,e.last_settled_at,e.finalized_at,e.outcome_at,e.last_activity_at]){if(t==null)continue;const o=Date.parse(t);Number.isFinite(o)&&o>n&&(n=o)}try{const t=K(v(pe(e.node_id),"telemetry.json"),{throwIfNoEntry:!1});t!==void 0&&t.mtimeMs>n&&(n=t.mtimeMs)}catch{}return n}r(J,"lastActivityMs");function Pn(e){const n=e.dryRun??!1,t=we(),o=t.filter(l=>U(l)&&!e.held(l.node_id)),i=t.length-o.length,s=Math.max(0,e.maxNodes-i),d=o.map(l=>({row:l,recency:J(l)})).sort((l,c)=>c.recency-l.recency).slice(s).map(({row:l})=>({node_id:l.node_id,status:l.status,created:l.created}));return n||d.length===0?{pruned:d,dryRun:n}:(z(d),{pruned:d,dryRun:n})}r(Pn,"pruneToLimit");export{Ue as assertRunNotDeleting,$e as canonicalSessionFile,Sn as childrenOf,Rn as claimWarmSpare,nn as clearFinalReportIfMatches,an as clearFrozen,Pe as createNode,Cn as deleteNode,In as deleteNodes,Fn as deliverAndSettleMessageWait,Ye as dueNodeDeadlines,Be as findNodeBySessionFile,en as getFinalReport,E as getNode,ze as getRow,Je as getRowByPane,_n as graphNodes,kn as hasActiveLiveSubscription,Wn as hasLiveMessageWait,xn as hasLiveSubscriber,U as isCollectible,gn as isWarmSpare,J as lastActivityMs,fn as listNodeIdentities,un as listNodeMemoryTargets,we as listNodes,ln as listNodesByProfile,pn as listNodesForSupervision,hn as listResumableRoots,Nn as listWarmSpares,h as nodeFiles,Un as pruneNodes,Pn as pruneToLimit,on as recordLaunch,dn as recordRespawnAttempt,rn as recordSettledTurn,vn as recordSpawn,En as registerWarmSpare,T as removeNodeFiles,Ke as rewriteLocalNodeIdentity,On as rosterEdges,wn as rosterNodes,sn as setFrozen,Xe as setIntent,jn as setMessageWait,qe as setNodeDeadline,tn as setPresence,Qe as setStatus,Ln as setSubscriptionActive,Hn as settleDeadMessageWait,Ve as shiftProfileNodeDeadlines,Tn as subscribe,An as subscribersOf,I as subscriptionsOf,Ze as transitionStatusIntent,mn as unregisterWarmSpare,Dn as unsubscribe,Ge as updateNode,cn as updateNodeTelemetry,bn as view,yn as warmSpareCount,Mn as withFreshTerminalGuard};
@@ -0,0 +1,20 @@
1
+ /** Files larger than this are replaced with a tombstone. */
2
+ export declare const CONTEXT_STRIP_FILE_LIMIT_BYTES: number;
3
+ /** The directory tombstone's file name; a directory whose only entry is this file is already stripped. */
4
+ export declare const CONTEXT_TOMBSTONE_NAME = "REMOVED.md";
5
+ export interface StrippedEntry {
6
+ /** Path relative to the context folder. */
7
+ path: string;
8
+ bytes: number;
9
+ reason: string;
10
+ }
11
+ export interface ContextStripResult {
12
+ removed: StrippedEntry[];
13
+ bytes: number;
14
+ }
15
+ /** When this node's context folder was last stripped (epoch ms), or null. */
16
+ export declare function lastContextStripMs(nodeId: string): Promise<number | null>;
17
+ /** Remove bulky content from one node's context folder and record the pass.
18
+ * The caller decides eligibility (finished, quiet, not held) and re-checks it
19
+ * immediately before calling. Per-entry failures are skipped, not thrown. */
20
+ export declare function stripContextDir(nodeId: string, now?: Date): Promise<ContextStripResult>;
@@ -0,0 +1,5 @@
1
+ var F=Object.defineProperty;var s=(t,e)=>F(t,"name",{value:e,configurable:!0});import{readFile as M,writeFile as R}from"node:fs/promises";import{setImmediate as B}from"node:timers/promises";import{join as p,relative as T}from"node:path";import{appSpace as v}from"../layout.js";import{readdirBeneath as d,removeTreeBeneath as $,statBeneath as E,writeFileBeneath as N}from"../spaces/open-beneath.js";import{appForNode as I,contextDir as C}from"./node-agent-paths.js";import{jobDir as w}from"./paths.js";const x=10*1024*1024,A=new Set(["node_modules",".pnpm-store",".git",".venv","venv","__pycache__","dist","build","target",".next",".turbo"]),L=[".heapsnapshot",".heapprofile",".cpuprofile"],g="REMOVED.md",D="context-stripped.json";async function Y(t){try{const e=JSON.parse(await M(p(w(t),D),"utf8")),n=typeof e.stripped_at=="string"?Date.parse(e.stripped_at):Number.NaN;return Number.isFinite(n)?n:null}catch{return null}}s(Y,"lastContextStripMs");function P(t,e){const n=t.toLowerCase();return n.endsWith(".md")?null:L.some(r=>n.endsWith(r))?"heap or CPU profile":n.endsWith(".har")||n==="har.json"?"browser network capture (HAR)":e>x?`file larger than ${x/(1024*1024)} MB`:null}s(P,"fileReason");function O(t,e,n){const r=(e.bytes/1048576).toFixed(1);return`# Removed by crouter retention
2
+
3
+ \`${e.path}\` (${r} MB, ${e.reason}) was deleted from node ${t}'s context folder on ${n.toISOString()}, after the node had been finished for at least a day. The original content is gone; recreate it if you need it.
4
+ `}s(O,"tombstoneText");function j(t,e){let n=0;const r=[e];for(;r.length>0;){const a=r.pop();for(const o of d(t,a)){const c=p(a,o.name);o.isDirectory()?r.push(c):o.isFile()&&(n+=E(t,c).size)}}return n}s(j,"treeBytes");function k(t,e){const n=d(t,e);return n.length===1&&n[0].name===g}s(k,"isTombstonedDir");async function q(t,e=new Date){const n=I(t),r=v(n).nodes,a=C(t,n),o=[],c=s(async u=>{let f;try{f=d(r,u)}catch{return}for(const m of f){const l=m.name,i=p(u,l);try{if(m.isDirectory()){if(!A.has(l)){await B(),await c(i);continue}if(k(r,i))continue;const S={path:T(a,i),bytes:j(r,i),reason:`${l} directory`};$(r,i),N(r,p(i,g),O(t,S,e)),o.push(S);continue}if(!m.isFile())continue;const h=E(r,i).size,_=P(l,h);if(_===null||h<1024)continue;const b={path:T(a,i),bytes:h,reason:_};N(r,i,O(t,b,e)),o.push(b)}catch{}}},"walk");await c(a);const y=o.reduce((u,f)=>u+f.bytes,0);try{await R(p(w(t),D),`${JSON.stringify({stripped_at:e.toISOString(),bytes:y,removed:o},null,2)}
5
+ `)}catch{}return{removed:o,bytes:y}}s(q,"stripContextDir");export{x as CONTEXT_STRIP_FILE_LIMIT_BYTES,g as CONTEXT_TOMBSTONE_NAME,Y as lastContextStripMs,q as stripContextDir};
@@ -19,6 +19,7 @@ export interface Cron {
19
19
  cron_id: string;
20
20
  name: string;
21
21
  created_by: string | null;
22
+ grantee: string;
22
23
  command: string;
23
24
  fire_at: string;
24
25
  recur: string | null;
@@ -73,6 +74,7 @@ export interface ArmCronSpec {
73
74
  cron_id: string;
74
75
  name: string;
75
76
  created_by: string | null;
77
+ grantee?: string;
76
78
  command: string;
77
79
  fire_at: string;
78
80
  recur: string | null;
@@ -111,24 +113,12 @@ export declare const CRON_RUN_RING = 20;
111
113
  export declare function parseCronSink(sinkJson: string): ParsedCronSink;
112
114
  /** Render a stored cron sink as the arm-time CLI spec, or null when it has no destination. */
113
115
  export declare function cronSinkDisplay(sinkJson: string): string | null;
114
- /** The ONLY sanctioned way to signal a cron run's process group from a stored
115
- * row. Re-captures the CURRENT identity of `run_pid` and signals only when it
116
- * MATCHES the fingerprint recorded at lease acquisition. Returns whether the
117
- * signal was sent.
118
- *
119
- * FAIL-CLOSED, unlike the rest of this repo's pid handling. Elsewhere the
120
- * baseline was captured by the same daemon life that is now signaling, so an
121
- * absent baseline or a failed `ps` probe means "no evidence of reuse" and
122
- * failing open to the signal is right. A cron lease outlives its daemon: after
123
- * a SIGKILL or a host reboot, `run_pid` is a number from a dead kernel's pid
124
- * space that the OS has very likely handed to an unrelated process, and
125
- * `isPidAlive` cheerfully confirms that stranger. So here the ONLY thing that
126
- * authorizes a kill is positive proof of sameness — no identity (pre-v23 row,
127
- * capture failed), no `ps` table (probe failed), no row for the pid (process
128
- * gone), or a mismatch (reused) all mean: do not signal. The caller settles the
129
- * lease instead; the worst case is a leaked runaway process, versus SIGTERMing
130
- * a stranger's process group. */
131
- export declare function killLeasedCronRun(c: Cron, signal?: NodeJS.Signals): boolean;
116
+ /** Signal only a run whose current pid identity matches its lease. A daemon
117
+ * replacement can leave a pid number that the kernel later reuses. */
118
+ export declare function stopLeasedCronRun(c: Cron, signal?: 'SIGTERM' | 'SIGKILL'): Promise<boolean>;
119
+ /** Start the signal inside the canvas write boundary; log a launcher refusal.
120
+ * Recovery uses the awaitable form so it cannot settle while the run lives. */
121
+ export declare function killLeasedCronRun(c: Cron, signal?: 'SIGTERM' | 'SIGKILL'): boolean;
132
122
  /** Positive proof that `run_pid` is STILL the process this lease launched:
133
123
  * a stored identity exists, the `ps` probe succeeded, the pid has a row, and
134
124
  * its current identity matches. Anything else — including "we could not tell"
@@ -229,7 +219,9 @@ export declare function dueClockCrons(nowIso: string): Cron[];
229
219
  *
230
220
  * `outOfBand` stamps the lease as a `cron run` (manual verification) so the
231
221
  * overlap pass leaves it alone — see `dueOverlapCrons`. */
232
- export declare function acquireCronRunLease(cron_id: string, leaseOwner: string, pid: number, startedAtIso: string, outOfBand: boolean): boolean;
222
+ export declare function acquireCronRunLease(cron_id: string, leaseOwner: string, startedAtIso: string, outOfBand: boolean): boolean;
223
+ /** Attach the launcher's pid only to the run that claimed this lease. */
224
+ export declare function attachCronRunPid(cron_id: string, leaseOwner: string, startedAtIso: string, pid: number): boolean;
233
225
  /** What a settling run does with the row's `held` state, applied in the SAME
234
226
  * UPDATE that releases the lease — one write boundary, so no tick can observe
235
227
  * `run_state='idle'` with the held transition not yet applied.
@@ -271,7 +263,7 @@ export declare function releaseCronRunLease(cron_id: string, held?: HeldSettle):
271
263
  * a paused held row keeps its state and unparks via a later poke/backstop
272
264
  * after resume (it still receives the stamp, harmlessly). Returns the
273
265
  * unparked count. Idempotent and free when nothing is held. */
274
- export declare function pokeHeldCrons(nowIso: string): number;
266
+ export declare function pokeHeldCrons(nowIso: string, grantee?: string | null): number;
275
267
  /** Recurring crons whose NEXT fire has arrived while their previous run is
276
268
  * still leased — the overlap-policy pass. One-shots never appear here (a
277
269
  * one-shot has exactly one fire, already consumed by its running lease).
@@ -1,8 +1,8 @@
1
- var f=Object.defineProperty;var t=(e,n)=>f(e,"name",{value:n,configurable:!0});import{openDb as a,withCanvasWrite as s}from"./db.js";import{capturePidIdentities as d,identitiesMatch as R,killProcessGroup as m}from"./pid.js";import{isProfilePaused as D}from"../profiles/manifest.js";const S=20;function u(e){return{cron_id:e.cron_id,name:e.name,created_by:e.created_by??null,command:e.command,fire_at:e.fire_at,recur:e.recur??null,tz:e.tz??null,expires_at:e.expires_at??null,anchor_node:e.anchor_node??null,cancel_on_wake:Number(e.cancel_on_wake)!==0,cwd:e.cwd,env_json:e.env_json??null,profile:e.profile??null,scope:e.scope,run_timeout_s:Number(e.run_timeout_s),overlap:e.overlap,on_output:e.on_output,sink:e.sink,tier:e.tier,last_output_hash:e.last_output_hash??null,held:Number(e.held)!==0,last_poke_at:e.last_poke_at??null,state:e.state,run_state:e.run_state,run_pid:e.run_pid??null,run_pid_identity:e.run_pid_identity??null,run_started_at:e.run_started_at??null,run_lease_owner:e.run_lease_owner??null,run_out_of_band:Number(e.run_out_of_band)!==0,created:e.created,updated:e.updated}}t(u,"cronFrom");function l(e){try{const n=JSON.parse(e);if(typeof n.node=="string")return{kind:"node",node:n.node};if(typeof n.spawn=="string")return{kind:"spawn",spawn:n.spawn};if(n.human===!0)return{kind:"human"}}catch{}return null}t(l,"parseCronSink");function x(e){const n=l(e);if(n===null)return null;switch(n.kind){case"node":return`node:${n.node}`;case"spawn":return`spawn:${n.spawn}`;case"human":return"human"}}t(x,"cronSinkDisplay");function c(e,n="SIGTERM"){return h(e)?(m(e.run_pid,n),!0):!1}t(c,"killLeasedCronRun");function h(e){const n=e.run_pid;if(n==null||e.run_pid_identity==null)return!1;const r=d([n]);if(r===null)return!1;const o=r.get(n);return o===void 0?!1:R(o,e.run_pid_identity)}t(h,"verifyLeasedCronRun");function k(e){return s(n=>{const r=[];if(e.cancel_on_wake&&e.anchor_node!==null){const o=n.prepare("SELECT * FROM crons WHERE anchor_node = ? AND cancel_on_wake = 1").all(e.anchor_node).map(u);for(const i of o)i.run_state==="running"&&c(i),n.prepare("DELETE FROM crons WHERE cron_id = ?").run(i.cron_id),r.push(i.cron_id)}return O(n,e),{cron_id:e.cron_id,replaced:r}})}t(k,"armCron");function O(e,n){const r=new Date().toISOString();e.prepare(`INSERT INTO crons (
2
- cron_id, name, created_by, command, fire_at, recur, tz, expires_at,
1
+ var f=Object.defineProperty;var o=(n,r)=>f(n,"name",{value:r,configurable:!0});import{openDb as i,withCanvasWrite as _}from"./db.js";import{capturePidIdentities as p,identitiesMatch as R,killProcessGroup as m}from"./pid.js";import{isProfilePaused as D}from"../profiles/manifest.js";import{stopAppProcess as S}from"../spaces/process.js";import{emitEvent as h}from"../events/emit.js";const O=20;function u(n){return{cron_id:n.cron_id,name:n.name,created_by:n.created_by??null,grantee:n.grantee,command:n.command,fire_at:n.fire_at,recur:n.recur??null,tz:n.tz??null,expires_at:n.expires_at??null,anchor_node:n.anchor_node??null,cancel_on_wake:Number(n.cancel_on_wake)!==0,cwd:n.cwd,env_json:n.env_json??null,profile:n.profile??null,scope:n.scope,run_timeout_s:Number(n.run_timeout_s),overlap:n.overlap,on_output:n.on_output,sink:n.sink,tier:n.tier,last_output_hash:n.last_output_hash??null,held:Number(n.held)!==0,last_poke_at:n.last_poke_at??null,state:n.state,run_state:n.run_state,run_pid:n.run_pid??null,run_pid_identity:n.run_pid_identity??null,run_started_at:n.run_started_at??null,run_lease_owner:n.run_lease_owner??null,run_out_of_band:Number(n.run_out_of_band)!==0,created:n.created,updated:n.updated}}o(u,"cronFrom");function l(n){try{const r=JSON.parse(n);if(typeof r.node=="string")return{kind:"node",node:r.node};if(typeof r.spawn=="string")return{kind:"spawn",spawn:r.spawn};if(r.human===!0)return{kind:"human"}}catch{}return null}o(l,"parseCronSink");function W(n){const r=l(n);if(r===null)return null;switch(r.kind){case"node":return`node:${r.node}`;case"spawn":return`spawn:${r.spawn}`;case"human":return"human"}}o(W,"cronSinkDisplay");async function N(n,r="SIGTERM"){if(!c(n))return!1;if(process.platform!=="linux")return m(n.run_pid,r),!0;try{return await S(n.run_pid,r,n.anchor_node??void 0),!0}catch(e){if(!c(n))return!1;throw e}}o(N,"stopLeasedCronRun");function d(n,r="SIGTERM"){return c(n)?(N(n,r).catch(e=>{h({level:"error",event:"cron.run.stop_failed",error:e,fields:{cron_id:n.cron_id,pid:n.run_pid}})}),!0):!1}o(d,"killLeasedCronRun");function c(n){const r=n.run_pid;if(r==null||n.run_pid_identity==null)return!1;const e=p([r]);if(e===null)return!1;const t=e.get(r);return t===void 0?!1:R(t,n.run_pid_identity)}o(c,"verifyLeasedCronRun");function H(n){return _(r=>{const e=[];if(n.cancel_on_wake&&n.anchor_node!==null){const t=r.prepare("SELECT * FROM crons WHERE anchor_node = ? AND cancel_on_wake = 1").all(n.anchor_node).map(u);for(const a of t)a.run_state==="running"&&d(a),r.prepare("DELETE FROM crons WHERE cron_id = ?").run(a.cron_id),e.push(a.cron_id)}return L(r,n),{cron_id:n.cron_id,replaced:e}})}o(H,"armCron");function L(n,r){const e=new Date().toISOString();n.prepare(`INSERT INTO crons (
2
+ cron_id, name, created_by, grantee, command, fire_at, recur, tz, expires_at,
3
3
  anchor_node, cancel_on_wake, cwd, env_json, profile, scope,
4
4
  run_timeout_s, overlap, on_output, sink, tier, created, updated
5
- ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(n.cron_id,n.name,n.created_by,n.command,n.fire_at,n.recur,n.tz,n.expires_at,n.anchor_node,n.cancel_on_wake?1:0,n.cwd,n.env_json,n.profile,n.scope,n.run_timeout_s,n.overlap,n.on_output,n.sink,n.tier,r,r)}t(O,"insertCron");function g(e){const n=a().prepare("SELECT * FROM crons WHERE cron_id = ?").get(e);return n===void 0?null:u(n)}t(g,"getCron");function W(e){const n=a();let r;return"profile"in e?r=n.prepare("SELECT * FROM crons WHERE scope = 'profile' AND profile = ? ORDER BY fire_at").all(e.profile):"global"in e?r=n.prepare("SELECT * FROM crons WHERE scope = 'global' ORDER BY fire_at").all():r=n.prepare("SELECT * FROM crons ORDER BY fire_at").all(),r.map(u)}t(W,"listCrons");function A(e,n){return s(r=>{const o=r.prepare("SELECT * FROM crons WHERE cron_id = ?").get(e);if(o===void 0)return!1;const i=u(o);return i.run_state==="running"&&n?.preserveRunningProcess!==!0&&c(i),r.prepare("DELETE FROM crons WHERE cron_id = ?").run(e),!0})}t(A,"cancelCron");function p(e,n){const r=[...new Set(n)];return r.length===0?{sql:"profile = ?",params:[e]}:{sql:`profile = ? OR anchor_node IN (${r.map(()=>"?").join(",")})`,params:[e,...r]}}t(p,"profileCronWhere");function H(e,n){const r=p(e,n);return a().prepare(`SELECT cron_id FROM crons WHERE ${r.sql} ORDER BY created, cron_id`).all(...r.params).map(({cron_id:o})=>o)}t(H,"cronIdsForProfileDeletion");function F(e,n){return s(r=>{const o=p(e,n),i=r.prepare(`SELECT * FROM crons WHERE ${o.sql} ORDER BY created, cron_id`).all(...o.params).map(u);for(const _ of i)_.run_state==="running"&&c(_);return r.prepare(`DELETE FROM crons WHERE ${o.sql}`).run(...o.params),i.map(({cron_id:_})=>_)})}t(F,"deleteCronsForProfile");function M(e){return a().prepare("SELECT cron_id FROM crons WHERE profile = ? ORDER BY created, cron_id").all(e).map(({cron_id:n})=>n)}t(M,"cronIdsForProfileDetach");function v(e){return s(n=>{const r=n.prepare("SELECT cron_id FROM crons WHERE profile = ? ORDER BY created, cron_id").all(e).map(({cron_id:o})=>o);return r.length>0&&n.prepare("UPDATE crons SET profile = NULL, scope = 'global', updated = ? WHERE profile = ?").run(new Date().toISOString(),e),r})}t(v,"globalizeCronsForProfile");function I(e){return a().prepare("DELETE FROM crons WHERE cron_id = ?").run(e).changes>0}t(I,"consumeCron");function P(e,n){return a().prepare("UPDATE crons SET state = ?, updated = ? WHERE cron_id = ?").run(n,new Date().toISOString(),e).changes>0}t(P,"setCronState");function U(e,n){a().prepare("UPDATE crons SET last_output_hash = ?, updated = ? WHERE cron_id = ?").run(n,new Date().toISOString(),e)}t(U,"setCronLastOutputHash");function y(e){const n=a().prepare(`SELECT anchor_node, cancel_on_wake, sink
5
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(r.cron_id,r.name,r.created_by,r.grantee??"app:terminal",r.command,r.fire_at,r.recur,r.tz,r.expires_at,r.anchor_node,r.cancel_on_wake?1:0,r.cwd,r.env_json,r.profile,r.scope,r.run_timeout_s,r.overlap,r.on_output,r.sink,r.tier,e,e)}o(L,"insertCron");function F(n){const r=i().prepare("SELECT * FROM crons WHERE cron_id = ?").get(n);return r===void 0?null:u(r)}o(F,"getCron");function M(n){const r=i();let e;return"profile"in n?e=r.prepare("SELECT * FROM crons WHERE scope = 'profile' AND profile = ? ORDER BY fire_at").all(n.profile):"global"in n?e=r.prepare("SELECT * FROM crons WHERE scope = 'global' ORDER BY fire_at").all():e=r.prepare("SELECT * FROM crons ORDER BY fire_at").all(),e.map(u)}o(M,"listCrons");function v(n,r){return _(e=>{const t=e.prepare("SELECT * FROM crons WHERE cron_id = ?").get(n);if(t===void 0)return!1;const a=u(t);return a.run_state==="running"&&r?.preserveRunningProcess!==!0&&d(a),e.prepare("DELETE FROM crons WHERE cron_id = ?").run(n),!0})}o(v,"cancelCron");function E(n,r){const e=[...new Set(r)];return e.length===0?{sql:"profile = ?",params:[n]}:{sql:`profile = ? OR anchor_node IN (${e.map(()=>"?").join(",")})`,params:[n,...e]}}o(E,"profileCronWhere");function I(n,r){const e=E(n,r);return i().prepare(`SELECT cron_id FROM crons WHERE ${e.sql} ORDER BY created, cron_id`).all(...e.params).map(({cron_id:t})=>t)}o(I,"cronIdsForProfileDeletion");function U(n,r){return _(e=>{const t=E(n,r),a=e.prepare(`SELECT * FROM crons WHERE ${t.sql} ORDER BY created, cron_id`).all(...t.params).map(u);for(const s of a)s.run_state==="running"&&d(s);return e.prepare(`DELETE FROM crons WHERE ${t.sql}`).run(...t.params),a.map(({cron_id:s})=>s)})}o(U,"deleteCronsForProfile");function P(n){return i().prepare("SELECT cron_id FROM crons WHERE profile = ? ORDER BY created, cron_id").all(n).map(({cron_id:r})=>r)}o(P,"cronIdsForProfileDetach");function y(n){return _(r=>{const e=r.prepare("SELECT cron_id FROM crons WHERE profile = ? ORDER BY created, cron_id").all(n).map(({cron_id:t})=>t);return e.length>0&&r.prepare("UPDATE crons SET profile = NULL, scope = 'global', updated = ? WHERE profile = ?").run(new Date().toISOString(),n),e})}o(y,"globalizeCronsForProfile");function b(n){return i().prepare("DELETE FROM crons WHERE cron_id = ?").run(n).changes>0}o(b,"consumeCron");function B(n,r){return i().prepare("UPDATE crons SET state = ?, updated = ? WHERE cron_id = ?").run(r,new Date().toISOString(),n).changes>0}o(B,"setCronState");function Y(n,r){i().prepare("UPDATE crons SET last_output_hash = ?, updated = ? WHERE cron_id = ?").run(r,new Date().toISOString(),n)}o(Y,"setCronLastOutputHash");function $(n){const r=i().prepare(`SELECT anchor_node, cancel_on_wake, sink
6
6
  FROM crons
7
7
  WHERE (anchor_node = ? AND cancel_on_wake = 1 AND state = 'active')
8
8
  OR (
@@ -11,24 +11,26 @@ var f=Object.defineProperty;var t=(e,n)=>f(e,"name",{value:n,configurable:!0});i
11
11
  run_state = 'running'
12
12
  OR (run_state = 'idle' AND state = 'active' AND (expires_at IS NULL OR expires_at > ?))
13
13
  )
14
- )`).all(e,new Date().toISOString());for(const r of n){if(r.anchor_node===e&&Number(r.cancel_on_wake)!==0)return!0;const o=l(r.sink);if(o?.kind==="node"&&o.node===e)return!0}return!1}t(y,"hasPendingCronWake");function b(e){return s(n=>{const r=n.prepare("SELECT * FROM crons WHERE anchor_node = ? AND cancel_on_wake = 1").all(e).map(u);for(const o of r)o.run_state==="running"&&c(o),n.prepare("DELETE FROM crons WHERE cron_id = ?").run(o.cron_id);return r.map(o=>o.cron_id)})}t(b,"cancelCronsOnWake");function B(e,n){a().prepare("UPDATE crons SET fire_at = ?, updated = ? WHERE cron_id = ?").run(n,new Date().toISOString(),e)}t(B,"advanceCron");function Y(e){return a().prepare(`SELECT * FROM crons
14
+ )`).all(n,new Date().toISOString());for(const e of r){if(e.anchor_node===n&&Number(e.cancel_on_wake)!==0)return!0;const t=l(e.sink);if(t?.kind==="node"&&t.node===n)return!0}return!1}o($,"hasPendingCronWake");function q(n){return _(r=>{const e=r.prepare("SELECT * FROM crons WHERE anchor_node = ? AND cancel_on_wake = 1").all(n).map(u);for(const t of e)t.run_state==="running"&&d(t),r.prepare("DELETE FROM crons WHERE cron_id = ?").run(t.cron_id);return e.map(t=>t.cron_id)})}o(q,"cancelCronsOnWake");function j(n,r){i().prepare("UPDATE crons SET fire_at = ?, updated = ? WHERE cron_id = ?").run(r,new Date().toISOString(),n)}o(j,"advanceCron");function z(n){return i().prepare(`SELECT * FROM crons
15
15
  WHERE state = 'active' AND run_state = 'idle' AND fire_at <= ?
16
- ORDER BY fire_at, created, cron_id`).all(e).map(u).filter(n=>!D(n.profile))}t(Y,"dueClockCrons");function q(e,n,r,o,i){const _=d([r])?.get(r)??null,E=a().prepare(`UPDATE crons
17
- SET run_state = 'running', run_started_at = ?, run_pid = ?, run_pid_identity = ?,
16
+ ORDER BY fire_at, created, cron_id`).all(n).map(u).filter(r=>!D(r.profile))}o(z,"dueClockCrons");function G(n,r,e,t){const a=i().prepare(`UPDATE crons
17
+ SET run_state = 'running', run_started_at = ?, run_pid = NULL, run_pid_identity = NULL,
18
18
  run_lease_owner = ?, run_out_of_band = ?, updated = ?
19
- WHERE cron_id = ? AND run_state = 'idle'`).run(o,r,_,n,i?1:0,new Date().toISOString(),e);return Number(E.changes)>0}t(q,"acquireCronRunLease");function $(e,n){let r="";const o=[];n!==void 0&&(n.kind==="clear"?r=", held = 0":n.kind==="park"?(r=n.fireAt!==void 0?", held = 1, fire_at = ?":", held = 1",n.fireAt!==void 0&&o.push(n.fireAt)):(r=", held = 0, fire_at = ?",o.push(n.nowIso))),a().prepare(`UPDATE crons
19
+ WHERE cron_id = ? AND run_state = 'idle'`).run(e,r,t?1:0,new Date().toISOString(),n);return Number(a.changes)>0}o(G,"acquireCronRunLease");function V(n,r,e,t){const a=p([t])?.get(t)??null,s=i().prepare(`UPDATE crons SET run_pid = ?, run_pid_identity = ?, updated = ?
20
+ WHERE cron_id = ? AND run_state = 'running' AND run_lease_owner = ?
21
+ AND run_started_at = ? AND run_pid IS NULL`).run(t,a,new Date().toISOString(),n,r,e);return Number(s.changes)>0}o(V,"attachCronRunPid");function J(n,r){let e="";const t=[];r!==void 0&&(r.kind==="clear"?e=", held = 0":r.kind==="park"?(e=r.fireAt!==void 0?", held = 1, fire_at = ?":", held = 1",r.fireAt!==void 0&&t.push(r.fireAt)):(e=", held = 0, fire_at = ?",t.push(r.nowIso))),i().prepare(`UPDATE crons
20
22
  SET run_state = 'idle', run_started_at = NULL, run_pid = NULL, run_pid_identity = NULL,
21
- run_lease_owner = NULL, run_out_of_band = 0, updated = ?${r}
22
- WHERE cron_id = ?`).run(new Date().toISOString(),...o,e)}t($,"releaseCronRunLease");function j(e){return s(n=>{n.prepare("UPDATE crons SET last_poke_at = ?").run(e);const r=n.prepare("UPDATE crons SET fire_at = ?, held = 0, updated = ? WHERE held = 1 AND state = 'active' AND run_state = 'idle'").run(e,e);return Number(r.changes)})}t(j,"pokeHeldCrons");function z(e){return a().prepare(`SELECT * FROM crons
23
+ run_lease_owner = NULL, run_out_of_band = 0, updated = ?${e}
24
+ WHERE cron_id = ?`).run(new Date().toISOString(),...t,n)}o(J,"releaseCronRunLease");function K(n,r=null){return _(e=>{const t=r===null?"":" AND grantee = ?",a=r===null?[]:[r];e.prepare(`UPDATE crons SET last_poke_at = ? WHERE 1 = 1${t}`).run(n,...a);const s=e.prepare(`UPDATE crons SET fire_at = ?, held = 0, updated = ? WHERE held = 1 AND state = 'active' AND run_state = 'idle'${t}`).run(n,n,...a);return Number(s.changes)})}o(K,"pokeHeldCrons");function Q(n){return i().prepare(`SELECT * FROM crons
23
25
  WHERE state = 'active' AND run_state = 'running' AND run_out_of_band = 0
24
26
  AND recur IS NOT NULL AND fire_at <= ?
25
- ORDER BY fire_at, created, cron_id`).all(e).map(u)}t(z,"dueOverlapCrons");function G(e){return a().prepare(`SELECT * FROM crons
27
+ ORDER BY fire_at, created, cron_id`).all(n).map(u)}o(Q,"dueOverlapCrons");function X(n){return i().prepare(`SELECT * FROM crons
26
28
  WHERE expires_at IS NOT NULL AND expires_at <= ? AND run_state = 'idle'
27
- ORDER BY expires_at`).all(e).map(u)}t(G,"expiredIdleCrons");function V(e){return a().prepare("SELECT * FROM cron_runs WHERE cron_id = ? ORDER BY started DESC, run_id DESC").all(e).map(n=>({run_id:n.run_id,cron_id:n.cron_id,started:n.started,finished:n.finished,duration_ms:Number(n.duration_ms),exit_code:n.exit_code??null,stdout_head:n.stdout_head??null,stderr_head:n.stderr_head??null,delivered:n.delivered??null}))}t(V,"listCronRuns");function J(){return a().prepare("SELECT * FROM crons WHERE run_state = 'running'").all().map(u)}t(J,"runningCrons");function C(e,n){return e.prepare("SELECT 1 FROM crons WHERE cron_id = ?").get(n.cron_id)===void 0?!1:(e.prepare(`INSERT INTO cron_runs (
29
+ ORDER BY expires_at`).all(n).map(u)}o(X,"expiredIdleCrons");function Z(n){return i().prepare("SELECT * FROM cron_runs WHERE cron_id = ? ORDER BY started DESC, run_id DESC").all(n).map(r=>({run_id:r.run_id,cron_id:r.cron_id,started:r.started,finished:r.finished,duration_ms:Number(r.duration_ms),exit_code:r.exit_code??null,stdout_head:r.stdout_head??null,stderr_head:r.stderr_head??null,delivered:r.delivered??null}))}o(Z,"listCronRuns");function nn(){return i().prepare("SELECT * FROM crons WHERE run_state = 'running'").all().map(u)}o(nn,"runningCrons");function C(n,r){return n.prepare("SELECT 1 FROM crons WHERE cron_id = ?").get(r.cron_id)===void 0?!1:(n.prepare(`INSERT INTO cron_runs (
28
30
  run_id, cron_id, started, finished, duration_ms, exit_code,
29
31
  stdout_head, stderr_head, delivered
30
- ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(n.run_id,n.cron_id,n.started,n.finished,n.duration_ms,n.exit_code,n.stdout_head,n.stderr_head,n.delivered),e.prepare(`DELETE FROM cron_runs
32
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(r.run_id,r.cron_id,r.started,r.finished,r.duration_ms,r.exit_code,r.stdout_head,r.stderr_head,r.delivered),n.prepare(`DELETE FROM cron_runs
31
33
  WHERE cron_id = ? AND run_id NOT IN (
32
34
  SELECT run_id FROM cron_runs WHERE cron_id = ?
33
35
  ORDER BY started DESC, run_id DESC LIMIT ?
34
- )`).run(n.cron_id,n.cron_id,S),!0)}t(C,"recordCronRunLocked");function K(e){return s(n=>C(n,e))}t(K,"recordCronRun");export{S as CRON_RUN_RING,q as acquireCronRunLease,B as advanceCron,k as armCron,A as cancelCron,b as cancelCronsOnWake,I as consumeCron,H as cronIdsForProfileDeletion,M as cronIdsForProfileDetach,x as cronSinkDisplay,F as deleteCronsForProfile,Y as dueClockCrons,z as dueOverlapCrons,G as expiredIdleCrons,g as getCron,v as globalizeCronsForProfile,y as hasPendingCronWake,c as killLeasedCronRun,V as listCronRuns,W as listCrons,l as parseCronSink,j as pokeHeldCrons,K as recordCronRun,C as recordCronRunLocked,$ as releaseCronRunLease,J as runningCrons,U as setCronLastOutputHash,P as setCronState,h as verifyLeasedCronRun};
36
+ )`).run(r.cron_id,r.cron_id,O),!0)}o(C,"recordCronRunLocked");function rn(n){return _(r=>C(r,n))}o(rn,"recordCronRun");export{O as CRON_RUN_RING,G as acquireCronRunLease,j as advanceCron,H as armCron,V as attachCronRunPid,v as cancelCron,q as cancelCronsOnWake,b as consumeCron,I as cronIdsForProfileDeletion,P as cronIdsForProfileDetach,W as cronSinkDisplay,U as deleteCronsForProfile,z as dueClockCrons,Q as dueOverlapCrons,X as expiredIdleCrons,F as getCron,y as globalizeCronsForProfile,$ as hasPendingCronWake,d as killLeasedCronRun,Z as listCronRuns,M as listCrons,l as parseCronSink,K as pokeHeldCrons,rn as recordCronRun,C as recordCronRunLocked,J as releaseCronRunLease,nn as runningCrons,Y as setCronLastOutputHash,B as setCronState,N as stopLeasedCronRun,c as verifyLeasedCronRun};
@@ -1,2 +1,2 @@
1
- var s=Object.defineProperty;var r=(t,e)=>s(t,"name",{value:e,configurable:!0});import{DatabaseSync as i}from"node:sqlite";import{appendFileSync as a}from"node:fs";import{canvasDbPath as c,ensureHome as p}from"./paths.js";import{migrate as D,MIGRATIONS as R}from"./migrations.js";const o=new Map;function u(){const t=process.env.CRTR_DB_OPEN_LEDGER;if(t)try{const e=`${new Date().toISOString()} ${process.pid} ${process.argv[1]??"<unknown>"}
2
- `;a(t,e)}catch{}}r(u,"recordOpenLedger");function f(){const t=c(),e=o.get(t);if(e)return e;p(),u();const n=new i(t);return n.exec("PRAGMA busy_timeout = 5000;"),n.exec("PRAGMA journal_mode = WAL;"),n.exec("PRAGMA foreign_keys = ON;"),o.set(t,n),n}r(f,"openDb");function g(t){const e=f();if(e.isTransaction)return t(e);e.exec("BEGIN IMMEDIATE");try{const n=t(e);return e.exec("COMMIT"),n}catch(n){try{e.exec("ROLLBACK")}catch{}throw n}}r(g,"withCanvasWrite");function h(){const t=c(),e=o.get(t);e&&(e.close(),o.delete(t))}r(h,"closeDb");export{R as MIGRATIONS,h as closeDb,D as migrate,f as openDb,g as withCanvasWrite};
1
+ var s=Object.defineProperty;var r=(t,e)=>s(t,"name",{value:e,configurable:!0});import{DatabaseSync as i}from"node:sqlite";import{appendFileSync as a}from"node:fs";import{canvasDbPath as c,ensureHome as p}from"./paths.js";import{initializeEmptyLayout as u}from"../layout.js";import{migrate as R,MIGRATIONS as b}from"./migrations.js";const o=new Map;function f(){const t=process.env.CRTR_DB_OPEN_LEDGER;if(t)try{const e=`${new Date().toISOString()} ${process.pid} ${process.argv[1]??"<unknown>"}
2
+ `;a(t,e)}catch{}}r(f,"recordOpenLedger");function m(){const t=c(),e=o.get(t);if(e)return e;u(),p(),f();const n=new i(t);return n.exec("PRAGMA busy_timeout = 5000;"),n.exec("PRAGMA journal_mode = WAL;"),n.exec("PRAGMA foreign_keys = ON;"),o.set(t,n),n}r(m,"openDb");function h(t){const e=m();if(e.isTransaction)return t(e);e.exec("BEGIN IMMEDIATE");try{const n=t(e);return e.exec("COMMIT"),n}catch(n){try{e.exec("ROLLBACK")}catch{}throw n}}r(h,"withCanvasWrite");function M(){const t=c(),e=o.get(t);e&&(e.close(),o.delete(t))}r(M,"closeDb");export{b as MIGRATIONS,M as closeDb,R as migrate,m as openDb,h as withCanvasWrite};
@@ -67,7 +67,10 @@ export type DeliverySettlement = {
67
67
  };
68
68
  /** The one execution/attempt/owner fence for node mail and external actions. */
69
69
  export declare function settleDelivery(deliveryId: string, attempts: number, claimOwner: string, settlement: DeliverySettlement | ProcessDeliverySettlement, now?: number): boolean;
70
- /** Broker acknowledgement additionally checks the live execution/refresh guards before the per-row fence. */
70
+ /** Broker acknowledgement additionally checks that the execution is live before the per-row fence.
71
+ * Refresh intent does not refuse it: a yielding turn still acknowledges the mail
72
+ * its conversation consumed, and the watcher withholds the queued mail the
73
+ * refresh abort discarded so the replacement execution replays only that. */
71
74
  export declare function acknowledgeNodeMail(nodeId: string, executionId: string, deliveries: Array<{
72
75
  deliveryId: string;
73
76
  attempts: number;
@@ -13,7 +13,7 @@ var w=Object.defineProperty;var o=(e,n)=>w(e,"name",{value:n,configurable:!0});i
13
13
  WHERE destination_kind = 'node_inbox' AND destination_id = ? AND wake = 1 AND state = 'pending' AND canceled_at IS NULL`).run(n,d,d,e),O(r,e,n,1,i)})}o(q,"claimKickoffMail");function C(e){return e.state==="accepted"?{state:"acknowledged"}:e}o(C,"normalizedSettlement");function h(e,n,d,r,i=Date.now()){const _=C(r),s=_.state==="pending"||_.state==="permanent_failed"?JSON.stringify(_.failure):null,c=_.state==="released"?"pending":_.state,t=_.state==="pending"?_.nextAttemptAt:c==="pending"?i:null;return N(a=>Number(a.prepare(`UPDATE deliveries
14
14
  SET state = ?, next_attempt_at = ?, claimed_at = NULL, claim_owner = NULL,
15
15
  acknowledged_at = ?, failed_at = ?, last_failure_json = ?, updated_at = ?
16
- WHERE delivery_id = ? AND state = 'handed_off' AND attempts = ? AND claim_owner = ?`).run(c,t,c==="acknowledged"?i:null,c==="permanent_failed"?i:null,s,i,e,n,d).changes)===1)}o(h,"settleDelivery");function $(e,n,d,r=Date.now()){return N(i=>y(i,e,n,!0)?{action:"acknowledged",results:d.map(s=>{const c=i.prepare("SELECT 1 FROM deliveries WHERE delivery_id = ? AND destination_kind = 'node_inbox' AND destination_id = ?").get(s.deliveryId,e)!==void 0;return{deliveryId:s.deliveryId,outcome:c&&h(s.deliveryId,s.attempts,n,{state:s.disposition},r)?s.disposition:"stale"}})}:{action:"hold",results:[]})}o($,"acknowledgeNodeMail");function J(e){const n=u().prepare(`SELECT m.body_json FROM deliveries d JOIN messages m ON m.message_id = d.message_id
16
+ WHERE delivery_id = ? AND state = 'handed_off' AND attempts = ? AND claim_owner = ?`).run(c,t,c==="acknowledged"?i:null,c==="permanent_failed"?i:null,s,i,e,n,d).changes)===1)}o(h,"settleDelivery");function $(e,n,d,r=Date.now()){return N(i=>y(i,e,n,!1)?{action:"acknowledged",results:d.map(s=>{const c=i.prepare("SELECT 1 FROM deliveries WHERE delivery_id = ? AND destination_kind = 'node_inbox' AND destination_id = ?").get(s.deliveryId,e)!==void 0;return{deliveryId:s.deliveryId,outcome:c&&h(s.deliveryId,s.attempts,n,{state:s.disposition},r)?s.disposition:"stale"}})}:{action:"hold",results:[]})}o($,"acknowledgeNodeMail");function J(e){const n=u().prepare(`SELECT m.body_json FROM deliveries d JOIN messages m ON m.message_id = d.message_id
17
17
  WHERE d.delivery_id = ? AND d.destination_kind = 'external_action'`).get(e);return n===void 0||n.body_json===null?null:JSON.parse(n.body_json)}o(J,"messageBodyForDelivery");function K(e){const n=u().prepare("SELECT * FROM deliveries WHERE destination_kind = 'external_action' AND idempotency_key = ?").get(e);return n===void 0?null:g(n)}o(K,"readExternalActionDelivery");function P(e){return u().prepare(`SELECT * FROM deliveries
18
18
  WHERE destination_kind = 'external_action' AND state = 'pending' AND canceled_at IS NULL AND next_attempt_at <= ?
19
19
  ORDER BY next_attempt_at, created_at, delivery_id`).all(e).map(g)}o(P,"dueExternalActionDeliveries");function G(e,n,d){return N(r=>{const i=r.prepare(`UPDATE deliveries SET state = 'handed_off', attempts = attempts + 1, claimed_at = ?, claim_owner = ?, updated_at = ?
@@ -1 +1 @@
1
- var x=Object.defineProperty;var n=(e,t)=>x(e,"name",{value:t,configurable:!0});import{randomUUID as E}from"node:crypto";import{openDb as c,withCanvasWrite as a}from"./db.js";import{capturePidIdentities as p,identitiesMatch as _,isBootScopedIdentity as N,isLegacyTicksIdentity as g}from"./pid.js";function u(){return new Date().toISOString()}n(u,"now");function l(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}}n(l,"hydrate");function h(e){const t=c().prepare("SELECT * FROM executions WHERE node_id = ? AND state != 'exited'").get(e);return t===void 0?null:l(t)}n(h,"liveExecutionForNode");function y(e,t){return a(i=>{const d=u();i.prepare("UPDATE executions SET state = 'exited', ended_at = ?, exit_reason = 'superseded' WHERE node_id = ? AND state != 'exited'").run(d,e);const o=E();return i.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(o,e,t.daemonEpoch,d),o})}n(y,"beginExecution");function m(e,t,i){const d=p([i])?.get(i)??null;return a(o=>o.prepare("UPDATE executions SET pid = ?, process_identity = ?, state = 'running' WHERE execution_id = ? AND node_id = ? AND state = 'launching'").run(i,d,e,t).changes>0||o.prepare("SELECT pid FROM executions WHERE execution_id = ? AND node_id = ? AND state = 'running'").get(e,t)?.pid===i?"recorded":"shutdown")}n(m,"recordExecutionPid");function A(e,t){return Number(c().prepare("UPDATE executions SET state = 'exited', ended_at = ?, exit_reason = ? WHERE execution_id = ? AND state != 'exited'").run(u(),t.reason,e).changes)===1}n(A,"endExecution");function S(e,t){return A(e,t)}n(S,"abortExecution");function U(e,t){return Number(c().prepare("UPDATE executions SET state = 'exited', ended_at = ?, exit_reason = ? WHERE node_id = ? AND state != 'exited'").run(u(),t.reason,e).changes)===1}n(U,"endLiveExecution");function R(e=t=>p([t])?.get(t)){const t=c(),i=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(),d=t.prepare("UPDATE executions SET process_identity = ? WHERE execution_id = ? AND pid = ? AND process_identity = ? AND state = 'running'"),o=[];for(const r of i){if(!g(r.process_identity))continue;const s=e(r.pid);s===void 0||!N(s)||!_(s,r.process_identity)||d.run(s,r.execution_id,r.pid,r.process_identity).changes>0&&o.push(r.execution_id)}return{migrated:o}}n(R,"migrateLegacyExecutionIdentities");export{S as abortExecution,y as beginExecution,A as endExecution,U as endLiveExecution,h as liveExecutionForNode,R as migrateLegacyExecutionIdentities,m as recordExecutionPid};
1
+ var m=Object.defineProperty;var o=(e,t)=>m(e,"name",{value:t,configurable:!0});import{randomUUID as g}from"node:crypto";import{openDb as _,withCanvasWrite as a}from"./db.js";import{capturePidIdentities as f,captureLivenessSnapshot as h,identitiesMatch as A,isBootScopedIdentity as T,isLegacyTicksIdentity as D}from"./pid.js";import{existsSync as L,readFileSync as y}from"node:fs";import{LAUNCHER_SOCKET as S}from"../../launcher/spec.js";import{forgetNodeToken as U,mintNodeToken as R,revokeNodeTokens as p}from"./node-tokens.js";function x(){return new Date().toISOString()}o(x,"now");function H(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(H,"hydrate");function M(e){const t=_().prepare("SELECT * FROM executions WHERE node_id = ? AND state != 'exited'").get(e);return t===void 0?null:H(t)}o(M,"liveExecutionForNode");function b(e,t){return a(n=>{const i=x();n.prepare("UPDATE executions SET state = 'exited', ended_at = ?, exit_reason = 'superseded' WHERE node_id = ? AND state != 'exited'").run(i,e),p(n,"node_id",e,i);const r=g();return 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),R(n,r,e,i),r})}o(b,"beginExecution");function $(e,t,n){const i=f([n])?.get(n)??null;return a(r=>{if(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 d=r.prepare("SELECT pid FROM executions WHERE execution_id = ? AND node_id = ? AND state = 'running'").get(e,t);if(d?.pid===n)return"recorded";if(process.platform==="linux"&&L(S)&&d?.pid!=null){const l=h(),c=[d.pid];for(let u=0;u<c.length;u++)c.push(...l?.childrenOf.get(c[u])??[]);if(c.includes(n))return"recorded";for(const u of c)try{const N=y(`/proc/${u}/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($,"recordExecutionPid");function O(e,t){return U(e),a(n=>{const i=x(),r=n.prepare("UPDATE executions SET state = 'exited', ended_at = ?, exit_reason = ? WHERE execution_id = ? AND state != 'exited'").run(i,t.reason,e);return p(n,"broker_process_id",e,i),Number(r.changes)===1})}o(O,"endExecution");function B(e,t){return O(e,t)}o(B,"abortExecution");function K(e,t){return a(n=>{const i=x(),r=n.prepare("UPDATE executions SET state = 'exited', ended_at = ?, exit_reason = ? WHERE node_id = ? AND state != 'exited'").run(i,t.reason,e);return p(n,"node_id",e,i),Number(r.changes)===1})}o(K,"endLiveExecution");function V(e=t=>f([t])?.get(t)){const t=_(),n=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 s of n){if(!D(s.process_identity))continue;const d=e(s.pid);d===void 0||!T(d)||!A(d,s.process_identity)||i.run(d,s.execution_id,s.pid,s.process_identity).changes>0&&r.push(s.execution_id)}return{migrated:r}}o(V,"migrateLegacyExecutionIdentities");export{B as abortExecution,b as beginExecution,O as endExecution,K as endLiveExecution,M as liveExecutionForNode,V as migrateLegacyExecutionIdentities,$ as recordExecutionPid};
@@ -111,7 +111,8 @@ export interface ResolvedRef {
111
111
  path: string | null;
112
112
  }
113
113
  /** Resolve a `<node-id>:<relpath>` handle to its content. Returns null when the
114
- * node is unknown or the artifact does not exist. Throws on path traversal. */
114
+ * node is unknown or the artifact is not a file in the node's own folder
115
+ * (absent, or on Linux reached through a symlink). Throws on path traversal. */
115
116
  export declare function resolveRef(ref: string): ResolvedRef | null;
116
117
  /** Enumerate one node's artifacts (for `history show`). */
117
118
  export declare function nodeArtifacts(nodeId: string, types?: HistorySource[]): HistoryArtifact[];