@phnx-labs/agents-cli 1.22.38 → 1.22.40
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/CHANGELOG.md +302 -0
- package/README.md +111 -70
- package/dist/bin/agents +0 -0
- package/dist/bootstrap.js +46 -27
- package/dist/browser.js +2 -2
- package/dist/cli/command-registry.d.ts +135 -0
- package/dist/cli/command-registry.js +260 -0
- package/dist/commands/accounts.d.ts +20 -0
- package/dist/commands/accounts.js +186 -25
- package/dist/commands/apply.d.ts +3 -3
- package/dist/commands/apply.js +20 -63
- package/dist/commands/browser.js +206 -94
- package/dist/commands/budget.d.ts +7 -6
- package/dist/commands/budget.js +8 -7
- package/dist/commands/cloud.js +17 -20
- package/dist/commands/commands.js +1 -1
- package/dist/commands/computer-actions.d.ts +1 -35
- package/dist/commands/computer-actions.js +13 -181
- package/dist/commands/computer.d.ts +28 -3
- package/dist/commands/computer.js +93 -65
- package/dist/commands/config.js +47 -4
- package/dist/commands/cost.d.ts +2 -1
- package/dist/commands/cost.js +7 -6
- package/dist/commands/daemon.js +151 -4
- package/dist/commands/detach.js +1 -1
- package/dist/commands/doctor.js +19 -11
- package/dist/commands/events.js +1 -1
- package/dist/commands/exec.d.ts +2 -50
- package/dist/commands/exec.js +161 -216
- package/dist/commands/factory.js +1 -1
- package/dist/commands/feed.d.ts +2 -2
- package/dist/commands/feed.js +9 -12
- package/dist/commands/fleet-capture.js +25 -27
- package/dist/commands/focus.d.ts +2 -3
- package/dist/commands/focus.js +34 -9
- package/dist/commands/go.js +15 -5
- package/dist/commands/harness.d.ts +3 -3
- package/dist/commands/harness.js +53 -5
- package/dist/commands/hooks.js +1 -1
- package/dist/commands/import.js +2 -2
- package/dist/commands/insights.d.ts +5 -5
- package/dist/commands/insights.js +15 -9
- package/dist/commands/inspect.d.ts +2 -3
- package/dist/commands/inspect.js +4 -16
- package/dist/commands/logs.d.ts +2 -2
- package/dist/commands/logs.js +9 -9
- package/dist/commands/mcp.js +2 -2
- package/dist/commands/memory.js +1 -1
- package/dist/commands/message.d.ts +1 -1
- package/dist/commands/message.js +7 -7
- package/dist/commands/mine.d.ts +11 -8
- package/dist/commands/mine.js +11 -10
- package/dist/commands/models.js +1 -1
- package/dist/commands/modes.js +1 -1
- package/dist/commands/monitors.js +23 -6
- package/dist/commands/output.d.ts +7 -6
- package/dist/commands/output.js +11 -10
- package/dist/commands/packages.js +4 -4
- package/dist/commands/perf.js +1 -1
- package/dist/commands/permissions.js +49 -32
- package/dist/commands/plugins.d.ts +1 -1
- package/dist/commands/plugins.js +3 -3
- package/dist/commands/profiles.d.ts +6 -9
- package/dist/commands/profiles.js +8 -321
- package/dist/commands/projects.d.ts +9 -0
- package/dist/commands/projects.js +140 -8
- package/dist/commands/prune.js +5 -13
- package/dist/commands/refresh-rules.js +1 -1
- package/dist/commands/repo.d.ts +5 -7
- package/dist/commands/repo.js +34 -18
- package/dist/commands/resource-view.js +4 -0
- package/dist/commands/resume.d.ts +11 -7
- package/dist/commands/resume.js +82 -98
- package/dist/commands/route.d.ts +12 -0
- package/dist/commands/route.js +261 -0
- package/dist/commands/routines.d.ts +2 -3
- package/dist/commands/routines.js +120 -145
- package/dist/commands/rules.js +1 -1
- package/dist/commands/run-account-picker.d.ts +1 -1
- package/dist/commands/run-account-picker.js +2 -2
- package/dist/commands/run-broadcast.d.ts +21 -0
- package/dist/commands/run-broadcast.js +89 -0
- package/dist/commands/run-cloud.js +1 -1
- package/dist/commands/secrets-vault.d.ts +10 -0
- package/dist/commands/{login.js → secrets-vault.js} +34 -14
- package/dist/commands/secrets.d.ts +4 -4
- package/dist/commands/secrets.js +72 -63
- package/dist/commands/sessions-backfill.js +1 -1
- package/dist/commands/sessions-browser.d.ts +1 -1
- package/dist/commands/sessions-browser.js +9 -5
- package/dist/commands/sessions-export.js +2 -2
- package/dist/commands/sessions-inject.js +4 -5
- package/dist/commands/sessions-migrate.js +16 -27
- package/dist/commands/sessions-picker.d.ts +13 -0
- package/dist/commands/sessions-picker.js +182 -8
- package/dist/commands/sessions-resume.d.ts +7 -3
- package/dist/commands/sessions-resume.js +81 -33
- package/dist/commands/sessions-stats.js +2 -2
- package/dist/commands/sessions.d.ts +75 -68
- package/dist/commands/sessions.js +142 -180
- package/dist/commands/setup-computer.js +1 -1
- package/dist/commands/setup-fleet.js +3 -0
- package/dist/commands/setup-mine.d.ts +7 -3
- package/dist/commands/setup-mine.js +13 -8
- package/dist/commands/setup-secrets.js +2 -2
- package/dist/commands/setup-watchdog.js +2 -2
- package/dist/commands/setup.js +7 -2
- package/dist/commands/share.d.ts +65 -0
- package/dist/commands/share.js +253 -20
- package/dist/commands/skills.js +3 -3
- package/dist/commands/snapshot.d.ts +2 -2
- package/dist/commands/snapshot.js +9 -9
- package/dist/commands/ssh.d.ts +1 -1
- package/dist/commands/ssh.js +318 -48
- package/dist/commands/subagents.js +1 -1
- package/dist/commands/sync.js +24 -9
- package/dist/commands/teams.d.ts +2 -2
- package/dist/commands/teams.js +9 -18
- package/dist/commands/tmux.js +5 -1
- package/dist/commands/trash.js +1 -1
- package/dist/commands/usage.d.ts +1 -1
- package/dist/commands/usage.js +2 -2
- package/dist/commands/utils.d.ts +4 -14
- package/dist/commands/utils.js +6 -27
- package/dist/commands/versions.js +2 -2
- package/dist/commands/view.d.ts +9 -77
- package/dist/commands/view.js +23 -8
- package/dist/commands/watchdog.js +1 -1
- package/dist/commands/webhook.js +11 -25
- package/dist/commands/workflows.js +1 -1
- package/dist/index.js +1 -1
- package/dist/lib/account-capabilities.d.ts +39 -0
- package/dist/lib/account-capabilities.js +59 -0
- package/dist/lib/account-catalog.js +1 -1
- package/dist/lib/account-registry.d.ts +66 -0
- package/dist/lib/account-registry.js +151 -5
- package/dist/lib/{rotate.d.ts → accounting/rotate.d.ts} +4 -4
- package/dist/lib/{rotate.js → accounting/rotate.js} +8 -8
- package/dist/lib/{usage.d.ts → accounting/usage.d.ts} +4 -4
- package/dist/lib/{usage.js → accounting/usage.js} +11 -11
- package/dist/lib/agent-spec/provider.js +1 -1
- package/dist/lib/agents.d.ts +72 -4
- package/dist/lib/agents.js +231 -199
- package/dist/lib/answer-router.d.ts +2 -2
- package/dist/lib/ask-classifier.d.ts +1 -1
- package/dist/lib/ask-classifier.js +1 -1
- package/dist/lib/audit/log.js +1 -1
- package/dist/lib/auth-health.d.ts +1 -1
- package/dist/lib/auth-health.js +2 -2
- package/dist/lib/brand.js +1 -1
- package/dist/lib/browser/caller-identity.d.ts +28 -0
- package/dist/lib/browser/caller-identity.js +156 -0
- package/dist/lib/browser/cdp.js +1 -1
- package/dist/lib/browser/drivers/ssh.d.ts +1 -1
- package/dist/lib/browser/drivers/ssh.js +2 -2
- package/dist/lib/browser/hygiene.d.ts +10 -2
- package/dist/lib/browser/hygiene.js +7 -4
- package/dist/lib/browser/ipc.d.ts +22 -2
- package/dist/lib/browser/ipc.js +185 -21
- package/dist/lib/browser/profiles.d.ts +67 -3
- package/dist/lib/browser/profiles.js +129 -7
- package/dist/lib/browser/remote-control.d.ts +2 -2
- package/dist/lib/browser/remote-control.js +3 -3
- package/dist/lib/browser/runtime-state.d.ts +79 -0
- package/dist/lib/browser/runtime-state.js +119 -1
- package/dist/lib/browser/service.d.ts +113 -1
- package/dist/lib/browser/service.js +454 -40
- package/dist/lib/browser/sessions-list.d.ts +2 -1
- package/dist/lib/browser/sessions-list.js +4 -13
- package/dist/lib/browser/types.d.ts +18 -0
- package/dist/lib/budget/config.js +1 -1
- package/dist/lib/budget/ledger.js +1 -1
- package/dist/lib/byok-usage.js +1 -1
- package/dist/lib/capabilities.js +3 -15
- package/dist/lib/catchup.d.ts +1 -1
- package/dist/lib/catchup.js +1 -1
- package/dist/lib/cloud/dispatch.js +1 -1
- package/dist/lib/cloud/host.d.ts +3 -3
- package/dist/lib/cloud/host.js +5 -5
- package/dist/lib/cloud/rush.d.ts +9 -21
- package/dist/lib/cloud/rush.js +33 -120
- package/dist/lib/cloud/types.d.ts +2 -2
- package/dist/lib/commands.js +3 -13
- package/dist/lib/computer/actions.d.ts +36 -0
- package/dist/lib/computer/actions.js +162 -0
- package/dist/lib/computer/dispatch.d.ts +2 -2
- package/dist/lib/computer/dispatch.js +2 -2
- package/dist/lib/computer/sessions-list.d.ts +3 -3
- package/dist/lib/computer/sessions-list.js +2 -2
- package/dist/lib/config-keys.d.ts +12 -3
- package/dist/lib/config-keys.js +29 -6
- package/dist/lib/config-machine-keys.d.ts +4 -2
- package/dist/lib/config-machine-keys.js +6 -2
- package/dist/lib/crabbox/lease.js +9 -1
- package/dist/lib/crabbox/runtimes.d.ts +32 -7
- package/dist/lib/crabbox/runtimes.js +72 -30
- package/dist/lib/{daemon.d.ts → daemon/daemon.d.ts} +59 -1
- package/dist/lib/{daemon.js → daemon/daemon.js} +237 -49
- package/dist/lib/daemon-services.d.ts +1 -1
- package/dist/lib/daemon-services.js +5 -0
- package/dist/lib/daemon-ticks.d.ts +25 -0
- package/dist/lib/daemon-ticks.js +31 -1
- package/dist/lib/daemon-webhooks.d.ts +102 -0
- package/dist/lib/daemon-webhooks.js +210 -0
- package/dist/lib/device-config.d.ts +116 -72
- package/dist/lib/device-config.js +366 -132
- package/dist/lib/devices/config-migration.d.ts +29 -34
- package/dist/lib/devices/config-migration.js +209 -130
- package/dist/lib/devices/connect.d.ts +2 -2
- package/dist/lib/devices/connect.js +2 -2
- package/dist/lib/devices/discovery-policy.d.ts +30 -0
- package/dist/lib/devices/discovery-policy.js +101 -0
- package/dist/lib/devices/fleet-inventory.js +8 -3
- package/dist/lib/devices/harness-inventory.d.ts +1 -1
- package/dist/lib/devices/harness-inventory.js +12 -3
- package/dist/lib/devices/known-hosts.js +1 -1
- package/dist/lib/devices/pool.d.ts +61 -0
- package/dist/lib/devices/pool.js +83 -0
- package/dist/lib/devices/registry.d.ts +1 -1
- package/dist/lib/devices/registry.js +1 -1
- package/dist/lib/devices/resolve-profile.d.ts +2 -2
- package/dist/lib/devices/resolve-profile.js +2 -2
- package/dist/lib/devices/resolve-target.d.ts +1 -1
- package/dist/lib/devices/resolve-target.js +4 -4
- package/dist/lib/devices/self-host.d.ts +1 -1
- package/dist/lib/devices/self-host.js +3 -3
- package/dist/lib/devices/ssh-config.d.ts +1 -1
- package/dist/lib/devices/stats-cache.js +1 -1
- package/dist/lib/devices/sync.d.ts +3 -1
- package/dist/lib/devices/sync.js +3 -3
- package/dist/lib/doctor-diff.js +4 -4
- package/dist/lib/drift-sync.js +2 -2
- package/dist/lib/drift.js +2 -2
- package/dist/lib/event-families.d.ts +1 -1
- package/dist/lib/event-stream.d.ts +1 -1
- package/dist/lib/event-stream.js +2 -2
- package/dist/lib/events-ingest.js +2 -2
- package/dist/lib/exec.d.ts +8 -5
- package/dist/lib/exec.js +19 -13
- package/dist/lib/factory/snapshot.d.ts +1 -1
- package/dist/lib/factory/snapshot.js +1 -1
- package/dist/lib/{activity.d.ts → feed/activity.d.ts} +1 -1
- package/dist/lib/{activity.js → feed/activity.js} +7 -7
- package/dist/lib/{events.d.ts → feed/events.d.ts} +2 -2
- package/dist/lib/{events.js → feed/events.js} +5 -5
- package/dist/lib/{feed.js → feed/feed.js} +4 -4
- package/dist/lib/feed-outcome.d.ts +1 -1
- package/dist/lib/feed-policy.d.ts +1 -1
- package/dist/lib/feed-policy.js +1 -1
- package/dist/lib/feed-post.d.ts +1 -1
- package/dist/lib/feed-post.js +1 -1
- package/dist/lib/feed-ranking.d.ts +1 -1
- package/dist/lib/fleet/apply.d.ts +0 -6
- package/dist/lib/fleet/apply.js +18 -45
- package/dist/lib/fleet/auth-sync.d.ts +16 -35
- package/dist/lib/fleet/auth-sync.js +16 -75
- package/dist/lib/fleet/capture.js +8 -6
- package/dist/lib/fleet/manifest.js +23 -11
- package/dist/lib/fleet/types.d.ts +19 -7
- package/dist/lib/fleet-cache.d.ts +1 -1
- package/dist/lib/fleet-cache.js +1 -1
- package/dist/lib/format.d.ts +19 -0
- package/dist/lib/format.js +44 -1
- package/dist/lib/friction-heuristics.d.ts +1 -1
- package/dist/lib/git.d.ts +24 -1
- package/dist/lib/git.js +82 -38
- package/dist/lib/heal.js +3 -3
- package/dist/lib/hooks.d.ts +18 -0
- package/dist/lib/hooks.js +113 -1
- package/dist/lib/hosts/credentials.d.ts +30 -10
- package/dist/lib/hosts/credentials.js +38 -26
- package/dist/lib/hosts/dispatch.d.ts +3 -3
- package/dist/lib/hosts/dispatch.js +3 -3
- package/dist/lib/hosts/option.d.ts +3 -3
- package/dist/lib/hosts/option.js +7 -8
- package/dist/lib/hosts/passthrough.d.ts +17 -17
- package/dist/lib/hosts/passthrough.js +67 -50
- package/dist/lib/hosts/providers/devices.d.ts +1 -1
- package/dist/lib/hosts/providers/devices.js +1 -1
- package/dist/lib/hosts/reconcile.d.ts +1 -1
- package/dist/lib/hosts/reconcile.js +1 -1
- package/dist/lib/hosts/reconnect.d.ts +1 -1
- package/dist/lib/hosts/reconnect.js +2 -2
- package/dist/lib/hosts/registry.d.ts +5 -5
- package/dist/lib/hosts/registry.js +5 -5
- package/dist/lib/hosts/remote-cmd.d.ts +10 -10
- package/dist/lib/hosts/remote-cmd.js +25 -18
- package/dist/lib/hosts/remote-os.d.ts +4 -4
- package/dist/lib/hosts/remote-os.js +4 -4
- package/dist/lib/hosts/remote-session-id.d.ts +2 -2
- package/dist/lib/hosts/remote-session-id.js +2 -2
- package/dist/lib/hosts/routing-flag.d.ts +3 -3
- package/dist/lib/hosts/routing-flag.js +4 -5
- package/dist/lib/hosts/run-target.d.ts +4 -4
- package/dist/lib/hosts/run-target.js +4 -4
- package/dist/lib/hosts/session-index.d.ts +2 -2
- package/dist/lib/hosts/session-index.js +1 -1
- package/dist/lib/hosts/session-marker.d.ts +1 -1
- package/dist/lib/hosts/session-marker.js +1 -1
- package/dist/lib/hosts/types.d.ts +2 -2
- package/dist/lib/hosts/types.js +2 -2
- package/dist/lib/import.js +1 -1
- package/dist/lib/{migrate.d.ts → installations/migrate.d.ts} +49 -1
- package/dist/lib/{migrate.js → installations/migrate.js} +265 -38
- package/dist/lib/installations/resolve.js +1 -1
- package/dist/lib/installations/strategies.js +1 -1
- package/dist/lib/installations/update.js +2 -2
- package/dist/lib/{versions.d.ts → installations/versions.d.ts} +12 -3
- package/dist/lib/{versions.js → installations/versions.js} +51 -31
- package/dist/lib/isolation-boundary-report.js +1 -1
- package/dist/lib/linear-projects.d.ts +28 -0
- package/dist/lib/linear-projects.js +30 -0
- package/dist/lib/loop.js +1 -1
- package/dist/lib/mailbox-gc.js +1 -1
- package/dist/lib/mailbox.js +1 -1
- package/dist/lib/mcp-registry.d.ts +62 -0
- package/dist/lib/mcp-registry.js +177 -0
- package/dist/lib/mcp.d.ts +5 -0
- package/dist/lib/mcp.js +124 -307
- package/dist/lib/menubar/MenubarHelper.app/Contents/CodeResources +0 -0
- package/dist/lib/menubar/MenubarHelper.app/Contents/MacOS/MenubarHelper +0 -0
- package/dist/lib/menubar/install-menubar.d.ts +7 -0
- package/dist/lib/menubar/install-menubar.js +24 -6
- package/dist/lib/menubar/snapshot.d.ts +7 -0
- package/dist/lib/menubar/snapshot.js +8 -6
- package/dist/lib/models.js +1 -1
- package/dist/lib/monitors/config.d.ts +12 -0
- package/dist/lib/monitors/config.js +3 -0
- package/dist/lib/monitors/dispatch.js +26 -5
- package/dist/lib/monitors/engine.js +10 -0
- package/dist/lib/monitors/sources/webhook.d.ts +1 -1
- package/dist/lib/monitors/state.d.ts +42 -0
- package/dist/lib/monitors/state.js +30 -0
- package/dist/lib/notify.d.ts +1 -1
- package/dist/lib/observe-aliases.d.ts +2 -2
- package/dist/lib/observe-aliases.js +2 -11
- package/dist/lib/output/git-output.js +2 -2
- package/dist/lib/overdue.d.ts +1 -1
- package/dist/lib/overdue.js +1 -1
- package/dist/lib/permissions-registry.d.ts +65 -0
- package/dist/lib/permissions-registry.js +599 -0
- package/dist/lib/permissions.d.ts +24 -13
- package/dist/lib/permissions.js +52 -271
- package/dist/lib/picker.d.ts +16 -0
- package/dist/lib/picker.js +33 -3
- package/dist/lib/placement.d.ts +1 -1
- package/dist/lib/placement.js +4 -4
- package/dist/lib/platform/paths.d.ts +8 -0
- package/dist/lib/platform/paths.js +11 -0
- package/dist/lib/platform/posixpath.js +3 -3
- package/dist/lib/{plugin-marketplace.d.ts → plugins/plugin-marketplace.d.ts} +1 -1
- package/dist/lib/{plugin-marketplace.js → plugins/plugin-marketplace.js} +2 -2
- package/dist/lib/{plugins.d.ts → plugins/plugins.d.ts} +1 -1
- package/dist/lib/{plugins.js → plugins/plugins.js} +7 -7
- package/dist/lib/{skills.d.ts → plugins/skills.d.ts} +1 -1
- package/dist/lib/{skills.js → plugins/skills.js} +7 -7
- package/dist/lib/pricing/cost.d.ts +1 -1
- package/dist/lib/pricing/cost.js +1 -1
- package/dist/lib/profiles-presets.d.ts +1 -1
- package/dist/lib/profiles-presets.js +1 -1
- package/dist/lib/profiles.js +2 -2
- package/dist/lib/project-import.js +4 -1
- package/dist/lib/project-launch.d.ts +1 -1
- package/dist/lib/project-launch.js +3 -3
- package/dist/lib/project-pull.d.ts +128 -0
- package/dist/lib/project-pull.js +384 -0
- package/dist/lib/project-root.d.ts +2 -2
- package/dist/lib/project-root.js +2 -2
- package/dist/lib/project-status.js +1 -1
- package/dist/lib/projects.d.ts +23 -0
- package/dist/lib/projects.js +29 -6
- package/dist/lib/refresh.d.ts +12 -1
- package/dist/lib/refresh.js +16 -9
- package/dist/lib/registry.d.ts +9 -2
- package/dist/lib/registry.js +11 -4
- package/dist/lib/resources.d.ts +2 -2
- package/dist/lib/resources.js +2 -2
- package/dist/lib/routers.d.ts +81 -0
- package/dist/lib/routers.js +153 -0
- package/dist/lib/routine-context.d.ts +1 -0
- package/dist/lib/routine-context.js +7 -2
- package/dist/lib/routine-notify-owner.d.ts +1 -1
- package/dist/lib/routine-notify.d.ts +1 -1
- package/dist/lib/routine-notify.js +1 -1
- package/dist/lib/routine-process-cleanup.d.ts +1 -1
- package/dist/lib/routine-readiness.d.ts +1 -1
- package/dist/lib/routine-readiness.js +11 -4
- package/dist/lib/routines-placement.d.ts +12 -2
- package/dist/lib/routines-placement.js +20 -3
- package/dist/lib/routines-project.d.ts +1 -1
- package/dist/lib/routines-project.js +1 -1
- package/dist/lib/rules/compile.d.ts +1 -0
- package/dist/lib/rules/compile.js +10 -2
- package/dist/lib/rules/rules.js +1 -1
- package/dist/lib/run-notify.js +1 -1
- package/dist/lib/runner.d.ts +80 -2
- package/dist/lib/runner.js +241 -62
- package/dist/lib/sandbox.d.ts +1 -1
- package/dist/lib/scheduler.d.ts +1 -1
- package/dist/lib/scheduler.js +1 -1
- package/dist/lib/{routines.d.ts → scheduling/routines.d.ts} +54 -9
- package/dist/lib/{routines.js → scheduling/routines.js} +173 -14
- package/dist/lib/secrets/Agents CLI.app/Contents/CodeResources +0 -0
- package/dist/lib/secrets/Agents CLI.app/Contents/MacOS/Agents CLI +0 -0
- package/dist/lib/secrets/agent.js +2 -2
- package/dist/lib/secrets/audit.js +1 -1
- package/dist/lib/secrets/bundles.d.ts +3 -3
- package/dist/lib/secrets/bundles.js +7 -7
- package/dist/lib/secrets/index.js +1 -1
- package/dist/lib/secrets/list-filter.d.ts +1 -1
- package/dist/lib/secrets/list-filter.js +2 -2
- package/dist/lib/secrets/push.d.ts +1 -1
- package/dist/lib/secrets/push.js +10 -12
- package/dist/lib/secrets/remote.d.ts +12 -10
- package/dist/lib/secrets/remote.js +21 -14
- package/dist/lib/secrets/vault.js +2 -2
- package/dist/lib/self-heal/checks/shadowing.js +1 -1
- package/dist/lib/self-heal/checks/shims.js +1 -1
- package/dist/lib/self-update.d.ts +39 -4
- package/dist/lib/self-update.js +78 -25
- package/dist/lib/serve/control.d.ts +1 -1
- package/dist/lib/serve/control.js +4 -4
- package/dist/lib/serve/data.d.ts +1 -1
- package/dist/lib/serve/data.js +1 -1
- package/dist/lib/serve/stream.js +1 -1
- package/dist/lib/service-manifest.d.ts +29 -0
- package/dist/lib/service-manifest.js +80 -0
- package/dist/lib/session/active.d.ts +59 -7
- package/dist/lib/session/active.js +158 -17
- package/dist/lib/session/bash-command.js +1 -1
- package/dist/lib/session/claude-accounts.d.ts +1 -1
- package/dist/lib/session/claude-accounts.js +1 -1
- package/dist/lib/session/db.d.ts +10 -2
- package/dist/lib/session/db.js +25 -6
- package/dist/lib/session/discover.d.ts +77 -0
- package/dist/lib/session/discover.js +130 -25
- package/dist/lib/session/fork.js +1 -1
- package/dist/lib/session/inject.d.ts +1 -1
- package/dist/lib/session/insights.d.ts +1 -1
- package/dist/lib/session/insights.js +1 -1
- package/dist/lib/session/live-metadata.d.ts +15 -0
- package/dist/lib/session/live-metadata.js +76 -0
- package/dist/lib/session/migrate-targets.d.ts +1 -1
- package/dist/lib/session/recovery.d.ts +1 -1
- package/dist/lib/session/recovery.js +2 -2
- package/dist/lib/session/remote-active.d.ts +10 -1
- package/dist/lib/session/remote-active.js +8 -3
- package/dist/lib/session/remote-bundle.d.ts +1 -1
- package/dist/lib/session/remote-bundle.js +2 -2
- package/dist/lib/session/remote-list.d.ts +15 -4
- package/dist/lib/session/remote-list.js +40 -3
- package/dist/lib/session/remote.d.ts +5 -5
- package/dist/lib/session/remote.js +13 -17
- package/dist/lib/session/resume-command.d.ts +3 -2
- package/dist/lib/session/resume-command.js +4 -3
- package/dist/lib/session/resume-owner.d.ts +3 -3
- package/dist/lib/session/resume-owner.js +3 -3
- package/dist/lib/session/session-cache.d.ts +12 -0
- package/dist/lib/session/session-cache.js +2 -0
- package/dist/lib/session/shell-programs.js +1 -1
- package/dist/lib/session/state.js +5 -5
- package/dist/lib/session/team-filter.d.ts +1 -1
- package/dist/lib/session/team-filter.js +1 -1
- package/dist/lib/session/types.d.ts +3 -3
- package/dist/lib/session/width.d.ts +2 -2
- package/dist/lib/session/width.js +2 -2
- package/dist/lib/share/delete.d.ts +21 -0
- package/dist/lib/share/delete.js +42 -0
- package/dist/lib/share/publish.d.ts +82 -0
- package/dist/lib/share/publish.js +170 -18
- package/dist/lib/share/worker-template.js +172 -9
- package/dist/lib/shims.js +35 -7
- package/dist/lib/smart-launch.d.ts +36 -6
- package/dist/lib/smart-launch.js +65 -8
- package/dist/lib/snapshot.d.ts +4 -4
- package/dist/lib/snapshot.js +2 -2
- package/dist/lib/ssh-exec.d.ts +1 -1
- package/dist/lib/ssh-exec.js +2 -2
- package/dist/lib/ssh-tunnel.d.ts +10 -10
- package/dist/lib/ssh-tunnel.js +12 -12
- package/dist/lib/staleness/checkers/hooks.d.ts +1 -1
- package/dist/lib/staleness/checkers/hooks.js +1 -1
- package/dist/lib/staleness/detectors/permissions.js +0 -23
- package/dist/lib/staleness/detectors/plugins.js +1 -1
- package/dist/lib/staleness/fingerprint.js +1 -1
- package/dist/lib/staleness/layers.d.ts +1 -1
- package/dist/lib/staleness/layers.js +1 -1
- package/dist/lib/staleness/writers/mcp.js +3 -1
- package/dist/lib/staleness/writers/plugins.js +1 -1
- package/dist/lib/staleness/writers/types.d.ts +8 -0
- package/dist/lib/startup/command-registry.d.ts +5 -147
- package/dist/lib/startup/command-registry.js +38 -303
- package/dist/lib/startup/dev-build.d.ts +0 -21
- package/dist/lib/startup/dev-build.js +29 -8
- package/dist/lib/state.d.ts +19 -1
- package/dist/lib/state.js +120 -51
- package/dist/lib/subagents.js +1 -1
- package/dist/lib/sync-status.js +1 -1
- package/dist/lib/sync-umbrella.d.ts +6 -1
- package/dist/lib/sync-umbrella.js +9 -4
- package/dist/lib/teams/agents.js +2 -2
- package/dist/lib/teams/registry.js +1 -1
- package/dist/lib/terminal/backends/vscodium-agent.js +1 -1
- package/dist/lib/terminal/engine.js +1 -1
- package/dist/lib/terminal/index.d.ts +4 -0
- package/dist/lib/terminal/index.js +3 -0
- package/dist/lib/terminal/inject.d.ts +2 -2
- package/dist/lib/terminal/inject.js +2 -2
- package/dist/lib/terminal/transport.js +1 -1
- package/dist/lib/tmux/index.d.ts +1 -1
- package/dist/lib/tmux/index.js +1 -1
- package/dist/lib/tmux/session.d.ts +21 -5
- package/dist/lib/tmux/session.js +76 -22
- package/dist/lib/triggers/handlers.d.ts +1 -1
- package/dist/lib/triggers/handlers.js +2 -2
- package/dist/lib/triggers/webhook.d.ts +36 -2
- package/dist/lib/triggers/webhook.js +97 -42
- package/dist/lib/types.d.ts +18 -6
- package/dist/lib/usage-fleet.d.ts +1 -1
- package/dist/lib/usage-fleet.js +1 -1
- package/dist/lib/usage-refresh.d.ts +1 -1
- package/dist/lib/usage-refresh.js +3 -3
- package/dist/lib/version-duplicates.js +2 -2
- package/dist/lib/view-types.d.ts +56 -0
- package/dist/lib/view-types.js +1 -0
- package/dist/lib/watchdog/rotate.d.ts +2 -2
- package/dist/lib/watchdog/rotate.js +3 -3
- package/dist/lib/watchdog/runner.d.ts +2 -3
- package/dist/lib/watchdog/runner.js +3 -4
- package/dist/lib/workflows.js +1 -1
- package/package.json +2 -1
- package/scripts/postinstall.js +2 -2
- package/dist/commands/bench.d.ts +0 -2
- package/dist/commands/bench.js +0 -101
- package/dist/commands/cp.d.ts +0 -84
- package/dist/commands/cp.js +0 -231
- package/dist/commands/login.d.ts +0 -2
- package/dist/lib/resources/commands.d.ts +0 -46
- package/dist/lib/resources/commands.js +0 -211
- package/dist/lib/resources/hooks.d.ts +0 -16
- package/dist/lib/resources/hooks.js +0 -153
- package/dist/lib/resources/mcp.d.ts +0 -34
- package/dist/lib/resources/mcp.js +0 -250
- package/dist/lib/resources/memory.d.ts +0 -15
- package/dist/lib/resources/memory.js +0 -46
- package/dist/lib/resources/permissions.d.ts +0 -13
- package/dist/lib/resources/permissions.js +0 -202
- package/dist/lib/resources/rules.d.ts +0 -46
- package/dist/lib/resources/rules.js +0 -179
- package/dist/lib/resources/skills.d.ts +0 -37
- package/dist/lib/resources/skills.js +0 -247
- package/dist/lib/resources/subagents.d.ts +0 -46
- package/dist/lib/resources/subagents.js +0 -202
- /package/dist/lib/{feed.d.ts → feed/feed.d.ts} +0 -0
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import * as fs from 'fs';
|
|
2
|
+
import * as path from 'path';
|
|
3
|
+
import { randomUUID } from 'node:crypto';
|
|
4
|
+
import { resolvePolicyPath } from '../computer-rpc.js';
|
|
5
|
+
import { COMPUTER_INPUT_GATED_VERBS, formatComputerPermissionGrantHint } from '../permissions.js';
|
|
6
|
+
import { emit as emitEvent } from '../feed/events.js';
|
|
7
|
+
import { recordComputerSession } from '../session/db.js';
|
|
8
|
+
import { resolveActor } from '../actor.js';
|
|
9
|
+
function isComputerInputVerb(verb) {
|
|
10
|
+
return typeof verb === 'string' && COMPUTER_INPUT_GATED_VERBS.includes(verb);
|
|
11
|
+
}
|
|
12
|
+
function computerSessionId(env = process.env) {
|
|
13
|
+
return env.CODEX_THREAD_ID
|
|
14
|
+
|| env.CLAUDE_CODE_SESSION_ID
|
|
15
|
+
|| env.CLAUDE_SESSION_ID
|
|
16
|
+
|| env.AGENTS_SESSION_ID
|
|
17
|
+
|| env.AGENTS_RUN_ID
|
|
18
|
+
|| null;
|
|
19
|
+
}
|
|
20
|
+
function admissionCachePath(env = process.env) {
|
|
21
|
+
if (env.AGENTS_COMPUTER_ADMISSION_CACHE)
|
|
22
|
+
return env.AGENTS_COMPUTER_ADMISSION_CACHE;
|
|
23
|
+
return path.join(path.dirname(resolvePolicyPath()), 'computer-target-admissions.json');
|
|
24
|
+
}
|
|
25
|
+
function targetSelector(opts) {
|
|
26
|
+
return opts.bundle ? `bundle:${opts.bundle}` : 'frontmost';
|
|
27
|
+
}
|
|
28
|
+
function readAdmissionCache(filePath) {
|
|
29
|
+
try {
|
|
30
|
+
const parsed = JSON.parse(fs.readFileSync(filePath, 'utf-8'));
|
|
31
|
+
return Array.isArray(parsed.admissions) ? parsed.admissions.filter(isAdmission) : [];
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
return [];
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
function isAdmission(v) {
|
|
38
|
+
if (!v || typeof v !== 'object')
|
|
39
|
+
return false;
|
|
40
|
+
const r = v;
|
|
41
|
+
return r.sessionId !== undefined
|
|
42
|
+
&& typeof r.sessionId === 'string'
|
|
43
|
+
&& typeof r.selector === 'string'
|
|
44
|
+
&& r.gateClass === 'input'
|
|
45
|
+
&& typeof r.pid === 'number'
|
|
46
|
+
&& typeof r.bundle_id === 'string'
|
|
47
|
+
&& typeof r.name === 'string'
|
|
48
|
+
&& typeof r.admittedAtMs === 'number'
|
|
49
|
+
&& isComputerInputVerb(r.admittedByVerb);
|
|
50
|
+
}
|
|
51
|
+
function rememberAdmission(app, opts) {
|
|
52
|
+
const sessionId = computerSessionId(opts.env);
|
|
53
|
+
if (!sessionId)
|
|
54
|
+
return;
|
|
55
|
+
const filePath = admissionCachePath(opts.env);
|
|
56
|
+
const admissions = readAdmissionCache(filePath);
|
|
57
|
+
const next = {
|
|
58
|
+
sessionId,
|
|
59
|
+
selector: opts.selector,
|
|
60
|
+
gateClass: 'input',
|
|
61
|
+
pid: app.pid,
|
|
62
|
+
bundle_id: app.bundle_id,
|
|
63
|
+
name: app.name,
|
|
64
|
+
admittedAtMs: opts.nowMs ?? Date.now(),
|
|
65
|
+
admittedByVerb: opts.verb,
|
|
66
|
+
};
|
|
67
|
+
const filtered = admissions.filter((a) => !(a.sessionId === sessionId && a.selector === opts.selector && a.gateClass === 'input'));
|
|
68
|
+
filtered.push(next);
|
|
69
|
+
try {
|
|
70
|
+
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
71
|
+
fs.writeFileSync(filePath, JSON.stringify({ admissions: filtered }, null, 2), { mode: 0o600 });
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
// Cache persistence is best-effort; the daemon remains the final gate.
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
function findAdmission(opts) {
|
|
78
|
+
const sessionId = computerSessionId(opts.env);
|
|
79
|
+
if (!sessionId)
|
|
80
|
+
return null;
|
|
81
|
+
const admissions = readAdmissionCache(admissionCachePath(opts.env));
|
|
82
|
+
const matches = admissions
|
|
83
|
+
.filter((a) => a.sessionId === sessionId && a.selector === opts.selector && a.gateClass === 'input')
|
|
84
|
+
.sort((a, b) => b.admittedAtMs - a.admittedAtMs);
|
|
85
|
+
return matches[0] ?? null;
|
|
86
|
+
}
|
|
87
|
+
export function pickTarget(list, opts) {
|
|
88
|
+
if (opts.pid != null) {
|
|
89
|
+
const app = list.find((a) => a.pid === opts.pid);
|
|
90
|
+
return { ok: true, app: app ?? { pid: opts.pid, name: '', bundle_id: '', active: false } };
|
|
91
|
+
}
|
|
92
|
+
if (opts.bundle) {
|
|
93
|
+
const app = list.find((a) => a.bundle_id === opts.bundle);
|
|
94
|
+
if (!app) {
|
|
95
|
+
return {
|
|
96
|
+
ok: false,
|
|
97
|
+
error: `bundle not in allow list (or not running): ${opts.bundle}\n${formatComputerPermissionGrantHint(opts.bundle)}`,
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
return { ok: true, app };
|
|
101
|
+
}
|
|
102
|
+
const active = list.find((a) => a.active);
|
|
103
|
+
if (!active) {
|
|
104
|
+
return {
|
|
105
|
+
ok: false,
|
|
106
|
+
error: `no active app found in allow list\n${formatComputerPermissionGrantHint()}`,
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
return { ok: true, app: active };
|
|
110
|
+
}
|
|
111
|
+
function unwrap(r) {
|
|
112
|
+
if (r.error) {
|
|
113
|
+
console.error(`error: ${r.error.code}: ${r.error.message}`);
|
|
114
|
+
process.exit(1);
|
|
115
|
+
}
|
|
116
|
+
return r.result ?? {};
|
|
117
|
+
}
|
|
118
|
+
export async function resolveTargetPidDecision(client, opts, gate) {
|
|
119
|
+
if (opts.pid != null)
|
|
120
|
+
return { ok: true, pid: opts.pid, source: 'pid' };
|
|
121
|
+
const apps = unwrap(await client.call('list_apps'));
|
|
122
|
+
const list = apps.apps || [];
|
|
123
|
+
const picked = pickTarget(list, opts);
|
|
124
|
+
const verb = gate?.verb;
|
|
125
|
+
const selector = targetSelector(opts);
|
|
126
|
+
if (picked.ok && isComputerInputVerb(verb)) {
|
|
127
|
+
rememberAdmission(picked.app, { selector, verb, env: gate?.env, nowMs: gate?.nowMs });
|
|
128
|
+
}
|
|
129
|
+
if (!picked.ok) {
|
|
130
|
+
if (isComputerInputVerb(verb)) {
|
|
131
|
+
const admitted = findAdmission({ selector, env: gate?.env });
|
|
132
|
+
if (admitted)
|
|
133
|
+
return { ok: true, pid: admitted.pid, source: 'session_admission' };
|
|
134
|
+
}
|
|
135
|
+
return { ok: false, error: picked.error };
|
|
136
|
+
}
|
|
137
|
+
return { ok: true, pid: picked.app.pid, source: 'list_apps' };
|
|
138
|
+
}
|
|
139
|
+
const COMPUTER_INVOCATION_ID = randomUUID();
|
|
140
|
+
export function emitComputerAction(verb, targetPid, opts, extra = {}) {
|
|
141
|
+
emitEvent('computer.action', {
|
|
142
|
+
command: verb,
|
|
143
|
+
invocationId: COMPUTER_INVOCATION_ID,
|
|
144
|
+
targetPid,
|
|
145
|
+
bundle: opts.bundle,
|
|
146
|
+
device: opts.device,
|
|
147
|
+
...extra,
|
|
148
|
+
});
|
|
149
|
+
try {
|
|
150
|
+
recordComputerSession({
|
|
151
|
+
invocationId: COMPUTER_INVOCATION_ID,
|
|
152
|
+
sessionId: process.env.AGENT_SESSION_ID || process.env.AGENTS_SESSION_ID,
|
|
153
|
+
launchId: process.env.AGENT_LAUNCH_ID,
|
|
154
|
+
actor: resolveActor().id,
|
|
155
|
+
actionCount: 1,
|
|
156
|
+
taskPreview: typeof extra.task === 'string' ? extra.task : undefined,
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
catch {
|
|
160
|
+
// Recording is best-effort; the action and its event are already done.
|
|
161
|
+
}
|
|
162
|
+
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import type { ComputerClient } from '../computer-rpc.js';
|
|
2
|
-
import { type AppInfo } from '
|
|
2
|
+
import { type AppInfo } from './actions.js';
|
|
3
3
|
import type { VerbDispatcher } from './loop.js';
|
|
4
4
|
declare function rpcMethodFor(verb: string): string;
|
|
5
5
|
declare function toRpcParams(verb: string, input: Record<string, unknown>, pid?: number): Record<string, unknown>;
|
|
6
6
|
export declare function makeVerbDispatcher(client: ComputerClient, context?: {
|
|
7
|
-
|
|
7
|
+
device?: string;
|
|
8
8
|
}): VerbDispatcher;
|
|
9
9
|
export { rpcMethodFor, toRpcParams };
|
|
10
10
|
export type { AppInfo };
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
// it names the same RPC methods the explicit `agents computer <verb>` commands
|
|
6
6
|
// call, so the external-agent verb surface is untouched. The daemon stays the
|
|
7
7
|
// single authority on permissions and targeting.
|
|
8
|
-
import { resolveTargetPidDecision, emitComputerAction } from '
|
|
8
|
+
import { resolveTargetPidDecision, emitComputerAction } from './actions.js';
|
|
9
9
|
// CLI verb -> daemon RPC method. Only the rename cases need listing; the rest
|
|
10
10
|
// pass through by name.
|
|
11
11
|
const RPC_METHOD = {
|
|
@@ -125,7 +125,7 @@ export function makeVerbDispatcher(client, context = {}) {
|
|
|
125
125
|
const res = await client.call(method, params);
|
|
126
126
|
if (res.error)
|
|
127
127
|
return { ok: false, error: `${res.error.code}: ${res.error.message}` };
|
|
128
|
-
emitComputerAction(verb, pid, { bundle: input.bundle,
|
|
128
|
+
emitComputerAction(verb, pid, { bundle: input.bundle, device: context.device });
|
|
129
129
|
return { ok: true, result: res.result ?? {} };
|
|
130
130
|
};
|
|
131
131
|
}
|
|
@@ -17,7 +17,7 @@ export interface ComputerAction {
|
|
|
17
17
|
/** The driven app's pid, when resolved. */
|
|
18
18
|
targetPid?: number;
|
|
19
19
|
bundle?: string;
|
|
20
|
-
/** `--
|
|
20
|
+
/** `--device <device>` target when this action drove a remote daemon. */
|
|
21
21
|
host?: string;
|
|
22
22
|
/** Truncated `--task` text; only ever present on a `verb: 'run'` marker. */
|
|
23
23
|
task?: string;
|
|
@@ -62,7 +62,7 @@ export interface ComputerRunRow {
|
|
|
62
62
|
* the driven one (see `remoteHost`). */
|
|
63
63
|
machine: string;
|
|
64
64
|
machineId?: string;
|
|
65
|
-
/** `--
|
|
65
|
+
/** `--device <device>` target when the run drove a remote (Windows) daemon. */
|
|
66
66
|
remoteHost?: string;
|
|
67
67
|
/** Best-known target app bundle across the run's actions. */
|
|
68
68
|
bundle?: string;
|
|
@@ -90,7 +90,7 @@ export declare function groupIntoComputerRuns(actions: ComputerAction[], resolve
|
|
|
90
90
|
/** Build task-first rows from the real ledger, resolving each row's owning
|
|
91
91
|
* session against the live indexes. The interactive picker's (and the
|
|
92
92
|
* flat/`--json` printer's) data source. `machine` narrows to rows whose
|
|
93
|
-
* invoking hostname, machineId, or `--
|
|
93
|
+
* invoking hostname, machineId, or `--device` target contains the substring. */
|
|
94
94
|
export declare function buildComputerSessionRows(opts?: {
|
|
95
95
|
limit?: number;
|
|
96
96
|
machine?: string;
|
|
@@ -58,7 +58,7 @@
|
|
|
58
58
|
* `sessionId` doesn't resolve (a rotated/unindexed session) but `launchId`
|
|
59
59
|
* still does via the more authoritative pid registry.
|
|
60
60
|
*/
|
|
61
|
-
import { query, truncate } from '../events.js';
|
|
61
|
+
import { query, truncate } from '../feed/events.js';
|
|
62
62
|
import { formatRelativeTime } from '../session/relative-time.js';
|
|
63
63
|
import { getSessionById, listComputerSessionRecords, pruneToolSessions } from '../session/db.js';
|
|
64
64
|
import { buildLaunchSessionIndex, resolveLaunchSession, } from '../browser/sessions-list.js';
|
|
@@ -237,7 +237,7 @@ function appendPrunedRunsFromDb(rows, limit) {
|
|
|
237
237
|
/** Build task-first rows from the real ledger, resolving each row's owning
|
|
238
238
|
* session against the live indexes. The interactive picker's (and the
|
|
239
239
|
* flat/`--json` printer's) data source. `machine` narrows to rows whose
|
|
240
|
-
* invoking hostname, machineId, or `--
|
|
240
|
+
* invoking hostname, machineId, or `--device` target contains the substring. */
|
|
241
241
|
export function buildComputerSessionRows(opts = {}) {
|
|
242
242
|
const actions = listComputerActions({ limit: opts.limit });
|
|
243
243
|
const index = buildLaunchSessionIndex();
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
import type { AgentId } from './types.js';
|
|
10
10
|
import { type ModelTier } from './model-tiers.js';
|
|
11
11
|
/** The top-level scope of a unified config key. */
|
|
12
|
-
export type ConfigScope = 'run' | 'interactive' | 'usage' | 'browser' | 'project' | 'device';
|
|
12
|
+
export type ConfigScope = 'run' | 'interactive' | 'usage' | 'auto' | 'browser' | 'project' | 'device';
|
|
13
13
|
/** A run-time default key: model, mode, effort, or tier override. */
|
|
14
14
|
export interface ParsedRunConfigKey {
|
|
15
15
|
scope: 'run';
|
|
@@ -28,6 +28,11 @@ export interface ParsedUsageConfigKey {
|
|
|
28
28
|
scope: 'usage';
|
|
29
29
|
property: 'primary-host';
|
|
30
30
|
}
|
|
31
|
+
/** Which devices automatic placement (`--device auto`) may pick. */
|
|
32
|
+
export interface ParsedAutoConfigKey {
|
|
33
|
+
scope: 'auto';
|
|
34
|
+
property: 'pool';
|
|
35
|
+
}
|
|
31
36
|
/** The default browser profile (device-scope, self or peer). */
|
|
32
37
|
export interface ParsedBrowserConfigKey {
|
|
33
38
|
scope: 'browser';
|
|
@@ -44,8 +49,8 @@ export interface ParsedDeviceConfigKey {
|
|
|
44
49
|
device: string;
|
|
45
50
|
property: DeviceConfigProperty;
|
|
46
51
|
}
|
|
47
|
-
export type ParsedConfigKey = ParsedRunConfigKey | ParsedInteractiveConfigKey | ParsedUsageConfigKey | ParsedBrowserConfigKey | ParsedProjectConfigKey | ParsedDeviceConfigKey;
|
|
48
|
-
export type DeviceConfigProperty = 'max-agents' | 'scheduler' | 'daemon' | 'watchdog' | 'browser.remote-control' | 'notes' | 'browser.profile';
|
|
52
|
+
export type ParsedConfigKey = ParsedRunConfigKey | ParsedInteractiveConfigKey | ParsedUsageConfigKey | ParsedAutoConfigKey | ParsedBrowserConfigKey | ParsedProjectConfigKey | ParsedDeviceConfigKey;
|
|
53
|
+
export type DeviceConfigProperty = 'role' | 'max-agents' | 'scheduler' | 'daemon' | 'watchdog' | 'tmux' | 'browser.remote-control' | 'browser.task-idle-minutes' | 'notes' | 'browser.profile';
|
|
49
54
|
/** Normalize agent@version to use `@` consistently. */
|
|
50
55
|
export declare function formatAgentVersion(agent: AgentId, version: string): string;
|
|
51
56
|
/**
|
|
@@ -58,13 +63,17 @@ export declare function formatAgentVersion(agent: AgentId, version: string): str
|
|
|
58
63
|
* run.<agent@version>.tier.<cheap|default|best|ultra>
|
|
59
64
|
* interactive.host
|
|
60
65
|
* usage.primary-host
|
|
66
|
+
* auto.pool
|
|
61
67
|
* browser.profile
|
|
62
68
|
* project.root
|
|
69
|
+
* devices.<name>.role
|
|
63
70
|
* devices.<name>.max-agents
|
|
64
71
|
* devices.<name>.scheduler
|
|
65
72
|
* devices.<name>.daemon
|
|
66
73
|
* devices.<name>.watchdog
|
|
74
|
+
* devices.<name>.tmux
|
|
67
75
|
* devices.<name>.browser.remote-control
|
|
76
|
+
* devices.<name>.browser.task-idle-minutes
|
|
68
77
|
* devices.<name>.notes
|
|
69
78
|
* devices.<name>.browser.profile
|
|
70
79
|
*/
|
package/dist/lib/config-keys.js
CHANGED
|
@@ -10,11 +10,14 @@ import { AGENTS } from './agents.js';
|
|
|
10
10
|
import { MODEL_TIERS } from './model-tiers.js';
|
|
11
11
|
import { VERSION_RE } from './run-defaults.js';
|
|
12
12
|
const DEVICE_CONFIG_PROPERTIES = [
|
|
13
|
+
'role',
|
|
13
14
|
'max-agents',
|
|
14
15
|
'scheduler',
|
|
15
16
|
'daemon',
|
|
16
17
|
'watchdog',
|
|
18
|
+
'tmux',
|
|
17
19
|
'browser.remote-control',
|
|
20
|
+
'browser.task-idle-minutes',
|
|
18
21
|
'notes',
|
|
19
22
|
'browser.profile',
|
|
20
23
|
];
|
|
@@ -45,13 +48,17 @@ export function formatAgentVersion(agent, version) {
|
|
|
45
48
|
* run.<agent@version>.tier.<cheap|default|best|ultra>
|
|
46
49
|
* interactive.host
|
|
47
50
|
* usage.primary-host
|
|
51
|
+
* auto.pool
|
|
48
52
|
* browser.profile
|
|
49
53
|
* project.root
|
|
54
|
+
* devices.<name>.role
|
|
50
55
|
* devices.<name>.max-agents
|
|
51
56
|
* devices.<name>.scheduler
|
|
52
57
|
* devices.<name>.daemon
|
|
53
58
|
* devices.<name>.watchdog
|
|
59
|
+
* devices.<name>.tmux
|
|
54
60
|
* devices.<name>.browser.remote-control
|
|
61
|
+
* devices.<name>.browser.task-idle-minutes
|
|
55
62
|
* devices.<name>.notes
|
|
56
63
|
* devices.<name>.browser.profile
|
|
57
64
|
*/
|
|
@@ -75,13 +82,16 @@ export function parseConfigKey(key) {
|
|
|
75
82
|
if (raw === 'usage.primary-host') {
|
|
76
83
|
return { scope: 'usage', property: 'primary-host' };
|
|
77
84
|
}
|
|
85
|
+
if (raw === 'auto.pool') {
|
|
86
|
+
return { scope: 'auto', property: 'pool' };
|
|
87
|
+
}
|
|
78
88
|
if (raw === 'browser.profile') {
|
|
79
89
|
return { scope: 'browser', property: 'profile' };
|
|
80
90
|
}
|
|
81
91
|
if (raw === 'project.root') {
|
|
82
92
|
return { scope: 'project', property: 'root' };
|
|
83
93
|
}
|
|
84
|
-
const deviceMatch = raw.match(/^devices\.(.+)\.(max-agents|scheduler|daemon|watchdog|notes|browser\.remote-control|browser\.profile)$/);
|
|
94
|
+
const deviceMatch = raw.match(/^devices\.(.+)\.(role|max-agents|scheduler|daemon|watchdog|tmux|notes|browser\.remote-control|browser\.task-idle-minutes|browser\.profile)$/);
|
|
85
95
|
if (deviceMatch) {
|
|
86
96
|
return {
|
|
87
97
|
scope: 'device',
|
|
@@ -99,6 +109,9 @@ export function parseConfigKey(key) {
|
|
|
99
109
|
if (raw.startsWith('usage.')) {
|
|
100
110
|
throw new Error(`Invalid usage config key '${key}'. Use usage.primary-host.`);
|
|
101
111
|
}
|
|
112
|
+
if (raw.startsWith('auto.')) {
|
|
113
|
+
throw new Error(`Invalid auto config key '${key}'. Use auto.pool.`);
|
|
114
|
+
}
|
|
102
115
|
if (raw.startsWith('browser.')) {
|
|
103
116
|
throw new Error(`Invalid browser config key '${key}'. Use browser.profile.`);
|
|
104
117
|
}
|
|
@@ -108,7 +121,7 @@ export function parseConfigKey(key) {
|
|
|
108
121
|
if (raw.startsWith('devices.')) {
|
|
109
122
|
throw new Error(`Invalid device config key '${key}'. Expected devices.<name>.<${DEVICE_CONFIG_PROPERTIES.join('|')}>.`);
|
|
110
123
|
}
|
|
111
|
-
throw new Error(`Unknown config scope in '${key}'. Use one of: run, interactive, usage, browser, project, devices.`);
|
|
124
|
+
throw new Error(`Unknown config scope in '${key}'. Use one of: run, interactive, usage, auto, browser, project, devices.`);
|
|
112
125
|
}
|
|
113
126
|
/** Render a parsed key back to its canonical dotted string. */
|
|
114
127
|
export function formatConfigKey(parsed) {
|
|
@@ -122,6 +135,8 @@ export function formatConfigKey(parsed) {
|
|
|
122
135
|
return 'interactive.host';
|
|
123
136
|
case 'usage':
|
|
124
137
|
return 'usage.primary-host';
|
|
138
|
+
case 'auto':
|
|
139
|
+
return 'auto.pool';
|
|
125
140
|
case 'browser':
|
|
126
141
|
return parsed.device ? `devices.${parsed.device}.browser.profile` : 'browser.profile';
|
|
127
142
|
case 'project':
|
|
@@ -137,7 +152,7 @@ export function listKnownConfigKeys() {
|
|
|
137
152
|
for (const tier of MODEL_TIERS) {
|
|
138
153
|
keys.push(`run.<agent@version>.tier.${tier}`);
|
|
139
154
|
}
|
|
140
|
-
keys.push('interactive.host', 'usage.primary-host', 'browser.profile', 'project.root');
|
|
155
|
+
keys.push('interactive.host', 'usage.primary-host', 'auto.pool', 'browser.profile', 'project.root');
|
|
141
156
|
for (const prop of DEVICE_CONFIG_PROPERTIES) {
|
|
142
157
|
keys.push(`devices.<name>.${prop}`);
|
|
143
158
|
}
|
|
@@ -150,6 +165,8 @@ export function listKnownConfigKeys() {
|
|
|
150
165
|
*/
|
|
151
166
|
export function devicePropertyToConfigName(property) {
|
|
152
167
|
switch (property) {
|
|
168
|
+
case 'role':
|
|
169
|
+
return 'role';
|
|
153
170
|
case 'max-agents':
|
|
154
171
|
return 'agents.max-concurrent';
|
|
155
172
|
case 'scheduler':
|
|
@@ -158,8 +175,12 @@ export function devicePropertyToConfigName(property) {
|
|
|
158
175
|
return 'daemon.enabled';
|
|
159
176
|
case 'watchdog':
|
|
160
177
|
return 'watchdog.enabled';
|
|
178
|
+
case 'tmux':
|
|
179
|
+
return 'tmux.enabled';
|
|
161
180
|
case 'browser.remote-control':
|
|
162
181
|
return 'browser.remote-control';
|
|
182
|
+
case 'browser.task-idle-minutes':
|
|
183
|
+
return 'browser.task-idle-minutes';
|
|
163
184
|
case 'notes':
|
|
164
185
|
return 'notes';
|
|
165
186
|
case 'browser.profile':
|
|
@@ -181,13 +202,15 @@ export function configKeyStorageHint(parsed) {
|
|
|
181
202
|
return 'config.interactiveHost';
|
|
182
203
|
case 'usage':
|
|
183
204
|
return 'config.usagePrimaryHost';
|
|
205
|
+
case 'auto':
|
|
206
|
+
return 'config.autoPool';
|
|
184
207
|
case 'browser':
|
|
185
208
|
return parsed.device
|
|
186
|
-
? `
|
|
187
|
-
: '
|
|
209
|
+
? `devices/${parsed.device}/agents.yaml config.defaultBrowserProfile`
|
|
210
|
+
: 'devices/<self>/agents.yaml config.defaultBrowserProfile';
|
|
188
211
|
case 'project':
|
|
189
212
|
return 'devices.<self>.projectRoot';
|
|
190
213
|
case 'device':
|
|
191
|
-
return `
|
|
214
|
+
return `devices/${parsed.device}/agents.yaml config (${devicePropertyToConfigName(parsed.property)}; fleet default: fleet.defaults.config)`;
|
|
192
215
|
}
|
|
193
216
|
}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The YAML keys of every machine-visibility config key — the ones that live in
|
|
3
|
-
* the owning box's own `devices/<machine>/agents.yaml` and
|
|
4
|
-
* fleet
|
|
3
|
+
* the owning box's own `devices/<machine>/agents.yaml` and cannot be read or
|
|
4
|
+
* set for a peer. A fleet default may still live under
|
|
5
|
+
* `fleet.defaults.config` (the shared default layer); the peer restriction
|
|
6
|
+
* is about targeting another device, not about fleet policy.
|
|
5
7
|
*
|
|
6
8
|
* This is a ZERO-DEPENDENCY leaf on purpose. The authority is `CONFIG_KEYS` in
|
|
7
9
|
* `lib/device-config.ts`, but that module imports `devices/config-migration.ts`,
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The YAML keys of every machine-visibility config key — the ones that live in
|
|
3
|
-
* the owning box's own `devices/<machine>/agents.yaml` and
|
|
4
|
-
* fleet
|
|
3
|
+
* the owning box's own `devices/<machine>/agents.yaml` and cannot be read or
|
|
4
|
+
* set for a peer. A fleet default may still live under
|
|
5
|
+
* `fleet.defaults.config` (the shared default layer); the peer restriction
|
|
6
|
+
* is about targeting another device, not about fleet policy.
|
|
5
7
|
*
|
|
6
8
|
* This is a ZERO-DEPENDENCY leaf on purpose. The authority is `CONFIG_KEYS` in
|
|
7
9
|
* `lib/device-config.ts`, but that module imports `devices/config-migration.ts`,
|
|
@@ -14,4 +16,6 @@ export const MACHINE_LOCAL_YAML_KEYS = new Set([
|
|
|
14
16
|
'browserRemoteControl', // browser.remote-control — a consent flag; syncing it is a leak
|
|
15
17
|
'schedulerEnabled', // scheduler.enabled
|
|
16
18
|
'daemonEnabled', // daemon.enabled
|
|
19
|
+
'tmuxEnabled', // tmux.enabled — whether an interactive run is tmux-wrapped on THIS box
|
|
20
|
+
'browserTaskIdleMinutes', // browser.task-idle-minutes — only THIS box's reaper reads it
|
|
17
21
|
]);
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
*/
|
|
32
32
|
import { crabboxFind, crabboxList, crabboxStatusReady, crabboxWarmup, crabboxWaitReady, crabboxRunScript, crabboxStop, poolReusableBoxes } from './cli.js';
|
|
33
33
|
import * as yaml from 'yaml';
|
|
34
|
-
import { buildCredentialScript, buildHomeFileWriteScript, CLAUDE_TOKEN_REMOTE } from './runtimes.js';
|
|
34
|
+
import { assertNoNativeOAuthTransfer, buildCredentialScript, buildHomeFileWriteScript, CLAUDE_TOKEN_REMOTE } from './runtimes.js';
|
|
35
35
|
import { LEASE_AGENT_MARKER, leasePhaseSentinel } from './progress.js';
|
|
36
36
|
import { copySetupToBox } from './setup-copy.js';
|
|
37
37
|
import { DEFAULT_CRABBOX_PROFILE } from './config.js';
|
|
@@ -262,6 +262,14 @@ function reapExpiredPoolStrays(opts, keepSlug) {
|
|
|
262
262
|
return reaped;
|
|
263
263
|
}
|
|
264
264
|
export async function leaseAndRun(opts) {
|
|
265
|
+
// SING-1b, FAIL FAST: `buildBootstrapScript` below refuses to copy a native OAuth
|
|
266
|
+
// login (via `buildCredentialScript`), but that runs only AFTER a box has been
|
|
267
|
+
// leased — and a `--fresh` box would leak because the throw escapes the teardown
|
|
268
|
+
// `finally`. Refuse HERE, before any box is provisioned or paid for, mirroring how
|
|
269
|
+
// `--copy-creds` refuses before it opens an SSH connection.
|
|
270
|
+
assertNoNativeOAuthTransfer(opts.credentialRuntimes ?? opts.runtimes, opts.detected, {
|
|
271
|
+
claudeCredentialsJson: opts.claudeCredentialsJson,
|
|
272
|
+
});
|
|
265
273
|
const startedAt = Date.now();
|
|
266
274
|
let box;
|
|
267
275
|
// A box this run did NOT provision — either the caller named it (`--box`) or
|
|
@@ -26,6 +26,10 @@ interface RuntimeCred {
|
|
|
26
26
|
remote: string;
|
|
27
27
|
}
|
|
28
28
|
export declare const LEASE_RUNTIMES: RuntimeCred[];
|
|
29
|
+
/** True when `id` is a native OAuth / session login that MUST NOT be copied between devices (SING-1b). */
|
|
30
|
+
export declare function isNativeOAuthRuntime(id: AgentId): boolean;
|
|
31
|
+
/** The fail-loud message naming the forbidden runtimes and the portable path to use instead. */
|
|
32
|
+
export declare function nativeOAuthTransferRefusal(nativeRuntimes: AgentId[]): string;
|
|
29
33
|
export interface DetectedRuntime {
|
|
30
34
|
id: AgentId;
|
|
31
35
|
label: string;
|
|
@@ -96,15 +100,36 @@ export declare function resolveClaudeCredentialsBlob(opts?: {
|
|
|
96
100
|
accountEmail?: (home: string) => Promise<string | null>;
|
|
97
101
|
}): Promise<string | null>;
|
|
98
102
|
/**
|
|
99
|
-
*
|
|
100
|
-
* home-level config path (0600), from the token contents read locally. Returns
|
|
101
|
-
* `''` when no runtimes were selected. The snippet is meant to be embedded in
|
|
102
|
-
* the `--script-stdin` body (never argv).
|
|
103
|
+
* The credential-provisioning snippet for a `--lease` box.
|
|
103
104
|
*
|
|
104
|
-
*
|
|
105
|
-
* `
|
|
106
|
-
*
|
|
105
|
+
* Every runtime this could serialize is a native OAuth / session login
|
|
106
|
+
* (`LEASE_RUNTIMES`), and SING-1b forbids copying one to another device —
|
|
107
|
+
* including an ephemeral leased box, whose refresh of a shared rotating token
|
|
108
|
+
* invalidates every other holder. So this no longer writes a login: it REFUSES
|
|
109
|
+
* (throws, steering to the portable `agents accounts` path) whenever a picked
|
|
110
|
+
* runtime actually has a native credential to copy — signed in locally
|
|
111
|
+
* (`credPath`), or a Claude OAuth blob supplied. A picked runtime with nothing to
|
|
112
|
+
* copy is simply skipped, so `buildCredentialScript` returns `''` (a no-op box
|
|
113
|
+
* bootstrap) rather than throwing on a not-signed-in runtime.
|
|
107
114
|
*/
|
|
115
|
+
/**
|
|
116
|
+
* The native OAuth runtimes among `picked` that actually have a credential to copy
|
|
117
|
+
* — signed in locally (`credPath`) or a Claude OAuth blob supplied — i.e. the ones
|
|
118
|
+
* a transfer would leak. A picked runtime with nothing to copy is not refused.
|
|
119
|
+
*/
|
|
120
|
+
export declare function refusedNativeOAuthRuntimes(picked: AgentId[], detected: DetectedRuntime[], extras?: {
|
|
121
|
+
claudeCredentialsJson?: string | null;
|
|
122
|
+
}): AgentId[];
|
|
123
|
+
/**
|
|
124
|
+
* Throw the SING-1b refusal if any picked runtime would transfer a native OAuth
|
|
125
|
+
* login. Callers should invoke this at a FAIL-FAST point — before any expensive or
|
|
126
|
+
* costly side effect (e.g. before `crabboxWarmup` leases a paid box) — so a refused
|
|
127
|
+
* `--lease` never leaks infra, mirroring how `--copy-creds` refuses before it opens
|
|
128
|
+
* an SSH connection.
|
|
129
|
+
*/
|
|
130
|
+
export declare function assertNoNativeOAuthTransfer(picked: AgentId[], detected: DetectedRuntime[], extras?: {
|
|
131
|
+
claudeCredentialsJson?: string | null;
|
|
132
|
+
}): void;
|
|
108
133
|
export declare function buildCredentialScript(picked: AgentId[], detected: DetectedRuntime[], extras?: {
|
|
109
134
|
claudeCredentialsJson?: string | null;
|
|
110
135
|
}): string;
|
|
@@ -17,8 +17,8 @@ import * as path from 'path';
|
|
|
17
17
|
import * as fs from 'fs';
|
|
18
18
|
import { getAccountInfo } from '../agents.js';
|
|
19
19
|
import { getKeychainToken } from '../secrets/index.js';
|
|
20
|
-
import { getClaudeKeychainService } from '../usage.js';
|
|
21
|
-
import { listInstalledVersions, getVersionHomePath } from '../versions.js';
|
|
20
|
+
import { getClaudeKeychainService } from '../accounting/usage.js';
|
|
21
|
+
import { listInstalledVersions, getVersionHomePath } from '../installations/versions.js';
|
|
22
22
|
import { readClaudeCredentialsBlob } from '../cloud/rush.js';
|
|
23
23
|
export const LEASE_RUNTIMES = [
|
|
24
24
|
{ id: 'claude', label: 'Claude Code', localCandidates: ['.claude/.claude.json', '.claude.json'], remote: '.claude.json' },
|
|
@@ -26,6 +26,34 @@ export const LEASE_RUNTIMES = [
|
|
|
26
26
|
{ id: 'gemini', label: 'Gemini CLI', localCandidates: ['.gemini/google_accounts.json'], remote: '.gemini/google_accounts.json' },
|
|
27
27
|
{ id: 'grok', label: 'Grok CLI', localCandidates: ['.grok/auth.json'], remote: '.grok/auth.json' },
|
|
28
28
|
];
|
|
29
|
+
/**
|
|
30
|
+
* Every runtime whose login this module can serialize (`LEASE_RUNTIMES`) is a
|
|
31
|
+
* native, rotating OAuth / session credential (Claude OAuth token, codex/grok
|
|
32
|
+
* `auth.json`, gemini `google_accounts.json`). The fleet-auth contract forbids
|
|
33
|
+
* copying any of them between devices — including to an ephemeral leased box —
|
|
34
|
+
* because a shared refresh token rotates server-side on the next refresh and
|
|
35
|
+
* invalidates every other copy (`docs/specifications.md` SING-1b,
|
|
36
|
+
* `docs/credential-management.md` invariant 2). The set is derived from
|
|
37
|
+
* `LEASE_RUNTIMES` so a newly-added runtime can never be silently exempted. This
|
|
38
|
+
* is the single canonical predicate; `--copy-creds` (`hosts/credentials.ts`) and
|
|
39
|
+
* `--lease` (this module's `buildCredentialScript`) both refuse against it.
|
|
40
|
+
*/
|
|
41
|
+
const NATIVE_OAUTH_RUNTIMES = new Set(LEASE_RUNTIMES.map((c) => c.id));
|
|
42
|
+
/** True when `id` is a native OAuth / session login that MUST NOT be copied between devices (SING-1b). */
|
|
43
|
+
export function isNativeOAuthRuntime(id) {
|
|
44
|
+
return NATIVE_OAUTH_RUNTIMES.has(id);
|
|
45
|
+
}
|
|
46
|
+
/** The fail-loud message naming the forbidden runtimes and the portable path to use instead. */
|
|
47
|
+
export function nativeOAuthTransferRefusal(nativeRuntimes) {
|
|
48
|
+
return (`Refusing to copy native OAuth / session credentials to another device: ${nativeRuntimes.join(', ')}.\n` +
|
|
49
|
+
`A rotating harness login copied across machines is invalidated on its next server-side token ` +
|
|
50
|
+
`refresh — it logs the rest of the fleet out — so agents-cli never stores or transfers a harness's ` +
|
|
51
|
+
`interactive login (docs/specifications.md SING-1b).\n` +
|
|
52
|
+
`Use a portable provider account instead — a long-lived, non-rotating API key / setup-token that is ` +
|
|
53
|
+
`safe to reuse on many devices:\n` +
|
|
54
|
+
` agents accounts add <name> --provider <provider> --auth <api-key|setup-token>\n` +
|
|
55
|
+
` agents accounts sync <name> --device <host>`);
|
|
56
|
+
}
|
|
29
57
|
/** First existing candidate path under the real home, or null. */
|
|
30
58
|
function findLocalCred(cred) {
|
|
31
59
|
const home = process.env.AGENTS_REAL_HOME || os.homedir();
|
|
@@ -225,36 +253,50 @@ export async function resolveClaudeCredentialsBlob(opts) {
|
|
|
225
253
|
return readClaudeCredentialsBlob(home);
|
|
226
254
|
}
|
|
227
255
|
/**
|
|
228
|
-
*
|
|
229
|
-
* home-level config path (0600), from the token contents read locally. Returns
|
|
230
|
-
* `''` when no runtimes were selected. The snippet is meant to be embedded in
|
|
231
|
-
* the `--script-stdin` body (never argv).
|
|
256
|
+
* The credential-provisioning snippet for a `--lease` box.
|
|
232
257
|
*
|
|
233
|
-
*
|
|
234
|
-
* `
|
|
235
|
-
*
|
|
258
|
+
* Every runtime this could serialize is a native OAuth / session login
|
|
259
|
+
* (`LEASE_RUNTIMES`), and SING-1b forbids copying one to another device —
|
|
260
|
+
* including an ephemeral leased box, whose refresh of a shared rotating token
|
|
261
|
+
* invalidates every other holder. So this no longer writes a login: it REFUSES
|
|
262
|
+
* (throws, steering to the portable `agents accounts` path) whenever a picked
|
|
263
|
+
* runtime actually has a native credential to copy — signed in locally
|
|
264
|
+
* (`credPath`), or a Claude OAuth blob supplied. A picked runtime with nothing to
|
|
265
|
+
* copy is simply skipped, so `buildCredentialScript` returns `''` (a no-op box
|
|
266
|
+
* bootstrap) rather than throwing on a not-signed-in runtime.
|
|
236
267
|
*/
|
|
237
|
-
|
|
268
|
+
/**
|
|
269
|
+
* The native OAuth runtimes among `picked` that actually have a credential to copy
|
|
270
|
+
* — signed in locally (`credPath`) or a Claude OAuth blob supplied — i.e. the ones
|
|
271
|
+
* a transfer would leak. A picked runtime with nothing to copy is not refused.
|
|
272
|
+
*/
|
|
273
|
+
export function refusedNativeOAuthRuntimes(picked, detected, extras) {
|
|
238
274
|
const byId = new Map(detected.map((d) => [d.id, d]));
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
const
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
275
|
+
return picked.filter((id) => {
|
|
276
|
+
if (!isNativeOAuthRuntime(id))
|
|
277
|
+
return false;
|
|
278
|
+
const hasLocalFile = !!byId.get(id)?.credPath && LEASE_RUNTIMES.some((c) => c.id === id);
|
|
279
|
+
const hasClaudeToken = id === 'claude' && !!extras?.claudeCredentialsJson;
|
|
280
|
+
return hasLocalFile || hasClaudeToken;
|
|
281
|
+
});
|
|
282
|
+
}
|
|
283
|
+
/**
|
|
284
|
+
* Throw the SING-1b refusal if any picked runtime would transfer a native OAuth
|
|
285
|
+
* login. Callers should invoke this at a FAIL-FAST point — before any expensive or
|
|
286
|
+
* costly side effect (e.g. before `crabboxWarmup` leases a paid box) — so a refused
|
|
287
|
+
* `--lease` never leaks infra, mirroring how `--copy-creds` refuses before it opens
|
|
288
|
+
* an SSH connection.
|
|
289
|
+
*/
|
|
290
|
+
export function assertNoNativeOAuthTransfer(picked, detected, extras) {
|
|
291
|
+
const refused = refusedNativeOAuthRuntimes(picked, detected, extras);
|
|
292
|
+
if (refused.length > 0) {
|
|
293
|
+
throw new Error(nativeOAuthTransferRefusal(refused));
|
|
258
294
|
}
|
|
259
|
-
|
|
295
|
+
}
|
|
296
|
+
export function buildCredentialScript(picked, detected, extras) {
|
|
297
|
+
assertNoNativeOAuthTransfer(picked, detected, extras);
|
|
298
|
+
// Past the refusal there is nothing to serialize — every runtime this handles is
|
|
299
|
+
// native OAuth, so a non-refused set has no credential to copy. (Always '' today;
|
|
300
|
+
// the shape stays general in case a non-native runtime is ever added.)
|
|
301
|
+
return '';
|
|
260
302
|
}
|