@north-light/cli 0.3.530 → 0.3.531
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/clients/attach/session/connection.js +1 -1
- package/dist/clients/attach/session/reconnect.js +1 -1
- package/dist/clients/attach/viewer.js +3 -3
- package/dist/core/async-array.d.ts +7 -0
- package/dist/core/async-array.js +1 -0
- package/dist/core/audit.d.ts +1 -1
- package/dist/core/audit.js +2 -2
- package/dist/core/canvas/attention.d.ts +4 -4
- package/dist/core/canvas/attention.js +1 -1
- package/dist/core/canvas/boot.d.ts +4 -4
- package/dist/core/canvas/boot.js +1 -1
- package/dist/core/canvas/canvas.d.ts +59 -59
- package/dist/core/canvas/canvas.js +19 -19
- package/dist/core/canvas/context-strip.js +2 -2
- package/dist/core/canvas/crons.d.ts +27 -27
- package/dist/core/canvas/crons.js +11 -11
- package/dist/core/canvas/daemon-actions.d.ts +10 -10
- package/dist/core/canvas/daemon-actions.js +8 -8
- package/dist/core/canvas/daemon-owner.d.ts +3 -3
- package/dist/core/canvas/daemon-owner.js +2 -2
- package/dist/core/canvas/db.d.ts +19 -30
- package/dist/core/canvas/db.js +3 -2
- package/dist/core/canvas/deliveries.d.ts +16 -16
- package/dist/core/canvas/deliveries.js +24 -24
- package/dist/core/canvas/executions.d.ts +8 -8
- package/dist/core/canvas/executions.js +1 -1
- package/dist/core/canvas/focuses.d.ts +8 -8
- package/dist/core/canvas/focuses.js +1 -1
- package/dist/core/canvas/history.d.ts +3 -3
- package/dist/core/canvas/history.js +9 -9
- package/dist/core/canvas/install-id.d.ts +1 -1
- package/dist/core/canvas/install-id.js +1 -1
- package/dist/core/canvas/managed-worktree-sweep-candidates.d.ts +1 -1
- package/dist/core/canvas/managed-worktree-sweep-candidates.js +2 -2
- package/dist/core/canvas/memory-reads.d.ts +6 -6
- package/dist/core/canvas/memory-reads.js +1 -1
- package/dist/core/canvas/nav-model.d.ts +13 -13
- package/dist/core/canvas/nav-model.js +1 -1
- package/dist/core/canvas/node-agent-paths.d.ts +6 -6
- package/dist/core/canvas/node-agent-paths.js +1 -1
- package/dist/core/canvas/node-tokens.d.ts +7 -7
- package/dist/core/canvas/node-tokens.js +3 -3
- package/dist/core/canvas/outcome-actions.d.ts +5 -5
- package/dist/core/canvas/outcome-actions.js +3 -3
- package/dist/core/canvas/recovery.d.ts +26 -26
- package/dist/core/canvas/recovery.js +2 -2
- package/dist/core/canvas/render-source.d.ts +1 -1
- package/dist/core/canvas/render-source.js +1 -1
- package/dist/core/canvas/sessions.d.ts +10 -10
- package/dist/core/canvas/sessions.js +4 -4
- package/dist/core/canvas/source.js +1 -1
- package/dist/core/canvas/structured-requests.d.ts +15 -15
- package/dist/core/canvas/structured-requests.js +5 -5
- package/dist/core/canvas/tree.d.ts +9 -9
- package/dist/core/canvas/tree.js +5 -5
- package/dist/core/canvas/waits.d.ts +13 -13
- package/dist/core/canvas/waits.js +6 -6
- package/dist/core/canvas/worktrees.d.ts +15 -15
- package/dist/core/canvas/worktrees.js +1 -1
- package/dist/core/command-hooks/transport/exec-lifecycle.js +1 -1
- package/dist/core/conversation-store/file-store.d.ts +7 -7
- package/dist/core/conversation-store/file-store.js +9 -9
- package/dist/core/conversation-store/index.d.ts +16 -14
- package/dist/core/conversation-store/index.js +1 -1
- package/dist/core/conversation-store/listener.js +5 -5
- package/dist/core/conversation-store/patch.d.ts +3 -1
- package/dist/core/conversation-store/patch.js +1 -1
- package/dist/core/feed/feed.js +3 -3
- package/dist/core/feed/inbox.d.ts +2 -2
- package/dist/core/feed/inbox.js +1 -1
- package/dist/core/feed/messages.d.ts +11 -12
- package/dist/core/feed/messages.js +5 -5
- package/dist/core/feed/reports.d.ts +4 -4
- package/dist/core/feed/reports.js +2 -2
- package/dist/core/grants/cover.d.ts +1 -1
- package/dist/core/grants/cover.js +1 -1
- package/dist/core/grants/local.d.ts +1 -1
- package/dist/core/grants/local.js +1 -1
- package/dist/core/grants/mirror.d.ts +19 -19
- package/dist/core/grants/mirror.js +2 -2
- package/dist/core/grants/on-sync.d.ts +1 -1
- package/dist/core/grants/on-sync.js +1 -1
- package/dist/core/grants/remove.js +1 -1
- package/dist/core/grants/sync.js +1 -1
- package/dist/core/graph/access.d.ts +17 -17
- package/dist/core/graph/access.js +3 -3
- package/dist/core/graph/custom.d.ts +16 -16
- package/dist/core/graph/custom.js +9 -9
- package/dist/core/graph/deletion.d.ts +3 -7
- package/dist/core/graph/deletion.js +4 -4
- package/dist/core/graph/documents.d.ts +24 -27
- package/dist/core/graph/documents.js +7 -7
- package/dist/core/graph/edges.d.ts +13 -13
- package/dist/core/graph/edges.js +1 -1
- package/dist/core/graph/events.d.ts +7 -9
- package/dist/core/graph/events.js +8 -8
- package/dist/core/graph/exposures.d.ts +6 -6
- package/dist/core/graph/exposures.js +4 -4
- package/dist/core/graph/jobs.d.ts +6 -8
- package/dist/core/graph/jobs.js +2 -2
- package/dist/core/graph/kinds/action.js +1 -1
- package/dist/core/graph/kinds/custom.js +2 -2
- package/dist/core/graph/kinds/document.d.ts +1 -0
- package/dist/core/graph/kinds/document.js +4 -4
- package/dist/core/graph/kinds/dto.d.ts +2 -2
- package/dist/core/graph/kinds/dto.js +1 -1
- package/dist/core/graph/kinds/job.js +2 -2
- package/dist/core/graph/kinds/kind.d.ts +6 -8
- package/dist/core/graph/kinds/kind.js +1 -1
- package/dist/core/graph/kinds/node.js +5 -5
- package/dist/core/graph/kinds/owner.js +2 -2
- package/dist/core/graph/kinds/registry.d.ts +6 -9
- package/dist/core/graph/kinds/registry.js +1 -1
- package/dist/core/graph/names.d.ts +6 -6
- package/dist/core/graph/names.js +3 -3
- package/dist/core/graph/object-waits.d.ts +4 -7
- package/dist/core/graph/object-waits.js +1 -1
- package/dist/core/graph/objects.d.ts +14 -14
- package/dist/core/graph/objects.js +9 -9
- package/dist/core/graph/package-docs.d.ts +2 -7
- package/dist/core/graph/package-docs.js +5 -5
- package/dist/core/graph/package-kinds.d.ts +2 -5
- package/dist/core/graph/package-kinds.js +1 -1
- package/dist/core/graph/package-reconcile.d.ts +2 -5
- package/dist/core/graph/package-reconcile.js +1 -1
- package/dist/core/graph/reader.d.ts +18 -18
- package/dist/core/graph/reader.js +3 -3
- package/dist/core/graph/receivers.d.ts +4 -4
- package/dist/core/graph/receivers.js +5 -5
- package/dist/core/graph/repo-sync/exchange.d.ts +3 -7
- package/dist/core/graph/repo-sync/exchange.js +2 -2
- package/dist/core/graph/repo-sync/repos.d.ts +7 -5
- package/dist/core/graph/repo-sync/repos.js +3 -3
- package/dist/core/graph/repo-sync/sync.d.ts +3 -6
- package/dist/core/graph/repo-sync/sync.js +2 -2
- package/dist/core/graph/rules.d.ts +5 -5
- package/dist/core/graph/rules.js +3 -3
- package/dist/core/graph/spaces/app.js +1 -1
- package/dist/core/graph/spaces/index.d.ts +4 -5
- package/dist/core/graph/spaces/index.js +1 -1
- package/dist/core/graph/spaces/own-memory.d.ts +4 -4
- package/dist/core/graph/spaces/own-memory.js +1 -1
- package/dist/core/graph/spaces/person.js +3 -3
- package/dist/core/graph/spaces/repo.d.ts +1 -1
- package/dist/core/graph/spaces/repo.js +1 -1
- package/dist/core/graph/watches.d.ts +15 -15
- package/dist/core/graph/watches.js +10 -10
- package/dist/core/human/feedback-companion.d.ts +2 -2
- package/dist/core/human/feedback-companion.js +1 -1
- package/dist/core/human/feedback.d.ts +3 -3
- package/dist/core/human/feedback.js +1 -1
- package/dist/core/human/requests.d.ts +34 -33
- package/dist/core/human/requests.js +20 -20
- package/dist/core/human/scan.d.ts +2 -2
- package/dist/core/human/scan.js +1 -1
- package/dist/core/human/tickets.d.ts +9 -9
- package/dist/core/human/tickets.js +1 -1
- package/dist/core/llm/app-rungs.d.ts +1 -1
- package/dist/core/llm/app-rungs.js +1 -1
- package/dist/core/llm/run.js +1 -1
- package/dist/core/peer/directory.d.ts +1 -1
- package/dist/core/peer/directory.js +1 -1
- package/dist/core/peer/envelope.d.ts +3 -3
- package/dist/core/peer/envelope.js +1 -1
- package/dist/core/peer/home.d.ts +7 -7
- package/dist/core/peer/home.js +2 -2
- package/dist/core/peer/ingest.d.ts +6 -6
- package/dist/core/peer/ingest.js +1 -1
- package/dist/core/peer/outbox-store.d.ts +14 -14
- package/dist/core/peer/outbox-store.js +5 -5
- package/dist/core/peer/receiver.d.ts +2 -2
- package/dist/core/peer/receiver.js +1 -1
- package/dist/core/peer/stubs.d.ts +10 -10
- package/dist/core/peer/stubs.js +1 -1
- package/dist/core/providers/approval.d.ts +2 -2
- package/dist/core/providers/approval.js +2 -2
- package/dist/core/providers/audit.d.ts +3 -3
- package/dist/core/providers/audit.js +2 -2
- package/dist/core/providers/bundles.js +2 -2
- package/dist/core/providers/call.d.ts +2 -2
- package/dist/core/providers/call.js +1 -1
- package/dist/core/providers/files.d.ts +1 -1
- package/dist/core/providers/files.js +1 -1
- package/dist/core/providers/mint.js +1 -1
- package/dist/core/providers/receipts.d.ts +1 -1
- package/dist/core/providers/receipts.js +2 -2
- package/dist/core/review/birth.js +1 -1
- package/dist/core/review/comments.d.ts +19 -19
- package/dist/core/review/comments.js +5 -5
- package/dist/core/review/companion.d.ts +1 -1
- package/dist/core/review/companion.js +1 -1
- package/dist/core/review/document.d.ts +3 -3
- package/dist/core/review/document.js +2 -2
- package/dist/core/review/fork.js +2 -2
- package/dist/core/review/realize.js +1 -1
- package/dist/core/review/remap.d.ts +2 -2
- package/dist/core/review/remap.js +4 -4
- package/dist/core/review/stage.d.ts +1 -1
- package/dist/core/review/stage.js +1 -1
- package/dist/core/review/store.d.ts +21 -21
- package/dist/core/review/store.js +1 -1
- package/dist/core/runs/activity.d.ts +1 -1
- package/dist/core/runs/activity.js +5 -5
- package/dist/core/runs/confinement.d.ts +7 -7
- package/dist/core/runs/confinement.js +2 -2
- package/dist/core/runs/events.d.ts +12 -12
- package/dist/core/runs/events.js +4 -4
- package/dist/core/runs/operations.d.ts +11 -11
- package/dist/core/runs/operations.js +5 -5
- package/dist/core/runs/questions.d.ts +10 -10
- package/dist/core/runs/questions.js +3 -3
- package/dist/core/runtime/auth-reload.js +1 -1
- package/dist/core/runtime/bearings.d.ts +5 -5
- package/dist/core/runtime/bearings.js +6 -6
- package/dist/core/runtime/broker-inventory.js +1 -1
- package/dist/core/runtime/broker-request.js +1 -1
- package/dist/core/runtime/broker.js +1 -1
- package/dist/core/runtime/close.d.ts +3 -3
- package/dist/core/runtime/close.js +1 -1
- package/dist/core/runtime/deliver-live.js +1 -1
- package/dist/core/runtime/fleet.d.ts +2 -2
- package/dist/core/runtime/host.d.ts +3 -3
- package/dist/core/runtime/host.js +3 -3
- package/dist/core/runtime/kickoff.d.ts +12 -12
- package/dist/core/runtime/kickoff.js +17 -17
- package/dist/core/runtime/launch-target.d.ts +1 -1
- package/dist/core/runtime/launch-target.js +1 -1
- package/dist/core/runtime/ledger.d.ts +3 -3
- package/dist/core/runtime/ledger.js +3 -3
- package/dist/core/runtime/lifecycle.d.ts +1 -1
- package/dist/core/runtime/lifecycle.js +2 -2
- package/dist/core/runtime/memory-admission.js +1 -1
- package/dist/core/runtime/model-swap.d.ts +2 -2
- package/dist/core/runtime/model-swap.js +1 -1
- package/dist/core/runtime/node-read.d.ts +1 -1
- package/dist/core/runtime/node-read.js +2 -2
- package/dist/core/runtime/nodes.d.ts +6 -6
- package/dist/core/runtime/nodes.js +1 -1
- package/dist/core/runtime/outcome-document.d.ts +1 -1
- package/dist/core/runtime/outcome-document.js +1 -1
- package/dist/core/runtime/persona.d.ts +3 -3
- package/dist/core/runtime/persona.js +2 -2
- package/dist/core/runtime/placement.d.ts +11 -11
- package/dist/core/runtime/placement.js +1 -1
- package/dist/core/runtime/promote.d.ts +3 -3
- package/dist/core/runtime/promote.js +1 -1
- package/dist/core/runtime/recycle.js +1 -1
- package/dist/core/runtime/reopen.d.ts +5 -5
- package/dist/core/runtime/reopen.js +1 -1
- package/dist/core/runtime/reset.d.ts +4 -4
- package/dist/core/runtime/reset.js +1 -1
- package/dist/core/runtime/revive-all.d.ts +2 -2
- package/dist/core/runtime/revive-all.js +1 -1
- package/dist/core/runtime/revive.d.ts +4 -4
- package/dist/core/runtime/revive.js +2 -2
- package/dist/core/runtime/roadmap.d.ts +6 -6
- package/dist/core/runtime/roadmap.js +5 -5
- package/dist/core/runtime/session-branch.d.ts +1 -1
- package/dist/core/runtime/session-branch.js +1 -1
- package/dist/core/runtime/session-list-cache.js +1 -1
- package/dist/core/runtime/situational-live.js +1 -1
- package/dist/core/runtime/spawn.d.ts +2 -2
- package/dist/core/runtime/spawn.js +2 -2
- package/dist/core/runtime/stop-guard.d.ts +2 -2
- package/dist/core/runtime/stop-guard.js +3 -3
- package/dist/core/runtime/warm-pool.d.ts +2 -2
- package/dist/core/runtime/warm-pool.js +1 -1
- package/dist/core/spaces/mounts.d.ts +2 -2
- package/dist/core/spaces/mounts.js +1 -1
- package/dist/core/spaces/permissions.d.ts +1 -1
- package/dist/core/spaces/permissions.js +1 -1
- package/dist/core/spaces/process.d.ts +1 -1
- package/dist/core/spaces/process.js +1 -1
- package/dist/core/spaces/space.js +1 -1
- package/dist/core/spaces/stop.d.ts +3 -3
- package/dist/core/spaces/stop.js +2 -2
- package/dist/core/spaces/users.d.ts +6 -6
- package/dist/core/spaces/users.js +1 -1
- package/dist/core/storage/attachments.d.ts +2 -2
- package/dist/core/storage/attachments.js +1 -1
- package/dist/core/storage/shares.d.ts +2 -2
- package/dist/core/storage/shares.js +1 -1
- package/dist/core/storage/tables.d.ts +21 -21
- package/dist/core/storage/tables.js +3 -3
- package/dist/core/substrate/delivery/corpus.d.ts +5 -8
- package/dist/core/substrate/delivery/corpus.js +3 -3
- package/dist/core/substrate/delivery/deliver.d.ts +10 -15
- package/dist/core/substrate/delivery/deliver.js +3 -3
- package/dist/core/substrate/delivery/plan.d.ts +2 -12
- package/dist/core/substrate/delivery/plan.js +3 -3
- package/dist/core/substrate/delivery/render-boot.d.ts +4 -4
- package/dist/core/substrate/delivery/render-boot.js +18 -18
- package/dist/core/substrate/delivery/render-event.d.ts +7 -14
- package/dist/core/substrate/delivery/render-event.js +4 -4
- package/dist/core/substrate/subject.d.ts +2 -2
- package/dist/core/substrate/subject.js +1 -1
- package/dist/core/usage/ledger.d.ts +6 -6
- package/dist/core/usage/ledger.js +4 -4
- package/dist/core/worktree-close.js +4 -4
- package/dist/core/worktree-mutation-async.js +7 -7
- package/dist/core/worktree-quarantine.js +1 -1
- package/dist/core/worktree-sweep.d.ts +1 -1
- package/dist/core/worktree-sweep.js +6 -6
- package/dist/core/worktree.d.ts +5 -5
- package/dist/core/worktree.js +13 -13
- package/dist/daemon/analytics/compute.d.ts +2 -2
- package/dist/daemon/analytics/compute.js +1 -1
- package/dist/daemon/api/app-listener.d.ts +4 -4
- package/dist/daemon/api/app-listener.js +13 -13
- package/dist/daemon/api/bridge.js +5 -5
- package/dist/daemon/api/document-listener.js +6 -6
- package/dist/daemon/api/handlers/analytics.js +1 -1
- package/dist/daemon/api/handlers/attach.js +1 -1
- package/dist/daemon/api/handlers/bash-jobs.js +1 -1
- package/dist/daemon/api/handlers/bash.js +1 -1
- package/dist/daemon/api/handlers/broker-ops.d.ts +1 -1
- package/dist/daemon/api/handlers/broker-ops.js +1 -1
- package/dist/daemon/api/handlers/broker-recovery.d.ts +1 -1
- package/dist/daemon/api/handlers/broker-recovery.js +1 -1
- package/dist/daemon/api/handlers/broker-signals.d.ts +2 -2
- package/dist/daemon/api/handlers/broker-signals.js +2 -2
- package/dist/daemon/api/handlers/canvas.d.ts +1 -1
- package/dist/daemon/api/handlers/canvas.js +4 -4
- package/dist/daemon/api/handlers/chat-inventory.js +1 -1
- package/dist/daemon/api/handlers/crons.js +1 -1
- package/dist/daemon/api/handlers/custom-objects.d.ts +4 -4
- package/dist/daemon/api/handlers/custom-objects.js +3 -3
- package/dist/daemon/api/handlers/delivery-retry.js +1 -1
- package/dist/daemon/api/handlers/delivery.js +1 -1
- package/dist/daemon/api/handlers/docs.d.ts +4 -4
- package/dist/daemon/api/handlers/docs.js +1 -1
- package/dist/daemon/api/handlers/feedback-comments.js +3 -3
- package/dist/daemon/api/handlers/files.js +1 -1
- package/dist/daemon/api/handlers/focus.js +1 -1
- package/dist/daemon/api/handlers/health.js +3 -3
- package/dist/daemon/api/handlers/hook-exec.js +1 -1
- package/dist/daemon/api/handlers/human-requests.js +1 -1
- package/dist/daemon/api/handlers/inbox-page.d.ts +1 -1
- package/dist/daemon/api/handlers/inbox-page.js +1 -1
- package/dist/daemon/api/handlers/inbox.d.ts +1 -1
- package/dist/daemon/api/handlers/inbox.js +1 -1
- package/dist/daemon/api/handlers/llm.d.ts +1 -1
- package/dist/daemon/api/handlers/llm.js +3 -3
- package/dist/daemon/api/handlers/memory-reads.js +1 -1
- package/dist/daemon/api/handlers/memory.d.ts +5 -5
- package/dist/daemon/api/handlers/memory.js +5 -5
- package/dist/daemon/api/handlers/messages.js +2 -2
- package/dist/daemon/api/handlers/node-events.d.ts +2 -2
- package/dist/daemon/api/handlers/node-events.js +3 -3
- package/dist/daemon/api/handlers/node-outcomes.js +1 -1
- package/dist/daemon/api/handlers/node-records.js +2 -2
- package/dist/daemon/api/handlers/nodes.d.ts +1 -1
- package/dist/daemon/api/handlers/nodes.js +1 -1
- package/dist/daemon/api/handlers/objects.js +3 -3
- package/dist/daemon/api/handlers/package-docs.js +1 -1
- package/dist/daemon/api/handlers/plugin-app-token.d.ts +1 -1
- package/dist/daemon/api/handlers/plugin-app-token.js +1 -1
- package/dist/daemon/api/handlers/profiles.d.ts +3 -3
- package/dist/daemon/api/handlers/profiles.js +1 -1
- package/dist/daemon/api/handlers/providers.d.ts +1 -1
- package/dist/daemon/api/handlers/providers.js +1 -1
- package/dist/daemon/api/handlers/questions.js +1 -1
- package/dist/daemon/api/handlers/reports.d.ts +1 -1
- package/dist/daemon/api/handlers/reports.js +5 -5
- package/dist/daemon/api/handlers/review-comments.js +1 -1
- package/dist/daemon/api/handlers/reviews.js +1 -1
- package/dist/daemon/api/handlers/runs.js +1 -1
- package/dist/daemon/api/handlers/structured-requests.js +1 -1
- package/dist/daemon/api/handlers/subscriptions.js +1 -1
- package/dist/daemon/api/handlers/transfer.js +1 -1
- package/dist/daemon/api/map.d.ts +3 -3
- package/dist/daemon/api/map.js +1 -1
- package/dist/daemon/api/principal.d.ts +1 -1
- package/dist/daemon/api/principal.js +1 -1
- package/dist/daemon/api/reader.d.ts +5 -5
- package/dist/daemon/api/reader.js +1 -1
- package/dist/daemon/api/router.d.ts +5 -5
- package/dist/daemon/api/router.js +1 -1
- package/dist/daemon/api/server.js +1 -1
- package/dist/daemon/broker-signals/bus.d.ts +1 -1
- package/dist/daemon/broker-signals/bus.js +1 -1
- package/dist/daemon/companion-retire.js +1 -1
- package/dist/daemon/cron/armed-context.d.ts +2 -2
- package/dist/daemon/cron/armed-context.js +1 -1
- package/dist/daemon/cron/authority.d.ts +2 -2
- package/dist/daemon/cron/authority.js +1 -1
- package/dist/daemon/cron/disposition.js +1 -1
- package/dist/daemon/cron/ended.d.ts +1 -1
- package/dist/daemon/cron/ended.js +2 -2
- package/dist/daemon/cron/escalation.js +3 -3
- package/dist/daemon/cron/folders.d.ts +1 -1
- package/dist/daemon/cron/folders.js +1 -1
- package/dist/daemon/cron/held.d.ts +1 -1
- package/dist/daemon/cron/held.js +1 -1
- package/dist/daemon/cron/lease-recovery.d.ts +1 -1
- package/dist/daemon/cron/lease-recovery.js +1 -1
- package/dist/daemon/cron/passes.d.ts +2 -2
- package/dist/daemon/cron/passes.js +1 -1
- package/dist/daemon/cron/run-socket.d.ts +1 -1
- package/dist/daemon/cron/run-socket.js +1 -1
- package/dist/daemon/cron/settle.js +1 -1
- package/dist/daemon/cron/sinks.d.ts +1 -1
- package/dist/daemon/cron/sinks.js +2 -2
- package/dist/daemon/cron-run.d.ts +12 -3
- package/dist/daemon/cron-run.js +2 -2
- package/dist/daemon/crtrd.js +6 -6
- package/dist/daemon/delivery/run-delivery.js +1 -1
- package/dist/daemon/due-sources.d.ts +3 -3
- package/dist/daemon/due-sources.js +1 -1
- package/dist/daemon/due.d.ts +3 -3
- package/dist/daemon/due.js +7 -7
- package/dist/daemon/fleet.d.ts +2 -2
- package/dist/daemon/fleet.js +11 -11
- package/dist/daemon/human/finish.js +3 -3
- package/dist/daemon/human/settle.d.ts +1 -1
- package/dist/daemon/human/settle.js +1 -1
- package/dist/daemon/human/sweep.js +1 -1
- package/dist/daemon/joined-owner.d.ts +2 -2
- package/dist/daemon/joined-owner.js +1 -1
- package/dist/daemon/messaging/node-message.js +1 -1
- package/dist/daemon/park-activity.d.ts +2 -2
- package/dist/daemon/park-activity.js +1 -1
- package/dist/daemon/peer/authority.js +1 -1
- package/dist/daemon/peer/forward.d.ts +6 -6
- package/dist/daemon/peer/forward.js +1 -1
- package/dist/daemon/peer/handlers.js +1 -1
- package/dist/daemon/peer/ingress.d.ts +4 -4
- package/dist/daemon/peer/ingress.js +1 -1
- package/dist/daemon/peer/outbox.d.ts +2 -2
- package/dist/daemon/peer/outbox.js +1 -1
- package/dist/daemon/peer/relay-service.js +1 -1
- package/dist/daemon/plugin-objects/read-leaf.d.ts +2 -2
- package/dist/daemon/plugin-objects/read-leaf.js +2 -2
- package/dist/daemon/profile-delete.js +1 -1
- package/dist/daemon/readiness.d.ts +2 -2
- package/dist/daemon/readiness.js +1 -1
- package/dist/daemon/reconcilers/action-lane.d.ts +1 -1
- package/dist/daemon/reconcilers/action-lane.js +1 -1
- package/dist/daemon/reconcilers/bash-deadline.js +2 -2
- package/dist/daemon/reconcilers/broker-supervision.d.ts +1 -1
- package/dist/daemon/reconcilers/broker-supervision.js +4 -4
- package/dist/daemon/reconcilers/controller-death.d.ts +1 -1
- package/dist/daemon/reconcilers/controller-death.js +1 -1
- package/dist/daemon/reconcilers/cron-lane.d.ts +1 -1
- package/dist/daemon/reconcilers/cron-lane.js +1 -1
- package/dist/daemon/reconcilers/delivery-lane.d.ts +1 -1
- package/dist/daemon/reconcilers/delivery-lane.js +2 -2
- package/dist/daemon/reconcilers/fault-retry-backstop.d.ts +3 -3
- package/dist/daemon/reconcilers/fault-retry-backstop.js +1 -1
- package/dist/daemon/reconcilers/grove-instance-sweep.d.ts +2 -2
- package/dist/daemon/reconcilers/grove-instance-sweep.js +1 -1
- package/dist/daemon/reconcilers/live-obligation.d.ts +6 -6
- package/dist/daemon/reconcilers/live-obligation.js +1 -1
- package/dist/daemon/reconcilers/managed-worktree-sweep.js +1 -1
- package/dist/daemon/reconcilers/node-deadline.d.ts +1 -1
- package/dist/daemon/reconcilers/node-deadline.js +1 -1
- package/dist/daemon/reconcilers/node-lifecycle/freeze-lane.js +1 -1
- package/dist/daemon/reconcilers/node-lifecycle/respawn-policy.d.ts +3 -3
- package/dist/daemon/reconcilers/node-lifecycle/respawn-policy.js +1 -1
- package/dist/daemon/reconcilers/node-lifecycle/terminating.js +1 -1
- package/dist/daemon/reconcilers/node-lifecycle/tick.js +1 -1
- package/dist/daemon/reconcilers/node-lifecycle/wants-execution.d.ts +1 -1
- package/dist/daemon/reconcilers/node-lifecycle/wants-execution.js +1 -1
- package/dist/daemon/reconcilers/pending-review-submit.d.ts +1 -1
- package/dist/daemon/reconcilers/pending-review-submit.js +1 -1
- package/dist/daemon/reconcilers/storage-due-work.js +1 -1
- package/dist/daemon/reconcilers/storage-maintenance.d.ts +1 -1
- package/dist/daemon/reconcilers/storage-maintenance.js +2 -2
- package/dist/daemon/reconcilers/structured-request-lane.d.ts +1 -1
- package/dist/daemon/reconcilers/structured-request-lane.js +1 -1
- package/dist/daemon/review/comment-notify.js +2 -2
- package/dist/daemon/review/companion.d.ts +3 -3
- package/dist/daemon/review/companion.js +1 -1
- package/dist/daemon/review/finish.js +1 -1
- package/dist/daemon/review/sweep.js +1 -1
- package/dist/daemon/run-notices.d.ts +4 -4
- package/dist/daemon/run-notices.js +1 -1
- package/dist/daemon/runs/append-section.d.ts +2 -2
- package/dist/daemon/runs/append-section.js +2 -2
- package/dist/daemon/runs/observer.d.ts +2 -2
- package/dist/daemon/runs/observer.js +2 -2
- package/dist/daemon/structured-requests/boot.d.ts +1 -1
- package/dist/daemon/structured-requests/boot.js +1 -1
- package/dist/daemon/structured-requests/effects.js +1 -1
- package/dist/daemon/structured-requests/sidecar.d.ts +1 -1
- package/dist/daemon/structured-requests/sidecar.js +1 -1
- package/dist/migrations/004-canvas-documents/apply.d.ts +3 -3
- package/dist/migrations/004-canvas-documents/apply.js +1 -1
- package/dist/migrations/004-canvas-documents/index.d.ts +2 -2
- package/dist/migrations/004-canvas-documents/index.js +2 -2
- package/dist/migrations/activation.js +2 -2
- package/docs/public-api.md +11 -0
- package/package.json +3 -2
- package/packages/crouter-identity/package.json +1 -1
- package/runtime.lock.json +12 -12
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
var
|
|
1
|
+
var u=Object.defineProperty;var a=(t,e)=>u(t,"name",{value:e,configurable:!0});import{randomBytes as N}from"node:crypto";import{withCanvasWrite as l,openDb as c}from"./db.js";import{normalizedSettlement as f}from"./deliveries.js";import{withRetryBudget as T}from"./delivery-contract.js";import{emitEvent as y}from"../events/emit.js";async function O(t){await t.exec(`CREATE TABLE IF NOT EXISTS daemon_actions (
|
|
2
2
|
action_id TEXT PRIMARY KEY,
|
|
3
3
|
adapter_json TEXT NOT NULL,
|
|
4
4
|
body_json TEXT,
|
|
@@ -15,14 +15,14 @@ var f=Object.defineProperty;var a=(t,e)=>f(t,"name",{value:e,configurable:!0});i
|
|
|
15
15
|
created_at INTEGER NOT NULL,
|
|
16
16
|
updated_at INTEGER NOT NULL
|
|
17
17
|
);
|
|
18
|
-
CREATE INDEX IF NOT EXISTS daemon_actions_due ON daemon_actions(state, next_attempt_at, created_at, action_id) WHERE canceled_at IS NULL;`)}a(
|
|
19
|
-
VALUES (?, ?, ?, ?, 'pending', 0, ?, ?, ?)`).run(
|
|
18
|
+
CREATE INDEX IF NOT EXISTS daemon_actions_due ON daemon_actions(state, next_attempt_at, created_at, action_id) WHERE canceled_at IS NULL;`)}a(O,"createDaemonActionsTable");function s(t){return{actionId:t.action_id,adapter:JSON.parse(t.adapter_json),body:t.body_json===null?null:JSON.parse(t.body_json),idempotencyKey:t.idempotency_key,state:t.state,attempts:t.attempts,nextAttemptAt:t.next_attempt_at,claimedAt:t.claimed_at,claimOwner:t.claim_owner,acknowledgedAt:t.acknowledged_at,failedAt:t.failed_at,lastFailure:t.last_failure_json===null?null:JSON.parse(t.last_failure_json),canceledAt:t.canceled_at,createdAt:t.created_at,updatedAt:t.updated_at}}a(s,"actionFrom");function A(){return N(16).toString("hex")}a(A,"newId");async function I(t){return await l(async e=>{const o=await e.prepare("SELECT action_id FROM daemon_actions WHERE idempotency_key = ?").get(t.idempotencyKey);if(o!==void 0)return o.action_id;const d=Date.now(),n=A(),r=t.bodyJson===void 0?null:JSON.stringify(t.bodyJson);return await e.prepare(`INSERT INTO daemon_actions (action_id, adapter_json, body_json, idempotency_key, state, attempts, next_attempt_at, created_at, updated_at)
|
|
19
|
+
VALUES (?, ?, ?, ?, 'pending', 0, ?, ?, ?)`).run(n,JSON.stringify(t.adapter),r,t.idempotencyKey,d,d,d),n})}a(I,"enqueueDaemonAction");async function U(t){const e=await(await c()).prepare("SELECT * FROM daemon_actions WHERE idempotency_key = ?").get(t);return e===void 0?null:s(e)}a(U,"readDaemonAction");async function w(t){const e=await(await c()).prepare("SELECT * FROM daemon_actions WHERE action_id = ?").get(t);return e===void 0?null:s(e)}a(w,"readDaemonActionById");async function h(t){return(await(await c()).prepare(`SELECT * FROM daemon_actions
|
|
20
20
|
WHERE state = 'pending' AND canceled_at IS NULL AND next_attempt_at <= ?
|
|
21
|
-
ORDER BY next_attempt_at, created_at, action_id`).all(t).map(
|
|
22
|
-
WHERE action_id = ? AND state = 'pending' AND canceled_at IS NULL AND next_attempt_at <= ?`).run(e,
|
|
21
|
+
ORDER BY next_attempt_at, created_at, action_id`).all(t)).map(s)}a(h,"dueDaemonActions");async function b(t,e,o){return await l(async d=>{const n=await d.prepare(`UPDATE daemon_actions SET state = 'handed_off', attempts = attempts + 1, claimed_at = ?, claim_owner = ?, updated_at = ?
|
|
22
|
+
WHERE action_id = ? AND state = 'pending' AND canceled_at IS NULL AND next_attempt_at <= ?`).run(e,o,e,t,e);return Number(n.changes)===0?null:s(await d.prepare("SELECT * FROM daemon_actions WHERE action_id = ?").get(t))})}a(b,"claimDaemonAction");async function H(t,e,o,d,n=Date.now()){const r=T(f(d),e),i=r.settlement,p=i.state==="pending"||i.state==="permanent_failed"?JSON.stringify(i.failure):null,_=i.state==="released"?"pending":i.state,E=i.state==="pending"?i.nextAttemptAt:_==="pending"?n:null,m=Number((await(await c()).prepare(`UPDATE daemon_actions
|
|
23
23
|
SET state = ?, next_attempt_at = ?, claimed_at = NULL, claim_owner = NULL,
|
|
24
24
|
acknowledged_at = ?, failed_at = ?, last_failure_json = ?, updated_at = ?
|
|
25
|
-
WHERE action_id = ? AND state = 'handed_off' AND attempts = ? AND claim_owner = ?`).run(
|
|
25
|
+
WHERE action_id = ? AND state = 'handed_off' AND attempts = ? AND claim_owner = ?`).run(_,E,_==="acknowledged"?n:null,_==="permanent_failed"?n:null,p,n,t,e,o)).changes)===1;return m&&r.exhausted&&i.state==="permanent_failed"&&y({level:"error",event:"daemon_action.exhausted",outcome:"failed",attempt:e,fields:{action_id:t,failure:i.failure,retry:`crtr sys retry-delivery ${t}`}}),m}a(H,"settleDaemonAction");async function j(t,e=Date.now()){return Number((await(await c()).prepare(`UPDATE daemon_actions
|
|
26
26
|
SET state = 'pending', attempts = 0, next_attempt_at = ?, failed_at = NULL, updated_at = ?
|
|
27
|
-
WHERE action_id = ? AND state = 'permanent_failed' AND canceled_at IS NULL AND last_failure_json IS NOT NULL`).run(e,e,t).changes)===1
|
|
28
|
-
WHERE state = 'handed_off'`).run(t,t).changes)
|
|
27
|
+
WHERE action_id = ? AND state = 'permanent_failed' AND canceled_at IS NULL AND last_failure_json IS NOT NULL`).run(e,e,t)).changes)===1}a(j,"retryFailedDaemonAction");async function C(t){return Number((await(await c()).prepare(`UPDATE daemon_actions SET state = 'pending', next_attempt_at = ?, claimed_at = NULL, claim_owner = NULL, updated_at = ?
|
|
28
|
+
WHERE state = 'handed_off'`).run(t,t)).changes)}a(C,"resetHandedOffDaemonActions");export{b as claimDaemonAction,O as createDaemonActionsTable,h as dueDaemonActions,I as enqueueDaemonAction,U as readDaemonAction,w as readDaemonActionById,C as resetHandedOffDaemonActions,j as retryFailedDaemonAction,H as settleDaemonAction};
|
|
@@ -55,13 +55,13 @@ export type DaemonOwnerClaimResult = {
|
|
|
55
55
|
* to probe), so a malformed incumbent can only ever be lost against, never
|
|
56
56
|
* reclaimed, by this primitive alone. That is intentional: this module never
|
|
57
57
|
* guesses at repair. */
|
|
58
|
-
export declare function claimDaemonOwnership(token: string): DaemonOwnerClaimResult
|
|
58
|
+
export declare function claimDaemonOwnership(token: string): Promise<DaemonOwnerClaimResult>;
|
|
59
59
|
/** Release exclusive daemon ownership, iff the persisted row still equals
|
|
60
60
|
* `claim` EXACTLY (key present and value byte-identical to this invocation's
|
|
61
61
|
* own winning claim). This is a conditional delete, not an unconditional one:
|
|
62
62
|
* a caller must never release a row a successor has since won (e.g. after
|
|
63
63
|
* this invocation's claim was already reclaimed via the dead-incumbent CAS
|
|
64
64
|
* path while this process lingered mid-teardown). */
|
|
65
|
-
export declare function releaseDaemonOwnership(claim: DaemonOwnerClaim): {
|
|
65
|
+
export declare function releaseDaemonOwnership(claim: DaemonOwnerClaim): Promise<{
|
|
66
66
|
readonly released: boolean;
|
|
67
|
-
}
|
|
67
|
+
}>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
var
|
|
1
|
+
var p=Object.defineProperty;var i=(e,n)=>p(e,"name",{value:n,configurable:!0});import{openDb as s}from"./db.js";import{capturePidIdentities as E,recordedPidLiveness as m}from"./pid.js";const c="daemon_owner";function l(e){return JSON.stringify({pid:e.pid,pid_identity:e.pid_identity,token:e.token})}i(l,"serializeClaim");function f(e){let n;try{n=JSON.parse(e)}catch{return null}if(typeof n!="object"||n===null)return null;const{pid:a,pid_identity:t,token:r}=n;return!Number.isInteger(a)||a<=0||typeof t!="string"||t.length===0||typeof r!="string"||r.length===0?null:{pid:a,pid_identity:t,token:r}}i(f,"parseClaim");async function y(){await(await s()).exec(`
|
|
2
2
|
CREATE TABLE IF NOT EXISTS canvas_meta (
|
|
3
3
|
key TEXT PRIMARY KEY,
|
|
4
4
|
value TEXT NOT NULL
|
|
5
5
|
)
|
|
6
|
-
`)}
|
|
6
|
+
`)}i(y,"ensureOwnerTable");async function w(){return(await(await s()).prepare("SELECT value FROM canvas_meta WHERE key = ?").get(c))?.value}i(w,"readSnapshot");async function O(e){const n=E([process.pid]),a=n?.get(process.pid);if(n===null||a===void 0)return{claimed:!1,reason:"own_identity_indeterminate"};const t={pid:process.pid,pid_identity:a,token:e},r=l(t);for(await y();;){const d=await w();if(d===void 0){if((await(await s()).prepare("INSERT INTO canvas_meta (key, value) SELECT ?, ? WHERE NOT EXISTS (SELECT 1 FROM canvas_meta WHERE key = ?)").run(c,r,c)).changes===1)return{claimed:!0,claim:t};continue}const o=f(d);if(o===null)return{claimed:!1,reason:"incumbent_malformed"};const u=m(o.pid,o.pid_identity);if(u==="alive"||u==="indeterminate")return{claimed:!1,reason:u==="alive"?"incumbent_alive":"incumbent_indeterminate",incumbentPid:o.pid,verdict:u};if((await(await s()).prepare("UPDATE canvas_meta SET value = ? WHERE key = ? AND value = ?").run(r,c,d)).changes===1)return{claimed:!0,claim:t}}}i(O,"claimDaemonOwnership");async function N(e){return{released:(await(await s()).prepare("DELETE FROM canvas_meta WHERE key = ? AND value = ?").run(c,l(e))).changes===1}}i(N,"releaseDaemonOwnership");export{c as DAEMON_OWNER_META_KEY,O as claimDaemonOwnership,N as releaseDaemonOwnership};
|
package/dist/core/canvas/db.d.ts
CHANGED
|
@@ -1,35 +1,11 @@
|
|
|
1
1
|
import { DatabaseSync, type SQLInputValue } from 'node:sqlite';
|
|
2
|
-
import { prepared } from '../sqlite-statements.js';
|
|
3
2
|
export { MIGRATIONS } from './migrations.js';
|
|
4
|
-
export { prepared };
|
|
5
3
|
/** A schema change invalidates statements compiled against the old schema. */
|
|
6
4
|
export declare function migrate(db: DatabaseSync): void;
|
|
7
5
|
/** Only the daemon (and its API-server test host) registers this process-local hook.
|
|
8
6
|
* Register after migration: TEMP triggers need the real tables to exist. */
|
|
9
7
|
export declare function bindDaemonCanvasOpenHook(hook: (db: DatabaseSync) => void): void;
|
|
10
8
|
export declare function clearDaemonCanvasOpenHook(): void;
|
|
11
|
-
/** Open (or reuse) the canvas db at the current `CRTR_HOME`, configuring WAL
|
|
12
|
-
* but never changing its schema. Keyed by path so tests with distinct homes get
|
|
13
|
-
* independent handles.
|
|
14
|
-
*
|
|
15
|
-
* A cache hit trusts the cached handle outright: `crtrd` is this process's
|
|
16
|
-
* sole canvas-db owner (see `crtrd-sole-state-owner`), and nothing outside
|
|
17
|
-
* `openDb`/`closeDb` ever touches `handles` — there is no other actor in this
|
|
18
|
-
* process that could invalidate a live handle out from under it. (A
|
|
19
|
-
* 2026-06-25 revision added a `PRAGMA database_list` liveness probe here that
|
|
20
|
-
* silently closed and reopened the handle on any throw; it shipped alongside
|
|
21
|
-
* an unrelated guest-relay `PATH` fix for the now-removed `hearth` guest
|
|
22
|
-
* bootstrap, named no concrete failure mode in its commit or a test, and that
|
|
23
|
-
* guest-relay path no longer exists. Removed rather than kept-and-logged: a
|
|
24
|
-
* silent boot-path reopen is worse than trusting a handle this process
|
|
25
|
-
* already owns.) */
|
|
26
|
-
export declare function openDb(): DatabaseSync;
|
|
27
|
-
/** Run `body` under the canvas SQLite write lock, joining an outer transaction
|
|
28
|
-
* when the shared connection already owns one. This is the common boundary for
|
|
29
|
-
* multi-statement mutations whose reads and writes must linearize as one unit;
|
|
30
|
-
* `node:sqlite` rejects nested BEGINs, so only the outermost call commits.
|
|
31
|
-
*/
|
|
32
|
-
export declare function withCanvasWrite<T>(body: (db: DatabaseSync) => T): T;
|
|
33
9
|
/** Close and forget the handle for the current home. Mainly for tests. */
|
|
34
10
|
export declare function closeDb(): void;
|
|
35
11
|
export type CanvasParams = [Record<string, SQLInputValue>, ...SQLInputValue[]] | SQLInputValue[];
|
|
@@ -48,12 +24,25 @@ export interface CanvasDb {
|
|
|
48
24
|
/** A statement compiled per call; for generated SQL (IN lists, schema-dependent text). */
|
|
49
25
|
prepareUncached(sql: string): CanvasStatement;
|
|
50
26
|
exec(sql: string): Promise<void>;
|
|
27
|
+
/** True when the calling async context is inside a `withCanvasWrite` body (its own open transaction). */
|
|
28
|
+
readonly inTransaction: boolean;
|
|
51
29
|
/** The SQLite connection, for the synchronous migration chain only. Deleted with the Postgres swap. */
|
|
52
30
|
readonly raw: DatabaseSync;
|
|
53
31
|
}
|
|
54
|
-
/**
|
|
55
|
-
export declare function
|
|
56
|
-
/** Run `
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
export declare function
|
|
32
|
+
/** Open (or reuse) the canvas db handle for the current `CRTR_HOME`. */
|
|
33
|
+
export declare function openDb(): Promise<CanvasDb>;
|
|
34
|
+
/** Run `hook` once the calling context's outermost transaction has committed (and released the write lock); drop it if
|
|
35
|
+
* the transaction or the savepoint holding it rolls back. Outside a transaction it runs in the next microtask. Use it for anything
|
|
36
|
+
* that tells another context about a write, so that context never reads uncommitted rows or hears of a rolled-back one. */
|
|
37
|
+
export declare function afterCommit(hook: () => void): void;
|
|
38
|
+
export interface CanvasWriteOptions {
|
|
39
|
+
/** When nested, run the body in a SAVEPOINT so a throw undoes only its own writes and the outer transaction continues. */
|
|
40
|
+
savepoint?: boolean;
|
|
41
|
+
/** Always undo the body's writes, even when it returns (a dry run). Nested, it runs in a SAVEPOINT rolled back at the end. */
|
|
42
|
+
rollback?: boolean;
|
|
43
|
+
}
|
|
44
|
+
/** Run `body` in one `BEGIN IMMEDIATE` transaction, the only transaction entry point for canvas.db.
|
|
45
|
+
* A call from inside the body's own async context joins it and only the outermost call commits; a call
|
|
46
|
+
* from any other context waits its turn. A throwing body rolls back (with `savepoint`, a nested body
|
|
47
|
+
* rolls back only its own writes). With `rollback` the body's writes are always undone. */
|
|
48
|
+
export declare function withCanvasWrite<T>(body: (db: CanvasDb) => Promise<T> | T, options?: CanvasWriteOptions): Promise<T>;
|
package/dist/core/canvas/db.js
CHANGED
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
var
|
|
2
|
-
`;
|
|
1
|
+
var C=Object.defineProperty;var o=(e,t)=>C(e,"name",{value:t,configurable:!0});import{DatabaseSync as v}from"node:sqlite";import{AsyncLocalStorage as R}from"node:async_hooks";import{forgetPrepared as y,prepared as $}from"../sqlite-statements.js";import{appendFileSync as D}from"node:fs";import{canvasDbPath as k,ensureHome as T}from"./paths.js";import{initializeEmptyLayout as _}from"../layout.js";import{migrate as I}from"./migrations.js";import{MIGRATIONS as re}from"./migrations.js";function J(e){try{I(e)}finally{y(e)}}o(J,"migrate");const l=new Map;let m;function Q(e){const t=x();e(t),m=e}o(Q,"bindDaemonCanvasOpenHook");function X(){m=void 0}o(X,"clearDaemonCanvasOpenHook");function P(){const e=process.env.CRTR_DB_OPEN_LEDGER;if(e)try{const t=`${new Date().toISOString()} ${process.pid} ${process.argv[1]??"<unknown>"}
|
|
2
|
+
`;D(e,t)}catch{}}o(P,"recordOpenLedger");function x(){const e=k(),t=l.get(e);if(t)return t;_(),T(),P();const n=new v(e);n.exec("PRAGMA busy_timeout = 5000;"),n.exec("PRAGMA journal_mode = WAL;"),n.exec("PRAGMA foreign_keys = ON;");try{m?.(n)}catch(r){throw n.close(),r}return l.set(e,n),n}o(x,"openConnection");function Y(){const e=k(),t=l.get(e);t&&(y(t),t.close(),l.delete(e))}o(Y,"closeDb");const b=1e3,i=new R;class B{static{o(this,"FifoLock")}tail=Promise.resolve();pending=0;get busy(){return this.pending>0}async acquire(){this.pending++;const t=this.tail;let n;return this.tail=new Promise(r=>{n=r}),await t,()=>{this.pending--,n()}}}const A=new WeakMap,M=new WeakMap;function S(e){let t=A.get(e);return t||A.set(e,t=new B),t}o(S,"lockFor");function w(e){const t=i.getStore();return t!==void 0&&t.open&&t.db===e}o(w,"ownsTransaction");async function p(e,t){const n=S(e);if(w(e)){const f=i.getStore(),u=performance.now();try{return t()}finally{f.statementMs+=performance.now()-u}}if(!n.busy)return t();const r=await n.acquire();try{return t()}finally{r()}}o(p,"gated");function E(e,t){const n=o(r=>r,"args");return{get:o((...r)=>p(e,()=>t().get(...n(r))),"get"),all:o((...r)=>p(e,()=>t().all(...n(r))),"all"),run:o((...r)=>p(e,()=>t().run(...n(r))),"run")}}o(E,"wrapStatement");function N(e){let t=M.get(e);return t||(t={prepare:o(n=>E(e,()=>$(e,n)),"prepare"),prepareUncached:o(n=>E(e,()=>e.prepare(n)),"prepareUncached"),exec:o(n=>p(e,()=>{e.exec(n)}),"exec"),get inTransaction(){return w(e)},raw:e},M.set(e,t)),t}o(N,"canvasDbFor");async function G(){return N(x())}o(G,"openDb");function Z(e){const t=i.getStore();if(t===void 0||!t.open){queueMicrotask(e);return}t.afterCommit.push(e)}o(Z,"afterCommit");let q=0;async function ee(e,t={}){const n=await G(),r=n.raw;if(w(r)){if(!t.savepoint&&!t.rollback)return e(n);const a=`canvas_write_${++q}`;r.exec(`SAVEPOINT ${a}`);const s=i.getStore()?.afterCommit,h=s?.length??0;let d;try{d=await e(n)}catch(O){throw r.exec(`ROLLBACK TO ${a}; RELEASE ${a}`),s?.splice(h),O}return r.exec(t.rollback?`ROLLBACK TO ${a}; RELEASE ${a}`:`RELEASE ${a}`),t.rollback&&s?.splice(h),d}const f=await S(r).acquire(),u=performance.now(),L=new Error("canvas write transaction entered here"),c={db:r,open:!0,afterCommit:[],statementMs:0};let g=!1;try{r.exec("BEGIN IMMEDIATE");try{const a=await i.run(c,()=>e(n));return r.exec(t.rollback?"ROLLBACK":"COMMIT"),g=!t.rollback,a}catch(a){try{r.exec("ROLLBACK")}catch{}throw a}}finally{c.open=!1;const a=performance.now()-u;if(a-c.statementMs>b&&console.warn(`[canvas db] write transaction held ${Math.round(a)}ms (${Math.round(c.statementMs)}ms in its statements); its body did non-db work while every other db caller waited
|
|
3
|
+
${L.stack}`),f(),g)for(const s of c.afterCommit)queueMicrotask(s)}}o(ee,"withCanvasWrite");export{re as MIGRATIONS,Z as afterCommit,Q as bindDaemonCanvasOpenHook,X as clearDaemonCanvasOpenHook,Y as closeDb,J as migrate,G as openDb,ee as withCanvasWrite};
|
|
@@ -60,12 +60,12 @@ export declare function deliveryFrom(row: StoredDelivery): DeliveryRecord;
|
|
|
60
60
|
/** Claim one broker channel. A refreshing or stale broker receives hold and changes nothing.
|
|
61
61
|
* Empty polls have no handoff to commit. If mail arrives after the plain read,
|
|
62
62
|
* the next tick claims it, just as if it arrived after the write transaction. */
|
|
63
|
-
export declare function claimNodeMail(nodeId: string, executionId: string, channel: 'wake' | 'passive' | 'deferred_run', now?: number): {
|
|
63
|
+
export declare function claimNodeMail(nodeId: string, executionId: string, channel: 'wake' | 'passive' | 'deferred_run', now?: number): Promise<{
|
|
64
64
|
action: 'claimed' | 'hold';
|
|
65
65
|
deliveries: ClaimedNodeMail[];
|
|
66
|
-
}
|
|
66
|
+
}>;
|
|
67
67
|
/** Pre-launch wake claim. It uses the same state transition but deliberately does not reject refresh intent. */
|
|
68
|
-
export declare function claimKickoffMail(nodeId: string, executionId: string, now?: number): ClaimedNodeMail[]
|
|
68
|
+
export declare function claimKickoffMail(nodeId: string, executionId: string, now?: number): Promise<ClaimedNodeMail[]>;
|
|
69
69
|
export type DeliverySettlement = {
|
|
70
70
|
state: 'acknowledged';
|
|
71
71
|
} | {
|
|
@@ -80,12 +80,12 @@ export type DeliverySettlement = {
|
|
|
80
80
|
};
|
|
81
81
|
export declare function normalizedSettlement(settlement: DeliverySettlement | ProcessDeliverySettlement): DeliverySettlement;
|
|
82
82
|
/** The one execution/attempt/owner fence for node mail and external actions. */
|
|
83
|
-
export declare function settleDelivery(deliveryId: string, attempts: number, claimOwner: string, settlement: DeliverySettlement | ProcessDeliverySettlement, now?: number): boolean
|
|
83
|
+
export declare function settleDelivery(deliveryId: string, attempts: number, claimOwner: string, settlement: DeliverySettlement | ProcessDeliverySettlement, now?: number): Promise<boolean>;
|
|
84
84
|
/** Deliberate operator retry of a delivery that failed for good: back to pending, due now,
|
|
85
85
|
* with a fresh attempt budget. The id and the claim fence are unchanged, and the last
|
|
86
86
|
* failure stays recorded until the next attempt replaces it. Returns false when the id
|
|
87
87
|
* is not a failed, uncanceled push delivery. */
|
|
88
|
-
export declare function retryFailedDelivery(deliveryId: string, now?: number): boolean
|
|
88
|
+
export declare function retryFailedDelivery(deliveryId: string, now?: number): Promise<boolean>;
|
|
89
89
|
/** Broker acknowledgement additionally checks that the execution is live before the per-row fence.
|
|
90
90
|
* Refresh intent does not refuse it: a yielding turn still acknowledges the mail
|
|
91
91
|
* its conversation consumed, and the watcher withholds the queued mail the
|
|
@@ -94,27 +94,27 @@ export declare function acknowledgeNodeMail(nodeId: string, executionId: string,
|
|
|
94
94
|
deliveryId: string;
|
|
95
95
|
attempts: number;
|
|
96
96
|
disposition: 'acknowledged' | 'released';
|
|
97
|
-
}>, now?: number): {
|
|
97
|
+
}>, now?: number): Promise<{
|
|
98
98
|
action: 'acknowledged' | 'hold';
|
|
99
99
|
results: Array<{
|
|
100
100
|
deliveryId: string;
|
|
101
101
|
outcome: 'acknowledged' | 'released' | 'stale';
|
|
102
102
|
}>;
|
|
103
|
-
}
|
|
103
|
+
}>;
|
|
104
104
|
/** The immutable action document belonging to one external-action obligation. */
|
|
105
|
-
export declare function messageBodyForDelivery(deliveryId: string): unknown | null
|
|
106
|
-
export declare function duePushDeliveries(now: number): DeliveryRecord[]
|
|
107
|
-
export declare function claimPushDelivery(deliveryId: string, now: number, claimOwner: string): DeliveryRecord | null
|
|
108
|
-
export declare function resetHandedOffDeliveries(now: number): number
|
|
105
|
+
export declare function messageBodyForDelivery(deliveryId: string): Promise<unknown | null>;
|
|
106
|
+
export declare function duePushDeliveries(now: number): Promise<DeliveryRecord[]>;
|
|
107
|
+
export declare function claimPushDelivery(deliveryId: string, now: number, claimOwner: string): Promise<DeliveryRecord | null>;
|
|
108
|
+
export declare function resetHandedOffDeliveries(now: number): Promise<number>;
|
|
109
109
|
/** The lane checks the claim immediately before launching the action. An action
|
|
110
110
|
* superseded after claim but before dispatch must not start with stale input. */
|
|
111
|
-
export declare function pushDeliveryClaimIsCurrent(delivery: DeliveryRecord, owner: string): boolean
|
|
111
|
+
export declare function pushDeliveryClaimIsCurrent(delivery: DeliveryRecord, owner: string): Promise<boolean>;
|
|
112
112
|
/** Reset mail held by an execution that is no longer this node's one live execution.
|
|
113
113
|
* Push receiver deliveries have a due timestamp and are claimed by the daemon lane. */
|
|
114
|
-
export declare function resetStaleExecutionMail(now: number): number
|
|
115
|
-
export declare function hasUnseenWakeMail(nodeId: string): boolean
|
|
116
|
-
export declare function hasWakeMailSince(nodeId: string, since: number): boolean
|
|
117
|
-
export declare function acknowledgedNodeMailCount(nodeId: string): number
|
|
114
|
+
export declare function resetStaleExecutionMail(now: number): Promise<number>;
|
|
115
|
+
export declare function hasUnseenWakeMail(nodeId: string): Promise<boolean>;
|
|
116
|
+
export declare function hasWakeMailSince(nodeId: string, since: number): Promise<boolean>;
|
|
117
|
+
export declare function acknowledgedNodeMailCount(nodeId: string): Promise<number>;
|
|
118
118
|
/** Create the messaging schema and import every legacy mailbox/action/wait row. The caller owns the encompassing migration transaction. */
|
|
119
119
|
export declare function migrateMessagingState(db: DatabaseSync): void;
|
|
120
120
|
export {};
|
|
@@ -1,51 +1,51 @@
|
|
|
1
|
-
var
|
|
2
|
-
WHERE n.node_id = ? AND e.execution_id = ? AND e.state != 'exited'${d?" AND n.intent IS NOT 'refresh'":""}`).get(a,
|
|
1
|
+
var x=Object.defineProperty;var _=(e,a)=>x(e,"name",{value:a,configurable:!0});import{prepared as m}from"../sqlite-statements.js";import{existsSync as O,readFileSync as D}from"node:fs";import{randomBytes as C}from"node:crypto";import{withCanvasWrite as T,openDb as N}from"./db.js";import{inboxPath as A,passivePath as v}from"./paths.js";import{withRetryBudget as H}from"./delivery-contract.js";import{emitEvent as X}from"../events/emit.js";import{mapAsync as F}from"../async-array.js";function I(e){return{deliveryId:e.delivery_id,messageId:e.message_id,destinationId:e.destination_id,urgency:e.urgency,wake:e.wake===1?1:0,state:e.state,attempts:e.attempts,nextAttemptAt:e.next_attempt_at,claimedAt:e.claimed_at,claimOwner:e.claim_owner,acknowledgedAt:e.acknowledged_at,failedAt:e.failed_at,lastFailure:e.last_failure_json===null?null:JSON.parse(e.last_failure_json),idempotencyKey:e.idempotency_key,canceledAt:e.canceled_at,createdAt:e.created_at,updatedAt:e.updated_at}}_(I,"deliveryFrom");async function L(e,a,r,d){return await e.prepare(`SELECT 1 FROM nodes n JOIN executions e ON e.node_id = n.node_id
|
|
2
|
+
WHERE n.node_id = ? AND e.execution_id = ? AND e.state != 'exited'${d?" AND n.intent IS NOT 'refresh'":""}`).get(a,r)!==void 0}_(L,"executionIsLive");async function w(e,a,r,d,s,E=!1){return(await e.prepare(`SELECT d.*, m.message_id AS m_message_id, m.seq, m.operation_id, m.created_at AS message_created_at,
|
|
3
3
|
m.sender_node_id, m.sender_name, m.kind, m.label, m.body_ref, m.body_json, m.disposition,
|
|
4
4
|
CASE WHEN d.state = 'handed_off' THEN 'inherited' ELSE 'fresh' END AS handoff
|
|
5
5
|
FROM deliveries d JOIN messages m ON m.message_id = d.message_id
|
|
6
6
|
WHERE d.destination_id = ? AND d.wake = ?
|
|
7
|
-
${
|
|
7
|
+
${E?"AND m.kind = 'message' AND json_extract(m.body_json, '$.start_turn') = 0":d===0?"AND NOT (m.kind = 'message' AND coalesce(json_extract(m.body_json, '$.start_turn'), 1) = 0)":""}
|
|
8
8
|
AND d.canceled_at IS NULL
|
|
9
9
|
AND (d.state = 'pending' OR (d.state = 'handed_off' AND d.claim_owner = ?))
|
|
10
|
-
ORDER BY m.seq`).all(a,d,
|
|
10
|
+
ORDER BY m.seq`).all(a,d,r)).map(i=>({...I(i),message:{messageId:i.m_message_id,seq:Number(i.seq),operationId:i.operation_id,createdAt:i.message_created_at,senderNodeId:i.sender_node_id,senderName:i.sender_name,kind:i.kind,label:i.label,bodyRef:i.body_ref,bodyJson:i.body_json===null?null:JSON.parse(i.body_json),disposition:i.disposition},handoff:s?.has(i.delivery_id)===!0?"fresh":i.handoff}))}_(w,"nodeMailRows");const R=`SELECT d.delivery_id FROM deliveries d JOIN messages m ON m.message_id = d.message_id
|
|
11
11
|
WHERE d.destination_id = ? AND d.wake = ? AND d.state = 'pending' AND d.canceled_at IS NULL
|
|
12
12
|
AND NOT (d.wake = 0 AND m.kind = 'message' AND coalesce(json_extract(m.body_json, '$.start_turn'), 1) = 0)`,j=`UPDATE deliveries SET state = 'handed_off', attempts = attempts + 1, claim_owner = ?, claimed_at = ?, updated_at = ?
|
|
13
|
-
WHERE delivery_id IN (${
|
|
13
|
+
WHERE delivery_id IN (${R})`;async function V(e,a,r,d=Date.now()){const s=r==="wake"?1:0;if(r==="deferred_run")return await T(async c=>{if(!await L(c,e,a,!0))return{action:"hold",deliveries:[]};const i=await c.prepare(`SELECT d.delivery_id FROM deliveries d JOIN messages m ON m.message_id = d.message_id
|
|
14
14
|
WHERE d.destination_id = ? AND d.wake = 0 AND d.canceled_at IS NULL
|
|
15
15
|
AND m.kind = 'message' AND json_extract(m.body_json, '$.start_turn') = 0
|
|
16
|
-
AND (d.state = 'pending' OR (d.state = 'handed_off' AND d.claim_owner = ?))`).all(e,a),t=new Set(
|
|
16
|
+
AND (d.state = 'pending' OR (d.state = 'handed_off' AND d.claim_owner = ?))`).all(e,a),t=new Set((await c.prepare(`SELECT d.delivery_id FROM deliveries d JOIN messages m ON m.message_id = d.message_id
|
|
17
17
|
WHERE d.destination_id = ? AND d.wake = 0 AND d.state = 'pending' AND d.canceled_at IS NULL
|
|
18
|
-
AND m.kind = 'message' AND json_extract(m.body_json, '$.start_turn') = 0`).all(e).map(n=>n.delivery_id));return i.length&&
|
|
19
|
-
WHERE delivery_id IN (${i.map(()=>"?").join(",")}) AND state = 'pending'`).run(a,d,d,...i.map(n=>n.delivery_id)),{action:"claimed",deliveries:
|
|
20
|
-
WHERE destination_id = ? AND wake = 1 AND state = 'pending' AND canceled_at IS NULL`).all(e).map(
|
|
21
|
-
WHERE destination_id = ? AND wake = 1 AND state = 'pending' AND canceled_at IS NULL`).run(a,
|
|
18
|
+
AND m.kind = 'message' AND json_extract(m.body_json, '$.start_turn') = 0`).all(e)).map(n=>n.delivery_id));return i.length&&await c.prepare(`UPDATE deliveries SET state = 'handed_off', attempts = attempts + 1, claim_owner = ?, claimed_at = ?, updated_at = ?
|
|
19
|
+
WHERE delivery_id IN (${i.map(()=>"?").join(",")}) AND state = 'pending'`).run(a,d,d,...i.map(n=>n.delivery_id)),{action:"claimed",deliveries:await w(c,e,a,0,t,!0)}});const E=await N();return!E.inTransaction&&await E.prepare(R).get(e,s)===void 0?await L(E,e,a,!0)?{action:"claimed",deliveries:await w(E,e,a,s)}:{action:"hold",deliveries:[]}:await T(async c=>{if(!await L(c,e,a,!0))return{action:"hold",deliveries:[]};const i=new Set((await c.prepare(R).all(e,s)).map(t=>t.delivery_id));return await c.prepare(j).run(a,d,d,e,s),{action:"claimed",deliveries:await w(c,e,a,s,i)}})}_(V,"claimNodeMail");async function z(e,a,r=Date.now()){return await T(async d=>{if(!await L(d,e,a,!1))throw new Error(`execution ${a} is not live for node ${e}`);const s=new Set((await d.prepare(`SELECT delivery_id FROM deliveries
|
|
20
|
+
WHERE destination_id = ? AND wake = 1 AND state = 'pending' AND canceled_at IS NULL`).all(e)).map(E=>E.delivery_id));return await d.prepare(`UPDATE deliveries SET state = 'handed_off', attempts = attempts + 1, claim_owner = ?, claimed_at = ?, updated_at = ?
|
|
21
|
+
WHERE destination_id = ? AND wake = 1 AND state = 'pending' AND canceled_at IS NULL`).run(a,r,r,e),await w(d,e,a,1,s)})}_(z,"claimKickoffMail");function M(e){return e.state==="accepted"?{state:"acknowledged"}:e}_(M,"normalizedSettlement");async function W(e,a,r,d,s=Date.now()){const E=[],c=await T(async i=>{const n=(await i.prepare("SELECT canceled_at FROM deliveries WHERE delivery_id = ? AND next_attempt_at IS NOT NULL").get(e))?.canceled_at!=null?{state:"acknowledged"}:M(d),o=H(n,a),l=o.settlement,S=l.state==="pending"||l.state==="permanent_failed"?JSON.stringify(l.failure):null,g=l.state==="released"?"pending":l.state,p=l.state==="pending"?l.nextAttemptAt:g==="pending"?s:null,f=Number((await i.prepare(`UPDATE deliveries
|
|
22
22
|
SET state = ?, next_attempt_at = ?, claimed_at = NULL, claim_owner = NULL,
|
|
23
23
|
acknowledged_at = ?, failed_at = ?, last_failure_json = ?, updated_at = ?
|
|
24
|
-
WHERE delivery_id = ? AND state = 'handed_off' AND attempts = ? AND claim_owner = ?`).run(g,
|
|
24
|
+
WHERE delivery_id = ? AND state = 'handed_off' AND attempts = ? AND claim_owner = ?`).run(g,p,g==="acknowledged"?s:null,g==="permanent_failed"?s:null,S,s,e,a,r)).changes)===1;if(f&&o.exhausted&&l.state==="permanent_failed"){const y=await i.prepare("SELECT destination_id, message_id FROM deliveries WHERE delivery_id = ?").get(e);E.push({failure:l.failure,destinationId:y.destination_id,messageId:y.message_id})}return f});for(const i of E)X({level:"error",event:"delivery.exhausted",outcome:"failed",attempt:a,fields:{delivery_id:e,destination_id:i.destinationId,message_id:i.messageId,failure:i.failure,retry:`crtr sys retry-delivery ${e}`}});return c}_(W,"settleDelivery");async function Z(e,a=Date.now()){return Number((await(await N()).prepare(`UPDATE deliveries
|
|
25
25
|
SET state = 'pending', attempts = 0, next_attempt_at = ?, failed_at = NULL, updated_at = ?
|
|
26
|
-
WHERE delivery_id = ? AND state = 'permanent_failed' AND canceled_at IS NULL AND last_failure_json IS NOT NULL`).run(a,a,e).changes)===1
|
|
27
|
-
WHERE d.delivery_id = ?`).get(e);return a===void 0||a.body_json===null?null:JSON.parse(a.body_json)}
|
|
26
|
+
WHERE delivery_id = ? AND state = 'permanent_failed' AND canceled_at IS NULL AND last_failure_json IS NOT NULL`).run(a,a,e)).changes)===1}_(Z,"retryFailedDelivery");async function ee(e,a,r,d=Date.now()){return await T(async s=>await L(s,e,a,!1)?{action:"acknowledged",results:await F(r,async c=>{const i=await s.prepare("SELECT 1 FROM deliveries WHERE delivery_id = ? AND destination_id = ?").get(c.deliveryId,e)!==void 0;return{deliveryId:c.deliveryId,outcome:i&&await W(c.deliveryId,c.attempts,a,{state:c.disposition},d)?c.disposition:"stale"}})}:{action:"hold",results:[]})}_(ee,"acknowledgeNodeMail");async function te(e){const a=await(await N()).prepare(`SELECT m.body_json FROM deliveries d JOIN messages m ON m.message_id = d.message_id
|
|
27
|
+
WHERE d.delivery_id = ?`).get(e);return a===void 0||a.body_json===null?null:JSON.parse(a.body_json)}_(te,"messageBodyForDelivery");async function ae(e){return(await(await N()).prepare(`SELECT * FROM deliveries
|
|
28
28
|
WHERE state = 'pending' AND canceled_at IS NULL AND next_attempt_at <= ?
|
|
29
|
-
ORDER BY next_attempt_at, created_at, delivery_id`).all(e).map(
|
|
29
|
+
ORDER BY next_attempt_at, created_at, delivery_id`).all(e)).map(I)}_(ae,"duePushDeliveries");async function ne(e,a,r){return await T(async d=>{const s=await d.prepare(`UPDATE deliveries AS d SET state = 'handed_off', attempts = attempts + 1, claimed_at = ?, claim_owner = ?, updated_at = ?
|
|
30
30
|
WHERE d.delivery_id = ? AND d.state = 'pending' AND d.canceled_at IS NULL AND d.next_attempt_at <= ?
|
|
31
31
|
AND NOT EXISTS (SELECT 1 FROM deliveries old JOIN messages prior ON prior.message_id = old.message_id
|
|
32
32
|
JOIN messages next ON next.message_id = d.message_id
|
|
33
33
|
WHERE old.destination_id = d.destination_id AND old.delivery_id != d.delivery_id
|
|
34
34
|
AND old.state = 'handed_off' AND old.canceled_at IS NOT NULL
|
|
35
|
-
AND prior.event = 'outcome' AND next.event = 'outcome' AND prior.object_id = next.object_id)`).run(a,
|
|
35
|
+
AND prior.event = 'outcome' AND next.event = 'outcome' AND prior.object_id = next.object_id)`).run(a,r,a,e,a);return Number(s.changes)===0?null:I(await d.prepare("SELECT * FROM deliveries WHERE delivery_id = ?").get(e))})}_(ne,"claimPushDelivery");async function ie(e){return await T(async a=>{const r=await a.prepare(`UPDATE deliveries SET state = 'permanent_failed', next_attempt_at = NULL,
|
|
36
36
|
claimed_at = NULL, claim_owner = NULL, failed_at = ?, updated_at = ?
|
|
37
|
-
WHERE state = 'handed_off' AND canceled_at IS NOT NULL AND next_attempt_at IS NOT NULL`).run(e,e),d=
|
|
37
|
+
WHERE state = 'handed_off' AND canceled_at IS NOT NULL AND next_attempt_at IS NOT NULL`).run(e,e),d=await a.prepare(`UPDATE deliveries SET state = 'pending', next_attempt_at = CASE WHEN next_attempt_at IS NOT NULL THEN ? ELSE NULL END,
|
|
38
38
|
claimed_at = NULL, claim_owner = NULL, updated_at = ?
|
|
39
|
-
WHERE state = 'handed_off' AND (canceled_at IS NULL OR next_attempt_at IS NULL)`).run(e,e);return Number(
|
|
40
|
-
AND attempts = ? AND claim_owner = ? AND canceled_at IS NULL`).get(e.deliveryId,e.attempts,a)!==void 0}
|
|
39
|
+
WHERE state = 'handed_off' AND (canceled_at IS NULL OR next_attempt_at IS NULL)`).run(e,e);return Number(r.changes)+Number(d.changes)})}_(ie,"resetHandedOffDeliveries");async function de(e,a){return await(await N()).prepare(`SELECT 1 FROM deliveries WHERE delivery_id = ? AND state = 'handed_off'
|
|
40
|
+
AND attempts = ? AND claim_owner = ? AND canceled_at IS NULL`).get(e.deliveryId,e.attempts,a)!==void 0}_(de,"pushDeliveryClaimIsCurrent");async function se(e){return Number((await(await N()).prepare(`UPDATE deliveries AS d SET state = 'pending', claimed_at = NULL, claim_owner = NULL, updated_at = ?
|
|
41
41
|
WHERE d.state = 'handed_off' AND d.next_attempt_at IS NULL
|
|
42
42
|
AND NOT EXISTS (
|
|
43
43
|
SELECT 1 FROM executions e WHERE e.node_id = d.destination_id AND e.execution_id = d.claim_owner AND e.state != 'exited'
|
|
44
|
-
)`).run(e).changes)
|
|
45
|
-
AND canceled_at IS NULL AND urgency != 'deferred' AND state IN ('pending', 'handed_off') LIMIT 1`).get(e)!==void 0}
|
|
46
|
-
AND urgency != 'deferred' AND created_at >= ? LIMIT 1`).get(e,a)!==void 0}
|
|
47
|
-
`).filter(
|
|
48
|
-
`).map(a=>a.trim()).filter(Boolean)):new Set}
|
|
44
|
+
)`).run(e)).changes)}_(se,"resetStaleExecutionMail");async function re(e){return await(await N()).prepare(`SELECT 1 FROM deliveries WHERE destination_id = ? AND wake = 1
|
|
45
|
+
AND canceled_at IS NULL AND urgency != 'deferred' AND state IN ('pending', 'handed_off') LIMIT 1`).get(e)!==void 0}_(re,"hasUnseenWakeMail");async function oe(e,a){return await(await N()).prepare(`SELECT 1 FROM deliveries WHERE destination_id = ? AND wake = 1
|
|
46
|
+
AND urgency != 'deferred' AND created_at >= ? LIMIT 1`).get(e,a)!==void 0}_(oe,"hasWakeMailSince");async function _e(e){return Number((await(await N()).prepare("SELECT COUNT(*) AS count FROM deliveries WHERE destination_id = ? AND acknowledged_at IS NOT NULL").get(e)).count)}_(_e,"acknowledgedNodeMailCount");function u(){let e;do e=C(16).toString("hex");while(e==="00000000000000000000000000000000");return e}_(u,"newId");function k(e){if(!O(e))return[];const a=D(e,"utf8");return a.trim()===""?[]:a.split(`
|
|
47
|
+
`).filter(r=>r.trim()!=="").map((r,d)=>{let s;try{s=JSON.parse(r)}catch(E){throw new Error(`invalid mailbox JSON at ${e}:${d+1}: ${E.message}`)}if(!/^(?!0{32}$)[0-9a-f]{32}$/.test(s.entry_id)||!/^(?!0{32}$)[0-9a-f]{32}$/.test(s.operation_id))throw new Error(`invalid mailbox identity at ${e}:${d+1}`);if(typeof s.ts!="string"||typeof s.label!="string")throw new Error(`incomplete mailbox entry at ${e}:${d+1}`);return s})}_(k,"readJsonLines");function $(e){return O(e)?new Set(D(e,"utf8").split(`
|
|
48
|
+
`).map(a=>a.trim()).filter(Boolean)):new Set}_($,"readCanceled");function le(e){e.exec(`
|
|
49
49
|
CREATE TABLE IF NOT EXISTS messages (
|
|
50
50
|
message_id TEXT PRIMARY KEY,
|
|
51
51
|
seq INTEGER NOT NULL UNIQUE,
|
|
@@ -99,4 +99,4 @@ CREATE TABLE IF NOT EXISTS waits (
|
|
|
99
99
|
);
|
|
100
100
|
CREATE UNIQUE INDEX IF NOT EXISTS waits_live ON waits(node_id) WHERE satisfied_at IS NULL;
|
|
101
101
|
CREATE INDEX IF NOT EXISTS waits_node ON waits(node_id);
|
|
102
|
-
`);const a=[];for(const t of
|
|
102
|
+
`);const a=[];for(const t of m(e,"SELECT node_id FROM nodes").all()){const n=t.node_id,o=k(A(n)),l=O(`${A(n)}.cursor`)?D(`${A(n)}.cursor`,"utf8").trim():"",S=o.findIndex(p=>p.entry_id===l),g=$(`${A(n)}.canceled`);o.forEach((p,f)=>a.push({nodeId:n,wake:1,source:"inbox",fileRank:0,physicalIndex:f,entry:p,acknowledged:S>=0&&f<=S,canceled:g.has(p.entry_id),seq:0}));for(const[p,f]of[[0,`${v(n)}.draining`],[1,v(n)]])k(f).forEach((y,h)=>a.push({nodeId:n,wake:0,source:"passive",fileRank:p,physicalIndex:h,entry:y,acknowledged:!1,canceled:!1,seq:0}))}a.sort((t,n)=>t.entry.ts.localeCompare(n.entry.ts)||t.nodeId.localeCompare(n.nodeId)||t.fileRank-n.fileRank||t.physicalIndex-n.physicalIndex),a.forEach((t,n)=>{t.seq=n+1});const r=new Map;for(const t of a){const n=`${t.nodeId}\0${t.source}`,o=r.get(n)??[];o.push(t),r.set(n,o)}for(const t of r.values()){const n=t.map(o=>o.seq).sort((o,l)=>o-l);t.sort((o,l)=>o.fileRank-l.fileRank||o.physicalIndex-l.physicalIndex).forEach((o,l)=>{o.seq=n[l]})}const d=m(e,"INSERT INTO messages (message_id, seq, operation_id, created_at, sender_node_id, sender_name, kind, label, body_ref, body_json, disposition) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"),s=m(e,"INSERT INTO deliveries (delivery_id, message_id, destination_kind, destination_id, urgency, wake, state, attempts, acknowledged_at, canceled_at, created_at, updated_at) VALUES (?, ?, 'node_inbox', ?, ?, ?, ?, 0, ?, ?, ?, ?)");for(const t of a){const n=t.entry;d.run(n.entry_id,t.seq,n.operation_id,n.ts,n.from,n.from_name??null,n.kind,n.label,n.ref??null,n.data===void 0?null:JSON.stringify(n.data),n.disposition??null);const o=Date.parse(n.ts),l=Number.isFinite(o)?o:0;s.run(u(),n.entry_id,t.nodeId,n.tier,t.wake,t.acknowledged?"acknowledged":"pending",t.acknowledged?l:null,t.canceled?l:null,l,l)}const E=m(e,"SELECT * FROM human_action_deliveries").all();for(const t of E){const n=u();d.run(n,U(e),u(),new Date(t.created_at).toISOString(),null,null,"completed",t.request_id,null,t.completion_json,null);const o=t.state==="running"?"handed_off":t.state==="accepted"?"acknowledged":t.state;m(e,"INSERT INTO deliveries (delivery_id, message_id, destination_kind, destination_id, urgency, wake, state, attempts, next_attempt_at, claimed_at, claim_owner, acknowledged_at, failed_at, last_failure_json, adapter_json, idempotency_key, created_at, updated_at) VALUES (?, ?, 'external_action', 'human_action', 'normal', 0, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)").run(u(),n,o,t.attempt,t.next_attempt_at,t.claimed_at,t.claim_owner,t.accepted_at,t.permanent_failed_at,t.last_failure_json,JSON.stringify({adapter:"subprocess",argv:JSON.parse(t.argv_json),cwd:t.cwd}),`human-action:${t.request_id}`,t.created_at,t.updated_at)}const c=m(e,"SELECT * FROM node_outcome_deliveries").all();for(const t of c){const n=t.document_json===null?null:u();n!==null&&d.run(n,U(e),u(),new Date(t.created_at).toISOString(),null,null,"completed",t.node_id,null,t.document_json,null);const o=t.document_json===null?"armed":t.state==="running"?"handed_off":t.state==="accepted"?"acknowledged":t.state;m(e,"INSERT INTO deliveries (delivery_id, message_id, destination_kind, destination_id, urgency, wake, state, attempts, next_attempt_at, claimed_at, claim_owner, acknowledged_at, failed_at, last_failure_json, adapter_json, idempotency_key, created_at, updated_at) VALUES (?, ?, 'external_action', ?, 'normal', 0, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)").run(u(),n,t.action_name,o,t.attempt,t.next_attempt_at,t.claimed_at,t.claim_owner,t.accepted_at,t.permanent_failed_at,t.last_failure_json,JSON.stringify({adapter:"subprocess",argv:JSON.parse(t.argv_json),cwd:t.cwd,config_origin:t.config_origin,payload:t.payload_json===null?null:JSON.parse(t.payload_json)}),`node-outcome:${t.node_id}`,t.created_at,t.updated_at)}const i=m(e,"SELECT node_id, waiting_for, waiting_for_generation FROM nodes WHERE waiting_for IS NOT NULL").all();for(const t of i)m(e,"INSERT INTO waits (wait_id, node_id, kind, target_id, generation, created_at, satisfied_at) VALUES (?, ?, 'controller', ?, ?, ?, NULL)").run(u(),t.node_id,t.waiting_for,t.waiting_for_generation,Date.now())}_(le,"migrateMessagingState");function U(e){return Number(m(e,"SELECT COALESCE(MAX(seq), 0) AS seq FROM messages").get().seq)+1}_(U,"nextSeq");export{ee as acknowledgeNodeMail,_e as acknowledgedNodeMailCount,z as claimKickoffMail,V as claimNodeMail,ne as claimPushDelivery,I as deliveryFrom,ae as duePushDeliveries,re as hasUnseenWakeMail,oe as hasWakeMailSince,te as messageBodyForDelivery,le as migrateMessagingState,M as normalizedSettlement,de as pushDeliveryClaimIsCurrent,ie as resetHandedOffDeliveries,se as resetStaleExecutionMail,Z as retryFailedDelivery,W as settleDelivery};
|
|
@@ -9,21 +9,21 @@ export interface Execution {
|
|
|
9
9
|
endedAt: string | null;
|
|
10
10
|
exitReason: string | null;
|
|
11
11
|
}
|
|
12
|
-
export declare function liveExecutionForNode(nodeId: string): Execution | null
|
|
12
|
+
export declare function liveExecutionForNode(nodeId: string): Promise<Execution | null>;
|
|
13
13
|
export declare function beginExecution(nodeId: string, input: {
|
|
14
14
|
daemonEpoch: string | null;
|
|
15
|
-
}): string
|
|
15
|
+
}): Promise<string>;
|
|
16
16
|
/** Returns shutdown when a late broker references an execution no longer live. */
|
|
17
|
-
export declare function recordExecutionPid(executionId: string, nodeId: string, pid: number): 'recorded' | 'shutdown'
|
|
17
|
+
export declare function recordExecutionPid(executionId: string, nodeId: string, pid: number): Promise<'recorded' | 'shutdown'>;
|
|
18
18
|
export declare function endExecution(executionId: string, input: {
|
|
19
19
|
reason: string;
|
|
20
|
-
}): boolean
|
|
20
|
+
}): Promise<boolean>;
|
|
21
21
|
export declare function abortExecution(executionId: string, input: {
|
|
22
22
|
reason: string;
|
|
23
|
-
}): boolean
|
|
23
|
+
}): Promise<boolean>;
|
|
24
24
|
export declare function endLiveExecution(nodeId: string, input: {
|
|
25
25
|
reason: string;
|
|
26
|
-
}): boolean
|
|
27
|
-
export declare function migrateLegacyExecutionIdentities(captureIdentity?: (pid: number) => string | undefined): {
|
|
26
|
+
}): Promise<boolean>;
|
|
27
|
+
export declare function migrateLegacyExecutionIdentities(captureIdentity?: (pid: number) => string | undefined): Promise<{
|
|
28
28
|
migrated: string[];
|
|
29
|
-
}
|
|
29
|
+
}>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var
|
|
1
|
+
var y=Object.defineProperty;var o=(e,t)=>y(e,"name",{value:t,configurable:!0});import{randomUUID as m}from"node:crypto";import{openDb as _,withCanvasWrite as u}from"./db.js";import{capturePidIdentities as f,captureLivenessSnapshot as g,identitiesMatch as h,isBootScopedIdentity as A,isLegacyTicksIdentity as T}from"./pid.js";import{existsSync as D,readFileSync as L}from"node:fs";import{LAUNCHER_SOCKET as S}from"../../launcher/spec.js";import{forgetNodeToken as w,mintNodeToken as U,revokeNodeTokens as p}from"./node-tokens.js";function x(){return new Date().toISOString()}o(x,"now");function R(e){return{executionId:e.execution_id,nodeId:e.node_id,daemonEpoch:e.daemon_epoch??null,pid:e.pid??null,processIdentity:e.process_identity??null,state:e.state,startedAt:e.started_at,endedAt:e.ended_at??null,exitReason:e.exit_reason??null}}o(R,"hydrate");async function F(e){const t=await(await _()).prepare("SELECT * FROM executions WHERE node_id = ? AND state != 'exited'").get(e);return t===void 0?null:R(t)}o(F,"liveExecutionForNode");async function M(e,t){return await u(async n=>{const i=x();await n.prepare("UPDATE executions SET state = 'exited', ended_at = ?, exit_reason = 'superseded' WHERE node_id = ? AND state != 'exited'").run(i,e),await p(n,"node_id",e,i);const r=m();return await n.prepare("INSERT INTO executions (execution_id, node_id, daemon_epoch, pid, process_identity, state, started_at, ended_at, exit_reason) VALUES (?, ?, ?, NULL, NULL, 'launching', ?, NULL, NULL)").run(r,e,t.daemonEpoch,i),await U(n,r,e,i),r})}o(M,"beginExecution");async function b(e,t,n){const i=f([n])?.get(n)??null;return await u(async r=>{if((await r.prepare("UPDATE executions SET pid = ?, process_identity = ?, state = 'running' WHERE execution_id = ? AND node_id = ? AND state = 'launching'").run(n,i,e,t)).changes>0)return"recorded";const s=await r.prepare("SELECT pid FROM executions WHERE execution_id = ? AND node_id = ? AND state = 'running'").get(e,t);if(s?.pid===n)return"recorded";if(process.platform==="linux"&&D(S)&&s?.pid!=null){const l=g(),c=[s.pid];for(let d=0;d<c.length;d++)c.push(...l?.childrenOf.get(c[d])??[]);if(c.includes(n))return"recorded";for(const d of c)try{const N=L(`/proc/${d}/status`,"utf8"),E=/^NSpid:\s*(.+)$/m.exec(N)?.[1]?.trim().split(/\s+/).map(Number)??[];if(E.length>1&&E.at(-1)===n)return"recorded"}catch{}}return"shutdown"})}o(b,"recordExecutionPid");async function H(e,t){return w(e),await u(async n=>{const i=x(),r=await n.prepare("UPDATE executions SET state = 'exited', ended_at = ?, exit_reason = ? WHERE execution_id = ? AND state != 'exited'").run(i,t.reason,e);return await p(n,"broker_process_id",e,i),Number(r.changes)===1})}o(H,"endExecution");async function $(e,t){return await H(e,t)}o($,"abortExecution");async function B(e,t){return await u(async n=>{const i=x(),r=await n.prepare("UPDATE executions SET state = 'exited', ended_at = ?, exit_reason = ? WHERE node_id = ? AND state != 'exited'").run(i,t.reason,e);return await p(n,"node_id",e,i),Number(r.changes)===1})}o(B,"endLiveExecution");async function K(e=t=>f([t])?.get(t)){const t=await _(),n=await t.prepare("SELECT execution_id, pid, process_identity FROM executions WHERE state = 'running' AND pid IS NOT NULL AND process_identity IS NOT NULL").all(),i=t.prepare("UPDATE executions SET process_identity = ? WHERE execution_id = ? AND pid = ? AND process_identity = ? AND state = 'running'"),r=[];for(const a of n){if(!T(a.process_identity))continue;const s=e(a.pid);s===void 0||!A(s)||!h(s,a.process_identity)||(await i.run(s,a.execution_id,a.pid,a.process_identity)).changes>0&&r.push(a.execution_id)}return{migrated:r}}o(K,"migrateLegacyExecutionIdentities");export{$ as abortExecution,M as beginExecution,H as endExecution,B as endLiveExecution,F as liveExecutionForNode,K as migrateLegacyExecutionIdentities,b as recordExecutionPid};
|
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
import type { FocusRow } from './types.js';
|
|
2
2
|
/** INSERT a viewport. Throws on UNIQUE(node_id) if `node_id` already occupies
|
|
3
3
|
* another focus (or on PK conflict if `focus_id` exists) — by design. */
|
|
4
|
-
export declare function openFocusRow(focus_id: string, pane: string | null, session: string | null, node_id: string): void
|
|
4
|
+
export declare function openFocusRow(focus_id: string, pane: string | null, session: string | null, node_id: string): Promise<void>;
|
|
5
5
|
/** Hot-swap a focus's occupant — single-statement UPDATE. Respects
|
|
6
6
|
* UNIQUE(node_id): if `node_id` already occupies ANOTHER focus this throws
|
|
7
7
|
* (correct — vacate-first is placement.focus()'s job, not this setter's). */
|
|
8
|
-
export declare function setFocusOccupant(focus_id: string, node_id: string): void
|
|
8
|
+
export declare function setFocusOccupant(focus_id: string, node_id: string): Promise<void>;
|
|
9
9
|
/** Re-point a viewer row's durable pane + its derived session cache after the
|
|
10
10
|
* pane moves. Single-statement UPDATE. */
|
|
11
|
-
export declare function setFocusPane(focus_id: string, pane: string | null, session: string | null): void
|
|
11
|
+
export declare function setFocusPane(focus_id: string, pane: string | null, session: string | null): Promise<void>;
|
|
12
12
|
/** DELETE a viewport. */
|
|
13
|
-
export declare function closeFocusRow(focus_id: string): void
|
|
13
|
+
export declare function closeFocusRow(focus_id: string): Promise<void>;
|
|
14
14
|
/** The focus a node occupies (≤1, UNIQUE node_id), or null. */
|
|
15
|
-
export declare function getFocusByNode(node_id: string): FocusRow | null
|
|
15
|
+
export declare function getFocusByNode(node_id: string): Promise<FocusRow | null>;
|
|
16
16
|
/** The focus realized by a given pane (`%id`), or null. */
|
|
17
|
-
export declare function getFocusByPane(pane: string): FocusRow | null
|
|
17
|
+
export declare function getFocusByPane(pane: string): Promise<FocusRow | null>;
|
|
18
18
|
/** A focus by its stable id, or null. Used by placement to read a row back by id
|
|
19
19
|
* after openFocusRow registers a viewer. */
|
|
20
|
-
export declare function getFocusById(focus_id: string): FocusRow | null
|
|
20
|
+
export declare function getFocusById(focus_id: string): Promise<FocusRow | null>;
|
|
21
21
|
/** Every focus row, ordered by id. */
|
|
22
|
-
export declare function listFocuses(): FocusRow[]
|
|
22
|
+
export declare function listFocuses(): Promise<FocusRow[]>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var
|
|
1
|
+
var c=Object.defineProperty;var n=(e,o)=>c(e,"name",{value:o,configurable:!0});import{openDb as s}from"./db.js";function a(e){return{focus_id:e.focus_id,pane:e.pane??null,session:e.session??null,node_id:e.node_id}}n(a,"focusFrom");async function p(e,o,t,u){await(await s()).prepare("INSERT INTO focuses (focus_id, pane, session, node_id) VALUES (?, ?, ?, ?)").run(e,o,t,u)}n(p,"openFocusRow");async function E(e,o){await(await s()).prepare("UPDATE focuses SET node_id = ? WHERE focus_id = ?").run(o,e)}n(E,"setFocusOccupant");async function f(e,o,t){await(await s()).prepare("UPDATE focuses SET pane = ?, session = ? WHERE focus_id = ?").run(o,t,e)}n(f,"setFocusPane");async function d(e){await(await s()).prepare("DELETE FROM focuses WHERE focus_id = ?").run(e)}n(d,"closeFocusRow");async function w(e){const o=await(await s()).prepare("SELECT * FROM focuses WHERE node_id = ?").get(e);return o?a(o):null}n(w,"getFocusByNode");async function R(e){const o=await(await s()).prepare("SELECT * FROM focuses WHERE pane = ?").get(e);return o?a(o):null}n(R,"getFocusByPane");async function l(e){const o=await(await s()).prepare("SELECT * FROM focuses WHERE focus_id = ?").get(e);return o?a(o):null}n(l,"getFocusById");async function F(){return(await(await s()).prepare("SELECT * FROM focuses ORDER BY focus_id").all()).map(a)}n(F,"listFocuses");export{d as closeFocusRow,l as getFocusById,w as getFocusByNode,R as getFocusByPane,F as listFocuses,p as openFocusRow,E as setFocusOccupant,f as setFocusPane};
|
|
@@ -70,11 +70,11 @@ export interface CorpusFilter {
|
|
|
70
70
|
/** The cwd the caller means by default: the calling node's cwd (resolved from
|
|
71
71
|
* CRTR_NODE_ID via the canvas data layer), falling back to the process cwd
|
|
72
72
|
* when not run as a node. */
|
|
73
|
-
export declare function callerCwd(): string
|
|
73
|
+
export declare function callerCwd(): Promise<string>;
|
|
74
74
|
/** Build the searchable artifact set for a scope + corpus filter. Node facets
|
|
75
75
|
* are applied against the db rows first (cheap); only surviving nodes' files
|
|
76
76
|
* are read. */
|
|
77
|
-
export declare function buildCorpus(scope: ScopeFilter, corpus: CorpusFilter): HistoryArtifact[]
|
|
77
|
+
export declare function buildCorpus(scope: ScopeFilter, corpus: CorpusFilter): Promise<HistoryArtifact[]>;
|
|
78
78
|
export type GroupKey = 'origin' | 'node' | 'kind' | 'day' | 'type' | 'role';
|
|
79
79
|
export interface CorpusGroup {
|
|
80
80
|
key: string;
|
|
@@ -101,4 +101,4 @@ export interface ResolvedRef {
|
|
|
101
101
|
/** Resolve a `<node-id>:inbox/<n>`, `<node-id>:session` or
|
|
102
102
|
* `<node-id>:session/<n>` handle to its content. Returns null when the node is
|
|
103
103
|
* unknown, the ref names another corpus, or the entry does not exist. */
|
|
104
|
-
export declare function resolveRef(ref: string): ResolvedRef | null
|
|
104
|
+
export declare function resolveRef(ref: string): Promise<ResolvedRef | null>;
|