@north-light/cli 0.3.561 → 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 +19 -19
- package/dist/daemon/api/viewer-presence.d.ts +20 -6
- package/dist/daemon/api/viewer-presence.js +2 -1
- package/dist/daemon/broker-signals/bus.d.ts +48 -11
- package/dist/daemon/broker-signals/bus.js +1 -1
- package/dist/daemon/cron/armed-context.js +1 -1
- package/dist/daemon/cron/lease-recovery.js +1 -1
- package/dist/daemon/cron/live-runs.d.ts +6 -0
- package/dist/daemon/cron/live-runs.js +1 -1
- package/dist/daemon/cron/run-socket.js +1 -1
- package/dist/daemon/cron-run.js +2 -2
- package/dist/daemon/crtrd-cli.js +1 -1
- package/dist/daemon/crtrd.d.ts +10 -0
- package/dist/daemon/crtrd.js +18 -17
- package/dist/daemon/delivery/run-delivery.d.ts +1 -1
- package/dist/daemon/delivery/run-delivery.js +1 -1
- package/dist/daemon/due-sources.d.ts +1 -1
- package/dist/daemon/due-sources.js +1 -1
- package/dist/daemon/due.js +7 -6
- package/dist/daemon/fleet.d.ts +6 -6
- package/dist/daemon/fleet.js +9 -9
- package/dist/daemon/park-activity.d.ts +2 -1
- package/dist/daemon/park-activity.js +1 -1
- package/dist/daemon/park-pending.d.ts +20 -13
- package/dist/daemon/park-pending.js +3 -1
- package/dist/daemon/profile-delete.js +1 -1
- package/dist/daemon/reconcilers/bash-deadline.d.ts +15 -10
- package/dist/daemon/reconcilers/bash-deadline.js +1 -3
- package/dist/daemon/reconcilers/broker-supervision.d.ts +13 -3
- package/dist/daemon/reconcilers/broker-supervision.js +4 -4
- package/dist/daemon/reconcilers/cron-lane.d.ts +0 -1
- package/dist/daemon/reconcilers/cron-lane.js +1 -1
- package/dist/daemon/reconcilers/fault-retry-backstop.d.ts +2 -9
- package/dist/daemon/reconcilers/fault-retry-backstop.js +1 -1
- package/dist/daemon/reconcilers/grant-effects.d.ts +8 -0
- package/dist/daemon/reconcilers/grant-effects.js +1 -0
- package/dist/daemon/reconcilers/grove-instance-sweep.d.ts +1 -3
- package/dist/daemon/reconcilers/grove-instance-sweep.js +1 -1
- package/dist/daemon/reconcilers/ledger-r2.d.ts +27 -0
- package/dist/daemon/reconcilers/ledger-r2.js +7 -0
- package/dist/daemon/reconcilers/ledger-sandbox.d.ts +55 -0
- package/dist/daemon/reconcilers/ledger-sandbox.js +9 -0
- package/dist/daemon/reconcilers/ledger-storage.d.ts +22 -0
- package/dist/daemon/reconcilers/ledger-storage.js +5 -0
- package/dist/daemon/reconcilers/live-obligation.d.ts +3 -2
- package/dist/daemon/reconcilers/live-obligation.js +1 -1
- package/dist/daemon/reconcilers/managed-worktree-sweep.d.ts +0 -5
- package/dist/daemon/reconcilers/managed-worktree-sweep.js +1 -1
- package/dist/daemon/reconcilers/node-deadline.d.ts +2 -1
- package/dist/daemon/reconcilers/node-deadline.js +1 -1
- package/dist/daemon/reconcilers/node-lifecycle/freeze-lane.d.ts +1 -2
- package/dist/daemon/reconcilers/node-lifecycle/freeze-lane.js +1 -1
- package/dist/daemon/reconcilers/node-lifecycle/remote-wake.d.ts +31 -0
- package/dist/daemon/reconcilers/node-lifecycle/remote-wake.js +1 -0
- package/dist/daemon/reconcilers/node-lifecycle/requested-stops.d.ts +5 -0
- package/dist/daemon/reconcilers/node-lifecycle/requested-stops.js +2 -0
- package/dist/daemon/reconcilers/node-lifecycle/tick.js +1 -1
- package/dist/daemon/reconcilers/pending-review-submit.js +1 -1
- package/dist/daemon/reconcilers/recipe-image.d.ts +49 -0
- package/dist/daemon/reconcilers/recipe-image.js +7 -0
- package/dist/daemon/reconcilers/row-claim.d.ts +19 -0
- package/dist/daemon/reconcilers/row-claim.js +2 -0
- package/dist/daemon/reconcilers/storage-due-work.d.ts +18 -3
- package/dist/daemon/reconcilers/storage-due-work.js +2 -1
- package/dist/daemon/reconcilers/storage-maintenance.d.ts +5 -13
- package/dist/daemon/reconcilers/storage-maintenance.js +1 -1
- package/dist/daemon/reconcilers/structured-request-lane.js +1 -1
- package/dist/daemon/reconcilers/throttled-lane.d.ts +11 -0
- package/dist/daemon/reconcilers/throttled-lane.js +1 -0
- package/dist/daemon/review/finish.js +1 -1
- package/dist/daemon/run-notices.d.ts +3 -0
- package/dist/daemon/run-notices.js +1 -1
- package/dist/daemon/runs/append-section.d.ts +4 -1
- package/dist/daemon/runs/append-section.js +2 -2
- package/dist/daemon/runs/observer.d.ts +3 -2
- package/dist/daemon/runs/observer.js +3 -2
- package/dist/daemon/runs/view-transport.d.ts +19 -0
- package/dist/daemon/runs/view-transport.js +1 -0
- package/dist/daemon/structured-requests/boot.d.ts +2 -1
- package/dist/daemon/structured-requests/boot.js +1 -1
- package/dist/daemon/structured-requests/effects.d.ts +4 -3
- package/dist/daemon/structured-requests/effects.js +1 -1
- package/dist/daemon/structured-requests/notifier.d.ts +2 -0
- package/dist/daemon/structured-requests/notifier.js +1 -1
- package/dist/daemon/structured-requests/sidecar.d.ts +4 -3
- package/dist/daemon/structured-requests/sidecar.js +1 -1
- package/dist/launcher/validate.js +1 -1
- package/dist/migrations/004-canvas-documents/index.js +2 -2
- package/dist/pi-extensions/broker-local.d.ts +3 -3
- package/dist/pi-extensions/broker-local.js +1 -2
- package/dist/pi-extensions/canvas-bash-valve.js +6 -6
- package/dist/pi-extensions/canvas-context-intro.js +2 -2
- package/dist/pi-extensions/canvas-elapsed.js +2 -2
- package/dist/pi-extensions/canvas-goal-capture.js +1 -1
- package/dist/pi-extensions/canvas-inbox-watcher.js +2 -2
- package/dist/pi-extensions/canvas-review-boundary.d.ts +11 -1
- package/dist/pi-extensions/canvas-review-boundary.js +3 -3
- package/dist/pi-extensions/canvas-stophook.js +1 -1
- package/dist/pi-extensions/canvas-structured-output.d.ts +5 -3
- package/dist/pi-extensions/canvas-structured-output.js +6 -11
- package/dist/pi-extensions/canvas-tool-guide.d.ts +9 -2
- package/dist/pi-extensions/canvas-tool-guide.js +6 -6
- package/dist/shared/inbox-entry-body.js +7 -7
- package/dist/types.d.ts +12 -0
- package/docs/sdk/release-notes.md +4 -0
- package/package.json +7 -4
- package/packages/crouter-identity/package.json +1 -1
- package/runtime.lock.json +13 -13
- package/scripts/git-credential-crtr +33 -0
- package/scripts/sandbox-bootstrap.sh +54 -0
- package/scripts/sandbox-start.mjs +320 -0
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.d.ts +0 -78
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.js +0 -1179
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.ts +0 -1406
- package/dist/core/conversation-store/file-store.d.ts +0 -37
- package/dist/core/conversation-store/file-store.js +0 -9
- package/dist/core/conversation-store/listener.d.ts +0 -4
- package/dist/core/conversation-store/listener.js +0 -8
- package/dist/core/scoped-state/profiles.d.ts +0 -27
- package/dist/core/scoped-state/profiles.js +0 -1
- package/dist/core/scoped-state/providers.d.ts +0 -24
- package/dist/core/scoped-state/providers.js +0 -1
- package/dist/core/scoped-state/settings.d.ts +0 -28
- package/dist/core/scoped-state/settings.js +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
var Y=Object.defineProperty;var o=(e,t)=>Y(e,"name",{value:t,configurable:!0});import{randomUUID as G}from"node:crypto";import{existsSync as W,realpathSync as b,rmSync as S,statSync as B}from"node:fs";import{join as A,resolve as E}from"node:path";import{SCHEMA_VERSION as R}from"../../types.js";import{profileSpace as g}from"../layout.js";import{PROFILE_PROJECT_MEMORY_VALUES as O}from"../../api/dto/profiles.js";import{userScopeRoot as c}from"../scope.js";import{ensureDir as k,nowIso as m}from"../fs-utils.js";import{deleteStoredProfile as Q,getStoredProfile as h,insertStoredProfile as M,listStoredProfiles as X,pausedProfileIds as I,profilePaused as ee,updateStoredProfile as te}from"../scoped-state/profiles.js";import{usage as f,notFound as d,ambiguous as D,general as L}from"../errors.js";import{withExclusiveDirectoryLock as re}from"../exclusive-lock.js";import{fuzzyMatchProfile as ne}from"./fuzzy-match.js";const N=/^[a-z0-9]+(?:-[a-z0-9]+)*-[0-9a-f]{8}$/,p="root-00000000",oe="root";function P(e){return e.grantee??"app:terminal"}o(P,"profileApp");function w(e,t){k(g(P(t),e).dir)}o(w,"scaffoldProfile");function y(e){if(!N.test(e))throw f(`invalid profile id: ${e}`,{received:e,next:"Profile ids look like <slug>-<8-hex-chars> (as printed by `crtr profile new`). Pass an exact id or a profile name, not a raw path."})}o(y,"assertSafeProfileId");function Ee(e){y(e);const t=h(c(),e);if(t===null)throw d(`profile not found: ${e}`,{received:e});return g(P(t.manifest),e).dir}o(Ee,"profileDir");function z(e){if(!Array.isArray(e))throw f("projects must be an array of {path} objects",{received:typeof e,field:"projects",next:'Pass entries like {"path": "/abs/dir"}.'});for(const t of e){if(typeof t!="object"||t===null||Array.isArray(t))throw f(`invalid project entry: ${JSON.stringify(t)}`,{field:"projects",next:'Every project is an object like {"path": "/abs/dir"}.'});const{path:r}=t;if(typeof r!="string"||r.trim()==="")throw f(`project entry has no path: ${JSON.stringify(t)}`,{field:"projects",next:"Give every project entry a non-empty directory path."})}}o(z,"assertProfileProjects");function ie(e){const t=O.join(", ");if(typeof e!="object"||e===null||Array.isArray(e))throw f("delivery_limits must be an object mapping owner handles to a level",{received:typeof e,field:"delivery_limits",next:`Pass e.g. {"crouter": "preview"} \u2014 each level is one of: ${t}.`});for(const[r,n]of Object.entries(e)){if(r.trim()==="")throw f("delivery_limits has an empty owner handle",{field:"delivery_limits",next:"Key each limit by an owner handle such as a repo handle or `user`, or exactly by `<type>:<handle>` such as `repo:crouter`."});if(typeof n!="string"||!O.includes(n))throw f(`invalid delivery limit for ${r}: ${JSON.stringify(n)}`,{received:String(n),field:"delivery_limits",next:`Set ${r} to one of: ${t}.`})}}o(ie,"assertDeliveryLimits");function ae(){return{entries:X(c()),unreadableIds:[]}}o(ae,"enumerateProfiles");function x(){return ae().entries}o(x,"listProfiles");function se(e){const t=x(),r=J(t,e,$);return r?{kind:"resolved",entry:r}:{kind:"absent"}}o(se,"lookupProfile");function C(e){y(e);const t=h(c(),e);if(t!==null)return t;throw d(`profile not found: ${e}`,{received:e,next:"Run `crtr profile list` to see available profiles."})}o(C,"loadExactProfileManifest");const $=o(e=>({profileId:e.profileId,name:e.manifest.name}),"entryCandidate");function J(e,t,r){if(N.test(t)){const i=e.find(a=>r(a).profileId===t);if(i!==void 0)return i}const n=e.filter(i=>r(i).name===t);if(n.length===1)return n[0];if(n.length>1){const i=n.map(a=>r(a).profileId);throw D(`profile name "${t}" matches ${i.length} profiles: ${i.join(", ")}`,{received:t,candidates:i,next:`Re-run with one exact profile id: ${i.join(", ")}.`})}return null}o(J,"findExactProfile");function T(e,t,r){const n=e.map(i=>`${r(i).profileId} (${r(i).name})`);return d(`profile not found: ${t}`,{received:t,available:n,next:n.length>0?`Re-run with one of the profiles on this host: ${n.join(", ")} \u2014 or create one with \`crtr profile new --name <name>\`.`:"No profiles exist on this host yet \u2014 create one with `crtr profile new --name <name>`."})}o(T,"profileNotFound");function fe(e){const t=se(e);if(t.kind==="resolved")return t.entry;throw T(x(),e,$)}o(fe,"loadProfileManifest");function Re(e){return le(x(),e,$)}o(Re,"resolveProfileOperand");function le(e,t,r){const n=J(e,t,r);if(n!==null)return n;const{match:i,tied:a}=ne(t,e.map(r));if(i!==null){const s=e.find(l=>r(l).profileId===i.profileId);return console.error(`crtr: no profile named "${t}" \u2014 using the closest match: ${r(s).name} (${r(s).profileId})`),s}if(a.length>1){const s=a.map(l=>`${l.profileId} (${l.name})`);throw D(`"${t}" is equally close to ${a.length} profiles: ${s.join(", ")}`,{received:t,candidates:a.map(l=>l.profileId),next:`Re-run with one exact profile id or name: ${s.join(", ")}.`})}throw T(e,t,r)}o(le,"matchProfileOperand");function U(){return A(c(),"profile-locks")}o(U,"locksDir");function v(e,t){return y(e),k(U()),re(A(U(),`${e}.lock`),t,{timeoutError:o(()=>L(`timed out waiting for the profile lock: ${e}`,{next:"Retry \u2014 another `crtr profile` command may be running concurrently on this profile."}),"timeoutError")})}o(v,"withProfileManifestLock");function F(e){const t=E(e);if(!W(t)||!B(t).isDirectory())throw f(`project directory does not exist or is not a directory: ${e}`,{received:e,next:"Pass an existing directory path."});try{return b(t)}catch{return t}}o(F,"resolveExistingProjectDir");function K(e){const t=new Set,r=[];for(const n of e)t.has(n.path)||(t.add(n.path),r.push(n));return r}o(K,"dedupeProjects");function ce(e){let t=e.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"");return t.length>40&&(t=t.slice(0,40).replace(/-+$/g,"")),t.length>0?t:"profile"}o(ce,"slugify");function ue(e){const t=ce(e);for(let r=0;r<20;r++){const n=G().replace(/-/g,"").slice(0,8),i=`${t}-${n}`;if(h(c(),i)===null)return i}throw L(`failed to generate a unique profile id for "${e}" after 20 attempts`)}o(ue,"generateProfileId");function Oe(){return v(p,()=>{const e=h(c(),p);if(e!==null)return w(p,e.manifest),e;const t={schema_version:R,name:oe,projects:[],grantee:"app:terminal",paused_at:null,created_at:m(),last_used_at:m()};return w(p,t),M(c(),{profileId:p,manifest:t}),{profileId:p,manifest:t}})}o(Oe,"ensureRootProfile");const q=/^[A-Za-z0-9][A-Za-z0-9_-]*$/;function H(e){return`CRTR_PROFILE_META_${e.toUpperCase().replace(/[^A-Z0-9]+/g,"_")}`}o(H,"metadataEnvName");function _(e){if(typeof e!="object"||e===null||Array.isArray(e))throw f("metadata must be a map of string keys to string values",{field:"metadata",next:'Pass an object, e.g. {"role": "support"}.'});const t=new Map;for(const[r,n]of Object.entries(e)){if(!q.test(r))throw f(`invalid metadata key: ${JSON.stringify(r)}`,{received:r,field:"metadata",next:"Keys start with a letter or digit, followed by letters, digits, `_`, or `-`."});if(typeof n!="string")throw f(`metadata value for ${r} must be a string`,{received:typeof n,field:"metadata",next:"Every metadata value is an env-var value \u2014 pass strings only."});if(n.includes("\0"))throw f(`metadata value for ${r} contains a NUL byte, which no OS accepts in an environment variable`,{field:"metadata",next:"Remove NUL bytes from the value and retry."});const i=H(r),a=t.get(i);if(a!==void 0)throw f(`metadata keys ${JSON.stringify(a)} and ${JSON.stringify(r)} both surface as ${i}`,{field:"metadata",next:"Rename or drop one \u2014 keys must stay distinct after uppercasing and `_`-folding."});t.set(i,r)}}o(_,"assertProfileMetadata");function Z(e){if(typeof e!="object"||e===null||Array.isArray(e))return{};const t={},r=new Set;for(const[n,i]of Object.entries(e)){if(typeof i!="string"||!q.test(n)||i.includes("\0"))continue;const a=H(n);r.has(a)||(r.add(a),t[n]=i)}return t}o(Z,"sanitizeProfileMetadata");function de(e,t=[],r={}){const n=e.trim();if(n==="")throw f("profile name must not be empty");r.metadata!==void 0&&_(r.metadata),z(t);const i=K(t.map(s=>({path:F(s.path)}))),a=ue(n);return v(a,()=>{const s={schema_version:R,name:n,projects:i,paused_at:null,...r.grantee===void 0?{}:{grantee:r.grantee},...r.defaultKind!==void 0?{default_kind:r.defaultKind}:{},...r.metadata!==void 0&&Object.keys(r.metadata).length>0?{metadata:{...r.metadata}}:{},created_at:m(),last_used_at:null};return w(a,s),M(c(),{profileId:a,manifest:s}),{profileId:a,manifest:s}})}o(de,"createProfile");function ke(e){if(!e.startsWith("app:")||e.length<=4)throw f("an app grantee is required");const t=`app-${e.slice(4)}`,r=x().filter(n=>n.manifest.name===t&&n.manifest.grantee===e);if(r.length>1)throw new Error(`duplicate default profile for ${e}`);return r[0]?r[0]:de(t,[],{grantee:e})}o(ke,"ensureAppProfile");function V(e){if(y(e),h(c(),e)===null)throw d(`profile not found: ${e}`,{received:e,next:"Run `crtr profile list` to see available profiles."})}o(V,"requireExistingProfile");function u(e,t){return V(e),v(e,()=>{const r=te(c(),e,t);if(r===null)throw d(`profile not found: ${e}`,{received:e});return r})}o(u,"mutateManifest");function Me(e){return u(e,t=>({...t,last_used_at:m()}))}o(Me,"updateProfileLastUsed");function pe(e){if(e==null||e==="")return null;try{return fe(e)}catch{return null}}o(pe,"loadProfileManifestOrNull");function De(e){if(e==null||e==="")return!1;try{return y(e),ee(c(),e)}catch{return!1}}o(De,"isProfilePaused");function Le(){return I(c())}o(Le,"pausedCanvasProfiles");function me(e){if(e.manifest.paused_at!==null)throw f(`profile "${e.manifest.name}" is paused and cannot start nodes`,{received:e.profileId,next:`Resume it with \`crtr profile resume ${e.profileId}\`.`})}o(me,"assertProfileEntryActive");function Ne(e){const t=pe(e);return t===null?null:(me(t),t)}o(Ne,"assertProfileActive");function ze(e){return u(e,t=>({...t,paused_at:t.paused_at??m()}))}o(ze,"pauseProfile");function Ce(e){let t=null;return{...u(e,n=>(t=n.paused_at,{...n,paused_at:null})),pausedAt:t}}o(Ce,"resumeProfile");function Je(e,t){return u(e,r=>({...r,default_kind:t}))}o(Je,"setProfileDefaultKind");function Te(e,t,r=[]){return _(t),u(e,n=>{const i={...Z(n.metadata),...t};for(const l of r)delete i[l];_(i);const{metadata:a,...s}=n;return{...s,...Object.keys(i).length>0?{metadata:i}:{}}})}o(Te,"updateProfileMetadata");function Ue(e){if(e===null||e==="")return{};try{return Z(C(e).manifest.metadata)}catch{return{}}}o(Ue,"readProfileMetadata");function Fe(e,t){const r=t.trim();if(r==="")throw f("profile name must not be empty");return u(e,i=>({...i,name:r}))}o(Fe,"renameProfile");function Ke(e,t){z([{path:t}]);const r=F(t);return u(e,i=>({...i,projects:K([...i.projects,{path:r}])}))}o(Ke,"addProfileProject");function qe(e,t,r){return ie({[t]:r}),u(e,n=>{const{[t]:i,...a}=n.delivery_limits??{},s=r==="content"?a:{...a,[t]:r},{delivery_limits:l,...j}=n;return Object.keys(s).length===0?j:{...j,delivery_limits:s}})}o(qe,"setProfileDeliveryLimit");function He(e,t){const r=E(t);let n=r;try{n=b(r)}catch{}return u(e,a=>{const s=a.projects.filter(l=>l.path!==n&&l.path!==r);if(s.length===a.projects.length)throw d(`project not found on profile: ${t}`,{received:t,next:`Current projects: ${a.projects.length>0?a.projects.map(l=>l.path).join(", "):"(none)"}.`});return{...a,projects:s}})}o(He,"removeProfileProject");function Ze(e){V(e),v(e,()=>{const t=g(P(C(e).manifest),e);if(!Q(c(),e))throw d(`profile not found: ${e}`,{received:e});S(t.dir,{recursive:!0,force:!0}),S(t.env,{force:!0})})}o(Ze,"deleteProfile");export{p as ROOT_PROFILE_ID,Ke as addProfileProject,ie as assertDeliveryLimits,Ne as assertProfileActive,me as assertProfileEntryActive,_ as assertProfileMetadata,z as assertProfileProjects,de as createProfile,Ze as deleteProfile,ke as ensureAppProfile,Oe as ensureRootProfile,De as isProfilePaused,x as listProfiles,C as loadExactProfileManifest,fe as loadProfileManifest,se as lookupProfile,le as matchProfileOperand,H as metadataEnvName,ze as pauseProfile,Le as pausedCanvasProfiles,Ee as profileDir,Ue as readProfileMetadata,He as removeProfileProject,Fe as renameProfile,Re as resolveProfileOperand,Ce as resumeProfile,Z as sanitizeProfileMetadata,Je as setProfileDefaultKind,qe as setProfileDeliveryLimit,Me as updateProfileLastUsed,Te as updateProfileMetadata,v as withProfileManifestLock};
|
|
1
|
+
var F=Object.defineProperty;var o=(e,t)=>F(e,"name",{value:t,configurable:!0});import{randomUUID as K}from"node:crypto";import{existsSync as q,realpathSync as b,rmSync as A,statSync as H}from"node:fs";import{resolve as E}from"node:path";import{SCHEMA_VERSION as S}from"../../types.js";import{profileSpace as v}from"../layout.js";import{PROFILE_PROJECT_MEMORY_VALUES as O}from"../../api/dto/profiles.js";import{ensureDir as Z,nowIso as m}from"../fs-utils.js";import{cachedPausedProfileIds as V,cachedProfilePaused as Y,getCachedProfile as d,listCachedProfiles as G,writeSettings as h}from"../scoped-state/person-store.js";import{usage as f,notFound as u,ambiguous as R,general as W}from"../errors.js";import{fuzzyMatchProfile as B}from"./fuzzy-match.js";const x=/^[a-z0-9]+(?:-[a-z0-9]+)*-[0-9a-f]{8}$/,p="root-00000000",Q="root";function w(e){return e.grantee??"app:terminal"}o(w,"profileApp");function g(e,t){Z(v(w(t),e).dir)}o(g,"scaffoldProfile");function P(e){if(!x.test(e))throw f(`invalid profile id: ${e}`,{received:e,next:"Profile ids look like <slug>-<8-hex-chars> (as printed by `crtr profile new`). Pass an exact id or a profile name, not a raw path."})}o(P,"assertSafeProfileId");function we(e){P(e);const t=d(e);if(t===null)throw u(`profile not found: ${e}`,{received:e});return v(w(t.manifest),e).dir}o(we,"profileDir");function M(e){if(!Array.isArray(e))throw f("projects must be an array of {path} objects",{received:typeof e,field:"projects",next:'Pass entries like {"path": "/abs/dir"}.'});for(const t of e){if(typeof t!="object"||t===null||Array.isArray(t))throw f(`invalid project entry: ${JSON.stringify(t)}`,{field:"projects",next:'Every project is an object like {"path": "/abs/dir"}.'});const{path:r}=t;if(typeof r!="string"||r.trim()==="")throw f(`project entry has no path: ${JSON.stringify(t)}`,{field:"projects",next:"Give every project entry a non-empty directory path."})}}o(M,"assertProfileProjects");function X(e){const t=O.join(", ");if(typeof e!="object"||e===null||Array.isArray(e))throw f("delivery_limits must be an object mapping owner handles to a level",{received:typeof e,field:"delivery_limits",next:`Pass e.g. {"crouter": "preview"} \u2014 each level is one of: ${t}.`});for(const[r,n]of Object.entries(e)){if(r.trim()==="")throw f("delivery_limits has an empty owner handle",{field:"delivery_limits",next:"Key each limit by an owner handle such as a repo handle or `user`, or exactly by `<type>:<handle>` such as `repo:crouter`."});if(typeof n!="string"||!O.includes(n))throw f(`invalid delivery limit for ${r}: ${JSON.stringify(n)}`,{received:String(n),field:"delivery_limits",next:`Set ${r} to one of: ${t}.`})}}o(X,"assertDeliveryLimits");function I(){return{entries:G(),unreadableIds:[]}}o(I,"enumerateProfiles");function y(){return I().entries}o(y,"listProfiles");function ee(e){const t=y(),r=C(t,e,$);return r?{kind:"resolved",entry:r}:{kind:"absent"}}o(ee,"lookupProfile");function k(e){P(e);const t=d(e);if(t!==null)return t;throw u(`profile not found: ${e}`,{received:e,next:"Run `crtr profile list` to see available profiles."})}o(k,"loadExactProfileManifest");const $=o(e=>({profileId:e.profileId,name:e.manifest.name}),"entryCandidate");function C(e,t,r){if(x.test(t)){const i=e.find(a=>r(a).profileId===t);if(i!==void 0)return i}const n=e.filter(i=>r(i).name===t);if(n.length===1)return n[0];if(n.length>1){const i=n.map(a=>r(a).profileId);throw R(`profile name "${t}" matches ${i.length} profiles: ${i.join(", ")}`,{received:t,candidates:i,next:`Re-run with one exact profile id: ${i.join(", ")}.`})}return null}o(C,"findExactProfile");function D(e,t,r){const n=e.map(i=>`${r(i).profileId} (${r(i).name})`);return u(`profile not found: ${t}`,{received:t,available:n,next:n.length>0?`Re-run with one of the profiles on this host: ${n.join(", ")} \u2014 or create one with \`crtr profile new --name <name>\`.`:"No profiles exist on this host yet \u2014 create one with `crtr profile new --name <name>`."})}o(D,"profileNotFound");function te(e){const t=ee(e);if(t.kind==="resolved")return t.entry;throw D(y(),e,$)}o(te,"loadProfileManifest");function ge(e){return re(y(),e,$)}o(ge,"resolveProfileOperand");function re(e,t,r){const n=C(e,t,r);if(n!==null)return n;const{match:i,tied:a}=B(t,e.map(r));if(i!==null){const s=e.find(c=>r(c).profileId===i.profileId);return console.error(`crtr: no profile named "${t}" \u2014 using the closest match: ${r(s).name} (${r(s).profileId})`),s}if(a.length>1){const s=a.map(c=>`${c.profileId} (${c.name})`);throw R(`"${t}" is equally close to ${a.length} profiles: ${s.join(", ")}`,{received:t,candidates:a.map(c=>c.profileId),next:`Re-run with one exact profile id or name: ${s.join(", ")}.`})}throw D(e,t,r)}o(re,"matchProfileOperand");function L(e){const t=E(e);if(!q(t)||!H(t).isDirectory())throw f(`project directory does not exist or is not a directory: ${e}`,{received:e,next:"Pass an existing directory path."});try{return b(t)}catch{return t}}o(L,"resolveExistingProjectDir");function N(e){const t=new Set,r=[];for(const n of e)t.has(n.path)||(t.add(n.path),r.push(n));return r}o(N,"dedupeProjects");function ne(e){let t=e.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"");return t.length>40&&(t=t.slice(0,40).replace(/-+$/g,"")),t.length>0?t:"profile"}o(ne,"slugify");function oe(e){const t=ne(e);for(let r=0;r<20;r++){const n=K().replace(/-/g,"").slice(0,8),i=`${t}-${n}`;if(d(i)===null)return i}throw W(`failed to generate a unique profile id for "${e}" after 20 attempts`)}o(oe,"generateProfileId");async function Pe(){const e=d(p);if(e!==null)return g(p,e.manifest),e;const t={schema_version:S,name:Q,projects:[],grantee:"app:terminal",paused_at:null,created_at:m(),last_used_at:m()};return g(p,t),await h(r=>r.profiles.some(n=>n.profileId===p)?[]:[{op:"profile.insert",profile:{profileId:p,manifest:t}}]),d(p)}o(Pe,"ensureRootProfile");const z=/^[A-Za-z0-9][A-Za-z0-9_-]*$/;function J(e){return`CRTR_PROFILE_META_${e.toUpperCase().replace(/[^A-Z0-9]+/g,"_")}`}o(J,"metadataEnvName");function _(e){if(typeof e!="object"||e===null||Array.isArray(e))throw f("metadata must be a map of string keys to string values",{field:"metadata",next:'Pass an object, e.g. {"role": "support"}.'});const t=new Map;for(const[r,n]of Object.entries(e)){if(!z.test(r))throw f(`invalid metadata key: ${JSON.stringify(r)}`,{received:r,field:"metadata",next:"Keys start with a letter or digit, followed by letters, digits, `_`, or `-`."});if(typeof n!="string")throw f(`metadata value for ${r} must be a string`,{received:typeof n,field:"metadata",next:"Every metadata value is an env-var value \u2014 pass strings only."});if(n.includes("\0"))throw f(`metadata value for ${r} contains a NUL byte, which no OS accepts in an environment variable`,{field:"metadata",next:"Remove NUL bytes from the value and retry."});const i=J(r),a=t.get(i);if(a!==void 0)throw f(`metadata keys ${JSON.stringify(a)} and ${JSON.stringify(r)} both surface as ${i}`,{field:"metadata",next:"Rename or drop one \u2014 keys must stay distinct after uppercasing and `_`-folding."});t.set(i,r)}}o(_,"assertProfileMetadata");function T(e){if(typeof e!="object"||e===null||Array.isArray(e))return{};const t={},r=new Set;for(const[n,i]of Object.entries(e)){if(typeof i!="string"||!z.test(n)||i.includes("\0"))continue;const a=J(n);r.has(a)||(r.add(a),t[n]=i)}return t}o(T,"sanitizeProfileMetadata");async function ie(e,t=[],r={}){const n=e.trim();if(n==="")throw f("profile name must not be empty");r.metadata!==void 0&&_(r.metadata),M(t);const i=N(t.map(c=>({path:L(c.path)}))),a=oe(n),s={schema_version:S,name:n,projects:i,paused_at:null,...r.grantee===void 0?{}:{grantee:r.grantee},...r.defaultKind!==void 0?{default_kind:r.defaultKind}:{},...r.metadata!==void 0&&Object.keys(r.metadata).length>0?{metadata:{...r.metadata}}:{},created_at:m(),last_used_at:null};return g(a,s),await h(()=>[{op:"profile.insert",profile:{profileId:a,manifest:s}}]),{profileId:a,manifest:s}}o(ie,"createProfile");async function $e(e){if(!e.startsWith("app:")||e.length<=4)throw f("an app grantee is required");const t=`app-${e.slice(4)}`,r=y().filter(n=>n.manifest.name===t&&n.manifest.grantee===e);if(r.length>1)throw new Error(`duplicate default profile for ${e}`);return r[0]?r[0]:await ie(t,[],{grantee:e})}o($e,"ensureAppProfile");function U(e){if(P(e),d(e)===null)throw u(`profile not found: ${e}`,{received:e,next:"Run `crtr profile list` to see available profiles."})}o(U,"requireExistingProfile");async function l(e,t){U(e);let r;return await h(n=>{const i=n.profiles.find(a=>a.profileId===e);if(i===void 0)throw u(`profile not found: ${e}`,{received:e});return r={profileId:e,manifest:t(structuredClone(i.manifest))},[{op:"profile.update",profile:r}]}),r}o(l,"mutateManifest");async function _e(e){return await l(e,t=>({...t,last_used_at:m()}))}o(_e,"updateProfileLastUsed");function ae(e){if(e==null||e==="")return null;try{return te(e)}catch{return null}}o(ae,"loadProfileManifestOrNull");function je(e){return e==null||e===""||!x.test(e)?!1:Y(e)}o(je,"isProfilePaused");function be(){return V()}o(be,"pausedCanvasProfiles");function se(e){if(e.manifest.paused_at!==null)throw f(`profile "${e.manifest.name}" is paused and cannot start nodes`,{received:e.profileId,next:`Resume it with \`crtr profile resume ${e.profileId}\`.`})}o(se,"assertProfileEntryActive");function Ae(e){const t=ae(e);return t===null?null:(se(t),t)}o(Ae,"assertProfileActive");async function Ee(e){return await l(e,t=>({...t,paused_at:t.paused_at??m()}))}o(Ee,"pauseProfile");async function Se(e){let t=null;return{...await l(e,n=>(t=n.paused_at,{...n,paused_at:null})),pausedAt:t}}o(Se,"resumeProfile");async function Oe(e,t){return await l(e,r=>({...r,default_kind:t}))}o(Oe,"setProfileDefaultKind");async function Re(e,t,r=[]){return _(t),await l(e,n=>{const i={...T(n.metadata),...t};for(const c of r)delete i[c];_(i);const{metadata:a,...s}=n;return{...s,...Object.keys(i).length>0?{metadata:i}:{}}})}o(Re,"updateProfileMetadata");function Me(e){if(e===null||e==="")return{};try{return T(k(e).manifest.metadata)}catch{return{}}}o(Me,"readProfileMetadata");async function ke(e,t){const r=t.trim();if(r==="")throw f("profile name must not be empty");return await l(e,i=>({...i,name:r}))}o(ke,"renameProfile");async function Ce(e,t){M([{path:t}]);const r=L(t);return await l(e,i=>({...i,projects:N([...i.projects,{path:r}])}))}o(Ce,"addProfileProject");async function De(e,t,r){return X({[t]:r}),await l(e,n=>{const{[t]:i,...a}=n.delivery_limits??{},s=r==="content"?a:{...a,[t]:r},{delivery_limits:c,...j}=n;return Object.keys(s).length===0?j:{...j,delivery_limits:s}})}o(De,"setProfileDeliveryLimit");async function Le(e,t){const r=E(t);let n=r;try{n=b(r)}catch{}return await l(e,a=>{const s=a.projects.filter(c=>c.path!==n&&c.path!==r);if(s.length===a.projects.length)throw u(`project not found on profile: ${t}`,{received:t,next:`Current projects: ${a.projects.length>0?a.projects.map(c=>c.path).join(", "):"(none)"}.`});return{...a,projects:s}})}o(Le,"removeProfileProject");async function Ne(e){U(e);const t=v(w(k(e).manifest),e);await h(r=>{if(!r.profiles.some(n=>n.profileId===e))throw u(`profile not found: ${e}`,{received:e});return[{op:"profile.delete",profileId:e}]}),A(t.dir,{recursive:!0,force:!0}),A(t.env,{force:!0})}o(Ne,"deleteProfile");export{p as ROOT_PROFILE_ID,Ce as addProfileProject,X as assertDeliveryLimits,Ae as assertProfileActive,se as assertProfileEntryActive,_ as assertProfileMetadata,M as assertProfileProjects,ie as createProfile,Ne as deleteProfile,$e as ensureAppProfile,Pe as ensureRootProfile,je as isProfilePaused,y as listProfiles,k as loadExactProfileManifest,te as loadProfileManifest,ee as lookupProfile,re as matchProfileOperand,J as metadataEnvName,Ee as pauseProfile,be as pausedCanvasProfiles,we as profileDir,Me as readProfileMetadata,Le as removeProfileProject,ke as renameProfile,ge as resolveProfileOperand,Se as resumeProfile,T as sanitizeProfileMetadata,Oe as setProfileDefaultKind,De as setProfileDeliveryLimit,_e as updateProfileLastUsed,Re as updateProfileMetadata};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var
|
|
1
|
+
var d=Object.defineProperty;var f=(e,i)=>d(e,"name",{value:i,configurable:!0});import{existsSync as n,readdirSync as l,renameSync as a,rmdirSync as p,statSync as m}from"node:fs";import{join as c}from"node:path";import{appSpace as h,appsRoot as y}from"../layout.js";function u(e,i,o){for(const r of l(e)){const t=c(e,r),s=c(i,r);if(!n(s)){a(t,s);continue}if(m(t).isDirectory()&&m(s).isDirectory()){u(t,s,o);try{p(t)}catch{o.push(t)}}else o.push(t)}}f(u,"mergeInto");function x(){const e=[];if(n(y()))for(const i of l(y(),{withFileTypes:!0})){if(!i.isDirectory()||!/^[a-zA-Z0-9][a-zA-Z0-9._-]*$/.test(i.name))continue;const o=h(i.name),r=c(o.root,"memory","profiles");if(n(r)){if(!n(o.profiles))a(r,o.profiles),e.push(`profile folders: moved ${r} to ${o.profiles}`);else{const t=[];u(r,o.profiles,t);try{p(r)}catch{}e.push(`profile folders: merged ${r} into ${o.profiles}`);for(const s of t)e.push(`profile folders: left ${s} in place; ${o.profiles} already holds that name`)}try{p(c(o.root,"memory"))}catch{}}}return e}f(x,"relocateProfileFolders");export{x as relocateProfileFolders};
|
|
@@ -1,35 +1,35 @@
|
|
|
1
|
-
var oe=Object.defineProperty;var l=(t,e)=>oe(t,"name",{value:e,configurable:!0});import{spawnSync as ie}from"node:child_process";import{existsSync as se,realpathSync as le}from"node:fs";import{basename as
|
|
1
|
+
var oe=Object.defineProperty;var l=(t,e)=>oe(t,"name",{value:e,configurable:!0});import{spawnSync as ie}from"node:child_process";import{existsSync as se,realpathSync as le}from"node:fs";import{basename as ae,resolve as ce,sep as S}from"node:path";import{createInterface as v}from"node:readline/promises";import{emitKeypressEvents as E}from"node:readline";import{listProfiles as A,loadProfileManifest as fe,resolveProfileOperand as ue,updateProfileLastUsed as P,createProfile as pe,addProfileProject as j,ensureRootProfile as D,ROOT_PROFILE_ID as O}from"./manifest.js";import{getDefaultProfileId as de,setDefaultProfileId as me,clearDefaultProfile as k}from"./default-binding.js";import{tildify as b}from"../fs-utils.js";import{stdoutColor as M}from"../output.js";import{inTmux as he}from"../runtime/placement-tmux.js";import{surfaceTmuxStyleArgs as $e}from"../runtime/surface-bg.js";import{formatBinding as w,matchesTerminalInput as we,resolveUserKeybindings as ge}from"../keybindings/index.js";const Ie=["crtr.profile.menu.abort","crtr.profile.menu.up","crtr.profile.menu.down","crtr.profile.menu.select","crtr.profile.menu.accept-default","crtr.profile.menu.slot.1","crtr.profile.menu.slot.2","crtr.profile.menu.slot.3","crtr.profile.menu.slot.4","crtr.profile.menu.slot.5","crtr.profile.menu.slot.6","crtr.profile.menu.slot.7","crtr.profile.menu.slot.8","crtr.profile.menu.slot.9","crtr.profile.menu.create","crtr.profile.menu.search-existing","crtr.profile.menu.use-root","crtr.profile.menu.set-default","crtr.profile.menu.add-directory","crtr.profile.menu.unpin","crtr.profile.menu.manage"],ye=["crtr.profile.search.abort","crtr.profile.search.back","crtr.profile.search.pick","crtr.profile.search.up","crtr.profile.search.down","crtr.profile.search.delete"];function L(t,e){return{input:e.ctrl===!0||e.meta===!0?e.name??t:t,upArrow:e.name==="up",downArrow:e.name==="down",return:e.name==="return"||e.name==="enter",escape:e.name==="escape",backspace:e.name==="backspace",ctrl:e.ctrl,meta:e.meta,shift:e.shift}}l(L,"profileRawInput");function N(t,e,r){return e.find(n=>we(t,n,r))??null}l(N,"firstProfileMatch");function xe(t,e){return N(t,Ie,e)}l(xe,"resolveProfileMenuAction");function Pe(t,e){return N(t,ye,e)}l(Pe,"resolveProfileSearchAction");function Y(t){const e=ce(t);if(!se(e))return e;try{return le(e)}catch{return e}}l(Y,"resolveCwd");function B(t,e){return!!(t===e||t.startsWith(e+S)||e.startsWith(t+S))}l(B,"projectCovers");function W(t,e){return t.manifest.projects.some(r=>B(e,r.path))}l(W,"profileCoversCwd");function T(t,e){return t===null?!1:e===null?!0:t>e}l(T,"isMoreRecent");function F(t){return t.reduce((e,r)=>T(r.manifest.last_used_at,e.manifest.last_used_at)?r:e)}l(F,"pickMostRecent");function U(t){const e=Y(t),r=A().filter(o=>W(o,e)),n=r.filter(o=>o.manifest.projects.some(u=>u.path===e)),s=de(e),i=s===null?null:r.find(o=>o.profileId===s)??null;return{covering:r,exact:n,pinnedId:s,pinned:i}}l(U,"profileSelectionState");function Ke(t){const{covering:e,exact:r,pinned:n}=U(t);if(n!==null)return n.profileId;if(r.length===1)return r[0].profileId;const s=r.length>0?r:e;return s.length>0?F(s).profileId:O}l(Ke,"selectProfileForCwdReadOnly");function H(){return!!process.stdin.isTTY&&!!process.stdout.isTTY}l(H,"isInteractive");const $=M.dim,x=M.bold,I=M.cyan;function be(t){return I(x(t))}l(be,"key");function K(t){if(t===null)return"never used";const e=Date.parse(t);if(Number.isNaN(e))return"used recently";const r=Math.max(0,Math.floor((Date.now()-e)/1e3));if(r<60)return"used just now";const n=Math.floor(r/60);if(n<60)return`used ${n}m ago`;const s=Math.floor(n/60);if(s<24)return`used ${s}h ago`;const i=Math.floor(s/24);if(i<30)return`used ${i}d ago`;const o=Math.floor(i/30);return o<12?`used ${o}mo ago`:`used ${Math.floor(o/12)}y ago`}l(K,"relativeUsed");function ve(t,e){const r=e!==void 0?` ${$(e)}
|
|
2
2
|
`:"";process.stdout.write(`
|
|
3
3
|
${x(t)}
|
|
4
4
|
${r}
|
|
5
|
-
`)}l(
|
|
6
|
-
`),n=r.length-1;let s=0;for(let i=0;i<n;i++){const o=r[i].replace(
|
|
5
|
+
`)}l(ve,"writeHeader");function Me(t){const e=t.manifest.projects.length,r=t.manifest.projects[0];return r===void 0?K(t.manifest.last_used_at):e>1?`${b(r.path)} \xB7 ${e} dirs total`:b(r.path)}l(Me,"purviewSummary");const q=I("\u25B8"),G=l(t=>t>0?`\x1B[${t}A\r`:"","cursorUp"),J="\x1B[0J",Te=/\u001b\[[0-9;]*m/g;function z(t){const e=process.stdout.columns??80,r=t.split(`
|
|
6
|
+
`),n=r.length-1;let s=0;for(let i=0;i<n;i++){const o=r[i].replace(Te,"").length;e>0&&o>e&&(s+=Math.ceil(o/e)-1)}return n+s}l(z,"blockRows");function _e(t,e,r,n,s,i){let o=`
|
|
7
7
|
${x(e)}
|
|
8
8
|
`;r!==void 0&&(o+=` ${$(r)}
|
|
9
9
|
`),o+=`
|
|
10
|
-
`;let u=0;for(const[h,m]of n.entries()){const
|
|
10
|
+
`;let u=0;for(const[h,m]of n.entries()){const c=m.bindingId===void 0?++u:0,d=m.bindingId!==void 0?w(t,m.bindingId):c<=9?w(t,`crtr.profile.menu.slot.${c}`):"",p=h===s?q:" ",f=m.detail!==""?" "+$(m.detail):"",a=m.isDefault?" "+I("\xB7 "+(m.defaultText??"default")):"";o+=` ${p} ${be(d)} ${m.label}${f}${a}
|
|
11
11
|
`}return i!==void 0&&(o+=`
|
|
12
12
|
${$(i)}
|
|
13
13
|
`),o+=`
|
|
14
|
-
${$(`${
|
|
15
|
-
`,o}l(
|
|
16
|
-
`),process.exit(130)),
|
|
17
|
-
`),!1)}l(V,"openProfileManager");const _=Symbol("profile-manager-ran");function X(t){return` ${
|
|
14
|
+
${$(`${w(t,"crtr.profile.menu.up")}/${w(t,"crtr.profile.menu.down")} move ${w(t,"crtr.profile.menu.select")} select ${w(t,"crtr.profile.menu.accept-default")} default ${w(t,"crtr.profile.menu.abort")} quit`)}
|
|
15
|
+
`,o}l(_e,"renderMenu");function Q(t,e,r,n,s={}){const i=[];n.forEach((u,h)=>{u.bindingId===void 0&&i.push(h)});let o=s.initialIndex??0;return new Promise(u=>{let h=0;const m=l(()=>{const p=_e(t,e,r,n,o,s.hint);process.stdout.write((h>0?G(h)+J:"")+p),h=z(p)},"draw"),c=l(()=>{process.stdin.off("keypress",d),process.stdin.isTTY&&process.stdin.setRawMode(!1),process.stdin.pause()},"cleanup"),d=l((p,f)=>{const a=xe(t,L(p,f));if(a==="crtr.profile.menu.abort"&&(c(),process.stdout.write(`
|
|
16
|
+
`),process.exit(130)),a==="crtr.profile.menu.up"){o=(o-1+n.length)%n.length,m();return}if(a==="crtr.profile.menu.down"){o=(o+1)%n.length,m();return}if(a==="crtr.profile.menu.select"){c(),u({index:o});return}if(a==="crtr.profile.menu.accept-default"){c(),u({index:s.initialIndex??0});return}if(a?.startsWith("crtr.profile.menu.slot.")){const g=Number.parseInt(a.slice(-1),10);g>=1&&g<=i.length&&(o=i[g-1],m());return}const y=n.findIndex(g=>g.bindingId!==void 0&&g.bindingId===a);if(y>=0){c(),u({index:y});return}a!==null&&s.actionBindingIds?.includes(a)===!0&&(c(),u({index:o,action:a}))},"onKey");E(process.stdin),process.stdin.isTTY&&process.stdin.setRawMode(!0),process.stdin.resume(),process.stdin.on("keypress",d),m()})}l(Q,"runMenu");function V(t){return he()?(ie("tmux",["display-popup","-E","-T"," profiles ","-w","90%","-h","85%","-d",t,...$e(),"crtr sys settings --page profiles"],{stdio:"inherit"}),!0):(process.stdout.write(` ${$("the profile manager needs tmux \u2014 run `crtr sys settings` instead")}
|
|
17
|
+
`),!1)}l(V,"openProfileManager");const _=Symbol("profile-manager-ran");function X(t){return` ${I("\u203A")} ${$(t)} `}l(X,"caret");function Ce(t){return`crtr: no profile covers ${t}, and this session is non-interactive \u2014 using the root profile.
|
|
18
18
|
Run \`crtr profile new --name <name> --project ${t}\` to create a dedicated profile, or pass --profile <id-or-name> next time.
|
|
19
|
-
`}l(
|
|
20
|
-
`))}l(Z,"offerAddDirToProfile");async function
|
|
21
|
-
`),null;let r="",n=0;const s=l(()=>r===""?e:e.filter(i=>i.manifest.name.toLowerCase().includes(r)||i.manifest.projects.some(o=>b(o.path).toLowerCase().includes(r))),"matchesOf");return new Promise(i=>{let o=0;const u=l(()=>{const
|
|
19
|
+
`}l(Ce,"rootProfileMessage");async function Re(t,e){const r=v({input:process.stdin,output:process.stdout});try{ve(`Profile "${t.manifest.name}" doesn't cover this directory`),await Z(r,t,e)}finally{r.close()}}l(Re,"promptAddDirToProfile");async function Z(t,e,r){const n=(await t.question(X(`add this directory to "${e.manifest.name}"? [Y/n]`))).trim().toLowerCase();n==="n"||n==="no"||(await j(e.profileId,r),process.stdout.write(` ${I("\u2713")} ${$(`added this directory to "${e.manifest.name}"`)}
|
|
20
|
+
`))}l(Z,"offerAddDirToProfile");async function Se(t){const e=[...A()].filter(i=>i.profileId!==O).sort((i,o)=>T(i.manifest.last_used_at,o.manifest.last_used_at)?-1:1);if(e.length===0)return process.stdout.write(` ${$("no existing profiles to select")}
|
|
21
|
+
`),null;let r="",n=0;const s=l(()=>r===""?e:e.filter(i=>i.manifest.name.toLowerCase().includes(r)||i.manifest.projects.some(o=>b(o.path).toLowerCase().includes(r))),"matchesOf");return new Promise(i=>{let o=0;const u=l(()=>{const c=s();n>=c.length&&(n=Math.max(0,c.length-1));let d=`
|
|
22
22
|
${x("Select an existing profile")}
|
|
23
23
|
`;if(d+=` ${$("across every profile, not just this directory")}
|
|
24
24
|
|
|
25
|
-
`,
|
|
26
|
-
`;else{const p=Math.max(...
|
|
25
|
+
`,c.length===0)d+=` ${$(`no match for "${r}"`)}
|
|
26
|
+
`;else{const p=Math.max(...c.map(f=>f.manifest.name.length));c.forEach((f,a)=>{d+=` ${a===n?q:" "} ${x(f.manifest.name.padEnd(p))} ${$(Me(f))}
|
|
27
27
|
`})}d+=`
|
|
28
|
-
${
|
|
29
|
-
`,d+=` ${$(`type to filter ${
|
|
30
|
-
`,process.stdout.write((o>0?
|
|
31
|
-
`),process.exit(130)),p==="crtr.profile.search.back"){h(),i(null);return}const f=s();if(p==="crtr.profile.search.pick"){f.length>0&&(h(),i(f[n].profileId));return}if(p==="crtr.profile.search.up"){f.length>0&&(n=(n-1+f.length)%f.length,u());return}if(p==="crtr.profile.search.down"){f.length>0&&(n=(n+1)%f.length,u());return}if(p==="crtr.profile.search.delete"){r=r.slice(0,-1),n=0,u();return}
|
|
32
|
-
`),i}l(ee,"createProfileHere");async function
|
|
33
|
-
`),f.profileId):(p.action==="crtr.profile.menu.set-default"?(
|
|
34
|
-
`)):p.action==="crtr.profile.menu.add-directory"&&(j(f.profileId,e),process.stdout.write(` ${
|
|
35
|
-
`)),f.profileId)}l(C,"promptPickProfileOrCreate");async function
|
|
28
|
+
${I("\u203A")} ${r}${$("\u2588")}
|
|
29
|
+
`,d+=` ${$(`type to filter ${w(t,"crtr.profile.search.up")}/${w(t,"crtr.profile.search.down")} move ${w(t,"crtr.profile.search.pick")} pick ${w(t,"crtr.profile.search.back")} back`)}
|
|
30
|
+
`,process.stdout.write((o>0?G(o)+J:"")+d),o=z(d)},"draw"),h=l(()=>{process.stdin.off("keypress",m),process.stdin.isTTY&&process.stdin.setRawMode(!1),process.stdin.pause()},"cleanup"),m=l((c,d)=>{const p=Pe(t,L(c,d));if(p==="crtr.profile.search.abort"&&(h(),process.stdout.write(`
|
|
31
|
+
`),process.exit(130)),p==="crtr.profile.search.back"){h(),i(null);return}const f=s();if(p==="crtr.profile.search.pick"){f.length>0&&(h(),i(f[n].profileId));return}if(p==="crtr.profile.search.up"){f.length>0&&(n=(n-1+f.length)%f.length,u());return}if(p==="crtr.profile.search.down"){f.length>0&&(n=(n+1)%f.length,u());return}if(p==="crtr.profile.search.delete"){r=r.slice(0,-1),n=0,u();return}c!==void 0&&c.length===1&&c>=" "&&d.ctrl!==!0&&(r+=c.toLowerCase(),n=0,u())},"onKey");E(process.stdin),process.stdin.isTTY&&process.stdin.setRawMode(!0),process.stdin.resume(),process.stdin.on("keypress",m),u()})}l(Se,"promptSelectExistingProfile");async function ee(t,e){const r=ae(e)||"profile",n=(await t.question(X(`name the new profile [${r}]`))).trim(),s=n!==""?n:r,i=(await pe(s,[{path:e}])).profileId;return process.stdout.write(` ${I("\u2713")} ${$(`created profile "${s}"`)}
|
|
32
|
+
`),i}l(ee,"createProfileHere");async function Ee(t,e){const r=[{label:"create a profile here",detail:"",bindingId:"crtr.profile.menu.create"},{label:"select an existing profile",detail:"",bindingId:"crtr.profile.menu.search-existing"},{label:$("use the root profile"),detail:"",bindingId:"crtr.profile.menu.use-root",isDefault:!0}];for(;;){const n=await Q(e,"No profile covers this directory",void 0,r,{initialIndex:2,actionBindingIds:["crtr.profile.menu.manage"],hint:`${w(e,"crtr.profile.menu.manage")}=manage profiles`});if(n.action==="crtr.profile.menu.manage"){if(V(t))return _;continue}if(n.index===0){const s=v({input:process.stdin,output:process.stdout});try{return await ee(s,t)}finally{s.close()}}if(n.index===1){const s=await Se(e);if(s===null)continue;const i=fe(s),o=v({input:process.stdin,output:process.stdout});try{await Z(o,i,t)}finally{o.close()}return i.profileId}return(await D()).profileId}}l(Ee,"promptCreateOrRoot");async function C(t,e,r,n,s){const i=[...t].sort((a,y)=>T(a.manifest.last_used_at,y.manifest.last_used_at)?-1:1),o=n!==null?i.find(a=>a.profileId===n)??null:null,u=o!==null?[o,...i.filter(a=>a!==o)]:i,h=Math.max(...u.map(a=>a.manifest.name.length)),m=u.map((a,y)=>{const g=a.manifest.projects.length,te=r?`${K(a.manifest.last_used_at)}${g>1?` \xB7 ${g} dirs total`:""}`:(()=>{const R=a.manifest.projects.find(ne=>B(e,ne.path))??a.manifest.projects[0];return g>1?`matches ${b(R.path)} \xB7 ${g} dirs total`:`matches ${b(R.path)}`})(),re=o!==null&&u[0]===o?"default (pinned)":"default";return{label:x(a.manifest.name.padEnd(h)),detail:te,isDefault:y===0,defaultText:re}});m.push({label:$("create a new profile here"),detail:"",bindingId:"crtr.profile.menu.create"});const c=["crtr.profile.menu.set-default","crtr.profile.menu.manage"];r||c.push("crtr.profile.menu.add-directory"),o!==null&&c.push("crtr.profile.menu.unpin");const d=[`${w(s,"crtr.profile.menu.set-default")}=set default`];r||d.push(`${w(s,"crtr.profile.menu.add-directory")}=add dir here`),o!==null&&d.push(`${w(s,"crtr.profile.menu.unpin")}=unpin`),d.push(`${w(s,"crtr.profile.menu.manage")}=manage profiles`);const p=await Q(s,r?"Choose a profile":"Select a profile",r?"Several profiles claim this directory as their project":"This directory falls under existing profile(s)",m,{actionBindingIds:c,hint:d.join(" ")});if(p.action==="crtr.profile.menu.manage")return V(e)?_:await C(t,e,r,n,s);if(p.index>=u.length){const a=v({input:process.stdin,output:process.stdout});try{return await ee(a,e)}finally{a.close()}}const f=u[p.index];return p.action==="crtr.profile.menu.unpin"?(await k(e),process.stdout.write(` ${I("\u2713")} ${$("cleared the default for this directory")}
|
|
33
|
+
`),f.profileId):(p.action==="crtr.profile.menu.set-default"?(await me(e,f.profileId),process.stdout.write(` ${I("\u2713")} ${$(`"${f.manifest.name}" is now the default here`)}
|
|
34
|
+
`)):p.action==="crtr.profile.menu.add-directory"&&(await j(f.profileId,e),process.stdout.write(` ${I("\u2713")} ${$(`added this directory to "${f.manifest.name}"`)}
|
|
35
|
+
`)),f.profileId)}l(C,"promptPickProfileOrCreate");async function qe(t,e,r=!1){const n=Y(t),s=ge();if(e!=null&&e!==""){const i=ue(e);return!W(i,n)&&H()&&await Re(i,n),await P(i.profileId),i.profileId}for(;;){const{covering:i,exact:o,pinnedId:u,pinned:h}=U(n);if(u!==null&&h===null&&await k(n),h!==null&&!r)return await P(h.profileId),h.profileId;if(!r&&h===null&&o.length===1)return await P(o[0].profileId),o[0].profileId;if(!H()){const d=o.length>0?o:i;if(d.length>0){const f=F(d);return await P(f.profileId),f.profileId}const p=await D();return process.stderr.write(Ce(n)),p.profileId}const m=h!==null?h.profileId:null,c=o.length>1?await C(o,n,!0,m,s):i.length>0?await C(i,n,!1,m,s):await Ee(n,s);if(c!==_)return await P(c),c}}l(qe,"selectProfileForCwd");export{W as profileCoversCwd,xe as resolveProfileMenuAction,Pe as resolveProfileSearchAction,qe as selectProfileForCwd,Ke as selectProfileForCwdReadOnly};
|
|
@@ -3,4 +3,4 @@ import type { ModelRegistry, ModelRuntime } from '@earendil-works/pi-coding-agen
|
|
|
3
3
|
* configured predicate shown by the setup Providers panel. */
|
|
4
4
|
export declare function isProviderCredentialConfigured(providerId: string, registry: ModelRegistry): boolean;
|
|
5
5
|
/** Whether any provider in the setup catalog has a usable configured credential. */
|
|
6
|
-
export declare function hasProviderCredential(runtime: ModelRuntime, registry: ModelRegistry): boolean
|
|
6
|
+
export declare function hasProviderCredential(runtime: ModelRuntime, registry: ModelRegistry): Promise<boolean>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var
|
|
1
|
+
var n=Object.defineProperty;var o=(e,r)=>n(e,"name",{value:r,configurable:!0});function d(e,r){return r.getProviderAuthStatus(e).configured}o(d,"isProviderCredentialConfigured");async function a(e,r){const i=new Set([...e.getProviders().map(t=>t.id),...r.getAll().map(t=>t.provider)]);for(const t of i)if(d(t,r))return!0;return!1}o(a,"hasProviderCredential");export{a as hasProviderCredential,d as isProviderCredentialConfigured};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { CrtrClient } from '../api/client.js';
|
|
1
2
|
/** The minimal shape of a Providers-panel row the removal router needs. */
|
|
2
3
|
export interface RemovableProviderRow {
|
|
3
4
|
providerId: string;
|
|
@@ -6,7 +7,5 @@ export interface RemovableProviderRow {
|
|
|
6
7
|
configured?: boolean;
|
|
7
8
|
label?: string;
|
|
8
9
|
}
|
|
9
|
-
/** Route a row's removal
|
|
10
|
-
|
|
11
|
-
* surface that as the notice. */
|
|
12
|
-
export declare function removeProviderRow(agentDir: string, row: RemovableProviderRow): Promise<string>;
|
|
10
|
+
/** Route a row's removal through the daemon and return the truthful panel notice. A managed account row removes that account only; a managed header row or a non-managed provider removes every credential for the provider. May throw (e.g. an unknown account) — callers surface that as the notice. */
|
|
11
|
+
export declare function removeProviderRow(client: CrtrClient, row: RemovableProviderRow): Promise<string>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var
|
|
1
|
+
var n=Object.defineProperty;var d=(a,e)=>n(a,"name",{value:e,configurable:!0});async function t(a,e){return e.managed&&e.label!==void 0?(await a.removeModelAuthAccount(e.providerId,e.label),`Removed ${e.name} account`):(await a.removeCredential(e.providerId),`Removed ${e.name}`)}d(t,"removeProviderRow");export{t as removeProviderRow};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var ue=Object.defineProperty;var a=(e,n)=>ue(e,"name",{value:n,configurable:!0});import{existsSync as g,readdirSync as W,readFileSync as S,rmSync as $,statSync as k}from"node:fs";import{join as d}from"node:path";import{validateCommandManifest as de}from"../../api/command-manifest/manifest.js";import{crtrHome as z}from"../canvas/paths.js";import{withCanvasWrite as G}from"../canvas/db.js";import{bundleVersion as ce,isInstalledGeneration as fe,recordCheckedGeneration as le}from"../command-plugins/bundle.js";import{readConfig as q,readState as pe,updateConfig as me,updateState as ve}from"../config.js";import{emitEvent as m}from"../events/emit.js";import{describeOutboundFailure as he,outboundFetch as we,outboundRefusal as V,OutboundError as ge}from"../events/outbound.js";import{withExclusiveDirectoryLockAsync as Z}from"../exclusive-lock.js";import{atomicWriteText as x,ensureDir as T,pathExists as $e}from"../fs-utils.js";import{reconcilePackages as L}from"../graph/package-reconcile.js";import{readPluginManifest as C}from"../manifest.js";import{bundleSwapLockPath as J}from"../plugin-swap-lock.js";import{pluginsDir as ye,userScopeRoot as K}from"../scope.js";import{listInstalledPlugins as be}from"../resolver.js";import{localGrants as j}from"../grants/mirror.js";import{ProviderError as c}from"./errors.js";const A="[A-Za-z0-9_-]{1,64}",_e=new RegExp(`^(${A}):(${A})$`),Q=new RegExp(`^${A}$`),Pe=3e4,X=3e4;function Y(e){const n=new Set;for(const r of e)if(r.status==="active")for(const{scope:t}of r.resolved_scopes){const o=_e.exec(t);o&&o[1]!=="crtr"&&n.add(o[1])}return[...n].sort()}a(Y,"providerIdsFromGrants");function v(e){return d(ye("user"),e)}a(v,"pluginRoot");function R(){return d(z(),"providers")}a(R,"providersRoot");function ee(e,n){return d(R(),e,`v${n}`)}a(ee,"majorDir");function B(e){if(!Q.test(e))throw new c("not_found",`"${e}" is not a provider id`,{param:"provider"})}a(B,"assertId");function E(){const e=q("user").runtime?.issuer;if(!e)throw new c("not_found","provider bundles need a directory-connected runtime");return e.replace(/\/+$/,"")}a(E,"directoryBase");async function ne(e,n){const r=`${E()}/providers/${encodeURIComponent(e)}/plugin${n.version!==void 0?`?version=${n.version}`:""}`;let t;try{t=await we("bundle_fetch",r,{headers:{Accept:"application/x-tar",...n.ifNoneMatch!==void 0?{"If-None-Match":n.ifNoneMatch}:{}},signal:AbortSignal.timeout(Pe)})}catch(i){return{status:"failed",message:`could not reach ${r}: ${i instanceof Error?i.message:String(i)}`,cause:i}}if(t.status===304){if(n.ifNoneMatch===void 0){const i=`HTTP 304 from ${r} without a conditional request`;return{status:"failed",message:i,cause:V("bundle_fetch",r,i)}}return{status:304}}if(t.status===404||t.status===410)return await t.body?.cancel().catch(()=>{}),{status:t.status===404?404:410,message:`HTTP ${t.status} from ${r}`};if(t.status<200||t.status>=300){await t.body?.cancel().catch(()=>{});{const i=`HTTP ${t.status} from ${r}`;return{status:"failed",message:i,cause:V("bundle_fetch",r,i)}}}let o;try{o=new Uint8Array(await t.arrayBuffer())}catch(i){return{status:"failed",message:`reading ${r} failed: ${i instanceof Error?i.message:String(i)}`,cause:new ge("bundle_fetch",r,i)}}const s=t.headers.get("etag");return{status:200,raw:o,...s!==null?{etag:s}:{}}}a(ne,"fetchProviderBundle");const I=new WeakSet;class M extends Error{static{a(this,"BundleInvalid")}issues;constructor(n,r){super(n),this.issues=r}}function re(e,n,r){if(r.provider===void 0)return"the archive carries no provider block";if(r.provider.id!==e)return`the archive is provider "${r.provider.id}", not "${e}"`;if(n!==void 0&&r.provider.major!==n)return`the archive is major ${r.provider.major}, not ${n}`;const t=["hooks","kinds","page_components","memory_extensions"].filter(o=>r[o]!==void 0);if(t.length>0)return`a provider bundle may not carry ${t.join(", ")}`}a(re,"wrongBundle");function D(e,n,r){m({level:"error",event:"daemon.providers.bundle_invalid",fields:{provider:e,...n!==void 0?{major:n}:{},...r instanceof M?{issues:r.issues}:{}},error:r})}a(D,"logInvalid");function te(e,n,r){m({level:"warn",event:"daemon.providers.bundle_fetch_failed",fields:{provider:e,...n!==void 0?{major:n}:{},message:r instanceof Error?r.message:String(r),...he(r instanceof Error?r.cause:void 0)}})}a(te,"logFailure");async function oe(){return import("../../commands/pkg/plugin-manage.js")}a(oe,"pluginManage");const y=new Map,b=a(e=>`${z()}\0${e}`,"installKey");function Se(e){const n=e,r=n?.code??n?.cause?.code;return typeof r=="string"&&/^[A-Z][A-Z0-9_]{1,30}$/.test(r)?`${r} on provider install directory`:e instanceof c&&e.message.includes("HTTP 404")?"directory returned HTTP 404":e instanceof c&&e.message.includes("HTTP 410")?"directory returned HTTP 410":"provider bundle could not be installed"}a(Se,"publicInstallCause");function Ee(e){if(h(e)===void 0)return y.get(b(e))??{status:"installing"}}a(Ee,"providerInstallState");function Ie(e){return new c("provider_unavailable",`provider "${e}" unavailable: ${Ee(e)?.error??"bundle installation pending"}`)}a(Ie,"unavailableProviderError");function h(e){const n=C(v(e));if(!(n?.provider===void 0||n.transport?.kind!=="http"&&n.transport?.kind!=="machine")&&$e(d(v(e),"commands.json"))){try{if(k(d(v(e),"commands.json")).size===0)return}catch{return}return{provider:n.provider,transport:n.transport.kind==="machine"?{kind:"machine"}:{kind:"http",endpoint:n.transport.endpoint}}}}a(h,"installedManifest");async function N(e,n,r=!1){const t=K();h(e)===void 0&&y.set(b(e),{status:"installing"});try{return T(d(t,"tmp")),await Z(J(t,e),async()=>{const o=v(e),s=C(o);if(s!==null&&s.provider===void 0)throw new c("provider_unavailable",`plugin "${e}" is installed and is not the directory's provider bundle`);const i=h(e)!==void 0;if(i&&r)return"unchanged";const f=i&&n?pe("user").plugins[e]?.etag:void 0,u=await ne(e,f!==void 0?{ifNoneMatch:f}:{});if(u.status===304)return"unchanged";if(u.status===404||u.status===410)throw new c("not_found",`the directory serves no provider "${e}" (${u.message})`,{param:"provider"});if(u.status==="failed")throw new c("provider_unavailable",`provider "${e}" bundle fetch failed: ${u.message}`,{cause:u.cause});const l=ce(u.raw);if(i&&fe(e,"user",o,l))return le("user",e,u.etag,{swapped:!1}),"unchanged";const{installPluginArchive:w}=await oe();try{await w(e,u.raw,{scope:"user",scopeRootPath:t,root:o,version:l,etag:u.etag,enable:!i,bundle:{endpoint:`${E()}/providers/${encodeURIComponent(e)}/plugin`},transport:{kind:"http",endpoint:E()},accept:a(p=>re(e,void 0,p),"accept")})}catch(p){D(e,void 0,p);const U=new c("not_found",`provider "${e}" served an invalid bundle: ${p instanceof Error?p.message:String(p)}`,{param:"provider"});throw I.add(U),U}try{await G(async p=>await L(p))}catch(p){m({level:"error",event:"daemon.providers.docs_reconcile_failed",fields:{provider:e},error:p})}return m({level:"info",event:"daemon.providers.bundle_installed",fields:{provider:e,version:l,replaced:i}}),y.delete(b(e)),i?"updated":"installed"},{timeoutMs:X,timeoutError:a(()=>new c("provider_unavailable",`timed out waiting for another process replacing plugin "${e}"`),"timeoutError")})}catch(o){throw h(e)===void 0&&y.set(b(e),{status:"install_failed",error:Se(o)}),o instanceof c?o:(m({level:"error",event:"daemon.providers.bundle_install_failed",fields:{provider:e},error:o}),Ie(e))}}a(N,"refreshInstalled");async function en(e){B(e),h(e)===void 0&&await N(e,!1,!0)}a(en,"ensureProviderBundle");async function nn(e,n){return B(e),n.version!==void 0&&h(e)?.provider.major!==n.version?O(e,n.version,n.conditional):N(e,n.conditional)}a(nn,"refreshProviderBundle");async function ae(e,n,r){const{validatePluginArchive:t}=await oe(),o=await t(r);if(o.bundle===void 0)throw new M(`provider "${e}" major ${n} bundle is invalid: ${o.issues.map(i=>i.message).join("; ")}`,o.issues);const s=re(e,n,o.bundle);if(s!==void 0)throw new M(`provider "${e}" major ${n} bundle is invalid: ${s}`,[]);if(o.bundle.transport===void 0)throw new M(`provider "${e}" major ${n} bundle declares no transport`,[]);return o.bundle}a(ae,"validateArchive");function Me(e){T(e),x(d(e,"retired"),`${new Date().toISOString()}
|
|
2
|
-
`),$(d(e,"bundle.tar"),{force:!0}),$(d(e,"etag"),{force:!0})}a(Me,"retire");function ie(e,n){return new c("provider_version_retired",`provider "${e}" major ${n} is retired`,{param:"version"})}a(ie,"retiredError");async function O(e,n,r){const t=ee(e,n),o=d(t,"bundle.tar"),s=g(o),i=s&&r&&g(d(t,"etag"))?S(d(t,"etag"),"utf8"):void 0,f=await ne(e,{version:n,...i!==void 0?{ifNoneMatch:i}:{}});if(f.status===304)return"unchanged";if(f.status===410)throw Me(t),m({level:"info",event:"daemon.providers.major_retired",fields:{provider:e,major:n}}),ie(e,n);if(f.status===404)throw new c("not_found",`provider "${e}" never served major ${n}`,{param:"version"});if(f.status==="failed")throw new c("provider_unavailable",`provider "${e}" major ${n} bundle fetch failed: ${f.message}`,{cause:f.cause});try{await ae(e,n,f.raw)}catch(l){D(e,n,l);const w=new c(s?"provider_unavailable":"not_found",l instanceof Error?l.message:String(l),{param:"version"});throw I.add(w),w}T(t),$(d(t,"retired"),{force:!0});const u=s&&Buffer.from(f.raw).equals(S(o));return u||x(o,f.raw),f.etag!==void 0?x(d(t,"etag"),f.etag):$(d(t,"etag"),{force:!0}),u?"unchanged":s?"updated":"installed"}a(O,"refreshPinned");function ke(){const e=[],n=R();if(!g(n))return e;for(const r of W(n)){if(!Q.test(r))continue;let t;try{t=W(d(n,r))}catch{continue}for(const o of t){const s=/^v([1-9][0-9]*)$/.exec(o);s&&g(d(n,r,o,"bundle.tar"))&&e.push([r,Number(s[1])])}}return e}a(ke,"cachedMajors");function xe(e){const n=de(e,{transport:"http",reservedCoreNames:new Set});if(n.manifest===void 0)throw new c("not_found","the provider bundle's commands.json no longer validates");return n.manifest}a(xe,"readCommands");const _=new Map,H=new Map;function Te(e,n){const r=k(n),t=`${r.ino}:${r.mtimeMs}:${r.size}`,o=H.get(e);if(o?.stamp===t)return o.commands;const s=xe(JSON.parse(S(n,"utf8")));return H.set(e,{stamp:t,commands:s}),s}a(Te,"installedCommands");async function rn(e,n){B(e);const r=h(e);if(n===void 0||r?.provider.major===n){if(r===void 0)throw new c("not_found",`provider "${e}" has no installed bundle`,{param:"provider"});const l=v(e),w=Te(e,d(l,"commands.json"));return{id:e,major:r.provider.major,provider:r.provider,commands:w,transport:r.transport,source:"installed",root:l}}if(!Number.isInteger(n)||n<1)throw new c("invalid_request","version must be an integer of at least 1",{param:"version"});const t=ee(e,n);if(g(d(t,"retired")))throw ie(e,n);const o=d(t,"bundle.tar");g(o)||await O(e,n,!1);const s=`${e}/${n}`,i=k(o),f=`${i.mtimeMs}:${i.size}`;let u=_.get(s)?.stamp===f?_.get(s).bundle:void 0;if(u===void 0){try{u=await ae(e,n,new Uint8Array(S(o)))}catch(l){throw D(e,n,l),new c("not_found",`provider "${e}" has no valid bundle for major ${n}`,{param:"version"})}_.set(s,{stamp:f,bundle:u})}return{id:e,major:n,provider:u.provider,commands:u.commands,transport:u.transport.kind==="machine"?{kind:"machine"}:{kind:"http",endpoint:u.transport.endpoint},source:"pinned"}}a(rn,"resolveProviderBundle");let P=null,F=!1;function Ce(e,n){return e?.provider?.id===n&&e.bundle?.endpoint===`${E()}/providers/${encodeURIComponent(n)}/plugin`}a(Ce,"isDirectoryBundle");async function se(e){return Y(await j()).includes(e)}a(se,"grantNames");async function je(e){await Z(J(K(),e),async()=>{if(!(await se(e)||!Ce(C(v(e)),e))){$(v(e),{recursive:!0,force:!0}),me("user",n=>{delete n.plugins[e]}),ve("user",n=>{delete n.plugins[e]}),$(d(R(),e),{recursive:!0,force:!0}),H.delete(e),y.delete(b(e));for(const n of[..._.keys()])n.startsWith(`${e}/`)&&_.delete(n);try{await G(async n=>await L(n))}catch(n){m({level:"error",event:"daemon.providers.docs_reconcile_failed",fields:{provider:e},error:n})}m({level:"info",event:"daemon.providers.bundle_uninstalled",fields:{provider:e}})}},{timeoutMs:X,timeoutError:a(()=>new c("provider_unavailable",`timed out waiting for another process replacing plugin "${e}"`),"timeoutError")})}a(je,"uninstallProvider");async function Ae(){if(!(await j()).every(e=>e.status!=="active")){for(const e of be("user"))if(!(e.manifest.provider===void 0||await se(e.name)))try{await je(e.name)}catch(n){m({level:"error",event:"daemon.providers.bundle_uninstall_failed",fields:{provider:e.name},error:n})}}}a(Ae,"uninstallDisconnected");async function Re(){if(!q("user").runtime?.issuer)return;const e=Y(await j());for(const n of e)try{await N(n,!0)}catch(r){r instanceof Object&&I.has(r)||te(n,void 0,r)}await Ae();for(const[n,r]of ke())try{await O(n,r,!0)}catch(t){if(t instanceof c&&t.code==="provider_version_retired"||t instanceof Object&&I.has(t))continue;te(n,r,t)}}a(Re,"syncOnce");function tn(){return P!==null?(F=!0,P):(P=(async()=>{try{do F=!1,await Re();while(F)}finally{P=null}})(),P)}a(tn,"syncProviderBundles");export{en as ensureProviderBundle,Y as providerIdsFromGrants,Ee as providerInstallState,nn as refreshProviderBundle,rn as resolveProviderBundle,tn as syncProviderBundles,Ie as unavailableProviderError};
|
|
1
|
+
var ue=Object.defineProperty;var a=(e,n)=>ue(e,"name",{value:n,configurable:!0});import{existsSync as g,readdirSync as W,readFileSync as S,rmSync as $,statSync as k}from"node:fs";import{join as d}from"node:path";import{validateCommandManifest as de}from"../../api/command-manifest/manifest.js";import{crtrHome as z}from"../canvas/paths.js";import{withCanvasWrite as G}from"../canvas/db.js";import{bundleVersion as ce,isInstalledGeneration as fe,recordCheckedGeneration as le}from"../command-plugins/bundle.js";import{readConfig as q,readState as pe,updateConfig as me,updateState as ve}from"../config.js";import{emitEvent as m}from"../events/emit.js";import{describeOutboundFailure as he,outboundFetch as we,outboundRefusal as V,OutboundError as ge}from"../events/outbound.js";import{withExclusiveDirectoryLockAsync as Z}from"../exclusive-lock.js";import{atomicWriteText as x,ensureDir as T,pathExists as $e}from"../fs-utils.js";import{reconcilePackages as L}from"../graph/package-reconcile.js";import{readPluginManifest as C}from"../manifest.js";import{bundleSwapLockPath as J}from"../plugin-swap-lock.js";import{pluginsDir as ye,userScopeRoot as K}from"../scope.js";import{listInstalledPlugins as be}from"../resolver.js";import{localGrants as j}from"../grants/mirror.js";import{ProviderError as c}from"./errors.js";const A="[A-Za-z0-9_-]{1,64}",_e=new RegExp(`^(${A}):(${A})$`),Q=new RegExp(`^${A}$`),Pe=3e4,X=3e4;function Y(e){const n=new Set;for(const r of e)if(r.status==="active")for(const{scope:t}of r.resolved_scopes){const o=_e.exec(t);o&&o[1]!=="crtr"&&n.add(o[1])}return[...n].sort()}a(Y,"providerIdsFromGrants");function v(e){return d(ye("user"),e)}a(v,"pluginRoot");function R(){return d(z(),"providers")}a(R,"providersRoot");function ee(e,n){return d(R(),e,`v${n}`)}a(ee,"majorDir");function B(e){if(!Q.test(e))throw new c("not_found",`"${e}" is not a provider id`,{param:"provider"})}a(B,"assertId");function E(){const e=q("user").runtime?.issuer;if(!e)throw new c("not_found","provider bundles need a directory-connected runtime");return e.replace(/\/+$/,"")}a(E,"directoryBase");async function ne(e,n){const r=`${E()}/providers/${encodeURIComponent(e)}/plugin${n.version!==void 0?`?version=${n.version}`:""}`;let t;try{t=await we("bundle_fetch",r,{headers:{Accept:"application/x-tar",...n.ifNoneMatch!==void 0?{"If-None-Match":n.ifNoneMatch}:{}},signal:AbortSignal.timeout(Pe)})}catch(i){return{status:"failed",message:`could not reach ${r}: ${i instanceof Error?i.message:String(i)}`,cause:i}}if(t.status===304){if(n.ifNoneMatch===void 0){const i=`HTTP 304 from ${r} without a conditional request`;return{status:"failed",message:i,cause:V("bundle_fetch",r,i)}}return{status:304}}if(t.status===404||t.status===410)return await t.body?.cancel().catch(()=>{}),{status:t.status===404?404:410,message:`HTTP ${t.status} from ${r}`};if(t.status<200||t.status>=300){await t.body?.cancel().catch(()=>{});{const i=`HTTP ${t.status} from ${r}`;return{status:"failed",message:i,cause:V("bundle_fetch",r,i)}}}let o;try{o=new Uint8Array(await t.arrayBuffer())}catch(i){return{status:"failed",message:`reading ${r} failed: ${i instanceof Error?i.message:String(i)}`,cause:new ge("bundle_fetch",r,i)}}const s=t.headers.get("etag");return{status:200,raw:o,...s!==null?{etag:s}:{}}}a(ne,"fetchProviderBundle");const I=new WeakSet;class M extends Error{static{a(this,"BundleInvalid")}issues;constructor(n,r){super(n),this.issues=r}}function re(e,n,r){if(r.provider===void 0)return"the archive carries no provider block";if(r.provider.id!==e)return`the archive is provider "${r.provider.id}", not "${e}"`;if(n!==void 0&&r.provider.major!==n)return`the archive is major ${r.provider.major}, not ${n}`;const t=["hooks","kinds","page_components","memory_extensions"].filter(o=>r[o]!==void 0);if(t.length>0)return`a provider bundle may not carry ${t.join(", ")}`}a(re,"wrongBundle");function D(e,n,r){m({level:"error",event:"daemon.providers.bundle_invalid",fields:{provider:e,...n!==void 0?{major:n}:{},...r instanceof M?{issues:r.issues}:{}},error:r})}a(D,"logInvalid");function te(e,n,r){m({level:"warn",event:"daemon.providers.bundle_fetch_failed",fields:{provider:e,...n!==void 0?{major:n}:{},message:r instanceof Error?r.message:String(r),...he(r instanceof Error?r.cause:void 0)}})}a(te,"logFailure");async function oe(){return import("../../commands/pkg/plugin-manage.js")}a(oe,"pluginManage");const y=new Map,b=a(e=>`${z()}\0${e}`,"installKey");function Se(e){const n=e,r=n?.code??n?.cause?.code;return typeof r=="string"&&/^[A-Z][A-Z0-9_]{1,30}$/.test(r)?`${r} on provider install directory`:e instanceof c&&e.message.includes("HTTP 404")?"directory returned HTTP 404":e instanceof c&&e.message.includes("HTTP 410")?"directory returned HTTP 410":"provider bundle could not be installed"}a(Se,"publicInstallCause");function Ee(e){if(h(e)===void 0)return y.get(b(e))??{status:"installing"}}a(Ee,"providerInstallState");function Ie(e){return new c("provider_unavailable",`provider "${e}" unavailable: ${Ee(e)?.error??"bundle installation pending"}`)}a(Ie,"unavailableProviderError");function h(e){const n=C(v(e));if(!(n?.provider===void 0||n.transport?.kind!=="http"&&n.transport?.kind!=="machine")&&$e(d(v(e),"commands.json"))){try{if(k(d(v(e),"commands.json")).size===0)return}catch{return}return{provider:n.provider,transport:n.transport.kind==="machine"?{kind:"machine"}:{kind:"http",endpoint:n.transport.endpoint}}}}a(h,"installedManifest");async function N(e,n,r=!1){const t=K();h(e)===void 0&&y.set(b(e),{status:"installing"});try{return T(d(t,"tmp")),await Z(J(t,e),async()=>{const o=v(e),s=C(o);if(s!==null&&s.provider===void 0)throw new c("provider_unavailable",`plugin "${e}" is installed and is not the directory's provider bundle`);const i=h(e)!==void 0;if(i&&r)return"unchanged";const f=i&&n?pe("user").plugins[e]?.etag:void 0,u=await ne(e,f!==void 0?{ifNoneMatch:f}:{});if(u.status===304)return"unchanged";if(u.status===404||u.status===410)throw new c("not_found",`the directory serves no provider "${e}" (${u.message})`,{param:"provider"});if(u.status==="failed")throw new c("provider_unavailable",`provider "${e}" bundle fetch failed: ${u.message}`,{cause:u.cause});const l=ce(u.raw);if(i&&fe(e,"user",o,l))return await le("user",e,u.etag,{swapped:!1}),"unchanged";const{installPluginArchive:w}=await oe();try{await w(e,u.raw,{scope:"user",scopeRootPath:t,root:o,version:l,etag:u.etag,enable:!i,bundle:{endpoint:`${E()}/providers/${encodeURIComponent(e)}/plugin`},transport:{kind:"http",endpoint:E()},accept:a(p=>re(e,void 0,p),"accept")})}catch(p){D(e,void 0,p);const U=new c("not_found",`provider "${e}" served an invalid bundle: ${p instanceof Error?p.message:String(p)}`,{param:"provider"});throw I.add(U),U}try{await G(async p=>await L(p))}catch(p){m({level:"error",event:"daemon.providers.docs_reconcile_failed",fields:{provider:e},error:p})}return m({level:"info",event:"daemon.providers.bundle_installed",fields:{provider:e,version:l,replaced:i}}),y.delete(b(e)),i?"updated":"installed"},{timeoutMs:X,timeoutError:a(()=>new c("provider_unavailable",`timed out waiting for another process replacing plugin "${e}"`),"timeoutError")})}catch(o){throw h(e)===void 0&&y.set(b(e),{status:"install_failed",error:Se(o)}),o instanceof c?o:(m({level:"error",event:"daemon.providers.bundle_install_failed",fields:{provider:e},error:o}),Ie(e))}}a(N,"refreshInstalled");async function en(e){B(e),h(e)===void 0&&await N(e,!1,!0)}a(en,"ensureProviderBundle");async function nn(e,n){return B(e),n.version!==void 0&&h(e)?.provider.major!==n.version?O(e,n.version,n.conditional):N(e,n.conditional)}a(nn,"refreshProviderBundle");async function ae(e,n,r){const{validatePluginArchive:t}=await oe(),o=await t(r);if(o.bundle===void 0)throw new M(`provider "${e}" major ${n} bundle is invalid: ${o.issues.map(i=>i.message).join("; ")}`,o.issues);const s=re(e,n,o.bundle);if(s!==void 0)throw new M(`provider "${e}" major ${n} bundle is invalid: ${s}`,[]);if(o.bundle.transport===void 0)throw new M(`provider "${e}" major ${n} bundle declares no transport`,[]);return o.bundle}a(ae,"validateArchive");function Me(e){T(e),x(d(e,"retired"),`${new Date().toISOString()}
|
|
2
|
+
`),$(d(e,"bundle.tar"),{force:!0}),$(d(e,"etag"),{force:!0})}a(Me,"retire");function ie(e,n){return new c("provider_version_retired",`provider "${e}" major ${n} is retired`,{param:"version"})}a(ie,"retiredError");async function O(e,n,r){const t=ee(e,n),o=d(t,"bundle.tar"),s=g(o),i=s&&r&&g(d(t,"etag"))?S(d(t,"etag"),"utf8"):void 0,f=await ne(e,{version:n,...i!==void 0?{ifNoneMatch:i}:{}});if(f.status===304)return"unchanged";if(f.status===410)throw Me(t),m({level:"info",event:"daemon.providers.major_retired",fields:{provider:e,major:n}}),ie(e,n);if(f.status===404)throw new c("not_found",`provider "${e}" never served major ${n}`,{param:"version"});if(f.status==="failed")throw new c("provider_unavailable",`provider "${e}" major ${n} bundle fetch failed: ${f.message}`,{cause:f.cause});try{await ae(e,n,f.raw)}catch(l){D(e,n,l);const w=new c(s?"provider_unavailable":"not_found",l instanceof Error?l.message:String(l),{param:"version"});throw I.add(w),w}T(t),$(d(t,"retired"),{force:!0});const u=s&&Buffer.from(f.raw).equals(S(o));return u||x(o,f.raw),f.etag!==void 0?x(d(t,"etag"),f.etag):$(d(t,"etag"),{force:!0}),u?"unchanged":s?"updated":"installed"}a(O,"refreshPinned");function ke(){const e=[],n=R();if(!g(n))return e;for(const r of W(n)){if(!Q.test(r))continue;let t;try{t=W(d(n,r))}catch{continue}for(const o of t){const s=/^v([1-9][0-9]*)$/.exec(o);s&&g(d(n,r,o,"bundle.tar"))&&e.push([r,Number(s[1])])}}return e}a(ke,"cachedMajors");function xe(e){const n=de(e,{transport:"http",reservedCoreNames:new Set});if(n.manifest===void 0)throw new c("not_found","the provider bundle's commands.json no longer validates");return n.manifest}a(xe,"readCommands");const _=new Map,H=new Map;function Te(e,n){const r=k(n),t=`${r.ino}:${r.mtimeMs}:${r.size}`,o=H.get(e);if(o?.stamp===t)return o.commands;const s=xe(JSON.parse(S(n,"utf8")));return H.set(e,{stamp:t,commands:s}),s}a(Te,"installedCommands");async function rn(e,n){B(e);const r=h(e);if(n===void 0||r?.provider.major===n){if(r===void 0)throw new c("not_found",`provider "${e}" has no installed bundle`,{param:"provider"});const l=v(e),w=Te(e,d(l,"commands.json"));return{id:e,major:r.provider.major,provider:r.provider,commands:w,transport:r.transport,source:"installed",root:l}}if(!Number.isInteger(n)||n<1)throw new c("invalid_request","version must be an integer of at least 1",{param:"version"});const t=ee(e,n);if(g(d(t,"retired")))throw ie(e,n);const o=d(t,"bundle.tar");g(o)||await O(e,n,!1);const s=`${e}/${n}`,i=k(o),f=`${i.mtimeMs}:${i.size}`;let u=_.get(s)?.stamp===f?_.get(s).bundle:void 0;if(u===void 0){try{u=await ae(e,n,new Uint8Array(S(o)))}catch(l){throw D(e,n,l),new c("not_found",`provider "${e}" has no valid bundle for major ${n}`,{param:"version"})}_.set(s,{stamp:f,bundle:u})}return{id:e,major:n,provider:u.provider,commands:u.commands,transport:u.transport.kind==="machine"?{kind:"machine"}:{kind:"http",endpoint:u.transport.endpoint},source:"pinned"}}a(rn,"resolveProviderBundle");let P=null,F=!1;function Ce(e,n){return e?.provider?.id===n&&e.bundle?.endpoint===`${E()}/providers/${encodeURIComponent(n)}/plugin`}a(Ce,"isDirectoryBundle");async function se(e){return Y(await j()).includes(e)}a(se,"grantNames");async function je(e){await Z(J(K(),e),async()=>{if(!(await se(e)||!Ce(C(v(e)),e))){$(v(e),{recursive:!0,force:!0}),await me("user",n=>{delete n.plugins[e]}),await ve("user",n=>{delete n.plugins[e]}),$(d(R(),e),{recursive:!0,force:!0}),H.delete(e),y.delete(b(e));for(const n of[..._.keys()])n.startsWith(`${e}/`)&&_.delete(n);try{await G(async n=>await L(n))}catch(n){m({level:"error",event:"daemon.providers.docs_reconcile_failed",fields:{provider:e},error:n})}m({level:"info",event:"daemon.providers.bundle_uninstalled",fields:{provider:e}})}},{timeoutMs:X,timeoutError:a(()=>new c("provider_unavailable",`timed out waiting for another process replacing plugin "${e}"`),"timeoutError")})}a(je,"uninstallProvider");async function Ae(){if(!(await j()).every(e=>e.status!=="active")){for(const e of be("user"))if(!(e.manifest.provider===void 0||await se(e.name)))try{await je(e.name)}catch(n){m({level:"error",event:"daemon.providers.bundle_uninstall_failed",fields:{provider:e.name},error:n})}}}a(Ae,"uninstallDisconnected");async function Re(){if(!q("user").runtime?.issuer)return;const e=Y(await j());for(const n of e)try{await N(n,!0)}catch(r){r instanceof Object&&I.has(r)||te(n,void 0,r)}await Ae();for(const[n,r]of ke())try{await O(n,r,!0)}catch(t){if(t instanceof c&&t.code==="provider_version_retired"||t instanceof Object&&I.has(t))continue;te(n,r,t)}}a(Re,"syncOnce");function tn(){return P!==null?(F=!0,P):(P=(async()=>{try{do F=!1,await Re();while(F)}finally{P=null}})(),P)}a(tn,"syncProviderBundles");export{en as ensureProviderBundle,Y as providerIdsFromGrants,Ee as providerInstallState,nn as refreshProviderBundle,rn as resolveProviderBundle,tn as syncProviderBundles,Ie as unavailableProviderError};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ManifestHttpLeaf
|
|
1
|
+
import type { ManifestHttpLeaf } from '../../api/plugin-manifest-schema.js';
|
|
2
2
|
import type { ValidatedCommandManifest } from '../../api/command-manifest/manifest.js';
|
|
3
3
|
import type { ProviderCaller, ProviderCallInput, ProviderRequest } from '../../daemon/api/handlers/providers.js';
|
|
4
4
|
import { ProviderError } from './errors.js';
|
|
@@ -10,39 +10,8 @@ export interface ProviderLeaf {
|
|
|
10
10
|
hidden: boolean;
|
|
11
11
|
}
|
|
12
12
|
export declare function providerLeaves(commands: ValidatedCommandManifest): ProviderLeaf[];
|
|
13
|
-
export type ProviderHelpLeaf
|
|
14
|
-
|
|
15
|
-
rootEntry?: ManifestRootEntry;
|
|
16
|
-
children: Array<ProviderHelpBranch | ProviderHelpLeaf>;
|
|
17
|
-
}
|
|
18
|
-
export interface ProviderToolDescription {
|
|
19
|
-
provider: string;
|
|
20
|
-
status: 'available';
|
|
21
|
-
major: number;
|
|
22
|
-
display_name: string;
|
|
23
|
-
/** `machine`: calls go to one of the account's device machines, so its leaves take `--machine`. */
|
|
24
|
-
transport?: 'http' | 'machine';
|
|
25
|
-
groups: Array<{
|
|
26
|
-
group: string;
|
|
27
|
-
leaves: Array<{
|
|
28
|
-
tool: string;
|
|
29
|
-
description: string;
|
|
30
|
-
summary: string;
|
|
31
|
-
params: ManifestHttpLeaf['params'];
|
|
32
|
-
output: ManifestHttpLeaf['output'];
|
|
33
|
-
}>;
|
|
34
|
-
}>;
|
|
35
|
-
/** Help-only tree of every grouped leaf, including groups the caller lacks (`groups` is only the caller's). Never contains REST mappings, endpoints, credentials, or executable paths. */
|
|
36
|
-
commands: ProviderHelpBranch[];
|
|
37
|
-
}
|
|
38
|
-
export interface UnavailableProviderToolDescription {
|
|
39
|
-
provider: string;
|
|
40
|
-
display_name: string;
|
|
41
|
-
status: 'installing' | 'install_failed';
|
|
42
|
-
error?: string;
|
|
43
|
-
groups: [];
|
|
44
|
-
commands: [];
|
|
45
|
-
}
|
|
13
|
+
export type { ProviderHelpLeaf, ProviderHelpBranch, ProviderToolDescription, UnavailableProviderToolDescription } from './description.js';
|
|
14
|
+
import type { ProviderToolDescription } from './description.js';
|
|
46
15
|
/** R8's broker help filter consumes groups[].leaves[].tool. */
|
|
47
16
|
export declare function providerTools(caller: ProviderCaller, id: string): Promise<ProviderToolDescription>;
|
|
48
17
|
export interface ProviderCallResult {
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { ManifestHttpLeaf, ManifestBranch, ManifestRootEntry } from '../../api/plugin-manifest-schema.js';
|
|
2
|
+
export type ProviderHelpLeaf = Pick<ManifestHttpLeaf, 'kind' | 'name' | 'description' | 'whenToUse' | 'tier' | 'summary' | 'params' | 'output' | 'effects' | 'group'>;
|
|
3
|
+
export interface ProviderHelpBranch extends Pick<ManifestBranch<ManifestHttpLeaf>, 'kind' | 'name' | 'description' | 'whenToUse' | 'tier' | 'summary' | 'model'> {
|
|
4
|
+
rootEntry?: ManifestRootEntry;
|
|
5
|
+
children: Array<ProviderHelpBranch | ProviderHelpLeaf>;
|
|
6
|
+
}
|
|
7
|
+
export interface ProviderToolDescription {
|
|
8
|
+
provider: string;
|
|
9
|
+
status: 'available';
|
|
10
|
+
major: number;
|
|
11
|
+
display_name: string;
|
|
12
|
+
/** `machine`: calls go to one of the account's device machines, so its leaves take `--machine`. */
|
|
13
|
+
transport?: 'http' | 'machine';
|
|
14
|
+
groups: Array<{
|
|
15
|
+
group: string;
|
|
16
|
+
leaves: Array<{
|
|
17
|
+
tool: string;
|
|
18
|
+
description: string;
|
|
19
|
+
summary: string;
|
|
20
|
+
params: ManifestHttpLeaf['params'];
|
|
21
|
+
output: ManifestHttpLeaf['output'];
|
|
22
|
+
}>;
|
|
23
|
+
}>;
|
|
24
|
+
/** Help-only tree of every grouped leaf, including groups the caller lacks (`groups` is only the caller's). Never contains REST mappings, endpoints, credentials, or executable paths. */
|
|
25
|
+
commands: ProviderHelpBranch[];
|
|
26
|
+
}
|
|
27
|
+
export interface UnavailableProviderToolDescription {
|
|
28
|
+
provider: string;
|
|
29
|
+
display_name: string;
|
|
30
|
+
status: 'installing' | 'install_failed';
|
|
31
|
+
error?: string;
|
|
32
|
+
groups: [];
|
|
33
|
+
commands: [];
|
|
34
|
+
}
|
|
File without changes
|
|
@@ -32,23 +32,23 @@ export declare function storeToken(key: string, token: CachedToken, epoch?: numb
|
|
|
32
32
|
export declare function discardFile(key: string): void;
|
|
33
33
|
/** Discard every cached token for (`sub`, `grantee`). Returns how many went. */
|
|
34
34
|
export declare function discardFor(sub: string, grantee: string, nowMs?: number): number;
|
|
35
|
-
/** The (
|
|
36
|
-
*
|
|
37
|
-
|
|
35
|
+
/** The grant-change hook (D3-TOK-20, CRD-16), called with the re-read state of one grant whose row changed: discard every cached
|
|
36
|
+
* token of its (`sub`, `grantee`), every token of `sub` naming a provider that no active grant of `sub` (`subGrants`, all of
|
|
37
|
+
* them) resolves, and, when the changed grant is a connection grant (`app:<provider>`) that is not active, every token of `sub`
|
|
38
|
+
* naming that provider whatever its grantee — a person's own calls mint as (`sub`, `sub`), a pair a connection grant never names.
|
|
39
|
+
* It is idempotent, so a repeated or replayed notification discards nothing more. */
|
|
40
|
+
export declare function discardTokensForGrant(changed: {
|
|
38
41
|
sub: string;
|
|
39
42
|
grantee: string;
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
* the active grants resolved before and no longer do, or whose connection
|
|
43
|
-
* grant (`sub` to `app:<provider>`) was active before and is not now, even
|
|
44
|
-
* while another grant still names its scopes. */
|
|
45
|
-
export declare function droppedProviders(before: readonly GrantRecord[], after: readonly GrantRecord[]): string[];
|
|
46
|
-
/** The grant-sync hook (D3-TOK-20, CRD-16): discard every cached token of each
|
|
47
|
-
* changed grant's (`sub`, `grantee`) and of each (`sub`, provider) the sync
|
|
48
|
-
* stopped resolving (whatever the token's grantee — a person's own calls mint
|
|
49
|
-
* as (`sub`, `sub`)), and prune expired files. */
|
|
50
|
-
export declare function discardChangedGrantTokens(before: readonly GrantRecord[], after: readonly GrantRecord[], nowMs?: number): {
|
|
43
|
+
active: boolean;
|
|
44
|
+
}, subGrants: readonly GrantRecord[], nowMs?: number): {
|
|
51
45
|
pairs: number;
|
|
52
46
|
providers: number;
|
|
53
47
|
tokens: number;
|
|
54
48
|
};
|
|
49
|
+
/** The catch-up form of `discardTokensForGrant`, for a changed grant whose row is gone (its `sub` and `grantee` unknown) and for
|
|
50
|
+
* the pass after the listen connection restarted: discard every token of an `app:` (`sub`, `grantee`) with no active grant, and
|
|
51
|
+
* every token naming a provider that no active grant of its `sub` resolves and that is not a connected `app:<provider>`. */
|
|
52
|
+
export declare function discardOrphanedTokens(grants: readonly GrantRecord[], nowMs?: number): {
|
|
53
|
+
tokens: number;
|
|
54
|
+
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var
|
|
1
|
+
var F=Object.defineProperty;var s=(e,t)=>F(e,"name",{value:t,configurable:!0});import{createHash as j}from"node:crypto";import{mkdirSync as J,readdirSync as M,readFileSync as N,rmSync as v}from"node:fs";import{join as g}from"node:path";import{crtrHome as A}from"../canvas/paths.js";import{atomicWriteJson as D}from"../fs-utils.js";const E=30;function b(){return g(A(),"secrets","outbound-tokens")}s(b,"tokenCacheDir");function C(e){return JSON.stringify([e.audience,e.sub,e.grantee,e.initiating_app,[...new Set(e.scope)].sort()])}s(C,"cacheKey");function m(e){return g(b(),`${j("sha256").update(e).digest("hex")}.json`)}s(m,"fileFor");function S(e){try{const t=JSON.parse(e);if(!Array.isArray(t)||typeof t[1]!="string"||typeof t[2]!="string")return null;const o=(Array.isArray(t[4])?t[4]:[]).flatMap(i=>typeof i=="string"?[x(i)]:[]).filter(i=>i!==null);return{sub:t[1],grantee:t[2],providers:[...new Set(o)]}}catch{return null}}s(S,"partsOf");function f(e,t){return JSON.stringify([e,t])}s(f,"pairKey");function w(e,t){return JSON.stringify([e,t])}s(w,"providerKey");function x(e){const t=e.indexOf(":");return t>0?e.slice(0,t):null}s(x,"providerOf");function k(e){try{const t=JSON.parse(N(e,"utf8"));if(typeof t.key!="string"||typeof t.access_token!="string"||typeof t.jti!="string"||typeof t.exp!="number")return null;const n=typeof t.payer=="string"&&t.payer?t.payer:S(t.key)?.sub??"";return n?{...t,payer:n}:null}catch{return null}}s(k,"readFile");function T(e,t){return t<(e.exp-E)*1e3}s(T,"usable");function I(e,t=Date.now()){const n=m(e),o=k(n);return!o||o.key!==e||!T(o,t)?(v(n,{force:!0}),null):{access_token:o.access_token,jti:o.jti,exp:o.exp,payer:o.payer}}s(I,"cachedToken");const l=new Map,d=new Map;function O(e){const t=S(e);return t===null?0:(l.get(f(t.sub,t.grantee))??0)+(d.get(t.sub)??0)}s(O,"discardEpoch");function U(e,t,n=O(e)){return O(e)!==n?!1:(J(b(),{recursive:!0,mode:448}),D(m(e),{key:e,...t},{mode:384}),!0)}s(U,"storeToken");function $(e){v(m(e),{force:!0})}s($,"discardFile");function h(e,t){let n;try{n=M(b())}catch{return 0}let o=0;for(const i of n){if(!i.endsWith(".json"))continue;const a=g(b(),i),u=k(a),r=u?S(u.key):null;u&&r!==null&&e(r)?(v(a,{force:!0}),o++):(!u||t>=u.exp*1e3)&&v(a,{force:!0})}return o}s(h,"sweep");function B(e,t,n=Date.now()){const o=f(e,t);return l.set(o,(l.get(o)??0)+1),h(i=>i.sub===e&&i.grantee===t,n)}s(B,"discardFor");function W(e){const t=new Set;for(const n of e)if(n.status==="active")for(const{scope:o}of n.resolved_scopes){const i=x(o);i!==null&&t.add(i)}return t}s(W,"resolvedProviders");function L(e,t,n=Date.now()){const o=W(t.filter(c=>c.sub===e.sub)),i=e.grantee.startsWith("app:")&&!e.active?e.grantee.slice(4):null,a=s(c=>!o.has(c)||c===i,"unserved"),u=f(e.sub,e.grantee);l.set(u,(l.get(u)??0)+1),d.set(e.sub,(d.get(e.sub)??0)+1);const r=new Set,p=h(c=>{if(c.sub!==e.sub)return!1;const y=c.providers.filter(a);for(const _ of y)r.add(_);return c.grantee===e.grantee||y.length>0},n);return{pairs:1,providers:r.size,tokens:p}}s(L,"discardTokensForGrant");function Q(e,t=Date.now()){const n=e.filter(r=>r.status==="active"),o=new Set(n.map(r=>f(r.sub,r.grantee))),i=new Set(n.flatMap(r=>r.resolved_scopes.flatMap(({scope:p})=>{const c=x(p);return c===null?[]:[w(r.sub,c)]}))),a=new Set,u=h(r=>{const p=r.grantee.startsWith("app:")&&!o.has(f(r.sub,r.grantee)),c=r.providers.some(y=>!i.has(w(r.sub,y)));return(p||c)&&a.add(r.sub),p||c},t);for(const r of a)d.set(r,(d.get(r)??0)+1);return{tokens:u}}s(Q,"discardOrphanedTokens");export{E as REUSE_MARGIN_S,C as cacheKey,I as cachedToken,O as discardEpoch,$ as discardFile,B as discardFor,Q as discardOrphanedTokens,L as discardTokensForGrant,U as storeToken,b as tokenCacheDir};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var S=Object.defineProperty;var d=(e,o)=>S(e,"name",{value:o,configurable:!0});import{randomUUID as v}from"node:crypto";import{conversationIdFromPath as w,conversationStore as u,ConversationNotFoundError as p}from"../conversation-store/index.js";import{basename as F,isAbsolute as c}from"node:path";import{BrokerClient as x}from"../broker-client/index.js";import{deleteNode as M,getNode as g}from"../canvas/index.js";import{expandModelCandidates as C
|
|
1
|
+
var S=Object.defineProperty;var d=(e,o)=>S(e,"name",{value:o,configurable:!0});import{randomUUID as v}from"node:crypto";import{conversationIdFromPath as w,conversationStore as u,ConversationNotFoundError as p}from"../conversation-store/index.js";import{basename as F,isAbsolute as c}from"node:path";import{BrokerClient as x}from"../broker-client/index.js";import{deleteNode as M,getNode as g}from"../canvas/index.js";import{expandModelCandidates as C}from"../model-routes.js";import{selectInitialModelRoute as E}from"../model-routes-pool.js";import{buildLaunchSpec as L}from"../runtime/launch.js";import{openModelRegistry as B}from"../runtime/model-registry.js";import{isBrokerLive as O}from"../runtime/model-swap.js";import{spawnNode as R}from"../runtime/nodes.js";import{SessionManager as D}from"../runtime/broker-sdk.js";import{isReviewBoundary as P}from"../runtime/session-visibility.js";import{forkNodeLedger as $}from"../runtime/ledger.js";import{ReviewOperationError as b}from"./types.js";const I=/^[^/\s:]+\/[^/\s:]+:(?:off|minimal|low|medium|high|xhigh|max)$/,q=100;function N(e){return new b("review_origin_missing","review origin was not found",{origin_node_id:e})}d(N,"originMissing");function f(e,o,r={}){return new b("review_origin_unforkable","review origin has no forkable exact session",{origin_node_id:e,reason:o,...r})}d(f,"originUnforkable");async function k(e,o,r){const i=w(o.sourceFile);if(!c(o.sourceFile)||i===null||i!==o.sourceSessionId||o.leafId===null||o.leafId==="")throw f(e,"no_forkable_session");try{await u().header(i)}catch(n){throw n instanceof p?f(e,"no_forkable_session"):n}if(o.modelSpec===null||!I.test(o.modelSpec))throw f(e,"model_unresolvable");const t=await E({kind:"exact",spec:o.modelSpec},r??await B(),{cwd:o.cwd,profileId:o.profileId});if(t.selected===void 0)throw f(e,"model_unresolvable",{model_reason:t.rejected[0]?.reason});return{sourceFile:o.sourceFile,sourceSessionId:o.sourceSessionId,leafId:o.leafId,modelSpec:o.modelSpec}}d(k,"validateCapture");function U(e){return new Promise(async(o,r)=>{const i=new x(e);let t=!1;function n(s){t||(t=!0,i.close(),s())}d(n,"finish"),i.on("error",s=>n(()=>r(s))),i.on("close",()=>n(()=>r(new Error("origin broker closed before fork coordinates were read")))),i.on("connect",()=>{i.send({type:"hello",role:"observer",client_id:v()}),i.request({type:"get_human_fork_coordinates"}).then(s=>{if(s.kind!=="human_fork_coordinates"){n(()=>r(new Error("origin broker returned an unexpected fork-coordinate response")));return}n(()=>o(s))}).catch(s=>n(()=>r(s)))}),i.connect()})}d(U,"captureLiveOrigin");async function ie(e,o={}){const r=await g(e);if(r===null)throw N(e);if(O(r)){const a=await U(e);return k(e,{...a,cwd:r.cwd,profileId:r.profile_id},o.registry)}const i=typeof r.pi_session_file=="string"?r.pi_session_file:"";let t="",n=null,s=null;const h=w(i);if(c(i)&&h!==null)try{const a=await u().read(h),m=D.inMemory(a.header.cwd,void 0,[a.header,...a.entries]);t=m.getSessionId(),n=m.getLeafId();const _=r.launch?.model,l=typeof _=="string"?(await C({kind:"exact",spec:_},r.cwd,r.profile_id))[0]:void 0;if(l!==void 0){const y=l.thinkingLevel??(m.buildSessionContext().thinkingLevel||"off");s=`${l.providerId}/${l.modelId}:${y}`}}catch(a){if(!(a instanceof p))throw a}return k(e,{sourceFile:i,sourceSessionId:t,leafId:n,modelSpec:s,cwd:r.cwd,profileId:r.profile_id},o.registry)}d(ie,"captureOrigin");async function ne(e){if(!c(e.branchFile)||!c(e.targetFile))throw new Error("review companion requires absolute branch and target paths");if(!I.test(e.modelSpec))throw new Error("review companion requires an exact model spec");const{launch:o}=L("review/companion","base",{lifecycle:"resident",hasManager:!1,model:e.modelSpec,modelExact:!0,cwd:e.cwd,profileId:e.profileId}),r=await R({nodeId:e.nodeId,kind:"review/companion",mode:"base",lifecycle:"resident",cwd:e.cwd,profile_id:e.profileId,parent:e.originNodeId,creator:e.originNodeId,subscribe:!1,forkFrom:e.branchFile,forkSourceFile:e.branchFile,modelOverride:e.modelSpec,reviewBinding:{review_id:e.reviewId,origin_node_id:e.originNodeId,branch_file:e.branchFile,target_file:e.targetFile},name:`review ${F(e.targetFile)}`,launch:o});try{await $(r.node_id,e.originNodeId)}catch(i){throw await M(r.node_id),i}}d(ne,"spawnReviewCompanion");async function A(e){const o=await g(e),r=o?.review_binding,i=o?.pi_session_file,t=typeof i=="string"?w(i):null;if(r==null||o?.pi_session_id==null||t===null)return!1;try{return(await u().read(t)).entries.some(n=>P(n,r.review_id))}catch(n){if(n instanceof p)return!1;throw n}}d(A,"isReviewCompanionBound");async function te(e,o){const r=Date.now()+Math.max(0,o);for(;;){if(await A(e))return!0;const i=r-Date.now();if(i<=0)return!1;await new Promise(t=>setTimeout(t,Math.min(q,i)))}}d(te,"awaitCompanionBind");export{te as awaitCompanionBind,ie as captureOrigin,A as isReviewCompanionBound,ne as spawnReviewCompanion};
|
|
@@ -8,4 +8,4 @@ export declare function toolCallSummary(args: unknown): string | null;
|
|
|
8
8
|
* state `run.trace` `in_progress_message` reads) says what the model is
|
|
9
9
|
* streaming. Null unless the run is `running`. `streaming` is that open
|
|
10
10
|
* message's newest block; a test passes it in place of a live broker. */
|
|
11
|
-
export declare function runActivity(runId: string, status: string, streaming?: () => OpenAssistantBlock | null): Promise<RunActivityDTO | null>;
|
|
11
|
+
export declare function runActivity(runId: string, status: string, streaming?: () => Promise<OpenAssistantBlock | null>): Promise<RunActivityDTO | null>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
var d=Object.defineProperty;var l=(t,n)=>d(t,"name",{value:n,configurable:!0});import{openDb as _}from"../canvas/db.js";import{openAssistantBlock as f}from"../../daemon/runs/observer.js";import{SUBMIT_RESULT_TOOL as p}from"../runtime/structured-output.js";const m=120;function y(t){if(!t||typeof t!="object")return null;const n=t,s=[n.command,n.file_path,n.path].find(r=>typeof r=="string"&&r.trim()!=="");if(s===void 0)return null;const o=s.trim().split(`
|
|
2
2
|
`)[0].trim();return o.length>m?`${o.slice(0,m-1)}\u2026`:o}l(y,"toolCallSummary");async function g(t,n,s=()=>f(t)){if(n!=="running")return null;const o=await _(),r=await o.prepare(`SELECT type, sequence_number FROM run_events WHERE run_id = ? AND node_id = ?
|
|
3
|
-
AND type IN ('node.turn.started', 'node.turn.completed') ORDER BY sequence_number DESC LIMIT 1`).get(t,t);if(!r)return{phase:"starting"};if(r.type==="node.turn.completed")return{phase:"between_turns"};const i=s();if(i?.kind==="text")return{phase:"writing"};if(i?.kind==="tool_call")return i.name===p?{phase:"submitting_result"}:{phase:"tool",tool:{name:i.name,summary:null}};if(i===null){const a=(await o.prepare(`SELECT type, body_json, sequence_number FROM run_events
|
|
3
|
+
AND type IN ('node.turn.started', 'node.turn.completed') ORDER BY sequence_number DESC LIMIT 1`).get(t,t);if(!r)return{phase:"starting"};if(r.type==="node.turn.completed")return{phase:"between_turns"};const i=await s();if(i?.kind==="text")return{phase:"writing"};if(i?.kind==="tool_call")return i.name===p?{phase:"submitting_result"}:{phase:"tool",tool:{name:i.name,summary:null}};if(i===null){const a=(await o.prepare(`SELECT type, body_json, sequence_number FROM run_events
|
|
4
4
|
WHERE run_id = ? AND node_id = ? AND type IN ('node.tool_call.started', 'node.tool_call.completed') AND sequence_number > ?
|
|
5
5
|
ORDER BY sequence_number`).all(t,t,r.sequence_number)).map(e=>({...e,id:JSON.parse(e.body_json).tool_call_id})),c=new Set(a.filter(e=>e.type==="node.tool_call.completed").map(e=>e.id)),u=a.filter(e=>e.type==="node.tool_call.started"&&!c.has(e.id)).at(-1);if(u){const e=JSON.parse(u.body_json);return e.name===p?{phase:"submitting_result"}:{phase:"tool",tool:{name:e.name,summary:y(e.arguments??null)}}}}return{phase:"thinking"}}l(g,"runActivity");export{g as runActivity,y as toolCallSummary};
|
|
@@ -7,6 +7,10 @@ export declare function onRunEventAppended(hook: ((runId: string) => void | Prom
|
|
|
7
7
|
/** Append one event to a run's log. `type` must be a declared run event and `fields` its fields. */
|
|
8
8
|
export declare function appendRunEvent<T extends RunEventType>(db: CanvasDb, runId: string, nodeId: string, type: T, fields: RunEventFields<T>): Promise<RunEventOf<T>>;
|
|
9
9
|
export declare function emitRunEvent<T extends RunEventType>(runId: string, nodeId: string, type: T, fields: RunEventFields<T>): Promise<RunEventOf<T>>;
|
|
10
|
+
/** Serializes read-then-append decisions on one run across processes. */
|
|
11
|
+
export declare function lockRunRoot(db: CanvasDb, runId: string): Promise<void>;
|
|
12
|
+
/** Append `node.status.changed` unless the node's newest status event already says `status`. Two processes that observe one change append one event. */
|
|
13
|
+
export declare function emitRunStatus(runId: string, nodeId: string, status: string, reason: string | null): Promise<void>;
|
|
10
14
|
export declare function emitRunSettlement<T extends 'node.settled' | 'child.settled'>(runId: string, nodeId: string, type: T, fields: RunEventFields<T>): Promise<void>;
|
|
11
15
|
export declare function readRunEvents(runId: string, after?: number): Promise<{
|
|
12
16
|
events: RunEvent[];
|
|
@@ -16,12 +20,8 @@ export declare function readRunEvents(runId: string, after?: number): Promise<{
|
|
|
16
20
|
backlog_bytes: number;
|
|
17
21
|
}>;
|
|
18
22
|
export declare function subscribeRunEvents(runId: string, wake: () => void): Promise<() => void>;
|
|
23
|
+
/** Wake every stream on the run, in every process; its next read observes the missing run. */
|
|
19
24
|
export declare function notifyRunDeleted(runId: string): void;
|
|
20
|
-
/** A run event cursor stays monotonic. Keep control/settlement/usage history
|
|
21
|
-
* for the observer's 30-day recovery window, but full payload events for 14
|
|
22
|
-
* days only; older conversation content is in the transcript store. The stream
|
|
23
|
-
* already signals a cursor gap when events have expired. Budget one page/tick. */
|
|
24
|
-
export declare function expireRunEvents(now: number, limit?: number): Promise<number>;
|
|
25
25
|
/** The conversation store is the canonical full transcript. Keep the full
|
|
26
26
|
* stream for one day, then redact settled tool calls, prompts and thinking.
|
|
27
27
|
* This includes older completed events of a still-live run, but tool-call
|
|
@@ -37,3 +37,5 @@ export declare function compactRunEvents(now: number, afterSeq?: number, scanLim
|
|
|
37
37
|
export declare function registerGrantStream(grant: string, close: () => void): () => void;
|
|
38
38
|
/** Close every open stream held under a grant that is no longer active. */
|
|
39
39
|
export declare function closeGrantStreams(grant: string): number;
|
|
40
|
+
/** The grant ids this process holds open `run.events` streams under. */
|
|
41
|
+
export declare function heldGrantIds(): string[];
|