@north-light/cli 0.3.561 → 0.3.563
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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/build-root.d.ts +1 -0
- package/dist/build-root.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/join.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.d.ts +5 -3
- 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 +19 -19
- package/dist/daemon/api/viewer-presence.d.ts +20 -6
- package/dist/daemon/api/viewer-presence.js +2 -1
- package/dist/daemon/boot-settings.d.ts +3 -0
- package/dist/daemon/boot-settings.js +1 -0
- 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
package/dist/core/bash-jobs.js
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
var
|
|
2
|
-
`)
|
|
3
|
-
`)}o(
|
|
4
|
-
`),
|
|
5
|
-
`)}
|
|
6
|
-
`)}catch(
|
|
7
|
-
`)
|
|
8
|
-
`)+1):
|
|
9
|
-
`)
|
|
10
|
-
`).map(n=>n.trim()).find(n=>n!=="")??"").replace(/\s+/g," ")}o(At,"bashJobCommandLine");function w(t,e=!1){let n;try{n=J(t)}catch{return[]}const r=[];for(const s of n){const i=E(s);if(i===void 0)continue;const u=f(t,s);let d;try{if(!a(u,u.jobBg)&&!(e&&a(u,u.jobRun))||a(u,u.jobExit))continue;d=b(t,u.cmdSh)}catch{continue}r.push({jobId:s,command:d,purpose:W(t,s),startedAtMs:i,logPath:u.jobLog,deadlineAtMs:Y(t,s)??null})}return r.sort((s,i)=>s.startedAtMs-i.startedAtMs)}o(w,"activeBackgroundBashJobs");function Jt(t,e){return w(t).filter(n=>n.deadlineAtMs!==null&&e>=n.deadlineAtMs)}o(Jt,"expiredAutoBackgroundBashJobs");function kt(t,e){if(!Number.isFinite(e)||e<=0)return 0;let n=0;for(const r of w(t))if(r.deadlineAtMs!==null)try{Z(f(t,r.jobId),r.deadlineAtMs+e),n+=1}catch{}return n}o(kt,"shiftAutoBackgroundBashDeadlines");function D(t){try{return z(t.root,t.jobRun,t.jobBg),"backgrounded"}catch(e){if(e.code!=="ENOENT")throw e;return a(t,t.jobBg)?"already-backgrounded":a(t,t.jobDone)?"finished":"missing"}}o(D,"backgroundBashJob");function L(t){let e;try{e=J(t)}catch{return[]}return e.flatMap(n=>{const r=f(t,n);try{return a(r,r.cmdSh)&&a(r,r.jobLog)&&a(r,r.jobRun)?[r]:[]}catch{return[]}})}o(L,"runningBashJobs");function Pt(t){let e;for(const n of L(t)){const r=E(n.jobId);r!==void 0&&(e===void 0||r<e)&&(e=r)}return e}o(Pt,"oldestRunningBashJobStartedAtMs");function Nt(t){const e=[];for(const n of L(t))D(n)==="backgrounded"&&e.push(n);return e}o(Nt,"backgroundRunningBashJobs");export{P as DEFAULT_BASH_NICENESS,K as MAX_BASH_NICENESS,w as activeBackgroundBashJobs,D as backgroundBashJob,Nt as backgroundRunningBashJobs,At as bashJobCommandLine,f as bashJobPaths,j as bashJobsDir,N as bashNicenessPath,V as cancelBashJobProcessTree,dt as clearJobDeadline,St as countJobLogLines,Jt as expiredAutoBackgroundBashJobs,xt as formatBashElapsed,jt as isBashJobProcessConfirmedGone,gt as isBashJobProcessGroupAlive,bt as isJobQuietOk,ct as isSafeBashJobId,E as jobStartedAtMs,ht as markJobQuietOk,Mt as newBashJobId,X as normalizeBashJobPurpose,Pt as oldestRunningBashJobStartedAtMs,at as readBashNiceness,lt as readJobActivity,Y as readJobDeadlineMs,q as readJobPgid,U as readJobPgidIdentity,W as readJobPurpose,pt as readJobSilence,kt as shiftAutoBackgroundBashDeadlines,yt as stopBackgroundBashJob,Bt as tailJobLog,ft as writeBashNiceness,Z as writeJobDeadlineMs,mt as writeJobSilence};
|
|
1
|
+
var F=Object.defineProperty;var o=(t,e)=>F(t,"name",{value:e,configurable:!0});import{randomBytes as I}from"node:crypto";import{closeSync as x,openSync as S,readSync as E,statSync as _}from"node:fs";import{dirname as p,join as a}from"node:path";import{captureTeardownSnapshot as C,isAnyPidAlive as O,isPidAlive as N,killProcessTreePids as J}from"./canvas/pid.js";import{launcherRequest as z}from"../launcher/client.js";import{LaunchRefused as G}from"../launcher/spec.js";import{createFileBeneath as P,existsBeneath as H,readTextBeneathIfExists as m,readdirBeneath as X,readFileBeneath as q,renameBeneath as U,unlinkBeneath as W,writeFileBeneath as w}from"./spaces/open-beneath.js";const K=280;function at(t){if(typeof t!="string"||/[\p{Cc}\p{Cf}]/u.test(t))return null;const e=t.trim();return e===""?null:Buffer.byteLength(e,"utf8")<=K?e:null}o(at,"normalizeBashJobPurpose");function g(t){return a(t,"jobs")}o(g,"bashJobsDir");function y(t,e){return q(p(t),e).toString("utf8")}o(y,"readJobText");function M(t){return X(p(t),g(t)).map(e=>e.name)}o(M,"jobIds");function c(t,e){return H(t.root,e)}o(c,"has");function k(t,e){try{W(t,e)}catch(n){if(n.code!=="ENOENT")throw n}}o(k,"unlinkIfPresent");function ct(t){return typeof t=="string"&&t!==""&&t!=="."&&t!==".."&&/^[A-Za-z0-9._~-]+$/u.test(t)&&Buffer.byteLength(t,"utf8")<=128}o(ct,"isSafeBashJobId");function b(t,e){const n=a(g(t),e);return{jobId:e,root:p(t),dir:n,cmdSh:a(n,"cmd.sh"),jobLog:a(n,"job.log"),jobExit:a(n,"job.exit"),jobRun:a(n,"job.run"),jobBg:a(n,"job.bg"),jobDone:a(n,"job.done"),jobPgid:a(n,"job.pgid"),jobPgidIdentity:a(n,"job.pgid-identity"),jobActivity:a(n,"job.activity"),jobDeadline:a(n,"job.deadline"),jobReported:a(n,"job.reported")}}o(b,"bashJobPaths");function A(t,e){try{const n=Number(y(t,b(t,e).jobPgid).trim());return Number.isInteger(n)&&n>1?n:void 0}catch{return}}o(A,"readJobPgid");function L(t,e){try{const n=y(t,b(t,e).jobPgidIdentity).trim();return n===""?void 0:n}catch{return}}o(L,"readJobPgidIdentity");function ft(t,e){const n=b(t,e),r={},s=A(t,e),i=L(t,e);s!==void 0&&(r.pgid=s),i!==void 0&&(r.pgidIdentity=i);const u=m(n.root,n.jobExit);u!==null&&Number.isSafeInteger(Number(u.trim()))&&u.trim()!==""&&(r.exitCode=Number(u.trim()));const f=m(n.root,n.jobDeadline);f!==null&&f.trim()!==""&&Number.isFinite(Number(f.trim()))&&(r.deadlineMs=Number(f.trim()));const d=m(n.root,n.jobActivity);if(d!==null){const[l,...h]=d.split(`
|
|
2
|
+
`),[B,j]=(l??"").split(" ").map(Number);Number.isFinite(B)&&Number.isFinite(j)&&(r.activity={lastActivityMs:B,sampledAtMs:j,files:h.filter(v=>v!=="")})}return r}o(ft,"readJobSupervisorState");function dt(t,e){w(t.root,t.jobDeadline,`${Math.trunc(e)}
|
|
3
|
+
`)}o(dt,"writeJobDeadlineFile");function lt(t){k(t.root,t.jobDeadline)}o(lt,"clearJobDeadlineFile");function bt(t){let e;try{e=M(t)}catch{return[]}return e.filter(n=>{const r=b(t,n);try{return(c(r,r.jobRun)||c(r,r.jobBg))&&!c(r,r.jobExit)}catch{return!1}})}o(bt,"unfinishedBashJobIds");const R=10,Y=19;function $(t){return a(g(t),"niceness")}o($,"bashNicenessPath");function ht(t){try{const e=Number(y(t,$(t)).trim());return!Number.isInteger(e)||e<0||e>Y?R:e}catch{return R}}o(ht,"readBashNiceness");function pt(t,e){w(p(t),$(t),`${Math.trunc(e)}
|
|
4
|
+
`)}o(pt,"writeBashNiceness");function mt(t,e){if(e===`launcher:${t}`)return N(t);try{return process.kill(-t,0),!0}catch(n){return n.code==="EPERM"}}o(mt,"isBashJobProcessGroupAlive");function gt(t,e){if(t===void 0||e===void 0)return!1;if(e===`launcher:${t}`)return!N(t);try{return process.kill(-t,0),!1}catch(n){return n.code==="ESRCH"}}o(gt,"isBashJobProcessConfirmedGone");async function Z(t,e){const n=C(t,e);if(n.reused||n.tree.length===0)return!1;const r=[...n.tree].reverse(),s=O(r);return J(r,"SIGTERM",n.identities),await new Promise(i=>setTimeout(i,400)),J(r,"SIGKILL",n.identities),s}o(Z,"cancelBashJobProcessTree");async function D(t,e,n){if(e!==`launcher:${t}`)return await Z(t,e);if(n===void 0)throw new Error("launcher job stop requires its owning node");try{if(!("ok"in await z({operation:"stop",pid:t,nodeId:n})))throw new Error("launcher did not stop job");return!0}catch(r){if(!(r instanceof G&&r.refusal==="invalid_spec"))throw r;return!1}}o(D,"signalBashJob");async function yt(t,e,n=!1,r,s){const i=b(t,e);if(!c(i,i.dir))return{kind:"missing"};if(!c(i,i.jobBg)&&!(n&&c(i,i.jobRun))||c(i,i.jobExit))return{kind:"retired",logPath:i.jobLog};const u=A(t,e),f=L(t,e);if(u===void 0||f===void 0)return{kind:"not-stoppable",logPath:i.jobLog};const d=a(i.dir,"job.stop");try{P(i.root,d,s===void 0?"":`${s}
|
|
5
|
+
`)}catch(l){if(l.code==="EEXIST")return{kind:"retired",logPath:i.jobLog};throw l}try{const l=await D(u,f,r);try{P(i.root,i.jobExit,`143
|
|
6
|
+
`)}catch(h){if(h.code!=="EEXIST")throw h}return{kind:"stopped",signaled:l,pgid:u,logPath:i.jobLog}}catch(l){throw k(i.root,d),l}}o(yt,"stopBackgroundBashJob");function Bt(t,e){if(e<=0)return[];const n=64*1024;let r;try{const s=_(t).size,i=Math.max(0,s-n),u=Buffer.alloc(Math.min(s,n));r=S(t,"r"),E(r,u,0,u.length,i);const f=u.toString("utf8"),d=(i>0?f.slice(f.indexOf(`
|
|
7
|
+
`)+1):f).split(`
|
|
8
|
+
`);return d[d.length-1]===""&&d.pop(),d.slice(-e)}catch{return[]}finally{r!==void 0&&x(r)}}o(Bt,"tailJobLog");function jt(t){let e;try{e=S(t,"r");const n=Buffer.alloc(64*1024);let r=0,s=0;for(;;){const i=E(e,n,0,n.length,null);if(i===0)break;for(let u=0;u<i;u+=1)n[u]===10&&(r+=1);s=n[i-1]}return s!==0&&s!==10?r+1:r}catch{return 0}finally{e!==void 0&&x(e)}}o(jt,"countJobLogLines");function xt(){return`${Date.now()}-${I(4).toString("hex")}`}o(xt,"newBashJobId");function Q(t){const e=t.indexOf("-");if(e<=0||e===t.length-1)return;const n=Number(t.slice(0,e));return Number.isFinite(n)?n:void 0}o(Q,"jobStartedAtMs");function St(t){const e=Math.max(0,Math.floor(t/1e3));if(e<60)return`${e}s`;const n=Math.floor(e/60),r=e%60;if(n<60)return`${n}m ${String(r).padStart(2,"0")}s`;const s=Math.floor(n/60),i=n%60;return`${s}h ${String(i).padStart(2,"0")}m`}o(St,"formatBashElapsed");function Et(t){return(t.split(`
|
|
9
|
+
`).map(n=>n.trim()).find(n=>n!=="")??"").replace(/\s+/g," ")}o(Et,"bashJobCommandLine");function V(t){try{return U(t.root,t.jobRun,t.jobBg),"backgrounded"}catch(e){if(e.code!=="ENOENT")throw e;return c(t,t.jobBg)?"already-backgrounded":c(t,t.jobDone)?"finished":"missing"}}o(V,"backgroundBashJob");function T(t){let e;try{e=M(t)}catch{return[]}return e.flatMap(n=>{const r=b(t,n);try{return c(r,r.cmdSh)&&c(r,r.jobLog)&&c(r,r.jobRun)?[r]:[]}catch{return[]}})}o(T,"runningBashJobs");function Nt(t){let e;for(const n of T(t)){const r=Q(n.jobId);r!==void 0&&(e===void 0||r<e)&&(e=r)}return e}o(Nt,"oldestRunningBashJobStartedAtMs");function Jt(t){const e=[];for(const n of T(t))V(n)==="backgrounded"&&e.push(n);return e}o(Jt,"backgroundRunningBashJobs");export{R as DEFAULT_BASH_NICENESS,Y as MAX_BASH_NICENESS,V as backgroundBashJob,Jt as backgroundRunningBashJobs,Et as bashJobCommandLine,b as bashJobPaths,g as bashJobsDir,$ as bashNicenessPath,Z as cancelBashJobProcessTree,lt as clearJobDeadlineFile,jt as countJobLogLines,St as formatBashElapsed,gt as isBashJobProcessConfirmedGone,mt as isBashJobProcessGroupAlive,ct as isSafeBashJobId,Q as jobStartedAtMs,xt as newBashJobId,at as normalizeBashJobPurpose,Nt as oldestRunningBashJobStartedAtMs,ht as readBashNiceness,A as readJobPgid,L as readJobPgidIdentity,ft as readJobSupervisorState,D as signalBashJob,yt as stopBackgroundBashJob,Bt as tailJobLog,bt as unfinishedBashJobIds,pt as writeBashNiceness,dt as writeJobDeadlineFile};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var S=Object.defineProperty;var i=(s,c)=>S(s,"name",{value:c,configurable:!0});import{randomUUID as w}from"node:crypto";import{closeSync as u,fsyncSync as a,mkdirSync as B,openSync as m,readFileSync as b,readSync as D,readdirSync as E,renameSync as N,rmSync as p,writeSync as $}from"node:fs";import{dirname as h,join as d}from"node:path";import{assertBlobKey as g}from"./index.js";import{blobFault as F}from"./fault.js";function O(s){const c=m(s,"r");try{a(c)}finally{u(c)}}i(O,"syncDir");function x(s){const c=i(e=>(g(e),d(s,...e.split("/"))),"pathOf");function l(e,n,r){let o;try{o=E(e,{withFileTypes:!0})}catch(t){if(t.code==="ENOENT")return;throw t}for(const t of o){if(t.name.endsWith(".tmp"))continue;const f=n===""?t.name:`${n}/${t.name}`;t.isDirectory()?l(d(e,t.name),f,r):r.push(f)}}return i(l,"walk"),{async put(e,n){F("put");const r=c(e);B(h(r),{recursive:!0,mode:448});const o=`${r}.${w()}.tmp`,t=m(o,"wx",384);try{const f=typeof n=="string"?Buffer.from(n,"utf8"):Buffer.from(n);let y=0;for(;y<f.length;)y+=$(t,f,y);a(t)}catch(f){throw u(t),p(o,{force:!0}),f}u(t),N(o,r),O(h(r))},async get(e,n){try{if(!n)return b(c(e));const r=m(c(e),"r");try{const o=Buffer.allocUnsafe(n.length),t=D(r,o,0,n.length,n.start);return o.subarray(0,t)}finally{u(r)}}catch(r){if(r.code==="ENOENT")return null;throw r}},async list(e){const n=[];return l(s,"",n),n.filter(r=>r.startsWith(e)).sort((r,o)=>Buffer.compare(Buffer.from(r),Buffer.from(o)))},async delete(e){p(c(e),{force:!0})}}}i(x,"createDirectoryBlobStore");export{x as createDirectoryBlobStore};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var u=Object.defineProperty;var o=(t,r)=>u(t,"name",{value:r,configurable:!0});function p(t){if(t==="put"&&process.env.CRTR_FAULT_BLOB==="put_fail")throw new Error("blob put refused (CRTR_FAULT_BLOB=put_fail)")}o(p,"blobFault");export{p as blobFault};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/** The one blob-store interface: conversation objects, run-event chunks, job output, attachments and releases are
|
|
2
|
+
* objects under slash-separated keys (`conversations/<node>/<session>/<seq>.jsonl`). Implementations: a directory
|
|
3
|
+
* (a Mac, `~/.crouter/blobs/`) and R2 (the cloud). A key never starts with `/` and has no `.` or `..` segment. */
|
|
4
|
+
export interface BlobStore {
|
|
5
|
+
/** Write `data` at `key`, replacing any object there. Resolves once the object is durable. */
|
|
6
|
+
put(key: string, data: Buffer | Uint8Array | string): Promise<void>;
|
|
7
|
+
/** The object's bytes (just `length` bytes from `start` when a range is given; fewer at the end), or `null` when no object has this key. */
|
|
8
|
+
get(key: string, range?: {
|
|
9
|
+
start: number;
|
|
10
|
+
length: number;
|
|
11
|
+
}): Promise<Buffer | null>;
|
|
12
|
+
/** Every key beginning with `prefix`, in ascending byte order. */
|
|
13
|
+
list(prefix: string): Promise<string[]>;
|
|
14
|
+
/** Remove the object at `key`; removing an absent key is not an error. */
|
|
15
|
+
delete(key: string): Promise<void>;
|
|
16
|
+
}
|
|
17
|
+
/** A key is safe when it is a relative path of plain segments. Throws on anything else. */
|
|
18
|
+
export declare function assertBlobKey(key: string): void;
|
|
19
|
+
export declare function blobStore(): Promise<BlobStore>;
|
|
20
|
+
/** Drop the selected store (tests that change the environment). */
|
|
21
|
+
export declare function resetBlobStore(): void;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var c=Object.defineProperty;var r=(e,t)=>c(e,"name",{value:t,configurable:!0});function l(e){if(e===""||e.startsWith("/")||e.endsWith("/")||e.split("/").some(t=>t===""||t==="."||t===".."))throw new Error(`invalid blob key: ${JSON.stringify(e)}`)}r(l,"assertBlobKey");let o;async function _(){if(o)return o;const e=process.env.CRTR_R2_BUCKET;if(e){const t=r(s=>{const n=process.env[s];if(!n)throw new Error(`${s} is required when CRTR_R2_BUCKET is set`);return n},"need"),{createR2BlobStore:i}=await import("./r2.js");o=i({bucket:e,endpoint:t("CRTR_R2_ENDPOINT"),accessKeyId:t("CRTR_R2_ACCESS_KEY_ID"),secretAccessKey:t("CRTR_R2_SECRET_ACCESS_KEY")})}else{const[{join:t},{layoutRoot:i},{createDirectoryBlobStore:s}]=await Promise.all([import("node:path"),import("../layout.js"),import("./directory.js")]);o=s(t(i(),"blobs"))}return o}r(_,"blobStore");function a(){o=void 0}r(a,"resetBlobStore");export{l as assertBlobKey,_ as blobStore,a as resetBlobStore};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type BlobStore } from './index.js';
|
|
2
|
+
export interface R2Config {
|
|
3
|
+
bucket: string;
|
|
4
|
+
endpoint: string;
|
|
5
|
+
accessKeyId: string;
|
|
6
|
+
secretAccessKey: string;
|
|
7
|
+
}
|
|
8
|
+
/** S3-compatible object store (R2) over `fetch`: path-style requests signed with SigV4, region `auto`. */
|
|
9
|
+
export declare function createR2BlobStore(config: R2Config): BlobStore;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
var I=Object.defineProperty;var c=(a,o)=>I(a,"name",{value:o,configurable:!0});import{createHash as U,createHmac as C}from"node:crypto";import{assertBlobKey as g}from"./index.js";import{blobFault as z}from"./fault.js";const T=c(a=>U("sha256").update(a).digest("hex"),"sha256"),d=c((a,o)=>C("sha256",a).update(o).digest(),"hmac"),$=c(a=>encodeURIComponent(a).replace(/[!'()*]/g,o=>`%${o.charCodeAt(0).toString(16).toUpperCase()}`),"encode");function G(a){const o=new URL(a.endpoint);async function u(t,e,n,r,s){const l=`/${$(a.bucket)}${e===""?"":`/${e.split("/").map($).join("/")}`}`,h=[...n].sort(([i],[w])=>i<w?-1:1).map(([i,w])=>`${$(i)}=${$(w)}`).join("&"),m=new Date().toISOString().replace(/[:-]|\.\d{3}/g,""),y=m.slice(0,8),B=T(r??""),p={host:o.host,"x-amz-content-sha256":B,"x-amz-date":m},S=Object.keys(p).sort(),b=S.map(i=>`${i}:${p[i]}
|
|
2
|
+
`).join(""),x=S.join(";"),A=`${y}/auto/s3/aws4_request`,j=[t,l,h,b,x,B].join(`
|
|
3
|
+
`),E=["AWS4-HMAC-SHA256",m,A,T(j)].join(`
|
|
4
|
+
`),K=d(d(d(d(`AWS4${a.secretAccessKey}`,y),"auto"),"s3"),"aws4_request"),q=C("sha256",K).update(E).digest("hex");p.authorization=`AWS4-HMAC-SHA256 Credential=${a.accessKeyId}/${A}, SignedHeaders=${x}, Signature=${q}`;const{host:R,...H}=p;return s&&(H.range=`bytes=${s.start}-${s.start+s.length-1}`),await fetch(`${o.origin}${l}${h?`?${h}`:""}`,{method:t,headers:H,...r?{body:new Uint8Array(r)}:{}})}c(u,"send");async function f(t,e){if(!t.ok)throw new Error(`R2 ${e} failed (${t.status}): ${(await t.text()).slice(0,300)}`);return t}return c(f,"ok"),{async put(t,e){z("put"),g(t),await f(await u("PUT",t,[],typeof e=="string"?Buffer.from(e,"utf8"):Buffer.from(e)),`put ${t}`)},async get(t,e){g(t);const n=await u("GET",t,[],void 0,e);return n.status===416?(await n.arrayBuffer(),Buffer.alloc(0)):n.status===404?(await n.arrayBuffer(),null):Buffer.from(await(await f(n,`get ${t}`)).arrayBuffer())},async list(t){const e=[];let n;do{const r=[["list-type","2"],["prefix",t],...n?[["continuation-token",n]]:[]],s=await(await f(await u("GET","",r),`list ${t}`)).text();for(const l of s.matchAll(/<Key>([^<]*)<\/Key>/g))e.push(l[1].replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,'"').replace(/'/g,"'"));n=/<IsTruncated>true<\/IsTruncated>/.test(s)?/<NextContinuationToken>([^<]*)<\/NextContinuationToken>/.exec(s)?.[1]:void 0}while(n);return e.sort((r,s)=>Buffer.compare(Buffer.from(r),Buffer.from(s)))},async delete(t){g(t);const e=await u("DELETE",t,[]);e.status!==404?await f(e,`delete ${t}`):await e.arrayBuffer()}}}c(G,"createR2BlobStore");export{G as createR2BlobStore};
|
package/dist/core/bootstrap.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare function ensureProjectScope(argv: string[]): void
|
|
1
|
+
export declare function ensureProjectScope(argv: string[]): Promise<void>;
|
package/dist/core/bootstrap.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var
|
|
2
|
-
`)}}}t(
|
|
1
|
+
var i=Object.defineProperty;var t=(e,r)=>i(e,"name",{value:r,configurable:!0});import{homedir as s}from"node:os";import{join as c,relative as p,sep as f}from"node:path";import{appsRoot as u}from"./layout.js";import{findProjectScopeRoot as m,userScopeRoot as a}from"./scope.js";import{ensureScopeInitialized as S}from"./config.js";import{CRTR_DIR_NAME as d}from"../types.js";import{envDebug as h}from"../shared/env.js";const l=new Set(["help","--help","-h","--version","-v"]);function R(e){const r=e[2];return r===void 0||r==="sys"&&e[3]==="migrate"?!0:l.has(r)}t(R,"shouldSkipForArgv");async function T(e){try{if(process.env.CRTR_NO_AUTO_INIT==="1"||R(e)||m()!==null)return;const r=process.cwd();if(r===s())return;const o=p(u(),r).split(f);if(o.length===2&&o[1]==="home")return;const n=c(r,d);if(n===a())return;await S("project",n)}catch(r){if(h()){const o=r instanceof Error?r.message:String(r);process.stderr.write(`crtr: project-init error: ${o}
|
|
2
|
+
`)}}}t(T,"ensureProjectScope");export{T as ensureProjectScope};
|
|
@@ -31,8 +31,10 @@ export declare function pruneExpiredCreateRequests(now?: number): Promise<number
|
|
|
31
31
|
* durable so a retry after a daemon handover returns the original node. */
|
|
32
32
|
export declare function recordCreateRequestNode(requestKey: string, nodeId: string): Promise<void>;
|
|
33
33
|
/** Reserve a cold-birth node id for a key (state stays `reserved`) so a retry
|
|
34
|
-
* after a daemon restart resumes the same identity instead of minting another.
|
|
35
|
-
|
|
34
|
+
* after a daemon restart resumes the same identity instead of minting another.
|
|
35
|
+
* Only the first caller binds: two API processes holding one unbound key race
|
|
36
|
+
* here, and each gets back the id the key actually names. */
|
|
37
|
+
export declare function reserveCreateRequestNode(requestKey: string, nodeId: string): Promise<string | null>;
|
|
36
38
|
export declare function completeCreateRequest(requestKey: string, nodeId: string): Promise<void>;
|
|
37
39
|
/** Forget an unserved reservation after a pre-birth failure. A record that
|
|
38
40
|
* names a durable node is never removed by this path. */
|
|
@@ -301,12 +303,12 @@ export type TerminalGuardResult<T> = {
|
|
|
301
303
|
* of it and the write that depends on that (for example, a deferred inbox
|
|
302
304
|
* append). Fresh-reads `nodeId`'s
|
|
303
305
|
* (status, final_report, frozen_at) and either runs `body` (a write) or short-circuits
|
|
304
|
-
* with a `'terminal'`/`'missing'` outcome — the read
|
|
305
|
-
*
|
|
306
|
+
* with a `'terminal'`/`'missing'` outcome — the read takes the node row
|
|
307
|
+
* `FOR UPDATE` and holds it through `body`'s write in the same transaction, so
|
|
306
308
|
* a concurrent finish/cancel/finalization/deletion either commits entirely
|
|
307
|
-
* before this reads (observed here, `body` never runs) or
|
|
308
|
-
*
|
|
309
|
-
*
|
|
309
|
+
* before this reads (observed here, `body` never runs) or waits on the row
|
|
310
|
+
* until `body` commits — never in the gap a separate check-then-write left
|
|
311
|
+
* open. Pass the shared `hasNoNaturalCycle` predicate rather than
|
|
310
312
|
* a bespoke one so the two never drift.
|
|
311
313
|
*
|
|
312
314
|
* A dangling `nodeId` — the row deleted after the
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
var ie=Object.defineProperty;var i=(e,n)=>ie(e,"name",{value:n,configurable:!0});import{envNodeId as W}from"../../shared/env.js";import{lstatSync as oe,realpathSync as b,rmdirSync as re,rmSync as se,statSync as de}from"node:fs";import{basename as ue,dirname as F,isAbsolute as le,join as S,relative as ce,resolve as _e,sep as pe}from"node:path";import{removeTreeBeneath as C}from"../spaces/open-beneath.js";import{emitEvent as fe}from"../events/emit.js";import{withCanvasWrite as p,openDb as s}from"./db.js";import{conversationStore as Ee,ConversationNotFoundError as we}from"../conversation-store/index.js";import{hasUnseenWakeMail as ye,UNSEEN_WAKE_MAIL_SQL as me}from"./deliveries.js";import{isAppRun as H}from"./app-run.js";import{registerOutcomeAction as M}from"./outcome-actions.js";import{publish as Ne}from"../graph/events.js";import{nodeObject as Re}from"../graph/objects.js";import{findNodeBySessionFileSql as Se}from"./sessions.js";import{hydrateFault as
|
|
1
|
+
var ie=Object.defineProperty;var i=(e,n)=>ie(e,"name",{value:n,configurable:!0});import{envNodeId as W}from"../../shared/env.js";import{lstatSync as oe,realpathSync as b,rmdirSync as re,rmSync as se,statSync as de}from"node:fs";import{basename as ue,dirname as F,isAbsolute as le,join as S,relative as ce,resolve as _e,sep as pe}from"node:path";import{removeTreeBeneath as C}from"../spaces/open-beneath.js";import{emitEvent as fe}from"../events/emit.js";import{withCanvasWrite as p,openDb as s}from"./db.js";import{conversationStore as Ee,ConversationNotFoundError as we}from"../conversation-store/index.js";import{hasUnseenWakeMail as ye,UNSEEN_WAKE_MAIL_SQL as me}from"./deliveries.js";import{isAppRun as H}from"./app-run.js";import{registerOutcomeAction as M}from"./outcome-actions.js";import{publish as Ne}from"../graph/events.js";import{nodeObject as Re}from"../graph/objects.js";import{findNodeBySessionFileSql as Se}from"./sessions.js";import{hydrateFault as Oe}from"./recovery.js";import{hasUnreconciledWorktree as he,openWorktree as Te,readWorktree as Le,worktreeFromRow as De}from"./worktrees.js";import{isPidAlive as ve,isPidPresent as P,recordedPidLiveness as Ae}from"./pid.js";import{ensureHome as ge,jobDir as ke,nodeDir as Ue,nodeRunDir as $}from"./paths.js";import{appForNode as xe,ensureNodeDirs as Ie,nodeAgentDir as je}from"./node-agent-paths.js";import{appSpace as T}from"../layout.js";import{createObject as We,getById as L,ownerForGrantee as be,setObjectKind as Fe,setObjectName as Ce}from"../graph/objects.js";import{profileObject as He}from"../graph/reader.js";import{writeActsFor as q}from"../permissions/facts.js";import{CrtrError as Me}from"../errors.js";import{deleteNodeWithOwned as Pe}from"../graph/deletion.js";import{SUBTREE_ALL_IDS_SQL as $e,SUBTREE_IDS_SQL as qe}from"./tree.js";import{filterAsync as m,mapAsync as D}from"../async-array.js";function E(e,n){if(e==null)return null;const t=JSON.stringify(e);if(t===void 0)throw new TypeError(`${n} must be JSON-serializable`);return t}i(E,"jsonValue");async function vn(e,n){if((await e.prepare("SELECT deleting_at FROM nodes WHERE node_id = ?").get(n))?.deleting_at)throw new Error("run is deleting")}i(vn,"assertRunNotDeleting");async function B(e,n,t){try{return await He(e,n,t)}catch(a){if(a instanceof Me&&a.code==="not_found")return null;throw a}}i(B,"profileObjectFor");async function Be(e,n){const t=await be(n,e.grantee??"app:terminal"),a=e.profile_id?await B(n,e.profile_id,t):null;await We(n,{id:e.node_id,type:"node",kind:e.kind,owner:(a??t).id,privacy:"public",name:e.name,preview:""}),a===null&&e.sub&&await q(n,e.node_id,e.sub),await n.prepare(`INSERT INTO nodes (node_id, description, title, icon, cycles, mode, lifecycle, cwd, host_kind, profile_id, parent, spawned_by, creator, fork_from, fork_source_file, created, passive_default, cycle_pending, model_override, persona_ack_json, review_binding_json, launch_config_json, scopes_json, isolated, status, intent, final_report, finalized_at, deadline_at, "window", tmux_session, pane, sub, grant_id, client_id, metadata_json, run_id, event_cursor, usage_json, deleting_at, caused_by, app) VALUES (${Array(42).fill("?").join(", ")})`).run(e.node_id,e.description??null,e.title??null,e.icon??null,e.cycles??null,e.mode,e.lifecycle,e.cwd,e.host_kind??null,e.profile_id??null,e.parent??null,e.spawned_by??null,e.creator??null,e.fork_from??null,e.fork_source_file??null,e.created,e.passive_default===!0?1:0,e.cycle_pending===!0?1:0,e.model_override??null,E(e.persona_ack,"persona_ack"),E(e.review_binding,"review_binding"),E(e.launch,"launch"),E(e.scopes,"scopes"),e.isolated===!0?1:0,e.status??"active",e.intent??null,e.final_report??null,e.finalized_at??null,e.deadline_at??null,e.window??null,e.tmux_session??null,e.pane??null,e.sub??null,e.grant_id??null,e.client_id??null,e.metadata_json??null,e.run_id??null,e.event_cursor??null,e.usage_json??null,e.deleting_at??null,e.caused_by??null,t.id)}i(Be,"seedRow");function z(e){if(e.fault_id==null)return null;const n=Object.entries(e).filter(([t])=>t.startsWith("fault_")).map(([t,a])=>[t==="fault_id"?t:t.slice(6),a]);return Oe(Object.fromEntries(n))}i(z,"faultFrom");function f(e){const n={node_id:e.node_id,name:e.name,description:e.description??void 0,cycles:e.cycles??void 0,kind:e.kind,mode:e.mode,lifecycle:e.lifecycle,status:e.status,cwd:e.cwd,host_kind:e.host_kind??null,profile_id:e.profile_id??null,scopes:e.scopes_json==null?null:JSON.parse(e.scopes_json),isolated:e.isolated===1,grantee:e.grantee,sub:e.sub??null,grant_id:e.grant_id??null,client_id:e.client_id??null,metadata_json:e.metadata_json??null,run_id:e.run_id??null,event_cursor:e.event_cursor??null,last_activity_at:e.last_activity_at??null,usage_json:e.usage_json??null,caused_by:e.caused_by??null,last_turn_error_json:e.last_turn_error_json??null,deleting_at:e.deleting_at??null,parent:e.parent??null,created:e.created,intent:e.intent??null,frozen_at:e.frozen_at??null,respawn_failures:e.respawn_failures??0,respawn_not_before:e.respawn_not_before??null,launched_at:e.launched_at??null,last_settled_at:e.last_settled_at??null,terminal_reason:e.terminal_reason??null,final_report:e.final_report??null,finalized_at:e.finalized_at??null,outcome_kind:e.outcome_kind??null,outcome_reason:e.outcome_reason??null,outcome_at:e.outcome_at??null,outcome_revision:e.outcome_revision??0,outcome_detail_json:e.outcome_detail_json??null,deadline_at:e.deadline_at??null,telemetry_tokens_in:e.telemetry_tokens_in??null,telemetry_context_tokens:e.telemetry_context_tokens??null,telemetry_last_activity:e.telemetry_last_activity??null,telemetry_updated_at:e.telemetry_updated_at??null,pi_pid:e.pi_pid??null,pi_pid_identity:e.pi_pid_identity??null,window:e.window??null,tmux_session:e.tmux_session??null,pane:e.pane??null,fault:null,streaming:!1},t=P(n.pi_pid),a=z(e);return n.fault=a?.link==="pi\u2192provider"&&a.retry.by==="daemon"&&a.retry.disposition==="auto"&&!t?null:a,n.streaming=e.turn_open_at!==null&&e.turn_closed_at===null&&t,n}i(f,"rowFrom");async function J(e,n){return n??=await Le(e.node_id),{...f(e),title:e.title??void 0,icon:e.icon??void 0,spawned_by:e.spawned_by??null,creator:e.creator??null,fork_from:e.fork_from??null,fork_source_file:e.fork_source_file??null,passive_default:e.passive_default===1,cycle_pending:e.cycle_pending===1,model_override:e.model_override??null,scopes:e.scopes_json==null?null:JSON.parse(e.scopes_json),persona_ack:e.persona_ack_json==null?void 0:JSON.parse(e.persona_ack_json),review_binding:e.review_binding_json==null?void 0:JSON.parse(e.review_binding_json),launch:e.launch_config_json==null?void 0:JSON.parse(e.launch_config_json),pi_session_id:e.pi_session_id??null,pi_session_file:e.pi_session_file??null,...n===null?{}:{managed_worktree:n}}}i(J,"metaFrom");async function An(e,n={}){return ge(),await p(async t=>{await Be(e,t),e.managed_worktree!==void 0&&e.managed_worktree!==null&&await Te(e.node_id,e.managed_worktree,t),n.outcomeDelivery!==void 0&&await M(t,e.node_id,n.outcomeDelivery),await n.withinCreate?.(t,e)}),await Ie(e.node_id),await O(e.node_id)}i(An,"createNode");async function O(e){const n=await(await s()).prepare("SELECT * FROM node_rows WHERE node_id = ?").get(e);return n===void 0?null:await J(n)}i(O,"getNode");const ze=1440*60*1e3;function Y(e){return{requestKey:e.request_key,nodeId:e.node_id,state:e.state}}i(Y,"createRequestRecord");async function gn(e){const n=await(await s()).prepareUncached("SELECT request_key, node_id, state FROM create_requests WHERE request_key = ?").get(e);return n===void 0?null:Y(n)}i(gn,"findCreateRequest");async function kn(e){return await p(async n=>{const t=Date.now();await n.prepareUncached("DELETE FROM create_requests WHERE expires_at <= ?").run(t),await n.prepareUncached("INSERT INTO create_requests (request_key, node_id, expires_at, state) VALUES (?, NULL, ?, 'reserved') ON CONFLICT (request_key) DO NOTHING").run(e,t+ze);const a=await n.prepareUncached("SELECT request_key, node_id, state FROM create_requests WHERE request_key = ?").get(e);return Y(a)})}i(kn,"reserveCreateRequest");async function Un(e=Date.now()){return Number((await(await s()).prepareUncached("DELETE FROM create_requests WHERE expires_at <= ?").run(e)).changes)}i(Un,"pruneExpiredCreateRequests");async function xn(e,n){await(await s()).prepareUncached("UPDATE create_requests SET node_id = ?, state = 'complete' WHERE request_key = ?").run(n,e)}i(xn,"recordCreateRequestNode");async function In(e,n){const t=await s();return await t.prepareUncached("UPDATE create_requests SET node_id = ?, state = 'reserved' WHERE request_key = ? AND node_id IS NULL").run(n,e),(await t.prepareUncached("SELECT node_id FROM create_requests WHERE request_key = ?").get(e))?.node_id??null}i(In,"reserveCreateRequestNode");async function jn(e,n){await(await s()).prepareUncached("UPDATE create_requests SET state = 'complete' WHERE request_key = ? AND node_id = ?").run(e,n)}i(jn,"completeCreateRequest");async function Wn(e,n){await p(async t=>{if(n===null){await t.prepareUncached("DELETE FROM create_requests WHERE request_key = ? AND node_id IS NULL").run(e);return}await t.prepareUncached("DELETE FROM create_requests WHERE request_key = ? AND node_id = ?").run(e,n)})}i(Wn,"abandonCreateRequest");function bn(e){return _e(e)}i(bn,"canonicalSessionFile");async function Fn(e){const n=await Se(e);return n===null?null:await O(n)}i(Fn,"findNodeBySessionFile");async function Cn(e){const n=await(await s()).prepare("SELECT * FROM node_rows WHERE node_id = ?").get(e);return n?f(n):null}i(Cn,"getRow");async function Hn(e){const n=await(await s()).prepare("SELECT * FROM node_rows WHERE pane = ?").get(e);return n?f(n):null}i(Hn,"getRowByPane");async function Mn(e){return(await(await s()).prepare(`SELECT * FROM node_rows
|
|
2
2
|
WHERE deadline_at IS NOT NULL AND outcome_at IS NULL
|
|
3
3
|
AND deadline_at <= ? AND status IN ('active','idle') AND kind != 'human'
|
|
4
4
|
ORDER BY deadline_at, created, node_id`).all(e)).map(f)}i(Mn,"dueNodeDeadlines");async function Pn(e,n){return Number((await(await s()).prepare("UPDATE nodes SET deadline_at = ? WHERE node_id = ?").run(n,e)).changes)===1}i(Pn,"setNodeDeadline");async function $n(e,n){return!Number.isFinite(n)||n<=0?0:await p(async t=>{const a=await t.prepare(`SELECT node_id, deadline_at FROM nodes
|
|
5
|
-
WHERE profile_id = ? AND deadline_at IS NOT NULL AND status IN ('active', 'idle')`).all(e),o=t.prepare("UPDATE nodes SET deadline_at = ? WHERE node_id = ? AND deadline_at = ?");let r=0;for(const d of a){const l=Date.parse(d.deadline_at);Number.isNaN(l)||(r+=Number((await o.run(new Date(l+n).toISOString(),d.node_id,d.deadline_at)).changes))}return r})}i($n,"shiftProfileNodeDeadlines");function v(e,n){if(e==null)return null;if(typeof e=="string"||typeof e=="number"||typeof e=="bigint"||e instanceof Uint8Array)return e;throw new TypeError(`${n} must be a SQLite scalar`)}i(v,"sqlInput");async function qn(e,n){const t=[],a=i((r,d=r)=>{Object.prototype.hasOwnProperty.call(n,r)&&t.push([d,v(n[r],r)])},"add");if(a("description"),a("title"),a("icon"),a("cycles"),a("mode"),a("lifecycle"),a("cwd"),a("host_kind"),a("profile_id"),a("parent"),a("spawned_by"),a("creator"),a("fork_from"),a("fork_source_file"),a("model_override"),Object.prototype.hasOwnProperty.call(n,"passive_default")&&t.push(["passive_default",n.passive_default===!0?1:0]),Object.prototype.hasOwnProperty.call(n,"cycle_pending")&&t.push(["cycle_pending",n.cycle_pending===!0?1:0]),Object.prototype.hasOwnProperty.call(n,"persona_ack")&&t.push(["persona_ack_json",E(n.persona_ack,"persona_ack")]),Object.prototype.hasOwnProperty.call(n,"review_binding")&&t.push(["review_binding_json",E(n.review_binding,"review_binding")]),Object.prototype.hasOwnProperty.call(n,"isolated"))throw new TypeError("isolated cannot change after node creation");Object.prototype.hasOwnProperty.call(n,"scopes")&&t.push(["scopes_json",E(n.scopes,"scopes")]),Object.prototype.hasOwnProperty.call(n,"launch")&&t.push(["launch_config_json",E(n.launch,"launch")]);const o=i(r=>Object.prototype.hasOwnProperty.call(n,r),"has");return await p(async r=>{const d=await L(r,e);if(d===null||d.type!=="node")throw new Error(`unknown node: ${e}`);if(o("name")&&await Ce(r,d,v(n.name,"name")),o("kind")&&await Fe(r,d,v(n.kind,"kind")),t.length===0)return;if(o("profile_id")){const u=await r.prepare("SELECT app FROM nodes WHERE node_id = ?").get(e),_=u?.app?await L(r,u.app):null;if(_){const w=n.profile_id?await B(r,n.profile_id,_):null;await r.prepare("UPDATE objects SET owner = ? WHERE id = ?").run((w??_).id,e);const R=(await r.prepare("SELECT sub FROM nodes WHERE node_id = ?").get(e)).sub;w===null&&R&&await q(r,e,R)}}if((await r.prepareUncached(`UPDATE nodes SET ${t.map(([u])=>`${u} = ?`).join(", ")} WHERE node_id = ?`).run(...t.map(([,u])=>u),e)).changes!==1)throw new Error(`unknown node: ${e}`)}),await
|
|
5
|
+
WHERE profile_id = ? AND deadline_at IS NOT NULL AND status IN ('active', 'idle')`).all(e),o=t.prepare("UPDATE nodes SET deadline_at = ? WHERE node_id = ? AND deadline_at = ?");let r=0;for(const d of a){const l=Date.parse(d.deadline_at);Number.isNaN(l)||(r+=Number((await o.run(new Date(l+n).toISOString(),d.node_id,d.deadline_at)).changes))}return r})}i($n,"shiftProfileNodeDeadlines");function v(e,n){if(e==null)return null;if(typeof e=="string"||typeof e=="number"||typeof e=="bigint"||e instanceof Uint8Array)return e;throw new TypeError(`${n} must be a SQLite scalar`)}i(v,"sqlInput");async function qn(e,n){const t=[],a=i((r,d=r)=>{Object.prototype.hasOwnProperty.call(n,r)&&t.push([d,v(n[r],r)])},"add");if(a("description"),a("title"),a("icon"),a("cycles"),a("mode"),a("lifecycle"),a("cwd"),a("host_kind"),a("profile_id"),a("parent"),a("spawned_by"),a("creator"),a("fork_from"),a("fork_source_file"),a("model_override"),Object.prototype.hasOwnProperty.call(n,"passive_default")&&t.push(["passive_default",n.passive_default===!0?1:0]),Object.prototype.hasOwnProperty.call(n,"cycle_pending")&&t.push(["cycle_pending",n.cycle_pending===!0?1:0]),Object.prototype.hasOwnProperty.call(n,"persona_ack")&&t.push(["persona_ack_json",E(n.persona_ack,"persona_ack")]),Object.prototype.hasOwnProperty.call(n,"review_binding")&&t.push(["review_binding_json",E(n.review_binding,"review_binding")]),Object.prototype.hasOwnProperty.call(n,"isolated"))throw new TypeError("isolated cannot change after node creation");Object.prototype.hasOwnProperty.call(n,"scopes")&&t.push(["scopes_json",E(n.scopes,"scopes")]),Object.prototype.hasOwnProperty.call(n,"launch")&&t.push(["launch_config_json",E(n.launch,"launch")]);const o=i(r=>Object.prototype.hasOwnProperty.call(n,r),"has");return await p(async r=>{const d=await L(r,e);if(d===null||d.type!=="node")throw new Error(`unknown node: ${e}`);if(o("name")&&await Ce(r,d,v(n.name,"name")),o("kind")&&await Fe(r,d,v(n.kind,"kind")),t.length===0)return;if(o("profile_id")){const u=await r.prepare("SELECT app FROM nodes WHERE node_id = ?").get(e),_=u?.app?await L(r,u.app):null;if(_){const w=n.profile_id?await B(r,n.profile_id,_):null;await r.prepare("UPDATE objects SET owner = ? WHERE id = ?").run((w??_).id,e);const R=(await r.prepare("SELECT sub FROM nodes WHERE node_id = ?").get(e)).sub;w===null&&R&&await q(r,e,R)}}if((await r.prepareUncached(`UPDATE nodes SET ${t.map(([u])=>`${u} = ?`).join(", ")} WHERE node_id = ?`).run(...t.map(([,u])=>u),e)).changes!==1)throw new Error(`unknown node: ${e}`)}),await O(e)}i(qn,"updateNode");async function Bn(e,n){await(await s()).prepare("UPDATE nodes SET status = ? WHERE node_id = ?").run(n,e)}i(Bn,"setStatus");async function zn(e,n){await(await s()).prepare("UPDATE nodes SET intent = ? WHERE node_id = ?").run(n??null,e)}i(zn,"setIntent");async function Jn(e,n,t={}){if(t.outcome===void 0){const o=[],r=[];Object.prototype.hasOwnProperty.call(n,"status")&&(o.push("status = ?"),r.push(n.status??null)),Object.prototype.hasOwnProperty.call(n,"intent")&&(o.push("intent = ?"),r.push(n.intent??null)),Object.prototype.hasOwnProperty.call(n,"terminal_reason")&&(o.push("terminal_reason = ?"),r.push(n.terminal_reason??null));const d=["node_id = ?"];r.push(e),t.fromStatuses!==void 0&&(d.push(`status IN (${t.fromStatuses.map(()=>"?").join(", ")})`),r.push(...t.fromStatuses)),t.requireNoFinalReport===!0&&d.push("final_report IS NULL");const l=await(await s()).prepareUncached(`UPDATE nodes SET ${o.join(", ")} WHERE ${d.join(" AND ")}`).run(...r);return Number(l.changes)}const a=t.outcome;return await p(async o=>{const r=[],d=[];Object.prototype.hasOwnProperty.call(n,"status")&&(r.push("status = ?"),d.push(n.status??null)),Object.prototype.hasOwnProperty.call(n,"intent")&&(r.push("intent = ?"),d.push(n.intent??null)),Object.prototype.hasOwnProperty.call(n,"terminal_reason")&&(r.push("terminal_reason = ?"),d.push(n.terminal_reason??null));const l=i((R,y)=>a.supersede===!0?"?":`CASE WHEN outcome_at IS NULL THEN ? ELSE ${y} END`,"outcomeValue");r.push(`outcome_kind = ${l(a.kind,"outcome_kind")}`,`outcome_reason = ${l(a.reason,"outcome_reason")}`,`outcome_detail_json = ${l(a.detailJson,"outcome_detail_json")}`,`outcome_revision = ${a.supersede===!0?"outcome_revision + 1":"CASE WHEN outcome_at IS NULL THEN outcome_revision + 1 ELSE outcome_revision END"}`,`outcome_at = ${l(a.at,"outcome_at")}`),d.push(a.kind,a.reason,a.detailJson,a.at);const u=["node_id = ?"];d.push(e),t.fromStatuses!==void 0&&(u.push(`status IN (${t.fromStatuses.map(()=>"?").join(", ")})`),d.push(...t.fromStatuses)),t.requireNoFinalReport===!0&&u.push("final_report IS NULL");const _=await o.prepareUncached(`UPDATE nodes SET ${r.join(", ")} WHERE ${u.join(" AND ")}`).run(...d);if(Number(_.changes)===0)return 0;const w=await o.prepare("SELECT outcome_at FROM nodes WHERE node_id = ?").get(e);return(a.supersede===!0||w.outcome_at===a.at)&&a.documentJson!==null&&a.documentJson!==void 0&&await Ne(o,{event:"outcome",object:await Re(o,e),actor:null,attrs:{revision:Number((await o.prepare("SELECT outcome_revision FROM nodes WHERE node_id = ?").get(e)).outcome_revision)},messageBody:JSON.parse(a.documentJson)}),Number(_.changes)})}i(Jn,"transitionStatusIntent");async function Yn(e){return(await(await s()).prepare("SELECT final_report FROM nodes WHERE node_id = ?").get(e))?.final_report??null}i(Yn,"getFinalReport");async function Qn(e,n){return(await(await s()).prepare("UPDATE nodes SET final_report = NULL, finalized_at = NULL WHERE node_id = ? AND final_report = ?").run(e,n)).changes>0}i(Qn,"clearFinalReportIfMatches");async function Vn(e,n){await(await s()).prepare('UPDATE nodes SET tmux_session = ?, "window" = ?, pane = ? WHERE node_id = ?').run(n.tmux_session??null,n.window??null,n.pane??null,e)}i(Vn,"setPresence");async function Kn(e,n){await(await s()).prepare("UPDATE nodes SET launched_at = ?, frozen_at = NULL, respawn_not_before = NULL WHERE node_id = ?").run(n,e)}i(Kn,"recordLaunch");async function Gn(e,n){await(await s()).prepare("UPDATE nodes SET last_settled_at = ? WHERE node_id = ?").run(n,e)}i(Gn,"recordSettledTurn");async function Xn(e,n){await(await s()).prepare("UPDATE nodes SET frozen_at = ? WHERE node_id = ?").run(n,e)}i(Xn,"setFrozen");async function Zn(e){await(await s()).prepare("UPDATE nodes SET frozen_at = NULL WHERE node_id = ?").run(e)}i(Zn,"clearFrozen");async function et(e,n){await(await s()).prepare("UPDATE nodes SET respawn_failures = ?, respawn_not_before = ? WHERE node_id = ?").run(n.failures,n.notBefore,e)}i(et,"recordRespawnAttempt");const N="node_id NOT IN (SELECT node_id FROM warm_pool)",Q=["state","cleanup_state","path","branch","repo_root","base_ref","base_sha","created_at","closed_at","next_attempt_at","attempts","quarantined","sweep_reason","sweep_detail","sweep_last_at","sweep_observed_json","abandoned_json","land_intent_json","disposal_json"];function Je(e){return e.worktree_state===null?null:De(Object.fromEntries(Q.map(n=>[n,e[`worktree_${n}`]])))}i(Je,"worktreeFromProjection");async function nt(e){const n=Q.map(a=>`w.${a} AS worktree_${a}`).join(", "),t=await(await s()).prepareUncached(`SELECT n.*, ${n} FROM node_rows n LEFT JOIN worktrees w ON w.node_id = n.node_id WHERE n.profile_id = ? ORDER BY n.created`).all(e);return await D(t,async a=>await J(a,Je(a)))}i(nt,"listNodesByProfile");async function tt(){return(await(await s()).prepare(`SELECT
|
|
6
6
|
node_id, name, description, kind, mode, lifecycle, status, cwd, profile_id,
|
|
7
7
|
grantee, parent, created, frozen_at, terminal_reason, final_report,
|
|
8
8
|
telemetry_tokens_in, telemetry_updated_at, pi_pid, turn_open_at, turn_closed_at,
|
|
@@ -48,20 +48,20 @@ var ie=Object.defineProperty;var i=(e,n)=>ie(e,"name",{value:n,configurable:!0})
|
|
|
48
48
|
ORDER BY v.created`;async function rt(){return(await(await s()).prepare(Ve).all()).map(f)}i(rt,"listNodesForSupervision");const V=i(e=>`(${e}.status = 'done' AND ${e}.intent = 'parked' AND ${e}.lifecycle = 'resident' AND ${e}.final_report IS NULL AND ${e}.deleting_at IS NULL)`,"PARKED_RESIDENT_SQL"),Ke=i(e=>`(${e}.status IN ('active', 'idle') OR ${V(e)} OR (${e}.status IN ('done', 'canceled', 'dead') AND ${e}.frozen_at IS NOT NULL AND ${e}.final_report IS NULL))`,"RESUMABLE_NODE_SQL");async function st(e){return await(await s()).prepare(`SELECT node_id, cwd FROM nodes WHERE ${Ke("nodes")} AND node_id != ?`).all(e)}i(st,"resumableNodeCwds");async function dt(){return(await(await s()).prepare(`SELECT v.* FROM node_rows v
|
|
49
49
|
WHERE ${V("v")}
|
|
50
50
|
AND EXISTS (SELECT 1 FROM deliveries d WHERE d.destination_id = v.node_id AND ${me("d")}) AND v.kind != 'human' AND v.node_id NOT IN (SELECT node_id FROM warm_pool)
|
|
51
|
-
ORDER BY v.created`).all()).map(f)}i(dt,"listParkedResidentsWithWakeMail");async function ut(e,n){await(await s()).prepare("INSERT INTO warm_pool (node_id, recipe_key, created) VALUES (?, ?, ?) ON CONFLICT (node_id) DO UPDATE SET recipe_key = excluded.recipe_key, created = excluded.created").run(e,n,new Date().toISOString())}i(ut,"registerWarmSpare");async function lt(e){return(await(await s()).prepare("DELETE FROM warm_pool WHERE node_id = ?").run(e)).changes>0}i(lt,"unregisterWarmSpare");async function
|
|
51
|
+
ORDER BY v.created`).all()).map(f)}i(dt,"listParkedResidentsWithWakeMail");async function ut(e,n){await(await s()).prepare("INSERT INTO warm_pool (node_id, recipe_key, created) VALUES (?, ?, ?) ON CONFLICT (node_id) DO UPDATE SET recipe_key = excluded.recipe_key, created = excluded.created").run(e,n,new Date().toISOString())}i(ut,"registerWarmSpare");async function lt(e){return(await(await s()).prepare("DELETE FROM warm_pool WHERE node_id = ?").run(e)).changes>0}i(lt,"unregisterWarmSpare");async function A(e,n){const t=`SELECT w.node_id AS node_id, w.recipe_key AS recipe_key, w.created AS created,
|
|
52
52
|
n.status AS status, n.pi_pid AS pi_pid, n.pi_pid_identity AS pi_pid_identity
|
|
53
|
-
FROM warm_pool w JOIN node_rows n ON n.node_id = w.node_id`+(n===void 0?"":" WHERE w.recipe_key = ?")+" ORDER BY w.created";return(n===void 0?await e.prepareUncached(t).all():await e.prepareUncached(t).all(n)).map(o=>({node_id:o.node_id,recipe_key:o.recipe_key,created:o.created,status:o.status,pi_pid:o.pi_pid??null,pi_pid_identity:o.pi_pid_identity??null}))}i(
|
|
53
|
+
FROM warm_pool w JOIN node_rows n ON n.node_id = w.node_id`+(n===void 0?"":" WHERE w.recipe_key = ?")+" ORDER BY w.created";return(n===void 0?await e.prepareUncached(t).all():await e.prepareUncached(t).all(n)).map(o=>({node_id:o.node_id,recipe_key:o.recipe_key,created:o.created,status:o.status,pi_pid:o.pi_pid??null,pi_pid_identity:o.pi_pid_identity??null}))}i(A,"warmSpareRowsFor");async function ct(){return await A(await s())}i(ct,"listWarmSpares");async function _t(e){return await(await s()).prepare("SELECT 1 FROM warm_pool WHERE node_id = ?").get(e)!==void 0}i(_t,"isWarmSpare");function K(e){return e.status!=="active"&&e.status!=="idle"?!1:Ae(e.pi_pid,e.pi_pid_identity)==="alive"}i(K,"spareIsClaimable");async function pt(e,n,t={}){return await p(async a=>{const o=(await A(a,e)).find(K);return o===void 0||t.requestKey!==void 0&&(await a.prepareUncached("UPDATE create_requests SET node_id = ?, state = 'warm_claimed' WHERE request_key = ? AND node_id IS NULL").run(o.node_id,t.requestKey)).changes===0||(await a.prepare("DELETE FROM warm_pool WHERE node_id = ?").run(o.node_id)).changes===0?null:(await a.prepare("UPDATE nodes SET created = ?, deadline_at = ? WHERE node_id = ?").run(n,t.deadlineAt??null,o.node_id),t.outcomeDelivery!==void 0&&await M(a,o.node_id,t.outcomeDelivery),o.node_id)})}i(pt,"claimWarmSpare");async function ft(e){return(await A(await s(),e)).filter(K).length}i(ft,"warmSpareCount");async function Et(e){return(await(await s()).prepare("SELECT node_id FROM nodes WHERE parent = ? ORDER BY created").all(e)).map(n=>n.node_id)}i(Et,"childrenOf");async function wt(){return(await(await s()).prepareUncached(`SELECT node_id, name, kind, mode, lifecycle, status, cwd, host_kind, parent, created, description
|
|
54
54
|
FROM node_rows WHERE ${N} ORDER BY created`).all()).map(e=>({node_id:e.node_id,name:e.name,kind:e.kind,mode:e.mode,lifecycle:e.lifecycle,status:e.status,cwd:e.cwd,host_kind:e.host_kind??null,parent:e.parent??null,created:e.created,description:e.description??null}))}i(wt,"rosterNodes");async function yt(e){return(await(await s()).prepareUncached(`SELECT * FROM node_rows
|
|
55
55
|
WHERE parent IS NULL AND kind != 'human'
|
|
56
56
|
AND status IN ('active','idle') AND cwd = ?
|
|
57
57
|
AND ${N}
|
|
58
|
-
ORDER BY created DESC`).all(e)).map(f)}i(yt,"listResumableRoots");export*from"./tree.js";async function mt(e,n,t){return await p(async a=>{const o=await a.prepare("SELECT status, final_report, frozen_at FROM nodes WHERE node_id = ?").get(e);return o===void 0?{kind:"missing"}:n(o)?{kind:"terminal",status:o.status,final_report:o.final_report}:{kind:"ran",result:await t()}})}i(mt,"withFreshTerminalGuard");async function
|
|
59
|
-
AND NOT EXISTS (SELECT 1 FROM sessions s WHERE s.node_id = n.node_id) LIMIT 1`);for(const{id:o,path:r,dir:d}of e)if(!(await t.get(o)!==void 0||await a.get(o)!==void 0)&&oe(r,{throwIfNoEntry:!1})!==void 0){if(!Ge(d,r)){console.error(`[canvas] not deleting transcript outside its node's conversations directory: ${r}`);continue}try{await Ee().delete(o,r)}catch(l){if(!(l instanceof we))throw l}}}i(k,"deleteNodeConversations");function Ge(e,n){try{const t=ce(b(e),S(b(F(n)),ue(n)));return t!==""&&t!==".."&&!t.startsWith(`..${pe}`)&&!le(t)}catch(t){if(t.code==="ENOENT")return!1;throw t}}i(Ge,"isBeneath");async function
|
|
58
|
+
ORDER BY created DESC`).all(e)).map(f)}i(yt,"listResumableRoots");export*from"./tree.js";async function mt(e,n,t){return await p(async a=>{const o=await a.prepare("SELECT status, final_report, frozen_at FROM nodes WHERE node_id = ? FOR UPDATE").get(e);return o===void 0?{kind:"missing"}:n(o)?{kind:"terminal",status:o.status,final_report:o.final_report}:{kind:"ran",result:await t()}})}i(mt,"withFreshTerminalGuard");async function h(e){return await he(e)}i(h,"hasUnreconciledManagedWorktree");async function G(e,n={}){return!["done","dead","canceled"].includes(e.status)||e.pi_pid!==null||e.frozen_at!==null||await h(e.node_id)||e.node_id===W()||H(e)?!1:n.pastTtl===!0||!["crashed","stranded",null].includes(e.terminal_reason??null)}i(G,"isCollectible");async function g(e){if(e.length===0)return[];const n=e.map(()=>"?").join(","),t=await(await s()).prepareUncached(`SELECT s.session_id, s.transcript_path, s.node_id, n.grantee FROM sessions s JOIN node_rows n ON n.node_id = s.node_id WHERE s.node_id IN (${n}) AND s.session_id IS NOT NULL AND s.transcript_path IS NOT NULL ORDER BY s.created_at, s.seq`).all(...e);return[...new Map(t.map(a=>[a.session_id,{id:a.session_id,path:a.transcript_path,dir:S(T(a.grantee).conversations,a.node_id)}])).values()]}i(g,"nodeConversationIds");async function k(e){const n=await s(),t=n.prepare("SELECT 1 FROM sessions WHERE session_id = ? LIMIT 1"),a=n.prepare(`SELECT 1 FROM nodes n WHERE n.fork_source_file LIKE '%\\_' || ? || '.jsonl' ESCAPE '\\'
|
|
59
|
+
AND NOT EXISTS (SELECT 1 FROM sessions s WHERE s.node_id = n.node_id) LIMIT 1`);for(const{id:o,path:r,dir:d}of e)if(!(await t.get(o)!==void 0||await a.get(o)!==void 0)&&oe(r,{throwIfNoEntry:!1})!==void 0){if(!Ge(d,r)){console.error(`[canvas] not deleting transcript outside its node's conversations directory: ${r}`);continue}try{await Ee().delete(o,r)}catch(l){if(!(l instanceof we))throw l}}}i(k,"deleteNodeConversations");function Ge(e,n){try{const t=ce(b(e),S(b(F(n)),ue(n)));return t!==""&&t!==".."&&!t.startsWith(`..${pe}`)&&!le(t)}catch(t){if(t.code==="ENOENT")return!1;throw t}}i(Ge,"isBeneath");async function U(e,n){const t=await L(e,n);return t===null||t.deleted_at!==null?!1:(await Pe(e,t),!0)}i(U,"deleteNodeObject");async function x(e){return{nodeId:e,app:await O(e)===null?null:await xe(e)}}i(x,"nodeFiles");async function X({nodeId:e,app:n}){n!==null&&C(T(n).nodes,await je(e,n)),C(F($(e)),$(e))}i(X,"removeNodeAppTrees");function Z({nodeId:e}){return[Ue(e)]}i(Z,"nodeOwnedDirs");function ee({nodeId:e,app:n}){if(n!==null)try{re(S(T(n).conversations,e))}catch(t){if(!["ENOENT","ENOTEMPTY"].includes(t.code??""))throw t}}i(ee,"removeNodeConversationDir");async function I(e){await X(e);for(const n of Z(e))se(n,{recursive:!0,force:!0});ee(e)}i(I,"removeNodeFiles");async function Nt(e){if(await h(e))return{deleted:!1};const n=await x(e),t=await g([e]),a=await p(async o=>(await U(o,e),{deleted:!0}));return await k(t),await I(n),a}i(Nt,"deleteNode");async function Rt(e){const n=[...new Set(e)];if(n.length===0)return[];const t=await m(n,h);if(t.length>0)throw new Error(`refusing to delete nodes with unreconciled managed worktrees: ${t.join(", ")}`);const a=await D(n,x),o=await g(n),r=n.map(()=>"?").join(","),d=(await(await s()).prepareUncached(`SELECT node_id FROM nodes WHERE node_id IN (${r}) ORDER BY created`).all(...n)).map(({node_id:u})=>u),l=await m(d,async u=>await p(async _=>await U(_,u)));await k(o);for(const u of l){const _=a[n.indexOf(u)];await j(_,async()=>await I(_))}return l}i(Rt,"deleteNodes");async function St(e){const n=e.dryRun??!1,t=e.includeStale??!1,a=Date.now()-e.ttlDays*864e5,o=new Date(a).toISOString(),r=W()??"",d=await s(),l=i(c=>ae(c)<a,"quiet"),u=i(c=>({node_id:c.node_id,status:c.status,created:c.created}),"toPruned"),_=await Xe(),w=(await m((await d.prepare(`SELECT * FROM node_rows
|
|
60
60
|
WHERE status IN ('dead', 'done', 'canceled') AND created < ?
|
|
61
61
|
ORDER BY created`).all(o)).map(f),async c=>await G(c,{pastTtl:!0})&&l(c)&&!_.has(c.node_id)&&!await e.held(c.node_id))).map(u),R=t?(await m((await d.prepare(`SELECT * FROM node_rows
|
|
62
62
|
WHERE status IN ('active', 'idle') AND created < ?
|
|
63
|
-
ORDER BY created`).all(o)).map(f),async c=>c.node_id!==r&&!ve(c.pi_pid??null)&&(c.frozen_at??null)===null&&(c.respawn_not_before??null)===null&&c.intent!=="idle-release"&&!H(c)&&!await ye(c.node_id)&&!await
|
|
63
|
+
ORDER BY created`).all(o)).map(f),async c=>c.node_id!==r&&!ve(c.pi_pid??null)&&(c.frozen_at??null)===null&&(c.respawn_not_before??null)===null&&c.intent!=="idle-release"&&!H(c)&&!await ye(c.node_id)&&!await h(c.node_id)&&l(c)&&!await e.held(c.node_id))).map(u):[],y=await ne([...w,...R]);return n||y.length===0?{pruned:y,dryRun:n}:(await te(y,e.removeDirs),{pruned:y,dryRun:n})}i(St,"pruneNodes");async function Xe(){const e=await(await s()).prepare(`SELECT DISTINCT d.owner AS owner FROM watches w
|
|
64
64
|
JOIN objects d ON d.id = w.object AND d.type = 'document' AND d.deleted_at IS NULL
|
|
65
65
|
JOIN objects o ON o.id = w.watcher AND o.deleted_at IS NULL
|
|
66
66
|
LEFT JOIN nodes n ON n.node_id = w.watcher
|
|
67
|
-
WHERE w.watcher != d.owner AND d.owner IS NOT NULL AND (n.node_id IS NULL OR n.status IN ('active', 'idle'))`).all();return new Set(e.map(n=>n.owner))}i(Xe,"ownersOfWatchedDocuments");async function ne(e){const t=(await s()).prepare("SELECT node_id FROM nodes WHERE run_id = ? AND node_id != ?"),a=new Set(e.map(o=>o.node_id));return await m(e,async o=>(await t.all(o.node_id,o.node_id)).every(r=>a.has(r.node_id)))}i(ne,"retainRunRootsWithMembers");async function te(e,n){if(e.length===0)return;const t=await D(e,async o=>await
|
|
67
|
+
WHERE w.watcher != d.owner AND d.owner IS NOT NULL AND (n.node_id IS NULL OR n.status IN ('active', 'idle'))`).all();return new Set(e.map(n=>n.owner))}i(Xe,"ownersOfWatchedDocuments");async function ne(e){const t=(await s()).prepare("SELECT node_id FROM nodes WHERE run_id = ? AND node_id != ?"),a=new Set(e.map(o=>o.node_id));return await m(e,async o=>(await t.all(o.node_id,o.node_id)).every(r=>a.has(r.node_id)))}i(ne,"retainRunRootsWithMembers");async function te(e,n){if(e.length===0)return;const t=await D(e,async o=>await x(o.node_id)),a=await g(e.map(o=>o.node_id));for(const o of e)await p(async r=>await U(r,o.node_id));if(await k(a),n!==void 0){for(const o of t)await j(o,async()=>{await X(o),ee(o)});n(t.flatMap(Z));return}for(const o of t)await j(o,async()=>await I(o))}i(te,"deletePrunedNodes");async function j(e,n){try{n()}catch(t){fe({level:"error",event:"canvas.node_files.remove_failed",error:t,fields:{node_id:e.nodeId}})}}i(j,"eachNodeBestEffort");function ae(e){let n=0;for(const t of[e.created,e.launched_at,e.last_settled_at,e.finalized_at,e.outcome_at,e.last_activity_at]){if(t==null)continue;const a=Date.parse(t);Number.isFinite(a)&&a>n&&(n=a)}try{const t=de(S(ke(e.node_id),"telemetry.json"),{throwIfNoEntry:!1});t!==void 0&&t.mtimeMs>n&&(n=t.mtimeMs)}catch{}return n}i(ae,"lastActivityMs");async function Ot(e){const n=e.dryRun??!1,t=await Ye(),a=await m(t,async u=>await G(u)&&!await e.held(u.node_id)),o=t.length-a.length,r=Math.max(0,e.maxNodes-o),d=a.map(u=>({row:u,recency:ae(u)})).sort((u,_)=>_.recency-u.recency).slice(r).map(({row:u})=>({node_id:u.node_id,status:u.status,created:u.created})),l=await ne(d);return n||l.length===0?{pruned:l,dryRun:n}:(await te(l),{pruned:l,dryRun:n})}i(Ot,"pruneToLimit");export{V as PARKED_RESIDENT_SQL,Ke as RESUMABLE_NODE_SQL,Wn as abandonCreateRequest,vn as assertRunNotDeleting,tt as browseNodes,bn as canonicalSessionFile,Et as childrenOf,pt as claimWarmSpare,Qn as clearFinalReportIfMatches,Zn as clearFrozen,jn as completeCreateRequest,An as createNode,Nt as deleteNode,Rt as deleteNodes,Mn as dueNodeDeadlines,gn as findCreateRequest,Fn as findNodeBySessionFile,Yn as getFinalReport,O as getNode,Cn as getRow,Hn as getRowByPane,it as graphNodes,G as isCollectible,_t as isWarmSpare,ae as lastActivityMs,Ye as listNodes,nt as listNodesByProfile,rt as listNodesForSupervision,dt as listParkedResidentsWithWakeMail,yt as listResumableRoots,ot as listTerminalPlacementResidue,ct as listWarmSpares,x as nodeFiles,Ve as nodesForSupervisionSql,Un as pruneExpiredCreateRequests,St as pruneNodes,Ot as pruneToLimit,xn as recordCreateRequestNode,Kn as recordLaunch,et as recordRespawnAttempt,Gn as recordSettledTurn,ut as registerWarmSpare,I as removeNodeFiles,kn as reserveCreateRequest,In as reserveCreateRequestNode,st as resumableNodeCwds,wt as rosterNodes,Xn as setFrozen,zn as setIntent,Pn as setNodeDeadline,Vn as setPresence,Bn as setStatus,$n as shiftProfileNodeDeadlines,Qe as terminalPlacementResidueSql,Jn as transitionStatusIntent,lt as unregisterWarmSpare,qn as updateNode,at as updateNodeTelemetry,ft as warmSpareCount,mt as withFreshTerminalGuard};
|
|
@@ -153,8 +153,9 @@ export declare function verifyLeasedCronRun(c: Cron): boolean;
|
|
|
153
153
|
* bounded wait moves the deadline. This is the invariant the dropped
|
|
154
154
|
* `triggers` partial unique index carried, and `idx_crons_deadline`
|
|
155
155
|
* (`crons(anchor_node) WHERE cancel_on_wake = 1`) is still its structural
|
|
156
|
-
* backstop; the displace-then-insert runs inside ONE
|
|
157
|
-
*
|
|
156
|
+
* backstop; the displace-then-insert runs inside ONE transaction that first
|
|
157
|
+
* locks the anchor node row, so two concurrent arms replace one another in
|
|
158
|
+
* sequence. Only the anchor's own cancel-on-wake
|
|
158
159
|
* rows are displaced — a standing declarative cron on the same anchor is
|
|
159
160
|
* untouched. Any displaced in-flight run's process group is killed first (the
|
|
160
161
|
* cancelCron discipline). */
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
var w=Object.defineProperty;var a=(n,r)=>w(n,"name",{value:r,configurable:!0});import{withCanvasWrite as c,openDb as i}from"./db.js";import{capturePidIdentities as l,identitiesMatch as R,killProcessGroup as m}from"./pid.js";import{isProfilePaused as h}from"../profiles/manifest.js";import{stopAppProcess as D}from"../spaces/process.js";import{emitEvent as S}from"../events/emit.js";import{personId as p}from"./person.js";const N=20;function O(n){if(typeof n!="string")return null;try{const r=JSON.parse(n);return Array.isArray(r)?r.filter(e=>typeof e=="string"):null}catch{return null}}a(O,"scopesFrom");function s(n){return{cron_id:n.cron_id,name:n.name,created_by:n.created_by??null,grantee:n.grantee,sub:n.sub??p(),grant_id:n.grant_id??null,scopes:O(n.scopes_json),origin_run_id:n.origin_run_id??null,run_execution_id:n.run_execution_id??null,armed_from_exec:Number(n.armed_from_exec??0)!==0,isolated:Number(n.isolated)!==0,command:n.command,fire_at:n.fire_at,recur:n.recur??null,tz:n.tz??null,expires_at:n.expires_at??null,anchor_node:n.anchor_node??null,cancel_on_wake:Number(n.cancel_on_wake)!==0,cwd:n.cwd,env_json:n.env_json??null,profile:n.profile??null,scope:n.scope,run_timeout_s:Number(n.run_timeout_s),overlap:n.overlap,on_output:n.on_output,sink:n.sink,tier:n.tier,last_output_hash:n.last_output_hash??null,held:Number(n.held)!==0,last_poke_at:n.last_poke_at??null,state:n.state,run_state:n.run_state,run_pid:n.run_pid??null,run_pid_identity:n.run_pid_identity??null,run_started_at:n.run_started_at??null,run_lease_owner:n.run_lease_owner??null,run_out_of_band:Number(n.run_out_of_band)!==0,created:n.created,updated:n.updated}}a(s,"cronFrom");function E(n){try{const r=JSON.parse(n);if(typeof r.node=="string")return{kind:"node",node:r.node};if(typeof r.spawn=="string")return{kind:"spawn",spawn:r.spawn};if(r.human===!0)return{kind:"human"}}catch{}return null}a(E,"parseCronSink");function F(n){const r=E(n);if(r===null)return null;switch(r.kind){case"node":return`node:${r.node}`;case"spawn":return`spawn:${r.spawn}`;case"human":return"human"}}a(F,"cronSinkDisplay");async function
|
|
1
|
+
var w=Object.defineProperty;var a=(n,r)=>w(n,"name",{value:r,configurable:!0});import{withCanvasWrite as c,openDb as i}from"./db.js";import{capturePidIdentities as l,identitiesMatch as R,killProcessGroup as m}from"./pid.js";import{isProfilePaused as h}from"../profiles/manifest.js";import{stopAppProcess as D}from"../spaces/process.js";import{emitEvent as S}from"../events/emit.js";import{personId as p}from"./person.js";const N=20;function O(n){if(typeof n!="string")return null;try{const r=JSON.parse(n);return Array.isArray(r)?r.filter(e=>typeof e=="string"):null}catch{return null}}a(O,"scopesFrom");function s(n){return{cron_id:n.cron_id,name:n.name,created_by:n.created_by??null,grantee:n.grantee,sub:n.sub??p(),grant_id:n.grant_id??null,scopes:O(n.scopes_json),origin_run_id:n.origin_run_id??null,run_execution_id:n.run_execution_id??null,armed_from_exec:Number(n.armed_from_exec??0)!==0,isolated:Number(n.isolated)!==0,command:n.command,fire_at:n.fire_at,recur:n.recur??null,tz:n.tz??null,expires_at:n.expires_at??null,anchor_node:n.anchor_node??null,cancel_on_wake:Number(n.cancel_on_wake)!==0,cwd:n.cwd,env_json:n.env_json??null,profile:n.profile??null,scope:n.scope,run_timeout_s:Number(n.run_timeout_s),overlap:n.overlap,on_output:n.on_output,sink:n.sink,tier:n.tier,last_output_hash:n.last_output_hash??null,held:Number(n.held)!==0,last_poke_at:n.last_poke_at??null,state:n.state,run_state:n.run_state,run_pid:n.run_pid??null,run_pid_identity:n.run_pid_identity??null,run_started_at:n.run_started_at??null,run_lease_owner:n.run_lease_owner??null,run_out_of_band:Number(n.run_out_of_band)!==0,created:n.created,updated:n.updated}}a(s,"cronFrom");function E(n){try{const r=JSON.parse(n);if(typeof r.node=="string")return{kind:"node",node:r.node};if(typeof r.spawn=="string")return{kind:"spawn",spawn:r.spawn};if(r.human===!0)return{kind:"human"}}catch{}return null}a(E,"parseCronSink");function F(n){const r=E(n);if(r===null)return null;switch(r.kind){case"node":return`node:${r.node}`;case"spawn":return`spawn:${r.spawn}`;case"human":return"human"}}a(F,"cronSinkDisplay");async function L(n,r="SIGTERM"){if(!d(n))return!1;if(process.platform!=="linux")return m(n.run_pid,r),!0;try{return await D(n.run_pid,r,n.anchor_node??void 0),!0}catch(e){if(!d(n))return!1;throw e}}a(L,"stopLeasedCronRun");function _(n,r="SIGTERM"){return d(n)?(L(n,r).catch(e=>{S({level:"error",event:"cron.run.stop_failed",error:e,fields:{cron_id:n.cron_id,pid:n.run_pid}})}),!0):!1}a(_,"killLeasedCronRun");function d(n){const r=n.run_pid;if(r==null||n.run_pid_identity==null)return!1;const e=l([r]);if(e===null)return!1;const t=e.get(r);return t===void 0?!1:R(t,n.run_pid_identity)}a(d,"verifyLeasedCronRun");async function U(n){return await c(async r=>{const e=[];if(n.cancel_on_wake&&n.anchor_node!==null){await r.prepare("SELECT 1 FROM nodes WHERE node_id = ? FOR UPDATE").get(n.anchor_node);const t=(await r.prepare("SELECT * FROM crons WHERE anchor_node = ? AND cancel_on_wake = 1").all(n.anchor_node)).map(s);for(const o of t)o.run_state==="running"&&_(o),await r.prepare("DELETE FROM crons WHERE cron_id = ?").run(o.cron_id),e.push(o.cron_id)}return await y(r,n),{cron_id:n.cron_id,replaced:e}})}a(U,"armCron");async function y(n,r){const e=new Date().toISOString();await n.prepare(`INSERT INTO crons (
|
|
2
2
|
cron_id, name, created_by, grantee, sub, grant_id, scopes_json, origin_run_id, isolated, command, fire_at, recur, tz, expires_at,
|
|
3
3
|
anchor_node, cancel_on_wake, cwd, env_json, profile, scope,
|
|
4
4
|
run_timeout_s, overlap, on_output, sink, tier, created, updated, armed_from_exec
|
|
5
|
-
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(r.cron_id,r.name,r.created_by,r.grantee??"app:terminal",r.sub??p(),r.grant_id??null,r.scopes==null?null:JSON.stringify(r.scopes),r.origin_run_id??null,r.isolated?1:0,r.command,r.fire_at,r.recur,r.tz,r.expires_at,r.anchor_node,r.cancel_on_wake?1:0,r.cwd,r.env_json,r.profile,r.scope,r.run_timeout_s,r.overlap,r.on_output,r.sink,r.tier,e,e,r.armed_from_exec?1:0)}a(
|
|
5
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(r.cron_id,r.name,r.created_by,r.grantee??"app:terminal",r.sub??p(),r.grant_id??null,r.scopes==null?null:JSON.stringify(r.scopes),r.origin_run_id??null,r.isolated?1:0,r.command,r.fire_at,r.recur,r.tz,r.expires_at,r.anchor_node,r.cancel_on_wake?1:0,r.cwd,r.env_json,r.profile,r.scope,r.run_timeout_s,r.overlap,r.on_output,r.sink,r.tier,e,e,r.armed_from_exec?1:0)}a(y,"insertCron");async function M(n){const r=await(await i()).prepare("SELECT * FROM crons WHERE cron_id = ?").get(n);return r===void 0?null:s(r)}a(M,"getCron");async function v(n){const r=await i();let e;return"profile"in n?e=await r.prepare("SELECT * FROM crons WHERE scope = 'profile' AND profile = ? ORDER BY fire_at").all(n.profile):"global"in n?e=await r.prepare("SELECT * FROM crons WHERE scope = 'global' ORDER BY fire_at").all():e=await r.prepare("SELECT * FROM crons ORDER BY fire_at").all(),e.map(s)}a(v,"listCrons");async function I(n,r){return await c(async e=>{const t=await e.prepare("SELECT * FROM crons WHERE cron_id = ?").get(n);if(t===void 0)return!1;const o=s(t);return o.run_state==="running"&&r?.preserveRunningProcess!==!0&&_(o),await e.prepare("DELETE FROM crons WHERE cron_id = ?").run(n),!0})}a(I,"cancelCron");function f(n,r){const e=[...new Set(r)];return e.length===0?{sql:"profile = ?",params:[n]}:{sql:`profile = ? OR anchor_node IN (${e.map(()=>"?").join(",")})`,params:[n,...e]}}a(f,"profileCronWhere");async function P(n,r){const e=f(n,r);return(await(await i()).prepareUncached(`SELECT cron_id FROM crons WHERE ${e.sql} ORDER BY created, cron_id`).all(...e.params)).map(({cron_id:t})=>t)}a(P,"cronIdsForProfileDeletion");async function b(n,r){return await c(async e=>{const t=f(n,r),o=(await e.prepareUncached(`SELECT * FROM crons WHERE ${t.sql} ORDER BY created, cron_id`).all(...t.params)).map(s);for(const u of o)u.run_state==="running"&&_(u);return await e.prepareUncached(`DELETE FROM crons WHERE ${t.sql}`).run(...t.params),o.map(({cron_id:u})=>u)})}a(b,"deleteCronsForProfile");async function B(n){return(await(await i()).prepare("SELECT cron_id FROM crons WHERE profile = ? ORDER BY created, cron_id").all(n)).map(({cron_id:r})=>r)}a(B,"cronIdsForProfileDetach");async function Y(n){return await c(async r=>{const e=(await r.prepare("SELECT cron_id FROM crons WHERE profile = ? ORDER BY created, cron_id").all(n)).map(({cron_id:t})=>t);return e.length>0&&await r.prepare("UPDATE crons SET profile = NULL, scope = 'global', updated = ? WHERE profile = ?").run(new Date().toISOString(),n),e})}a(Y,"globalizeCronsForProfile");async function $(n){return(await(await i()).prepare("DELETE FROM crons WHERE cron_id = ?").run(n)).changes>0}a($,"consumeCron");async function j(n,r){return(await(await i()).prepare("UPDATE crons SET state = ?, updated = ? WHERE cron_id = ?").run(r,new Date().toISOString(),n)).changes>0}a(j,"setCronState");async function q(n,r){await(await i()).prepare("UPDATE crons SET last_output_hash = ?, updated = ? WHERE cron_id = ?").run(r,new Date().toISOString(),n)}a(q,"setCronLastOutputHash");async function z(n){const r=await(await i()).prepare(`SELECT anchor_node, cancel_on_wake, sink
|
|
6
6
|
FROM crons
|
|
7
7
|
WHERE (anchor_node = ? AND cancel_on_wake = 1 AND state = 'active')
|
|
8
8
|
OR (
|
|
@@ -33,4 +33,4 @@ var w=Object.defineProperty;var a=(n,r)=>w(n,"name",{value:r,configurable:!0});i
|
|
|
33
33
|
WHERE cron_id = ? AND run_id NOT IN (
|
|
34
34
|
SELECT run_id FROM cron_runs WHERE cron_id = ?
|
|
35
35
|
ORDER BY started DESC, run_id DESC LIMIT ?
|
|
36
|
-
)`).run(r.cron_id,r.cron_id,N),!0)}a(g,"recordCronRunLocked");async function an(n){return await c(async r=>await g(r,n))}a(an,"recordCronRun");export{N as CRON_RUN_RING,K as acquireCronRunLease,J as advanceCron,U as armCron,Q as attachCronRunPid,I as cancelCron,G as cancelCronsOnWake,$ as consumeCron,
|
|
36
|
+
)`).run(r.cron_id,r.cron_id,N),!0)}a(g,"recordCronRunLocked");async function an(n){return await c(async r=>await g(r,n))}a(an,"recordCronRun");export{N as CRON_RUN_RING,K as acquireCronRunLease,J as advanceCron,U as armCron,Q as attachCronRunPid,I as cancelCron,G as cancelCronsOnWake,$ as consumeCron,P as cronIdsForProfileDeletion,B as cronIdsForProfileDetach,F as cronSinkDisplay,b as deleteCronsForProfile,V as dueClockCrons,nn as dueOverlapCrons,rn as expiredIdleCrons,M as getCron,Y as globalizeCronsForProfile,z as hasPendingCronWake,_ as killLeasedCronRun,en as listCronRuns,v as listCrons,E as parseCronSink,Z as pokeHeldCrons,an as recordCronRun,g as recordCronRunLocked,X as releaseCronRunLease,tn as runningCrons,q as setCronLastOutputHash,j as setCronState,L as stopLeasedCronRun,d as verifyLeasedCronRun};
|
|
@@ -11,6 +11,11 @@ export interface DaemonOwnerClaim {
|
|
|
11
11
|
readonly pid_identity: string;
|
|
12
12
|
readonly token: string;
|
|
13
13
|
}
|
|
14
|
+
/** Whether a daemon of this role takes the `daemon_owner` claim. A Mac install has one owner (`role` undefined: the single
|
|
15
|
+
* process running both roles); the cloud's `--role api` and `--role reconcile` processes are several per database by design, so
|
|
16
|
+
* they never claim, never release, and never read the row. The caller (`crtrd.ts`) checks this before
|
|
17
|
+
* `claimDaemonOwnership` / `releaseDaemonOwnership` / `daemonOwnershipClaimed`. */
|
|
18
|
+
export declare function daemonOwnershipApplies(role: 'api' | 'reconcile' | undefined): boolean;
|
|
14
19
|
/** Every terminal, non-retriable way `claimDaemonOwnership` can lose. A loss
|
|
15
20
|
* never deletes or otherwise mutates the incumbent row — only a positively
|
|
16
21
|
* DEAD incumbent is ever CAS-replaced. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var m=Object.defineProperty;var
|
|
1
|
+
var m=Object.defineProperty;var t=(e,n)=>m(e,"name",{value:n,configurable:!0});import{openDb as d}from"./db.js";import{capturePidIdentities as f,recordedPidLiveness as E}from"./pid.js";const s="daemon_owner";function p(e){return JSON.stringify({pid:e.pid,pid_identity:e.pid_identity,token:e.token})}t(p,"serializeClaim");function y(e){let n;try{n=JSON.parse(e)}catch{return null}if(typeof n!="object"||n===null)return null;const{pid:a,pid_identity:i,token:r}=n;return!Number.isInteger(a)||a<=0||typeof i!="string"||i.length===0||typeof r!="string"||r.length===0?null:{pid:a,pid_identity:i,token:r}}t(y,"parseClaim");async function l(){return(await(await d()).prepare("SELECT value FROM canvas_meta WHERE key = ?").get(s))?.value}t(l,"readSnapshot");function v(e){return e===void 0}t(v,"daemonOwnershipApplies");async function N(e){const n=f([process.pid]),a=n?.get(process.pid);if(n===null||a===void 0)return{claimed:!1,reason:"own_identity_indeterminate"};const i={pid:process.pid,pid_identity:a,token:e},r=p(i);for(;;){const u=await l();if(u===void 0){if((await(await d()).prepare("INSERT INTO canvas_meta (key, value) SELECT ?, ? WHERE NOT EXISTS (SELECT 1 FROM canvas_meta WHERE key = ?) ON CONFLICT (key) DO NOTHING").run(s,r,s)).changes===1)return{claimed:!0,claim:i};continue}const o=y(u);if(o===null)return{claimed:!1,reason:"incumbent_malformed"};const c=E(o.pid,o.pid_identity);if(c==="alive"||c==="indeterminate")return{claimed:!1,reason:c==="alive"?"incumbent_alive":"incumbent_indeterminate",incumbentPid:o.pid,verdict:c};if((await(await d()).prepare("UPDATE canvas_meta SET value = ? WHERE key = ? AND value = ?").run(r,s,u)).changes===1)return{claimed:!0,claim:i}}}t(N,"claimDaemonOwnership");async function T(e){return{released:(await(await d()).prepare("DELETE FROM canvas_meta WHERE key = ? AND value = ?").run(s,p(e))).changes===1}}t(T,"releaseDaemonOwnership");async function b(){return await l()!==void 0}t(b,"daemonOwnershipClaimed");export{s as DAEMON_OWNER_META_KEY,N as claimDaemonOwnership,v as daemonOwnershipApplies,b as daemonOwnershipClaimed,T as releaseDaemonOwnership};
|
package/dist/core/canvas/db.d.ts
CHANGED
|
@@ -27,19 +27,17 @@ export interface CanvasDb {
|
|
|
27
27
|
/** True when the calling async context is inside a `withCanvasWrite` body (its own open transaction). */
|
|
28
28
|
readonly inTransaction: boolean;
|
|
29
29
|
}
|
|
30
|
-
|
|
31
|
-
* a comment-led statement, an unrecognised shape — is not a read, so a wrong guess lands on the writer. */
|
|
32
|
-
export declare function isReadStatement(sql: string): boolean;
|
|
30
|
+
export declare function canvasPoolSize(env?: Record<string, string | undefined>): number;
|
|
33
31
|
/** The URL of the database for the current `CRTR_HOME`. In a test it creates the home's database on first use. */
|
|
34
32
|
export declare function canvasDatabaseUrl(): Promise<string>;
|
|
35
33
|
/** Open (or reuse) the canvas db handle for the current `CRTR_HOME`. Keyed by database URL, so tests with distinct
|
|
36
|
-
* homes get independent handles. The first open
|
|
34
|
+
* homes get independent handles. The first open applies the schema. */
|
|
37
35
|
export declare function openDb(): Promise<CanvasDb>;
|
|
38
36
|
/** Close and forget the connection for the current home. Mainly for tests. */
|
|
39
37
|
export declare function closeDb(): Promise<void>;
|
|
40
38
|
/** Close every connection this process holds (daemon shutdown). */
|
|
41
39
|
export declare function closeAllDbs(): Promise<void>;
|
|
42
|
-
/** Run `hook` once the calling context's outermost transaction has committed (and
|
|
40
|
+
/** Run `hook` once the calling context's outermost transaction has committed (and returned its connection to the pool); drop it if
|
|
43
41
|
* the transaction or the savepoint holding it rolls back. Outside a transaction it runs in the next microtask. Use it for anything
|
|
44
42
|
* that tells another context about a write, so that context never reads uncommitted rows or hears of a rolled-back one. */
|
|
45
43
|
export declare function afterCommit(hook: () => void): void;
|
|
@@ -49,10 +47,13 @@ export interface CanvasWriteOptions {
|
|
|
49
47
|
/** Always undo the body's writes, even when it returns (a dry run). Nested, it runs in a SAVEPOINT rolled back at the end. */
|
|
50
48
|
rollback?: boolean;
|
|
51
49
|
}
|
|
52
|
-
/** Run `body` in one transaction, the only transaction entry point for the canvas database.
|
|
53
|
-
* A call from inside the body's own async context joins it and only the outermost call commits
|
|
54
|
-
*
|
|
55
|
-
*
|
|
50
|
+
/** Run `body` in one transaction on its own pooled connection, the only transaction entry point for the canvas database.
|
|
51
|
+
* A call from inside the body's own async context joins it and only the outermost call commits. A call from any other
|
|
52
|
+
* context opens a separate transaction that runs concurrently (READ COMMITTED): a read-modify-write that must not lose an
|
|
53
|
+
* update takes its row with `SELECT … FOR UPDATE` or writes conditionally. A throwing body rolls back (with `savepoint`, a
|
|
54
|
+
* nested body rolls back only its own writes). With `rollback` the body's writes are always undone.
|
|
55
|
+
*
|
|
56
|
+
* The body holds its connection until it returns: keep network, subprocess and filesystem waits out of it.
|
|
56
57
|
*
|
|
57
58
|
* Postgres aborts the whole transaction when a statement fails, so a body that catches a failed statement and
|
|
58
59
|
* carries on must run that statement inside a nested `withCanvasWrite(…, { savepoint: true })`. */
|