@north-light/cli 0.3.560 → 0.3.562
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/client.d.ts +27 -4
- package/dist/api/client.js +3 -3
- package/dist/api/contract.d.ts +1 -1
- package/dist/api/contract.js +1 -1
- package/dist/api/dto/bash-jobs.d.ts +5 -1
- package/dist/api/dto/broker-ops.d.ts +25 -1
- package/dist/api/dto/charges.d.ts +9 -2
- package/dist/api/dto/delivery.d.ts +26 -2
- package/dist/api/dto/execution-start.d.ts +57 -0
- package/dist/api/dto/execution-start.js +0 -0
- package/dist/api/dto/modelauth.d.ts +5 -0
- package/dist/api/dto/node-records.d.ts +16 -0
- package/dist/api/dto/objects.d.ts +1 -1
- package/dist/api/dto/reports.d.ts +0 -3
- package/dist/api/dto/run-events.d.ts +7 -1
- package/dist/api/dto/settings.d.ts +55 -0
- package/dist/api/dto/settings.js +0 -0
- package/dist/api/index.d.ts +2 -0
- package/dist/api/index.js +1 -1
- package/dist/api/routes.d.ts +11 -0
- package/dist/api/routes.js +1 -1
- package/dist/builtin-memory/crouter-sdk/release-notes.md +4 -0
- package/dist/cli.js +7 -7
- package/dist/clients/attach/chrome/bash-jobs.d.ts +11 -1
- package/dist/clients/attach/chrome/bash-jobs.js +1 -1
- package/dist/clients/attach/chrome/canvas-panels.d.ts +1 -1
- package/dist/clients/attach/chrome/roster.js +6 -4
- package/dist/clients/attach/overlays/auth.js +2 -2
- package/dist/clients/attach/render/chat-view.js +1 -1
- package/dist/clients/attach/viewer.js +550 -567
- package/dist/commands/canvas-config.js +2 -2
- package/dist/commands/canvas-use.js +1 -1
- package/dist/commands/human.js +2 -2
- package/dist/commands/node/bash.js +3 -3
- package/dist/commands/node/create.js +2 -2
- package/dist/commands/person-settings.d.ts +1 -0
- package/dist/commands/person-settings.js +1 -0
- package/dist/commands/pkg/market-manage.d.ts +2 -2
- package/dist/commands/pkg/market-manage.js +1 -1
- package/dist/commands/pkg/plugin-manage.js +13 -13
- package/dist/commands/pkg/shared.js +1 -1
- package/dist/commands/profile/default.js +1 -1
- package/dist/commands/push.js +2 -3
- package/dist/commands/sys/config.js +1 -1
- package/dist/commands/sys/connect.js +1 -1
- package/dist/commands/sys/context/sysprompt.js +2 -2
- package/dist/commands/sys/doctor.js +1 -1
- package/dist/commands/sys/panels/broker-limits-panel.js +1 -1
- package/dist/commands/sys/panels/keybindings-panel.js +1 -1
- package/dist/commands/sys/panels/models-panel.d.ts +8 -2
- package/dist/commands/sys/panels/models-panel.js +1 -1
- package/dist/commands/sys/panels/prefs-panel.d.ts +1 -0
- package/dist/commands/sys/panels/prefs-panel.js +1 -1
- package/dist/commands/sys/panels/profiles-panel.js +1 -1
- package/dist/commands/sys/panels/provider-panel.d.ts +4 -0
- package/dist/commands/sys/panels/provider-panel.js +1 -1
- package/dist/commands/sys/provider-login.js +5 -5
- package/dist/commands/sys/setup-core.js +3 -3
- package/dist/commands/sys/setup-settings-runner.js +1 -1
- package/dist/commands/sys/spend.js +3 -3
- package/dist/commands/sys/update.js +1 -1
- package/dist/core/auth-file.d.ts +11 -19
- package/dist/core/auth-file.js +1 -2
- package/dist/core/auto-update.d.ts +1 -1
- package/dist/core/auto-update.js +4 -4
- package/dist/core/bash-jobs.d.ts +29 -71
- package/dist/core/bash-jobs.js +9 -10
- package/dist/core/blobs/directory.d.ts +3 -0
- package/dist/core/blobs/directory.js +1 -0
- package/dist/core/blobs/fault.d.ts +3 -0
- package/dist/core/blobs/fault.js +1 -0
- package/dist/core/blobs/index.d.ts +21 -0
- package/dist/core/blobs/index.js +1 -0
- package/dist/core/blobs/r2.d.ts +9 -0
- package/dist/core/blobs/r2.js +4 -0
- package/dist/core/bootstrap.d.ts +1 -1
- package/dist/core/bootstrap.js +2 -2
- package/dist/core/canvas/canvas.d.ts +9 -7
- package/dist/core/canvas/canvas.js +8 -8
- package/dist/core/canvas/crons.d.ts +3 -2
- package/dist/core/canvas/crons.js +3 -3
- package/dist/core/canvas/daemon-owner.d.ts +5 -0
- package/dist/core/canvas/daemon-owner.js +1 -1
- package/dist/core/canvas/db.d.ts +10 -9
- package/dist/core/canvas/db.js +4 -4
- package/dist/core/canvas/executions.d.ts +100 -4
- package/dist/core/canvas/executions.js +1 -1
- package/dist/core/canvas/export-sqlite.js +1 -1
- package/dist/core/canvas/focuses.d.ts +4 -0
- package/dist/core/canvas/focuses.js +1 -1
- package/dist/core/canvas/history.js +9 -9
- package/dist/core/canvas/managed-worktree-sweep-candidates.d.ts +2 -1
- package/dist/core/canvas/managed-worktree-sweep-candidates.js +3 -2
- package/dist/core/canvas/node-tokens.d.ts +1 -4
- package/dist/core/canvas/node-tokens.js +3 -3
- package/dist/core/canvas/paths.d.ts +0 -1
- package/dist/core/canvas/paths.js +1 -1
- package/dist/core/canvas/person-state.d.ts +26 -0
- package/dist/core/canvas/person-state.js +1 -0
- package/dist/core/canvas/person.d.ts +3 -10
- package/dist/core/canvas/person.js +7 -7
- package/dist/core/canvas/reconciler-leases.d.ts +12 -0
- package/dist/core/canvas/reconciler-leases.js +8 -0
- package/dist/core/canvas/recovery.d.ts +4 -0
- package/dist/core/canvas/recovery.js +1 -1
- package/dist/core/canvas/schema-pg/003-fleet-removals.sql +1 -1
- package/dist/core/canvas/schema-pg/005-fleet-blobs.sql +13 -0
- package/dist/core/canvas/schema-pg/006-job-rows.sql +20 -0
- package/dist/core/canvas/schema-pg/007-ledger-check.sql +117 -0
- package/dist/core/canvas/schema-version.d.ts +1 -1
- package/dist/core/canvas/schema-version.js +1 -1
- package/dist/core/canvas/sessions.d.ts +8 -11
- package/dist/core/canvas/sessions.js +1 -4
- package/dist/core/canvas/tree.d.ts +4 -2
- package/dist/core/canvas/tree.js +6 -6
- package/dist/core/canvas/types.d.ts +7 -0
- package/dist/core/command-hooks/transport/exec-lifecycle.js +1 -1
- package/dist/core/command-plugins/bundle.d.ts +1 -1
- package/dist/core/command-plugins/bundle.js +1 -1
- package/dist/core/command-plugins/compose.d.ts +1 -1
- package/dist/core/command-plugins/discovery.d.ts +0 -1
- package/dist/core/command-plugins/discovery.js +1 -1
- package/dist/core/command-plugins/help-addenda.js +1 -1
- package/dist/core/command-plugins/presence.d.ts +2 -0
- package/dist/core/command-plugins/presence.js +1 -1
- package/dist/core/config.d.ts +16 -15
- package/dist/core/config.js +1 -1
- package/dist/core/conversation-store/client-worker.js +1 -1
- package/dist/core/conversation-store/client.js +2 -2
- package/dist/core/conversation-store/index.d.ts +9 -11
- package/dist/core/conversation-store/index.js +1 -1
- package/dist/core/conversation-store/patch.js +1 -1
- package/dist/core/conversation-store/row-store.d.ts +14 -0
- package/dist/core/conversation-store/row-store.js +13 -0
- package/dist/core/directory/join.js +1 -1
- package/dist/core/env-name.d.ts +1 -0
- package/dist/core/env-name.js +1 -1
- package/dist/core/environment-recipe.d.ts +15 -0
- package/dist/core/environment-recipe.js +1 -0
- package/dist/core/environments.js +1 -1
- package/dist/core/events/emit.js +2 -2
- package/dist/core/events/run-event-chunks.d.ts +25 -0
- package/dist/core/events/run-event-chunks.js +5 -0
- package/dist/core/feed/messages.js +5 -5
- package/dist/core/grants/mirror.d.ts +15 -0
- package/dist/core/grants/mirror.js +15 -3
- package/dist/core/grants/on-sync.d.ts +9 -5
- package/dist/core/grants/on-sync.js +1 -1
- package/dist/core/grants/remove.d.ts +1 -6
- package/dist/core/grants/remove.js +1 -1
- package/dist/core/grants/sync.js +1 -1
- package/dist/core/grants/watch.d.ts +15 -9
- package/dist/core/grants/watch.js +1 -1
- package/dist/core/graph/custom.js +8 -8
- package/dist/core/graph/jobs.d.ts +83 -5
- package/dist/core/graph/jobs.js +11 -2
- package/dist/core/graph/kinds/job.js +2 -2
- package/dist/core/graph/names.js +7 -7
- package/dist/core/graph/objects.d.ts +5 -1
- package/dist/core/graph/objects.js +11 -11
- package/dist/core/graph/reader.d.ts +3 -0
- package/dist/core/graph/reader.js +3 -3
- package/dist/core/graph/repo-sync/identity.d.ts +3 -1
- package/dist/core/graph/repo-sync/identity.js +1 -1
- package/dist/core/graph/repo-sync/repos.d.ts +1 -1
- package/dist/core/graph/repo-sync/repos.js +2 -2
- package/dist/core/graph/repo-sync/sync.js +2 -2
- package/dist/core/installed-plugins.js +1 -1
- package/dist/core/keybindings/persistence.d.ts +1 -1
- package/dist/core/keybindings/persistence.js +1 -1
- package/dist/core/layout-migrate/loose-keys.d.ts +1 -1
- package/dist/core/layout-migrate/loose-keys.js +1 -1
- package/dist/core/ledger/account.d.ts +12 -0
- package/dist/core/ledger/account.js +2 -0
- package/dist/core/ledger/charges.d.ts +2 -2
- package/dist/core/ledger/charges.js +1 -1
- package/dist/core/ledger/check.d.ts +5 -1
- package/dist/core/ledger/check.js +1 -7
- package/dist/core/ledger/chunks.d.ts +8 -0
- package/dist/core/ledger/chunks.js +2 -0
- package/dist/core/ledger/index.d.ts +2 -1
- package/dist/core/ledger/index.js +1 -1
- package/dist/core/ledger/infra-allowance.d.ts +9 -0
- package/dist/core/ledger/infra-allowance.js +1 -0
- package/dist/core/ledger/limits.js +3 -3
- package/dist/core/ledger/payer.d.ts +1 -1
- package/dist/core/ledger/payer.js +1 -1
- package/dist/core/ledger/read.d.ts +14 -4
- package/dist/core/ledger/read.js +2 -3
- package/dist/core/ledger/totals.d.ts +5 -16
- package/dist/core/ledger/totals.js +4 -4
- package/dist/core/ledger/types.d.ts +12 -3
- package/dist/core/llm/run.js +2 -2
- package/dist/core/managed-providers.d.ts +72 -0
- package/dist/core/managed-providers.js +1 -0
- package/dist/core/model-auth/api-credential-store.d.ts +10 -0
- package/dist/core/model-auth/api-credential-store.js +1 -0
- package/dist/core/model-auth/daemon-login.d.ts +1 -1
- package/dist/core/model-auth/daemon-login.js +1 -1
- package/dist/core/model-auth/flows.d.ts +5 -4
- package/dist/core/model-auth/flows.js +1 -1
- package/dist/core/model-auth/handoff-jti.d.ts +3 -4
- package/dist/core/model-auth/handoff-jti.js +1 -1
- package/dist/core/model-auth/readiness.js +1 -1
- package/dist/core/model-config.d.ts +1 -1
- package/dist/core/model-config.js +1 -1
- package/dist/core/model-routes-pool.d.ts +14 -0
- package/dist/core/model-routes-pool.js +1 -0
- package/dist/core/model-routes.d.ts +11 -16
- package/dist/core/model-routes.js +1 -1
- package/dist/core/peer/ingest.d.ts +2 -0
- package/dist/core/peer/ingest.js +1 -1
- package/dist/core/peer/stubs.d.ts +8 -0
- package/dist/core/peer/stubs.js +1 -1
- package/dist/core/permissions/evaluator.d.ts +7 -2
- package/dist/core/permissions/evaluator.js +2 -2
- package/dist/core/plugin-env.js +1 -1
- package/dist/core/pool-credential-store.d.ts +2 -5
- package/dist/core/pool-credential-store.js +1 -1
- package/dist/core/profiles/app-env-store.d.ts +5 -5
- package/dist/core/profiles/app-env-store.js +1 -2
- package/dist/core/profiles/default-binding.d.ts +5 -5
- package/dist/core/profiles/default-binding.js +1 -1
- package/dist/core/profiles/env-store.d.ts +10 -21
- package/dist/core/profiles/env-store.js +1 -2
- package/dist/core/profiles/manifest.d.ts +14 -18
- package/dist/core/profiles/manifest.js +1 -1
- package/dist/core/profiles/relocate.js +1 -1
- package/dist/core/profiles/select.js +21 -21
- package/dist/core/provider-credential.d.ts +1 -1
- package/dist/core/provider-credential.js +1 -1
- package/dist/core/provider-management.d.ts +3 -4
- package/dist/core/provider-management.js +1 -1
- package/dist/core/providers/bundles.js +2 -2
- package/dist/core/providers/call.d.ts +3 -34
- package/dist/core/providers/description.d.ts +34 -0
- package/dist/core/providers/description.js +0 -0
- package/dist/core/providers/token-cache.d.ts +14 -14
- package/dist/core/providers/token-cache.js +1 -1
- package/dist/core/review/companion.js +1 -1
- package/dist/core/runs/activity.d.ts +1 -1
- package/dist/core/runs/activity.js +1 -1
- package/dist/core/runs/events.d.ts +7 -5
- package/dist/core/runs/events.js +2 -6
- package/dist/core/runs/operations.d.ts +1 -1
- package/dist/core/runs/operations.js +6 -6
- package/dist/core/runtime/bearings.js +1 -1
- package/dist/core/runtime/broker/attachments-fetch.d.ts +5 -0
- package/dist/core/runtime/broker/attachments-fetch.js +1 -0
- package/dist/core/runtime/broker/bash-job-launch.d.ts +4 -2
- package/dist/core/runtime/broker/bash-job-launch.js +1 -1
- package/dist/core/runtime/broker/boot-state.d.ts +9 -0
- package/dist/core/runtime/broker/boot-state.js +1 -0
- package/dist/core/runtime/broker/cli-relay.d.ts +2 -1
- package/dist/core/runtime/broker/cli-relay.js +1 -1
- package/dist/core/runtime/broker/client-registry.d.ts +3 -3
- package/dist/core/runtime/broker/daemon-ops.d.ts +10 -1
- package/dist/core/runtime/broker/daemon-ops.js +1 -1
- package/dist/core/runtime/broker/fault-retry.d.ts +2 -0
- package/dist/core/runtime/broker/fault-retry.js +1 -1
- package/dist/core/runtime/broker/frame-engine-control.js +1 -1
- package/dist/core/runtime/broker/held-deferred-inbox.d.ts +3 -0
- package/dist/core/runtime/broker/held-deferred-inbox.js +1 -1
- package/dist/core/runtime/broker/job-reporter.d.ts +18 -0
- package/dist/core/runtime/broker/job-reporter.js +2 -0
- package/dist/core/runtime/broker/model-adapter.d.ts +3 -0
- package/dist/core/runtime/broker/model-adapter.js +3 -2
- package/dist/core/runtime/broker/signal-stream.js +1 -1
- package/dist/core/runtime/broker/spilled-body.d.ts +5 -0
- package/dist/core/runtime/broker/spilled-body.js +1 -0
- package/dist/core/runtime/broker/summaries-post.d.ts +5 -0
- package/dist/core/runtime/broker/summaries-post.js +1 -0
- package/dist/core/runtime/broker/tool-groups.d.ts +3 -0
- package/dist/core/runtime/broker/tool-groups.js +1 -1
- package/dist/core/runtime/broker/turn-replies.d.ts +1 -0
- package/dist/core/runtime/broker/turn-replies.js +1 -1
- package/dist/core/runtime/broker-persona-guidance.js +2 -2
- package/dist/core/runtime/broker.js +1 -1
- package/dist/core/runtime/deliver-live.js +1 -1
- package/dist/core/runtime/first-boot-rows.d.ts +8 -0
- package/dist/core/runtime/first-boot-rows.js +2 -0
- package/dist/core/runtime/fleet.d.ts +13 -12
- package/dist/core/runtime/front-door-login.js +1 -1
- package/dist/core/runtime/front-door.js +6 -6
- package/dist/core/runtime/headless-pi.js +1 -1
- package/dist/core/runtime/host.d.ts +14 -3
- package/dist/core/runtime/host.js +3 -3
- package/dist/core/runtime/invocation.d.ts +6 -0
- package/dist/core/runtime/kickoff.d.ts +2 -14
- package/dist/core/runtime/kickoff.js +17 -19
- package/dist/core/runtime/launch-config-worker.js +1 -1
- package/dist/core/runtime/launch.js +2 -2
- package/dist/core/runtime/model-registry.js +1 -1
- package/dist/core/runtime/node-read.d.ts +4 -6
- package/dist/core/runtime/node-read.js +3 -3
- package/dist/core/runtime/nodes.js +1 -1
- package/dist/core/runtime/outcome-document.d.ts +0 -1
- package/dist/core/runtime/outcome-document.js +1 -1
- package/dist/core/runtime/output-result.d.ts +15 -0
- package/dist/core/runtime/output-result.js +5 -0
- package/dist/core/runtime/placement.d.ts +17 -1
- package/dist/core/runtime/placement.js +1 -1
- package/dist/core/runtime/provider-credential-gate.d.ts +6 -2
- package/dist/core/runtime/provider-credential-gate.js +2 -2
- package/dist/core/runtime/recovery-hold.d.ts +21 -2
- package/dist/core/runtime/recovery-hold.js +2 -1
- package/dist/core/runtime/recycle.js +1 -1
- package/dist/core/runtime/reset.js +1 -1
- package/dist/core/runtime/revive.d.ts +2 -2
- package/dist/core/runtime/revive.js +2 -2
- package/dist/core/runtime/runner/blaxel/client.d.ts +81 -0
- package/dist/core/runtime/runner/blaxel/client.js +1 -0
- package/dist/core/runtime/runner/blaxel/image-build.d.ts +74 -0
- package/dist/core/runtime/runner/blaxel/image-build.js +5 -0
- package/dist/core/runtime/runner/blaxel/runner.d.ts +41 -0
- package/dist/core/runtime/runner/blaxel/runner.js +3 -0
- package/dist/core/runtime/runner/index.d.ts +8 -0
- package/dist/core/runtime/runner/index.js +1 -0
- package/dist/core/runtime/runner/process.d.ts +11 -0
- package/dist/core/runtime/runner/process.js +1 -0
- package/dist/core/runtime/runner/types.d.ts +95 -0
- package/dist/core/runtime/runner/types.js +0 -0
- package/dist/core/runtime/situational-context.d.ts +3 -6
- package/dist/core/runtime/situational-context.js +2 -2
- package/dist/core/runtime/situational-live.js +1 -1
- package/dist/core/runtime/spawn-env-rows.d.ts +5 -0
- package/dist/core/runtime/spawn-env-rows.js +1 -0
- package/dist/core/runtime/spawn-env.d.ts +4 -18
- package/dist/core/runtime/spawn-env.js +1 -1
- package/dist/core/runtime/spawn.js +2 -2
- package/dist/core/runtime/stop-guard.d.ts +1 -1
- package/dist/core/runtime/stop-guard.js +2 -8
- package/dist/core/runtime/structured-output.d.ts +0 -67
- package/dist/core/runtime/structured-output.js +3 -8
- package/dist/core/runtime/tmux-driver.d.ts +8 -0
- package/dist/core/runtime/tmux-driver.js +6 -6
- package/dist/core/runtime/view-socket.d.ts +20 -0
- package/dist/core/runtime/view-socket.js +3 -1
- package/dist/core/runtime/warm-pool.d.ts +13 -1
- package/dist/core/runtime/warm-pool.js +1 -1
- package/dist/core/scoped-state/legacy-profiles.d.ts +11 -0
- package/dist/core/scoped-state/legacy-profiles.js +1 -0
- package/dist/core/scoped-state/materialized-plugins.d.ts +18 -0
- package/dist/core/scoped-state/materialized-plugins.js +1 -0
- package/dist/core/scoped-state/migrate.d.ts +8 -1
- package/dist/core/scoped-state/migrate.js +3 -3
- package/dist/core/scoped-state/person-rows.d.ts +10 -0
- package/dist/core/scoped-state/person-rows.js +6 -0
- package/dist/core/scoped-state/person-store.d.ts +72 -0
- package/dist/core/scoped-state/person-store.js +1 -0
- package/dist/core/secrets/blaxel-launch.d.ts +24 -0
- package/dist/core/secrets/blaxel-launch.js +4 -0
- package/dist/core/secrets/blaxel-register.d.ts +2 -0
- package/dist/core/secrets/blaxel-register.js +1 -0
- package/dist/core/secrets/env-rows.d.ts +17 -0
- package/dist/core/secrets/env-rows.js +4 -0
- package/dist/core/secrets/environment-owner.d.ts +8 -0
- package/dist/core/secrets/environment-owner.js +1 -0
- package/dist/core/secrets/environment-secrets.d.ts +14 -0
- package/dist/core/secrets/environment-secrets.js +1 -0
- package/dist/core/secrets/index.d.ts +2 -0
- package/dist/core/secrets/index.js +1 -0
- package/dist/core/secrets/key.d.ts +3 -0
- package/dist/core/secrets/key.js +2 -0
- package/dist/core/secrets/seal.d.ts +18 -0
- package/dist/core/secrets/seal.js +1 -0
- package/dist/core/spaces/mounts.d.ts +1 -1
- package/dist/core/spaces/mounts.js +1 -1
- package/dist/core/spaces/process.d.ts +1 -1
- package/dist/core/spaces/stop.d.ts +7 -5
- package/dist/core/spaces/stop.js +2 -2
- package/dist/core/spaces/users.d.ts +2 -1
- package/dist/core/spaces/users.js +1 -1
- package/dist/core/storage/attachments.d.ts +11 -8
- package/dist/core/storage/attachments.js +1 -1
- package/dist/core/storage/tables.d.ts +4 -0
- package/dist/core/storage/tables.js +3 -3
- package/dist/core/subscription-state.d.ts +34 -72
- package/dist/core/subscription-state.js +1 -4
- package/dist/core/substrate/delivery/plan.js +1 -1
- package/dist/core/user-settings.js +1 -1
- package/dist/daemon/api/app-listener.js +10 -10
- package/dist/daemon/api/auth/person-bearer.d.ts +14 -0
- package/dist/daemon/api/auth/person-bearer.js +1 -0
- package/dist/daemon/api/bridge.js +4 -4
- package/dist/daemon/api/document-listener.js +3 -3
- package/dist/daemon/api/environment-of.d.ts +18 -0
- package/dist/daemon/api/environment-of.js +5 -0
- package/dist/daemon/api/handlers/analytics.js +1 -1
- package/dist/daemon/api/handlers/app-profiles.d.ts +2 -2
- package/dist/daemon/api/handlers/app-profiles.js +1 -1
- package/dist/daemon/api/handlers/bash-jobs.js +1 -1
- package/dist/daemon/api/handlers/bash.js +1 -1
- package/dist/daemon/api/handlers/broker-ops.d.ts +3 -0
- package/dist/daemon/api/handlers/broker-ops.js +1 -1
- package/dist/daemon/api/handlers/broker-recovery.js +1 -1
- package/dist/daemon/api/handlers/broker-signals.d.ts +0 -3
- package/dist/daemon/api/handlers/broker-signals.js +2 -2
- package/dist/daemon/api/handlers/canvas.js +4 -4
- package/dist/daemon/api/handlers/charges.d.ts +1 -1
- package/dist/daemon/api/handlers/charges.js +1 -1
- package/dist/daemon/api/handlers/conversations.d.ts +2 -0
- package/dist/daemon/api/handlers/conversations.js +3 -0
- package/dist/daemon/api/handlers/crons.js +1 -1
- package/dist/daemon/api/handlers/daemon.js +1 -1
- package/dist/daemon/api/handlers/delivery.d.ts +1 -1
- package/dist/daemon/api/handlers/delivery.js +1 -1
- package/dist/daemon/api/handlers/docs.js +1 -1
- package/dist/daemon/api/handlers/exec.js +1 -1
- package/dist/daemon/api/handlers/execution-start.d.ts +2 -0
- package/dist/daemon/api/handlers/execution-start.js +2 -0
- package/dist/daemon/api/handlers/files.js +1 -1
- package/dist/daemon/api/handlers/git-credential.d.ts +11 -0
- package/dist/daemon/api/handlers/git-credential.js +1 -0
- package/dist/daemon/api/handlers/hook-exec.d.ts +1 -1
- package/dist/daemon/api/handlers/hook-exec.js +1 -1
- package/dist/daemon/api/handlers/human-requests.js +1 -1
- package/dist/daemon/api/handlers/inbox.js +1 -1
- package/dist/daemon/api/handlers/messages.js +1 -1
- package/dist/daemon/api/handlers/model-config.js +1 -1
- package/dist/daemon/api/handlers/modelauth.d.ts +1 -1
- package/dist/daemon/api/handlers/modelauth.js +1 -1
- package/dist/daemon/api/handlers/node-events.d.ts +6 -0
- package/dist/daemon/api/handlers/node-events.js +3 -3
- package/dist/daemon/api/handlers/node-outcomes.js +1 -1
- package/dist/daemon/api/handlers/node-records.js +3 -2
- package/dist/daemon/api/handlers/nodes.js +1 -1
- package/dist/daemon/api/handlers/objects.js +3 -3
- package/dist/daemon/api/handlers/profiles.js +1 -1
- package/dist/daemon/api/handlers/providers.js +1 -1
- package/dist/daemon/api/handlers/reports.js +9 -13
- package/dist/daemon/api/handlers/reviews.js +1 -1
- package/dist/daemon/api/handlers/runs.js +1 -1
- package/dist/daemon/api/handlers/settings.d.ts +2 -0
- package/dist/daemon/api/handlers/settings.js +1 -0
- package/dist/daemon/api/handlers/structured-requests.js +1 -1
- package/dist/daemon/api/handlers/vendor-status.d.ts +1 -1
- package/dist/daemon/api/handlers/vendor-status.js +1 -1
- package/dist/daemon/api/handlers/worktree.js +1 -1
- package/dist/daemon/api/map.d.ts +2 -2
- package/dist/daemon/api/map.js +2 -2
- package/dist/daemon/api/operations.js +1 -1
- package/dist/daemon/api/reader.d.ts +8 -1
- package/dist/daemon/api/reader.js +1 -1
- package/dist/daemon/api/router.d.ts +4 -2
- package/dist/daemon/api/router.js +1 -1
- package/dist/daemon/api/server.d.ts +15 -3
- package/dist/daemon/api/server.js +1 -1
- package/dist/daemon/api/vendor-signin.d.ts +2 -1
- package/dist/daemon/api/vendor-signin.js +20 -20
- package/dist/daemon/api/viewer-presence.d.ts +20 -6
- package/dist/daemon/api/viewer-presence.js +2 -1
- package/dist/daemon/broker-signals/bus.d.ts +48 -11
- package/dist/daemon/broker-signals/bus.js +1 -1
- package/dist/daemon/cron/armed-context.js +1 -1
- package/dist/daemon/cron/lease-recovery.js +1 -1
- package/dist/daemon/cron/live-runs.d.ts +6 -0
- package/dist/daemon/cron/live-runs.js +1 -1
- package/dist/daemon/cron/run-socket.js +1 -1
- package/dist/daemon/cron-run.js +2 -2
- package/dist/daemon/crtrd-cli.js +1 -1
- package/dist/daemon/crtrd.d.ts +10 -0
- package/dist/daemon/crtrd.js +18 -17
- package/dist/daemon/delivery/run-delivery.d.ts +1 -1
- package/dist/daemon/delivery/run-delivery.js +1 -1
- package/dist/daemon/due-sources.d.ts +1 -1
- package/dist/daemon/due-sources.js +1 -1
- package/dist/daemon/due.js +7 -6
- package/dist/daemon/fleet.d.ts +6 -6
- package/dist/daemon/fleet.js +9 -9
- package/dist/daemon/park-activity.d.ts +2 -1
- package/dist/daemon/park-activity.js +1 -1
- package/dist/daemon/park-pending.d.ts +20 -13
- package/dist/daemon/park-pending.js +3 -1
- package/dist/daemon/profile-delete.js +1 -1
- package/dist/daemon/reconcilers/bash-deadline.d.ts +15 -10
- package/dist/daemon/reconcilers/bash-deadline.js +1 -3
- package/dist/daemon/reconcilers/broker-supervision.d.ts +13 -3
- package/dist/daemon/reconcilers/broker-supervision.js +4 -4
- package/dist/daemon/reconcilers/cron-lane.d.ts +0 -1
- package/dist/daemon/reconcilers/cron-lane.js +1 -1
- package/dist/daemon/reconcilers/fault-retry-backstop.d.ts +2 -9
- package/dist/daemon/reconcilers/fault-retry-backstop.js +1 -1
- package/dist/daemon/reconcilers/grant-effects.d.ts +8 -0
- package/dist/daemon/reconcilers/grant-effects.js +1 -0
- package/dist/daemon/reconcilers/grove-instance-sweep.d.ts +1 -3
- package/dist/daemon/reconcilers/grove-instance-sweep.js +1 -1
- package/dist/daemon/reconcilers/ledger-r2.d.ts +27 -0
- package/dist/daemon/reconcilers/ledger-r2.js +7 -0
- package/dist/daemon/reconcilers/ledger-sandbox.d.ts +55 -0
- package/dist/daemon/reconcilers/ledger-sandbox.js +9 -0
- package/dist/daemon/reconcilers/ledger-storage.d.ts +22 -0
- package/dist/daemon/reconcilers/ledger-storage.js +5 -0
- package/dist/daemon/reconcilers/live-obligation.d.ts +3 -2
- package/dist/daemon/reconcilers/live-obligation.js +1 -1
- package/dist/daemon/reconcilers/managed-worktree-sweep.d.ts +0 -5
- package/dist/daemon/reconcilers/managed-worktree-sweep.js +1 -1
- package/dist/daemon/reconcilers/node-deadline.d.ts +2 -1
- package/dist/daemon/reconcilers/node-deadline.js +1 -1
- package/dist/daemon/reconcilers/node-lifecycle/freeze-lane.d.ts +1 -2
- package/dist/daemon/reconcilers/node-lifecycle/freeze-lane.js +1 -1
- package/dist/daemon/reconcilers/node-lifecycle/remote-wake.d.ts +31 -0
- package/dist/daemon/reconcilers/node-lifecycle/remote-wake.js +1 -0
- package/dist/daemon/reconcilers/node-lifecycle/requested-stops.d.ts +5 -0
- package/dist/daemon/reconcilers/node-lifecycle/requested-stops.js +2 -0
- package/dist/daemon/reconcilers/node-lifecycle/tick.js +1 -1
- package/dist/daemon/reconcilers/pending-review-submit.js +1 -1
- package/dist/daemon/reconcilers/recipe-image.d.ts +49 -0
- package/dist/daemon/reconcilers/recipe-image.js +7 -0
- package/dist/daemon/reconcilers/row-claim.d.ts +19 -0
- package/dist/daemon/reconcilers/row-claim.js +2 -0
- package/dist/daemon/reconcilers/storage-due-work.d.ts +18 -3
- package/dist/daemon/reconcilers/storage-due-work.js +2 -1
- package/dist/daemon/reconcilers/storage-maintenance.d.ts +5 -13
- package/dist/daemon/reconcilers/storage-maintenance.js +1 -1
- package/dist/daemon/reconcilers/structured-request-lane.js +1 -1
- package/dist/daemon/reconcilers/throttled-lane.d.ts +11 -0
- package/dist/daemon/reconcilers/throttled-lane.js +1 -0
- package/dist/daemon/review/finish.js +1 -1
- package/dist/daemon/run-notices.d.ts +3 -0
- package/dist/daemon/run-notices.js +1 -1
- package/dist/daemon/runs/append-section.d.ts +4 -1
- package/dist/daemon/runs/append-section.js +2 -2
- package/dist/daemon/runs/observer.d.ts +3 -2
- package/dist/daemon/runs/observer.js +3 -2
- package/dist/daemon/runs/view-transport.d.ts +19 -0
- package/dist/daemon/runs/view-transport.js +1 -0
- package/dist/daemon/structured-requests/boot.d.ts +2 -1
- package/dist/daemon/structured-requests/boot.js +1 -1
- package/dist/daemon/structured-requests/effects.d.ts +4 -3
- package/dist/daemon/structured-requests/effects.js +1 -1
- package/dist/daemon/structured-requests/notifier.d.ts +2 -0
- package/dist/daemon/structured-requests/notifier.js +1 -1
- package/dist/daemon/structured-requests/sidecar.d.ts +4 -3
- package/dist/daemon/structured-requests/sidecar.js +1 -1
- package/dist/launcher/validate.js +1 -1
- package/dist/migrations/004-canvas-documents/index.js +2 -2
- package/dist/pi-extensions/broker-local.d.ts +3 -3
- package/dist/pi-extensions/broker-local.js +1 -2
- package/dist/pi-extensions/canvas-bash-valve.js +6 -6
- package/dist/pi-extensions/canvas-context-intro.js +2 -2
- package/dist/pi-extensions/canvas-elapsed.js +2 -2
- package/dist/pi-extensions/canvas-goal-capture.js +1 -1
- package/dist/pi-extensions/canvas-inbox-watcher.js +2 -2
- package/dist/pi-extensions/canvas-review-boundary.d.ts +11 -1
- package/dist/pi-extensions/canvas-review-boundary.js +3 -3
- package/dist/pi-extensions/canvas-stophook.js +1 -1
- package/dist/pi-extensions/canvas-structured-output.d.ts +5 -3
- package/dist/pi-extensions/canvas-structured-output.js +6 -11
- package/dist/pi-extensions/canvas-tool-guide.d.ts +9 -2
- package/dist/pi-extensions/canvas-tool-guide.js +6 -6
- package/dist/shared/inbox-entry-body.js +7 -7
- package/dist/types.d.ts +12 -0
- package/docs/sdk/release-notes.md +4 -0
- package/package.json +7 -4
- package/packages/crouter-identity/package.json +1 -1
- package/runtime.lock.json +13 -13
- package/scripts/git-credential-crtr +33 -0
- package/scripts/sandbox-bootstrap.sh +54 -0
- package/scripts/sandbox-start.mjs +320 -0
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.d.ts +0 -78
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.js +0 -1179
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.ts +0 -1406
- package/dist/core/conversation-store/file-store.d.ts +0 -37
- package/dist/core/conversation-store/file-store.js +0 -9
- package/dist/core/conversation-store/listener.d.ts +0 -4
- package/dist/core/conversation-store/listener.js +0 -8
- package/dist/core/scoped-state/profiles.d.ts +0 -27
- package/dist/core/scoped-state/profiles.js +0 -1
- package/dist/core/scoped-state/providers.d.ts +0 -24
- package/dist/core/scoped-state/providers.js +0 -1
- package/dist/core/scoped-state/settings.d.ts +0 -28
- package/dist/core/scoped-state/settings.js +0 -1
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{jobRow as d}from"../jobs.js";import{objectDTO as c}from"./dto.js";import{withBase as
|
|
2
|
-
`);return{data:
|
|
1
|
+
import{jobRow as d}from"../jobs.js";import{objectDTO as c}from"./dto.js";import{withBase as u}from"./kind.js";import{recordLiveRead as p}from"./live-read.js";import{attr as r,header as l}from"./render.js";const v={name:"job",addressable:"id",events:u({exited:{level:7},killed:{level:7},silent:{level:7}}),async read(a,i,e,s){const t=await d(a,e);if(!t)throw new Error(`job object ${e.id} has no jobs row`);await p(a,i,e,s.reposFn);const n=await c(a,e),o={command:t.command,status:t.status,exit_code:t.exit_code,output_key:t.output_key},m=[l("object",n,r("status",o.status)+r("exit_code",o.exit_code)),`Command: ${o.command}`,`Output: ${o.output_key}`].join(`
|
|
2
|
+
`);return{data:o,text:m}}};export{v as jobKind};
|
package/dist/core/graph/names.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
var F=Object.defineProperty;var p=(t,e)=>F(t,"name",{value:e,configurable:!0});import{isSafeNodeId as H}from"../canvas/paths.js";import{OBJECT_TYPE as x}from"../permissions/builtin.js";import{ceilingFrag as W,resolveCeiling as v}from"../permissions/ceiling.js";import{compilePermission as Y}from"../permissions/compile.js";import{permits as k,
|
|
2
|
-
WHERE o.type = 'person' AND o.home_machine IS NULL AND regexp_replace(i.external_id, '^user:', '') = ?`).get(
|
|
1
|
+
var F=Object.defineProperty;var p=(t,e)=>F(t,"name",{value:e,configurable:!0});import{isSafeNodeId as H}from"../canvas/paths.js";import{OBJECT_TYPE as x}from"../permissions/builtin.js";import{ceilingFrag as W,resolveCeiling as v}from"../permissions/ceiling.js";import{compilePermission as Y}from"../permissions/compile.js";import{permits as k,readerUser as q,resolveReader as A}from"../permissions/evaluator.js";import{loadDefinitions as B}from"../permissions/schemas.js";import{and as P,or as b,raw as I}from"../permissions/sql.js";import{getById as J}from"./objects.js";import{flatMapAsync as O}from"../async-array.js";async function g(t,e){const o=await q(t,e),s=o===null?void 0:await t.prepare(`SELECT o.* FROM objects o JOIN identities i ON i.object = o.id AND i.scheme = 'user'
|
|
2
|
+
WHERE o.type = 'person' AND o.home_machine IS NULL AND regexp_replace(i.external_id, '^user:', '') = ?`).get(o),a=await t.prepare(`SELECT a.* FROM objects a WHERE a.type = 'app' AND a.deleted_at IS NULL AND EXISTS (
|
|
3
3
|
SELECT 1 FROM objects o JOIN documents d ON d.object = o.id
|
|
4
4
|
WHERE o.owner = a.id AND o.type = 'document' AND o.deleted_at IS NULL AND d.source_path IS NOT NULL)
|
|
5
|
-
ORDER BY a.name = 'crtr', a.name`).all(),
|
|
5
|
+
ORDER BY a.name = 'crtr', a.name`).all(),c=e.class==="node"?[e.node,...e.repos,...e.projectRepos,e.profile,e.app]:e.class==="app"?[e.app]:e.class==="object"?[e.owner,...e.repos,e.app]:[],r=new Set;return[...c,s,...a].filter(i=>!!i&&!r.has(i.id)&&!!r.add(i.id))}p(g,"viewOf");async function V(t,e,o){const s=await k(t,e,"read",o),a=await v(t,e.reader,"read"),c=Y(await B(t),e.subjects,x,"read",I("gr.id")),r={sql:`EXISTS (WITH RECURSIVE up(id, depth) AS (
|
|
6
6
|
SELECT ${o}.id, 0
|
|
7
7
|
UNION ALL SELECT p.owner, up.depth + 1 FROM up JOIN objects p ON p.id = up.id WHERE p.owner IS NOT NULL AND up.depth < 12)
|
|
8
|
-
SELECT 1 FROM up gr WHERE ${
|
|
9
|
-
AND o.deleted_at IS ${a?"NOT NULL":"NULL"} AND ${r.sql}${a?" ORDER BY o.deleted_at DESC":""}`).all(o.id,
|
|
10
|
-
OR (type IN ('person','app','repo','profile') AND (name = ? OR id = ?) AND home_machine IS NULL)`).all(e,e,e)}p(U,"ownersByHandle");const _=/^([^:/]+):reports\/(.+?)(?:\.md)?$/;async function ie(t,e,o){const
|
|
11
|
-
AND o.owner = ANY(?::text[]) AND o.name = ANY(?::text[]) AND o.home_machine IS NULL AND o.deleted_at IS NULL AND ${
|
|
8
|
+
SELECT 1 FROM up gr WHERE ${c.sql})`,params:c.params},i=P([I(`${o}.deleted_at IS NOT NULL AND ${o}.schema_type IS NULL`),...a===null?[]:[W(a,o)],r]);return b([s,i])}p(V,"readableOrDeleted");const S=new WeakMap;function D(t,e){let o=S.get(e);return o===void 0&&(o=V(t,e,"o"),o.catch(()=>S.delete(e)),S.set(e,o)),o}p(D,"readableFrag");async function X(t,e,o){const s=await D(t,e);return(await t.prepareUncached(`SELECT ${s.sql} AS ok FROM objects o WHERE o.id = ?`).get(...s.params,o))?.ok===!0}p(X,"canReadOrDeleted");async function E(t,e,o,s,a,c=!1){const r=await D(t,e);return await t.prepareUncached(`SELECT o.* FROM objects o WHERE (o.type = 'document' OR strpos(o.type, '.') > 0) AND o.owner = ? AND o.name = ? AND o.home_machine IS ${c?"NOT NULL":"NULL"}
|
|
9
|
+
AND o.deleted_at IS ${a?"NOT NULL":"NULL"} AND ${r.sql}${a?" ORDER BY o.deleted_at DESC":""}`).all(o.id,s,...r.params)}p(E,"namedObjects");const re=["person","app","repo","profile"],T=/^(person|app|repo|profile|node):([^/]+)\/(.+)$/,h=p(t=>t.trim().replace(/^\[\[(.*)\]\]$/,"$1").trim(),"unwrapRef");function j(t){const e=T.exec(t);if(e)return{type:e[1],handle:e[2],rest:e[3]};const o=t.indexOf("/");return o>0?{handle:t.slice(0,o),rest:t.slice(o+1)}:null}p(j,"splitOwnerRef");async function U(t,e,o){return o==="node"?await t.prepare("SELECT * FROM objects WHERE type = 'node' AND id = ?").all(e):o?await t.prepare("SELECT * FROM objects WHERE type = ? AND (name = ? OR id = ?) AND home_machine IS NULL").all(o,e,e):await t.prepare(`SELECT * FROM objects WHERE (type = 'node' AND id = ?)
|
|
10
|
+
OR (type IN ('person','app','repo','profile') AND (name = ? OR id = ?) AND home_machine IS NULL)`).all(e,e,e)}p(U,"ownersByHandle");const _=/^([^:/]+):reports\/(.+?)(?:\.md)?$/;async function ie(t,e,o){const s=[...new Set(o.filter(n=>h(n)===n&&!_.test(n)))],a=new Map;if(s.length===0||e.view.length===0)return a;const c=new Set((await t.prepare("SELECT id FROM objects WHERE id = ANY(?::text[])").all(s)).map(n=>n.id)),r=s.filter(n=>!c.has(n));for(const n of r)a.set(n,null);const i=await D(t,e.ev),w=await t.prepareUncached(`SELECT o.id, o.owner, o.name FROM objects o WHERE (o.type = 'document' OR strpos(o.type, '.') > 0)
|
|
11
|
+
AND o.owner = ANY(?::text[]) AND o.name = ANY(?::text[]) AND o.home_machine IS NULL AND o.deleted_at IS NULL AND ${i.sql}`).all(e.view.map(n=>n.id),r,...i.params),m=new Map(e.view.map((n,d)=>[n.id,d])),l=new Map;for(const n of w){const d=m.get(n.owner);d<(l.get(n.name)??1/0)&&(l.set(n.name,d),a.set(n.name,n.id))}return a}p(ie,"viewResolutions");async function se(t,e,o,s){let a=h(o);const c=_.exec(a);c&&!T.test(a)&&(a=`${c[1]}/reports/${c[2]}`);const r=s?.ev??await A(t,e),i=await J(t,a);if(i&&await X(t,r,i.id))return i.deleted_at?{deleted:i}:{object:i};const w=s?.view??await g(t,e);for(const l of w){const n=(await E(t,r,l,a,!1))[0];if(n)return{object:n}}const m=j(a);if(m){const{type:l,handle:n,rest:d}=m,C=l!==void 0,N=await U(t,n,l),R=p(f=>{const u=w.findIndex($=>$.id===f.id);return u<0?1/0:u},"rank"),M=N.filter(f=>R(f)<1/0).sort((f,u)=>R(f)-R(u));for(const f of M){const u=(await E(t,r,f,d,!1))[0];if(u)return{object:u}}const L=await O(N,async f=>await E(t,r,f,d,!1));if(L.length===1)return{object:L[0]};if(L.length>1)return{ambiguous:L};const y=(await O(N,async f=>await E(t,r,f,d,!0)))[0];return y?{deleted:y}:!C&&N.length===0&&H(n)?{remote:a}:{missing:!0}}for(const l of w){const n=(await E(t,r,l,a,!0))[0];if(n)return{deleted:n}}return{missing:!0}}p(se,"resolveName");async function ce(t,e,o){const s=h(o),a=await A(t,e),c=p(async(w,m)=>await O(w,async l=>await E(t,a,l,m,!1,!0)),"found"),r=await c(await g(t,e),s);if(r.length)return r;const i=j(s);return i?await c(await U(t,i.handle,i.type),i.rest):[]}p(ce,"stubsNamed");export{re as HANDLE_TYPES,X as canReadOrDeleted,U as ownersByHandle,V as readableOrDeleted,se as resolveName,ce as stubsNamed,h as unwrapRef,g as viewOf,ie as viewResolutions};
|
|
@@ -15,6 +15,8 @@ export declare function createObject(db: CanvasDb, spec: {
|
|
|
15
15
|
/** The permission schema type the object is evaluated under (`firstlight/memory`); omitted = `crtr/object`. */
|
|
16
16
|
schema_type?: string;
|
|
17
17
|
}): Promise<ObjectRow>;
|
|
18
|
+
/** The advisory lock key `ensureOwner` takes for a first sighting of an identity. */
|
|
19
|
+
export declare const ownerLockKey: (scheme: string, externalId: string) => string;
|
|
18
20
|
/** The owner object for an identity, created on first sight. Idempotent on
|
|
19
21
|
* (scheme, externalId). Handles are unique per owner type: a handle already held
|
|
20
22
|
* by a different identity of the same type throws `conflict` naming both; it is
|
|
@@ -26,7 +28,9 @@ export declare function ensureOwner(db: CanvasDb, type: OwnerType, scheme: strin
|
|
|
26
28
|
* A profile with no object yet has nothing to rename (its object is created from the manifest name
|
|
27
29
|
* on first use). Returns whether an object was renamed. Links are edges to ids, so they keep resolving. */
|
|
28
30
|
export declare function renameProfileObject(db: CanvasDb, profileId: string, handle: string): Promise<boolean>;
|
|
29
|
-
/** The owner object of a principal: `app:<x>` → app `<x>`; `user:<id>` → person (handle `user` for this install's person, else the id).
|
|
31
|
+
/** The owner object of a principal: `app:<x>` → app `<x>`; `user:<id>` → person (handle `user` for this install's person, else the id).
|
|
32
|
+
* A cloud role serves many people and `personId()` is the request's person, so every person there gets the id as its handle: the one
|
|
33
|
+
* `user` handle would otherwise go to whichever person was created first and refuse every other person with a `conflict`. */
|
|
30
34
|
export declare function ownerForGrantee(db: CanvasDb, grantee: string): Promise<ObjectRow>;
|
|
31
35
|
/** The owner's live document named `name`, or null. */
|
|
32
36
|
export declare function liveDocumentNamed(db: CanvasDb, owner: string, name: string): Promise<ObjectRow | null>;
|
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
var F=Object.defineProperty;var
|
|
2
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?) RETURNING *`).get(t.id??await H(),t.type,t.kind,t.owner,t.privacy,t.name,t.preview,new Date().toISOString(),t.home_machine??null,t.schema_type??null)}
|
|
3
|
-
WHERE i.scheme = ? AND i.external_id = ?`).get(o,
|
|
1
|
+
var F=Object.defineProperty;var s=(e,t)=>F(e,"name",{value:t,configurable:!0});import{CrtrError as j,notFound as M}from"../errors.js";import{ExitCode as y}from"../../types.js";import{newNodeId as H}from"../runtime/nodes.js";import{kindOf as W}from"./kinds/registry.js";import{bodyOf as v}from"./bodies.js";import{isCloudRole as k,personId as J,personIdAsync as P}from"../canvas/person.js";import{check as K,permits as L,resolveReader as I}from"../permissions/evaluator.js";import{userSubject as b,writeActsFor as D}from"../permissions/facts.js";const Y=new Set(["person","app","repo","profile"]);function T(e){return e||null}s(T,"rowFrom");async function X(e,t){return T(await e.prepare("SELECT * FROM objects WHERE id = ?").get(t))}s(X,"getById");async function z(e,t){return await W(e,t.type),await e.prepare(`INSERT INTO objects (id, type, kind, owner, privacy, name, preview, created_at, home_machine, schema_type)
|
|
2
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?) RETURNING *`).get(t.id??await H(),t.type,t.kind,t.owner,t.privacy,t.name,t.preview,new Date().toISOString(),t.home_machine??null,t.schema_type??null)}s(z,"createObject");const B=s((e,t)=>`owner:${e}:${t}`,"ownerLockKey");async function x(e,t,o,i,n,c){if(!Y.has(t))throw new Error(`ensureOwner: ${t} is not an owner type`);const d=s(async()=>await e.prepare(`SELECT o.* FROM identities i JOIN objects o ON o.id = i.object
|
|
3
|
+
WHERE i.scheme = ? AND i.external_id = ?`).get(o,i),"find"),E=await d();if(E)return E;await e.prepare("SELECT pg_advisory_xact_lock(hashtext(?))").get(B(o,i));const w=await d();if(w)return w;const p=await e.prepare(`SELECT o.id, o.type, i.scheme, i.external_id FROM objects o
|
|
4
4
|
LEFT JOIN identities i ON i.object = o.id
|
|
5
|
-
WHERE o.name = ? AND o.type = ? AND o.home_machine IS NULL`).get(n,t);if(
|
|
5
|
+
WHERE o.name = ? AND o.type = ? AND o.home_machine IS NULL`).get(n,t);if(p)throw new j("conflict",`handle "${n}" is held by ${p.type} ${p.id} (${p.scheme}:${p.external_id}); cannot give it to ${t} ${o}:${i}`,y.GENERAL,{handle:n,holder:p.id});const N=await z(e,{type:t,kind:null,owner:t==="profile"?c?.id??null:null,privacy:"public",name:n,preview:""});return await e.prepare("INSERT INTO identities (object, scheme, external_id) VALUES (?, ?, ?)").run(N.id,o,i),t==="person"&&o==="user"?await D(e,N.id,b(i).id):(t==="profile"||t==="repo")&&await D(e,N.id,b(await P()).id),N}s(x,"ensureOwner");async function se(e,t,o){const i=await e.prepare(`SELECT o.* FROM identities i JOIN objects o ON o.id = i.object
|
|
6
6
|
WHERE i.scheme = 'profile' AND i.external_id = ? AND o.type = 'profile' AND o.deleted_at IS NULL`).get(t),n=await e.prepare(`SELECT o.id FROM objects o
|
|
7
|
-
WHERE o.name = ? AND o.type = 'profile' AND o.deleted_at IS NULL AND o.home_machine IS NULL AND o.id <> ?`).get(o,
|
|
7
|
+
WHERE o.name = ? AND o.type = 'profile' AND o.deleted_at IS NULL AND o.home_machine IS NULL AND o.id <> ?`).get(o,i?i.id:"");if(n)throw new j("conflict",`handle "${o}" is already held by profile object ${n.id}; cannot rename profile ${t} to it`,y.GENERAL,{handle:o,holder:n.id});if(!i)return!1;const c=i;return c.name===o?!1:(await G(e,c,o),!0)}s(se,"renameProfileObject");async function ae(e,t){if(/^app:[a-z0-9][a-z0-9._-]*$/.test(t))return await x(e,"app","app",t,t.slice(4));if(/^user:[a-z0-9][a-z0-9._-]*$/.test(t))return await x(e,"person","user",t,!k()&&t===J()?"user":t.slice(5));throw new Error(`principal ${JSON.stringify(t)} is neither app:<name> nor user:<id>`)}s(ae,"ownerForGrantee");async function ce(e,t,o){return T(await e.prepare("SELECT * FROM objects WHERE (type = 'document' OR strpos(type, '.') > 0) AND owner = ? AND name = ? AND deleted_at IS NULL AND home_machine IS NULL").get(t,o))}s(ce,"liveDocumentNamed");async function de(e,t){const o=await X(e,t);if(!o||o.type!=="node")throw M(`no node object ${t}`);return o}s(de,"nodeObject");async function G(e,t,o){await e.prepare("UPDATE objects SET name = ? WHERE id = ?").run(o,t.id)}s(G,"setObjectName");async function pe(e,t,o){await e.prepare("UPDATE objects SET kind = ? WHERE id = ?").run(o,t.id)}s(pe,"setObjectKind");function O(e,t){const o=[];return e.type!==void 0&&(o.push("o.type = ?"),t.push(e.type)),e.kind!==void 0&&(o.push("o.kind = ?"),t.push(e.kind)),e.owner!==void 0&&(o.push("o.owner = ?"),t.push(e.owner.id)),e.namePrefix!==void 0&&(o.push("o.name LIKE ? ESCAPE '\\'"),t.push(`${e.namePrefix.replace(/[\\%_]/g,i=>`\\${i}`)}%`)),e.schemaType!==void 0&&(o.push("o.schema_type = ?"),t.push(e.schemaType)),e.extensions!==void 0&&(o.push("EXISTS (SELECT 1 FROM documents x WHERE x.object = o.id AND x.extensions_json::jsonb @> ?::jsonb)"),t.push(JSON.stringify(e.extensions))),o}s(O,"narrowing");function V(e,t){const o="WITH RECURSIVE sa(id, owner, depth) AS (SELECT o.id, o.owner, 0 UNION ALL SELECT p.id, p.owner, sa.depth + 1 FROM sa JOIN objects p ON p.id = sa.owner WHERE sa.depth < 12)";t.push(e.subjects.userIds,e.subjects.groupIds);const i=["o.schema_type IS NULL",`EXISTS (${o} SELECT 1 FROM sa JOIN relations r ON r.resource_type = 'crtr/object' AND r.resource_id = sa.id
|
|
8
8
|
AND r.relation IN ('reader', 'editor', 'messenger', 'user_of') AND r.written_by <> 'package'
|
|
9
|
-
AND ((r.subject_type = 'user' AND r.subject_id = ANY(?::text[])) OR (r.subject_type = 'crtr/group' AND r.subject_relation = 'member' AND r.subject_id = ANY(?::text[]))))
|
|
10
|
-
AND r.relation = 'acts_for' AND r.subject_type = 'user' AND r.subject_id = ?)`]}
|
|
9
|
+
AND ((r.subject_type = 'user' AND r.subject_id = ANY(?::text[])) OR (r.subject_type = 'crtr/group' AND r.subject_relation = 'member' AND r.subject_id = ANY(?::text[]))))`];return e.userId===null?i:(t.push(e.userId),[...i,`NOT EXISTS (${o} SELECT 1 FROM sa JOIN relations r ON r.resource_type = 'crtr/object' AND r.resource_id = sa.id
|
|
10
|
+
AND r.relation = 'acts_for' AND r.subject_type = 'user' AND r.subject_id = ?)`])}s(V,"sharedOnly");async function ue(e,t,o,i={}){const n=["o.seq > ?"],c=[i.after_seq??0];o.privacy!==void 0&&(n.push("o.privacy = ?"),c.push(o.privacy)),o.name!==void 0&&(n.push("o.name = ?"),c.push(o.name)),n.push("o.home_machine IS NULL"),n.push(o.deleted?"o.deleted_at IS NOT NULL":"o.deleted_at IS NULL"),n.push(...O(o,c));const d=await I(e,t);o.shared&&n.push(...V(d,c));const E=await L(e,d,"read","o"),w=Math.min(i.limit??100,100);return await e.prepareUncached(`SELECT o.* FROM objects o WHERE ${n.join(" AND ")} AND (${E.sql}) ORDER BY o.seq LIMIT ${w}`).all(...c,...E.params)}s(ue,"listObjects");async function Ee(e,t,o){const n=[],c=`%${o.text.replace(/[\\%_]/g,r=>`\\${r}`)}%`,d=await I(e,t);if(!o.grep){const r=[c],u=O(o,r).map(l=>` AND ${l}`).join(""),a=await L(e,d,"read","o"),m=await e.prepareUncached(`SELECT o.*, (SELECT d.summary FROM documents d WHERE d.object = o.id) AS _summary FROM objects o
|
|
11
11
|
WHERE o.deleted_at IS NULL AND o.home_machine IS NULL AND (o.name ILIKE ?1 ESCAPE '\\' OR o.preview ILIKE ?1 ESCAPE '\\'
|
|
12
12
|
OR EXISTS (SELECT 1 FROM documents d WHERE d.object = o.id AND d.summary ILIKE ?1 ESCAPE '\\'))${u}
|
|
13
|
-
AND (${a.sql}) ORDER BY o.seq LIMIT 100`).all(...r,...a.params),
|
|
13
|
+
AND (${a.sql}) ORDER BY o.seq LIMIT 100`).all(...r,...a.params),f=o.text.toLowerCase();for(const l of m){const{_summary:U,...g}=l,S=g,R=S.name.toLowerCase().includes(f)?"name":S.preview.toLowerCase().includes(f)?"preview":"summary";n.push({object:S,field:R,...R==="summary"?{text:String(U)}:{}})}if(n.length>=100)return n}if(!o.body&&!o.grep)return n;const E=new Set(n.map(r=>r.object.id)),w=o.grep?(r=>u=>r.test(u))(new RegExp(o.text)):r=>r.includes(o.text),p=[],N=O(o,p).map(r=>` AND ${r}`).join(""),$=await e.prepareUncached(`SELECT o.id, r.body_hash AS body_hash, d.source_path AS source_path FROM objects o
|
|
14
14
|
JOIN documents d ON d.object = o.id JOIN revisions r ON r.document = o.id
|
|
15
|
-
WHERE o.type = 'document' AND o.deleted_at IS NULL AND NOT EXISTS (SELECT 1 FROM revision_parents p WHERE p.parent = r.rev_id)${
|
|
16
|
-
ORDER BY o.seq, r.number`).all(...
|
|
17
|
-
`),m=a.findIndex(
|
|
15
|
+
WHERE o.type = 'document' AND o.deleted_at IS NULL AND NOT EXISTS (SELECT 1 FROM revision_parents p WHERE p.parent = r.rev_id)${N}
|
|
16
|
+
ORDER BY o.seq, r.number`).all(...p),A=await L(e,d,"read","o"),C=200;let h=[];const _=s(async()=>{if(h.length===0)return!1;const r=await e.prepareUncached(`SELECT o.* FROM objects o WHERE o.id = ANY(?::text[]) AND (${A.sql})`).all(h.map(a=>a.id),...A.params),u=new Map(r.map(a=>[a.id,a]));for(const a of h){const m=u.get(a.id);if(m!==void 0&&(n.push({object:m,field:"body",line:a.line,text:a.text}),n.length>=100))return!0}return h=[],!1},"flush");for(const r of $){if(E.has(r.id))continue;let u;try{u=v(r.body_hash,r.source_path)}catch(f){if(await K(e,d,"read",r.id))throw f;continue}if(!o.grep&&!u.includes(o.text))continue;const a=u.split(`
|
|
17
|
+
`),m=a.findIndex(w);if(!(m<0)&&(E.add(r.id),h.push({id:r.id,line:m+1,text:a[m]}),h.length>=C&&await _()))return n}return await _(),n}s(Ee,"searchObjects");export{z as createObject,x as ensureOwner,X as getById,ue as listObjects,ce as liveDocumentNamed,de as nodeObject,ae as ownerForGrantee,B as ownerLockKey,se as renameProfileObject,Ee as searchObjects,pe as setObjectKind,G as setObjectName};
|
|
@@ -10,6 +10,9 @@ export type ReposFn = (cwd: string) => Promise<Checkout[]>;
|
|
|
10
10
|
export declare function viewRepos(cwd: string, profileId: string | null, reposFn: ReposFn, lookups: Pick<ReaderLookups, 'projectPaths'>): Promise<Pick<Extract<Reader, {
|
|
11
11
|
class: 'node';
|
|
12
12
|
}>, 'repos' | 'checkouts' | 'projectRepos' | 'projectCheckouts'>>;
|
|
13
|
+
/** Run the git lookups a node's reader needs (its cwd and its profile's project paths) now, before a canvas write opens, so
|
|
14
|
+
* `viewRepos` inside the write hits the identity cache instead of spawning git while the write holds a pooled connection. */
|
|
15
|
+
export declare function warmNodeRepos(db: CanvasDb, nodeId: string): Promise<void>;
|
|
13
16
|
export declare function readerFor(db: CanvasDb, principal: RequestPrincipal, reposFn: ReposFn): Promise<Exclude<Reader, {
|
|
14
17
|
class: 'object';
|
|
15
18
|
}>>;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
var
|
|
2
|
-
sub, grant_id, scopes_json, cwd, profile_id, app FROM nodes WHERE node_id = ?`).get(e);if(!
|
|
3
|
-
WHERE i.scheme = 'profile' AND i.external_id = ?`).get(e)??await
|
|
1
|
+
var b=Object.defineProperty;var p=(o,e)=>b(o,"name",{value:e,configurable:!0});import{coveredByAny as d,isSandboxedNode as C}from"../../shared/env.js";import{existsSync as S}from"node:fs";import{CrtrError as L}from"../errors.js";import{getCachedProfile as M}from"../scoped-state/person-store.js";import{parseScope as R}from"@north-light/identity";import{activeGrant as O,grantFor as v}from"../grants/mirror.js";import{ApiError as $}from"../../api/errors.js";import{pluginAppToken as A}from"../secrets.js";import{loadExactProfileManifest as T}from"../profiles/manifest.js";import{ensureOwner as y,getById as H,nodeObject as W,ownerForGrantee as D}from"./objects.js";import{personId as P}from"../canvas/person.js";import{warmCheckoutIdentities as F}from"./repo-sync/repos.js";async function N(o,e,n,a){const t=e===null?[]:a.projectPaths(e),r=await n(o),l=new Set(r.map(s=>s.repo.id)),c=[];for(const s of t){if(!S(s))continue;let i;try{i=await n(s)}catch(u){if(u instanceof L&&u.code==="git-lookup-failed")continue;throw u}for(const u of i)l.has(u.repo.id)||(l.add(u.repo.id),c.push(u))}return{repos:r.map(s=>s.repo),checkouts:r,projectRepos:c.map(s=>s.repo),projectCheckouts:c}}p(N,"viewRepos");async function te(o,e){const n=await o.prepare("SELECT cwd, profile_id FROM nodes WHERE node_id = ?").get(e);if(n!==void 0&&(await F(n.cwd),n.profile_id))for(const a of w(o).projectPaths(n.profile_id))S(a)&&await F(a)}p(te,"warmNodeRepos");async function ne(o,e,n){if(e.class==="anonymous")throw new Error("a publish token cannot read as a principal");if(e.class==="person")return{class:"person",person:await j(o)};if(e.class==="app")return{class:"app",app:await E(o,e.app),scopes:e.scopes,...e.sub===void 0?{}:{sub:e.sub}};if(e.class==="machine")throw new Error("a machine token cannot read as a principal");if(e.class==="forwarded"){if(e.actor.kind==="person")return{class:"person",person:await j(o)};const c=await v(e.actor.app,e.sub);if(!c)throw new $(403,"app_not_granted",`${e.actor.app} holds no active grant for ${e.sub} on this machine`);const s=e.actor.node_scopes;return{class:"app",app:await E(o,e.actor.app),place:e.actor.place,launched:s,scopes:s===null?c.resolved:s.filter(i=>d(c.resolved,i))}}if(e.class==="cron"){const c=e.grant?(await O(e.grant))?.resolved??[]:[],s=e.scopes;return{class:"app",app:await E(o,e.app),scopes:s===null?c:s.filter(i=>d(c,i)),launched:s,place:{run:e.origin_run??"",isolated:e.isolated}}}const a=w(o),t=await W(o,e.node),r=await o.prepare("SELECT cwd, profile_id, app FROM nodes WHERE node_id = ?").get(e.node),l=r.app===null?null:await a.object(r.app);if(!l)throw new Error(`node ${e.node} has no app`);return{class:"node",node:t,app:l,scopes:await x(e.app,e.sub,e.grant,e.scopes,a),launched:e.scopes,cwd:r.cwd,...await N(r.cwd,r.profile_id,n,a),profile:r.profile_id===null?null:await a.profile(r.profile_id,l)}}p(ne,"readerFor");async function B(o,e,n,a=w(o),t=!1){const r=await o.prepare("SELECT o.* FROM objects o WHERE o.id = ? AND o.type = 'node'").get(e),l=await o.prepare(`SELECT (SELECT external_id FROM identities WHERE object = nodes.app) AS grantee,
|
|
2
|
+
sub, grant_id, scopes_json, cwd, profile_id, app FROM nodes WHERE node_id = ?`).get(e);if(!r||!l)throw new Error(`no node ${e}`);const{grantee:c,sub:s,grant_id:i,scopes_json:u,cwd:f,profile_id:g,app:h}=l,m=h===null?null:await a.object(h);if(!m)throw new Error(`node ${e} has no app`);const _=u===null?null:JSON.parse(u);return{class:"node",node:r,app:m,scopes:await x(c,s??"",i,_,a,t),launched:_,cwd:f,...await N(f,g,n,a),profile:g===null?null:await a.profile(g,m)}}p(B,"readerForNode");async function re(o,e,n=async()=>[],a=w(o)){const t=await o.prepare("SELECT envelope_json FROM peer_stubs WHERE object = ?").get(e.id);if(t!==void 0)return await J(o,e,t.envelope_json===null?null:JSON.parse(t.envelope_json),a);if(e.type==="node")return await B(o,e.id,n,a,!0);const r=e.owner===null?null:await a.object(e.owner);if(!r)throw new Error(`watcher ${e.id} has no owner`);const c=(r.type==="app"?r:r.type==="profile"&&r.owner!==null?await a.object(r.owner):null)??await o.prepare("SELECT o.* FROM identities i JOIN objects o ON o.id = i.object WHERE i.external_id = 'app:terminal' AND i.scheme = 'app'").get()??await o.prepare("SELECT * FROM objects WHERE type = 'person' AND name = 'user' AND home_machine IS NULL").get();if(!c)throw new Error("no terminal app or person object");const s=(await o.prepare("SELECT external_id FROM identities WHERE object = ? AND scheme = 'app'").get(c.id))?.external_id??"app:terminal",i=await o.prepare("SELECT resolved_scopes_json FROM grants WHERE grantee = ? AND status = 'active'").all(s),u=r.type==="person"?null:i.length===0?a.pluginScopes(s):i.length===1?JSON.parse(i[0].resolved_scopes_json).filter(f=>f.mode==="always").map(f=>R(f.scope)):null;return{class:"object",object:e,node:e,owner:r,app:c,scopes:u,repos:r.type==="repo"?[r]:[]}}p(re,"readerForObject");async function ae(o,e,n){const a=(await o.prepare("SELECT external_id FROM identities WHERE object = ? AND scheme = 'app'").get(e.id))?.external_id;if(a===void 0)return null;const t=await o.prepare("SELECT resolved_scopes_json FROM grants WHERE grantee = ? AND status = 'active'").all(a);return t.length===0?n.pluginScopes(a):t.length>1?null:JSON.parse(t[0].resolved_scopes_json).filter(r=>r.mode==="always").map(r=>R(r.scope))}p(ae,"appScopesNow");async function J(o,e,n,a){const t=await j(o);if(n!==null&&n.app===null)return{class:"object",object:e,node:e,owner:t,app:t,scopes:null,repos:[]};const r=n?.app==null?null:await E(o,n.app),l=n?.app==null?null:await a.grantFor(n.app,n.sub),c=n===null||l===null?null:n.node_scopes===null?l.resolved:n.node_scopes.filter(i=>d(l.resolved,i)),s=r??(e.owner===null?t:await a.object(e.owner)??t);return{class:"object",object:e,node:e,owner:s,app:s,scopes:c,launched:n?.node_scopes??null,repos:[],...n?.place==null?{}:{place:n.place}}}p(J,"readerForStub");function w(o){return{grantById:O,grantFor:v,pluginScopes:p(e=>A(e.replace(/^app:/,""))?.scopes??null,"pluginScopes"),object:p(async e=>await H(o,e),"object"),profile:p(async(e,n)=>await I(o,e,n),"profile"),projectPaths:p(e=>C()?[]:M(e)?.manifest.projects.map(n=>n.path)??[],"projectPaths")}}p(w,"liveLookups");function se(o){const e=w(o),n=new Map,a=p((t,r)=>(n.has(t)||n.set(t,r()),n.get(t)),"memo");return{grantById:p(t=>a(`g\0${t}`,()=>e.grantById(t)),"grantById"),grantFor:p((t,r)=>a(`a\0${t}\0${r}`,()=>e.grantFor(t,r)),"grantFor"),pluginScopes:p(t=>a(`t\0${t}`,()=>e.pluginScopes(t)),"pluginScopes"),object:p(async t=>await a(`o\0${t}`,async()=>await e.object(t)),"object"),profile:p(async(t,r)=>await a(`p\0${t}\0${r.id}`,async()=>await e.profile(t,r)),"profile"),projectPaths:p(t=>a(`j\0${t}`,()=>e.projectPaths(t)),"projectPaths")}}p(se,"publishLookups");async function x(o,e,n,a,t,r=!1){const l=n?await t.grantById(n):await t.grantFor(o,e),c=l&&l.grantee===o?l.resolved:null;if(c===null){if(r)return null;throw new Error(`the grant of ${o} is not active`)}return a===null?c:a.filter(s=>d(c,s))}p(x,"nodeScopes");async function j(o){return await D(o,P())}p(j,"personObject");async function E(o,e){return await y(o,"app","app",e,e.replace(/^app:/,""))}p(E,"appObject");async function I(o,e,n){return await o.prepare(`SELECT o.* FROM identities i JOIN objects o ON o.id = i.object
|
|
3
|
+
WHERE i.scheme = 'profile' AND i.external_id = ?`).get(e)??await y(o,"profile","profile",e,T(e).manifest.name,n)}p(I,"profileObject");export{ae as appScopesNow,w as liveLookups,I as profileObject,se as publishLookups,ne as readerFor,B as readerForNode,re as readerForObject,N as viewRepos,te as warmNodeRepos};
|
|
@@ -25,6 +25,8 @@ export declare function normalizeRemoteUrl(url: string, base?: string): string;
|
|
|
25
25
|
/** Owner handle a new repo object takes: the last segment of its external id (the normalized remote path, or the folder of a local-path repo), without `.git`. */
|
|
26
26
|
export declare function handleHint(externalId: string): string;
|
|
27
27
|
export declare function identifyCheckout(dir: string): CheckoutIdentity;
|
|
28
|
+
/** `identifyCheckout` without blocking the event loop: the same parsing and cache, git run through `gitAsync`. */
|
|
29
|
+
export declare function identifyCheckoutAsync(dir: string): Promise<CheckoutIdentity>;
|
|
28
30
|
/** Checkouts enclosing `dir`, innermost first; stops at the first directory
|
|
29
31
|
* that is not in a repo. A failed lookup ends the chain and is returned last. */
|
|
30
|
-
export declare function checkoutChain(dir: string): CheckoutIdentity[]
|
|
32
|
+
export declare function checkoutChain(dir: string): Promise<CheckoutIdentity[]>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var
|
|
1
|
+
var L=Object.defineProperty;var a=(t,e)=>L(t,"name",{value:e,configurable:!0});import{existsSync as S}from"node:fs";import{basename as m,dirname as h,isAbsolute as U,resolve as d}from"node:path";import{gitAsync as g,gitSync as k}from"../../git.js";import{realpathOrSelf as u}from"../../fs-utils.js";const c=5e3,_=6e4,f=new Map;function A(t,e){const r=t.trim();let o,n;const s=/^([a-z][a-z0-9+.-]*):\/\//i.exec(r);if(s){if(s[1].toLowerCase()==="file")return`file:${y(decodeURIComponent(r.slice(7)),e)}`;const i=r.slice(s[0].length),l=i.indexOf("/"),E=l<0?i:i.slice(0,l);n=l<0?"":i.slice(l),o=E.replace(/^.*@/,"").replace(/:\d*$/,"")}else{const i=/^(?:[^@/]+@)?([^:/]+):(.*)$/.exec(r);if(!i)return`file:${y(r,e)}`;o=i[1],n=i[2]}return n=n.replace(/^\/*~?/,"").replace(/\/+$/,"").replace(/\.git$/i,"").replace(/\/+$/,""),`${o}/${n}`.toLowerCase()}a(A,"normalizeRemoteUrl");function y(t,e){const r=U(t)?t:d(e??process.cwd(),t);return u(r).replace(/\/+$/,"")||"/"}a(y,"localPath");function w(t){const e=t.startsWith("file:")?t.slice(5):t;return m(e).replace(/\.git$/i,"")||"repo"}a(w,"handleHint");const $=["rev-parse","--path-format=absolute","--show-toplevel","--git-common-dir"],x=["remote","get-url","origin"];function M(t){const e=f.get(t);return e&&Date.now()-e.at<_?e.id:void 0}a(M,"cached");function O(t){return S(t)?void 0:{ok:!1,code:"not-a-repo",dir:t,reason:"directory does not exist"}}a(O,"missingDir");function C(t,e){if(t.timedOut)return{done:{ok:!1,code:"git-lookup-failed",dir:e,reason:`git lookup timed out after ${c}ms`}};if(t.status!==0){if(/not a git repository/i.test(t.stderr)){const n={ok:!1,code:"not-a-repo",dir:e,reason:t.stderr.trim()};return f.set(e,{at:Date.now(),id:n}),{done:n}}return{done:{ok:!1,code:"git-lookup-failed",dir:e,reason:t.stderr.trim()||t.processError||`git rev-parse exited ${t.status}`}}}const[r,o]=t.stdout.split(/\r?\n/).map(n=>n.trim());return!r||!o?{done:{ok:!1,code:"git-lookup-failed",dir:e,reason:"git rev-parse returned no work tree (bare repository?)"}}:{root:u(r),commonDir:u(o)}}a(C,"parseRevParse");function R(t,e,r,o){if(t.timedOut)return{ok:!1,code:"git-lookup-failed",dir:e,reason:`git remote lookup timed out after ${c}ms`};let n;const s=t.stdout.trim();if(t.status===0&&s!==""){const i=A(s,r);n={ok:!0,scheme:"git",externalId:i,remoteUrl:s,root:r,commonDir:o,handleHint:w(i)}}else if(/no such remote/i.test(t.stderr)){const i=m(o)===".git"?h(o):o;n={ok:!0,scheme:"local-path",externalId:i,root:r,handleHint:w(i)}}else return{ok:!1,code:"git-lookup-failed",dir:e,reason:t.stderr.trim()||`git remote get-url exited ${t.status}`};return f.set(e,{at:Date.now(),id:n}),n}a(R,"parseOrigin");function v(t){const e=u(d(t)),r=M(e)??O(e);if(r)return r;const o=C(k($,e,void 0,{timeoutMs:c}),e);return"done"in o?o.done:R(k(x,o.root,void 0,{timeoutMs:c}),e,o.root,o.commonDir)}a(v,"identifyCheckout");const p=new Map;async function D(t){const e=u(d(t)),r=M(e)??O(e);if(r)return r;const o=p.get(e);if(o)return await o;const n=(async()=>{const s=C(await g($,e,void 0,{timeoutMs:c}),e);return"done"in s?s.done:R(await g(x,s.root,void 0,{timeoutMs:c}),e,s.root,s.commonDir)})().finally(()=>p.delete(e));return p.set(e,n),await n}a(D,"identifyCheckoutAsync");async function K(t){const e=[];let r=t;for(;;){const o=await D(r);if(!o.ok)return o.code==="git-lookup-failed"&&e.push(o),e;e.push(o);const n=h(o.root);if(n===o.root)return e;r=n}}a(K,"checkoutChain");export{K as checkoutChain,w as handleHint,v as identifyCheckout,D as identifyCheckoutAsync,A as normalizeRemoteUrl};
|
|
@@ -16,6 +16,6 @@ export declare function ensureRepo(db: CanvasDb, id: RepoIdentity, handle?: stri
|
|
|
16
16
|
export declare function reposForCwd(db: CanvasDb, cwd: string): Promise<ObjectRow[]>;
|
|
17
17
|
/** Run the git lookups for `cwd`'s checkouts now, so a later `checkoutsForCwd` inside a canvas write hits the identity
|
|
18
18
|
* cache instead of spawning git while every other db caller waits on the write lock. */
|
|
19
|
-
export declare function warmCheckoutIdentities(cwd: string): void
|
|
19
|
+
export declare function warmCheckoutIdentities(cwd: string): Promise<void>;
|
|
20
20
|
/** `reposForCwd` with the directory each repo is checked out at. */
|
|
21
21
|
export declare function checkoutsForCwd(db: CanvasDb, cwd: string): Promise<Checkout[]>;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
var l=Object.defineProperty;var a=(t,o)=>l(t,"name",{value:o,configurable:!0});import{resolve as c,sep as f}from"node:path";import{CrtrError as u}from"../../errors.js";import{realpathOrSelf as h}from"../../fs-utils.js";import{ExitCode as m}from"../../../types.js";import{ensureOwner as w}from"../objects.js";import{checkoutChain as d,handleHint as E}from"./identity.js";async function x(t,o,r){return await t.prepare(`SELECT o.* FROM identities i JOIN objects o ON o.id = i.object
|
|
2
|
-
WHERE o.type = 'repo' AND i.scheme = ? AND i.external_id = ?`).get(o,r)??null}a(x,"existingRepo");async function N(t,o,r){const n=await x(t,o.scheme,o.externalId);if(n)return n;const s=r??o.handleHint,p=t.prepare("SELECT 1 FROM objects WHERE name = ? AND type = 'repo' AND home_machine IS NULL");let e=s;for(let i=2;await p.get(e);i++)e=`${s}-${i}`;return await w(t,"repo",o.scheme,o.externalId,e)}a(N,"ensureRepo");async function I(t,o){return(await
|
|
3
|
-
WHERE o.type = 'repo' AND i.scheme = 'local-path'`).all();for(const{path:e,...i}of s)(r===e||r.startsWith(e.endsWith(f)?e:e+f))&&n.push({root:e,repo:i});n.sort((e,i)=>i.root.length-e.root.length);const p=new Set;return n.filter(({repo:e})=>!p.has(e.id)&&(p.add(e.id),!0))}a(
|
|
2
|
+
WHERE o.type = 'repo' AND i.scheme = ? AND i.external_id = ?`).get(o,r)??null}a(x,"existingRepo");async function N(t,o,r){const n=await x(t,o.scheme,o.externalId);if(n)return n;const s=r??o.handleHint,p=t.prepare("SELECT 1 FROM objects WHERE name = ? AND type = 'repo' AND home_machine IS NULL");let e=s;for(let i=2;await p.get(e);i++)e=`${s}-${i}`;return await w(t,"repo",o.scheme,o.externalId,e)}a(N,"ensureRepo");async function I(t,o){return(await y(t,o)).map(r=>r.repo)}a(I,"reposForCwd");async function L(t){await d(h(c(t)))}a(L,"warmCheckoutIdentities");async function y(t,o){const r=h(c(o)),n=[];for(const e of await d(r)){if(!e.ok)throw new u("git-lookup-failed",`cannot identify the repo at ${e.dir}: ${e.reason}`,m.GENERAL,{dir:e.dir});n.push({root:e.root,repo:await N(t,e)})}const s=await t.prepare(`SELECT o.*, i.external_id AS path FROM identities i JOIN objects o ON o.id = i.object
|
|
3
|
+
WHERE o.type = 'repo' AND i.scheme = 'local-path'`).all();for(const{path:e,...i}of s)(r===e||r.startsWith(e.endsWith(f)?e:e+f))&&n.push({root:e,repo:i});n.sort((e,i)=>i.root.length-e.root.length);const p=new Set;return n.filter(({repo:e})=>!p.has(e.id)&&(p.add(e.id),!0))}a(y,"checkoutsForCwd");export{y as checkoutsForCwd,N as ensureRepo,E as handleHint,I as reposForCwd,L as warmCheckoutIdentities};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var N=Object.defineProperty;var c=(t,n)=>N(t,"name",{value:n,configurable:!0});import{existsSync as D}from"node:fs";import{readFile as B,writeFile as q}from"node:fs/promises";import{join as R}from"node:path";import{emitEvent as K}from"../../events/emit.js";import{exportRepo as G,importTree as J,pendingPaths as Q}from"./exchange.js";import{checkoutChain as V}from"./identity.js";import{checkoutsForCwd as X,reposForCwd as Y,warmCheckoutIdentities as Z}from"./repos.js";import{commitTree as S,fetchDocs as ee,FIRST_FETCH_MARKER as te,isAncestor as I,mergeBase as ne,openMirror as b,pushDocs as re,readTree as m,remoteDocsTip as ae,resolveRef as h,setRef as y}from"./mirror.js";import{mergeTrees as ie}from"./ref-format.js";import{withCanvasWrite as se}from"../../canvas/db.js";import{filterAsync as oe}from"../../async-array.js";const ce=2e4,L=3,A="remote-url",w="refs/crtr/docs",fe="refs/crtr/remote-docs",g="refs/crtr/imported";function v(t){try{K(t)}catch{}}c(v,"emitEvent");let T=null;const M=new Map,H=new Set;async function Me(t,n){T={lifecycle:t,db:n}}c(Me,"startRepoSync");async function P(t,n){return n.type!=="repo"?!1:await t.prepare("SELECT 1 FROM identities WHERE object = ? AND scheme = 'git'").get(n.id)!==void 0}c(P,"gitScheme");async function U(t,n){const e=new Map;for(const f of n)for(const a of V(f))a.ok&&a.scheme==="git"&&e.set(a.externalId,a.remoteUrl);if(e.size===0)return;const r=(await T.db()).prepare("SELECT external_id FROM identities WHERE object = ? AND scheme = 'git'");for(const f of t){const a=await r.get(f.id),s=a&&e.get(a.external_id);if(!s)continue;const i=await b(f.id);await q(R(i.dir,A),`${s}
|
|
2
|
-
`)}}c(U,"recordRemoteUrls");async function de(t,n){const o=await E().db(),r=await oe(t,async i=>await P(o,i));if(r.length===0)return;await U(r,[n]);const f=[];for(const i of r){const l=!H.has(i.id)&&!D(R((await b(i.id)).dir,te)),u=k(i);l&&u&&f.push(u)}if(f.length===0)return;let a;const s=new Promise(i=>{a=setTimeout(i,ce)});await Promise.race([Promise.all(f),s]),clearTimeout(a)}c(de,"noteNodeWorking");async function _e(t){try{const n=await E().db(),e=await n.prepare("SELECT cwd FROM nodes WHERE node_id = ?").get(t);if(!e)return;Z(e.cwd);const o=await se(async()=>await Y(n,e.cwd));o.length>0&&await de(o,e.cwd)}catch(n){v({level:"warn",event:"repo_sync.failed",outcome:"failed",error:n,node_id:t,fields:{step:"fetch",reason:`the boot trigger failed: ${n instanceof Error?n.message:String(n)}`}})}}c(_e,"noteNodeBooting");async function xe(t,n=[]){const e=E();if(!await P(await e.db(),t))return;if(n.length===0){k(t);return}const o=U([t],n).then(()=>{k(t)},r=>{v({level:"error",event:"repo_sync.failed",error:r,fields:{repo:t.name,step:"fetch",reason:"recording the remote URL failed"}})});e.lifecycle.registerDetached(o)}c(xe,"noteRepoDocumentsChanged");function E(){if(!T)throw new Error("repo sync is not started: crtrd must call startRepoSync first");return T}c(E,"requireEngine");function k(t){const n=E(),e=M.get(t.id)??{running:null,again:!1};if(M.set(t.id,e),e.running)return e.again=!0,e.running.then(()=>M.get(t.id)?.running??null).then(r=>r??{ok:!0,pushed:!1,imported:$()});if(!n.lifecycle.acceptsDetachedWork())return null;H.add(t.id);const o=ue(t).then(r=>(W(t,r),r),r=>{const f={ok:!1,step:"export",reason:r instanceof Error?r.message:String(r)};return W(t,f),f}).finally(()=>{e.running=null,e.again&&(e.again=!1,k(t))});return e.running=o,n.lifecycle.registerDetached(o.then(()=>{})),o}c(k,"schedule");function W(t,n){if(n.ok){const e=n.imported;v({level:"info",event:"repo_sync.completed",outcome:"succeeded",fields:{repo:t.name,pushed:n.pushed,created:e.created,revisions:e.revisions,deleted:e.deleted,needs_merge:e.needsMerge,refused:e.refused}})}else v({level:"warn",event:"repo_sync.failed",outcome:"failed",fields:{repo:t.name,step:n.step,reason:n.reason}})}c(W,"report");function $(){return{created:0,revisions:0,deleted:0,needsMerge:[],refused:[]}}c($,"emptyImport");class _ extends Error{static{c(this,"StepError")}step;constructor(n,e){super(e),this.step=n}}async function x(t,n){try{return await n()}catch(e){throw e instanceof _?e:new _(t,e instanceof Error?e.message:String(e))}}c(x,"step");async function ue(t){const n=E();try{const e=await b(t.id),o=await le(e);if(o===null)return{ok:!1,step:"fetch",reason:`no checkout of ${t.name} with an origin remote has been seen by this runtime`};let r=$();const f=c(()=>x("import",async()=>{const a=await h(e,w),s=await h(e,g);if(a===null||s===a)return;const i=s?await m(e,g):new Map,l=await n.db(),u=await m(e,w),d=await J(l,t,i,u,async p=>await X(l,p));r={created:r.created+d.created,revisions:r.revisions+d.revisions,deleted:r.deleted+d.deleted,needsMerge:[...new Set([...r.needsMerge,...d.needsMerge])],refused:[...r.refused,...d.refused]},await j(e,a,u,i,new Set(d.refused.map(p=>p.path)),s)}),"importLocal");await f(),await x("export",async()=>{const a=await h(e,w),s=a?await m(e,w):null,i=await h(e,g),l=i?await m(e,g):null,u=await G(await n.db(),t,s,l);if(a?z(s,u):u.size===0)return;const d=await S(e,u,a?[a]:[],`crtr: export ${t.name}`);await y(e,w,d,a),await j(e,d,u,l??new Map,new Set(Q(s,l)),i)});for(let a=1;;a++){const s=await ae(e,o);if(!s.ok)return{ok:!1,step:"fetch",reason:s.reason};let i=await h(e,w);if(s.value!==null&&!(i&&await we(e,s.value)&&await I(e,s.value,i))){const u=await ee(e,o);if(!u.ok)return{ok:!1,step:"fetch",reason:u.reason};const d=u.value;i=await x("merge",async()=>{if(!i||await I(e,i,d))return await y(e,w,d,i),d;const p=await ne(e,i,d),C=ie(p?await m(e,p):new Map,await m(e,w),await m(e,fe));for(const O of C.refused)r.refused.push(O);const F=await S(e,C.tree,[i,d],`crtr: merge ${t.name}`);return await y(e,w,F,i),F})}if(await f(),i===null||i===s.value)return{ok:!0,pushed:!1,imported:r};const l=await re(e,o,i);if(l.ok)return{ok:!0,pushed:!0,imported:r};if(l.reason!=="rejected")return{ok:!1,step:"push",reason:l.reason};if(a>=L)return{ok:!1,step:"push",reason:`push rejected ${L} times`}}}catch(e){if(e instanceof _)return{ok:!1,step:e.step,reason:e.message};throw e}}c(ue,"syncRepo");async function j(t,n,e,o,r,f){if(r.size===0){await y(t,g,n,f);return}const a=new Map(e);for(const s of r)o.has(s)?a.set(s,o.get(s)):a.delete(s);f!==null&&z(o,a)||await y(t,g,await S(t,a,[],"crtr: imported baseline (some files pending)"),f)}c(j,"advanceImported");async function le(t){const n=R(t.dir,A);return D(n)&&(await B(n,"utf8")).trim()||null}c(le,"readUrl");async function we(t,n){return await h(t,n)!==null}c(we,"hasCommit");function z(t,n){if(t.size!==n.size)return!1;for(const[e,o]of t)if(n.get(e)!==o)return!1;return!0}c(z,"sameTree");export{ce as FIRST_FETCH_WAIT_MS,_e as noteNodeBooting,de as noteNodeWorking,xe as noteRepoDocumentsChanged,Me as startRepoSync,ue as syncRepo};
|
|
1
|
+
var N=Object.defineProperty;var c=(t,n)=>N(t,"name",{value:n,configurable:!0});import{existsSync as D}from"node:fs";import{readFile as B,writeFile as q}from"node:fs/promises";import{join as R}from"node:path";import{emitEvent as K}from"../../events/emit.js";import{exportRepo as G,importTree as J,pendingPaths as Q}from"./exchange.js";import{checkoutChain as V}from"./identity.js";import{checkoutsForCwd as X,reposForCwd as Y,warmCheckoutIdentities as Z}from"./repos.js";import{commitTree as S,fetchDocs as ee,FIRST_FETCH_MARKER as te,isAncestor as I,mergeBase as ne,openMirror as b,pushDocs as re,readTree as m,remoteDocsTip as ae,resolveRef as h,setRef as y}from"./mirror.js";import{mergeTrees as ie}from"./ref-format.js";import{withCanvasWrite as se}from"../../canvas/db.js";import{filterAsync as oe}from"../../async-array.js";const ce=2e4,L=3,A="remote-url",w="refs/crtr/docs",fe="refs/crtr/remote-docs",g="refs/crtr/imported";function v(t){try{K(t)}catch{}}c(v,"emitEvent");let T=null;const M=new Map,H=new Set;async function Me(t,n){T={lifecycle:t,db:n}}c(Me,"startRepoSync");async function P(t,n){return n.type!=="repo"?!1:await t.prepare("SELECT 1 FROM identities WHERE object = ? AND scheme = 'git'").get(n.id)!==void 0}c(P,"gitScheme");async function U(t,n){const e=new Map;for(const f of n)for(const a of await V(f))a.ok&&a.scheme==="git"&&e.set(a.externalId,a.remoteUrl);if(e.size===0)return;const r=(await T.db()).prepare("SELECT external_id FROM identities WHERE object = ? AND scheme = 'git'");for(const f of t){const a=await r.get(f.id),s=a&&e.get(a.external_id);if(!s)continue;const i=await b(f.id);await q(R(i.dir,A),`${s}
|
|
2
|
+
`)}}c(U,"recordRemoteUrls");async function de(t,n){const o=await E().db(),r=await oe(t,async i=>await P(o,i));if(r.length===0)return;await U(r,[n]);const f=[];for(const i of r){const l=!H.has(i.id)&&!D(R((await b(i.id)).dir,te)),u=k(i);l&&u&&f.push(u)}if(f.length===0)return;let a;const s=new Promise(i=>{a=setTimeout(i,ce)});await Promise.race([Promise.all(f),s]),clearTimeout(a)}c(de,"noteNodeWorking");async function _e(t){try{const n=await E().db(),e=await n.prepare("SELECT cwd FROM nodes WHERE node_id = ?").get(t);if(!e)return;await Z(e.cwd);const o=await se(async()=>await Y(n,e.cwd));o.length>0&&await de(o,e.cwd)}catch(n){v({level:"warn",event:"repo_sync.failed",outcome:"failed",error:n,node_id:t,fields:{step:"fetch",reason:`the boot trigger failed: ${n instanceof Error?n.message:String(n)}`}})}}c(_e,"noteNodeBooting");async function xe(t,n=[]){const e=E();if(!await P(await e.db(),t))return;if(n.length===0){k(t);return}const o=U([t],n).then(()=>{k(t)},r=>{v({level:"error",event:"repo_sync.failed",error:r,fields:{repo:t.name,step:"fetch",reason:"recording the remote URL failed"}})});e.lifecycle.registerDetached(o)}c(xe,"noteRepoDocumentsChanged");function E(){if(!T)throw new Error("repo sync is not started: crtrd must call startRepoSync first");return T}c(E,"requireEngine");function k(t){const n=E(),e=M.get(t.id)??{running:null,again:!1};if(M.set(t.id,e),e.running)return e.again=!0,e.running.then(()=>M.get(t.id)?.running??null).then(r=>r??{ok:!0,pushed:!1,imported:$()});if(!n.lifecycle.acceptsDetachedWork())return null;H.add(t.id);const o=ue(t).then(r=>(W(t,r),r),r=>{const f={ok:!1,step:"export",reason:r instanceof Error?r.message:String(r)};return W(t,f),f}).finally(()=>{e.running=null,e.again&&(e.again=!1,k(t))});return e.running=o,n.lifecycle.registerDetached(o.then(()=>{})),o}c(k,"schedule");function W(t,n){if(n.ok){const e=n.imported;v({level:"info",event:"repo_sync.completed",outcome:"succeeded",fields:{repo:t.name,pushed:n.pushed,created:e.created,revisions:e.revisions,deleted:e.deleted,needs_merge:e.needsMerge,refused:e.refused}})}else v({level:"warn",event:"repo_sync.failed",outcome:"failed",fields:{repo:t.name,step:n.step,reason:n.reason}})}c(W,"report");function $(){return{created:0,revisions:0,deleted:0,needsMerge:[],refused:[]}}c($,"emptyImport");class _ extends Error{static{c(this,"StepError")}step;constructor(n,e){super(e),this.step=n}}async function x(t,n){try{return await n()}catch(e){throw e instanceof _?e:new _(t,e instanceof Error?e.message:String(e))}}c(x,"step");async function ue(t){const n=E();try{const e=await b(t.id),o=await le(e);if(o===null)return{ok:!1,step:"fetch",reason:`no checkout of ${t.name} with an origin remote has been seen by this runtime`};let r=$();const f=c(()=>x("import",async()=>{const a=await h(e,w),s=await h(e,g);if(a===null||s===a)return;const i=s?await m(e,g):new Map,l=await n.db(),u=await m(e,w),d=await J(l,t,i,u,async p=>await X(l,p));r={created:r.created+d.created,revisions:r.revisions+d.revisions,deleted:r.deleted+d.deleted,needsMerge:[...new Set([...r.needsMerge,...d.needsMerge])],refused:[...r.refused,...d.refused]},await j(e,a,u,i,new Set(d.refused.map(p=>p.path)),s)}),"importLocal");await f(),await x("export",async()=>{const a=await h(e,w),s=a?await m(e,w):null,i=await h(e,g),l=i?await m(e,g):null,u=await G(await n.db(),t,s,l);if(a?z(s,u):u.size===0)return;const d=await S(e,u,a?[a]:[],`crtr: export ${t.name}`);await y(e,w,d,a),await j(e,d,u,l??new Map,new Set(Q(s,l)),i)});for(let a=1;;a++){const s=await ae(e,o);if(!s.ok)return{ok:!1,step:"fetch",reason:s.reason};let i=await h(e,w);if(s.value!==null&&!(i&&await we(e,s.value)&&await I(e,s.value,i))){const u=await ee(e,o);if(!u.ok)return{ok:!1,step:"fetch",reason:u.reason};const d=u.value;i=await x("merge",async()=>{if(!i||await I(e,i,d))return await y(e,w,d,i),d;const p=await ne(e,i,d),C=ie(p?await m(e,p):new Map,await m(e,w),await m(e,fe));for(const O of C.refused)r.refused.push(O);const F=await S(e,C.tree,[i,d],`crtr: merge ${t.name}`);return await y(e,w,F,i),F})}if(await f(),i===null||i===s.value)return{ok:!0,pushed:!1,imported:r};const l=await re(e,o,i);if(l.ok)return{ok:!0,pushed:!0,imported:r};if(l.reason!=="rejected")return{ok:!1,step:"push",reason:l.reason};if(a>=L)return{ok:!1,step:"push",reason:`push rejected ${L} times`}}}catch(e){if(e instanceof _)return{ok:!1,step:e.step,reason:e.message};throw e}}c(ue,"syncRepo");async function j(t,n,e,o,r,f){if(r.size===0){await y(t,g,n,f);return}const a=new Map(e);for(const s of r)o.has(s)?a.set(s,o.get(s)):a.delete(s);f!==null&&z(o,a)||await y(t,g,await S(t,a,[],"crtr: imported baseline (some files pending)"),f)}c(j,"advanceImported");async function le(t){const n=R(t.dir,A);return D(n)&&(await B(n,"utf8")).trim()||null}c(le,"readUrl");async function we(t,n){return await h(t,n)!==null}c(we,"hasCommit");function z(t,n){if(t.size!==n.size)return!1;for(const[e,o]of t)if(n.get(e)!==o)return!1;return!0}c(z,"sameTree");export{ce as FIRST_FETCH_WAIT_MS,_e as noteNodeBooting,de as noteNodeWorking,xe as noteRepoDocumentsChanged,Me as startRepoSync,ue as syncRepo};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var
|
|
1
|
+
var d=Object.defineProperty;var f=(n,e)=>d(n,"name",{value:e,configurable:!0});import{join as l}from"node:path";import{CONFIG_FILE as p}from"../types.js";import{listDirs as g,pathExists as I,readJsonIfExists as b}from"./fs-utils.js";import{readPluginManifest as w}from"./manifest.js";import{awaitBundleSwap as y,bundleSwapInFlightElsewhere as h}from"./plugin-swap-lock.js";import{isCloudRole as a,requestPersonId as v}from"./canvas/person-state.js";import{materializedPluginsDir as k}from"./scoped-state/materialized-plugins.js";import{readCachedSettings as C}from"./scoped-state/person-store.js";import{pluginsDir as E}from"./scope.js";function F(n,e){const r=n==="user"?C("user").settings:b(l(e,p));return r&&r.plugins&&typeof r.plugins=="object"?r.plugins:{}}f(F,"pluginConfigForRoot");function S(n,e,r){const i=Object.keys(e);return i.every(t=>r.has(t))?[]:i.filter(t=>!r.has(t)&&h(n,t))}f(S,"swapsToWaitOut");function G(n,e){const r=n==="user"&&a()?v():void 0;if(n==="user"&&a()&&r===void 0)return[];const i=n!=="user"?l(e,"plugins"):r!==void 0?k(r):E("user");if(i===void 0||!I(i))return[];const t=F(n,e),u=m(n,i,t),s=S(e,t,new Set(u.map(o=>o.name)));if(s.length===0)return u;for(const o of s)y(e,o);return m(n,i,t)}f(G,"listInstalledPluginsInRoot");function m(n,e,r){const i=[];for(const t of g(e)){const u=l(e,t),s=w(u);if(!s)continue;const o=r[t],c=typeof o?.version=="string"?o.version:s.version;i.push({name:t,scope:n,root:u,manifest:s,enabled:typeof o?.enabled=="boolean"?o.enabled:!0,sourceMarketplace:typeof o?.source_marketplace=="string"?o.source_marketplace:void 0,version:c})}return i}f(m,"collectInstalledPlugins");export{G as listInstalledPluginsInRoot};
|
|
@@ -15,4 +15,4 @@ export interface PersistedKeybindings {
|
|
|
15
15
|
readonly overrides: SparseKeybindingOverrides<BindingId>;
|
|
16
16
|
readonly tmuxPassthrough: readonly BindingId[];
|
|
17
17
|
}
|
|
18
|
-
export declare function persistUserKeybindings(prospectiveOverrides: unknown, options?: PersistKeybindingsOptions): PersistedKeybindings
|
|
18
|
+
export declare function persistUserKeybindings(prospectiveOverrides: unknown, options?: PersistKeybindingsOptions): Promise<PersistedKeybindings>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var c=Object.defineProperty;var i=(n,e)=>c(n,"name",{value:e,configurable:!0});import{isDeepStrictEqual as
|
|
1
|
+
var c=Object.defineProperty;var i=(n,e)=>c(n,"name",{value:e,configurable:!0});import{isDeepStrictEqual as o}from"node:util";import{configPath as m,normalizeTmuxPassthrough as g,updateRawConfigAtomically as x}from"../config.js";import{normalizeSparseOverrides as b}from"./resolve.js";class l extends Error{static{i(this,"KeybindingConcurrentEditError")}latestKeybindings;latestTmuxPassthrough;constructor(e,t){super("keybindings changed on disk; reload before saving"),this.name="KeybindingConcurrentEditError",this.latestKeybindings=e,this.latestTmuxPassthrough=t}}async function O(n,e={}){const t=b(n),d=Object.hasOwn(e,"tmuxPassthrough"),u=g(e.tmuxPassthrough);let h=[];const a=m("user");if(a===null)throw new Error("user config path is unavailable");return await x("user",r=>{if(Object.hasOwn(e,"expectedKeybindings")&&!o(r.keybindings,e.expectedKeybindings)||Object.hasOwn(e,"expectedTmuxPassthrough")&&!o(r.tmux_passthrough,e.expectedTmuxPassthrough))throw new l(r.keybindings,r.tmux_passthrough);const s={...r};return delete s.canvasNav,Object.keys(t).length===0?delete s.keybindings:s.keybindings=t,d&&(u.length===0?delete s.tmux_passthrough:s.tmux_passthrough=u),h=g(s.tmux_passthrough),s}),Object.freeze({path:a,overrides:Object.freeze({...t}),tmuxPassthrough:Object.freeze([...h])})}i(O,"persistUserKeybindings");export{l as KeybindingConcurrentEditError,O as persistUserKeybindings};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
/** Idempotent post-layout migration. Reports paths only; never key contents. */
|
|
2
|
-
export declare function migrateLooseKeys(dryRun?: boolean): string[]
|
|
2
|
+
export declare function migrateLooseKeys(dryRun?: boolean): Promise<string[]>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var u=Object.defineProperty;var c=(
|
|
1
|
+
var u=Object.defineProperty;var c=(o,i)=>u(o,"name",{value:i,configurable:!0});import{existsSync as p,mkdirSync as f,readFileSync as d,renameSync as l}from"node:fs";import{join as a}from"node:path";import{layoutRoot as y}from"../layout.js";import{listAppEnvNames as A,setAppEnvVar as E}from"../profiles/app-env-store.js";async function $(o=!1){if(process.platform!=="darwin")return[];const i=y(),m=a(i,"runtime","set-aside","loose-keys"),t=[];for(const n of["exa.key","composio.key","secrets.json"]){const e=a(i,n);if(!p(e))continue;const s=a(m,n);if(n==="exa.key"&&!(await A("app:terminal")).includes("EXA_API_KEY")){const r=d(e,"utf8").trim();if(!r||r.includes("\0")){t.push(`${e}: invalid or empty; left untouched`);continue}o||await E("app:terminal","EXA_API_KEY",r),t.push(`${e}: imported EXA_API_KEY into app:terminal`)}if(p(s)){t.push(`${e}: destination already exists; left untouched`);continue}o||(f(m,{recursive:!0,mode:448}),l(e,s)),t.push(`${e}: moved to ${s}`)}return t}c($,"migrateLooseKeys");export{$ as migrateLooseKeys};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { CanvasDb } from '../canvas/db.js';
|
|
2
|
+
/** The Northlight team's principal in the directory's `relations` rows. A payer it holds is house-paid: its rows carry no account and bill $0. */
|
|
3
|
+
export declare const NORTHLIGHT_TEAM = "team:apofkzuloox7";
|
|
4
|
+
export interface BillingAccount {
|
|
5
|
+
/** The principal to invoice, or null when the payer is house-paid or has no holder. */
|
|
6
|
+
account: string | null;
|
|
7
|
+
/** Whether a row for this payer can be billed: false for a house-paid payer and for one with no holder. */
|
|
8
|
+
billable: boolean;
|
|
9
|
+
}
|
|
10
|
+
export declare function billingAccountOf(db: CanvasDb, payer: string): Promise<BillingAccount>;
|
|
11
|
+
/** The `app:<id>` payers whose holder (`ledger_holder`) is one of `holders` (a `user:<id>` or a `team:<id>`): the apps whose spend is that holder's. */
|
|
12
|
+
export declare function appsHeldBy(db: CanvasDb, holders: readonly string[]): Promise<string[]>;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
var t=Object.defineProperty;var a=(e,r)=>t(e,"name",{value:r,configurable:!0});const p="team:apofkzuloox7";async function c(e,r){const o=(await e.prepare("SELECT ledger_holder(?) AS holder").get(r)).holder;return o===null||o===p?{account:null,billable:!1}:{account:o,billable:!0}}a(c,"billingAccountOf");async function u(e,r){return(await e.prepare(`SELECT 'app:' || r.resource_id AS app FROM (SELECT DISTINCT resource_id FROM relations WHERE resource_type = 'app' AND relation = 'admin') r
|
|
2
|
+
WHERE ledger_holder('app:' || r.resource_id) = ANY(?::text[]) ORDER BY 1`).all(r)).map(l=>l.app)}a(u,"appsHeldBy");export{p as NORTHLIGHT_TEAM,u as appsHeldBy,c as billingAccountOf};
|
|
@@ -10,9 +10,9 @@ export interface WriteResult {
|
|
|
10
10
|
}
|
|
11
11
|
/** The take percentage of `ledger.take_pct`; 0 (the default) writes no take rows. */
|
|
12
12
|
export declare function takePct(): number;
|
|
13
|
-
/** Write one charge row
|
|
13
|
+
/** Write one charge row; the `charges` trigger (schema delta 007) adds it to `charge_totals`. A refused row is stored with
|
|
14
14
|
* usd 0 and never rolled up; a take row (written only while `ledger.take_pct` > 0) is stored and never rolled up. Inside a
|
|
15
15
|
* caller's `withCanvasWrite` it joins that transaction. */
|
|
16
16
|
export declare function writeCharge(input: ChargeInput): Promise<WriteResult>;
|
|
17
|
-
/** A stored row as the `Charge` shape (jsonb arrives as text). */
|
|
17
|
+
/** A stored row as the `Charge` shape (jsonb arrives as text from `charges`, as an object from a moved chunk). */
|
|
18
18
|
export declare function chargeOf(row: Record<string, unknown>): Charge;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var
|
|
1
|
+
var I=Object.defineProperty;var n=(e,r)=>I(e,"name",{value:r,configurable:!0});import{randomUUID as b}from"node:crypto";import{withCanvasWrite as k}from"../canvas/db.js";import{readConfig as w}from"../config.js";import{usageMonth as y}from"./months.js";const U=n((e,r)=>`receipt:${e}:${r}`,"receiptChargeId"),c="id, request, at, month, kind, what, units, usd, payer, funding, sub, grantee, node, run, provider, caused_by, vendor_ref, refused, account, billed_usd, usd_rolled_by_trigger",i="?, ?, ?, ?, ?, ?, ?::jsonb, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?::jsonb, ?, ?, true";function S(){const e=w("user").ledger?.take_pct??0;if(typeof e!="number"||!Number.isFinite(e)||e<0||e>100)throw new Error("ledger.take_pct must be a number from 0 to 100");return e}n(S,"takePct");async function D(e){const r=e.at??new Date,t=e.refused??null,o=e.id??b(),f=y(r),s=t?0:e.usd,a=S();return await k(async d=>{const u=n((g,m,N,O,h)=>[g,e.request??null,r.toISOString(),f,m,N,e.units==null?null:JSON.stringify(e.units),O,e.payer,h,e.sub??null,e.grantee,e.node??null,e.run??null,e.provider??null,e.causedBy??null,e.vendorRef??null,t===null?null:JSON.stringify(t),e.account??null,e.billedUsd??null],"row");if((await d.prepare(`INSERT INTO charges (${c}) VALUES (${i}) ON CONFLICT (id) DO NOTHING`).run(...u(o,e.kind,e.what,s,e.funding))).changes===0)return{written:!1,id:o,takeId:null};let l=null;return a>0&&t===null&&(e.kind==="model"||e.kind==="tool")&&s!==null&&s>0&&(l=`take:${o}`,await d.prepare(`INSERT INTO charges (${c}) VALUES (${i}) ON CONFLICT (id) DO NOTHING`).run(...u(l,"take",e.what,s*a/100,"take"))),{written:!0,id:o,takeId:l}})}n(D,"writeCharge");function j(e){const r=n(t=>typeof t=="string"?JSON.parse(t):typeof t=="object"?t:null,"json");return{...e,units:r(e.units),refused:r(e.refused)}}n(j,"chargeOf");export{j as chargeOf,U as receiptChargeId,S as takePct,D as writeCharge};
|
|
@@ -5,6 +5,8 @@ import type { Funding, Limit } from './types.js';
|
|
|
5
5
|
export interface CallCandidate {
|
|
6
6
|
scope: 'call';
|
|
7
7
|
payer: string;
|
|
8
|
+
/** The principal Northlight invoices for `payer`; absent means the function finds the payer's holder. */
|
|
9
|
+
account?: string | null;
|
|
8
10
|
funding: Funding;
|
|
9
11
|
sub: string | null;
|
|
10
12
|
grantee: string;
|
|
@@ -16,6 +18,7 @@ export interface CallCandidate {
|
|
|
16
18
|
export interface StartCandidate {
|
|
17
19
|
scope: 'start';
|
|
18
20
|
payer: string;
|
|
21
|
+
account?: string | null;
|
|
19
22
|
sub: string | null;
|
|
20
23
|
grantee: string;
|
|
21
24
|
}
|
|
@@ -27,7 +30,8 @@ export interface Refusal {
|
|
|
27
30
|
month: string;
|
|
28
31
|
reset_at: string;
|
|
29
32
|
}
|
|
30
|
-
/** The first limit (by id) that refuses `candidate` this month, or null. One
|
|
33
|
+
/** The first limit (by id) that refuses `candidate` this month, or null. One call to the SQL function `ledger_check`
|
|
34
|
+
* (schema delta 007), which holds the rule. */
|
|
31
35
|
export declare function findRefusal(candidate: Candidate, at?: Date): Promise<Refusal | null>;
|
|
32
36
|
/** The `user_action` a person can take for a limit of this source; absent for an operator limit. */
|
|
33
37
|
export declare function userActionOf(source: Limit['source']): 'raise_cap' | 'clear_limit' | undefined;
|
|
@@ -1,7 +1 @@
|
|
|
1
|
-
var
|
|
2
|
-
AND (l.funding IS NULL OR t.funding = l.funding) AND (l.grantee IS NULL OR t.grantee = l.grantee)
|
|
3
|
-
AND (l.provider IS NULL OR t.provider = l.provider) AND (l.sub IS NULL OR t.sub = l.sub))`;async function N(e,r=new Date){const t=m(r),s=e.sub??"",o=e.scope==="call"?`l.payer = ? AND (l.funding IS NULL OR l.funding = ?) AND (l.grantee IS NULL OR l.grantee = ?)
|
|
4
|
-
AND (l.provider IS NULL OR l.provider = ?) AND (l.sub IS NULL OR l.sub = ?)`:"l.payer = ? AND l.funding IS NULL AND l.provider IS NULL AND (l.grantee IS NULL OR l.grantee = ?) AND (l.sub IS NULL OR l.sub = ?)",u=e.scope==="call"?[e.payer,e.funding,e.grantee,e.provider??"",s]:[e.payer,e.grantee,s],i=await(await d()).prepareUncached(`SELECT * FROM (
|
|
5
|
-
SELECT l.id, l.payer, l.funding, l.grantee, l.provider, l.sub, l.usd_per_month, l.source, l.updated_at, ${g} AS spent
|
|
6
|
-
FROM limits l WHERE ${o}) q
|
|
7
|
-
WHERE q.spent >= q.usd_per_month ORDER BY q.id LIMIT 1`).get(t,...u);if(i===void 0)return null;const{spent:l,...p}=i;return{limit:p,usd:l,month:t,reset_at:L(t)}}n(N,"findRefusal");function f(e){return e==="grant_sync"?"raise_cap":e==="person"?"clear_limit":void 0}n(f,"userActionOf");function _(e){const{limit:r}=e,t=f(r.source);return new c(402,"cap_exhausted",`${r.payer} reached its monthly limit (${r.id})`,void 0,{limit:{id:r.id,payer:r.payer,filters:{funding:r.funding,grantee:r.grantee,provider:r.provider,sub:r.sub},usd_per_month:r.usd_per_month,source:r.source},usd:e.usd,reset_at:e.reset_at,spend_cap:r.usd_per_month,usd_equivalent:e.usd,...t===void 0?{}:{user_action:t}})}n(_,"refusalError");async function E(e,r){const t=await N(e,r);if(t!==null)throw _(t)}n(E,"check");const D=n(e=>({limit:e.limit.id,reason:`${e.limit.payer} reached ${e.limit.usd_per_month} USD this month (spent ${e.usd})`}),"refusedMark");export{E as check,N as findRefusal,_ as refusalError,D as refusedMark,f as userActionOf};
|
|
1
|
+
var i=Object.defineProperty;var r=(n,t)=>i(n,"name",{value:t,configurable:!0});import{openDb as u}from"../canvas/db.js";import{RunError as s}from"../runs/operations.js";import{usageMonth as c}from"./months.js";async function a(n,t=new Date){const e={...n,month:c(t)},o=await(await u()).prepare("SELECT ledger_check(?::jsonb) AS refusal").get(JSON.stringify(e));return typeof o?.refusal=="string"?JSON.parse(o.refusal):o?.refusal??null}r(a,"findRefusal");function d(n){return n==="grant_sync"?"raise_cap":n==="person"?"clear_limit":void 0}r(d,"userActionOf");function p(n){const{limit:t}=n,e=d(t.source);return new s(402,"cap_exhausted",`${t.payer??t.account} reached its monthly limit (${t.id})`,void 0,{limit:{id:t.id,payer:t.payer,account:t.account,filters:{account:t.account,funding:t.funding,grantee:t.grantee,provider:t.provider,sub:t.sub},usd_per_month:t.usd_per_month,source:t.source},usd:n.usd,reset_at:n.reset_at,spend_cap:t.usd_per_month,usd_equivalent:n.usd,...e===void 0?{}:{user_action:e}})}r(p,"refusalError");async function g(n,t){const e=await a(n,t);if(e!==null)throw p(e)}r(g,"check");const y=r(n=>({limit:n.limit.id,reason:`${n.limit.payer??n.limit.account} reached ${n.limit.usd_per_month} USD this month (spent ${n.usd})`}),"refusedMark");export{g as check,a as findRefusal,p as refusalError,y as refusedMark,d as userActionOf};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Charge } from './types.js';
|
|
2
|
+
/** The moved rows of a month (or of every month), read once per instance. A chunk row whose blob is missing throws: the rows are nowhere else. */
|
|
3
|
+
export declare class ChunkRows {
|
|
4
|
+
private readonly byMonth;
|
|
5
|
+
private all;
|
|
6
|
+
rows(month?: string): Promise<Charge[]>;
|
|
7
|
+
private load;
|
|
8
|
+
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
var f=Object.defineProperty;var u=(t,e)=>f(t,"name",{value:e,configurable:!0});import{zstdDecompressSync as l}from"node:zlib";import{blobStore as h}from"../blobs/index.js";import{openDb as b}from"../canvas/db.js";import{chargeOf as p}from"./charges.js";const g=["id","request","at","month","kind","what","units","usd","payer","funding","sub","grantee","node","run","provider","caused_by","vendor_ref","refused","account","billed_usd"];class _{static{u(this,"ChunkRows")}byMonth=new Map;all;rows(e){if(e===void 0)return this.all??=this.load(void 0);let n=this.byMonth.get(e);return n===void 0&&(n=this.load(e),this.byMonth.set(e,n)),n}async load(e){const n=await(await b()).prepareUncached(`SELECT blob_key FROM charge_chunks${e===void 0?"":" WHERE month = ?"} ORDER BY month, payer`).all(...e===void 0?[]:[e]);if(n.length===0)return[];const d=await h(),r=[];for(const{blob_key:o}of n){const s=await d.get(o);if(s===null)throw new Error(`charge chunk ${o} is recorded in charge_chunks but its blob is missing`);for(const i of l(s).toString("utf8").split(`
|
|
2
|
+
`)){if(i==="")continue;const c=JSON.parse(i);r.push(p(Object.fromEntries(g.map(a=>[a,c[a]??null]))))}}return r}}export{_ as ChunkRows};
|
|
@@ -4,5 +4,6 @@ export { payerOf, type Payer, type PayerCall } from './payer.js';
|
|
|
4
4
|
export { writeCharge, receiptChargeId, takePct, chargeOf, type WriteResult } from './charges.js';
|
|
5
5
|
export { check, findRefusal, refusalError, refusedMark, userActionOf, type Candidate, type CallCandidate, type StartCandidate, type Refusal } from './check.js';
|
|
6
6
|
export { upsertLimit, deleteLimit, listLimits } from './limits.js';
|
|
7
|
-
export { usageFor, listCharges, monthTotals, assertReference, type ChargePage, type ListFilter, type MonthTotals } from './read.js';
|
|
7
|
+
export { usageFor, listCharges, monthTotals, assertReference, type Reader, type ChargePage, type ListFilter, type MonthTotals } from './read.js';
|
|
8
8
|
export { REBUILD_ALL_TOTALS, rebuildTotalsFor } from './totals.js';
|
|
9
|
+
export { appsHeldBy } from './account.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export*from"./types.js";export*from"./months.js";import{payerOf as f}from"./payer.js";import{writeCharge as a,receiptChargeId as
|
|
1
|
+
export*from"./types.js";export*from"./months.js";import{payerOf as f}from"./payer.js";import{writeCharge as a,receiptChargeId as p,takePct as i,chargeOf as m}from"./charges.js";import{check as x,findRefusal as c,refusalError as u,refusedMark as L,userActionOf as d}from"./check.js";import{upsertLimit as g,deleteLimit as n,listLimits as O}from"./limits.js";import{usageFor as k,listCharges as A,monthTotals as C,assertReference as R}from"./read.js";import{REBUILD_ALL_TOTALS as B,rebuildTotalsFor as E}from"./totals.js";import{appsHeldBy as I}from"./account.js";export{B as REBUILD_ALL_TOTALS,I as appsHeldBy,R as assertReference,m as chargeOf,x as check,n as deleteLimit,c as findRefusal,A as listCharges,O as listLimits,C as monthTotals,f as payerOf,E as rebuildTotalsFor,p as receiptChargeId,u as refusalError,L as refusedMark,i as takePct,g as upsertLimit,k as usageFor,d as userActionOf,a as writeCharge};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type WriteResult } from './charges.js';
|
|
2
|
+
import type { ChargeInput } from './types.js';
|
|
3
|
+
export declare const DEFAULT_INFRA_FREE_USD = 50;
|
|
4
|
+
export declare const infraFreeUsd: () => number;
|
|
5
|
+
/** Write a `sandbox` or `storage` row whose `billed_usd` is the part of its usd above the account's monthly allowance. A row with no
|
|
6
|
+
* billable account (house-paid, or no holder) bills 0 and takes no lock. */
|
|
7
|
+
export declare function writeInfraCharge(input: ChargeInput & {
|
|
8
|
+
usd: number;
|
|
9
|
+
}, billable: boolean): Promise<WriteResult>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var h=Object.defineProperty;var t=(r,a)=>h(r,"name",{value:a,configurable:!0});import{withCanvasWrite as l}from"../canvas/db.js";import{readConfig as E}from"../config.js";import{writeCharge as d}from"./charges.js";import{usageMonth as g}from"./months.js";const _=50,i=t(r=>Math.round(r*1e6)/1e6,"round6"),p=t(()=>E("user").ledger?.infra_free_usd_per_month??_,"infraFreeUsd");async function D(r,a){const e=i(r.usd),o=r.account??null;if(!a||o===null)return await d({...r,usd:e,billedUsd:0});const c=p(),n=g(r.at??new Date);return await l(async s=>{await s.prepare("SELECT pg_advisory_xact_lock(hashtextextended(?, 0))").get(`infra:${o}:${n}`);const u=await s.prepare("SELECT COALESCE(sum(usd), 0) AS usd FROM charges WHERE account = ? AND month = ? AND kind IN ('sandbox', 'storage') AND id <> ?").get(o,n,r.id??""),m=Number(u.usd),f=i(Math.min(e,Math.max(0,m+e-c)));return await d({...r,usd:e,billedUsd:f})})}t(D,"writeInfraCharge");export{_ as DEFAULT_INFRA_FREE_USD,p as infraFreeUsd,D as writeInfraCharge};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
var d=Object.defineProperty;var
|
|
2
|
-
ON CONFLICT (id) DO UPDATE SET payer = excluded.payer, funding = excluded.funding, grantee = excluded.grantee,
|
|
3
|
-
provider = excluded.provider, sub = excluded.sub, usd_per_month = excluded.usd_per_month, source = excluded.source, updated_at = excluded.updated_at`).run(e.id,e.payer,e.funding,e.grantee,e.provider,e.sub,e.usd_per_month,e.source,e.updated_at)}),e}
|
|
1
|
+
var d=Object.defineProperty;var u=(n,e)=>d(n,"name",{value:e,configurable:!0});import{openDb as i,withCanvasWrite as t}from"../canvas/db.js";const a="id, payer, account, funding, grantee, provider, sub, usd_per_month, source, updated_at";async function c(n){if(!Number.isFinite(n.usd_per_month)||n.usd_per_month<0)throw new RangeError("usd_per_month must be a number of at least 0");const e={account:null,funding:null,grantee:null,provider:null,sub:null,...n,updated_at:new Date().toISOString()};return await t(async r=>{await r.prepare(`INSERT INTO limits (${a}) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
2
|
+
ON CONFLICT (id) DO UPDATE SET payer = excluded.payer, account = excluded.account, funding = excluded.funding, grantee = excluded.grantee,
|
|
3
|
+
provider = excluded.provider, sub = excluded.sub, usd_per_month = excluded.usd_per_month, source = excluded.source, updated_at = excluded.updated_at`).run(e.id,e.payer,e.account,e.funding,e.grantee,e.provider,e.sub,e.usd_per_month,e.source,e.updated_at)}),e}u(c,"upsertLimit");async function p(n){return await t(async e=>(await e.prepare("DELETE FROM limits WHERE id = ?").run(n)).changes>0)}u(p,"deleteLimit");async function l(n={}){const e=[],r=[];return n.source!==void 0&&(e.push("source = ?"),r.push(n.source)),n.payer!==void 0&&(e.push("payer = ?"),r.push(n.payer)),await(await i()).prepareUncached(`SELECT ${a} FROM limits${e.length?` WHERE ${e.join(" AND ")}`:""} ORDER BY id`).all(...r)}u(l,"listLimits");export{p as deleteLimit,l as listLimits,c as upsertLimit};
|
|
@@ -17,7 +17,7 @@ export type PayerCall =
|
|
|
17
17
|
route: 'subscription' | 'key';
|
|
18
18
|
sub: string;
|
|
19
19
|
}
|
|
20
|
-
/** A tool call over HTTP: the outbound token's `payer` claim (`app:<id>` when the app pays, else the person). */
|
|
20
|
+
/** A tool call over HTTP: the outbound token's `payer` claim (`app:<id>` when the app pays, else the person). Both are `bill`: the app's holder is invoiced for an app-paid call. */
|
|
21
21
|
| {
|
|
22
22
|
call: 'tool';
|
|
23
23
|
tokenPayer: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var t=Object.defineProperty;var n=(e,r)=>t(e,"name",{value:r,configurable:!0});function
|
|
1
|
+
var t=Object.defineProperty;var n=(e,r)=>t(e,"name",{value:r,configurable:!0});function p(e){switch(e.call){case"model":return e.route==="endpoint"?{payer:e.grantee,funding:"endpoint"}:{payer:e.sub,funding:e.route};case"tool":return e.tokenPayer.startsWith("app:")?{payer:e.tokenPayer,funding:"bill"}:{payer:e.sub,funding:"bill"};case"start":return e.grantPayer==="app"?{payer:e.grantee,funding:"endpoint"}:{payer:e.sub,funding:"bill"}}}n(p,"payerOf");export{p as payerOf};
|