@north-light/cli 0.3.560 → 0.3.562
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/client.d.ts +27 -4
- package/dist/api/client.js +3 -3
- package/dist/api/contract.d.ts +1 -1
- package/dist/api/contract.js +1 -1
- package/dist/api/dto/bash-jobs.d.ts +5 -1
- package/dist/api/dto/broker-ops.d.ts +25 -1
- package/dist/api/dto/charges.d.ts +9 -2
- package/dist/api/dto/delivery.d.ts +26 -2
- package/dist/api/dto/execution-start.d.ts +57 -0
- package/dist/api/dto/execution-start.js +0 -0
- package/dist/api/dto/modelauth.d.ts +5 -0
- package/dist/api/dto/node-records.d.ts +16 -0
- package/dist/api/dto/objects.d.ts +1 -1
- package/dist/api/dto/reports.d.ts +0 -3
- package/dist/api/dto/run-events.d.ts +7 -1
- package/dist/api/dto/settings.d.ts +55 -0
- package/dist/api/dto/settings.js +0 -0
- package/dist/api/index.d.ts +2 -0
- package/dist/api/index.js +1 -1
- package/dist/api/routes.d.ts +11 -0
- package/dist/api/routes.js +1 -1
- package/dist/builtin-memory/crouter-sdk/release-notes.md +4 -0
- package/dist/cli.js +7 -7
- package/dist/clients/attach/chrome/bash-jobs.d.ts +11 -1
- package/dist/clients/attach/chrome/bash-jobs.js +1 -1
- package/dist/clients/attach/chrome/canvas-panels.d.ts +1 -1
- package/dist/clients/attach/chrome/roster.js +6 -4
- package/dist/clients/attach/overlays/auth.js +2 -2
- package/dist/clients/attach/render/chat-view.js +1 -1
- package/dist/clients/attach/viewer.js +550 -567
- package/dist/commands/canvas-config.js +2 -2
- package/dist/commands/canvas-use.js +1 -1
- package/dist/commands/human.js +2 -2
- package/dist/commands/node/bash.js +3 -3
- package/dist/commands/node/create.js +2 -2
- package/dist/commands/person-settings.d.ts +1 -0
- package/dist/commands/person-settings.js +1 -0
- package/dist/commands/pkg/market-manage.d.ts +2 -2
- package/dist/commands/pkg/market-manage.js +1 -1
- package/dist/commands/pkg/plugin-manage.js +13 -13
- package/dist/commands/pkg/shared.js +1 -1
- package/dist/commands/profile/default.js +1 -1
- package/dist/commands/push.js +2 -3
- package/dist/commands/sys/config.js +1 -1
- package/dist/commands/sys/connect.js +1 -1
- package/dist/commands/sys/context/sysprompt.js +2 -2
- package/dist/commands/sys/doctor.js +1 -1
- package/dist/commands/sys/panels/broker-limits-panel.js +1 -1
- package/dist/commands/sys/panels/keybindings-panel.js +1 -1
- package/dist/commands/sys/panels/models-panel.d.ts +8 -2
- package/dist/commands/sys/panels/models-panel.js +1 -1
- package/dist/commands/sys/panels/prefs-panel.d.ts +1 -0
- package/dist/commands/sys/panels/prefs-panel.js +1 -1
- package/dist/commands/sys/panels/profiles-panel.js +1 -1
- package/dist/commands/sys/panels/provider-panel.d.ts +4 -0
- package/dist/commands/sys/panels/provider-panel.js +1 -1
- package/dist/commands/sys/provider-login.js +5 -5
- package/dist/commands/sys/setup-core.js +3 -3
- package/dist/commands/sys/setup-settings-runner.js +1 -1
- package/dist/commands/sys/spend.js +3 -3
- package/dist/commands/sys/update.js +1 -1
- package/dist/core/auth-file.d.ts +11 -19
- package/dist/core/auth-file.js +1 -2
- package/dist/core/auto-update.d.ts +1 -1
- package/dist/core/auto-update.js +4 -4
- package/dist/core/bash-jobs.d.ts +29 -71
- package/dist/core/bash-jobs.js +9 -10
- package/dist/core/blobs/directory.d.ts +3 -0
- package/dist/core/blobs/directory.js +1 -0
- package/dist/core/blobs/fault.d.ts +3 -0
- package/dist/core/blobs/fault.js +1 -0
- package/dist/core/blobs/index.d.ts +21 -0
- package/dist/core/blobs/index.js +1 -0
- package/dist/core/blobs/r2.d.ts +9 -0
- package/dist/core/blobs/r2.js +4 -0
- package/dist/core/bootstrap.d.ts +1 -1
- package/dist/core/bootstrap.js +2 -2
- package/dist/core/canvas/canvas.d.ts +9 -7
- package/dist/core/canvas/canvas.js +8 -8
- package/dist/core/canvas/crons.d.ts +3 -2
- package/dist/core/canvas/crons.js +3 -3
- package/dist/core/canvas/daemon-owner.d.ts +5 -0
- package/dist/core/canvas/daemon-owner.js +1 -1
- package/dist/core/canvas/db.d.ts +10 -9
- package/dist/core/canvas/db.js +4 -4
- package/dist/core/canvas/executions.d.ts +100 -4
- package/dist/core/canvas/executions.js +1 -1
- package/dist/core/canvas/export-sqlite.js +1 -1
- package/dist/core/canvas/focuses.d.ts +4 -0
- package/dist/core/canvas/focuses.js +1 -1
- package/dist/core/canvas/history.js +9 -9
- package/dist/core/canvas/managed-worktree-sweep-candidates.d.ts +2 -1
- package/dist/core/canvas/managed-worktree-sweep-candidates.js +3 -2
- package/dist/core/canvas/node-tokens.d.ts +1 -4
- package/dist/core/canvas/node-tokens.js +3 -3
- package/dist/core/canvas/paths.d.ts +0 -1
- package/dist/core/canvas/paths.js +1 -1
- package/dist/core/canvas/person-state.d.ts +26 -0
- package/dist/core/canvas/person-state.js +1 -0
- package/dist/core/canvas/person.d.ts +3 -10
- package/dist/core/canvas/person.js +7 -7
- package/dist/core/canvas/reconciler-leases.d.ts +12 -0
- package/dist/core/canvas/reconciler-leases.js +8 -0
- package/dist/core/canvas/recovery.d.ts +4 -0
- package/dist/core/canvas/recovery.js +1 -1
- package/dist/core/canvas/schema-pg/003-fleet-removals.sql +1 -1
- package/dist/core/canvas/schema-pg/005-fleet-blobs.sql +13 -0
- package/dist/core/canvas/schema-pg/006-job-rows.sql +20 -0
- package/dist/core/canvas/schema-pg/007-ledger-check.sql +117 -0
- package/dist/core/canvas/schema-version.d.ts +1 -1
- package/dist/core/canvas/schema-version.js +1 -1
- package/dist/core/canvas/sessions.d.ts +8 -11
- package/dist/core/canvas/sessions.js +1 -4
- package/dist/core/canvas/tree.d.ts +4 -2
- package/dist/core/canvas/tree.js +6 -6
- package/dist/core/canvas/types.d.ts +7 -0
- 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/command-plugins/compose.d.ts +1 -1
- package/dist/core/command-plugins/discovery.d.ts +0 -1
- package/dist/core/command-plugins/discovery.js +1 -1
- package/dist/core/command-plugins/help-addenda.js +1 -1
- package/dist/core/command-plugins/presence.d.ts +2 -0
- package/dist/core/command-plugins/presence.js +1 -1
- package/dist/core/config.d.ts +16 -15
- package/dist/core/config.js +1 -1
- package/dist/core/conversation-store/client-worker.js +1 -1
- package/dist/core/conversation-store/client.js +2 -2
- package/dist/core/conversation-store/index.d.ts +9 -11
- package/dist/core/conversation-store/index.js +1 -1
- package/dist/core/conversation-store/patch.js +1 -1
- package/dist/core/conversation-store/row-store.d.ts +14 -0
- package/dist/core/conversation-store/row-store.js +13 -0
- package/dist/core/directory/join.js +1 -1
- package/dist/core/env-name.d.ts +1 -0
- package/dist/core/env-name.js +1 -1
- package/dist/core/environment-recipe.d.ts +15 -0
- package/dist/core/environment-recipe.js +1 -0
- package/dist/core/environments.js +1 -1
- package/dist/core/events/emit.js +2 -2
- package/dist/core/events/run-event-chunks.d.ts +25 -0
- package/dist/core/events/run-event-chunks.js +5 -0
- package/dist/core/feed/messages.js +5 -5
- package/dist/core/grants/mirror.d.ts +15 -0
- package/dist/core/grants/mirror.js +15 -3
- package/dist/core/grants/on-sync.d.ts +9 -5
- package/dist/core/grants/on-sync.js +1 -1
- package/dist/core/grants/remove.d.ts +1 -6
- package/dist/core/grants/remove.js +1 -1
- package/dist/core/grants/sync.js +1 -1
- package/dist/core/grants/watch.d.ts +15 -9
- package/dist/core/grants/watch.js +1 -1
- package/dist/core/graph/custom.js +8 -8
- package/dist/core/graph/jobs.d.ts +83 -5
- package/dist/core/graph/jobs.js +11 -2
- package/dist/core/graph/kinds/job.js +2 -2
- package/dist/core/graph/names.js +7 -7
- package/dist/core/graph/objects.d.ts +5 -1
- package/dist/core/graph/objects.js +11 -11
- package/dist/core/graph/reader.d.ts +3 -0
- package/dist/core/graph/reader.js +3 -3
- package/dist/core/graph/repo-sync/identity.d.ts +3 -1
- package/dist/core/graph/repo-sync/identity.js +1 -1
- package/dist/core/graph/repo-sync/repos.d.ts +1 -1
- package/dist/core/graph/repo-sync/repos.js +2 -2
- package/dist/core/graph/repo-sync/sync.js +2 -2
- package/dist/core/installed-plugins.js +1 -1
- package/dist/core/keybindings/persistence.d.ts +1 -1
- package/dist/core/keybindings/persistence.js +1 -1
- package/dist/core/layout-migrate/loose-keys.d.ts +1 -1
- package/dist/core/layout-migrate/loose-keys.js +1 -1
- package/dist/core/ledger/account.d.ts +12 -0
- package/dist/core/ledger/account.js +2 -0
- package/dist/core/ledger/charges.d.ts +2 -2
- package/dist/core/ledger/charges.js +1 -1
- package/dist/core/ledger/check.d.ts +5 -1
- package/dist/core/ledger/check.js +1 -7
- package/dist/core/ledger/chunks.d.ts +8 -0
- package/dist/core/ledger/chunks.js +2 -0
- package/dist/core/ledger/index.d.ts +2 -1
- package/dist/core/ledger/index.js +1 -1
- package/dist/core/ledger/infra-allowance.d.ts +9 -0
- package/dist/core/ledger/infra-allowance.js +1 -0
- package/dist/core/ledger/limits.js +3 -3
- package/dist/core/ledger/payer.d.ts +1 -1
- package/dist/core/ledger/payer.js +1 -1
- package/dist/core/ledger/read.d.ts +14 -4
- package/dist/core/ledger/read.js +2 -3
- package/dist/core/ledger/totals.d.ts +5 -16
- package/dist/core/ledger/totals.js +4 -4
- package/dist/core/ledger/types.d.ts +12 -3
- package/dist/core/llm/run.js +2 -2
- package/dist/core/managed-providers.d.ts +72 -0
- package/dist/core/managed-providers.js +1 -0
- package/dist/core/model-auth/api-credential-store.d.ts +10 -0
- package/dist/core/model-auth/api-credential-store.js +1 -0
- package/dist/core/model-auth/daemon-login.d.ts +1 -1
- package/dist/core/model-auth/daemon-login.js +1 -1
- package/dist/core/model-auth/flows.d.ts +5 -4
- package/dist/core/model-auth/flows.js +1 -1
- package/dist/core/model-auth/handoff-jti.d.ts +3 -4
- package/dist/core/model-auth/handoff-jti.js +1 -1
- package/dist/core/model-auth/readiness.js +1 -1
- package/dist/core/model-config.d.ts +1 -1
- package/dist/core/model-config.js +1 -1
- package/dist/core/model-routes-pool.d.ts +14 -0
- package/dist/core/model-routes-pool.js +1 -0
- package/dist/core/model-routes.d.ts +11 -16
- package/dist/core/model-routes.js +1 -1
- package/dist/core/peer/ingest.d.ts +2 -0
- package/dist/core/peer/ingest.js +1 -1
- package/dist/core/peer/stubs.d.ts +8 -0
- package/dist/core/peer/stubs.js +1 -1
- package/dist/core/permissions/evaluator.d.ts +7 -2
- package/dist/core/permissions/evaluator.js +2 -2
- package/dist/core/plugin-env.js +1 -1
- package/dist/core/pool-credential-store.d.ts +2 -5
- package/dist/core/pool-credential-store.js +1 -1
- package/dist/core/profiles/app-env-store.d.ts +5 -5
- package/dist/core/profiles/app-env-store.js +1 -2
- package/dist/core/profiles/default-binding.d.ts +5 -5
- package/dist/core/profiles/default-binding.js +1 -1
- package/dist/core/profiles/env-store.d.ts +10 -21
- package/dist/core/profiles/env-store.js +1 -2
- package/dist/core/profiles/manifest.d.ts +14 -18
- package/dist/core/profiles/manifest.js +1 -1
- package/dist/core/profiles/relocate.js +1 -1
- package/dist/core/profiles/select.js +21 -21
- package/dist/core/provider-credential.d.ts +1 -1
- package/dist/core/provider-credential.js +1 -1
- package/dist/core/provider-management.d.ts +3 -4
- package/dist/core/provider-management.js +1 -1
- package/dist/core/providers/bundles.js +2 -2
- package/dist/core/providers/call.d.ts +3 -34
- package/dist/core/providers/description.d.ts +34 -0
- package/dist/core/providers/description.js +0 -0
- package/dist/core/providers/token-cache.d.ts +14 -14
- package/dist/core/providers/token-cache.js +1 -1
- package/dist/core/review/companion.js +1 -1
- package/dist/core/runs/activity.d.ts +1 -1
- package/dist/core/runs/activity.js +1 -1
- package/dist/core/runs/events.d.ts +7 -5
- package/dist/core/runs/events.js +2 -6
- package/dist/core/runs/operations.d.ts +1 -1
- package/dist/core/runs/operations.js +6 -6
- package/dist/core/runtime/bearings.js +1 -1
- package/dist/core/runtime/broker/attachments-fetch.d.ts +5 -0
- package/dist/core/runtime/broker/attachments-fetch.js +1 -0
- package/dist/core/runtime/broker/bash-job-launch.d.ts +4 -2
- package/dist/core/runtime/broker/bash-job-launch.js +1 -1
- package/dist/core/runtime/broker/boot-state.d.ts +9 -0
- package/dist/core/runtime/broker/boot-state.js +1 -0
- package/dist/core/runtime/broker/cli-relay.d.ts +2 -1
- package/dist/core/runtime/broker/cli-relay.js +1 -1
- package/dist/core/runtime/broker/client-registry.d.ts +3 -3
- package/dist/core/runtime/broker/daemon-ops.d.ts +10 -1
- package/dist/core/runtime/broker/daemon-ops.js +1 -1
- package/dist/core/runtime/broker/fault-retry.d.ts +2 -0
- package/dist/core/runtime/broker/fault-retry.js +1 -1
- package/dist/core/runtime/broker/frame-engine-control.js +1 -1
- package/dist/core/runtime/broker/held-deferred-inbox.d.ts +3 -0
- package/dist/core/runtime/broker/held-deferred-inbox.js +1 -1
- package/dist/core/runtime/broker/job-reporter.d.ts +18 -0
- package/dist/core/runtime/broker/job-reporter.js +2 -0
- package/dist/core/runtime/broker/model-adapter.d.ts +3 -0
- package/dist/core/runtime/broker/model-adapter.js +3 -2
- package/dist/core/runtime/broker/signal-stream.js +1 -1
- package/dist/core/runtime/broker/spilled-body.d.ts +5 -0
- package/dist/core/runtime/broker/spilled-body.js +1 -0
- package/dist/core/runtime/broker/summaries-post.d.ts +5 -0
- package/dist/core/runtime/broker/summaries-post.js +1 -0
- package/dist/core/runtime/broker/tool-groups.d.ts +3 -0
- package/dist/core/runtime/broker/tool-groups.js +1 -1
- package/dist/core/runtime/broker/turn-replies.d.ts +1 -0
- package/dist/core/runtime/broker/turn-replies.js +1 -1
- package/dist/core/runtime/broker-persona-guidance.js +2 -2
- package/dist/core/runtime/broker.js +1 -1
- package/dist/core/runtime/deliver-live.js +1 -1
- package/dist/core/runtime/first-boot-rows.d.ts +8 -0
- package/dist/core/runtime/first-boot-rows.js +2 -0
- package/dist/core/runtime/fleet.d.ts +13 -12
- package/dist/core/runtime/front-door-login.js +1 -1
- package/dist/core/runtime/front-door.js +6 -6
- package/dist/core/runtime/headless-pi.js +1 -1
- package/dist/core/runtime/host.d.ts +14 -3
- package/dist/core/runtime/host.js +3 -3
- package/dist/core/runtime/invocation.d.ts +6 -0
- package/dist/core/runtime/kickoff.d.ts +2 -14
- package/dist/core/runtime/kickoff.js +17 -19
- package/dist/core/runtime/launch-config-worker.js +1 -1
- package/dist/core/runtime/launch.js +2 -2
- package/dist/core/runtime/model-registry.js +1 -1
- package/dist/core/runtime/node-read.d.ts +4 -6
- package/dist/core/runtime/node-read.js +3 -3
- package/dist/core/runtime/nodes.js +1 -1
- package/dist/core/runtime/outcome-document.d.ts +0 -1
- package/dist/core/runtime/outcome-document.js +1 -1
- package/dist/core/runtime/output-result.d.ts +15 -0
- package/dist/core/runtime/output-result.js +5 -0
- package/dist/core/runtime/placement.d.ts +17 -1
- package/dist/core/runtime/placement.js +1 -1
- package/dist/core/runtime/provider-credential-gate.d.ts +6 -2
- package/dist/core/runtime/provider-credential-gate.js +2 -2
- package/dist/core/runtime/recovery-hold.d.ts +21 -2
- package/dist/core/runtime/recovery-hold.js +2 -1
- package/dist/core/runtime/recycle.js +1 -1
- package/dist/core/runtime/reset.js +1 -1
- package/dist/core/runtime/revive.d.ts +2 -2
- package/dist/core/runtime/revive.js +2 -2
- package/dist/core/runtime/runner/blaxel/client.d.ts +81 -0
- package/dist/core/runtime/runner/blaxel/client.js +1 -0
- package/dist/core/runtime/runner/blaxel/image-build.d.ts +74 -0
- package/dist/core/runtime/runner/blaxel/image-build.js +5 -0
- package/dist/core/runtime/runner/blaxel/runner.d.ts +41 -0
- package/dist/core/runtime/runner/blaxel/runner.js +3 -0
- package/dist/core/runtime/runner/index.d.ts +8 -0
- package/dist/core/runtime/runner/index.js +1 -0
- package/dist/core/runtime/runner/process.d.ts +11 -0
- package/dist/core/runtime/runner/process.js +1 -0
- package/dist/core/runtime/runner/types.d.ts +95 -0
- package/dist/core/runtime/runner/types.js +0 -0
- package/dist/core/runtime/situational-context.d.ts +3 -6
- package/dist/core/runtime/situational-context.js +2 -2
- package/dist/core/runtime/situational-live.js +1 -1
- package/dist/core/runtime/spawn-env-rows.d.ts +5 -0
- package/dist/core/runtime/spawn-env-rows.js +1 -0
- package/dist/core/runtime/spawn-env.d.ts +4 -18
- package/dist/core/runtime/spawn-env.js +1 -1
- package/dist/core/runtime/spawn.js +2 -2
- package/dist/core/runtime/stop-guard.d.ts +1 -1
- package/dist/core/runtime/stop-guard.js +2 -8
- package/dist/core/runtime/structured-output.d.ts +0 -67
- package/dist/core/runtime/structured-output.js +3 -8
- package/dist/core/runtime/tmux-driver.d.ts +8 -0
- package/dist/core/runtime/tmux-driver.js +6 -6
- package/dist/core/runtime/view-socket.d.ts +20 -0
- package/dist/core/runtime/view-socket.js +3 -1
- package/dist/core/runtime/warm-pool.d.ts +13 -1
- package/dist/core/runtime/warm-pool.js +1 -1
- package/dist/core/scoped-state/legacy-profiles.d.ts +11 -0
- package/dist/core/scoped-state/legacy-profiles.js +1 -0
- package/dist/core/scoped-state/materialized-plugins.d.ts +18 -0
- package/dist/core/scoped-state/materialized-plugins.js +1 -0
- package/dist/core/scoped-state/migrate.d.ts +8 -1
- package/dist/core/scoped-state/migrate.js +3 -3
- package/dist/core/scoped-state/person-rows.d.ts +10 -0
- package/dist/core/scoped-state/person-rows.js +6 -0
- package/dist/core/scoped-state/person-store.d.ts +72 -0
- package/dist/core/scoped-state/person-store.js +1 -0
- package/dist/core/secrets/blaxel-launch.d.ts +24 -0
- package/dist/core/secrets/blaxel-launch.js +4 -0
- package/dist/core/secrets/blaxel-register.d.ts +2 -0
- package/dist/core/secrets/blaxel-register.js +1 -0
- package/dist/core/secrets/env-rows.d.ts +17 -0
- package/dist/core/secrets/env-rows.js +4 -0
- package/dist/core/secrets/environment-owner.d.ts +8 -0
- package/dist/core/secrets/environment-owner.js +1 -0
- package/dist/core/secrets/environment-secrets.d.ts +14 -0
- package/dist/core/secrets/environment-secrets.js +1 -0
- package/dist/core/secrets/index.d.ts +2 -0
- package/dist/core/secrets/index.js +1 -0
- package/dist/core/secrets/key.d.ts +3 -0
- package/dist/core/secrets/key.js +2 -0
- package/dist/core/secrets/seal.d.ts +18 -0
- package/dist/core/secrets/seal.js +1 -0
- package/dist/core/spaces/mounts.d.ts +1 -1
- package/dist/core/spaces/mounts.js +1 -1
- package/dist/core/spaces/process.d.ts +1 -1
- package/dist/core/spaces/stop.d.ts +7 -5
- package/dist/core/spaces/stop.js +2 -2
- package/dist/core/spaces/users.d.ts +2 -1
- package/dist/core/spaces/users.js +1 -1
- package/dist/core/storage/attachments.d.ts +11 -8
- package/dist/core/storage/attachments.js +1 -1
- package/dist/core/storage/tables.d.ts +4 -0
- package/dist/core/storage/tables.js +3 -3
- package/dist/core/subscription-state.d.ts +34 -72
- package/dist/core/subscription-state.js +1 -4
- package/dist/core/substrate/delivery/plan.js +1 -1
- package/dist/core/user-settings.js +1 -1
- package/dist/daemon/api/app-listener.js +10 -10
- package/dist/daemon/api/auth/person-bearer.d.ts +14 -0
- package/dist/daemon/api/auth/person-bearer.js +1 -0
- package/dist/daemon/api/bridge.js +4 -4
- package/dist/daemon/api/document-listener.js +3 -3
- package/dist/daemon/api/environment-of.d.ts +18 -0
- package/dist/daemon/api/environment-of.js +5 -0
- package/dist/daemon/api/handlers/analytics.js +1 -1
- package/dist/daemon/api/handlers/app-profiles.d.ts +2 -2
- package/dist/daemon/api/handlers/app-profiles.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 +3 -0
- package/dist/daemon/api/handlers/broker-ops.js +1 -1
- package/dist/daemon/api/handlers/broker-recovery.js +1 -1
- package/dist/daemon/api/handlers/broker-signals.d.ts +0 -3
- package/dist/daemon/api/handlers/broker-signals.js +2 -2
- package/dist/daemon/api/handlers/canvas.js +4 -4
- package/dist/daemon/api/handlers/charges.d.ts +1 -1
- package/dist/daemon/api/handlers/charges.js +1 -1
- package/dist/daemon/api/handlers/conversations.d.ts +2 -0
- package/dist/daemon/api/handlers/conversations.js +3 -0
- package/dist/daemon/api/handlers/crons.js +1 -1
- package/dist/daemon/api/handlers/daemon.js +1 -1
- package/dist/daemon/api/handlers/delivery.d.ts +1 -1
- package/dist/daemon/api/handlers/delivery.js +1 -1
- package/dist/daemon/api/handlers/docs.js +1 -1
- package/dist/daemon/api/handlers/exec.js +1 -1
- package/dist/daemon/api/handlers/execution-start.d.ts +2 -0
- package/dist/daemon/api/handlers/execution-start.js +2 -0
- package/dist/daemon/api/handlers/files.js +1 -1
- package/dist/daemon/api/handlers/git-credential.d.ts +11 -0
- package/dist/daemon/api/handlers/git-credential.js +1 -0
- package/dist/daemon/api/handlers/hook-exec.d.ts +1 -1
- 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.js +1 -1
- package/dist/daemon/api/handlers/messages.js +1 -1
- package/dist/daemon/api/handlers/model-config.js +1 -1
- package/dist/daemon/api/handlers/modelauth.d.ts +1 -1
- package/dist/daemon/api/handlers/modelauth.js +1 -1
- package/dist/daemon/api/handlers/node-events.d.ts +6 -0
- 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 +3 -2
- package/dist/daemon/api/handlers/nodes.js +1 -1
- package/dist/daemon/api/handlers/objects.js +3 -3
- package/dist/daemon/api/handlers/profiles.js +1 -1
- package/dist/daemon/api/handlers/providers.js +1 -1
- package/dist/daemon/api/handlers/reports.js +9 -13
- package/dist/daemon/api/handlers/reviews.js +1 -1
- package/dist/daemon/api/handlers/runs.js +1 -1
- package/dist/daemon/api/handlers/settings.d.ts +2 -0
- package/dist/daemon/api/handlers/settings.js +1 -0
- package/dist/daemon/api/handlers/structured-requests.js +1 -1
- package/dist/daemon/api/handlers/vendor-status.d.ts +1 -1
- package/dist/daemon/api/handlers/vendor-status.js +1 -1
- package/dist/daemon/api/handlers/worktree.js +1 -1
- package/dist/daemon/api/map.d.ts +2 -2
- package/dist/daemon/api/map.js +2 -2
- package/dist/daemon/api/operations.js +1 -1
- package/dist/daemon/api/reader.d.ts +8 -1
- package/dist/daemon/api/reader.js +1 -1
- package/dist/daemon/api/router.d.ts +4 -2
- package/dist/daemon/api/router.js +1 -1
- package/dist/daemon/api/server.d.ts +15 -3
- package/dist/daemon/api/server.js +1 -1
- package/dist/daemon/api/vendor-signin.d.ts +2 -1
- package/dist/daemon/api/vendor-signin.js +20 -20
- package/dist/daemon/api/viewer-presence.d.ts +20 -6
- package/dist/daemon/api/viewer-presence.js +2 -1
- package/dist/daemon/broker-signals/bus.d.ts +48 -11
- package/dist/daemon/broker-signals/bus.js +1 -1
- package/dist/daemon/cron/armed-context.js +1 -1
- package/dist/daemon/cron/lease-recovery.js +1 -1
- package/dist/daemon/cron/live-runs.d.ts +6 -0
- package/dist/daemon/cron/live-runs.js +1 -1
- package/dist/daemon/cron/run-socket.js +1 -1
- package/dist/daemon/cron-run.js +2 -2
- package/dist/daemon/crtrd-cli.js +1 -1
- package/dist/daemon/crtrd.d.ts +10 -0
- package/dist/daemon/crtrd.js +18 -17
- package/dist/daemon/delivery/run-delivery.d.ts +1 -1
- package/dist/daemon/delivery/run-delivery.js +1 -1
- package/dist/daemon/due-sources.d.ts +1 -1
- package/dist/daemon/due-sources.js +1 -1
- package/dist/daemon/due.js +7 -6
- package/dist/daemon/fleet.d.ts +6 -6
- package/dist/daemon/fleet.js +9 -9
- package/dist/daemon/park-activity.d.ts +2 -1
- package/dist/daemon/park-activity.js +1 -1
- package/dist/daemon/park-pending.d.ts +20 -13
- package/dist/daemon/park-pending.js +3 -1
- package/dist/daemon/profile-delete.js +1 -1
- package/dist/daemon/reconcilers/bash-deadline.d.ts +15 -10
- package/dist/daemon/reconcilers/bash-deadline.js +1 -3
- package/dist/daemon/reconcilers/broker-supervision.d.ts +13 -3
- package/dist/daemon/reconcilers/broker-supervision.js +4 -4
- package/dist/daemon/reconcilers/cron-lane.d.ts +0 -1
- package/dist/daemon/reconcilers/cron-lane.js +1 -1
- package/dist/daemon/reconcilers/fault-retry-backstop.d.ts +2 -9
- package/dist/daemon/reconcilers/fault-retry-backstop.js +1 -1
- package/dist/daemon/reconcilers/grant-effects.d.ts +8 -0
- package/dist/daemon/reconcilers/grant-effects.js +1 -0
- package/dist/daemon/reconcilers/grove-instance-sweep.d.ts +1 -3
- package/dist/daemon/reconcilers/grove-instance-sweep.js +1 -1
- package/dist/daemon/reconcilers/ledger-r2.d.ts +27 -0
- package/dist/daemon/reconcilers/ledger-r2.js +7 -0
- package/dist/daemon/reconcilers/ledger-sandbox.d.ts +55 -0
- package/dist/daemon/reconcilers/ledger-sandbox.js +9 -0
- package/dist/daemon/reconcilers/ledger-storage.d.ts +22 -0
- package/dist/daemon/reconcilers/ledger-storage.js +5 -0
- package/dist/daemon/reconcilers/live-obligation.d.ts +3 -2
- package/dist/daemon/reconcilers/live-obligation.js +1 -1
- package/dist/daemon/reconcilers/managed-worktree-sweep.d.ts +0 -5
- package/dist/daemon/reconcilers/managed-worktree-sweep.js +1 -1
- package/dist/daemon/reconcilers/node-deadline.d.ts +2 -1
- package/dist/daemon/reconcilers/node-deadline.js +1 -1
- package/dist/daemon/reconcilers/node-lifecycle/freeze-lane.d.ts +1 -2
- package/dist/daemon/reconcilers/node-lifecycle/freeze-lane.js +1 -1
- package/dist/daemon/reconcilers/node-lifecycle/remote-wake.d.ts +31 -0
- package/dist/daemon/reconcilers/node-lifecycle/remote-wake.js +1 -0
- package/dist/daemon/reconcilers/node-lifecycle/requested-stops.d.ts +5 -0
- package/dist/daemon/reconcilers/node-lifecycle/requested-stops.js +2 -0
- package/dist/daemon/reconcilers/node-lifecycle/tick.js +1 -1
- package/dist/daemon/reconcilers/pending-review-submit.js +1 -1
- package/dist/daemon/reconcilers/recipe-image.d.ts +49 -0
- package/dist/daemon/reconcilers/recipe-image.js +7 -0
- package/dist/daemon/reconcilers/row-claim.d.ts +19 -0
- package/dist/daemon/reconcilers/row-claim.js +2 -0
- package/dist/daemon/reconcilers/storage-due-work.d.ts +18 -3
- package/dist/daemon/reconcilers/storage-due-work.js +2 -1
- package/dist/daemon/reconcilers/storage-maintenance.d.ts +5 -13
- package/dist/daemon/reconcilers/storage-maintenance.js +1 -1
- package/dist/daemon/reconcilers/structured-request-lane.js +1 -1
- package/dist/daemon/reconcilers/throttled-lane.d.ts +11 -0
- package/dist/daemon/reconcilers/throttled-lane.js +1 -0
- package/dist/daemon/review/finish.js +1 -1
- package/dist/daemon/run-notices.d.ts +3 -0
- package/dist/daemon/run-notices.js +1 -1
- package/dist/daemon/runs/append-section.d.ts +4 -1
- package/dist/daemon/runs/append-section.js +2 -2
- package/dist/daemon/runs/observer.d.ts +3 -2
- package/dist/daemon/runs/observer.js +3 -2
- package/dist/daemon/runs/view-transport.d.ts +19 -0
- package/dist/daemon/runs/view-transport.js +1 -0
- package/dist/daemon/structured-requests/boot.d.ts +2 -1
- package/dist/daemon/structured-requests/boot.js +1 -1
- package/dist/daemon/structured-requests/effects.d.ts +4 -3
- package/dist/daemon/structured-requests/effects.js +1 -1
- package/dist/daemon/structured-requests/notifier.d.ts +2 -0
- package/dist/daemon/structured-requests/notifier.js +1 -1
- package/dist/daemon/structured-requests/sidecar.d.ts +4 -3
- package/dist/daemon/structured-requests/sidecar.js +1 -1
- package/dist/launcher/validate.js +1 -1
- package/dist/migrations/004-canvas-documents/index.js +2 -2
- package/dist/pi-extensions/broker-local.d.ts +3 -3
- package/dist/pi-extensions/broker-local.js +1 -2
- package/dist/pi-extensions/canvas-bash-valve.js +6 -6
- package/dist/pi-extensions/canvas-context-intro.js +2 -2
- package/dist/pi-extensions/canvas-elapsed.js +2 -2
- package/dist/pi-extensions/canvas-goal-capture.js +1 -1
- package/dist/pi-extensions/canvas-inbox-watcher.js +2 -2
- package/dist/pi-extensions/canvas-review-boundary.d.ts +11 -1
- package/dist/pi-extensions/canvas-review-boundary.js +3 -3
- package/dist/pi-extensions/canvas-stophook.js +1 -1
- package/dist/pi-extensions/canvas-structured-output.d.ts +5 -3
- package/dist/pi-extensions/canvas-structured-output.js +6 -11
- package/dist/pi-extensions/canvas-tool-guide.d.ts +9 -2
- package/dist/pi-extensions/canvas-tool-guide.js +6 -6
- package/dist/shared/inbox-entry-body.js +7 -7
- package/dist/types.d.ts +12 -0
- package/docs/sdk/release-notes.md +4 -0
- package/package.json +7 -4
- package/packages/crouter-identity/package.json +1 -1
- package/runtime.lock.json +13 -13
- package/scripts/git-credential-crtr +33 -0
- package/scripts/sandbox-bootstrap.sh +54 -0
- package/scripts/sandbox-start.mjs +320 -0
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.d.ts +0 -78
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.js +0 -1179
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.ts +0 -1406
- package/dist/core/conversation-store/file-store.d.ts +0 -37
- package/dist/core/conversation-store/file-store.js +0 -9
- package/dist/core/conversation-store/listener.d.ts +0 -4
- package/dist/core/conversation-store/listener.js +0 -8
- package/dist/core/scoped-state/profiles.d.ts +0 -27
- package/dist/core/scoped-state/profiles.js +0 -1
- package/dist/core/scoped-state/providers.d.ts +0 -24
- package/dist/core/scoped-state/providers.js +0 -1
- package/dist/core/scoped-state/settings.d.ts +0 -28
- package/dist/core/scoped-state/settings.js +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
var y=Object.defineProperty;var o=(e,t)=>y(e,"name",{value:t,configurable:!0});import{randomUUID as m}from"node:crypto";import{openDb as _,withCanvasWrite as u}from"./db.js";import{capturePidIdentities as f,captureLivenessSnapshot as g,identitiesMatch as h,isBootScopedIdentity as A,isLegacyTicksIdentity as T}from"./pid.js";import{existsSync as D,readFileSync as L}from"node:fs";import{LAUNCHER_SOCKET as S}from"../../launcher/spec.js";import{forgetNodeToken as w,mintNodeToken as U,revokeNodeTokens as p}from"./node-tokens.js";function x(){return new Date().toISOString()}o(x,"now");function R(e){return{executionId:e.execution_id,nodeId:e.node_id,daemonEpoch:e.daemon_epoch??null,pid:e.pid??null,processIdentity:e.process_identity??null,state:e.state,startedAt:e.started_at,endedAt:e.ended_at??null,exitReason:e.exit_reason??null}}o(R,"hydrate");async function F(e){const t=await(await _()).prepare("SELECT * FROM executions WHERE node_id = ? AND state != 'exited'").get(e);return t===void 0?null:R(t)}o(F,"liveExecutionForNode");async function M(e,t){return await u(async n=>{const i=x();await n.prepare("UPDATE executions SET state = 'exited', ended_at = ?, exit_reason = 'superseded' WHERE node_id = ? AND state != 'exited'").run(i,e),await p(n,"node_id",e,i);const r=m();return await n.prepare("INSERT INTO executions (execution_id, node_id, daemon_epoch, pid, process_identity, state, started_at, ended_at, exit_reason) VALUES (?, ?, ?, NULL, NULL, 'launching', ?, NULL, NULL)").run(r,e,t.daemonEpoch,i),await U(n,r,e,i),r})}o(M,"beginExecution");async function b(e,t,n){const i=f([n])?.get(n)??null;return await u(async r=>{if((await r.prepare("UPDATE executions SET pid = ?, process_identity = ?, state = 'running' WHERE execution_id = ? AND node_id = ? AND state = 'launching'").run(n,i,e,t)).changes>0)return"recorded";const s=await r.prepare("SELECT pid FROM executions WHERE execution_id = ? AND node_id = ? AND state = 'running'").get(e,t);if(s?.pid===n)return"recorded";if(process.platform==="linux"&&D(S)&&s?.pid!=null){const l=g(),c=[s.pid];for(let d=0;d<c.length;d++)c.push(...l?.childrenOf.get(c[d])??[]);if(c.includes(n))return"recorded";for(const d of c)try{const N=L(`/proc/${d}/status`,"utf8"),E=/^NSpid:\s*(.+)$/m.exec(N)?.[1]?.trim().split(/\s+/).map(Number)??[];if(E.length>1&&E.at(-1)===n)return"recorded"}catch{}}return"shutdown"})}o(b,"recordExecutionPid");async function H(e,t){return w(e),await u(async n=>{const i=x(),r=await n.prepare("UPDATE executions SET state = 'exited', ended_at = ?, exit_reason = ? WHERE execution_id = ? AND state != 'exited'").run(i,t.reason,e);return await p(n,"broker_process_id",e,i),Number(r.changes)===1})}o(H,"endExecution");async function $(e,t){return await H(e,t)}o($,"abortExecution");async function B(e,t){return await u(async n=>{const i=x(),r=await n.prepare("UPDATE executions SET state = 'exited', ended_at = ?, exit_reason = ? WHERE node_id = ? AND state != 'exited'").run(i,t.reason,e);return await p(n,"node_id",e,i),Number(r.changes)===1})}o(B,"endLiveExecution");async function K(e=t=>f([t])?.get(t)){const t=await _(),n=await t.prepare("SELECT execution_id, pid, process_identity FROM executions WHERE state = 'running' AND pid IS NOT NULL AND process_identity IS NOT NULL").all(),i=t.prepare("UPDATE executions SET process_identity = ? WHERE execution_id = ? AND pid = ? AND process_identity = ? AND state = 'running'"),r=[];for(const a of n){if(!T(a.process_identity))continue;const s=e(a.pid);s===void 0||!A(s)||!h(s,a.process_identity)||(await i.run(s,a.execution_id,a.pid,a.process_identity)).changes>0&&r.push(a.execution_id)}return{migrated:r}}o(K,"migrateLegacyExecutionIdentities");export{$ as abortExecution,M as beginExecution,H as endExecution,B as endLiveExecution,F as liveExecutionForNode,K as migrateLegacyExecutionIdentities,b as recordExecutionPid};
|
|
1
|
+
var T=Object.defineProperty;var a=(e,t)=>T(e,"name",{value:t,configurable:!0});import{randomUUID as g}from"node:crypto";import{openDb as r,withCanvasWrite as _}from"./db.js";import{capturePidIdentities as R,captureLivenessSnapshot as L,identitiesMatch as D,isBootScopedIdentity as y,isLegacyTicksIdentity as C}from"./pid.js";import{existsSync as O,readFileSync as P}from"node:fs";import{LAUNCHER_SOCKET as U}from"../../launcher/spec.js";import{revokeNodeTokens as x}from"./node-tokens.js";import{clearPendingParkIn as l}from"../../daemon/park-pending.js";function d(){return new Date().toISOString()}a(d,"now");function A(e){return{executionId:e.execution_id,nodeId:e.node_id,daemonEpoch:e.daemon_epoch??null,pid:e.pid??null,processIdentity:e.process_identity??null,state:e.state,startedAt:e.started_at,endedAt:e.ended_at??null,exitReason:e.exit_reason??null,runner:e.runner,sandboxName:e.sandbox_name??null,attempt:Number(e.attempt),release:e.release??null,heartbeatAt:e.heartbeat_at??null,awakeSince:e.awake_since??null,idleAt:e.idle_at??null,exitedAt:e.exited_at??null,launchJson:e.launch_json??null,stopRequestedAt:e.stop_requested_at??null,stopAfterTurn:Number(e.stop_after_turn)===1,stopReason:e.stop_reason??null}}a(A,"hydrate");async function X(e){const t=await(await r()).prepare("SELECT * FROM executions WHERE node_id = ? AND state != 'exited'").get(e);return t===void 0?null:A(t)}a(X,"liveExecutionForNode");class W extends Error{static{a(this,"ExecutionCapReached")}cap;live;constructor(t,n){super(`no broker slot is free \u2014 ${n} live executions at the cap of ${t}.`),this.cap=t,this.live=n,this.name="ExecutionCapReached"}}class H extends Error{static{a(this,"ExecutionAlreadyLive")}nodeId;executionId;constructor(t,n){super(`${t} already has a live execution ${n}.`),this.nodeId=t,this.executionId=n,this.name="ExecutionAlreadyLive"}}const b=7340001;async function Y(e,t){return await _(async n=>{const i=d();if(!await n.prepare("SELECT node_id FROM nodes WHERE node_id = ? FOR UPDATE").get(e))throw new Error(`cannot begin execution: missing node ${e}`);if(t.cap!==void 0){await n.prepare(`SELECT pg_advisory_xact_lock(${b})`).get();const u=Number((await n.prepare("SELECT COUNT(*) AS n FROM executions WHERE state != 'exited' AND node_id != ?").get(e)).n);if(u>=t.cap)throw new W(t.cap,u)}const s=(await n.prepare("SELECT execution_id, runner, daemon_epoch, state FROM executions WHERE node_id = ? AND state != 'exited'").all(e)).find(u=>u.state==="launching"?u.runner!=="process"||t.daemonEpoch!==null&&u.daemon_epoch===t.daemonEpoch:u.runner!=="process");if(s!==void 0)throw new H(e,s.execution_id);(await n.prepare("UPDATE executions SET state = 'exited', ended_at = ?, exited_at = ?, exit_reason = 'superseded' WHERE node_id = ? AND state != 'exited'").run(i,i,e)).changes>0&&await l(n,e),await x(n,"node_id",e,i);const p=g(),E=t.attempt??Number((await n.prepare("SELECT COALESCE(MAX(attempt), 0) + 1 AS next FROM executions WHERE node_id = ?").get(e)).next);return await n.prepare("INSERT INTO executions (execution_id, node_id, daemon_epoch, pid, process_identity, state, started_at, ended_at, exit_reason, runner, sandbox_name, attempt, release, launch_json) VALUES (?, ?, ?, NULL, NULL, 'launching', ?, NULL, NULL, ?, ?, ?, ?, ?)").run(p,e,t.daemonEpoch,i,t.runner??"process",t.sandboxName??null,E,t.release??null,t.launchJson??null),p})}a(Y,"beginExecution");async function j(e,t){const n=await(await r()).prepare("UPDATE executions SET launch_json = ? WHERE execution_id = ? AND state = 'launching'").run(t,e);if(Number(n.changes)!==1)throw new Error(`cannot set launch recipe for execution ${e}: no launching execution`)}a(j,"setExecutionLaunchJson");async function J(e){const t=await(await r()).prepare("UPDATE executions SET idle_at = ? WHERE execution_id = ? AND state = 'running' AND idle_at IS NULL").run(d(),e);return Number(t.changes)===1}a(J,"recordExecutionIdle");async function G(e){await(await r()).prepare("UPDATE executions SET awake_since = ?, idle_at = NULL WHERE execution_id = ? AND state = 'running'").run(d(),e)}a(G,"recordExecutionAwake");async function V(e,t,n){const i=R([n])?.get(n)??null;return await _(async o=>{if((await o.prepare("UPDATE executions SET pid = ?, process_identity = ?, state = 'running', awake_since = ? WHERE execution_id = ? AND node_id = ? AND state = 'launching'").run(n,i,d(),e,t)).changes>0)return"recorded";const s=await o.prepare("SELECT pid FROM executions WHERE execution_id = ? AND node_id = ? AND state = 'running'").get(e,t);if(s?.pid===n)return"recorded";if(process.platform==="linux"&&O(U)&&s?.pid!=null){const S=L(),p=[s.pid];for(let E=0;E<p.length;E++)p.push(...S?.childrenOf.get(p[E])??[]);if(p.includes(n))return"recorded";for(const E of p)try{const u=P(`/proc/${E}/status`,"utf8"),m=/^NSpid:\s*(.+)$/m.exec(u)?.[1]?.trim().split(/\s+/).map(Number)??[];if(m.length>1&&m.at(-1)===n)return"recorded"}catch{}}return"shutdown"})}a(V,"recordExecutionPid");async function F(e,t){return await _(async n=>{const i=d(),o=await n.prepare("UPDATE executions SET state = 'exited', ended_at = ?, exited_at = ?, exit_reason = COALESCE(exit_reason, ?) WHERE execution_id = ? AND state != 'exited' RETURNING node_id").get(i,i,t.reason,e);return await x(n,"broker_process_id",e,i),o!==void 0&&await l(n,o.node_id),o!==void 0})}a(F,"endExecution");async function z(e,t){return await _(async n=>{const i=d(),o=await n.prepare("UPDATE executions SET state = 'exited', ended_at = ?, exited_at = ?, exit_reason = COALESCE(exit_reason, ?) WHERE execution_id = ? AND state = 'launching' RETURNING node_id").get(i,i,t.reason,e);return o===void 0?!1:(await x(n,"broker_process_id",e,i),await l(n,o.node_id),!0)})}a(z,"endLaunchingExecution");async function Q(e,t){return await F(e,t)}a(Q,"abortExecution");async function Z(e,t){return await _(async n=>{const i=d(),o=await n.prepare("UPDATE executions SET state = 'exited', ended_at = ?, exited_at = ?, exit_reason = COALESCE(exit_reason, ?) WHERE node_id = ? AND state != 'exited'").run(i,i,t.reason,e);return await x(n,"node_id",e,i),Number(o.changes)>0&&await l(n,e),Number(o.changes)===1})}a(Z,"endLiveExecution");async function ee(e=t=>R([t])?.get(t)){const t=await r(),n=await t.prepare("SELECT execution_id, pid, process_identity FROM executions WHERE state = 'running' AND pid IS NOT NULL AND process_identity IS NOT NULL").all(),i=t.prepare("UPDATE executions SET process_identity = ? WHERE execution_id = ? AND pid = ? AND process_identity = ? AND state = 'running'"),o=[];for(const c of n){if(!C(c.process_identity))continue;const s=e(c.pid);s===void 0||!y(s)||!D(s,c.process_identity)||(await i.run(s,c.execution_id,c.pid,c.process_identity)).changes>0&&o.push(c.execution_id)}return{migrated:o}}a(ee,"migrateLegacyExecutionIdentities");async function te(e,t){const n=await(await r()).prepare("UPDATE executions SET stop_requested_at = COALESCE(stop_requested_at, ?), stop_after_turn = CASE WHEN stop_requested_at IS NULL THEN ? ELSE stop_after_turn END, stop_reason = COALESCE(stop_reason, ?) WHERE node_id = ? AND state != 'exited'").run(d(),t.afterTurn?1:0,t.reason,e);return Number(n.changes)>0}a(te,"requestExecutionStop");async function ne(e){return(await(await r()).prepare("SELECT * FROM executions WHERE state != 'exited' AND stop_requested_at IS NOT NULL AND stop_requested_at <= ? ORDER BY stop_requested_at").all(e)).map(A)}a(ne,"executionsWithStopRequestedBefore");async function f(e){const t=await(await r()).prepare("SELECT * FROM executions WHERE node_id = ? ORDER BY started_at DESC, attempt DESC LIMIT 1").get(e);return t===void 0?null:A(t)}a(f,"latestExecutionForNode");async function ae(e){return await(await r()).prepare("SELECT 1 AS x FROM executions WHERE node_id = ? AND state = 'running' AND runner != 'process'").get(e)!==void 0}a(ae,"hasRunningRemoteExecution");async function ie(e,t){return await(await r()).prepare("SELECT 1 AS x FROM executions WHERE node_id = ? AND state = 'launching' AND (runner != 'process' OR daemon_epoch = ?)").get(e,t)!==void 0}a(ie,"hasLaunchingExecution");async function oe(e){const t=await(await r()).prepare("SELECT node_id FROM executions WHERE state != 'exited' AND runner = 'process' AND daemon_epoch = ?").all(e);return new Set(t.map(n=>n.node_id))}a(oe,"liveProcessExecutionNodeIds");async function re(){const e=await(await r()).prepare("SELECT node_id FROM executions WHERE state != 'exited'").all();return new Set(e.map(t=>t.node_id))}a(re,"liveExecutionNodeIds");const h="profile_pause",w="profile_pause_absorbed";async function se(e){await(await r()).prepare("UPDATE executions SET stop_requested_at = COALESCE(stop_requested_at, ?), stop_reason = ? WHERE node_id = ? AND state != 'exited'").run(d(),h,e)}a(se,"markProfilePauseStop");async function ce(e){return(await f(e))?.stopReason===h}a(ce,"hasProfilePauseStop");async function ue(e){const t=await(await r()).prepare("UPDATE executions SET stop_reason = ? WHERE execution_id = (SELECT execution_id FROM executions WHERE node_id = ? ORDER BY started_at DESC, attempt DESC LIMIT 1) AND stop_reason = ?").run(w,e,h);return Number(t.changes)>0}a(ue,"absorbProfilePauseStop");async function de(e){return(await f(e))?.stopReason===w}a(de,"hasAbsorbedProfilePauseStop");const N="exited:";async function pe(e,t){const n=t.oomKilled===!0?"out_of_memory":`${N}${t.code??""}:${t.signal??""}`;await(await r()).prepare("UPDATE executions SET exit_reason = ? WHERE execution_id = ? AND exit_reason IS NULL").run(n,e)}a(pe,"recordExecutionExit");async function Ee(e){const t=(await f(e))?.exitReason;return t!=null&&(t==="out_of_memory"||t.startsWith(N))}a(Ee,"hasObservedExit");async function _e(e){const t=await f(e),n=t?.exitReason;if(t===null||n==null)return;const i=n==="out_of_memory";if(!i&&!n.startsWith(N))return;const o=await(await r()).prepare("UPDATE executions SET exit_reason = 'exit_handled' WHERE execution_id = ? AND exit_reason = ?").run(t.executionId,n);if(Number(o.changes)===0)return;if(i)return{code:null,signal:null,oomKilled:!0};const[c,s]=n.slice(N.length).split(":");return{code:c===""?null:Number(c),signal:s===""?null:s}}a(_e,"takeObservedExit");export{H as ExecutionAlreadyLive,W as ExecutionCapReached,h as PROFILE_PAUSE_STOP_REASON,Q as abortExecution,ue as absorbProfilePauseStop,Y as beginExecution,F as endExecution,z as endLaunchingExecution,Z as endLiveExecution,ne as executionsWithStopRequestedBefore,de as hasAbsorbedProfilePauseStop,ie as hasLaunchingExecution,Ee as hasObservedExit,ce as hasProfilePauseStop,ae as hasRunningRemoteExecution,f as latestExecutionForNode,X as liveExecutionForNode,re as liveExecutionNodeIds,oe as liveProcessExecutionNodeIds,se as markProfilePauseStop,ee as migrateLegacyExecutionIdentities,G as recordExecutionAwake,pe as recordExecutionExit,J as recordExecutionIdle,V as recordExecutionPid,te as requestExecutionStop,j as setExecutionLaunchJson,_e as takeObservedExit};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
var V=Object.defineProperty;var w=(i,a)=>V(i,"name",{value:a,configurable:!0});import{DatabaseSync as W}from"node:sqlite";import{existsSync as Y,mkdirSync as D,mkdtempSync as J,renameSync as X,rmSync as P}from"node:fs";import{tmpdir as Q}from"node:os";import{join as A}from"node:path";import j from"pg";import{migrate as z,MIGRATIONS as I}from"./migrations.js";import{canvasDbPath as Z}from"./paths.js";import{canvasSearchPathOptions as ee}from"./schema-version.js";import{EXPORT_MARK_KEY as F,IMPORT_MARK_KEY as te,OBJECT_COLUMNS as ne,pgColumns as se,quote as
|
|
1
|
+
var V=Object.defineProperty;var w=(i,a)=>V(i,"name",{value:a,configurable:!0});import{DatabaseSync as W}from"node:sqlite";import{existsSync as Y,mkdirSync as D,mkdtempSync as J,renameSync as X,rmSync as P}from"node:fs";import{tmpdir as Q}from"node:os";import{join as A}from"node:path";import j from"pg";import{migrate as z,MIGRATIONS as I}from"./migrations.js";import{canvasDbPath as Z}from"./paths.js";import{canvasSearchPathOptions as ee}from"./schema-version.js";import{EXPORT_MARK_KEY as F,IMPORT_MARK_KEY as te,OBJECT_COLUMNS as ne,pgColumns as se,quote as m,TABLE_ORDER as C}from"./import-sqlite.js";const oe=5e3,re=new Set(["environments","relations","schemas","charges","charge_totals","limits","viewer_attachments","reconciler_leases","environment_repos","conversation_entries","conversation_parts","charge_chunks","profiles","profile_projects","profile_defaults","scope_settings","scope_bookkeeping","scope_marketplaces","scope_plugins","person_settings","model_accounts","model_account_cooldowns","model_api_keys","model_settings","model_sign_in_flows","env_vars","usage","grantee_usage","provider_receipts"]),ae={exposures:"node, object, channel",rules:"object, position",edges:"type, src, dst",unresolved_links:"src, name",revision_parents:"child, parent",canvas_meta:"key",runtime_state:"key",message_causes:"message_id",peer_ingested:"key",peer_ingested_destinations:"key",message_sequence:"id",messages:"seq",review_comment_events:"seq",audit_rows:"id",peer_outbox:"id",app_users:"uid"},ie={objects:"id",revisions:"rev_id",watches:"watch_id"},H=new Set(["daemon_owner","schema_version","schema_min_reader","ledger_migrated",te,F]);function ce(i){const a=J(A(Q(),"crtr-export-")),s=process.env.CRTR_HOME;process.env.CRTR_HOME=a,D(A(a,"runtime","nodes"),{recursive:!0});try{const o=new W(i);return o.exec("PRAGMA journal_mode = DELETE;"),o.exec("PRAGMA foreign_keys = ON;"),z(o),o.exec("DELETE FROM canvas_meta; DELETE FROM message_sequence;"),o}finally{s===void 0?delete process.env.CRTR_HOME:process.env.CRTR_HOME=s,P(a,{recursive:!0,force:!0})}}w(ce,"createEmptyDatabase");async function Re(i,a=()=>{}){const s=Z();if(Y(s))throw new Error(`${s} already exists; refusing to overwrite it`);D(A(s,".."),{recursive:!0,mode:448});const o=`${s}.exporting-${process.pid}`,u=Date.now(),t=new j.Client({connectionString:i,application_name:`crtr-export-${process.pid}`,options:ee(),types:{getTypeParser:w(((d,r)=>d===20?f=>Number(f):j.types.getTypeParser(d,r)),"getTypeParser")}});await t.connect();let l;try{if((await t.query("SELECT value FROM canvas_meta WHERE key = 'schema_version'").catch(()=>({rows:[]}))).rows.length===0)throw new Error("the Postgres database has no canvas schema; nothing to export");l=ce(o);const r=l;r.exec("PRAGMA foreign_keys = OFF;");const f=await se(t),L=[...f.keys()].filter(e=>!re.has(e)&&!C.includes(e));if(L.length>0)throw new Error(`export: Postgres tables with no export rule: ${L.join(", ")}`);await t.query("BEGIN READ ONLY ISOLATION LEVEL REPEATABLE READ");const E={};for(const[e,S]of Object.entries(ie)){const h=new Map;for(const _ of(await t.query(`SELECT ${S} AS id, seq FROM ${e}`)).rows)h.set(_.id,Number(_.seq));E[e]=h}const B=E.objects;let M=0;r.exec("BEGIN");for(const e of C){const S=Date.now(),h=new Set(r.prepare(`PRAGMA table_info(${m(e)})`).all().map(n=>n.name)),_=f.get(e);if(_===void 0)throw new Error(`export: Postgres has no table ${e}`);const G=_.some(n=>n.name==="seq"),O=_.filter(n=>h.has(n.name)),K=new Set(ne[e]??[]),g=e==="objects"||e==="revisions"||e==="watches"||e==="watch_subscriptions",$=O.map(n=>n.type==="jsonb"?`${m(n.name)}::text AS ${m(n.name)}`:m(n.name));e==="watches"&&$.push("watch_id AS _watch_id"),g&&$.push("seq AS _seq");const R=O.map(n=>m(n.name)),U=r.prepare(`INSERT INTO ${m(e)} (${g?["rowid",...R]:R}) VALUES (${(g?["?",...R]:R).map(()=>"?").join(", ")})`),q=G?"seq":ae[e],b=`export_${e}`;await t.query(`DECLARE ${b} NO SCROLL CURSOR FOR SELECT ${$.join(", ")} FROM ${m(e)}${e==="canvas_meta"?` WHERE key NOT IN (${[...H].map(n=>`'${n}'`).join(", ")})`:""}${q===void 0?"":` ORDER BY ${q}`}`);let T=0;for(;;){const n=await t.query(`FETCH ${oe} FROM ${b}`);if(n.rows.length===0)break;for(const k of n.rows){const N=g?[Number(k._seq)]:[];for(const c of O){let p=k[c.name];e==="revision_parents"&&(c.name==="child"||c.name==="parent")?p=x(E.revisions,"revision",e,c.name,p):e==="watch_subscriptions"&&c.name==="watch"?p=x(E.watches,"watch",e,c.name,p):K.has(c.name)?p=x(B,"object",e,c.name,p):e==="jobs"&&(c.name==="job_dir"||c.name==="log_path")&&(p=p??""),N.push(p??null)}U.run(...N)}T+=n.rows.length}await t.query(`CLOSE ${b}`),M+=T,a(`export ${e}: ${T} rows in ${Date.now()-S} ms`)}r.exec("COMMIT"),await t.query("COMMIT");const v=r.prepare("PRAGMA foreign_key_check").all();if(v.length>0)throw new Error(`export: ${v.length} foreign key violation(s) in the exported canvas.db, first: ${JSON.stringify(v[0])}`);await pe(t,r);const y=r.prepare("PRAGMA user_version").get().user_version;if(y!==I.length)throw new Error(`export: exported canvas.db is at user_version ${y}, expected ${I.length}`);return r.close(),l=void 0,await t.query("INSERT INTO canvas_meta (key, value) VALUES ($1, $2) ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value",[F,JSON.stringify({at:new Date().toISOString(),path:s})]),X(o,s),{path:s,rows:M,ms:Date.now()-u,userVersion:y}}catch(d){await t.query("ROLLBACK").catch(()=>{});try{l?.close()}catch{}for(const r of["","-wal","-shm","-journal"])P(`${o}${r}`,{force:!0});throw d}finally{await t.end().catch(()=>{})}}w(Re,"exportPostgresToSqlite");function x(i,a,s,o,u){if(u==null)return null;const t=i.get(u);if(t===void 0)throw new Error(`export: ${s}.${o} references ${a} ${String(u)}, which was not exported (`);return t}w(x,"mapId");async function pe(i,a){const s=[];for(const o of C){const u=Number((await i.query(`SELECT count(*) AS n FROM ${m(o)}`)).rows[0].n);let t=Number(a.prepare(`SELECT count(*) AS n FROM ${m(o)}`).get().n),l=u;o==="canvas_meta"&&(l=Number((await i.query("SELECT count(*) AS n FROM canvas_meta WHERE key <> ALL($1)",[[...H]])).rows[0].n),t=Number(a.prepare("SELECT count(*) AS n FROM canvas_meta").get().n)),l!==t&&s.push(`${o}: Postgres ${l} rows, SQLite ${t}`)}if(s.length>0)throw new Error(`Postgres \u2192 SQLite export verification failed:
|
|
2
2
|
${s.join(`
|
|
3
3
|
`)}`)}w(pe,"verify");export{Re as exportPostgresToSqlite};
|
|
@@ -11,8 +11,12 @@ export declare function setFocusOccupant(focus_id: string, node_id: string): Pro
|
|
|
11
11
|
export declare function setFocusPane(focus_id: string, pane: string | null, session: string | null): Promise<void>;
|
|
12
12
|
/** DELETE a viewport. */
|
|
13
13
|
export declare function closeFocusRow(focus_id: string): Promise<void>;
|
|
14
|
+
/** DELETE a viewport only while it still sits on `pane`: a row re-pointed to another pane since `pane` was probed is kept. */
|
|
15
|
+
export declare function closeFocusRowOnPane(focus_id: string, pane: string): Promise<boolean>;
|
|
14
16
|
/** The focus a node occupies (≤1, UNIQUE node_id), or null. */
|
|
15
17
|
export declare function getFocusByNode(node_id: string): Promise<FocusRow | null>;
|
|
18
|
+
/** {@link getFocusByNode} taking the row's lock: call inside `withCanvasWrite`, where a concurrent re-point or close of the row waits for the commit. */
|
|
19
|
+
export declare function getFocusByNodeForUpdate(node_id: string): Promise<FocusRow | null>;
|
|
16
20
|
/** The focus realized by a given pane (`%id`), or null. */
|
|
17
21
|
export declare function getFocusByPane(pane: string): Promise<FocusRow | null>;
|
|
18
22
|
/** A focus by its stable id, or null. Used by placement to read a row back by id
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var
|
|
1
|
+
var u=Object.defineProperty;var o=(e,n)=>u(e,"name",{value:n,configurable:!0});import{openDb as a}from"./db.js";function s(e){return{focus_id:e.focus_id,pane:e.pane??null,session:e.session??null,node_id:e.node_id}}o(s,"focusFrom");async function p(e,n,t,c){await(await a()).prepare("INSERT INTO focuses (focus_id, pane, session, node_id) VALUES (?, ?, ?, ?)").run(e,n,t,c)}o(p,"openFocusRow");async function E(e,n){await(await a()).prepare("UPDATE focuses SET node_id = ? WHERE focus_id = ?").run(n,e)}o(E,"setFocusOccupant");async function f(e,n,t){await(await a()).prepare("UPDATE focuses SET pane = ?, session = ? WHERE focus_id = ?").run(n,t,e)}o(f,"setFocusPane");async function d(e){await(await a()).prepare("DELETE FROM focuses WHERE focus_id = ?").run(e)}o(d,"closeFocusRow");async function w(e,n){return(await(await a()).prepare("DELETE FROM focuses WHERE focus_id = ? AND pane = ?").run(e,n)).changes>0}o(w,"closeFocusRowOnPane");async function R(e){const n=await(await a()).prepare("SELECT * FROM focuses WHERE node_id = ?").get(e);return n?s(n):null}o(R,"getFocusByNode");async function F(e){const n=await(await a()).prepare("SELECT * FROM focuses WHERE node_id = ? FOR UPDATE").get(e);return n?s(n):null}o(F,"getFocusByNodeForUpdate");async function l(e){const n=await(await a()).prepare("SELECT * FROM focuses WHERE pane = ?").get(e);return n?s(n):null}o(l,"getFocusByPane");async function _(e){const n=await(await a()).prepare("SELECT * FROM focuses WHERE focus_id = ?").get(e);return n?s(n):null}o(_,"getFocusById");async function y(){return(await(await a()).prepare("SELECT * FROM focuses ORDER BY focus_id").all()).map(s)}o(y,"listFocuses");export{d as closeFocusRow,w as closeFocusRowOnPane,_ as getFocusById,R as getFocusByNode,F as getFocusByNodeForUpdate,l as getFocusByPane,y as listFocuses,p as openFocusRow,E as setFocusOccupant,f as setFocusPane};
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
var S=Object.defineProperty;var
|
|
1
|
+
var S=Object.defineProperty;var d=(n,s)=>S(n,"name",{value:s,configurable:!0});import{envNodeId as M}from"../../shared/env.js";import{getNode as p,listNodes as j,view as v}from"./canvas.js";import{openDb as E}from"./db.js";import{readTextIfExists as O}from"../fs-utils.js";import{conversationIdFromPath as y,conversationStore as g,ConversationNotFoundError as I}from"../conversation-store/index.js";import{reportBodyByName as C}from"../feed/reports.js";import{readStamps as A}from"../runtime/stamp/protocol.js";import{forEachAsync as B}from"../async-array.js";const nn=["human","inbox","wake","revive","restart-continuation","stop-guard","park","recovery","context-nudge","kickoff","unknown"],en=["user","assistant","toolResult"];async function R(){const n=M();if(n!==void 0&&n!==""){const s=await p(n);if(s!==null)return s.cwd}return process.cwd()}d(R,"callerCwd");function x(n){const s=Date.parse(n);return Number.isNaN(s)?0:s}d(x,"toMs");async function k(n){return(await(await E()).prepare(`SELECT m.created_at, m.sender_node_id, d.urgency, m.kind, m.label, m.body_ref, m.body_json
|
|
2
2
|
FROM deliveries d JOIN messages m ON m.message_id = d.message_id
|
|
3
3
|
WHERE d.destination_id = ? AND d.wake = 1
|
|
4
|
-
ORDER BY m.seq, d.created_at, d.delivery_id`).all(n)).map(e=>({ts:e.created_at,from:e.sender_node_id,tier:e.urgency,kind:e.kind,label:e.label,ref:e.body_ref,data:e.body_json===null?null:JSON.parse(e.body_json)}))}
|
|
5
|
-
`),e=`[${n.kind}] ${n.label}`,t=typeof n.data=="object"&&n.data!==null&&!Array.isArray(n.data)?n.data.body:void 0,i=typeof t=="string"?t.trim():"",o=typeof t=="string",r=n.ref!==null?o?O(n.ref)??"":await C(n.ref)??"":i,c
|
|
4
|
+
ORDER BY m.seq, d.created_at, d.delivery_id`).all(n)).map(e=>({ts:e.created_at,from:e.sender_node_id,tier:e.urgency,kind:e.kind,label:e.label,ref:e.body_ref,data:e.body_json===null?null:JSON.parse(e.body_json)}))}d(k,"allInboxEntries");async function _(n){const s=[`from: ${n.from??"system"}`,`tier: ${n.tier}`].join(`
|
|
5
|
+
`),e=`[${n.kind}] ${n.label}`,t=typeof n.data=="object"&&n.data!==null&&!Array.isArray(n.data)?n.data.body:void 0,i=typeof t=="string"?t.trim():"",o=typeof t=="string",r=typeof n.data=="object"&&n.data!==null&&!Array.isArray(n.data)?n.data.body_full:void 0,c=n.ref!==null?o?typeof r=="string"?r:O(n.ref)??"":await C(n.ref)??"":i,u=c!==""&&c!==n.label,a=[s,e];return n.ref!==null&&a.push(`ref: ${n.ref}`),u&&a.push(c),a.join(`
|
|
6
6
|
|
|
7
|
-
`)}
|
|
8
|
-
`)}
|
|
9
|
-
`).map(r=>r.trim()).find(r=>r!=="")??"",o={ref:`${n.node_id}:${t}`,nodeId:n.node_id,relpath:t,source:"transcript",ts:e.ts,tsMs:e.tsMs,title:`[${e.role}] ${i.length>80?`${i.slice(0,80)}\u2026`:i}`,nodeName:n.name,nodeKind:n.kind,nodeStatus:n.status,nodeCwd:n.cwd,nodeDesc:s,loadBody:
|
|
7
|
+
`)}d(_,"inboxEntryBody");async function D(n,s,e,t){const i=`inbox/${String(t).padStart(6,"0")}`,o=await _(e),r={ref:`${n.node_id}:${i}`,nodeId:n.node_id,relpath:i,source:"inbox",ts:e.ts,tsMs:x(e.ts),title:`[${e.kind}] from ${e.from??"system"}: ${e.label}`,nodeName:n.name,nodeKind:n.kind,nodeStatus:n.status,nodeCwd:n.cwd,nodeDesc:s,loadBody:d(()=>o,"loadBody"),origin:"inbox"};return typeof e.from=="string"&&e.from!==""&&(r.from=e.from),r}d(D,"inboxArtifact");async function N(n){const s=(await p(n))?.pi_session_file,e=typeof s=="string"?y(s):null;if(e===null)return null;try{return(await g().header(e)).path}catch(t){if(t instanceof I)return null;throw t}}d(N,"resolveSessionFile");function T(n){if(typeof n=="string")return n;if(!Array.isArray(n))return"";const s=[];for(const e of n){if(e===null||typeof e!="object")continue;const t=e;t.type==="text"&&typeof t.text=="string"?s.push(t.text):t.type==="toolCall"&&s.push(`Tool: ${typeof t.name=="string"?t.name:"call"}`)}return s.join(`
|
|
8
|
+
`)}d(T,"textFromBlocks");function F(n){return n==null?"unknown":n.type==="human"?"human":n.kind}d(F,"originToken");function L(n){if(n==null||n.type!=="runtime")return;const s=n.entries;if(s===void 0||s.length===0)return;const e=new Set;for(const t of s){const i=t.fromName??t.from;typeof i=="string"&&i!==""&&e.add(i)}return e.size===0?void 0:[...e].join(", ")}d(L,"sendersOf");async function $(n){const s=await N(n);if(s===null)return[];const e=(await g().read(y(s))).entries,t=new Map;for(const o of A(e)){if(o.kind!=="message")continue;const r=o.payload;typeof r.msgTs=="number"&&t.set(r.msgTs,r.origin)}const i=[];for(const o of e){if(o===null||typeof o!="object")continue;const r=o;if(r.type!=="message")continue;const c=r.message;if(c===null||typeof c!="object")continue;const u=c,a=typeof u.role=="string"?u.role:"";if(a==="")continue;const f=typeof u.timestamp=="number"?u.timestamp:void 0,l=typeof r.timestamp=="string"?r.timestamp:f!==void 0?new Date(f).toISOString():"",m=T(u.content),b={index:i.length,role:a,text:m,ts:l,tsMs:f??x(l)};if(a==="user"){const w=f!==void 0&&t.has(f)?t.get(f):null;b.origin=F(w);const h=L(w);h!==void 0&&(b.from=h)}i.push(b)}return i}d($,"sessionMessages");async function J(n,s){const e=(await g().read(y(n))).entries;let t=0;for(const i of e){if(i.type!=="message")continue;const o=i.message;if(!(o===null||typeof o!="object"||typeof o.role!="string")){if(t===s)return JSON.stringify(i);t++}}return null}d(J,"rawSessionLine");function K(n,s,e){const t=`session/${String(e.index).padStart(6,"0")}`,i=e.text.split(`
|
|
9
|
+
`).map(r=>r.trim()).find(r=>r!=="")??"",o={ref:`${n.node_id}:${t}`,nodeId:n.node_id,relpath:t,source:"transcript",ts:e.ts,tsMs:e.tsMs,title:`[${e.role}] ${i.length>80?`${i.slice(0,80)}\u2026`:i}`,nodeName:n.name,nodeKind:n.kind,nodeStatus:n.status,nodeCwd:n.cwd,nodeDesc:s,loadBody:d(()=>e.text,"loadBody"),role:e.role};return e.origin!==void 0&&(o.origin=e.origin),e.from!==void 0&&(o.from=e.from),o}d(K,"transcriptArtifact");async function W(n){return(await p(n))?.description??""}d(W,"nodeDescOf");async function tn(n,s){const e=await P(n),t=s.kinds,i=s.statuses,o=e.filter(a=>!(t!==void 0&&t.length>0&&!t.includes(a.kind)||i!==void 0&&i.length>0&&!i.includes(a.status))),r=s.types!==void 0&&s.types.length>0?s.types:["inbox"],c=new Set(r),u=[];for(const a of o){const f=await W(a.node_id);if(c.has("inbox")&&await B(await k(a.node_id),async(l,m)=>u.push(await D(a,f,l,m))),c.has("transcript"))for(const l of await $(a.node_id))u.push(K(a,f,l))}return u.filter(a=>s.sinceMs!==void 0&&a.tsMs<s.sinceMs||s.untilMs!==void 0&&a.tsMs>s.untilMs?!1:G(a,s))}d(tn,"buildCorpus");function G(n,s){const{origins:e,roles:t,from:i}=s;return!(e!==void 0&&e.length>0&&(n.origin===void 0||!e.includes(n.origin))||t!==void 0&&t.length>0&&(n.role===void 0||!t.includes(n.role))||i!==void 0&&i!==""&&(n.from===void 0||!n.from.toLowerCase().includes(i.toLowerCase())))}d(G,"matchesMessageFilters");function sn(n,s){const e=new Map;for(const t of n){let i;switch(s){case"origin":i=t.origin;break;case"role":i=t.role;break;case"node":i=`${t.nodeName} (${t.nodeId})`;break;case"kind":i=t.nodeKind;break;case"type":i=t.source;break;case"day":i=t.ts.slice(0,10)||void 0;break}i===void 0||i===""||e.set(i,(e.get(i)??0)+1)}return[...e.entries()].map(([t,i])=>({key:t,count:i})).sort((t,i)=>i.count-t.count||t.key.localeCompare(i.key))}d(sn,"groupCorpus");async function P(n){const s=await j(),e=new Map(s.map(i=>[i.node_id,i]));if(n.nodes!==void 0&&n.nodes.length>0)return n.nodes.map(i=>e.get(i)).filter(i=>i!==void 0);if(n.under!==void 0&&n.under!=="")return[n.under,...await v(n.under)].map(o=>e.get(o)).filter(o=>o!==void 0);if(n.allCwds===!0)return s;const t=n.cwd!==void 0&&n.cwd!==""?n.cwd:await R();return s.filter(i=>i.cwd===t)}d(P,"scopedRows");async function on(n){const s=n.indexOf(":");if(s===-1)return null;const e=n.slice(0,s),t=n.slice(s+1),i=await p(e);if(i===null)return null;if(t.startsWith("inbox/")){const o=Number(t.slice(6)),r=(await k(e))[o];return r===void 0?null:{nodeId:e,relpath:t,source:"inbox",ts:r.ts,nodeName:i.name,body:await _(r),raw:null,path:null}}if(t==="session"||t.startsWith("session/")){const o=await N(e);if(o===null)return null;const r=await $(e);if(t==="session"){const a=r.map(f=>`## ${f.role}${f.origin!==void 0?` (origin: ${f.origin})`:""}
|
|
10
10
|
|
|
11
|
-
${
|
|
11
|
+
${f.text}`).join(`
|
|
12
12
|
|
|
13
|
-
`);return{nodeId:e,relpath:t,source:"transcript",ts:r[r.length-1]?.ts??i.created,nodeName:i.name,body:
|
|
14
|
-
`).join("")})(),path:o}}const c=Number(t.slice(8)),
|
|
13
|
+
`);return{nodeId:e,relpath:t,source:"transcript",ts:r[r.length-1]?.ts??i.created,nodeName:i.name,body:a,raw:await(async()=>{const{header:f,entries:l}=await g().read(y(o));return[f,...l].map(m=>`${JSON.stringify(m)}
|
|
14
|
+
`).join("")})(),path:o}}const c=Number(t.slice(8)),u=r[c];return u===void 0?null:{nodeId:e,relpath:t,source:"transcript",ts:u.ts,nodeName:i.name,body:u.text,raw:await J(o,c),path:o}}return null}d(on,"resolveRef");export{en as MESSAGE_ROLES,nn as ORIGIN_TOKENS,tn as buildCorpus,R as callerCwd,sn as groupCorpus,on as resolveRef};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
/** Find only terminal nodes with an unreconciled, explicitly disposable worktree.
|
|
1
|
+
/** Find only terminal nodes with an unreconciled, explicitly disposable worktree. A node that ever ran in a Blaxel sandbox
|
|
2
|
+
* is never a candidate: its sandbox is its worktree and the control plane has no checkout to sweep (D102).
|
|
2
3
|
* Keep due-time parsing in JS: Date.parse accepts more than SQLite's date
|
|
3
4
|
* functions, and malformed dates are due rather than permanently skipped. */
|
|
4
5
|
export declare function managedWorktreeSweepCandidates(now: number): Promise<string[]>;
|
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
var d=Object.defineProperty;var s=(t,o)=>d(t,"name",{value:o,configurable:!0});import{openDb as _}from"./db.js";async function
|
|
1
|
+
var d=Object.defineProperty;var s=(t,o)=>d(t,"name",{value:o,configurable:!0});import{openDb as _}from"./db.js";async function p(t){const o=await(await _()).prepare(`
|
|
2
2
|
SELECT w.node_id, w.sweep_observed_json, w.next_attempt_at,
|
|
3
3
|
w.abandoned_json, w.land_intent_json, w.disposal_json
|
|
4
4
|
FROM worktrees w
|
|
5
5
|
JOIN nodes n ON n.node_id = w.node_id
|
|
6
6
|
WHERE n.status IN ('done', 'dead', 'canceled')
|
|
7
7
|
AND n.node_id NOT IN (SELECT node_id FROM warm_pool)
|
|
8
|
+
AND NOT EXISTS (SELECT 1 FROM executions e WHERE e.node_id = n.node_id AND e.runner = 'blaxel')
|
|
8
9
|
AND w.state IN ('open', 'closed')
|
|
9
10
|
AND (w.state = 'open' OR w.cleanup_state IS NULL OR w.cleanup_state != 'complete')
|
|
10
11
|
AND (w.state = 'closed' OR (n.status = 'done' AND n.final_report IS NOT NULL))
|
|
11
12
|
ORDER BY n.created
|
|
12
|
-
`).all(),a=[];for(const e of o){try{for(const n of[e.sweep_observed_json,e.abandoned_json,e.land_intent_json,e.disposal_json])n!==null&&JSON.parse(n)}catch{continue}if(e.sweep_observed_json!==null&&e.next_attempt_at!==null){const n=Date.parse(e.next_attempt_at);if(!Number.isNaN(n)&&n>t)continue}a.push(e.node_id)}return a}s(
|
|
13
|
+
`).all(),a=[];for(const e of o){try{for(const n of[e.sweep_observed_json,e.abandoned_json,e.land_intent_json,e.disposal_json])n!==null&&JSON.parse(n)}catch{continue}if(e.sweep_observed_json!==null&&e.next_attempt_at!==null){const n=Date.parse(e.next_attempt_at);if(!Number.isNaN(n)&&n>t)continue}a.push(e.node_id)}return a}s(p,"managedWorktreeSweepCandidates");export{p as managedWorktreeSweepCandidates};
|
|
@@ -9,10 +9,7 @@ export interface NodePrincipal {
|
|
|
9
9
|
client_id: string | null;
|
|
10
10
|
scopes: string[] | null;
|
|
11
11
|
}
|
|
12
|
-
export declare function mintNodeToken(db: CanvasDb, executionId: string, nodeId: string, issuedAt: string): Promise<
|
|
13
|
-
/** Called exactly once by the host at spawn, never serialized into a launch recipe. */
|
|
14
|
-
export declare function takeNodeToken(executionId: string): string;
|
|
15
|
-
export declare function forgetNodeToken(executionId: string): void;
|
|
12
|
+
export declare function mintNodeToken(db: CanvasDb, executionId: string, nodeId: string, issuedAt: string): Promise<string>;
|
|
16
13
|
/** A stopped or superseded execution can never authenticate, even after restart. */
|
|
17
14
|
export declare function resolveNodeToken(token: string): Promise<NodePrincipal | null>;
|
|
18
15
|
export declare function revokeExitedNodeToken(executionId: string): Promise<void>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
var E=Object.defineProperty;var
|
|
1
|
+
var E=Object.defineProperty;var r=(n,e)=>E(n,"name",{value:e,configurable:!0});import{createHash as g,randomBytes as l}from"node:crypto";import{openDb as d}from"./db.js";import{terminalGrant as k}from"../grants/mirror.js";import{personId as N}from"./person.js";import{uidForApp as w}from"../spaces/users.js";const c=r(n=>g("sha256").update(n).digest("hex"),"hash");async function b(n,e,o,i){const t=await n.prepare("SELECT grantee, sub, grant_id, client_id, scopes_json, run_id FROM node_rows WHERE node_id = ?").get(o);if(!t)throw new Error(`cannot mint node token: missing node ${o}`);const a=t.run_id&&t.run_id!==o?await n.prepare("SELECT sub, grant_id, client_id FROM nodes WHERE node_id = ?").get(t.run_id):void 0,s=t.grantee==="app:terminal"?await k():null;if(t.grantee==="app:terminal"&&!s)throw new Error("cannot mint node token: terminal grant is not active");const u=s?.sub??a?.sub??t.sub??N(),p=s?.id??a?.grant_id??t.grant_id??null,_=l(32).toString("base64url");if(!await n.prepare("SELECT 1 AS ok FROM executions WHERE execution_id = ? AND node_id = ? AND state = 'launching'").get(e,o))throw new Error(`cannot mint node token: execution ${e} is not launching`);return await n.prepare('INSERT INTO node_tokens (broker_process_id, node_id, token_hash, grantee, uid, sub, "grant", client_id, scopes_json, issued_at, revoked_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, NULL)').run(e,o,c(_),t.grantee,await w(t.grantee),u,p,a?.client_id??t.client_id,t.scopes_json,i),_}r(b,"mintNodeToken");async function x(n){if(!/^[A-Za-z0-9_-]{43}$/.test(n))return null;const e=await(await d()).prepare(`SELECT t.node_id, t.grantee, t.uid, t.sub, t."grant", t.client_id, t.scopes_json, n.run_id
|
|
2
2
|
FROM node_tokens t JOIN executions e ON e.execution_id = t.broker_process_id
|
|
3
3
|
JOIN nodes n ON n.node_id = t.node_id
|
|
4
|
-
WHERE t.token_hash = ? AND t.revoked_at IS NULL AND e.state != 'exited'`).get(c(
|
|
5
|
-
AND broker_process_id IN (SELECT execution_id FROM executions WHERE daemon_epoch IS DISTINCT FROM ?)`).run(new Date().toISOString(),
|
|
4
|
+
WHERE t.token_hash = ? AND t.revoked_at IS NULL AND e.state != 'exited'`).get(c(n));return e?{app:e.grantee,node:e.node_id,run:e.run_id,uid:e.uid,sub:e.sub,grant:e.grant,client_id:e.client_id,scopes:e.scopes_json===null?null:JSON.parse(e.scopes_json)}:null}r(x,"resolveNodeToken");async function A(n){await m(await d(),"broker_process_id",n,new Date().toISOString())}r(A,"revokeExitedNodeToken");async function D(n){await(await d()).prepare(`UPDATE node_tokens SET revoked_at = ? WHERE revoked_at IS NULL
|
|
5
|
+
AND broker_process_id IN (SELECT execution_id FROM executions WHERE daemon_epoch IS DISTINCT FROM ?)`).run(new Date().toISOString(),n)}r(D,"revokePriorEpochNodeTokens");async function m(n,e,o,i){await n.prepareUncached(`UPDATE node_tokens SET revoked_at = ? WHERE ${e} = ? AND revoked_at IS NULL`).run(i,o)}r(m,"revokeNodeTokens");export{b as mintNodeToken,x as resolveNodeToken,A as revokeExitedNodeToken,m as revokeNodeTokens,D as revokePriorEpochNodeTokens};
|
|
@@ -71,7 +71,6 @@ export declare function inboxPath(nodeId: string): string;
|
|
|
71
71
|
export declare function situationalContextPath(nodeId: string): string;
|
|
72
72
|
export declare function passivePath(nodeId: string): string;
|
|
73
73
|
export declare function transcriptPath(nodeId: string): string;
|
|
74
|
-
export declare function sessionPtrPath(nodeId: string): string;
|
|
75
74
|
/** Create the full directory skeleton for a node. Idempotent. The agent and
|
|
76
75
|
* run folders are app-writable, so their subfolders are made beneath them. */
|
|
77
76
|
export declare function ensureNodeDirs(nodeId: string, grantee: string): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var v=Object.defineProperty;var e=(t,n)=>v(t,"name",{value:n,configurable:!0});import{join as r}from"node:path";import{mkdirSync as c}from"node:fs";import{appSpace as f,runtimeRoot as
|
|
1
|
+
var v=Object.defineProperty;var e=(t,n)=>v(t,"name",{value:n,configurable:!0});import{join as r}from"node:path";import{mkdirSync as c}from"node:fs";import{appSpace as f,runtimeRoot as k,socketDir as m}from"../layout.js";import{envGrantee as E,envNodeId as P}from"../../shared/env.js";import{withDirBeneath as h}from"../spaces/open-beneath.js";function i(){return k()}e(i,"crtrHome");function B(){return r(i(),"canvas.db")}e(B,"canvasDbPath");function C(){return r(i(),"on-disk-migration.lock")}e(C,"onDiskMigrationLockPath");function L(){return r(i(),"on-disk-migrations.json")}e(L,"onDiskMigrationMarkerPath");function H(t){return r(s(t),"view.sock")}e(H,"viewSocketPath");function l(){return r(i(),"nodes")}e(l,"nodesRoot");function b(){return r(i(),"reviews")}e(b,"reviewsRoot");function D(t){return p(t),r(b(),t)}e(D,"reviewDir");function K(t){return r(D(t),"result.json")}e(K,"reviewResultPath");function $(t){c(D(t),{recursive:!0,mode:448})}e($,"ensureReviewDir");function F(){return r(m(),"api.sock")}e(F,"apiSocketPath");function G(){return r(i(),"session-list-cache.json")}e(G,"sessionListCachePath");const j=128;function w(t){return typeof t=="string"&&t!==""&&t!=="."&&t!==".."&&!/[\\/\0]/u.test(t)&&Buffer.byteLength(t,"utf8")<=j}e(w,"isSafeNodeId");function p(t){if(!w(t))throw new TypeError("node_id must be a non-empty path segment of at most 128 UTF-8 bytes")}e(p,"assertSafeNodeId");function a(t){return p(t),r(l(),t)}e(a,"nodeRecordDir");const u=a;function x(t,n){p(t);const o=n??(P()===t?E():void 0);if(!o)throw new Error(`node ${t} has no app assignment`);return r(f(o).nodes,t)}e(x,"nodeAgentDir");function _(t,n){return r(x(t,n),"home")}e(_,"isolatedNodeHome");function X(t,n,o){return o?_(t,n):f(n).home}e(X,"nodeHome");function s(t){return p(t),process.platform==="linux"?r(m(),"nodes",t):r(a(t),"run")}e(s,"nodeRunDir");const Y="broker-released",J="cli-relay-generation";function U(t){return r(s(t),"scopes.json")}e(U,"scopesFilePath");function g(t,n){return r(x(t,n),"context")}e(g,"contextDir");function q(t,n,o){return t.replaceAll("$CRTR_CONTEXT_DIR",g(n,o)).replaceAll("$CRTR_NODE_ID",n)}e(q,"interpolateNodePaths");function N(t){return r(a(t),"job")}e(N,"jobDir");function A(t){return r(s(t),"job")}e(A,"nodeRunJobDir");function z(t){return r(u(t),"messages")}e(z,"messagesDir");function Q(t){return r(u(t),"meta.json")}e(Q,"nodeMetaPath");function V(t){return r(u(t),"inbox.jsonl")}e(V,"inboxPath");function W(t){return r(s(t),"situational-context.md")}e(W,"situationalContextPath");function Z(t){return r(u(t),"passive.jsonl")}e(Z,"passivePath");function I(t){return r(u(t),"transcript.jsonl")}e(I,"transcriptPath");function tt(t,n){const o=x(t,n);c(a(t),{recursive:!0}),c(N(t),{recursive:!0});for(const R of["context","reports","attachments","worktree"])h(f(n).nodes,r(o,R),()=>{},!0);h(s(t),A(t),()=>{},!0)}e(tt,"ensureNodeDirs");function et(){c(l(),{recursive:!0})}e(et,"ensureHome");export{J as BROKER_RELAY_GENERATION,Y as BROKER_RELEASED_MARKER,F as apiSocketPath,B as canvasDbPath,g as contextDir,i as crtrHome,et as ensureHome,tt as ensureNodeDirs,$ as ensureReviewDir,V as inboxPath,q as interpolateNodePaths,w as isSafeNodeId,_ as isolatedNodeHome,N as jobDir,z as messagesDir,x as nodeAgentDir,u as nodeDir,X as nodeHome,Q as nodeMetaPath,a as nodeRecordDir,s as nodeRunDir,A as nodeRunJobDir,l as nodesRoot,C as onDiskMigrationLockPath,L as onDiskMigrationMarkerPath,Z as passivePath,D as reviewDir,K as reviewResultPath,b as reviewsRoot,U as scopesFilePath,G as sessionListCachePath,W as situationalContextPath,I as transcriptPath,H as viewSocketPath};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/** Thrown by `personId()` before the person is known (a hosted first boot, before its first grant snapshot). */
|
|
2
|
+
export declare class PersonUnresolvedError extends Error {
|
|
3
|
+
readonly code = "person_unresolved";
|
|
4
|
+
constructor();
|
|
5
|
+
}
|
|
6
|
+
/** Thrown by `personId()` on a cloud role (`crtrd --role api|reconcile`) outside a request: the control plane serves many people and
|
|
7
|
+
* has no install person to fall back to. A lane that works for a person takes the person from the row it claimed. */
|
|
8
|
+
export declare class PersonOutsideRequestError extends Error {
|
|
9
|
+
readonly code = "person_outside_request";
|
|
10
|
+
constructor();
|
|
11
|
+
}
|
|
12
|
+
/** crtrd sets this once at boot; it wins unconditionally. */
|
|
13
|
+
export declare function setPersonId(id: string): void;
|
|
14
|
+
/** crtrd calls this at boot on a cloud role, instead of resolving a person: from then on a person read outside a request throws. */
|
|
15
|
+
export declare function markCloudRole(): void;
|
|
16
|
+
/** Whether this process is a cloud role (`markCloudRole` ran at boot). */
|
|
17
|
+
export declare function isCloudRole(): boolean;
|
|
18
|
+
/** Run `fn` as `person` (`user:<id>`, the request token's `sub`): every `personId()` inside it, across awaits, answers `person`. */
|
|
19
|
+
export declare function runAsPerson<T>(person: string, fn: () => T): T;
|
|
20
|
+
/** The request's person; else, on a Mac, the boot-set person. Throws `PersonOutsideRequestError` on a cloud role outside a request and
|
|
21
|
+
* `PersonUnresolvedError` when a Mac's person is not bound. Tests and non-daemon processes use `personIdAsync()`. */
|
|
22
|
+
export declare function personId(): string;
|
|
23
|
+
/** The boot-set person, if any (for `personIdAsync`). */
|
|
24
|
+
export declare function bootPersonId(): string | undefined;
|
|
25
|
+
/** The request's person, if any (for `personIdAsync`). */
|
|
26
|
+
export declare function requestPersonId(): string | undefined;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var u=Object.defineProperty;var r=(e,n)=>u(e,"name",{value:n,configurable:!0});import{AsyncLocalStorage as d}from"node:async_hooks";class i extends Error{static{r(this,"PersonUnresolvedError")}code="person_unresolved";constructor(){super("the install's person is not resolved yet"),this.name="PersonUnresolvedError"}}class c extends Error{static{r(this,"PersonOutsideRequestError")}code="person_outside_request";constructor(){super("no person: a cloud role reads the person only inside a request, from its token"),this.name="PersonOutsideRequestError"}}let o,t=!1;const s=new d;function f(e){o=e}r(f,"setPersonId");function a(){t=!0}r(a,"markCloudRole");function x(){return t}r(x,"isCloudRole");function P(e,n){return s.run(e,n)}r(P,"runAsPerson");function m(){const e=s.getStore();if(e!==void 0)return e;if(t)throw new c;if(o===void 0)throw new i;return o}r(m,"personId");function q(){return o}r(q,"bootPersonId");function h(){return s.getStore()}r(h,"requestPersonId");export{c as PersonOutsideRequestError,i as PersonUnresolvedError,q as bootPersonId,x as isCloudRole,a as markCloudRole,m as personId,h as requestPersonId,P as runAsPerson,f as setPersonId};
|
|
@@ -1,17 +1,10 @@
|
|
|
1
|
+
import { PersonUnresolvedError, PersonOutsideRequestError, setPersonId, markCloudRole, isCloudRole, runAsPerson, personId } from './person-state.js';
|
|
1
2
|
import { type CanvasDb } from './db.js';
|
|
2
3
|
import { LEGACY_LOCAL_PERSON } from './legacy-person.js';
|
|
3
4
|
export { LEGACY_LOCAL_PERSON };
|
|
4
|
-
/** Thrown by `personId()` before the person is known (a hosted first boot, before its first grant snapshot). */
|
|
5
|
-
export declare class PersonUnresolvedError extends Error {
|
|
6
|
-
readonly code = "person_unresolved";
|
|
7
|
-
constructor();
|
|
8
|
-
}
|
|
9
5
|
export type PersonSource = 'stored' | 'joined' | 'grants' | 'minted';
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
/** The boot-set person. Throws `PersonUnresolvedError` when unset. Tests and non-daemon processes use `personIdAsync()`. */
|
|
13
|
-
export declare function personId(): string;
|
|
14
|
-
/** Lazy get-or-create keyed by the active canvas database, for processes that are not the daemon. */
|
|
6
|
+
export { PersonUnresolvedError, PersonOutsideRequestError, setPersonId, markCloudRole, isCloudRole, runAsPerson, personId };
|
|
7
|
+
/** As `personId()`, but a process that is not the daemon gets a lazy get-or-create keyed by the active canvas database. */
|
|
15
8
|
export declare function personIdAsync(): Promise<string>;
|
|
16
9
|
/** Get-or-create the person and say where it came from. Order: stored, the join file's owner, the single `sub` of the
|
|
17
10
|
* mirrored grants (a runtime with an issuer and no join file), else a minted id on a runtime without an issuer.
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
var
|
|
1
|
+
var H=Object.defineProperty;var c=(n,e)=>H(n,"name",{value:e,configurable:!0});import{randomBytes as W}from"node:crypto";import{CrtrError as T}from"../errors.js";import{PersonUnresolvedError as g,PersonOutsideRequestError as A,setPersonId as y,markCloudRole as b,isCloudRole as D,runAsPerson as v,personId as $,bootPersonId as k,requestPersonId as C}from"./person-state.js";import{readConfig as S}from"../config.js";import{joinedOwner as j}from"../directory/join.js";import{installLocalTerminalGrant as M}from"../grants/local.js";import{dropLocalGrantMirror as F}from"../grants/mirror.js";import{ownerForGrantee as x,ensureOwner as G}from"../graph/objects.js";import{canvasDatabaseUrl as J,CanvasConstraintError as q,withCanvasWrite as h}from"./db.js";import{LEGACY_LOCAL_PERSON as E,LEGACY_LOCAL_TERMINAL_GRANT as B}from"./legacy-person.js";import{rebuildTotalsFor as Y}from"../ledger/totals.js";const l="person_id",O="local_person_retired",z=/^user:[A-Za-z0-9._-]+$/,I="abcdefghijklmnopqrstuvwxyz0123456789",L=new Map;async function me(){const n=C();if(n!==void 0)return n;if(D())throw new A;const e=k();if(e!==void 0)return e;const r=await J(),t=L.get(r);if(t!==void 0)return t;const a=await V();if(a===null)throw new g;return L.set(r,a),a}c(me,"personIdAsync");function K(){const n=W(12);let e="user:";for(let r=0;r<12;r++)e+=I[n[r]%I.length];return e}c(K,"mintPersonId");async function m(n,e){return(await n.prepare("SELECT value FROM canvas_meta WHERE key = ?").get(e))?.value??null}c(m,"readMeta");async function d(n,e,r){await n.prepare("INSERT INTO canvas_meta (key, value) VALUES (?, ?) ON CONFLICT(key) DO UPDATE SET value = excluded.value").run(e,r)}c(d,"writeMeta");async function X(){return await h(async n=>{const e=await m(n,l);if(e!==null)return{id:e,source:"stored"};const r=j();if(r!==null)return await d(n,l,r),{id:r,source:"joined"};if(S("user").runtime?.issuer){const a=await n.prepare("SELECT DISTINCT sub FROM grants").all();return a.length!==1?null:(await d(n,l,a[0].sub),{id:a[0].sub,source:"grants"})}const t=K();return await d(n,l,t),{id:t,source:"minted"}})}c(X,"resolvePerson");async function V(){return(await X())?.id??null}c(V,"resolvePersonId");const o=c(n=>Number(n.changes),"changes"),Z=[["nodes","sub"],["node_tokens","sub"],["grants","sub"],["crons","sub"],["audit_rows","sub"],["provider_approvals","sub"],["audit_rows","grantee"],["run_events","grantee"],["node_tokens","grantee"],["uploads","grantee"],["provider_approvals","grantee"]],Q=["profiles","profile_defaults","scope_settings","scope_bookkeeping","scope_marketplaces","scope_plugins","person_settings","model_accounts","model_account_cooldowns","model_api_keys","model_settings","model_sign_in_flows","env_vars"],ee=[["charges","sub"],["charges","payer"],["charges","grantee"],["limits","payer"],["limits","sub"],["limits","grantee"]];function P(n,e){if(!z.test(e))throw new T("invalid_person",`${n} must be a user:<id> principal, got ${JSON.stringify(e)}`)}c(P,"assertPerson");async function ne(n,e){return await n.prepare("SELECT 1 AS found FROM charge_totals WHERE payer = ? OR sub = ? OR grantee = ? UNION ALL SELECT 1 FROM charge_chunks WHERE payer = ? LIMIT 1").get(e,e,e,e)!==void 0}c(ne,"namesPerson");async function U(n,e,r){if(P("from",e),P("to",r),e===r)throw new T("invalid_person","cannot substitute a person with itself");const t={};try{t.identities=o(await n.prepare("UPDATE identities SET scheme = 'user', external_id = ? WHERE scheme IN ('local-user', 'user') AND external_id = ?").run(r,e))}catch(s){throw s instanceof q?new T("person_conflict",`another person object already holds ${r}; merging two person objects is not supported (${s.message})`,void 0,{from:e,to:r}):s}t["daemon_actions.principal_sub"]=o(await n.prepare(`UPDATE daemon_actions SET adapter_json = jsonb_set(adapter_json::jsonb, '{principal,sub}', to_jsonb(?::text))::text
|
|
2
2
|
WHERE state IN ('pending', 'handed_off') AND adapter_json::jsonb ->> 'adapter' = 'cron_spawn'
|
|
3
|
-
AND adapter_json::jsonb #>> '{principal,sub}' = ?`).run(r,
|
|
3
|
+
AND adapter_json::jsonb #>> '{principal,sub}' = ?`).run(r,e));for(const[s,i]of Z)t[`${s}.${i}`]=o(await n.prepareUncached(`UPDATE ${s} SET ${i} = ? WHERE ${i} = ?`).run(r,e));t["idempotency_keys.grantee"]=o(await n.prepare("DELETE FROM idempotency_keys WHERE grantee = ? AND key IN (SELECT key FROM idempotency_keys WHERE grantee = ?)").run(e,r))+o(await n.prepare("UPDATE idempotency_keys SET grantee = ? WHERE grantee = ?").run(r,e));const a=e.replace(/^user:/,""),p=r.replace(/^user:/,"");t["relations.subject_id"]=o(await n.prepare(`DELETE FROM relations r WHERE r.subject_type = 'user' AND r.subject_id = ?
|
|
4
4
|
AND EXISTS (SELECT 1 FROM relations n WHERE n.subject_type = 'user' AND n.subject_id = ? AND n.resource_type = r.resource_type
|
|
5
|
-
AND n.resource_id = r.resource_id AND n.relation = r.relation AND n.subject_relation = r.subject_relation)`).run(a,p))+
|
|
6
|
-
WHERE o.type = 'node' AND i.scheme = 'local-user' AND i.external_id = '${
|
|
5
|
+
AND n.resource_id = r.resource_id AND n.relation = r.relation AND n.subject_relation = r.subject_relation)`).run(a,p))+o(await n.prepare("UPDATE relations SET subject_id = ? WHERE subject_type = 'user' AND subject_id = ?").run(p,a)),t["relations.written_by"]=o(await n.prepare("UPDATE relations SET written_by = ? WHERE written_by = ?").run(r,e)),t["revisions.acting_for"]=o(await n.prepare("UPDATE revisions SET acting_for = ? WHERE acting_for = ?").run(r,e));for(const[s,i]of ee)t[`${s}.${i}`]=o(await n.prepareUncached(`UPDATE ${s} SET ${i} = ? WHERE ${i} = ?`).run(r,e));for(const s of Q){const u=o(await n.prepareUncached(`DELETE FROM ${s} WHERE person = ? AND EXISTS (SELECT 1 FROM ${s} WHERE person = ?)`).run(e,r))+o(await n.prepareUncached(`UPDATE ${s} SET person = ? WHERE person = ?`).run(r,e));u!==0&&(t[`${s}.person`]=u)}return(Object.entries(t).some(([s,i])=>s.startsWith("charges.")&&i!==0)||await ne(n,e))&&(await Y(n,e,r),t["charge_totals.rebuilt"]=1),t}c(U,"substitutePerson");async function re(n){const e=`SELECT o.id FROM objects o JOIN identities i ON i.object = o.owner JOIN nodes n ON n.node_id = o.id
|
|
6
|
+
WHERE o.type = 'node' AND i.scheme = 'local-user' AND i.external_id = '${E}'`;return(await n.prepareUncached(`${e} LIMIT 1`).get()!==void 0?o(await n.prepareUncached(`UPDATE objects SET owner = ? WHERE id IN (${e})`).run((await x(n,"app:terminal")).id)):0)+o(await n.prepare("UPDATE node_tokens SET grantee = 'app:terminal' WHERE grantee = ?").run(E))+o(await n.prepare("UPDATE run_events SET grantee = 'app:terminal' WHERE grantee = ?").run(E))+o(await n.prepare("DELETE FROM idempotency_keys WHERE grantee = ? AND key IN (SELECT key FROM idempotency_keys WHERE grantee = 'app:terminal')").run(E))+o(await n.prepare("UPDATE idempotency_keys SET grantee = 'app:terminal' WHERE grantee = ?").run(E))}c(re,"rewriteLegacyGrantees");async function te(n,e,r){const t=[B,`terminal:${e}`].filter(i=>i!==r),a=t.map(()=>"?").join(", "),p={};p["nodes.grant_id"]=o(await n.prepareUncached(`UPDATE nodes SET grant_id = ? WHERE grant_id IN (${a})`).run(r,...t)),p["node_tokens.grant"]=o(await n.prepareUncached(`UPDATE node_tokens SET "grant" = ? WHERE "grant" IN (${a})`).run(r,...t)),p["crons.grant_id"]=o(await n.prepareUncached(`UPDATE crons SET grant_id = ? WHERE grant_id IN (${a})`).run(r,...t));const s=r===null?"'null'::jsonb":"to_jsonb(?::text)";return p["daemon_actions.principal_grant_id"]=o(await n.prepareUncached(`UPDATE daemon_actions SET adapter_json = jsonb_set(adapter_json::jsonb, '{principal,grant_id}', ${s})::text
|
|
7
7
|
WHERE state IN ('pending', 'handed_off') AND adapter_json::jsonb ->> 'adapter' = 'cron_spawn'
|
|
8
|
-
AND adapter_json::jsonb #>> '{principal,grant_id}' IN (${a})`).run(...r===null?[]:[r],...t)),p}
|
|
9
|
-
WHERE o.type = 'node' AND o.reception = 2 AND s.envelope_json ->> 'app' IS NULL AND i.scheme = 'app' AND i.external_id = 'app:terminal'`;if(await
|
|
8
|
+
AND adapter_json::jsonb #>> '{principal,grant_id}' IN (${a})`).run(...r===null?[]:[r],...t)),p}c(te,"repointGrantReferences");async function Te(){const n=await h(async e=>{const r={},t=c((_,w="")=>{for(const[N,R]of Object.entries(_))R!==0&&(r[w+N]=(r[w+N]??0)+R)},"add");let a=await m(e,l);if(a===null)throw new g;let p=null;const s=j();s!==null&&s!==a&&(t(await U(e,a,s),"join."),await d(e,l,s),p=a,a=s);const i=S("user").runtime?.issuer,u=await m(e,"install_id");if(u===null)throw new Error("retireLocalPerson: the install id is not stored");const f=await m(e,O)!==a;if(f){t({legacy_grantees:await re(e)}),t(await U(e,E,a));const _=`SELECT o.id FROM objects o JOIN peer_stubs s ON s.object = o.id JOIN identities i ON i.object = o.owner
|
|
9
|
+
WHERE o.type = 'node' AND o.reception = 2 AND s.envelope_json ->> 'app' IS NULL AND i.scheme = 'app' AND i.external_id = 'app:terminal'`;if(await e.prepareUncached(`${_} LIMIT 1`).get()!==void 0){const w=await G(e,"person","user",a,"user");t({repaired_stubs:o(await e.prepareUncached(`UPDATE objects SET owner = ? WHERE id IN (${_})`).run(w.id))})}t({"nodes.sub_null_terminal":o(await e.prepare(`UPDATE nodes SET sub = ? WHERE sub IS NULL AND node_id IN (
|
|
10
10
|
SELECT n.node_id FROM nodes n JOIN identities i ON i.object = n.app
|
|
11
|
-
WHERE i.scheme = 'app' AND i.external_id = 'app:terminal')`).run(a))}),t(await
|
|
11
|
+
WHERE i.scheme = 'app' AND i.external_id = 'app:terminal')`).run(a))}),t(await te(e,u,i?null:`terminal:${u}`)),i&&t({local_grant_mirror:await F(e)}),await d(e,O,a)}return i||await M(u,a),{person:a,joinedFrom:p,retired:f,columns:r}});return y(n.person),n}c(Te,"retireLocalPerson");export{E as LEGACY_LOCAL_PERSON,A as PersonOutsideRequestError,g as PersonUnresolvedError,D as isCloudRole,b as markCloudRole,$ as personId,me as personIdAsync,X as resolvePerson,V as resolvePersonId,Te as retireLocalPerson,v as runAsPerson,y as setPersonId,U as substitutePerson};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/** A claim owner is a fresh token for each attempt, not a process id: a timed-out worker cannot renew a successor's claim. */
|
|
2
|
+
export interface ReconcilerLease {
|
|
3
|
+
cursor: string | null;
|
|
4
|
+
}
|
|
5
|
+
/** Claim an unowned or expired lane/key; retain its cursor across owner changes. */
|
|
6
|
+
export declare function claimReconcilerLease(lane: string, key: string, owner: string, ttlMs: number): Promise<ReconcilerLease | undefined>;
|
|
7
|
+
/** Only the still-current claim may extend its lifetime. */
|
|
8
|
+
export declare function renewReconcilerLease(lane: string, key: string, owner: string, ttlMs: number): Promise<boolean>;
|
|
9
|
+
/** An expired owner cannot advance the cursor. Cursor changes and row work that require exact-once must share a transaction. */
|
|
10
|
+
export declare function advanceReconcilerCursor(lane: string, key: string, owner: string, cursor: string | null): Promise<boolean>;
|
|
11
|
+
/** Release only the current claim, preserving its cursor for the next worker. */
|
|
12
|
+
export declare function releaseReconcilerLease(lane: string, key: string, owner: string): Promise<boolean>;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
var u=Object.defineProperty;var a=(e,r)=>u(e,"name",{value:r,configurable:!0});import{openDb as i}from"./db.js";function c(e){if(!Number.isFinite(e)||e<=0)throw new Error("reconciler lease duration must be positive");return new Date(Date.now()+e).toISOString()}a(c,"expiry");async function E(e,r,n,t){const o=c(t),s=new Date().toISOString();return(await i()).prepare(`INSERT INTO reconciler_leases (lane, key, owner, expires_at)
|
|
2
|
+
VALUES (?, ?, ?, ?)
|
|
3
|
+
ON CONFLICT (lane, key) DO UPDATE SET owner = EXCLUDED.owner, expires_at = EXCLUDED.expires_at
|
|
4
|
+
WHERE reconciler_leases.expires_at <= ?
|
|
5
|
+
RETURNING cursor`).get(e,r,n,o,s)}a(E,"claimReconcilerLease");async function S(e,r,n,t){const o=c(t),s=new Date().toISOString();return(await(await i()).prepare(`UPDATE reconciler_leases SET expires_at = ?
|
|
6
|
+
WHERE lane = ? AND key = ? AND owner = ? AND expires_at > ?`).run(o,e,r,n,s)).changes===1}a(S,"renewReconcilerLease");async function N(e,r,n,t){return(await(await i()).prepare(`UPDATE reconciler_leases SET cursor = ?
|
|
7
|
+
WHERE lane = ? AND key = ? AND owner = ? AND expires_at > ?`).run(t,e,r,n,new Date().toISOString())).changes===1}a(N,"advanceReconcilerCursor");async function x(e,r,n){return(await(await i()).prepare(`UPDATE reconciler_leases SET expires_at = ?
|
|
8
|
+
WHERE lane = ? AND key = ? AND owner = ? AND expires_at > ?`).run(new Date(0).toISOString(),e,r,n,new Date().toISOString())).changes===1}a(x,"releaseReconcilerLease");export{N as advanceReconcilerCursor,E as claimReconcilerLease,x as releaseReconcilerLease,S as renewReconcilerLease};
|
|
@@ -105,11 +105,15 @@ export interface PendingProviderRetry {
|
|
|
105
105
|
fault: StoredFault;
|
|
106
106
|
/** When the fault row last changed (ISO) — the daemon's anchor for "due". */
|
|
107
107
|
updatedAt: string;
|
|
108
|
+
/** When a reconciler last claimed this fault for a nudge (ISO), or null. */
|
|
109
|
+
nudgedAt: string | null;
|
|
108
110
|
}
|
|
109
111
|
/** Every node with an active daemon-retried provider fault (connection,
|
|
110
112
|
* rate-limit, overloaded) and a pending episode on its live session binding.
|
|
111
113
|
* The daemon backstop reads this to find retries whose broker timer died. */
|
|
112
114
|
export declare function listPendingProviderRetries(): Promise<PendingProviderRetry[]>;
|
|
115
|
+
/** Claim one nudge of a fault: only the caller whose conditional UPDATE changes the row may send it, and a later claim waits out `graceMs`. */
|
|
116
|
+
export declare function claimFaultNudge(faultId: string, nowMs: number, graceMs: number): Promise<boolean>;
|
|
113
117
|
export declare function beginBootFaultAttempt(nodeId: string): Promise<BootFaultAttempt>;
|
|
114
118
|
/** Import legacy witness and recovery files inside the parent's one shared consolidation transaction. */
|
|
115
119
|
/** v98 — `notified_since` on a fault row: the episode start its fatal notice was published for.
|
|
@@ -23,4 +23,4 @@ CREATE TABLE IF NOT EXISTS node_faults (
|
|
|
23
23
|
);
|
|
24
24
|
CREATE UNIQUE INDEX IF NOT EXISTS idx_node_faults_active ON node_faults(node_id) WHERE active = 1;
|
|
25
25
|
CREATE UNIQUE INDEX IF NOT EXISTS idx_node_faults_episode ON node_faults(node_id) WHERE episode_state IS NOT NULL;
|
|
26
|
-
`)}o(me,"createFaultTable");function g(e,t){return typeof t=="string"&&e.includes(t)}o(g,"contains");function W(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}o(W,"isRecord");function q(e){if(!W(e)||typeof e.provider!="string"||e.provider===""||typeof e.model!="string"||e.model==="")return;const t=typeof e.status=="number"&&Number.isFinite(e.status)?e.status:void 0,n=typeof e.code=="string"||typeof e.code=="number"?e.code:void 0,r=typeof e.errno=="string"?e.errno:void 0,i=typeof e.body=="string"?e.body:void 0,a=le(e.ratelimit),d=Array.isArray(e.causes)?e.causes.flatMap(s=>{if(!W(s))return[];const E={...typeof s.message=="string"?{message:s.message}:{},...typeof s.status=="number"&&Number.isFinite(s.status)?{status:s.status}:{},...typeof s.code=="string"||typeof s.code=="number"?{code:s.code}:{},...typeof s.errno=="string"?{errno:s.errno}:{},...typeof s.body=="string"?{body:s.body}:{}};return Object.keys(E).length===0?[]:[E]}):void 0;return{provider:e.provider,model:e.model,...t===void 0?{}:{status:t},...n===void 0?{}:{code:n},...r===void 0?{}:{errno:r},...i===void 0?{}:{body:i},...d===void 0||d.length===0?{}:{causes:d},...a===void 0?{}:{ratelimit:a}}}o(q,"parseProviderError");function V(e){try{const t=JSON.parse(e);if(!g(fe,t.link)||typeof t.op!="string"||t.op===""||!g(ye,t.kind)||typeof t.message!="string"||typeof t.since!="string")return null;const n=Y(t.operation_id);if(!W(t.retry)||!g(Te,t.retry.disposition)||t.retry.by!==void 0&&!g(Ne,t.retry.by)||t.retry.attempt!==void 0&&typeof t.retry.attempt!="number"||t.retry.max!==void 0&&typeof t.retry.max!="number"||t.retry.nextAt!==void 0&&typeof t.retry.nextAt!="string"||t.anchorEntryId!==void 0&&(typeof t.anchorEntryId!="string"||t.anchorEntryId===""))return null;const r=t.providerError===void 0?void 0:q(t.providerError);return t.providerError!==void 0&&r===void 0?null:{link:t.link,op:t.op,kind:t.kind,retry:{disposition:t.retry.disposition,...t.retry.by===void 0?{}:{by:t.retry.by},...t.retry.attempt===void 0?{}:{attempt:t.retry.attempt},...t.retry.max===void 0?{}:{max:t.retry.max},...t.retry.nextAt===void 0?{}:{nextAt:t.retry.nextAt}},message:t.message,since:t.since,operation_id:n,...t.anchorEntryId===void 0?{}:{anchorEntryId:t.anchorEntryId},...r===void 0?{}:{providerError:r}}}catch{return null}}o(V,"parseLegacyFault");function Ae(e){const t=_e(e);try{return ue(t)}catch{return t}}o(Ae,"canonicalPath");function Se(e){try{const t=JSON.parse(e);if(!g(ge,t.state)||typeof t.sessionFile!="string"||t.sessionFile==="")return null;const n=JSON.stringify(t.fault),r=V(n);if(r===null||r.link!=="pi\u2192provider"||r.retry.disposition!=="auto"||r.retry.by!=="daemon")return null;const i=t.anchorEntryId;return i!==null&&typeof i!="string"||(r.anchorEntryId??null)!==i?null:{state:t.state,sessionFile:Ae(t.sessionFile),fault:r}}catch{return null}}o(Se,"parseLegacyEpisode");function Q(e){return e!==void 0?Y(e):K.current()??K.fresh(n=>n)}o(Q,"resolveOperationId");function xe(e){return e.slice(0,Ee)}o(xe,"clampMessage");function w(e){return e.link==="pi\u2192provider"&&e.retry.disposition==="auto"&&e.retry.by==="daemon"?3:e.retry.disposition==="fatal"?2:1}o(w,"faultPriority");function z(e){return{link:e.link,op:e.op,kind:e.kind,message:e.message,since:e.since,operationId:e.operation_id,anchorEntryId:e.anchorEntryId??null,retryDisposition:e.retry.disposition,retryBy:e.retry.by??null,retryAttempt:e.retry.attempt??null,retryMax:e.retry.max??null,retryNextAt:e.retry.nextAt??null,providerError:e.providerError===void 0?null:JSON.stringify(e.providerError)}}o(z,"encodeFault");function b(e){const t=e.provider_error_json,n=typeof t=="string"?q(JSON.parse(t)):void 0;if(typeof t=="string"&&n===void 0)throw new Error(`invalid provider error on stored fault ${e.fault_id}`);const r={disposition:e.retry_disposition,...e.retry_by===null?{}:{by:e.retry_by},...e.retry_attempt===null?{}:{attempt:e.retry_attempt},...e.retry_max===null?{}:{max:e.retry_max},...e.retry_next_at===null?{}:{nextAt:e.retry_next_at}};return{faultId:e.fault_id,link:e.link,op:e.op,kind:e.kind,message:e.message,since:e.since,operation_id:e.operation_id,retry:r,...e.anchor_entry_id===null?{}:{anchorEntryId:e.anchor_entry_id},...n===void 0?{}:{providerError:n},...typeof e.notified_since=="string"?{notifiedSince:e.notified_since}:{}}}o(b,"hydrateFault");async function L(e,t){const n=await e.prepare("SELECT * FROM node_faults WHERE node_id = ? AND active = 1").get(t);return n===void 0?null:b(n)}o(L,"activeFault");function P(e){if(!g(G,e.link))throw new Error(`fault link is not durable: ${e.link}`);return{link:e.link,op:e.op,kind:e.kind,retry:e.retry,message:xe(e.message),since:e.since??u(),operation_id:Q(e.operation_id),...typeof e.anchorEntryId=="string"&&e.anchorEntryId!==""?{anchorEntryId:e.anchorEntryId}:{},...e.providerError===void 0?{}:{providerError:e.providerError}}}o(P,"storedFault");function M(e,t){J({level:t.retry.disposition==="fatal"?"error":"warn",event:"fault.recorded",operation_id:t.operation_id,node_id:e,error_class:B(t),fields:{link:t.link,op:t.op,kind:t.kind,retry:t.retry,message:t.message,...t.anchorEntryId===void 0?{}:{anchor_entry_id:t.anchorEntryId},...t.providerError===void 0?{}:{provider_error:t.providerError}}})}o(M,"emitRecordedFault");const Z="INSERT INTO node_faults (fault_id, node_id, link, op, kind, message, since, operation_id, anchor_entry_id, retry_disposition, retry_by, retry_attempt, retry_max, retry_next_at, provider_error_json, active, episode_state, episode_binding_id, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";function ee(e,t,n,r,i){const a=z(n),d=u();return[e,t,a.link,a.op,a.kind,a.message,a.since,a.operationId,a.anchorEntryId,a.retryDisposition,a.retryBy,a.retryAttempt,a.retryMax,a.retryNextAt,a.providerError,r?1:0,i?.state??null,i?.bindingId??null,d,d]}o(ee,"faultInsertParams");async function te(e,t,n,r,i){const a=I();return await e.prepare(Z).run(...ee(a,t,n,r,i)),{...n,faultId:a}}o(te,"insertFault");async function D(e,t,n,r){const i=z(n);return await e.prepare("UPDATE node_faults SET link = ?, op = ?, kind = ?, message = ?, since = ?, operation_id = ?, anchor_entry_id = ?, retry_disposition = ?, retry_by = ?, retry_attempt = ?, retry_max = ?, retry_next_at = ?, provider_error_json = ?, episode_state = COALESCE(?, episode_state), episode_binding_id = COALESCE(?, episode_binding_id), updated_at = ? WHERE fault_id = ?").run(i.link,i.op,i.kind,i.message,i.since,i.operationId,i.anchorEntryId,i.retryDisposition,i.retryBy,i.retryAttempt,i.retryMax,i.retryNextAt,i.providerError,r?.state??null,r?.bindingId??null,u(),t),{...n,faultId:t}}o(D,"updateFault");async function U(e,t){await e.prepare("DELETE FROM node_faults WHERE fault_id = ? AND active = 0 AND episode_state IS NULL").run(t)}o(U,"deleteIfUnretained");async function ne(e,t,n,r){const i=await L(e,t);if(i===null){const a=await e.prepare("SELECT fault_id, link, kind, since, operation_id FROM node_faults WHERE node_id = ? AND active = 0 AND episode_state IS NOT NULL").get(t);return a!==void 0&&a.link===n.link&&a.kind===n.kind&&a.since===n.since&&a.operation_id===n.operation_id?(await e.prepare("UPDATE node_faults SET active = 1, updated_at = ? WHERE fault_id = ?").run(u(),a.fault_id),await D(e,a.fault_id,n)):await te(e,t,n,!0,r)}if(i.link===n.link&&i.kind===n.kind){const a=n.retry.disposition==="auto"?{...i.retry,...n.retry}:n.retry,d=i.retry.disposition===n.retry.disposition&&(n.retry.disposition!=="fatal"||i.message===n.message),s=d?i.since:n.since,E=await D(e,i.faultId,{...n,since:s,anchorEntryId:n.anchorEntryId??i.anchorEntryId,retry:a},r);return d||await e.prepare("UPDATE node_faults SET notified_since = NULL WHERE fault_id = ?").run(i.faultId),E}return i.link!==n.link&&w(i)>w(n)?null:(await e.prepare("UPDATE node_faults SET active = 0, updated_at = ? WHERE fault_id = ?").run(u(),i.faultId),await U(e,i.faultId),await te(e,t,n,!0,r))}o(ne,"replaceActiveFault");async function m(e,t,n){return(await e.prepare("SELECT binding_id FROM sessions WHERE node_id = ? AND session_id = ? AND unbound_at IS NULL").get(t,n))?.binding_id??null}o(m,"liveBinding");async function Xe(e,t){return await l(async n=>{const r=u();return(await n.prepare("UPDATE executions SET turn_progress_at = ? WHERE execution_id = ? AND state != 'exited' AND turn_open_at IS NOT NULL AND turn_closed_at IS NULL").run(r,e)).changes>0?!0:(await n.prepare("UPDATE executions SET turn_open_at = ?, turn_progress_at = ?, turn_closed_at = NULL, turn_end_reason = NULL WHERE execution_id = ? AND state != 'exited'").run(r,r,e)).changes>0})}o(Xe,"openTurn");async function $e(e){return(await(await p()).prepare("UPDATE executions SET turn_progress_at = ? WHERE execution_id = ? AND state != 'exited' AND turn_open_at IS NOT NULL AND turn_closed_at IS NULL").run(u(),e)).changes>0}o($e,"recordTurnProgress");async function je(e,t){return await l(async n=>{const r=u(),i=(await n.prepare("UPDATE executions SET turn_closed_at = ?, turn_end_reason = ? WHERE execution_id = ? AND state != 'exited' AND turn_open_at IS NOT NULL AND turn_closed_at IS NULL").run(r,t.endReason,e)).changes>0;if(i&&t.endReason==="settled"){const a="(SELECT node_id FROM executions WHERE execution_id = ?)";t.viewerPresent===!0?await n.prepare(`UPDATE nodes SET reply_at = ?, read_at = ? WHERE node_id = ${a}`).run(r,r,e):await n.prepare(`UPDATE nodes SET reply_at = ? WHERE node_id = ${a}`).run(r,e)}return i})}o(je,"closeTurn");async function Be(e){return(await(await p()).prepare("UPDATE nodes SET read_at = ? WHERE node_id = ?").run(u(),e)).changes>0}o(Be,"markNodeRead");async function Je(e,t){if(!Number.isInteger(t.consecutivePasses)||t.consecutivePasses<1||t.routes.length===0||!t.routes.every(n=>n!==""))throw new Error("invalid transport-poison verdict");return(await(await p()).prepare("UPDATE executions SET exit_diagnostic_json = ? WHERE execution_id = ? AND state != 'exited'").run(JSON.stringify({schema:"crtr.execution-exit-diagnostic/v1",transport_poison:{consecutive_passes:t.consecutivePasses,routes:t.routes}}),e)).changes>0}o(Je,"recordTransportPoisonVerdict");async function Ke(e){const t=await(await p()).prepare("SELECT exit_diagnostic_json FROM executions WHERE node_id = ? ORDER BY seq DESC LIMIT 1").get(e);if(t===void 0||t.exit_diagnostic_json===null)return null;try{const n=JSON.parse(t.exit_diagnostic_json),r=n.transport_poison;return n.schema!=="crtr.execution-exit-diagnostic/v1"||r===void 0||!Number.isInteger(r.consecutive_passes)||r.consecutive_passes<1||!Array.isArray(r.routes)||r.routes.length===0||!r.routes.every(i=>typeof i=="string"&&i!=="")?null:{consecutivePasses:r.consecutive_passes,routes:r.routes}}catch{return null}}o(Ke,"readTransportPoisonVerdict");async function Ye(e){const t=await(await p()).prepare("SELECT turn_open_at, turn_closed_at, turn_progress_at FROM executions WHERE node_id = ? AND state != 'exited'").get(e);return t===void 0?null:{busy:t.turn_open_at!==null&&t.turn_closed_at===null,progressAt:t.turn_progress_at}}o(Ye,"readLiveTurn");async function Ge(e){const t=await p(),n=await t.prepare("SELECT turn_closed_at, turn_progress_at FROM executions WHERE node_id = ? AND turn_open_at IS NOT NULL ORDER BY seq DESC LIMIT 1").get(e);if(n===void 0)return null;const r=await t.prepare("SELECT turn_end_reason FROM executions WHERE node_id = ? ORDER BY seq DESC LIMIT 1").get(e);return{interrupted:n.turn_closed_at===null||r?.turn_end_reason==="teardown-aborted",progressAt:n.turn_progress_at}}o(Ge,"readInterruptedTurn");async function qe(e){return await(await p()).prepare("SELECT 1 FROM executions WHERE node_id = ? AND turn_open_at IS NOT NULL LIMIT 1").get(e)!==void 0}o(qe,"hasAdmittedTurn");async function Ve(e,t){const n=P(t);return M(e,n),await l(async r=>await ne(r,e,n))}o(Ve,"recordFault");async function Qe(e){return await l(async t=>(await t.prepare("UPDATE node_faults SET notified_since = since, updated_at = ? WHERE fault_id = ?").run(u(),e)).changes>0)}o(Qe,"markFaultNotified");function Re(e){return e.link==="pi\u2192provider"&&e.retry.disposition==="fatal"&&e.notifiedSince!==e.since}o(Re,"isUnnotifiedFatalProviderFault");async function ze(){return(await(await p()).prepare("SELECT f.node_id FROM node_faults f JOIN nodes n ON n.node_id = f.node_id WHERE f.active = 1 AND f.link = 'pi\u2192provider' AND f.retry_disposition = 'fatal' AND (f.notified_since IS NULL OR f.notified_since != f.since) AND n.status IN ('active', 'idle')").all()).map(e=>e.node_id)}o(ze,"listUnnotifiedFatalFaultNodes");let X=null;function Ze(e){X=e}o(Ze,"setFatalFaultAnnouncer");async function et(e,t){const n=await L(await p(),e);return n===null||t?.link!==void 0&&n.link!==t.link?!1:await l(async r=>{const i=await L(r,e);if(i===null||t?.link!==void 0&&i.link!==t.link)return!1;X!==null&&Re(i)&&await X(e);const a=await r.prepare("SELECT episode_state FROM node_faults WHERE fault_id = ?").get(i.faultId);await r.prepare("UPDATE node_faults SET active = 0, updated_at = ? WHERE fault_id = ?").run(u(),i.faultId),a.episode_state==="pending"&&t?.preserveEpisode!==!0&&await r.prepare("UPDATE node_faults SET episode_state = NULL, episode_binding_id = NULL, updated_at = ? WHERE fault_id = ?").run(u(),i.faultId),await U(r,i.faultId);const d=Q();return J({level:"info",event:"fault.cleared",operation_id:d,node_id:e,error_class:B(i),fields:{cleared_fault_operation_id:i.operation_id,link:i.link,op:i.op,kind:i.kind,retry:i.retry,message:i.message,since:i.since,...i.anchorEntryId===void 0?{}:{anchor_entry_id:i.anchorEntryId}}}),!0})}o(et,"clearFault");async function re(e){return await L(await p(),e)}o(re,"readFault");async function tt(e,t){const n=P(t.input);if(n.link!=="pi\u2192provider"||n.retry.disposition!=="auto"||n.retry.by!=="daemon")throw new Error("provider retry episode requires an automatic daemon provider fault");return M(e,n),await l(async r=>{const i=await m(r,e,t.sessionId);if(i===null)return null;const a=await L(r,e);if(a!==null&&(a.link!==n.link||a.kind!==n.kind)&&w(a)>w(n))return null;const d=await r.prepare("SELECT fault_id FROM node_faults WHERE node_id = ? AND episode_state IS NOT NULL").all(e);await r.prepare("UPDATE node_faults SET episode_state = NULL, episode_binding_id = NULL, updated_at = ? WHERE node_id = ? AND episode_state IS NOT NULL").run(u(),e);for(const E of d)await U(r,E.fault_id);const s=await ne(r,e,n,{state:"pending",bindingId:i});return s===null?null:(await r.prepare("UPDATE node_faults SET episode_state = ?, episode_binding_id = ?, updated_at = ? WHERE fault_id = ?").run("pending",i,u(),s.faultId),s)})}o(tt,"recordPendingEpisode");async function nt(e,t){return await l(async n=>{if(await n.prepare("SELECT 1 FROM nodes WHERE node_id = ? AND intent = 'refresh'").get(e)!==void 0)return!1;const r=await m(n,e,t.sessionId);return r===null?!1:(await n.prepare("UPDATE node_faults SET episode_state = 'admitted', retry_disposition = ?, retry_by = ?, retry_attempt = ?, retry_max = ?, retry_next_at = ?, updated_at = ? WHERE node_id = ? AND fault_id = ? AND episode_state = 'pending' AND episode_binding_id = ?").run(t.retry.disposition,t.retry.by??null,t.retry.attempt??null,t.retry.max??null,t.retry.nextAt??null,u(),e,t.faultId,r)).changes>0})}o(nt,"admitEpisode");async function rt(e,t){const n=P(t.fault);return await l(async r=>{const i=await m(r,e,t.sessionId);return i===null||(await L(r,e))?.faultId!==t.faultId||await r.prepare("SELECT 1 FROM node_faults WHERE node_id = ? AND fault_id = ? AND episode_state = 'admitted' AND episode_binding_id = ?").get(e,t.faultId,i)===void 0?!1:(M(e,n),t.reopen?await D(r,t.faultId,n,{state:"pending",bindingId:i}):(await D(r,t.faultId,n),await r.prepare("UPDATE node_faults SET episode_state = NULL, episode_binding_id = NULL, updated_at = ? WHERE fault_id = ?").run(u(),t.faultId),await r.prepare("UPDATE node_faults SET notified_since = NULL WHERE fault_id = ?").run(t.faultId)),!0)})}o(rt,"settleRejectedEpisode");async function it(e,t){return await l(async n=>{const r=await m(n,e,t.sessionId);return r===null?!1:(await n.prepare("UPDATE node_faults SET episode_state = 'pending', updated_at = ? WHERE node_id = ? AND episode_state = 'admitted' AND episode_binding_id = ?").run(u(),e,r)).changes>0})}o(it,"reopenEpisode");async function ot(e,t){return await l(async n=>{const r=await m(n,e,t.sessionId);return r===null?!1:(await n.prepare("UPDATE node_faults SET episode_state = 'invalidated', updated_at = ? WHERE node_id = ? AND episode_state != 'invalidated' AND episode_state IS NOT NULL AND episode_binding_id = ?").run(u(),e,r)).changes>0})}o(ot,"invalidateEpisode");async function at(e,t){return await l(async n=>{const r=await m(n,e,t.sessionId);if(r===null)return!1;const i=await n.prepare("SELECT fault_id FROM node_faults WHERE node_id = ? AND episode_binding_id = ? AND episode_state IS NOT NULL").all(e,r);if(i.length===0)return!1;await n.prepare("UPDATE node_faults SET episode_state = NULL, episode_binding_id = NULL, updated_at = ? WHERE node_id = ? AND episode_binding_id = ? AND episode_state IS NOT NULL").run(u(),e,r);for(const a of i)await U(n,a.fault_id);return!0})}o(at,"clearEpisode");async function st(e){const t=await(await p()).prepare("SELECT f.*, s.session_id FROM node_faults f JOIN sessions s ON s.binding_id = f.episode_binding_id WHERE f.node_id = ? AND f.episode_state IS NOT NULL").get(e);return t===void 0?null:{state:t.episode_state,sessionId:t.session_id,fault:b(t)}}o(st,"readEpisode");async function dt(){return(await(await p()).prepare("SELECT f.*, s.session_id AS bound_session_id FROM node_faults f JOIN sessions s ON s.binding_id = f.episode_binding_id WHERE f.active = 1 AND f.episode_state = 'pending' AND s.unbound_at IS NULL AND s.session_id IS NOT NULL AND f.link = 'pi\u2192provider' AND f.retry_disposition = 'auto' AND f.retry_by = 'daemon' AND f.kind IN ('connection', 'rate-limit', 'overloaded')").all()).map(t=>({nodeId:t.node_id,sessionId:t.bound_session_id,fault:b(t),updatedAt:t.updated_at}))}o(dt,"listPendingProviderRetries");async function ut(e){const t=await re(e)===null;return{async explanation(){if(!t)return null;const n=await re(e);if(n===null||n.link!=="crtr\u2192pi"||n.retry.disposition!=="fatal")return null;const r=n.op.trim(),i=n.message.trim();return r===""||i===""?null:`${r}: ${i}`}}}o(ut,"beginBootFaultAttempt");function ie(e,t){try{return ce(e).mtime.toISOString()}catch{return t}}o(ie,"markerMtime");function $(e,t){if(!f(e))return null;try{return de(e,"utf8")}catch(n){if(!t)return null;throw new Error(`cannot import recovery input ${e}: ${n.message}`)}}o($,"legacyFile");function Ie(e,t){return _(e,"SELECT execution_id, started_at FROM executions WHERE node_id = ? ORDER BY rowid DESC LIMIT 1").get(t)??null}o(Ie,"latestExecution");function we(e,t){const r=H(e,"nodes").has("launched_at")?_(e,"SELECT COALESCE(launched_at, created) AS started_at FROM nodes WHERE node_id = ?").get(t):_(e,"SELECT created AS started_at FROM nodes WHERE node_id = ?").get(t);if(r===void 0)throw new Error(`cannot import recovery witness for unknown node ${t}`);const i=I();return _(e,"INSERT INTO executions (execution_id, node_id, daemon_epoch, pid, process_identity, state, started_at, ended_at, exit_reason) VALUES (?, ?, NULL, NULL, NULL, 'exited', ?, ?, 'pre-consolidation')").run(i,t,r.started_at,r.started_at),{execution_id:i,started_at:r.started_at}}o(we,"syntheticExecution");function oe(e,t,n,r,i){const a=I();return _(e,Z).run(...ee(a,t,n,r,i)),{...n,faultId:a}}o(oe,"insertMigratedFault");function De(e,t,n,r){const i=_(e,"SELECT binding_id, node_id FROM sessions WHERE transcript_path = ? AND unbound_at IS NULL").get(n);if(i!==void 0){if(i.node_id!==t)throw new Error(`cannot import provider retry ${r}: transcript is live-owned by ${i.node_id}`);return i.binding_id}const a=_(e,"SELECT binding_id FROM sessions WHERE node_id = ? AND transcript_path = ? ORDER BY rowid DESC LIMIT 1").get(t,n);if(a!==void 0)return a.binding_id;const d=_(e,"SELECT created FROM nodes WHERE node_id = ?").get(t);if(d===void 0)throw new Error(`cannot import provider retry ${r}: unknown node ${t}`);const s=I();return _(e,"INSERT INTO sessions (binding_id, session_id, node_id, transcript_path, source_session_id, fork_entry_id, created_at, bound_at, unbound_at) VALUES (?, NULL, ?, ?, NULL, NULL, ?, ?, ?)").run(s,t,n,d.created,d.created,u()),s}o(De,"migrationBinding");function ct(e){e.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'node_faults'").get()!==void 0&&(H(e,"node_faults").has("notified_since")||e.exec("ALTER TABLE node_faults ADD COLUMN notified_since TEXT"))}o(ct,"addFaultNotifiedSince");function _t(e){if(Le(e),me(e),!f(C()))return;const t=se(C(),{withFileTypes:!0}).filter(r=>r.isDirectory()).sort((r,i)=>r.name.localeCompare(i.name)),n=_(e,"SELECT 1 FROM nodes WHERE node_id = ?");for(const r of t){const i=r.name,a=pe(i),d=N(a,"busy"),s=N(a,"clean-abort"),E=N(a,"transport-poison.json"),O=N(a,"fault"),A=N(a,"provider-retry"),h=f(d),k=f(s);if(!h&&!k&&!f(E)&&!f(O)&&!f(A)||!f(N(C(),i,"meta.json"))&&n.get(i)===void 0)continue;const v=$(E,!1),S=$(O,!0),x=$(A,!0);if(!h&&!k&&v===null&&S===null&&x===null)continue;let y=Ie(e,i);if(y===null&&(y=we(e,i)),h){const c=ie(d,y.started_at);_(e,"UPDATE executions SET turn_open_at = ?, turn_progress_at = ?, turn_closed_at = NULL, turn_end_reason = NULL WHERE execution_id = ?").run(c,c,y.execution_id)}else if(k){const c=ie(s,y.started_at);_(e,"UPDATE executions SET turn_open_at = ?, turn_progress_at = ?, turn_closed_at = ?, turn_end_reason = 'teardown-aborted' WHERE execution_id = ?").run(c,c,c,y.execution_id)}if(v!==null)try{const c=JSON.parse(v);Number.isInteger(c.consecutivePasses)&&c.consecutivePasses>=1&&Array.isArray(c.routes)&&c.routes.length>0&&c.routes.every(j=>typeof j=="string"&&j!=="")&&_(e,"UPDATE executions SET exit_diagnostic_json = ? WHERE execution_id = ?").run(JSON.stringify({schema:"crtr.execution-exit-diagnostic/v1",transport_poison:{consecutive_passes:c.consecutivePasses,routes:c.routes}}),y.execution_id)}catch{}const R=S===null?null:V(S);if(S!==null&&R===null)throw new Error(`cannot import recovery fault ${O}`);const T=x===null?null:Se(x);if(x!==null&&T===null)throw new Error(`cannot import provider retry ${A}`);let F=R===null||R.link==="broker\u2194crtrd"?null:oe(e,i,R,!0);if(T!==null){const c=De(e,i,T.sessionFile,A);F!==null&&F.since===T.fault.since?_(e,"UPDATE node_faults SET episode_state = ?, episode_binding_id = ?, updated_at = ? WHERE fault_id = ?").run(T.state,c,u(),F.faultId):oe(e,i,T.fault,!1,{state:T.state,bindingId:c})}}}o(_t,"migrateRecoveryWitnesses");export{Me as FAULT_QUIET_MS,ct as addFaultNotifiedSince,nt as admitEpisode,ut as beginBootFaultAttempt,at as clearEpisode,et as clearFault,je as closeTurn,qe as hasAdmittedTurn,b as hydrateFault,ot as invalidateEpisode,dt as listPendingProviderRetries,ze as listUnnotifiedFatalFaultNodes,Qe as markFaultNotified,Be as markNodeRead,_t as migrateRecoveryWitnesses,Xe as openTurn,q as parseProviderError,st as readEpisode,re as readFault,Ge as readInterruptedTurn,Ye as readLiveTurn,Ke as readTransportPoisonVerdict,Ve as recordFault,tt as recordPendingEpisode,Je as recordTransportPoisonVerdict,$e as recordTurnProgress,it as reopenEpisode,Ze as setFatalFaultAnnouncer,rt as settleRejectedEpisode};
|
|
26
|
+
`)}o(me,"createFaultTable");function g(e,t){return typeof t=="string"&&e.includes(t)}o(g,"contains");function W(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}o(W,"isRecord");function q(e){if(!W(e)||typeof e.provider!="string"||e.provider===""||typeof e.model!="string"||e.model==="")return;const t=typeof e.status=="number"&&Number.isFinite(e.status)?e.status:void 0,n=typeof e.code=="string"||typeof e.code=="number"?e.code:void 0,r=typeof e.errno=="string"?e.errno:void 0,i=typeof e.body=="string"?e.body:void 0,a=le(e.ratelimit),d=Array.isArray(e.causes)?e.causes.flatMap(s=>{if(!W(s))return[];const E={...typeof s.message=="string"?{message:s.message}:{},...typeof s.status=="number"&&Number.isFinite(s.status)?{status:s.status}:{},...typeof s.code=="string"||typeof s.code=="number"?{code:s.code}:{},...typeof s.errno=="string"?{errno:s.errno}:{},...typeof s.body=="string"?{body:s.body}:{}};return Object.keys(E).length===0?[]:[E]}):void 0;return{provider:e.provider,model:e.model,...t===void 0?{}:{status:t},...n===void 0?{}:{code:n},...r===void 0?{}:{errno:r},...i===void 0?{}:{body:i},...d===void 0||d.length===0?{}:{causes:d},...a===void 0?{}:{ratelimit:a}}}o(q,"parseProviderError");function V(e){try{const t=JSON.parse(e);if(!g(fe,t.link)||typeof t.op!="string"||t.op===""||!g(ye,t.kind)||typeof t.message!="string"||typeof t.since!="string")return null;const n=Y(t.operation_id);if(!W(t.retry)||!g(Te,t.retry.disposition)||t.retry.by!==void 0&&!g(Ne,t.retry.by)||t.retry.attempt!==void 0&&typeof t.retry.attempt!="number"||t.retry.max!==void 0&&typeof t.retry.max!="number"||t.retry.nextAt!==void 0&&typeof t.retry.nextAt!="string"||t.anchorEntryId!==void 0&&(typeof t.anchorEntryId!="string"||t.anchorEntryId===""))return null;const r=t.providerError===void 0?void 0:q(t.providerError);return t.providerError!==void 0&&r===void 0?null:{link:t.link,op:t.op,kind:t.kind,retry:{disposition:t.retry.disposition,...t.retry.by===void 0?{}:{by:t.retry.by},...t.retry.attempt===void 0?{}:{attempt:t.retry.attempt},...t.retry.max===void 0?{}:{max:t.retry.max},...t.retry.nextAt===void 0?{}:{nextAt:t.retry.nextAt}},message:t.message,since:t.since,operation_id:n,...t.anchorEntryId===void 0?{}:{anchorEntryId:t.anchorEntryId},...r===void 0?{}:{providerError:r}}}catch{return null}}o(V,"parseLegacyFault");function Ae(e){const t=_e(e);try{return ue(t)}catch{return t}}o(Ae,"canonicalPath");function Se(e){try{const t=JSON.parse(e);if(!g(ge,t.state)||typeof t.sessionFile!="string"||t.sessionFile==="")return null;const n=JSON.stringify(t.fault),r=V(n);if(r===null||r.link!=="pi\u2192provider"||r.retry.disposition!=="auto"||r.retry.by!=="daemon")return null;const i=t.anchorEntryId;return i!==null&&typeof i!="string"||(r.anchorEntryId??null)!==i?null:{state:t.state,sessionFile:Ae(t.sessionFile),fault:r}}catch{return null}}o(Se,"parseLegacyEpisode");function Q(e){return e!==void 0?Y(e):K.current()??K.fresh(n=>n)}o(Q,"resolveOperationId");function Re(e){return e.slice(0,Ee)}o(Re,"clampMessage");function w(e){return e.link==="pi\u2192provider"&&e.retry.disposition==="auto"&&e.retry.by==="daemon"?3:e.retry.disposition==="fatal"?2:1}o(w,"faultPriority");function z(e){return{link:e.link,op:e.op,kind:e.kind,message:e.message,since:e.since,operationId:e.operation_id,anchorEntryId:e.anchorEntryId??null,retryDisposition:e.retry.disposition,retryBy:e.retry.by??null,retryAttempt:e.retry.attempt??null,retryMax:e.retry.max??null,retryNextAt:e.retry.nextAt??null,providerError:e.providerError===void 0?null:JSON.stringify(e.providerError)}}o(z,"encodeFault");function b(e){const t=e.provider_error_json,n=typeof t=="string"?q(JSON.parse(t)):void 0;if(typeof t=="string"&&n===void 0)throw new Error(`invalid provider error on stored fault ${e.fault_id}`);const r={disposition:e.retry_disposition,...e.retry_by===null?{}:{by:e.retry_by},...e.retry_attempt===null?{}:{attempt:e.retry_attempt},...e.retry_max===null?{}:{max:e.retry_max},...e.retry_next_at===null?{}:{nextAt:e.retry_next_at}};return{faultId:e.fault_id,link:e.link,op:e.op,kind:e.kind,message:e.message,since:e.since,operation_id:e.operation_id,retry:r,...e.anchor_entry_id===null?{}:{anchorEntryId:e.anchor_entry_id},...n===void 0?{}:{providerError:n},...typeof e.notified_since=="string"?{notifiedSince:e.notified_since}:{}}}o(b,"hydrateFault");async function L(e,t){const n=await e.prepare("SELECT * FROM node_faults WHERE node_id = ? AND active = 1").get(t);return n===void 0?null:b(n)}o(L,"activeFault");function P(e){if(!g(G,e.link))throw new Error(`fault link is not durable: ${e.link}`);return{link:e.link,op:e.op,kind:e.kind,retry:e.retry,message:Re(e.message),since:e.since??u(),operation_id:Q(e.operation_id),...typeof e.anchorEntryId=="string"&&e.anchorEntryId!==""?{anchorEntryId:e.anchorEntryId}:{},...e.providerError===void 0?{}:{providerError:e.providerError}}}o(P,"storedFault");function M(e,t){J({level:t.retry.disposition==="fatal"?"error":"warn",event:"fault.recorded",operation_id:t.operation_id,node_id:e,error_class:B(t),fields:{link:t.link,op:t.op,kind:t.kind,retry:t.retry,message:t.message,...t.anchorEntryId===void 0?{}:{anchor_entry_id:t.anchorEntryId},...t.providerError===void 0?{}:{provider_error:t.providerError}}})}o(M,"emitRecordedFault");const Z="INSERT INTO node_faults (fault_id, node_id, link, op, kind, message, since, operation_id, anchor_entry_id, retry_disposition, retry_by, retry_attempt, retry_max, retry_next_at, provider_error_json, active, episode_state, episode_binding_id, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";function ee(e,t,n,r,i){const a=z(n),d=u();return[e,t,a.link,a.op,a.kind,a.message,a.since,a.operationId,a.anchorEntryId,a.retryDisposition,a.retryBy,a.retryAttempt,a.retryMax,a.retryNextAt,a.providerError,r?1:0,i?.state??null,i?.bindingId??null,d,d]}o(ee,"faultInsertParams");async function te(e,t,n,r,i){const a=I();return await e.prepare(Z).run(...ee(a,t,n,r,i)),{...n,faultId:a}}o(te,"insertFault");async function D(e,t,n,r){const i=z(n);return await e.prepare("UPDATE node_faults SET link = ?, op = ?, kind = ?, message = ?, since = ?, operation_id = ?, anchor_entry_id = ?, retry_disposition = ?, retry_by = ?, retry_attempt = ?, retry_max = ?, retry_next_at = ?, provider_error_json = ?, episode_state = COALESCE(?, episode_state), episode_binding_id = COALESCE(?, episode_binding_id), updated_at = ? WHERE fault_id = ?").run(i.link,i.op,i.kind,i.message,i.since,i.operationId,i.anchorEntryId,i.retryDisposition,i.retryBy,i.retryAttempt,i.retryMax,i.retryNextAt,i.providerError,r?.state??null,r?.bindingId??null,u(),t),{...n,faultId:t}}o(D,"updateFault");async function U(e,t){await e.prepare("DELETE FROM node_faults WHERE fault_id = ? AND active = 0 AND episode_state IS NULL").run(t)}o(U,"deleteIfUnretained");async function ne(e,t,n,r){const i=await L(e,t);if(i===null){const a=await e.prepare("SELECT fault_id, link, kind, since, operation_id FROM node_faults WHERE node_id = ? AND active = 0 AND episode_state IS NOT NULL").get(t);return a!==void 0&&a.link===n.link&&a.kind===n.kind&&a.since===n.since&&a.operation_id===n.operation_id?(await e.prepare("UPDATE node_faults SET active = 1, updated_at = ? WHERE fault_id = ?").run(u(),a.fault_id),await D(e,a.fault_id,n)):await te(e,t,n,!0,r)}if(i.link===n.link&&i.kind===n.kind){const a=n.retry.disposition==="auto"?{...i.retry,...n.retry}:n.retry,d=i.retry.disposition===n.retry.disposition&&(n.retry.disposition!=="fatal"||i.message===n.message),s=d?i.since:n.since,E=await D(e,i.faultId,{...n,since:s,anchorEntryId:n.anchorEntryId??i.anchorEntryId,retry:a},r);return d||await e.prepare("UPDATE node_faults SET notified_since = NULL WHERE fault_id = ?").run(i.faultId),E}return i.link!==n.link&&w(i)>w(n)?null:(await e.prepare("UPDATE node_faults SET active = 0, updated_at = ? WHERE fault_id = ?").run(u(),i.faultId),await U(e,i.faultId),await te(e,t,n,!0,r))}o(ne,"replaceActiveFault");async function m(e,t,n){return(await e.prepare("SELECT binding_id FROM sessions WHERE node_id = ? AND session_id = ? AND unbound_at IS NULL").get(t,n))?.binding_id??null}o(m,"liveBinding");async function Xe(e,t){return await l(async n=>{const r=u();return(await n.prepare("UPDATE executions SET turn_progress_at = ? WHERE execution_id = ? AND state != 'exited' AND turn_open_at IS NOT NULL AND turn_closed_at IS NULL").run(r,e)).changes>0?!0:(await n.prepare("UPDATE executions SET turn_open_at = ?, turn_progress_at = ?, turn_closed_at = NULL, turn_end_reason = NULL WHERE execution_id = ? AND state != 'exited'").run(r,r,e)).changes>0})}o(Xe,"openTurn");async function $e(e){return(await(await p()).prepare("UPDATE executions SET turn_progress_at = ? WHERE execution_id = ? AND state != 'exited' AND turn_open_at IS NOT NULL AND turn_closed_at IS NULL").run(u(),e)).changes>0}o($e,"recordTurnProgress");async function je(e,t){return await l(async n=>{const r=u(),i=(await n.prepare("UPDATE executions SET turn_closed_at = ?, turn_end_reason = ? WHERE execution_id = ? AND state != 'exited' AND turn_open_at IS NOT NULL AND turn_closed_at IS NULL").run(r,t.endReason,e)).changes>0;if(i&&t.endReason==="settled"){const a="(SELECT node_id FROM executions WHERE execution_id = ?)";t.viewerPresent===!0?await n.prepare(`UPDATE nodes SET reply_at = ?, read_at = ? WHERE node_id = ${a}`).run(r,r,e):await n.prepare(`UPDATE nodes SET reply_at = ? WHERE node_id = ${a}`).run(r,e)}return i})}o(je,"closeTurn");async function Be(e){return(await(await p()).prepare("UPDATE nodes SET read_at = ? WHERE node_id = ?").run(u(),e)).changes>0}o(Be,"markNodeRead");async function Je(e,t){if(!Number.isInteger(t.consecutivePasses)||t.consecutivePasses<1||t.routes.length===0||!t.routes.every(n=>n!==""))throw new Error("invalid transport-poison verdict");return(await(await p()).prepare("UPDATE executions SET exit_diagnostic_json = ? WHERE execution_id = ? AND state != 'exited'").run(JSON.stringify({schema:"crtr.execution-exit-diagnostic/v1",transport_poison:{consecutive_passes:t.consecutivePasses,routes:t.routes}}),e)).changes>0}o(Je,"recordTransportPoisonVerdict");async function Ke(e){const t=await(await p()).prepare("SELECT exit_diagnostic_json FROM executions WHERE node_id = ? ORDER BY seq DESC LIMIT 1").get(e);if(t===void 0||t.exit_diagnostic_json===null)return null;try{const n=JSON.parse(t.exit_diagnostic_json),r=n.transport_poison;return n.schema!=="crtr.execution-exit-diagnostic/v1"||r===void 0||!Number.isInteger(r.consecutive_passes)||r.consecutive_passes<1||!Array.isArray(r.routes)||r.routes.length===0||!r.routes.every(i=>typeof i=="string"&&i!=="")?null:{consecutivePasses:r.consecutive_passes,routes:r.routes}}catch{return null}}o(Ke,"readTransportPoisonVerdict");async function Ye(e){const t=await(await p()).prepare("SELECT turn_open_at, turn_closed_at, turn_progress_at FROM executions WHERE node_id = ? AND state != 'exited'").get(e);return t===void 0?null:{busy:t.turn_open_at!==null&&t.turn_closed_at===null,progressAt:t.turn_progress_at}}o(Ye,"readLiveTurn");async function Ge(e){const t=await p(),n=await t.prepare("SELECT turn_closed_at, turn_progress_at FROM executions WHERE node_id = ? AND turn_open_at IS NOT NULL ORDER BY seq DESC LIMIT 1").get(e);if(n===void 0)return null;const r=await t.prepare("SELECT turn_end_reason FROM executions WHERE node_id = ? ORDER BY seq DESC LIMIT 1").get(e);return{interrupted:n.turn_closed_at===null||r?.turn_end_reason==="teardown-aborted",progressAt:n.turn_progress_at}}o(Ge,"readInterruptedTurn");async function qe(e){return await(await p()).prepare("SELECT 1 FROM executions WHERE node_id = ? AND turn_open_at IS NOT NULL LIMIT 1").get(e)!==void 0}o(qe,"hasAdmittedTurn");async function Ve(e,t){const n=P(t);return M(e,n),await l(async r=>await ne(r,e,n))}o(Ve,"recordFault");async function Qe(e){return await l(async t=>(await t.prepare("UPDATE node_faults SET notified_since = since, updated_at = ? WHERE fault_id = ?").run(u(),e)).changes>0)}o(Qe,"markFaultNotified");function xe(e){return e.link==="pi\u2192provider"&&e.retry.disposition==="fatal"&&e.notifiedSince!==e.since}o(xe,"isUnnotifiedFatalProviderFault");async function ze(){return(await(await p()).prepare("SELECT f.node_id FROM node_faults f JOIN nodes n ON n.node_id = f.node_id WHERE f.active = 1 AND f.link = 'pi\u2192provider' AND f.retry_disposition = 'fatal' AND (f.notified_since IS NULL OR f.notified_since != f.since) AND n.status IN ('active', 'idle')").all()).map(e=>e.node_id)}o(ze,"listUnnotifiedFatalFaultNodes");let X=null;function Ze(e){X=e}o(Ze,"setFatalFaultAnnouncer");async function et(e,t){const n=await L(await p(),e);return n===null||t?.link!==void 0&&n.link!==t.link?!1:await l(async r=>{const i=await L(r,e);if(i===null||t?.link!==void 0&&i.link!==t.link)return!1;X!==null&&xe(i)&&await X(e);const a=await r.prepare("SELECT episode_state FROM node_faults WHERE fault_id = ?").get(i.faultId);await r.prepare("UPDATE node_faults SET active = 0, updated_at = ? WHERE fault_id = ?").run(u(),i.faultId),a.episode_state==="pending"&&t?.preserveEpisode!==!0&&await r.prepare("UPDATE node_faults SET episode_state = NULL, episode_binding_id = NULL, updated_at = ? WHERE fault_id = ?").run(u(),i.faultId),await U(r,i.faultId);const d=Q();return J({level:"info",event:"fault.cleared",operation_id:d,node_id:e,error_class:B(i),fields:{cleared_fault_operation_id:i.operation_id,link:i.link,op:i.op,kind:i.kind,retry:i.retry,message:i.message,since:i.since,...i.anchorEntryId===void 0?{}:{anchor_entry_id:i.anchorEntryId}}}),!0})}o(et,"clearFault");async function re(e){return await L(await p(),e)}o(re,"readFault");async function tt(e,t){const n=P(t.input);if(n.link!=="pi\u2192provider"||n.retry.disposition!=="auto"||n.retry.by!=="daemon")throw new Error("provider retry episode requires an automatic daemon provider fault");return M(e,n),await l(async r=>{const i=await m(r,e,t.sessionId);if(i===null)return null;const a=await L(r,e);if(a!==null&&(a.link!==n.link||a.kind!==n.kind)&&w(a)>w(n))return null;const d=await r.prepare("SELECT fault_id FROM node_faults WHERE node_id = ? AND episode_state IS NOT NULL").all(e);await r.prepare("UPDATE node_faults SET episode_state = NULL, episode_binding_id = NULL, updated_at = ? WHERE node_id = ? AND episode_state IS NOT NULL").run(u(),e);for(const E of d)await U(r,E.fault_id);const s=await ne(r,e,n,{state:"pending",bindingId:i});return s===null?null:(await r.prepare("UPDATE node_faults SET episode_state = ?, episode_binding_id = ?, updated_at = ? WHERE fault_id = ?").run("pending",i,u(),s.faultId),s)})}o(tt,"recordPendingEpisode");async function nt(e,t){return await l(async n=>{if(await n.prepare("SELECT 1 FROM nodes WHERE node_id = ? AND intent = 'refresh'").get(e)!==void 0)return!1;const r=await m(n,e,t.sessionId);return r===null?!1:(await n.prepare("UPDATE node_faults SET episode_state = 'admitted', retry_disposition = ?, retry_by = ?, retry_attempt = ?, retry_max = ?, retry_next_at = ?, updated_at = ? WHERE node_id = ? AND fault_id = ? AND episode_state = 'pending' AND episode_binding_id = ?").run(t.retry.disposition,t.retry.by??null,t.retry.attempt??null,t.retry.max??null,t.retry.nextAt??null,u(),e,t.faultId,r)).changes>0})}o(nt,"admitEpisode");async function rt(e,t){const n=P(t.fault);return await l(async r=>{const i=await m(r,e,t.sessionId);return i===null||(await L(r,e))?.faultId!==t.faultId||await r.prepare("SELECT 1 FROM node_faults WHERE node_id = ? AND fault_id = ? AND episode_state = 'admitted' AND episode_binding_id = ?").get(e,t.faultId,i)===void 0?!1:(M(e,n),t.reopen?await D(r,t.faultId,n,{state:"pending",bindingId:i}):(await D(r,t.faultId,n),await r.prepare("UPDATE node_faults SET episode_state = NULL, episode_binding_id = NULL, updated_at = ? WHERE fault_id = ?").run(u(),t.faultId),await r.prepare("UPDATE node_faults SET notified_since = NULL WHERE fault_id = ?").run(t.faultId)),!0)})}o(rt,"settleRejectedEpisode");async function it(e,t){return await l(async n=>{const r=await m(n,e,t.sessionId);return r===null?!1:(await n.prepare("UPDATE node_faults SET episode_state = 'pending', updated_at = ? WHERE node_id = ? AND episode_state = 'admitted' AND episode_binding_id = ?").run(u(),e,r)).changes>0})}o(it,"reopenEpisode");async function ot(e,t){return await l(async n=>{const r=await m(n,e,t.sessionId);return r===null?!1:(await n.prepare("UPDATE node_faults SET episode_state = 'invalidated', updated_at = ? WHERE node_id = ? AND episode_state != 'invalidated' AND episode_state IS NOT NULL AND episode_binding_id = ?").run(u(),e,r)).changes>0})}o(ot,"invalidateEpisode");async function at(e,t){return await l(async n=>{const r=await m(n,e,t.sessionId);if(r===null)return!1;const i=await n.prepare("SELECT fault_id FROM node_faults WHERE node_id = ? AND episode_binding_id = ? AND episode_state IS NOT NULL").all(e,r);if(i.length===0)return!1;await n.prepare("UPDATE node_faults SET episode_state = NULL, episode_binding_id = NULL, updated_at = ? WHERE node_id = ? AND episode_binding_id = ? AND episode_state IS NOT NULL").run(u(),e,r);for(const a of i)await U(n,a.fault_id);return!0})}o(at,"clearEpisode");async function st(e){const t=await(await p()).prepare("SELECT f.*, s.session_id FROM node_faults f JOIN sessions s ON s.binding_id = f.episode_binding_id WHERE f.node_id = ? AND f.episode_state IS NOT NULL").get(e);return t===void 0?null:{state:t.episode_state,sessionId:t.session_id,fault:b(t)}}o(st,"readEpisode");async function dt(){return(await(await p()).prepare("SELECT f.*, s.session_id AS bound_session_id FROM node_faults f JOIN sessions s ON s.binding_id = f.episode_binding_id WHERE f.active = 1 AND f.episode_state = 'pending' AND s.unbound_at IS NULL AND s.session_id IS NOT NULL AND f.link = 'pi\u2192provider' AND f.retry_disposition = 'auto' AND f.retry_by = 'daemon' AND f.kind IN ('connection', 'rate-limit', 'overloaded')").all()).map(t=>({nodeId:t.node_id,sessionId:t.bound_session_id,fault:b(t),updatedAt:t.updated_at,nudgedAt:t.nudged_at??null}))}o(dt,"listPendingProviderRetries");async function ut(e,t,n){return(await(await p()).prepare("UPDATE node_faults SET nudged_at = ? WHERE fault_id = ? AND active = 1 AND episode_state = 'pending' AND (nudged_at IS NULL OR nudged_at <= ?)").run(new Date(t).toISOString(),e,new Date(t-n).toISOString())).changes===1}o(ut,"claimFaultNudge");async function ct(e){const t=await re(e)===null;return{async explanation(){if(!t)return null;const n=await re(e);if(n===null||n.link!=="crtr\u2192pi"||n.retry.disposition!=="fatal")return null;const r=n.op.trim(),i=n.message.trim();return r===""||i===""?null:`${r}: ${i}`}}}o(ct,"beginBootFaultAttempt");function ie(e,t){try{return ce(e).mtime.toISOString()}catch{return t}}o(ie,"markerMtime");function $(e,t){if(!f(e))return null;try{return de(e,"utf8")}catch(n){if(!t)return null;throw new Error(`cannot import recovery input ${e}: ${n.message}`)}}o($,"legacyFile");function Ie(e,t){return _(e,"SELECT execution_id, started_at FROM executions WHERE node_id = ? ORDER BY rowid DESC LIMIT 1").get(t)??null}o(Ie,"latestExecution");function we(e,t){const r=H(e,"nodes").has("launched_at")?_(e,"SELECT COALESCE(launched_at, created) AS started_at FROM nodes WHERE node_id = ?").get(t):_(e,"SELECT created AS started_at FROM nodes WHERE node_id = ?").get(t);if(r===void 0)throw new Error(`cannot import recovery witness for unknown node ${t}`);const i=I();return _(e,"INSERT INTO executions (execution_id, node_id, daemon_epoch, pid, process_identity, state, started_at, ended_at, exit_reason) VALUES (?, ?, NULL, NULL, NULL, 'exited', ?, ?, 'pre-consolidation')").run(i,t,r.started_at,r.started_at),{execution_id:i,started_at:r.started_at}}o(we,"syntheticExecution");function oe(e,t,n,r,i){const a=I();return _(e,Z).run(...ee(a,t,n,r,i)),{...n,faultId:a}}o(oe,"insertMigratedFault");function De(e,t,n,r){const i=_(e,"SELECT binding_id, node_id FROM sessions WHERE transcript_path = ? AND unbound_at IS NULL").get(n);if(i!==void 0){if(i.node_id!==t)throw new Error(`cannot import provider retry ${r}: transcript is live-owned by ${i.node_id}`);return i.binding_id}const a=_(e,"SELECT binding_id FROM sessions WHERE node_id = ? AND transcript_path = ? ORDER BY rowid DESC LIMIT 1").get(t,n);if(a!==void 0)return a.binding_id;const d=_(e,"SELECT created FROM nodes WHERE node_id = ?").get(t);if(d===void 0)throw new Error(`cannot import provider retry ${r}: unknown node ${t}`);const s=I();return _(e,"INSERT INTO sessions (binding_id, session_id, node_id, transcript_path, source_session_id, fork_entry_id, created_at, bound_at, unbound_at) VALUES (?, NULL, ?, ?, NULL, NULL, ?, ?, ?)").run(s,t,n,d.created,d.created,u()),s}o(De,"migrationBinding");function _t(e){e.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'node_faults'").get()!==void 0&&(H(e,"node_faults").has("notified_since")||e.exec("ALTER TABLE node_faults ADD COLUMN notified_since TEXT"))}o(_t,"addFaultNotifiedSince");function pt(e){if(Le(e),me(e),!f(C()))return;const t=se(C(),{withFileTypes:!0}).filter(r=>r.isDirectory()).sort((r,i)=>r.name.localeCompare(i.name)),n=_(e,"SELECT 1 FROM nodes WHERE node_id = ?");for(const r of t){const i=r.name,a=pe(i),d=N(a,"busy"),s=N(a,"clean-abort"),E=N(a,"transport-poison.json"),O=N(a,"fault"),A=N(a,"provider-retry"),h=f(d),v=f(s);if(!h&&!v&&!f(E)&&!f(O)&&!f(A)||!f(N(C(),i,"meta.json"))&&n.get(i)===void 0)continue;const k=$(E,!1),S=$(O,!0),R=$(A,!0);if(!h&&!v&&k===null&&S===null&&R===null)continue;let y=Ie(e,i);if(y===null&&(y=we(e,i)),h){const c=ie(d,y.started_at);_(e,"UPDATE executions SET turn_open_at = ?, turn_progress_at = ?, turn_closed_at = NULL, turn_end_reason = NULL WHERE execution_id = ?").run(c,c,y.execution_id)}else if(v){const c=ie(s,y.started_at);_(e,"UPDATE executions SET turn_open_at = ?, turn_progress_at = ?, turn_closed_at = ?, turn_end_reason = 'teardown-aborted' WHERE execution_id = ?").run(c,c,c,y.execution_id)}if(k!==null)try{const c=JSON.parse(k);Number.isInteger(c.consecutivePasses)&&c.consecutivePasses>=1&&Array.isArray(c.routes)&&c.routes.length>0&&c.routes.every(j=>typeof j=="string"&&j!=="")&&_(e,"UPDATE executions SET exit_diagnostic_json = ? WHERE execution_id = ?").run(JSON.stringify({schema:"crtr.execution-exit-diagnostic/v1",transport_poison:{consecutive_passes:c.consecutivePasses,routes:c.routes}}),y.execution_id)}catch{}const x=S===null?null:V(S);if(S!==null&&x===null)throw new Error(`cannot import recovery fault ${O}`);const T=R===null?null:Se(R);if(R!==null&&T===null)throw new Error(`cannot import provider retry ${A}`);let F=x===null||x.link==="broker\u2194crtrd"?null:oe(e,i,x,!0);if(T!==null){const c=De(e,i,T.sessionFile,A);F!==null&&F.since===T.fault.since?_(e,"UPDATE node_faults SET episode_state = ?, episode_binding_id = ?, updated_at = ? WHERE fault_id = ?").run(T.state,c,u(),F.faultId):oe(e,i,T.fault,!1,{state:T.state,bindingId:c})}}}o(pt,"migrateRecoveryWitnesses");export{Me as FAULT_QUIET_MS,_t as addFaultNotifiedSince,nt as admitEpisode,ct as beginBootFaultAttempt,ut as claimFaultNudge,at as clearEpisode,et as clearFault,je as closeTurn,qe as hasAdmittedTurn,b as hydrateFault,ot as invalidateEpisode,dt as listPendingProviderRetries,ze as listUnnotifiedFatalFaultNodes,Qe as markFaultNotified,Be as markNodeRead,pt as migrateRecoveryWitnesses,Xe as openTurn,q as parseProviderError,st as readEpisode,re as readFault,Ge as readInterruptedTurn,Ye as readLiveTurn,Ke as readTransportPoisonVerdict,Ve as recordFault,tt as recordPendingEpisode,Je as recordTransportPoisonVerdict,$e as recordTurnProgress,it as reopenEpisode,Ze as setFatalFaultAnnouncer,rt as settleRejectedEpisode};
|