@north-light/cli 0.3.529 → 0.3.531
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/dto/lifecycle.d.ts +3 -1
- package/dist/api/dto/messages.d.ts +5 -3
- package/dist/builtin-memory/crouter-plugin/bundles-and-memory.md +1 -1
- package/dist/builtin-memory/crouter-plugin/commands.md +1 -1
- package/dist/clients/attach/session/connection.js +1 -1
- package/dist/clients/attach/session/reconnect.js +1 -1
- package/dist/clients/attach/viewer.js +508 -508
- package/dist/commands/node/message.js +1 -1
- package/dist/commands/sys/join.js +1 -1
- 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/lifecycle-catalog.d.ts +4 -4
- package/dist/core/command-hooks/lifecycle-catalog.js +1 -1
- package/dist/core/command-hooks/transport/exec-lifecycle.js +1 -1
- package/dist/core/command-plugins/bundle.d.ts +1 -1
- package/dist/core/command-plugins/bundle.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/directory/join.d.ts +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 +21 -10
- 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 +3 -3
- 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/launcher/run.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/plugin/bundles-and-memory.md +1 -1
- package/docs/plugin/commands.md +1 -1
- package/docs/public-api.md +11 -0
- package/package.json +4 -3
- package/packages/crouter-identity/package.json +1 -1
- package/runtime.lock.json +12 -12
package/dist/daemon/crtrd.js
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
var Pe=Object.defineProperty;var a=(t,n)=>Pe(t,"name",{value:n,configurable:!0});import{startPeerOutbox as xe}from"./peer/outbox.js";import{reportMachineStatus as Ie}from"../core/peer/directory.js";import{createPeerRelay as De}from"./peer/relay-service.js";import{writeFileSync as Te,readFileSync as Ce,rmSync as $e,mkdirSync as ee,existsSync as E,chmodSync as Le}from"node:fs";import{createServer as re}from"node:http";import{dirname as Ae}from"node:path";import{envCrtrdTcp as Ne,envDocumentPort as Me}from"../shared/env.js";import{serveCanvasConversationStore as Oe}from"../core/canvas/sessions.js";import{pollRunObservers as Fe}from"./runs/observer.js";import{randomBytes as Ge}from"node:crypto";import{apiSocketPath as He,crtrHome as je}from"../core/canvas/paths.js";import{activeAppUsers as Be}from"../core/spaces/users.js";import{ensureAppSpace as qe,ensureUserFiles as ze}from"../core/spaces/space.js";import{LAUNCHER_SOCKET as x}from"../launcher/spec.js";import{launcherRequest as D}from"../launcher/client.js";import{installLauncherEventSink as We}from"./launcher-events.js";import{initializeEmptyLayout as Ue,layoutNeedsMigration as Ke,socketDir as te}from"../core/layout.js";import{migrateLooseKeys as Je}from"../core/layout-migrate/loose-keys.js";import{relocateProfileFolders as Ve}from"../core/profiles/relocate.js";import{getNode as Qe,listNodesForSupervision as ne,setFrozen as oe}from"../core/canvas/index.js";import{createApiServer as Ye}from"./api/server.js";import{createDocumentListener as Xe}from"./api/document-listener.js";import{documentSecret as Ze}from"./api/document-secret.js";import{createAppListener as er}from"./api/app-listener.js";import{installLocalTerminalGrant as rr}from"../core/grants/local.js";import{onRunEventAppended as tr}from"../core/runs/events.js";import{runNotices as nr}from"./run-notices.js";import{createGrantSync as or,GRANT_SYNC_INTERVAL_S as ir}from"../core/grants/sync.js";import{runRemovalCascades as sr}from"../core/grants/remove.js";import{sweepSandboxes as ar}from"../core/grants/on-sync.js";import{rebuildCronExecutions as cr}from"./cron/run-socket.js";import{hasSyncedGrants as dr}from"../core/grants/mirror.js";import{readConfig as ie}from"../core/config.js";import{reconcileUndeliveredTickets as lr}from"./human/sweep.js";import{resetHandedOffDeliveries as pr}from"../core/canvas/deliveries.js";import{resetHandedOffDaemonActions as mr}from"../core/canvas/daemon-actions.js";import{sweepReviews as fr}from"./review/sweep.js";import{pidfilePath as B}from"./pidfile.js";import{rendererWarning as ur}from"../core/runtime/package-health.js";import{DEFAULT_INTERVAL_MS as hr}from"./supervise-cadence.js";import{createResumeDetector as vr}from"./resume-detector.js";import{setFatalFaultAnnouncer as wr}from"../core/canvas/recovery.js";import{BrokerSupervisionReconciler as gr}from"./reconcilers/broker-supervision.js";import{ControllerDeathReconciler as yr}from"./reconcilers/controller-death.js";import{NodeLifecycleReconciler as Sr}from"./reconcilers/node-lifecycle/tick.js";import{NodeDeadlineReconciler as _r}from"./reconcilers/node-deadline.js";import{CronLaneReconciler as br}from"./reconcilers/cron-lane.js";import{DeliveryLaneReconciler as kr}from"./reconcilers/delivery-lane.js";import{ActionLaneReconciler as Er}from"./reconcilers/action-lane.js";import{endLiveExecution as Rr,migrateLegacyExecutionIdentities as Pr}from"../core/canvas/executions.js";import{revokePriorEpochNodeTokens as xr}from"../core/canvas/node-tokens.js";import{PendingReviewSubmitReconciler as Ir}from"./reconcilers/pending-review-submit.js";import{StorageMaintenanceReconciler as Dr}from"./reconcilers/storage-maintenance.js";import{StorageDueWorkReconciler as Tr}from"./reconcilers/storage-due-work.js";import{BashDeadlineReconciler as Cr}from"./reconcilers/bash-deadline.js";import{FaultRetryBackstopReconciler as $r}from"./reconcilers/fault-retry-backstop.js";import{StructuredRequestReconciler as Lr}from"./reconcilers/structured-request-lane.js";import{reconcileStructuredRequestSidecars as Ar}from"./structured-requests/boot.js";import{captureLivenessSnapshot as se,capturePidCommand as Nr,captureTeardownSnapshot as ae,isPidAlive as Mr,isAnyPidAlive as ce,killProcessTreePids as de}from"../core/canvas/pid.js";import{bindFleet as Or,boundFleet as Fr}from"../core/runtime/fleet.js";import{bindDaemonControl as Gr,clearDaemonControl as Hr}from"./control.js";import{execDaemon as jr,spawnDaemon as Br}from"./manage.js";import{reconcileAndMigrateBoot as qr}from"../core/canvas/boot.js";import{resolveInstallId as zr}from"../core/canvas/install-id.js";import{setInstallId as Wr}from"../core/runtime/nodes.js";import{claimDaemonOwnership as Ur,releaseDaemonOwnership as le}from"../core/canvas/daemon-owner.js";import{migrate as Kr,openDb as pe,withCanvasWrite as Jr,bindDaemonCanvasOpenHook as Vr,clearDaemonCanvasOpenHook as me}from"../core/canvas/db.js";import{brokerSignalBus as q}from"./broker-signals/bus.js";import{brokerSignalStreams as Qr}from"./api/handlers/broker-signals.js";import{reconcilePackages as Yr}from"../core/graph/package-reconcile.js";import{startRepoSync as Xr}from"../core/graph/repo-sync/index.js";import{prewarmRecentRecipes as Zr,reapStaleSpares as et}from"../core/runtime/warm-pool.js";import{DaemonFleet as rt}from"./fleet.js";import{BOOT_MIGRATIONS as tt}from"./boot-migrations.js";import{applyJoinedOwner as nt}from"./joined-owner.js";import{emitEvent as f}from"../core/events/emit.js";import{operationIdContext as _}from"../core/events/operation-id.js";import{bindDaemonEventSource as ot}from"../core/events/source.js";import{activateCanvasImport as it,MigrationBlockedError as st,runForcedCanvasImport as at}from"../migrations/activation.js";import{convertLegacyProviderStore as ct,convertLegacyScopedStore as dt}from"../core/scoped-state/migrate.js";import{userScopeRoot as lt}from"../core/scope.js";import{secretsDir as pt}from"../core/layout.js";function z(t,n){return t.includes(` --canvas-home ${n} `)}a(z,"brokerCommandDeclaresCanvasHome");function W(t){return/ --epoch (\S+) /.exec(t)?.[1]??null}a(W,"brokerCommandEpoch");const mt=5e3,fe=150;async function ft(t){const n=se();if(n===null)throw f({level:"error",event:"daemon.census.snapshot_failed",fields:{invariant:"prior-epoch brokers are reaped before readiness"}}),new Error("prior-epoch broker census could not capture the process table");const c=je(),u=[];for(const[s,m]of n.processes){const y=m.command;if(m.zombie||!y.includes("broker-cli.js")||!z(y,c)||W(y)===t)continue;const b=y.trim().split(/\s+/).at(-1)??"";b===""||b.endsWith("broker-cli.js")||u.push({pid:s,nodeId:b})}let h=0;const o=[];for(const s of u){const m=Nr(s.pid);if(m===null||!m.includes("broker-cli.js")||!z(m,c)||W(m)===t||m.trim().split(/\s+/).at(-1)!==s.nodeId)continue;const y=ae(s.pid,null);if(!y.reused){try{process.platform==="linux"&&E(x)?await D({operation:"stop",pid:s.pid}):process.kill(s.pid,"SIGTERM")}catch{continue}h++,o.push({pid:s.pid,snap:y})}}const g=Date.now()+mt;for(;Date.now()<g&&o.some(s=>ce(s.snap.tree.length>0?s.snap.tree:[s.pid]));)await new Promise(s=>setTimeout(s,fe));let w=0;for(const s of o){const m=s.snap.tree.length>0?s.snap.tree:[s.pid];ce(m)&&(process.platform==="linux"&&E(x)?await D({operation:"stop",pid:s.pid}):de(m,"SIGKILL",s.snap.identities),w++)}w>0&&await new Promise(s=>setTimeout(s,fe));const d=se();if(d===null)throw f({level:"error",event:"daemon.census.snapshot_failed",fields:{invariant:"prior-epoch brokers are reaped before readiness",stage:"final"}}),new Error("prior-epoch broker census could not capture the final process table");const p=[];for(const[s,m]of d.processes){const y=m.command;m.zombie||!y.includes("broker-cli.js")||z(y,c)&&W(y)!==t&&p.push(s)}if(p.length>0)throw new Error(`prior-epoch broker census could not prove termination of pid(s): ${p.join(", ")}`);f({level:"info",event:"daemon.census.completed",fields:{prior_epoch_brokers:u.length,sigtermed:h,sigkilled:w}})}a(ft,"reapPriorEpochBrokers");const ut=5e3;async function ht(t){const n=Array.from(t.entries());if(n.length===0)return;for(const[o]of n){const g=Qe(o)?.status;(g==="active"||g==="idle")&&oe(o,new Date().toISOString())}const c=n.map(([,o])=>({pid:o.pid,snap:ae(o.pid,null),exited:o.handle.exited}));for(const o of c)if(!o.snap.reused)try{process.platform==="linux"&&E(x)?await D({operation:"stop",pid:o.pid}):process.kill(o.pid,"SIGTERM")}catch{}const u=new Promise(o=>{setTimeout(o,ut).unref()});await Promise.allSettled(c.map(o=>Promise.race([o.exited.then(()=>{}),u])));const h=[];for(const o of c)Mr(o.pid)&&(process.platform==="linux"&&E(x)?await D({operation:"stop",pid:o.pid}):de(o.snap.tree.length>0?o.snap.tree:[o.pid],"SIGKILL",o.snap.identities),h.push(o));await Promise.all(h.map(o=>o.exited));for(const[o]of n)Rr(o,{reason:"daemon-teardown"});f({level:"info",event:"daemon.fleet_teardown.completed",fields:{brokers:c.length,sigkilled:h.length}})}a(ht,"teardownFleet");function ue(){ee(Ae(B()),{recursive:!0}),Te(B(),String(process.pid),"utf8")}a(ue,"writePidfile");function he(t){return typeof t=="object"&&t!==null&&t.code==="ENOENT"}a(he,"isMissingPathError");function ve(t){const n=B();let c;try{c=Ce(n,"utf8")}catch(u){if(he(u))return;throw u}if(c.trim()!==String(t))throw new Error(`daemon readiness mirror does not name this invocation (expected pid ${t})`);try{$e(n)}catch(u){if(he(u))return;throw u}}a(ve,"removeOwnedPidfileMirror");const vt={acceptsDetachedWork:a(()=>!0,"acceptsDetachedWork"),registerDetached:a(t=>{t.catch(()=>{})},"registerDetached")},O=new gr;wr(t=>O.handleFatalFault(t,!1));const wt=new yr,gt=new Sr,yt=new _r,St=new br,_t=new kr,bt=new Er,kt=new Ir,Et=new Dr,Rt=new Tr,Pt=new Cr,xt=new $r,It=new Lr;async function Dt(t=Date.now(),n=vt){const c=Fr(),u=await O.runFleetPreamble(c);let h,o;try{const w=ne();h=w.filter(d=>d.status==="active"||d.status==="idle"),o=w.filter(d=>d.status==="done"||d.status==="canceled"||d.status==="dead")}catch(w){f({level:"error",event:"canvas.node_list.failed",error:w});return}await O.run(t,{rows:h,fleet:c,lifecycle:n}),wt.run(t,{rows:h});const g=await gt.run(t,{rows:[...h,...o],fleet:c});yt.run(t),It.run(t),St.run(t,{lifecycle:n}),_t.run(t,{lifecycle:n}),bt.run(t,{lifecycle:n}),kt.run(t,{lifecycle:n}),Et.run(t,{lifecycle:n,fleet:c}),Rt.run(t,{lifecycle:n}),Fe(),xt.run(t,{fleet:c,lifecycle:n}),await Pt.run(t,{rows:h}),O.warnIfSaturated({fleet:c,lifecycle:n,thresholds:u,frozen:g})}a(Dt,"superviseTick");async function Tt(t){ee(te(),{recursive:!0,mode:493}),process.platform==="linux"&&Le(te(),493);const n=He();if(E(n))throw new Error(`layout refusal cannot bind occupied socket: ${n}`);const c=re((d,p)=>{if(d.method==="GET"&&d.url==="/healthz"){p.writeHead(200,{"content-type":"application/json; charset=utf-8"}),p.end(JSON.stringify({ok:!1,daemon_up:!0,store_accessible:!1,brokers_reconciled:!1,startup_phase:"blocked",startup_blocked:"layout_migration_required"}));return}p.writeHead(503,{"content-type":"application/json; charset=utf-8"}),p.end(JSON.stringify({error:{code:"layout_migration_required",message:"run crtr sys migrate while the runtime is offline",type:"server_error",origin:"runtime",retryable:!1}}))});await new Promise((d,p)=>{c.once("error",p),c.listen(n,()=>{c.off("error",p),d()})});let u;const h=t.tcp??Ne();if(h){const d=/^(.*):(\d+)$/.exec(h);if(!d||Number(d[2])>65535)throw new Error(`invalid refusal TCP address: ${h}`);const p=re(c.listeners("request")[0]);await new Promise((s,m)=>{p.once("error",m),p.listen(Number(d[2]),d[1],()=>{p.off("error",m),s()})}),u=p}ue();let o;const g=a(()=>(o??=(async()=>{c.closeAllConnections(),u?.closeAllConnections(),await Promise.all([c,u].filter(d=>d!==void 0).map(d=>new Promise((p,s)=>d.close(m=>m?s(m):p())))),ve(process.pid),process.off("SIGINT",w),process.off("SIGTERM",w)})(),o),"cleanup"),w=a(()=>{g().then(()=>process.exit(0),d=>{process.stderr.write(`[crtrd] layout refusal cleanup failed: ${String(d)}
|
|
2
|
-
`),process.exit(1)})},"onSignal");return process.on("SIGINT",
|
|
1
|
+
var Pe=Object.defineProperty;var s=(t,n)=>Pe(t,"name",{value:n,configurable:!0});import{startPeerOutbox as xe}from"./peer/outbox.js";import{reportMachineStatus as Ie}from"../core/peer/directory.js";import{createPeerRelay as De}from"./peer/relay-service.js";import{writeFileSync as Te,readFileSync as Ce,rmSync as $e,mkdirSync as ee,existsSync as E,chmodSync as Le}from"node:fs";import{createServer as re}from"node:http";import{dirname as Ae}from"node:path";import{envCrtrdTcp as Ne,envDocumentPort as Me}from"../shared/env.js";import{serveCanvasConversationStore as Oe}from"../core/canvas/sessions.js";import{pollRunObservers as Fe}from"./runs/observer.js";import{randomBytes as Ge}from"node:crypto";import{apiSocketPath as He,crtrHome as je}from"../core/canvas/paths.js";import{activeAppUsers as Be}from"../core/spaces/users.js";import{ensureAppSpace as qe,ensureUserFiles as ze}from"../core/spaces/space.js";import{LAUNCHER_SOCKET as x}from"../launcher/spec.js";import{launcherRequest as D}from"../launcher/client.js";import{installLauncherEventSink as We}from"./launcher-events.js";import{initializeEmptyLayout as Ue,layoutNeedsMigration as Ke,socketDir as te}from"../core/layout.js";import{migrateLooseKeys as Je}from"../core/layout-migrate/loose-keys.js";import{relocateProfileFolders as Ve}from"../core/profiles/relocate.js";import{getNode as Qe,listNodesForSupervision as ne,setFrozen as oe}from"../core/canvas/index.js";import{createApiServer as Ye}from"./api/server.js";import{createDocumentListener as Xe}from"./api/document-listener.js";import{documentSecret as Ze}from"./api/document-secret.js";import{createAppListener as er}from"./api/app-listener.js";import{installLocalTerminalGrant as rr}from"../core/grants/local.js";import{onRunEventAppended as tr}from"../core/runs/events.js";import{runNotices as nr}from"./run-notices.js";import{createGrantSync as or,GRANT_SYNC_INTERVAL_S as ir}from"../core/grants/sync.js";import{runRemovalCascades as ar}from"../core/grants/remove.js";import{sweepSandboxes as sr}from"../core/grants/on-sync.js";import{rebuildCronExecutions as cr}from"./cron/run-socket.js";import{hasSyncedGrants as dr}from"../core/grants/mirror.js";import{readConfig as ie}from"../core/config.js";import{reconcileUndeliveredTickets as lr}from"./human/sweep.js";import{resetHandedOffDeliveries as pr}from"../core/canvas/deliveries.js";import{resetHandedOffDaemonActions as mr}from"../core/canvas/daemon-actions.js";import{sweepReviews as fr}from"./review/sweep.js";import{pidfilePath as B}from"./pidfile.js";import{rendererWarning as ur}from"../core/runtime/package-health.js";import{DEFAULT_INTERVAL_MS as hr}from"./supervise-cadence.js";import{createResumeDetector as wr}from"./resume-detector.js";import{setFatalFaultAnnouncer as vr}from"../core/canvas/recovery.js";import{BrokerSupervisionReconciler as gr}from"./reconcilers/broker-supervision.js";import{ControllerDeathReconciler as yr}from"./reconcilers/controller-death.js";import{NodeLifecycleReconciler as Sr}from"./reconcilers/node-lifecycle/tick.js";import{NodeDeadlineReconciler as _r}from"./reconcilers/node-deadline.js";import{CronLaneReconciler as br}from"./reconcilers/cron-lane.js";import{DeliveryLaneReconciler as kr}from"./reconcilers/delivery-lane.js";import{ActionLaneReconciler as Er}from"./reconcilers/action-lane.js";import{endLiveExecution as Rr,migrateLegacyExecutionIdentities as Pr}from"../core/canvas/executions.js";import{revokePriorEpochNodeTokens as xr}from"../core/canvas/node-tokens.js";import{PendingReviewSubmitReconciler as Ir}from"./reconcilers/pending-review-submit.js";import{StorageMaintenanceReconciler as Dr}from"./reconcilers/storage-maintenance.js";import{StorageDueWorkReconciler as Tr}from"./reconcilers/storage-due-work.js";import{BashDeadlineReconciler as Cr}from"./reconcilers/bash-deadline.js";import{FaultRetryBackstopReconciler as $r}from"./reconcilers/fault-retry-backstop.js";import{StructuredRequestReconciler as Lr}from"./reconcilers/structured-request-lane.js";import{reconcileStructuredRequestSidecars as Ar}from"./structured-requests/boot.js";import{captureLivenessSnapshot as ae,capturePidCommand as Nr,captureTeardownSnapshot as se,isPidAlive as Mr,isAnyPidAlive as ce,killProcessTreePids as de}from"../core/canvas/pid.js";import{bindFleet as Or,boundFleet as Fr}from"../core/runtime/fleet.js";import{bindDaemonControl as Gr,clearDaemonControl as Hr}from"./control.js";import{execDaemon as jr,spawnDaemon as Br}from"./manage.js";import{reconcileAndMigrateBoot as qr}from"../core/canvas/boot.js";import{resolveInstallId as zr}from"../core/canvas/install-id.js";import{setInstallId as Wr}from"../core/runtime/nodes.js";import{claimDaemonOwnership as Ur,releaseDaemonOwnership as le}from"../core/canvas/daemon-owner.js";import{migrate as Kr,bindDaemonCanvasOpenHook as Jr,clearDaemonCanvasOpenHook as pe,openDb as me,withCanvasWrite as Vr}from"../core/canvas/db.js";import{brokerSignalBus as q}from"./broker-signals/bus.js";import{brokerSignalStreams as Qr}from"./api/handlers/broker-signals.js";import{reconcilePackages as Yr}from"../core/graph/package-reconcile.js";import{startRepoSync as Xr}from"../core/graph/repo-sync/index.js";import{prewarmRecentRecipes as Zr,reapStaleSpares as et}from"../core/runtime/warm-pool.js";import{DaemonFleet as rt}from"./fleet.js";import{BOOT_MIGRATIONS as tt}from"./boot-migrations.js";import{applyJoinedOwner as nt}from"./joined-owner.js";import{emitEvent as f}from"../core/events/emit.js";import{operationIdContext as _}from"../core/events/operation-id.js";import{bindDaemonEventSource as ot}from"../core/events/source.js";import{activateCanvasImport as it,MigrationBlockedError as at,runForcedCanvasImport as st}from"../migrations/activation.js";import{convertLegacyProviderStore as ct,convertLegacyScopedStore as dt}from"../core/scoped-state/migrate.js";import{userScopeRoot as lt}from"../core/scope.js";import{secretsDir as pt}from"../core/layout.js";function z(t,n){return t.includes(` --canvas-home ${n} `)}s(z,"brokerCommandDeclaresCanvasHome");function W(t){return/ --epoch (\S+) /.exec(t)?.[1]??null}s(W,"brokerCommandEpoch");const mt=5e3,fe=150;async function ft(t){const n=ae();if(n===null)throw f({level:"error",event:"daemon.census.snapshot_failed",fields:{invariant:"prior-epoch brokers are reaped before readiness"}}),new Error("prior-epoch broker census could not capture the process table");const c=je(),u=[];for(const[a,m]of n.processes){const y=m.command;if(m.zombie||!y.includes("broker-cli.js")||!z(y,c)||W(y)===t)continue;const b=y.trim().split(/\s+/).at(-1)??"";b===""||b.endsWith("broker-cli.js")||u.push({pid:a,nodeId:b})}let h=0;const o=[];for(const a of u){const m=Nr(a.pid);if(m===null||!m.includes("broker-cli.js")||!z(m,c)||W(m)===t||m.trim().split(/\s+/).at(-1)!==a.nodeId)continue;const y=se(a.pid,null);if(!y.reused){try{process.platform==="linux"&&E(x)?await D({operation:"stop",pid:a.pid}):process.kill(a.pid,"SIGTERM")}catch{continue}h++,o.push({pid:a.pid,snap:y})}}const g=Date.now()+mt;for(;Date.now()<g&&o.some(a=>ce(a.snap.tree.length>0?a.snap.tree:[a.pid]));)await new Promise(a=>setTimeout(a,fe));let v=0;for(const a of o){const m=a.snap.tree.length>0?a.snap.tree:[a.pid];ce(m)&&(process.platform==="linux"&&E(x)?await D({operation:"stop",pid:a.pid}):de(m,"SIGKILL",a.snap.identities),v++)}v>0&&await new Promise(a=>setTimeout(a,fe));const d=ae();if(d===null)throw f({level:"error",event:"daemon.census.snapshot_failed",fields:{invariant:"prior-epoch brokers are reaped before readiness",stage:"final"}}),new Error("prior-epoch broker census could not capture the final process table");const p=[];for(const[a,m]of d.processes){const y=m.command;m.zombie||!y.includes("broker-cli.js")||z(y,c)&&W(y)!==t&&p.push(a)}if(p.length>0)throw new Error(`prior-epoch broker census could not prove termination of pid(s): ${p.join(", ")}`);f({level:"info",event:"daemon.census.completed",fields:{prior_epoch_brokers:u.length,sigtermed:h,sigkilled:v}})}s(ft,"reapPriorEpochBrokers");const ut=5e3;async function ht(t){const n=Array.from(t.entries());if(n.length===0)return;for(const[o]of n){const g=(await Qe(o))?.status;(g==="active"||g==="idle")&&await oe(o,new Date().toISOString())}const c=n.map(([,o])=>({pid:o.pid,snap:se(o.pid,null),exited:o.handle.exited}));for(const o of c)if(!o.snap.reused)try{process.platform==="linux"&&E(x)?await D({operation:"stop",pid:o.pid}):process.kill(o.pid,"SIGTERM")}catch{}const u=new Promise(o=>{setTimeout(o,ut).unref()});await Promise.allSettled(c.map(o=>Promise.race([o.exited.then(()=>{}),u])));const h=[];for(const o of c)Mr(o.pid)&&(process.platform==="linux"&&E(x)?await D({operation:"stop",pid:o.pid}):de(o.snap.tree.length>0?o.snap.tree:[o.pid],"SIGKILL",o.snap.identities),h.push(o));await Promise.all(h.map(o=>o.exited));for(const[o]of n)await Rr(o,{reason:"daemon-teardown"});f({level:"info",event:"daemon.fleet_teardown.completed",fields:{brokers:c.length,sigkilled:h.length}})}s(ht,"teardownFleet");function ue(){ee(Ae(B()),{recursive:!0}),Te(B(),String(process.pid),"utf8")}s(ue,"writePidfile");function he(t){return typeof t=="object"&&t!==null&&t.code==="ENOENT"}s(he,"isMissingPathError");function we(t){const n=B();let c;try{c=Ce(n,"utf8")}catch(u){if(he(u))return;throw u}if(c.trim()!==String(t))throw new Error(`daemon readiness mirror does not name this invocation (expected pid ${t})`);try{$e(n)}catch(u){if(he(u))return;throw u}}s(we,"removeOwnedPidfileMirror");const wt={acceptsDetachedWork:s(()=>!0,"acceptsDetachedWork"),registerDetached:s(t=>{t.catch(()=>{})},"registerDetached")},O=new gr;vr(t=>O.handleFatalFault(t,!1));const vt=new yr,gt=new Sr,yt=new _r,St=new br,_t=new kr,bt=new Er,kt=new Ir,Et=new Dr,Rt=new Tr,Pt=new Cr,xt=new $r,It=new Lr;async function Dt(t=Date.now(),n=wt){const c=Fr(),u=await O.runFleetPreamble(c);let h,o;try{const v=await ne();h=v.filter(d=>d.status==="active"||d.status==="idle"),o=v.filter(d=>d.status==="done"||d.status==="canceled"||d.status==="dead")}catch(v){f({level:"error",event:"canvas.node_list.failed",error:v});return}await O.run(t,{rows:h,fleet:c,lifecycle:n}),await vt.run(t,{rows:h});const g=await gt.run(t,{rows:[...h,...o],fleet:c});await yt.run(t),await It.run(t),await St.run(t,{lifecycle:n}),await _t.run(t,{lifecycle:n}),await bt.run(t,{lifecycle:n}),await kt.run(t,{lifecycle:n}),await Et.run(t,{lifecycle:n,fleet:c}),Rt.run(t,{lifecycle:n}),await Fe(),xt.run(t,{fleet:c,lifecycle:n}),await Pt.run(t,{rows:h}),O.warnIfSaturated({fleet:c,lifecycle:n,thresholds:u,frozen:g})}s(Dt,"superviseTick");async function Tt(t){ee(te(),{recursive:!0,mode:493}),process.platform==="linux"&&Le(te(),493);const n=He();if(E(n))throw new Error(`layout refusal cannot bind occupied socket: ${n}`);const c=re((d,p)=>{if(d.method==="GET"&&d.url==="/healthz"){p.writeHead(200,{"content-type":"application/json; charset=utf-8"}),p.end(JSON.stringify({ok:!1,daemon_up:!0,store_accessible:!1,brokers_reconciled:!1,startup_phase:"blocked",startup_blocked:"layout_migration_required"}));return}p.writeHead(503,{"content-type":"application/json; charset=utf-8"}),p.end(JSON.stringify({error:{code:"layout_migration_required",message:"run crtr sys migrate while the runtime is offline",type:"server_error",origin:"runtime",retryable:!1}}))});await new Promise((d,p)=>{c.once("error",p),c.listen(n,()=>{c.off("error",p),d()})});let u;const h=t.tcp??Ne();if(h){const d=/^(.*):(\d+)$/.exec(h);if(!d||Number(d[2])>65535)throw new Error(`invalid refusal TCP address: ${h}`);const p=re(c.listeners("request")[0]);await new Promise((a,m)=>{p.once("error",m),p.listen(Number(d[2]),d[1],()=>{p.off("error",m),a()})}),u=p}ue();let o;const g=s(()=>(o??=(async()=>{c.closeAllConnections(),u?.closeAllConnections(),await Promise.all([c,u].filter(d=>d!==void 0).map(d=>new Promise((p,a)=>d.close(m=>m?a(m):p())))),we(process.pid),process.off("SIGINT",v),process.off("SIGTERM",v)})(),o),"cleanup"),v=s(()=>{g().then(()=>process.exit(0),d=>{process.stderr.write(`[crtrd] layout refusal cleanup failed: ${String(d)}
|
|
2
|
+
`),process.exit(1)})},"onSignal");return process.on("SIGINT",v),process.on("SIGTERM",v),g}s(Tt,"serveLayoutRefusal");async function Ct(t={}){if(Ke())return Tt(t);Ue();const n=await Ur(Ge(16).toString("hex"));if(!n.claimed){if(n.reason==="incumbent_alive")process.stderr.write(`[crtrd] already running (pid ${n.incumbentPid??"?"})
|
|
3
3
|
`);else{const r=[n.incumbentPid!==void 0?`pid ${n.incumbentPid}`:void 0,n.verdict!==void 0?`verdict ${n.verdict}`:void 0].filter(i=>i!==void 0),e=r.length>0?` (${r.join(", ")})`:"";process.stderr.write(`[crtrd] claim lost: ${n.reason}${e}
|
|
4
4
|
`),n.reason==="own_identity_indeterminate"&&process.stderr.write("[crtrd] cannot read its own process identity. crouter needs /proc on Linux, or the `ps` command elsewhere (Debian/Ubuntu: apt-get install procps).\n"),(n.reason==="own_identity_indeterminate"||n.reason==="incumbent_malformed")&&(process.exitCode=1)}return async()=>{}}const c=n.claim;let u=null;try{await ft(c.token),dt({kind:"user",root:lt()});for(const e of Ve())process.stderr.write(`[crtrd] ${e}
|
|
5
5
|
`);if(process.platform==="darwin"){const{readConfig:e,updateConfig:i}=await import("../core/config.js");if(e("user").paths?.user_files===void 0){const{homedir:l}=await import("node:os");i("user",S=>{S.paths??={},S.paths.user_files??=l()})}}await ct(pt());for(const e of Je())process.stderr.write(`[crtrd] ${e}
|
|
6
|
-
`);Kr(
|
|
6
|
+
`);Kr((await me()).raw),Jr(e=>q.install(e));const r=await Vr(async e=>await Yr(e));for(const e of r.conflicts)process.stderr.write(`[crtrd] plugin documents not reconciled: ${e.message}
|
|
7
7
|
`);for(const e of r.invalid)process.stderr.write(`[crtrd] package file is not a document: ${e.path}: ${e.error}
|
|
8
8
|
`);for(const e of r.quarantined)process.stderr.write(`[crtrd] plugin "${e.name}" has a damaged ${e.file} (${e.reason}); ${e.movedTo!==void 0?`moved to ${e.movedTo}`:"left in place and skipped"}
|
|
9
9
|
`);for(const e of r.kinds.refused)process.stderr.write(`[crtrd] plugin "${e.plugin}" kind ${e.kind} not registered: ${e.message}
|
|
10
10
|
`);for(const e of r.kinds.invalid)process.stderr.write(`[crtrd] plugin "${e.plugin}" declares invalid object kinds or scopes; no kinds registered and no app token: ${e.error}
|
|
11
|
-
`);u=nt(),process.platform==="linux"&&E(x)&&(We(),await D({operation:"users.sync",users:Be()})),xr(c.token)}catch(r){
|
|
11
|
+
`);u=await nt(),process.platform==="linux"&&E(x)&&(We(),await D({operation:"users.sync",users:await Be()})),await xr(c.token)}catch(r){pe(),q.close();try{const{released:e}=await le(c);if(!e)throw new Error("daemon ownership claim was not released")}catch(e){throw new AggregateError([r,e],"daemon startup failed and cleanup also failed")}throw r}let h=!0,o,g=Promise.resolve(),v=!1,d,p;const a=new Set;let m=!1,y=!1,b,A,F,U=!1,N,T,C,$,G;const ve=wr();let R,w={phase:"initializing",message:"daemon startup is running the canvas import and normal services are unavailable",blockerPaths:[]},I="initial startup activation",ge=null;function ye(){return w.phase==="ready"?null:{phase:w.phase,message:w.message,blockerPaths:w.blockerPaths}}s(ye,"startupBlock");function k(r){a.add(r),r.finally(()=>{a.delete(r)}).catch(()=>{})}s(k,"registerDetached");const K={acceptsDetachedWork:s(()=>h,"acceptsDetachedWork"),registerDetached:k};await Xr(K,me);async function Se(){try{h=!1,Qr.close(),pe(),q.close(),d!==void 0&&(clearInterval(d),d=void 0),C!==void 0&&(clearInterval(C),C=void 0),G?.(),G=void 0;let r;do r=g,await r;while(r!==g);for(;a.size>0;)await Promise.allSettled([...a]);if(p!==void 0&&(await ht(p),p.dispose()),F!==void 0&&await F.close(),A!==void 0&&!U&&(U=!0,await A.close()),$!==void 0){const e=$;$=void 0,await e.stop()}if(T!==void 0){const e=T;T=void 0,await e.close()}if(N!==void 0){const e=N;N=void 0,await e.close()}if(m||(we(process.pid),m=!0),m&&!y){const{released:e}=await le(c);if(!e)throw new Error("daemon ownership claim was not released");y=!0}}finally{Hr(),process.off("SIGINT",Q),process.off("SIGTERM",Y),process.off("exit",X)}}s(Se,"cleanupAttempt");const M=1e3;let J=!1;function _e(){return J?{graceMs:M}:(J=!0,_.fresh(()=>{f({level:"info",event:"daemon.handover.armed",fields:{pid:process.pid,grace_ms:M}})}),setTimeout(()=>{be()},M),{graceMs:M})}s(_e,"requestHandover");async function be(){try{await P()}catch(r){const e=r instanceof Error?r.stack??r.message:String(r);process.stderr.write(`[crtrd] handover cleanup failed:
|
|
12
12
|
${e}
|
|
13
13
|
`),process.exit(1)}try{process.platform==="linux"&&E(x)&&(await D({operation:"daemon.handover"}),process.exit(0)),process.pid===1&&await jr();const r=await Br({waitForJoinLock:!0});_.fresh(()=>{f({level:"info",event:"daemon.handover.completed",fields:{predecessor_pid:process.pid,successor_pid:r.pid??r.existing_pid??null,spawned:r.started}})})}catch(r){_.fresh(()=>{f({level:"error",event:"daemon.handover.successor_failed",error:r})});const e=r instanceof Error?r.message:String(r);process.stderr.write(`[crtrd] handover successor failed to start: ${e}
|
|
14
|
-
`),process.exit(1)}process.exit(0)}
|
|
14
|
+
`),process.exit(1)}process.exit(0)}s(be,"performHandover");function P(){if(b!==void 0)return b;const r=Se();return b=r,r.then(()=>{b===r&&(b=void 0)},()=>{b===r&&(b=void 0)}),r}s(P,"requestCleanup");async function V(r){try{await P(),process.exit(0)}catch(e){process.exitCode=1;const i=e instanceof Error?e.stack??`${e.name}: ${e.message}`:String(e);process.stderr.write(`[crtrd] ${r} cleanup failed:
|
|
15
15
|
${i}
|
|
16
|
-
`),process.exit(1)}}
|
|
16
|
+
`),process.exit(1)}}s(V,"handleSignal");function Q(){V("SIGINT")}s(Q,"onSigint");function Y(){V("SIGTERM")}s(Y,"onSigterm");function X(){P().catch(()=>{})}s(X,"onExit");async function H(r){h&&(g=g.then(r).then(()=>{},e=>{_.fresh(()=>{f({level:"error",event:"daemon.lane_job.failed",error:e})})}))}s(H,"enqueue");async function Z(){!h||v||(ve.check()&&R&&(f({level:"info",event:"daemon.resume.detected"}),k(R().catch(()=>{}))),v=!0,await H(async()=>{if(v=!1,!!h)try{await Dt(Date.now(),K)}catch(r){_.fresh(()=>{f({level:"error",event:"daemon.tick.failed",error:r})})}}))}s(Z,"enqueueTick");let L=null;async function ke(){if(L!==null)throw{status:500,code:"admission_failed",message:`daemon admission previously failed: ${L instanceof Error?L.message:String(L)}`};if(w.phase==="ready")return{admitted:!1,already_admitted:!0,startup_phase:"ready"};if(w.phase!=="prepared"&&w.phase!=="recovering")throw{status:409,code:"not_prepared",message:w.message};const r=w.phase==="prepared";try{return await j(),w={phase:"ready",message:"",blockerPaths:[]},r?{admitted:!0,already_admitted:!1,startup_phase:"ready"}:{admitted:!1,already_admitted:!0,startup_phase:"ready"}}catch(e){throw L=e,{status:500,code:"admission_failed",message:`daemon admission failed: ${e instanceof Error?e.message:String(e)}`}}}s(ke,"admitStartup");async function Ee(r){if(I!==null)throw{status:409,code:"migration_in_progress",message:`the canvas import is already running (${I})`};I="repair";try{const e=await st({dryRun:r.dryRun});if(r.dryRun||e.pending||w.phase!=="blocked")return{result:e,resumed:!1};if(t.prepare)return w={phase:"prepared",message:"daemon storage is prepared and normal services are unavailable until admission",blockerPaths:[]},{result:e,resumed:!1};try{return await j(),w={phase:"ready",message:"",blockerPaths:[]},{result:e,resumed:!0}}catch(i){const l=i instanceof Error?i.message:String(i);return setTimeout(()=>{P().catch(()=>{})},1e3),{result:e,resumed:!1,resumeError:l}}}finally{I=null}}s(Ee,"repairMigrations");async function Re(){o=t.intervalMs??hr;const r=c.token;p=new rt({epoch:r,enqueue:H}),Or(p),w={phase:"recovering",message:"daemon startup recovery is running and normal services are unavailable",blockerPaths:[]},_.fresh(()=>{f({level:"info",event:"daemon.started",fields:{pid:process.pid,interval_ms:o}})});const e=await zr();if(Wr(e),_.fresh(()=>{f({level:"info",event:"daemon.install_id.resolved",fields:{install_id:e}})}),_.fresh(()=>{let i;try{i=ur()}catch{return}i!==null&&f({level:"warn",event:"daemon.startup.warning",fields:{stage:"termrender",warning:i.slice(0,2048)}})}),await _.fresh(async()=>{await fr(),await lr(),await pr(Date.now()),await mr(Date.now())}),await _.fresh(async()=>{const{reconcile:i,migrated:l}=await qr(Pr);i.changed&&f({level:"info",event:"daemon.boot_change.reconciled",fields:{cleared_count:i.cleared.length,same_boot_proven:i.sameBootProven}}),l.length>0&&f({level:"info",event:"daemon.pid_identity.migrated",fields:{migrated_count:l.length}})}),await _.fresh(async()=>{for(const i of await ne())i.status!=="active"||i.pi_pid!=null||i.frozen_at!=null||i.respawn_not_before!=null||(await oe(i.node_id,new Date().toISOString()),f({level:"warn",event:"daemon.startup.launch_debt_recorded",node_id:i.node_id}))}),await _.fresh(async()=>{await Ar();for(const i of tt){const l=i.apply();l.changed&&f({level:"info",event:"daemon.boot_migration.applied",fields:{migration:i.id,...l.summary}})}}),k(cr()),R){const i=s(()=>{k(R().catch(()=>{})),k(Ie().then(l=>$?.observe(l)).then(()=>{},l=>{f({level:"warn",event:"daemon.peer.status_failed",error:l})}))},"refresh");k(ar().catch(()=>{})),k(sr().then(({completion:l})=>l).catch(l=>{f({level:"error",event:"daemon.grants.sweep_failed",error:l})})),i(),C=setInterval(i,ir*1e3),C.unref(),G=xe({joined:!0,register:k})}await H(async()=>{await et(),await Zr()}),d=setInterval(()=>{Z().catch(i=>f({level:"error",event:"daemon.tick.failed",error:i}))},o),await Z()}s(Re,"completeStartup");function j(){return ge??=Re().catch(r=>{throw w={phase:"initializing",message:"daemon startup recovery failed and normal services are unavailable",blockerPaths:[]},r})}s(j,"resumeStartup");try{process.on("SIGINT",Q),process.on("SIGTERM",Y),process.on("exit",X),ot(),u!==null&&f({level:"info",event:"daemon.joined_owner.applied",fields:{owner:u.owner,rows:u.rows}}),N=await Oe();const r=c.token;Gr({epoch:r,requestHandover:_e,registerDetached:k,startupBlock:ye,admitStartup:ke,repairMigrations:Ee}),ue(),A=Ye({tcp:t.tcp}),await A.ready;const e=Me()??ie("user").document_port,i=Xe(e,Ze());try{await i.ready,F=i}catch(S){f({level:"warn",event:"daemon.document_listener.bind_failed",fields:{port:e,error:S instanceof Error?S.message:String(S)}})}const l=ie("user").runtime;l?.issuer?(R=or(l.issuer,k),l.unsandboxed===!0&&($=De({syncGrants:R})),tr(S=>nr().appended(S))):await rr(),l?.unsandboxed===!0&&l.listener!==void 0&&f({level:"warn",event:"daemon.app_listener.refused_unsandboxed",fields:{reason:"runtime.unsandboxed is set; runtime.listener is ignored"}}),l!==void 0&&l.listener!==void 0&&l.unsandboxed!==!0&&(T=await er(l,async()=>await dr(l.issuer.replace(/\/$/,"")),R),await T.ready);try{await it()}catch(S){if(I=null,S instanceof at)return w={phase:"blocked",message:S.message,blockerPaths:S.blockerPaths},P;throw S}process.platform==="linux"&&E(x)&&(ze(),await qe("app:terminal"));try{t.prepare?w={phase:"prepared",message:"daemon storage is prepared and normal services are unavailable until admission",blockerPaths:[]}:(await j(),w={phase:"ready",message:"",blockerPaths:[]})}finally{I=null}return P}catch(r){try{await P()}catch(e){throw new AggregateError([r,e],"daemon startup failed and cleanup also failed")}throw r}}s(Ct,"runDaemon");var co=Ct;export{z as brokerCommandDeclaresCanvasHome,W as brokerCommandEpoch,co as default,Ct as runDaemon,Dt as superviseTick,ht as teardownFleet};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var C=Object.defineProperty;var l=(e,t)=>C(e,"name",{value:t,configurable:!0});import{spawn as T}from"node:child_process";import{envHomeOverride as _}from"../../shared/env.js";import{deliveryBackoffMs as g}from"../../core/canvas/delivery-contract.js";import{killProcessGroup as x}from"../../core/canvas/pid.js";import{buildOperationalEnvBase as y}from"../../core/runtime/spawn-env.js";import{getNode as R}from"../../core/canvas/canvas.js";import{appProcessSandboxed as A,launchAppProcess as O}from"../../core/spaces/process.js";const I=12e4,h=2e3,E=4*1024;function w(e,t,r){return e.spawnError!==void 0?{state:"pending",nextAttemptAt:r+g(t),failure:m("spawn_error",{message:e.spawnError.message,stderr:e.stderr})}:e.timedOut?{state:"pending",nextAttemptAt:r+g(t),failure:m("timeout",{...e.signal===null?{}:{signal:e.signal},stderr:e.stderr})}:e.signal!==null?{state:"pending",nextAttemptAt:r+g(t),failure:m("signal",{signal:e.signal,stderr:e.stderr})}:e.exitCode===0?{state:"accepted"}:e.exitCode===78?{state:"permanent_failed",failure:m("exit",{exitCode:78,stderr:e.stderr})}:{state:"pending",nextAttemptAt:r+g(t),failure:m("exit",{exitCode:e.exitCode??void 0,stderr:e.stderr})}}l(w,"deliverySettlementForOutcome");function m(e,t){return{kind:e,...t}}l(m,"failure");function D(){let e=Buffer.alloc(0);return{take(t){e=t.length>=E?t.subarray(t.length-E):Buffer.concat([e,t]).subarray(Math.max(0,e.length+t.length-E))},decode(){return e.toString("utf8")}}}l(D,"stderrTailCapture");function S(e,t,r){if(r)return JSON.stringify(e);const d=e,n=d.delivery;return JSON.stringify({...d,delivery:{...n,attempt:t}})}l(S,"documentForAttempt");function L(e,t){const r=y({targetCwd:e,targetProfileId:null}),d=_();return d!==void 0&&d!==""&&(r.CRTR_HOME=d),{...r,...t}}l(L,"deliveryEnv");async function H(e,t){const r=D();let d;try{d=S(e.document,e.attempt,e.custom!==void 0)}catch(s){t(w({exitCode:null,signal:null,timedOut:!1,spawnError:s,stderr:r.decode()},e.attempt,Date.now()));return}if(process.platform==="linux"){let s;try{if(!A())throw new Error("root launcher is required for delivery");const u=e.nodeId===null||e.nodeId===void 0?null:R(e.nodeId),f=e.app??u?.grantee??(e.nodeId==null?"app:terminal":void 0);if(!f)throw new Error(`delivery origin ${e.nodeId} was deleted without a stored app`);const o=await O({...u?{nodeId:e.nodeId}:{},app:f,command:e.argv,cwd:e.cwd,env:{...y({targetCwd:e.cwd,targetProfileId:null,skipSpawnAllow:!0}),...e.custom?{CRTR_DELIVERY_ID:e.custom.deliveryId,CRTR_CAUSE_EVENT:e.custom.messageId}:{}},stdin:d,stdoutBytes:0,stderrBytes:E,stderrTail:!0});let a,p=!1;try{a=setTimeout(()=>{p=!0,o.stop().catch(i=>{console.error(`delivery process ${o.pid} could not be stopped:`,i)})},I),a.unref?.();const c=await o.completion;s={exitCode:c.exitCode,signal:c.signal,timedOut:p,stderr:c.stderr}}finally{a!==void 0&&clearTimeout(a)}}catch(u){s={exitCode:null,signal:null,timedOut:!1,spawnError:u,stderr:""}}t(w(s,e.attempt,Date.now()));return}let n;try{n=T(e.argv[0],e.argv.slice(1),{cwd:e.cwd,env:L(e.cwd,e.custom?{CRTR_DELIVERY_ID:e.custom.deliveryId,CRTR_CAUSE_EVENT:e.custom.messageId}:void 0),detached:!0,stdio:["pipe","pipe","pipe"]})}catch(s){t(w({exitCode:null,signal:null,timedOut:!1,spawnError:s,stderr:r.decode()},e.attempt,Date.now()));return}await new Promise(s=>{let u=!1,f=!1,o,a;const p=l(i=>{u||(u=!0,a!==void 0&&clearTimeout(a),!i.timedOut&&o!==void 0&&clearTimeout(o),n.stdin?.destroy(),n.stdout?.destroy(),n.stderr?.destroy(),t(w(i,e.attempt,Date.now())),s())},"finish");n.stdout?.on("data",()=>{}),n.stderr?.on("data",i=>r.take(i)),n.stdin?.on("error",()=>{}),n.on("error",i=>{p({exitCode:null,signal:null,timedOut:!1,spawnError:i,stderr:r.decode()})}),n.on("exit",(i,v)=>{p({exitCode:i,signal:v,timedOut:f,stderr:r.decode()})});const c=l(()=>{n.pid!==void 0&&(x(n.pid),o=setTimeout(()=>x(n.pid,"SIGKILL"),h),o.unref?.())},"killWithEscalation");a=setTimeout(()=>{f=!0,c()},I),a.unref?.(),n.stdin?.end(d,"utf8")})}l(H,"runDelivery");export{E as DELIVERY_STDERR_TAIL_BYTES,I as DELIVERY_TIMEOUT_MS,w as deliverySettlementForOutcome,H as runDelivery};
|
|
1
|
+
var C=Object.defineProperty;var l=(e,t)=>C(e,"name",{value:t,configurable:!0});import{spawn as T}from"node:child_process";import{envHomeOverride as _}from"../../shared/env.js";import{deliveryBackoffMs as g}from"../../core/canvas/delivery-contract.js";import{killProcessGroup as x}from"../../core/canvas/pid.js";import{buildOperationalEnvBase as y}from"../../core/runtime/spawn-env.js";import{getNode as R}from"../../core/canvas/canvas.js";import{appProcessSandboxed as A,launchAppProcess as O}from"../../core/spaces/process.js";const I=12e4,h=2e3,E=4*1024;function w(e,t,r){return e.spawnError!==void 0?{state:"pending",nextAttemptAt:r+g(t),failure:m("spawn_error",{message:e.spawnError.message,stderr:e.stderr})}:e.timedOut?{state:"pending",nextAttemptAt:r+g(t),failure:m("timeout",{...e.signal===null?{}:{signal:e.signal},stderr:e.stderr})}:e.signal!==null?{state:"pending",nextAttemptAt:r+g(t),failure:m("signal",{signal:e.signal,stderr:e.stderr})}:e.exitCode===0?{state:"accepted"}:e.exitCode===78?{state:"permanent_failed",failure:m("exit",{exitCode:78,stderr:e.stderr})}:{state:"pending",nextAttemptAt:r+g(t),failure:m("exit",{exitCode:e.exitCode??void 0,stderr:e.stderr})}}l(w,"deliverySettlementForOutcome");function m(e,t){return{kind:e,...t}}l(m,"failure");function D(){let e=Buffer.alloc(0);return{take(t){e=t.length>=E?t.subarray(t.length-E):Buffer.concat([e,t]).subarray(Math.max(0,e.length+t.length-E))},decode(){return e.toString("utf8")}}}l(D,"stderrTailCapture");function S(e,t,r){if(r)return JSON.stringify(e);const d=e,n=d.delivery;return JSON.stringify({...d,delivery:{...n,attempt:t}})}l(S,"documentForAttempt");function L(e,t){const r=y({targetCwd:e,targetProfileId:null}),d=_();return d!==void 0&&d!==""&&(r.CRTR_HOME=d),{...r,...t}}l(L,"deliveryEnv");async function H(e,t){const r=D();let d;try{d=S(e.document,e.attempt,e.custom!==void 0)}catch(s){t(w({exitCode:null,signal:null,timedOut:!1,spawnError:s,stderr:r.decode()},e.attempt,Date.now()));return}if(process.platform==="linux"){let s;try{if(!A())throw new Error("root launcher is required for delivery");const u=e.nodeId===null||e.nodeId===void 0?null:await R(e.nodeId),f=e.app??u?.grantee??(e.nodeId==null?"app:terminal":void 0);if(!f)throw new Error(`delivery origin ${e.nodeId} was deleted without a stored app`);const o=await O({...u?{nodeId:e.nodeId}:{},app:f,command:e.argv,cwd:e.cwd,env:{...y({targetCwd:e.cwd,targetProfileId:null,skipSpawnAllow:!0}),...e.custom?{CRTR_DELIVERY_ID:e.custom.deliveryId,CRTR_CAUSE_EVENT:e.custom.messageId}:{}},stdin:d,stdoutBytes:0,stderrBytes:E,stderrTail:!0});let a,p=!1;try{a=setTimeout(()=>{p=!0,o.stop().catch(i=>{console.error(`delivery process ${o.pid} could not be stopped:`,i)})},I),a.unref?.();const c=await o.completion;s={exitCode:c.exitCode,signal:c.signal,timedOut:p,stderr:c.stderr}}finally{a!==void 0&&clearTimeout(a)}}catch(u){s={exitCode:null,signal:null,timedOut:!1,spawnError:u,stderr:""}}t(w(s,e.attempt,Date.now()));return}let n;try{n=T(e.argv[0],e.argv.slice(1),{cwd:e.cwd,env:L(e.cwd,e.custom?{CRTR_DELIVERY_ID:e.custom.deliveryId,CRTR_CAUSE_EVENT:e.custom.messageId}:void 0),detached:!0,stdio:["pipe","pipe","pipe"]})}catch(s){t(w({exitCode:null,signal:null,timedOut:!1,spawnError:s,stderr:r.decode()},e.attempt,Date.now()));return}await new Promise(s=>{let u=!1,f=!1,o,a;const p=l(i=>{u||(u=!0,a!==void 0&&clearTimeout(a),!i.timedOut&&o!==void 0&&clearTimeout(o),n.stdin?.destroy(),n.stdout?.destroy(),n.stderr?.destroy(),t(w(i,e.attempt,Date.now())),s())},"finish");n.stdout?.on("data",()=>{}),n.stderr?.on("data",i=>r.take(i)),n.stdin?.on("error",()=>{}),n.on("error",i=>{p({exitCode:null,signal:null,timedOut:!1,spawnError:i,stderr:r.decode()})}),n.on("exit",(i,v)=>{p({exitCode:i,signal:v,timedOut:f,stderr:r.decode()})});const c=l(()=>{n.pid!==void 0&&(x(n.pid),o=setTimeout(()=>x(n.pid,"SIGKILL"),h),o.unref?.())},"killWithEscalation");a=setTimeout(()=>{f=!0,c()},I),a.unref?.(),n.stdin?.end(d,"utf8")})}l(H,"runDelivery");export{E as DELIVERY_STDERR_TAIL_BYTES,I as DELIVERY_TIMEOUT_MS,w as deliverySettlementForOutcome,H as runDelivery};
|
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
export declare const TICK_LANES: readonly ["brokerSupervision", "controllerDeath", "nodeLifecycle", "nodeDeadline", "structuredRequests", "cronLane", "deliveryLane", "actionLane", "pendingReviewSubmit", "storageMaintenance", "storageDueWork", "pollRunObservers", "faultRetryBackstop", "bashDeadline"];
|
|
3
3
|
export interface DueSource {
|
|
4
4
|
/** Epoch ms of the earliest timed work this lane owes; `now` when work is due already; null when none. */
|
|
5
|
-
nextDue(now: number): number | null
|
|
5
|
+
nextDue(now: number): Promise<number | null>;
|
|
6
6
|
}
|
|
7
7
|
export declare function registerDueSource(lane: string, source: DueSource): void;
|
|
8
8
|
export declare function declareBusyOnly(lane: string, reason: string): void;
|
|
9
9
|
export declare function dueSourceLanes(): string[];
|
|
10
10
|
export declare function busyOnlyLanes(): string[];
|
|
11
11
|
/** The earliest due time over every source, and whether any source is due at `now`. A source that throws counts as due now: a lane that cannot answer must keep the sandbox awake, never let it sleep past work. */
|
|
12
|
-
export declare function collectDue(now: number, onError?: (lane: string, error: unknown) => void): {
|
|
12
|
+
export declare function collectDue(now: number, onError?: (lane: string, error: unknown) => void): Promise<{
|
|
13
13
|
dueNow: boolean;
|
|
14
14
|
nextDueMs: number | null;
|
|
15
|
-
}
|
|
15
|
+
}>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var f=Object.defineProperty;var r=(e,n)=>f(e,"name",{value:n,configurable:!0});const
|
|
1
|
+
var f=Object.defineProperty;var r=(e,n)=>f(e,"name",{value:n,configurable:!0});const d=["brokerSupervision","controllerDeath","nodeLifecycle","nodeDeadline","structuredRequests","cronLane","deliveryLane","actionLane","pendingReviewSubmit","storageMaintenance","storageDueWork","pollRunObservers","faultRetryBackstop","bashDeadline"],u=new Map,c=new Map;function p(e,n){u.set(e,n)}r(p,"registerDueSource");function x(e,n){c.set(e,n)}r(x,"declareBusyOnly");function D(){return[...u.keys()]}r(D,"dueSourceLanes");function b(){return[...c.keys()]}r(b,"busyOnlyLanes");async function L(e,n=()=>{}){let o=null,s=!1;for(const[a,i]of u){let t;try{t=await i.nextDue(e)}catch(l){n(a,l),t=e}t===null||!Number.isFinite(t)||(t<=e&&(s=!0),(o===null||t<o)&&(o=t))}return{dueNow:s,nextDueMs:o}}r(L,"collectDue");export{d as TICK_LANES,b as busyOnlyLanes,L as collectDue,x as declareBusyOnly,D as dueSourceLanes,p as registerDueSource};
|
package/dist/daemon/due.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/** Register every due source and busy-only declaration. Idempotent. */
|
|
2
|
-
export declare function installDueSources(): void
|
|
2
|
+
export declare function installDueSources(): Promise<void>;
|
|
3
3
|
/** How long a node with no engine yet, or an engine that has not opened its first
|
|
4
4
|
* turn, counts as work the daemon is about to do. Past it the node is idle or
|
|
5
5
|
* stranded, not starting: a resident revived with no prompt sits at an idle
|
|
@@ -9,6 +9,6 @@ export interface DueReport {
|
|
|
9
9
|
busy: boolean;
|
|
10
10
|
next_due_at: string | null;
|
|
11
11
|
}
|
|
12
|
-
export declare function dueReport(now?: number): DueReport
|
|
12
|
+
export declare function dueReport(now?: number): Promise<DueReport>;
|
|
13
13
|
/** For tests and diagnostics: the lanes covered. */
|
|
14
|
-
export declare function coveredLanes(): string[]
|
|
14
|
+
export declare function coveredLanes(): Promise<string[]>;
|
package/dist/daemon/due.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
var
|
|
2
|
-
WHERE status IN ('active', 'idle') AND kind != 'human' AND ${
|
|
3
|
-
AND pi_pid IS NULL AND respawn_not_before IS NOT NULL`)
|
|
4
|
-
WHERE deadline_at IS NOT NULL AND outcome_at IS NULL AND status IN ('active', 'idle') AND kind != 'human'`).filter(e=>!p(e.profile_id)).map(e=>
|
|
1
|
+
var D=Object.defineProperty;var a=(n,e)=>D(n,"name",{value:e,configurable:!0});import{openDb as f}from"../core/canvas/db.js";import{isPidPresent as R}from"../core/canvas/pid.js";import{isProfilePaused as p}from"../core/profiles/manifest.js";import{hasUnseenWakeMail as E}from"../core/canvas/deliveries.js";import{listPendingProviderRetries as T}from"../core/canvas/recovery.js";import{listSubmitRequestedRequests as x}from"../core/human/requests.js";import{storageConfig as I}from"../core/storage/client.js";import{emitEvent as A}from"../core/events/emit.js";import{wantsExecution as L}from"./reconcilers/node-lifecycle/wants-execution.js";import{dueAtMs as O}from"./reconcilers/fault-retry-backstop.js";import{UNUSED_UPLOAD_TTL_MS as y}from"./reconcilers/storage-due-work.js";import{busyOnlyLanes as M,collectDue as b,declareBusyOnly as l,dueSourceLanes as g,registerDueSource as r}from"./due-sources.js";import{filterAsync as h}from"../core/async-array.js";const c=a(async(n,...e)=>await(await f()).prepare(n).all(...e),"rows"),s=a(async n=>await(await f()).prepare(n).get(),"first"),o=a(n=>{if(n==null)return null;const e=Date.parse(n);return Number.isFinite(e)?e:null},"iso"),_=a(n=>{let e=null;for(const t of n)t!==null&&(e===null||t<e)&&(e=t);return e},"earliest"),N="node_id NOT IN (SELECT node_id FROM warm_pool)";let m=!1;async function S(){if(m)return;m=!0,l("brokerSupervision","acts only on live broker processes, which already make busy true"),l("controllerDeath","acts only on live controller processes"),l("pollRunObservers","follows live pids only"),l("bashDeadline","acts only on running bash jobs, which already make busy true"),l("storageMaintenance","retention and placement housekeeping: never time-critical, and it must not wake or hold a sleeping runtime"),r("nodeLifecycle",{nextDue:a(async()=>_((await h(await c(`SELECT node_id, status, intent, profile_id, respawn_not_before FROM node_rows
|
|
2
|
+
WHERE status IN ('active', 'idle') AND kind != 'human' AND ${N}
|
|
3
|
+
AND pi_pid IS NULL AND respawn_not_before IS NOT NULL`),async e=>!p(e.profile_id)&&await L({node_id:e.node_id,status:e.status,intent:e.intent}))).map(e=>o(e.respawn_not_before))),"nextDue")}),r("nodeDeadline",{nextDue:a(async()=>_((await c(`SELECT deadline_at, profile_id FROM node_rows
|
|
4
|
+
WHERE deadline_at IS NOT NULL AND outcome_at IS NULL AND status IN ('active', 'idle') AND kind != 'human'`)).filter(e=>!p(e.profile_id)).map(e=>o(e.deadline_at))),"nextDue")}),r("structuredRequests",{nextDue:a(async e=>await s("SELECT 1 FROM structured_requests WHERE state != 'pending' AND effects_done_at IS NULL LIMIT 1")!==void 0?e:(await s("SELECT MIN(deadline_at) AS at FROM structured_requests WHERE state = 'pending' AND deadline_at IS NOT NULL"))?.at??null,"nextDue")}),r("cronLane",{nextDue:a(async()=>{const e=(await c(`SELECT fire_at, profile FROM crons
|
|
5
5
|
WHERE state = 'active' AND run_state = 'idle'
|
|
6
|
-
AND NOT (held = 1 AND recur IS NULL AND expires_at IS NULL)`).filter(i=>!p(i.profile)).map(i=>
|
|
7
|
-
AND NOT EXISTS (SELECT 1 FROM upload_uses x WHERE x.upload_id = u.upload_id)`)?.at,u=
|
|
6
|
+
AND NOT (held = 1 AND recur IS NULL AND expires_at IS NULL)`)).filter(i=>!p(i.profile)).map(i=>o(i.fire_at)),t=(await c("SELECT expires_at FROM crons WHERE expires_at IS NOT NULL AND run_state = 'idle'")).map(i=>o(i.expires_at));return _([...e,...t])},"nextDue")});const n=a(async e=>async()=>(await s(`SELECT MIN(next_attempt_at) AS at FROM ${e} WHERE state = 'pending' AND canceled_at IS NULL AND next_attempt_at IS NOT NULL`))?.at??null,"attempts");r("deliveryLane",{nextDue:await n("deliveries")}),r("actionLane",{nextDue:await n("daemon_actions")}),r("pendingReviewSubmit",{nextDue:a(async e=>(await x()).length>0?e:null,"nextDue")}),r("storageDueWork",{nextDue:a(async e=>{if(I()===null)return null;if(await s("SELECT 1 FROM uploads WHERE delete_pending_since IS NOT NULL LIMIT 1")!==void 0||await s("SELECT 1 FROM shares WHERE status = 'off' AND object_deleted_at IS NULL LIMIT 1")!==void 0)return e;const t=(await s("SELECT MIN(expires_at) AS at FROM shares WHERE status = 'on' AND expires_at IS NOT NULL"))?.at,i=(await s(`SELECT MIN(created_at) AS at FROM uploads u WHERE delete_pending_since IS NULL
|
|
7
|
+
AND NOT EXISTS (SELECT 1 FROM upload_uses x WHERE x.upload_id = u.upload_id)`))?.at,u=o(i);return _([o(t),u===null?null:u+y])},"nextDue")}),r("faultRetryBackstop",{nextDue:a(async()=>_((await T()).map(e=>O(e))),"nextDue")})}a(S,"installDueSources");const w=12e4;async function U(n){const e=await c(`SELECT n.node_id, n.status, n.intent, n.profile_id, n.pi_pid, n.frozen_at, n.respawn_not_before, n.created, n.launched_at,
|
|
8
8
|
n.turn_open_at, n.turn_closed_at,
|
|
9
9
|
(SELECT x.started_at FROM executions x WHERE x.node_id = n.node_id AND x.state != 'exited') AS exec_started_at
|
|
10
10
|
FROM node_rows n
|
|
11
|
-
WHERE n.status IN ('active', 'idle') AND n.kind != 'human' AND n.${
|
|
11
|
+
WHERE n.status IN ('active', 'idle') AND n.kind != 'human' AND n.${N}`);for(const t of e){if(p(t.profile_id)||!await L({node_id:t.node_id,status:t.status,intent:t.intent}))continue;if(t.pi_pid!==null&&R(t.pi_pid)){if(t.turn_open_at!==null&&t.turn_closed_at===null)return!0;const d=o(t.exec_started_at);if(t.turn_open_at===null&&d!==null&&n-d<w||await E(t.node_id))return!0;continue}if(t.respawn_not_before!==null)continue;if(t.pi_pid!==null||t.frozen_at!==null||t.status==="active")return!0;const u=Math.max(...[t.created,t.launched_at,t.exec_started_at].map(d=>o(d)??0));if(u>0&&n-u<w||t.status==="idle"&&await E(t.node_id))return!0}return!1}a(U,"nodesOweWork");async function X(n=Date.now()){await S();const{dueNow:e,nextDueMs:t}=await b(n,(u,d)=>{A({level:"warn",event:"daemon.due.source_failed",error:d,fields:{lane:u}})});return{busy:e||await U(n)||await s("SELECT 1 FROM crons WHERE run_state = 'running' LIMIT 1")!==void 0||await s("SELECT 1 FROM jobs j JOIN objects o ON o.rowid = j.object WHERE j.status = 'running' AND o.deleted_at IS NULL LIMIT 1")!==void 0,next_due_at:t===null?null:new Date(t).toISOString()}}a(X,"dueReport");async function K(){return await S(),[...g(),...M()]}a(K,"coveredLanes");export{w as START_GRACE_MS,K as coveredLanes,X as dueReport,S as installDueSources};
|
package/dist/daemon/fleet.d.ts
CHANGED
|
@@ -66,8 +66,8 @@ export declare class DaemonFleet implements FleetRegistry {
|
|
|
66
66
|
interruptForProfilePause(nodeId: string, pid?: number | undefined): void;
|
|
67
67
|
hasProfilePauseInterruption(nodeId: string): boolean;
|
|
68
68
|
forget(nodeId: string): void;
|
|
69
|
-
onChildExit(nodeId: string, status: FleetExitStatus, executionId?: string): void
|
|
70
|
-
deliverExit(nodeId: string, status: FleetExitStatus): void
|
|
69
|
+
onChildExit(nodeId: string, status: FleetExitStatus, executionId?: string): Promise<void>;
|
|
70
|
+
deliverExit(nodeId: string, status: FleetExitStatus): Promise<void>;
|
|
71
71
|
/** The node-lifecycle tick's enactment entry. */
|
|
72
72
|
applyDeadRowPolicy(nodeId: string): Promise<void>;
|
|
73
73
|
/** A revive refusal before its launch try/catch leaves the row active but
|
package/dist/daemon/fleet.js
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
var g=Object.defineProperty;var l=(
|
|
1
|
+
var g=Object.defineProperty;var l=(i,e)=>g(i,"name",{value:e,configurable:!0});import{getNode as w,getRow as k}from"../core/canvas/index.js";import{revokeExitedNodeToken as $}from"../core/canvas/node-tokens.js";import{isProfilePaused as T}from"../core/profiles/manifest.js";import{fullName as p}from"../core/canvas/labels.js";import{isSafeNodeId as o}from"../core/canvas/paths.js";import{hasIdleReleaseIntent as R,transition as v}from"../core/runtime/lifecycle.js";import{publishNotice as E}from"../core/runtime/close.js";import{readFault as P,readInterruptedTurn as N,readTransportPoisonVerdict as x}from"../core/canvas/recovery.js";import{hasPendingWake as C}from"./reconcilers/live-obligation.js";import{clearRespawnPolicy as h,deferRespawnWhileOffline as F,MAX_RESPAWN_ATTEMPTS as M,OFFLINE_RESPAWN_RETRY_MS as S,recordRespawnPolicy as O,respawnBackoffMs as z}from"./reconcilers/node-lifecycle/respawn-policy.js";import{probeOnline as A}from"../core/runtime/connectivity.js";import{reviveNode as B}from"../core/runtime/revive.js";import{pushUrgent as m}from"../core/feed/feed.js";import{emitEvent as c}from"../core/events/emit.js";import{brokerThresholdsForDaemon as D}from"../core/runtime/fleet.js";import{isRecoveryHeld as L}from"../core/runtime/recovery-hold.js";async function _(i,e){const t=await P(i.node_id),r=t===null?"":`The broker reported a ${t.kind} fault on ${t.link} (${t.op}) before it exited: ${t.message}
|
|
2
2
|
|
|
3
|
-
`,
|
|
3
|
+
`,s=e===void 0?"The daemon did not observe an exit status.":`The observed exit status was code ${e.code??"null"}, signal ${e.signal??"null"}.`;return`\u26A0 Spawn failed \u2014 \`${i.name}\` (${i.kind}) never started.
|
|
4
4
|
|
|
5
|
-
Its pi vehicle exited before the session came up (no pi_session_id was ever recorded), so the node produced no output. ${
|
|
5
|
+
Its pi vehicle exited before the session came up (no pi_session_id was ever recorded), so the node produced no output. ${s}
|
|
6
6
|
|
|
7
|
-
`+
|
|
7
|
+
`+r+`Inspect canonical event diagnostics with \`crtr sys logs --node ${i.node_id}\`.
|
|
8
8
|
|
|
9
|
-
If the work still needs doing, re-spawn it.`}l(
|
|
9
|
+
If the work still needs doing, re-spawn it.`}l(_,"bootFailureBody");async function y(i,e){await m(i.node_id,await _(i,e),{from:i.node_id})}l(y,"surfaceBootFailure");function b(i){return`\u26A0 Out of memory \u2014 \`${i.name}\` (${i.kind}) was killed because its app's processes together passed the app's memory limit.
|
|
10
10
|
|
|
11
|
-
Every process of the run was stopped. The daemon does not restart it, because it would reach the same limit. Reduce what the run holds in memory, or ask the person to raise the app's limit (\`crtr sys limits set --app ${
|
|
11
|
+
Every process of the run was stopped. The daemon does not restart it, because it would reach the same limit. Reduce what the run holds in memory, or ask the person to raise the app's limit (\`crtr sys limits set --app ${i.grantee??"app:terminal"} --memory <size>\`), then revive the node.`}l(b,"outOfMemoryBody");async function W(i){const e=await x(i.node_id),t=e===null?"":`
|
|
12
12
|
|
|
13
|
-
Provider rotation observed ${e.consecutivePasses} consecutive route-queue passes with no HTTP response (tried ${e.routes.join(", ")}). Check network and provider transport before reviving.`,
|
|
13
|
+
Provider rotation observed ${e.consecutivePasses} consecutive route-queue passes with no HTTP response (tried ${e.routes.join(", ")}). Check network and provider transport before reviving.`,r=`\u26A0 Crash loop \u2014 \`${i.name}\` (${i.kind}) kept dying without settling a turn.
|
|
14
14
|
|
|
15
|
-
Its session started successfully, but six consecutive relaunches made no progress, so the daemon stopped retrying.`+
|
|
15
|
+
Its session started successfully, but six consecutive relaunches made no progress, so the daemon stopped retrying.`+t+`
|
|
16
16
|
|
|
17
|
-
Fix the crash cause, then revive the node if the work still needs doing.`;await m(
|
|
17
|
+
Fix the crash cause, then revive the node if the work still needs doing.`;await m(i.node_id,r,{from:i.node_id})}l(W,"surfaceCrashLoop");async function q(i,e){const t=e instanceof Error?e.message:String(e),r=`\u26A0 Recovery failed \u2014 \`${i.name}\` (${i.kind}) could not be relaunched.
|
|
18
18
|
|
|
19
|
-
The daemon refused this recovery before starting a broker: ${
|
|
19
|
+
The daemon refused this recovery before starting a broker: ${t}
|
|
20
20
|
|
|
21
|
-
The node is now dead. Fix the recorded launch configuration, then revive it if the work still needs doing.`;await m(
|
|
21
|
+
The node is now dead. Fix the recorded launch configuration, then revive it if the work still needs doing.`;await m(i.node_id,r,{from:i.node_id})}l(q,"surfaceRecoveryFailure");function G(i){return i?.cycle_pending!==!0}l(G,"retryResumeMode");function H(i,e,t=!0){return i===null||i.status==="done"||i.status==="canceled"||i.status==="dead"?"forget":i.intent==="refresh"?"respawn-fresh":R(i)?"dormant":i.lifecycle==="resident"&&!e&&!t&&i.pi_session_id!=null?"release-idle":i.pi_session_id!=null?G(i)?"respawn-resume":"respawn-cycle":e||i.fork_from!=null?"respawn-fresh":"boot-failure"}l(H,"classifyDeadNode");const Y=3e4;class le{static{l(this,"DaemonFleet")}#n;#o;#i;#l;#e=new Map;#t=new Set;#a=new Set;#r=new Map;#c=Number.NEGATIVE_INFINITY;constructor(e){this.#n=e.epoch,this.#o=e.enqueue,this.#i=e.now??Date.now,this.#l=e.probeOnline??(()=>A())}epoch(){return this.#n}register(e,t){if(this.#e.has(e))throw new Error(`fleet: ${e} already has a live broker entry \u2014 refusing a second launch (programming error)`);if(t.pid===null)throw new Error(`fleet: refusing to register ${e} with no pid`);this.#t.delete(e),this.#r.delete(e),this.#e.set(e,{pid:t.pid,handle:t})}has(e){return this.#e.has(e)}isClaimed(e){return this.#e.has(e)||this.#t.has(e)}get(e){return this.#e.get(e)}size(){return this.#e.size}occupancy(){return this.#e.size+this.#t.size}reserveSlot(e){if(this.#t.has(e)||this.#e.has(e))return!0;const{automaticReviveCap:t}=D();if(this.occupancy()<t)return this.#t.add(e),!0;const r=this.#i();return r-this.#c>=Y&&(this.#c=r,c({level:"warn",event:"broker.capacity.revive_deferred",fields:{live_count:this.occupancy(),hard_cap:t}})),!1}releaseReservation(e){this.#t.delete(e)}entries(){return this.#e.entries()}interruptForProfilePause(e,t=this.#e.get(e)?.pid){if(t!==void 0){this.#a.add(e);try{process.kill(t,"SIGTERM")}catch{}}}hasProfilePauseInterruption(e){return this.#a.has(e)}forget(e){this.#e.delete(e),this.#t.delete(e),this.#r.delete(e)}async onChildExit(e,t,r){r&&await $(r),this.#e.delete(e),this.#o(async()=>{const s=await w(e),a=s?.launched_at==null?Number.NaN:Date.parse(s.launched_at),n=Number.isFinite(a)?Math.max(0,this.#i()-a):null,d=s?.respawn_failures??0;s?.status==="done"||s?.status==="canceled"||s?.status==="dead"?this.#r.delete(e):this.#r.set(e,t),this.#u(e,t,n,d)})}async deliverExit(e,t){await this.onChildExit(e,t)}async applyDeadRowPolicy(e){const t=this.#r.get(e);try{await this.#f(e,t)}finally{this.#r.get(e)===t&&this.#r.delete(e)}}async terminalizeIfStillNonTerminal(e,t,r,s,a){const n=await w(e);return n===null||n.status==="done"||n.status==="canceled"||n.status==="dead"?!1:(await this.#s(e,n,{event:t,reason:s,detail:a,wake:`Child crashed \u2014 ${p(n)} (${e}) could not be relaunched and is now dead. It stays dead until you revive it \u2014 \`crtr node lifecycle revive ${e}\`.`,surface:l(()=>q(n,r),"surface")}),!0)}dispose(){}#u(e,t,r,s){c({level:"info",event:"broker.exit.observed",...o(e)?{node_id:e}:{},fields:{...o(e)?{}:{affected_node_id:e},code:t.code,signal:t.signal,uptime_ms:r,consecutive_failures:s}})}async#f(e,t){return this.#h(e,t)}async#h(e,t){const r=await w(e);if(r!==null&&T(r.profile_id))return await h(e),"forget";if(this.#a.delete(e))return await h(e),"forget";if(L(e))return"dormant";const s=(await N(e))?.interrupted===!0;if(t?.oomKilled===!0&&r!==null&&r.status!=="done"&&r.status!=="canceled"&&r.status!=="dead")return await h(e),await this.#s(e,r,{event:"broker.out_of_memory",reason:"out_of_memory",detail:{schema:"crtr.node-outcome-detail/v1",message:b(r)},wake:`Child out of memory \u2014 ${p(r)} (${e}) used more memory than its app is allowed and is now dead. It is not restarted automatically. Revive it with \`crtr node lifecycle revive ${e}\` once the work needs less memory or the cap is raised (\`crtr sys limits set\`).`,surface:l(async()=>{await m(e,b(r),{from:e})},"surface")}),"forget";const a=H(r,s,await C(e));switch(a){case"forget":await h(e);break;case"dormant":await h(e);break;case"release-idle":await h(e),await v(e,"release"),c({level:"info",event:"broker.recovery.released",...o(e)?{node_id:e}:{},fields:{...o(e)?{}:{affected_node_id:e}}});break;case"boot-failure":await this.#s(e,r,{event:"broker.boot.failed",reason:"boot_failed",detail:{schema:"crtr.node-outcome-detail/v1",message:await _(r,t)},wake:`Child crashed \u2014 ${p(r)} (${e}) exited before its session ever came up and is now dead. It stays dead until you revive it \u2014 \`crtr node lifecycle revive ${e}\`.`,surface:l(()=>y(r,t),"surface")});break;case"respawn-fresh":case"respawn-cycle":case"respawn-resume":await this.#d(e,r,a,s);break}return a}async#d(e,t,r,s){const a=await k(e);if(a===null)return;const n=a.respawn_failures??0;if(!await this.#l()){await F(e,n,this.#i()),c({level:"info",event:"broker.respawn.offline_deferred",...o(e)?{node_id:e}:{},fields:{...o(e)?{}:{affected_node_id:e},action:r,retry_in_ms:S,consecutive_failures:n}});return}const d=a.respawn_not_before==null,f=d?await O(a,this.#i()):{failures:n,notBefore:a.respawn_not_before,exhausted:n>=M};if(f.exhausted){const u=`Child crashed \u2014 ${p(t)} (${e}) kept dying without settling a turn (${f.failures} consecutive launches) and is now dead. It stays dead until you revive it \u2014 \`crtr node lifecycle revive ${e}\`.`;await this.#s(e,t,{event:"broker.respawn.exhausted",reason:"crash_looped",detail:{schema:"crtr.node-outcome-detail/v1",message:u,respawn_failures:f.failures},wake:u,...t.pi_session_id!=null?{surface:l(()=>W(t),"surface")}:{}});return}if(d&&f.notBefore!==null){c({level:"info",event:"broker.respawn.deferred",...o(e)?{node_id:e}:{},fields:{...o(e)?{}:{affected_node_id:e},action:r,backoff_ms:z(f.failures),consecutive_failures:f.failures}});return}c({level:"info",event:"broker.respawn.started",...o(e)?{node_id:e}:{},fields:{...o(e)?{}:{affected_node_id:e},action:r,consecutive_failures:f.failures}});try{await B(e,{capacity:"freeze",resume:r==="respawn-resume",wakeReason:r==="respawn-resume"&&s?"runtime-restart-abort":void 0,recovery:!0})}catch(u){c({level:"error",event:"broker.respawn.failed",...o(e)?{node_id:e}:{},error:u,fields:{...o(e)?{}:{affected_node_id:e},action:r}}),await this.terminalizeIfStillNonTerminal(e,"broker.respawn.refused",u,"launch_failed",{schema:"crtr.node-outcome-detail/v1",message:u instanceof Error?u.message:String(u)})}}async#s(e,t,r){c({level:"error",event:r.event,...o(e)?{node_id:e}:{fields:{affected_node_id:e}}}),await v(e,"crash",{reason:r.reason,outcome:{detail:r.detail}});try{await(r.surface??(()=>y(t)))()}catch(s){c({level:"error",event:"broker.boot_failure_surface.failed",...o(e)?{node_id:e}:{fields:{affected_node_id:e}},error:s})}await E(e,"notice.crash",r.wake,{reason:"child-crashed",child:e})}}export{le as DaemonFleet,H as classifyDeadNode,G as retryResumeMode,y as surfaceBootFailure};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
var _=Object.defineProperty;var r=(t,e)=>_(t,"name",{value:e,configurable:!0});import{getRequest as y,getRequestByInboxTicket as b,presentationDir as q}from"../../core/human/requests.js";import{buildPageSummary as v}from"../../core/human/summary.js";import{validateFinalPageResponses as $}from"../../core/human/tickets.js";import{composeHumanCompletion as j}from"../../core/human/completion.js";import{describePageAnswer as k}from"../../core/human/answer.js";import{renderAnswerText as S}from"../../core/human/answer-text.js";import{readPageFeedback as T}from"../../core/human/feedback.js";import{pageDocumentSha256 as A}from"../../core/human/feedback-companion.js";import{pagePath as N}from"../../core/human/convention.js";import{retireCompanion as f}from"../companion-retire.js";import{settleHumanRequest as
|
|
2
|
-
`)[0]??"";return n.length>e?`${n.slice(0,e-1)}\u2026`:n}r(O,"firstLine");function x(t){try{return c(t).title}catch{return}}r(x,"pageTitle");function
|
|
1
|
+
var _=Object.defineProperty;var r=(t,e)=>_(t,"name",{value:e,configurable:!0});import{getRequest as y,getRequestByInboxTicket as b,presentationDir as q}from"../../core/human/requests.js";import{buildPageSummary as v}from"../../core/human/summary.js";import{validateFinalPageResponses as $}from"../../core/human/tickets.js";import{composeHumanCompletion as j}from"../../core/human/completion.js";import{describePageAnswer as k}from"../../core/human/answer.js";import{renderAnswerText as S}from"../../core/human/answer-text.js";import{readPageFeedback as T}from"../../core/human/feedback.js";import{pageDocumentSha256 as A}from"../../core/human/feedback-companion.js";import{pagePath as N}from"../../core/human/convention.js";import{retireCompanion as f}from"../companion-retire.js";import{settleHumanRequest as w}from"./settle.js";async function d(t){const e=await y(t)??await b(t);if(e===null||e.kind!=="page")throw new Error(`unknown page request: ${t}`);return e}r(d,"requestForTicket");function c(t){try{const e=JSON.parse(t.specification_json);if(typeof e!="object"||e===null)throw new Error("not an object");return e}catch(e){throw new Error(`corrupt page specification: ${t.request_id}`,{cause:e})}}r(c,"manifest");function u(t,e){if(t.action_json!==null)try{const n=JSON.parse(t.action_json);if(n.schema!=="crtr.human-action-binding/v1"||!Array.isArray(n.argv)||typeof n.cwd!="string")throw new Error("invalid binding");return{adapter:{adapter:"subprocess",argv:n.argv,cwd:n.cwd,node_id:t.requester_node_id,...n.app?{app:n.app}:{}},bodyJson:j({requestId:t.request_id,result:e,binding:n,source:c(t).source??{}})}}catch(n){throw new Error(`corrupt frozen completion action: ${t.request_id}`,{cause:n})}}r(u,"completionAction");function O(t,e=80){const n=t.split(`
|
|
2
|
+
`)[0]??"";return n.length>e?`${n.slice(0,e-1)}\u2026`:n}r(O,"firstLine");function x(t){try{return c(t).title}catch{return}}r(x,"pageTitle");async function h(t){let e;try{const n=await T(t.request_dir);if(n.companionNodeId===void 0)return"";e=[],n.firstCommentedSha256!==void 0&&await A(t.request_dir)!==n.firstCommentedSha256&&e.push(`The page changed during feedback: the person commented on it and its companion conversation (node ${n.companionNodeId}) revised it in place. Reread the final page at ${N(q(t),c(t).dialect)} before interpreting this outcome.`);const o=n.comments.filter(i=>i.status==="open");if(o.length>0){const i=o.map(s=>[...s.quote.split(`
|
|
3
3
|
`).map(a=>`> ${a}`),s.note].join(`
|
|
4
4
|
`));e.push([`Feedback left unresolved at settlement \u2014 the companion conversation (node ${n.companionNodeId}) had not dealt with these items:`,...i].join(`
|
|
5
5
|
|
|
@@ -7,4 +7,4 @@ var _=Object.defineProperty;var r=(t,e)=>_(t,"name",{value:e,configurable:!0});i
|
|
|
7
7
|
|
|
8
8
|
${e.join(`
|
|
9
9
|
|
|
10
|
-
`)}`}r(
|
|
10
|
+
`)}`}r(h,"feedbackAddendum");async function E(t,e){const n=k(c(t),e.responses,{completedAt:e.completedAt});return S(n)+await h(t)}r(E,"answerBody");async function J(t,e,n){const o=x(t),i=o===void 0?`the human interaction ${t.request_id}`:`\u201C${o}\u201D`,s=n!==void 0&&n!==""?n:"no reason was given";return(e?`The user dismissed ${i} without answering \u2014 a deliberate \u201Cno, I'm not answering this.\u201D Treat it as a rejection: no response will arrive, no partial answer exists, and the same ask must not be raised again.`:`${o===void 0?`The human interaction ${t.request_id}`:`The page \u201C${o}\u201D`} was canceled \u2014 ${s}. No response will arrive, and any partial answers the user had entered were discarded unsent.`)+await h(t)}r(J,"cancelBody");function g(t,e,n,o){if(t.requester_node_id!==null)return{label:O(n),disposition:e,body_json:{body:n,result:o}}}r(g,"notification");function l(t){return t.companion_node_id===null?void 0:{retire:r(async(e,n)=>{await f(e,n)},"retire")}}r(l,"retire");async function Q(t,e,n={}){return(await P(t,e,n)).result}r(Q,"resolvePageTicket");async function P(t,e,n={}){const o=await d(t),i=c(o),s=$(i,e),a={schema:"crtr.page-response/v1",kind:"page",responses:s,summary:v(i,s),completedAt:n.completedAt??new Date().toISOString(),...n.actor===void 0?{}:{actor:n.actor}},m=await w({request_id:o.request_id,outcome:"answered",result_json:JSON.stringify(a),notification:r(async p=>g(p,"human-answer",await E(p,a),a),"notification"),...u(o,a)===void 0?{}:{completion_action:u(o,a)},...l(o)===void 0?{}:{post_commit:l(o)}});if(m.outcome==="already_settled"){if(m.request.result_json===null)throw new Error(`settled page request lacks a result: ${o.request_id}`);return{outcome:"already_settled",result:JSON.parse(m.request.result_json)}}return{outcome:"settled",result:a}}r(P,"answerPageTicket");async function U(t,e){const n=await d(t),i={schema:"humanloop.cancel/v1",kind:"canceled",canceledAt:new Date().toISOString(),...e.reason===void 0?{}:{reason:e.reason},...e.actor===void 0?{}:{actor:e.actor},...e.disposition===void 0?{}:{disposition:e.disposition}},s=await w({request_id:n.request_id,outcome:e.disposition==="dismissed"?"dismissed":"canceled",result_json:JSON.stringify(i),notification:r(async a=>g(a,"human-canceled",await J(a,e.disposition==="dismissed",e.reason),i),"notification"),...u(n,i)===void 0?{}:{completion_action:u(n,i)},...l(n)===void 0?{}:{post_commit:l(n)}});if(s.outcome==="already_settled"){if(s.request.result_json===null)throw new Error(`settled page request lacks a result: ${n.request_id}`);return{outcome:"already_settled",result:JSON.parse(s.request.result_json)}}return{outcome:"settled",result:i}}r(U,"cancelHumanTicket");async function V(t){return(await d(t)).state==="settled"}r(V,"deliverTerminalResult");async function W(t,e){const n=await d(t);n.companion_node_id!==null&&await f(n.companion_node_id,e)}r(W,"settleFeedbackCompanion");export{P as answerPageTicket,U as cancelHumanTicket,V as deliverTerminalResult,Q as resolvePageTicket,W as settleFeedbackCompanion};
|
|
@@ -14,7 +14,7 @@ export interface SettleHumanRequestInput {
|
|
|
14
14
|
outcome: HumanRequestOutcome;
|
|
15
15
|
result_json: string;
|
|
16
16
|
settled_at?: string;
|
|
17
|
-
notification?: SettlementNotification | ((request: HumanRequestRecord) => SettlementNotification | undefined);
|
|
17
|
+
notification?: SettlementNotification | ((request: HumanRequestRecord) => Promise<SettlementNotification | undefined> | SettlementNotification | undefined);
|
|
18
18
|
completion_action?: {
|
|
19
19
|
adapter: DaemonActionAdapter;
|
|
20
20
|
bodyJson: unknown;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var u=Object.defineProperty;var d=(e,o)=>u(e,"name",{value:o,configurable:!0});import{withCanvasWrite as m}from"../../core/canvas/db.js";import{enqueueDaemonAction as f}from"../../core/canvas/daemon-actions.js";import{cancelDelivery as
|
|
1
|
+
var u=Object.defineProperty;var d=(e,o)=>u(e,"name",{value:o,configurable:!0});import{withCanvasWrite as m}from"../../core/canvas/db.js";import{enqueueDaemonAction as f}from"../../core/canvas/daemon-actions.js";import{cancelDelivery as w,enqueueNodeMail as p}from"../../core/feed/messages.js";import{getRequest as l,markCompanionRetired as y,markProjected as q,markProjectionError as v,setSettlementDeliveryMarksLocked as j,settleRequestLocked as h}from"../../core/human/requests.js";import{appendQuestionAnswered as k}from"../../core/runs/questions.js";import{notifyProviderApproval as b}from"../../core/providers/approval.js";async function x(e){const o=await m(async n=>{const _=e.settled_at??new Date().toISOString(),t=await h(n,{request_id:e.request_id,outcome:e.outcome,result_json:e.result_json,settled_at:_});if(t===null){const c=await l(e.request_id);if(c===null)throw new Error(`human request disappeared while settling: ${e.request_id}`);return{outcome:"already_settled",request:c}}const i=typeof e.notification=="function"?await e.notification(t):e.notification;if(t.requester_node_id!==null&&i===void 0)throw new Error(`request ${t.request_id} needs a requester notification`);if(t.action_json!==null&&t.kind==="page"&&e.completion_action===void 0)throw new Error(`request ${t.request_id} needs its frozen completion action`);if(t.kind==="review"&&t.projected_at===null&&e.post_commit?.project===void 0)throw new Error(`review ${t.request_id} needs a projection effect`);if(t.companion_node_id!==null&&t.companion_retired_at===null&&e.post_commit?.retire===void 0)throw new Error(`request ${t.request_id} needs a companion retirement effect`);let a=null,s=null;if(t.requester_node_id!==null){if(i===void 0)throw new Error(`request ${t.request_id} needs a requester notification`);a=(await p(t.requester_node_id,{kind:"completed",label:i.label,senderName:"crtrd",...i.body_ref===void 0?{}:{bodyRef:i.body_ref},...i.body_json===void 0?{}:{bodyJson:i.body_json},disposition:i.disposition,urgency:"normal",wake:1})).deliveryId}t.action_json!==null&&e.completion_action!==void 0&&t.kind==="page"&&(s=await f({adapter:e.completion_action.adapter,bodyJson:e.completion_action.bodyJson,idempotencyKey:`human-action:${t.inbox_ticket_id}`})),t.submit_note_delivery_id!==null&&await w(t.submit_note_delivery_id),await j(n,t.request_id,{settlement_delivery_id:a,action_delivery_id:s});const r=await l(t.request_id);if(r===null)throw new Error(`settled human request disappeared: ${t.request_id}`);return await k(n,r),{outcome:"settled",request:r}});return o.outcome==="settled"&&(b(o.request.request_id),e.post_commit!==void 0&&await g(o.request,e.post_commit)),o}d(x,"settleHumanRequest");async function g(e,o){if(e.kind==="review"&&e.projected_at===null&&o.project!==void 0)try{await o.project(e),await q(e.request_id,new Date().toISOString())}catch(n){await v(e.request_id,n instanceof Error?n.message:String(n))}if(e.companion_node_id!==null&&e.companion_retired_at===null&&o.retire!==void 0)try{await o.retire(e.companion_node_id,e.outcome==="canceled"||e.outcome==="dismissed"?"canceled":"approved"),await y(e.request_id,new Date().toISOString())}catch{}}d(g,"projectAndRetire");export{g as projectAndRetire,x as settleHumanRequest};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var m=Object.defineProperty;var n=(e,o)=>m(e,"name",{value:o,configurable:!0});import{existsSync as p,readdirSync as
|
|
1
|
+
var m=Object.defineProperty;var n=(e,o)=>m(e,"name",{value:o,configurable:!0});import{existsSync as p,readdirSync as w,rmSync as f}from"node:fs";import{reviewsRoot as a}from"../../core/canvas/paths.js";import{listBindingRequests as y,listRequests as u,listUnprojectedReviews as q,markProjectionError as v}from"../../core/human/requests.js";import{projectAndRetire as d}from"./settle.js";function R(e){return e instanceof Error?e.message:String(e)}n(R,"errorText");async function g(){}n(g,"reconcileUndeliveredTickets");async function k(e){let o=0,c=0,s=0,l=0,i=0;for(const t of await y())try{await e.realizeReview(t.request_id),o+=1}catch{i+=1}try{const t=new Set((await u({kind:"review"})).map(r=>r.request_id));if(p(a()))for(const r of w(a(),{withFileTypes:!0}))r.isDirectory()&&!t.has(r.name)&&(f(`${a()}/${r.name}`,{recursive:!0,force:!0}),c+=1)}catch{i+=1}for(const t of await q())try{await d(t,{project:e.projectReview,retire:e.retireCompanion}),s+=1}catch(r){await v(t.request_id,R(r)),i+=1}for(const t of await u({state:"settled"}))if(!(t.companion_node_id===null||t.companion_retired_at!==null))try{await d(t,{retire:e.retireCompanion}),l+=1}catch{i+=1}return{realized:o,collected:c,reprojected:s,retired:l,failed:i}}n(k,"sweepHumanRequests");export{g as reconcileUndeliveredTickets,k as sweepHumanRequests};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
/** Rows changed, or null when this runtime has not joined a directory. */
|
|
2
|
-
export declare function applyJoinedOwner(): {
|
|
1
|
+
/** Rows changed, or null when this runtime has not joined a directory or the rewrite already ran for its owner. */
|
|
2
|
+
export declare function applyJoinedOwner(): Promise<{
|
|
3
3
|
owner: string;
|
|
4
4
|
rows: number;
|
|
5
|
-
} | null
|
|
5
|
+
} | null>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var i=Object.defineProperty;var
|
|
1
|
+
var i=Object.defineProperty;var a=(r,e)=>i(r,"name",{value:e,configurable:!0});import{withCanvasWrite as p}from"../core/canvas/db.js";import{rewriteLocalNodeIdentity as l}from"../core/canvas/canvas.js";import{rewriteLocalNodeTokenIdentity as m}from"../core/canvas/node-tokens.js";import{joinedOwner as w}from"../core/directory/join.js";import{LOCAL_TERMINAL_GRANT_ID as t}from"../core/grants/local.js";import{dropLocalGrantMirror as c}from"../core/grants/mirror.js";import{rewriteLocalRunEventGrantee as u}from"../core/runs/events.js";import{rewriteLocalIdempotencyGrantee as E}from"../core/runs/operations.js";const o="joined_owner_applied";async function d(){const r=w();return r===null?null:await p(async e=>{if((await e.prepare("SELECT value FROM canvas_meta WHERE key = ?").get(o))?.value===r)return null;const n=await l(e,r,t)+await m(e,r,t)+await c(e)+await u(e)+await E(e);return await e.prepare("INSERT INTO canvas_meta (key, value) VALUES (?, ?) ON CONFLICT(key) DO UPDATE SET value = excluded.value").run(o,r),{owner:r,rows:n}})}a(d,"applyJoinedOwner");export{d as applyJoinedOwner};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var
|
|
1
|
+
var u=Object.defineProperty;var r=(e,i)=>u(e,"name",{value:i,configurable:!0});import{getNode as f}from"../../core/canvas/canvas.js";import{cancelCronsOnWake as c}from"../../core/canvas/crons.js";import{withFreshTerminalGuard as s}from"../../core/canvas/canvas.js";import{emitEvent as _}from"../../core/events/emit.js";import{enqueueNodeMail as y}from"../../core/feed/messages.js";import{BrokerUnreachableError as p}from"../../core/runtime/broker-request.js";import{deliverLive as v}from"../../core/runtime/interactive-deliver.js";import{isBrokerLive as l}from"../../core/runtime/model-swap.js";import{reviveNode as w}from"../../core/runtime/revive.js";import{hasNoNaturalCycle as b}from"../../core/runtime/revive-all.js";import{ReviewOperationError as h}from"../../core/review/types.js";import{formatCard as k}from"../../shared/generated-context.js";import{isProfilePaused as N}from"../../core/profiles/manifest.js";function t(e,i){throw new h("delivery_unroutable",i==="origin_missing"?"message target was not found":"message target has no natural delivery cycle",{node_id:e,reason:i})}r(t,"deliveryUnroutable");async function a(e,i){const n=await s(e,b,i);return n.kind==="missing"&&t(e,"origin_missing"),n.kind==="terminal"&&t(e,"no_natural_cycle"),n.result}r(a,"guardRoutable");async function G(e){await a(e.node_id,async()=>{});let i=await f(e.node_id);if(i===null&&t(e.node_id,"origin_missing"),e.mode==="interactive"&&!i.run_id&&!N(i.profile_id)&&l(i))try{return await v(e.node_id,e.runtime===void 0?e.body:k(e.runtime.kind,e.runtime.facts,e.body),{origin:e.from==="human"?{type:"human"}:{type:"runtime",kind:"inbox",entries:[{...e.from==null?{}:{from:e.from},kind:"message",tier:"normal"}]}}),await a(e.node_id,async()=>{}),await c(e.node_id),{entry_id:null,via:"engine",revived:!1}}catch(o){if(!(o instanceof p))throw o}const n=await a(e.node_id,async()=>await y(e.node_id,{senderNodeId:e.from??null,kind:"message",label:e.label,bodyJson:{...e.data,body:e.body},urgency:e.mode==="quiet"?"deferred":"normal",wake:1}));let m=!1,d;if(n.urgency!=="deferred"&&(i=await f(e.node_id),i===null&&t(e.node_id,"origin_missing"),!l(i)))try{const o=await w(e.node_id,{resume:!0,capacity:"freeze"});m=o.launch!==void 0,o.outcome==="frozen"&&(d="capacity_frozen")}catch(o){_({level:"error",event:"message.wake_failed",node_id:e.node_id,error:o,fields:{message_id:n.messageId}})}return{entry_id:n.messageId,via:"inbox",revived:m,...d===void 0?{}:{reason:d}}}r(G,"deliverNodeMessage");export{G as deliverNodeMessage};
|
|
@@ -2,8 +2,8 @@ import type { NodeMeta } from '../core/canvas/types.js';
|
|
|
2
2
|
import type { PendingPark } from './park-pending.js';
|
|
3
3
|
/** A main-session write after parking was armed is durable evidence of live
|
|
4
4
|
* input even when the turn has since settled and the viewer detached. */
|
|
5
|
-
export declare function mainSessionActivitySince(sessionFile: string | null | undefined, startedAt: number): boolean
|
|
5
|
+
export declare function mainSessionActivitySince(sessionFile: string | null | undefined, startedAt: number): Promise<boolean>;
|
|
6
6
|
/** One verdict shared by normal completion and grace expiry. A broker records
|
|
7
7
|
* accepted live input against the process-local marker before it drives Pi, so
|
|
8
8
|
* the verdict cannot race a viewer, live delivery, or durable wake. */
|
|
9
|
-
export declare function shouldParkAfterSummary(nodeId: string, node: Pick<NodeMeta, 'lifecycle' | 'pi_session_file'>, pending: PendingPark): boolean
|
|
9
|
+
export declare function shouldParkAfterSummary(nodeId: string, node: Pick<NodeMeta, 'lifecycle' | 'pi_session_file'>, pending: PendingPark): Promise<boolean>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var
|
|
1
|
+
var n=Object.defineProperty;var e=(r,t)=>n(r,"name",{value:t,configurable:!0});import{conversationIdFromPath as o,conversationStore as f,ConversationNotFoundError as c}from"../core/conversation-store/index.js";import{emitEvent as s}from"../core/events/emit.js";import{hasWakeMailSince as u}from"../core/canvas/deliveries.js";import{readLiveTurn as m}from"../core/canvas/recovery.js";import{parkEvent as l}from"./reconcilers/live-obligation.js";async function v(r,t){if(r==null)return!1;const a=o(r);if(a===null)return!1;try{return(await f().header(a)).mtime>=t}catch(i){return i instanceof c?!1:(s({level:"warn",event:"broker.park.session_activity_scan_failed",error:i}),!0)}}e(v,"mainSessionActivitySince");async function _(r,t,a){return!a.activity&&(await m(r))?.busy!==!0&&!await v(t.pi_session_file,a.startedAt)&&!await u(r,a.startedAt)&&await l(r,t.lifecycle)==="park"}e(_,"shouldParkAfterSummary");export{v as mainSessionActivitySince,_ as shouldParkAfterSummary};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var b=Object.defineProperty;var c=(e,n)=>b(e,"name",{value:n,configurable:!0});import{decodeEnvelope as m,EnvelopeError as v}from"../../core/peer/envelope.js";import{coverGrant as w}from"../../core/grants/cover.js";import{grantFor as g}from"../../core/grants/mirror.js";import{RunError as f}from"../../core/runs/operations.js";const r=c((e,n,o)=>({status:e,code:n,message:o}),"refuse"),l="the envelope does not match its token";function G(e){return async(n,o)=>{const t=c(()=>new f(403,"app_not_granted",`${n.sub} holds no active grant for ${o} on this machine`),"notGranted");if(n.grant===void 0){const i=g(n.sub,o);if(i===null)throw t();return i}try{return await w(n.grant,n.rev??1,o,n.sub,e)}catch(i){throw i instanceof f&&i.status===401?t():i}}}c(G,"mirrorGrantLink");async function L(e,n,o){const t=e.chain[0];if(t===void 0||!t.sub.startsWith("runtime:"))return r(401,"unauthorized","not a machine's token");if(t.sub===o.self())return r(401,"unauthorized","a machine does not call itself");if(e.scope!==void 0)return r(401,"unauthorized","a provider token does not authorize on a machine");const i=o.relation(e.sub);if(i===null)return r(403,"forbidden","no relation reaches this machine");let u;if(n!==void 0){try{u=m(n)}catch(a){return r(400,"invalid_request",a instanceof v?a.message:"invalid envelope")}if(u.act.sub!==t.sub||u.sub!==e.sub)return r(401,"unauthorized",l);if(u.act.act!==void 0&&u.act.act.place===null)return r(400,"invalid_request","the envelope names an app with no run place")}const s=u?.act.act,p=e.chain.slice(1).filter(a=>a.sub.startsWith("app:"));if(p.length>1)return r(401,"unauthorized","the token names more than one app");const d=p[0];if(d!==void 0&&(s===void 0||s.sub!==d.sub))return r(401,"unauthorized",l);const h=d??(s===void 0?void 0:{sub:s.sub});if(h!==void 0)try{await o.grantLink(h,e.sub)}catch(a){if(a instanceof f)return r(a.status,a.code,a.message);throw a}return u===void 0?{principal:{class:"machine",via:t.sub,sub:e.sub}}:s!==void 0?{principal:{class:"forwarded",via:t.sub,sub:e.sub,actor:{kind:"app",app:s.sub,node:s.node,node_scopes:s.node_scopes,place:s.place}}}:i!=="owner"?r(403,"forbidden","only the owner acts as the person"):{principal:{class:"forwarded",via:t.sub,sub:e.sub,actor:{kind:"person"}}}}c(L,"peerAuthority");export{G as mirrorGrantLink,L as peerAuthority};
|
|
1
|
+
var b=Object.defineProperty;var c=(e,n)=>b(e,"name",{value:n,configurable:!0});import{decodeEnvelope as m,EnvelopeError as v}from"../../core/peer/envelope.js";import{coverGrant as w}from"../../core/grants/cover.js";import{grantFor as g}from"../../core/grants/mirror.js";import{RunError as f}from"../../core/runs/operations.js";const r=c((e,n,o)=>({status:e,code:n,message:o}),"refuse"),l="the envelope does not match its token";function G(e){return async(n,o)=>{const t=c(()=>new f(403,"app_not_granted",`${n.sub} holds no active grant for ${o} on this machine`),"notGranted");if(n.grant===void 0){const i=await g(n.sub,o);if(i===null)throw t();return i}try{return await w(n.grant,n.rev??1,o,n.sub,e)}catch(i){throw i instanceof f&&i.status===401?t():i}}}c(G,"mirrorGrantLink");async function L(e,n,o){const t=e.chain[0];if(t===void 0||!t.sub.startsWith("runtime:"))return r(401,"unauthorized","not a machine's token");if(t.sub===o.self())return r(401,"unauthorized","a machine does not call itself");if(e.scope!==void 0)return r(401,"unauthorized","a provider token does not authorize on a machine");const i=o.relation(e.sub);if(i===null)return r(403,"forbidden","no relation reaches this machine");let u;if(n!==void 0){try{u=m(n)}catch(a){return r(400,"invalid_request",a instanceof v?a.message:"invalid envelope")}if(u.act.sub!==t.sub||u.sub!==e.sub)return r(401,"unauthorized",l);if(u.act.act!==void 0&&u.act.act.place===null)return r(400,"invalid_request","the envelope names an app with no run place")}const s=u?.act.act,p=e.chain.slice(1).filter(a=>a.sub.startsWith("app:"));if(p.length>1)return r(401,"unauthorized","the token names more than one app");const d=p[0];if(d!==void 0&&(s===void 0||s.sub!==d.sub))return r(401,"unauthorized",l);const h=d??(s===void 0?void 0:{sub:s.sub});if(h!==void 0)try{await o.grantLink(h,e.sub)}catch(a){if(a instanceof f)return r(a.status,a.code,a.message);throw a}return u===void 0?{principal:{class:"machine",via:t.sub,sub:e.sub}}:s!==void 0?{principal:{class:"forwarded",via:t.sub,sub:e.sub,actor:{kind:"app",app:s.sub,node:s.node,node_scopes:s.node_scopes,place:s.place}}}:i!=="owner"?r(403,"forbidden","only the owner acts as the person"):{principal:{class:"forwarded",via:t.sub,sub:e.sub,actor:{kind:"person"}}}}c(L,"peerAuthority");export{G as mirrorGrantLink,L as peerAuthority};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ApiError } from '../../api/errors.js';
|
|
2
|
-
import type
|
|
2
|
+
import { type CanvasDb } from '../../core/canvas/db.js';
|
|
3
3
|
import type { ObjectRow, Privacy } from '../../core/graph/types.js';
|
|
4
4
|
import { type Envelope, type EnvelopeCaller } from '../../core/peer/envelope.js';
|
|
5
5
|
import { type PeerRequest } from '../../core/peer/client.js';
|
|
@@ -14,7 +14,7 @@ export interface MachineLabel {
|
|
|
14
14
|
export interface ForwardDeps extends Omit<HomeDeps, 'call'> {
|
|
15
15
|
/** Without an envelope the call is the machine's own (`peer.locate`); with one it is made for the caller. */
|
|
16
16
|
call(machine: string, request: PeerRequest, envelope?: Envelope, signal?: AbortSignal): ReturnType<typeof peerCall>;
|
|
17
|
-
envelope(principal: EnvelopeCaller): Envelope
|
|
17
|
+
envelope(principal: EnvelopeCaller): Promise<Envelope>;
|
|
18
18
|
label(machine: string): Promise<MachineLabel>;
|
|
19
19
|
}
|
|
20
20
|
export declare const defaultForwardDeps: ForwardDeps;
|
|
@@ -54,11 +54,11 @@ export declare function envelopeOfForwarded(principal: Extract<RequestPrincipal,
|
|
|
54
54
|
export declare function queryWithoutMachine(ctx: RequestContext): Record<string, string>;
|
|
55
55
|
/** On the home machine: the stub of the node a forwarded app call is made for (created or refreshed from the verified envelope), or null
|
|
56
56
|
* for a person actor, an unanchored app, or a local caller. */
|
|
57
|
-
export declare function callerStub(db:
|
|
57
|
+
export declare function callerStub(db: CanvasDb, ctx: RequestContext): Promise<ObjectRow | null>;
|
|
58
58
|
/** On the calling machine: the node making a call, when the caller is a node (a broker), else null. */
|
|
59
|
-
export declare function callerNode(db:
|
|
59
|
+
export declare function callerNode(db: CanvasDb, ctx: RequestContext): Promise<ObjectRow | null>;
|
|
60
60
|
/** On the calling machine: the stub of an object the home machine answered for. */
|
|
61
|
-
export declare function remoteStub(db:
|
|
61
|
+
export declare function remoteStub(db: CanvasDb, id: string, type: string, machine: string, ref?: {
|
|
62
62
|
kind?: string | null;
|
|
63
63
|
name?: string;
|
|
64
64
|
preview?: string;
|
|
@@ -69,4 +69,4 @@ export declare function remoteStub(db: DatabaseSync, id: string, type: string, m
|
|
|
69
69
|
} | null;
|
|
70
70
|
kind_decl?: KindDeclaration;
|
|
71
71
|
privacy?: Privacy;
|
|
72
|
-
}): ObjectRow
|
|
72
|
+
}): Promise<ObjectRow>;
|