@phnx-labs/agents-cli 1.22.39 → 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 +294 -0
- package/README.md +111 -70
- package/dist/bin/agents +0 -0
- package/dist/bootstrap.js +45 -26
- 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 +16 -3
- 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 +160 -215
- 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 +186 -64
- 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 +2 -1
- package/dist/lib/config-keys.js +8 -4
- package/dist/lib/config-machine-keys.d.ts +4 -2
- package/dist/lib/config-machine-keys.js +5 -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 +85 -75
- package/dist/lib/device-config.js +279 -141
- 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 +10 -5
- package/dist/lib/devices/pool.js +5 -7
- 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 +4 -4
- package/dist/lib/exec.js +11 -11
- 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} +13 -1
- package/dist/lib/{migrate.js → installations/migrate.js} +160 -40
- 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 +4 -4
- package/dist/lib/smart-launch.js +6 -4
- 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
package/dist/commands/webhook.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as path from 'path';
|
|
2
2
|
import chalk from 'chalk';
|
|
3
3
|
import { readAndResolveBundleEnv } from '../lib/secrets/bundles.js';
|
|
4
|
-
import { createFileDeliveryStore, startWebhookServer } from '../lib/triggers/webhook.js';
|
|
4
|
+
import { createFileDeliveryStore, startWebhookServer, waitForListening } from '../lib/triggers/webhook.js';
|
|
5
5
|
import { getRuntimeStateDir } from '../lib/state.js';
|
|
6
6
|
const DEFAULT_HOST = '127.0.0.1';
|
|
7
7
|
const DEFAULT_PORT = 8787;
|
|
@@ -30,26 +30,6 @@ function readWebhookSecrets(bundleName) {
|
|
|
30
30
|
}
|
|
31
31
|
return secrets;
|
|
32
32
|
}
|
|
33
|
-
function waitForListening(server) {
|
|
34
|
-
if (server.listening)
|
|
35
|
-
return Promise.resolve();
|
|
36
|
-
return new Promise((resolve, reject) => {
|
|
37
|
-
const cleanup = () => {
|
|
38
|
-
server.off('listening', onListening);
|
|
39
|
-
server.off('error', onError);
|
|
40
|
-
};
|
|
41
|
-
const onListening = () => {
|
|
42
|
-
cleanup();
|
|
43
|
-
resolve();
|
|
44
|
-
};
|
|
45
|
-
const onError = (err) => {
|
|
46
|
-
cleanup();
|
|
47
|
-
reject(err);
|
|
48
|
-
};
|
|
49
|
-
server.once('listening', onListening);
|
|
50
|
-
server.once('error', onError);
|
|
51
|
-
});
|
|
52
|
-
}
|
|
53
33
|
export function registerWebhooksCommand(program) {
|
|
54
34
|
const webhooks = program
|
|
55
35
|
.command('webhooks')
|
|
@@ -58,7 +38,7 @@ export function registerWebhooksCommand(program) {
|
|
|
58
38
|
.command('serve')
|
|
59
39
|
.description('Receive signed GitHub/Linear webhooks on /hooks/<source> and fire matching routines.')
|
|
60
40
|
.requiredOption('--secrets-bundle <name>', 'agents secrets bundle containing GITHUB_WEBHOOK_SECRET and/or LINEAR_WEBHOOK_SECRET')
|
|
61
|
-
.option('--
|
|
41
|
+
.option('--bind <addr>', `Bind address (default ${DEFAULT_HOST})`, DEFAULT_HOST)
|
|
62
42
|
.option('-p, --port <n>', `Local port (default ${DEFAULT_PORT})`, String(DEFAULT_PORT))
|
|
63
43
|
.option('--rate-limit <n>', 'Accepted deliveries per source per minute', '60')
|
|
64
44
|
.action(async (opts) => {
|
|
@@ -74,7 +54,7 @@ export function registerWebhooksCommand(program) {
|
|
|
74
54
|
const rateLimit = positiveInt(opts.rateLimit, 60);
|
|
75
55
|
try {
|
|
76
56
|
const server = startWebhookServer({
|
|
77
|
-
host: opts.
|
|
57
|
+
host: opts.bind ?? DEFAULT_HOST,
|
|
78
58
|
port,
|
|
79
59
|
secrets,
|
|
80
60
|
rateLimitPerMinute: rateLimit,
|
|
@@ -90,12 +70,18 @@ export function registerWebhooksCommand(program) {
|
|
|
90
70
|
console.log(`${new Date().toISOString()} ${webhook.source}:${webhook.event} ` +
|
|
91
71
|
(parts.length ? `fired ${parts.join('; ')}` : 'no match'));
|
|
92
72
|
},
|
|
73
|
+
// The delivery is acked 202 before dispatch (RUSH-2548), so a dispatch
|
|
74
|
+
// failure has no HTTP status left to ride — print it instead.
|
|
75
|
+
onDeliveryError: (webhook, err) => {
|
|
76
|
+
console.error(chalk.red(`${new Date().toISOString()} ${webhook.source}:${webhook.event} dispatch failed after ack: ${err.message}`));
|
|
77
|
+
},
|
|
93
78
|
});
|
|
94
79
|
await waitForListening(server);
|
|
95
80
|
const address = server.address();
|
|
96
81
|
const bound = typeof address === 'object' && address ? address.port : port;
|
|
97
|
-
console.log(`${chalk.green('agents webhooks')} ${chalk.dim('→')} ${chalk.cyan(`http://${opts.
|
|
98
|
-
console.log(chalk.dim('signed · localhost by default · endpoints: /hooks/github, /hooks/linear · Ctrl-C to stop'));
|
|
82
|
+
console.log(`${chalk.green('agents webhooks')} ${chalk.dim('→')} ${chalk.cyan(`http://${opts.bind ?? DEFAULT_HOST}:${bound}`)}`);
|
|
83
|
+
console.log(chalk.dim('signed · localhost by default · endpoints: /hooks/github, /hooks/linear · acks 202 then dispatches · Ctrl-C to stop'));
|
|
84
|
+
console.log(chalk.dim('for a supervised receiver that survives reboot: agents daemon webhooks add --secrets-bundle <name>'));
|
|
99
85
|
const shutdown = () => {
|
|
100
86
|
server.close(() => process.exit(0));
|
|
101
87
|
};
|
|
@@ -8,7 +8,7 @@ import { resolveAgentName, agentLabel } from '../lib/agents.js';
|
|
|
8
8
|
import { capableAgents } from '../lib/capabilities.js';
|
|
9
9
|
import { cloneRepo } from '../lib/git.js';
|
|
10
10
|
import { discoverWorkflowsFromRepo, installWorkflowCentrally, removeWorkflow, listInstalledWorkflows, listWorkflowsForAgent, removeWorkflowFromVersion, iterWorkflowsCapableVersions, } from '../lib/workflows.js';
|
|
11
|
-
import { getVersionHomePath, getGlobalDefault, syncResourcesToVersion, promptAgentVersionSelection, } from '../lib/versions.js';
|
|
11
|
+
import { getVersionHomePath, getGlobalDefault, syncResourcesToVersion, promptAgentVersionSelection, } from '../lib/installations/versions.js';
|
|
12
12
|
import { recordVersionResources, getUserWorkflowsDir } from '../lib/state.js';
|
|
13
13
|
import { isPromptCancelled, isInteractiveTerminal, requireInteractiveSelection, printWithPager, promptRemovalTargets, parseCommaSeparatedList, resolveAgentTargetsAutoInstalling, resolveListFilterOrExit, } from './utils.js';
|
|
14
14
|
import { showResourceList, buildTargetsSection, } from './resource-view.js';
|
package/dist/index.js
CHANGED
|
@@ -71,7 +71,7 @@ if (process.argv[2] === '__shim') {
|
|
|
71
71
|
process.exit(code);
|
|
72
72
|
}
|
|
73
73
|
if (process.argv[2] === '__daemon-run') {
|
|
74
|
-
const { runDaemon, log: daemonLog } = await import('./lib/daemon.js');
|
|
74
|
+
const { runDaemon, log: daemonLog } = await import('./lib/daemon/daemon.js');
|
|
75
75
|
// RUSH-2418: the daemon is the one always-on process here, and it ran with no
|
|
76
76
|
// top-level handler of any kind — an uncaught throw or a rejected promise from
|
|
77
77
|
// any of its background ticks died on Node's default handler, printing a raw
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { AgentId } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* How safely agents-cli can read a harness's native login identity, and at what
|
|
4
|
+
* granularity that identity is scoped.
|
|
5
|
+
*
|
|
6
|
+
* - `inspection`: `strong` = a stable account key (Claude/Codex/Grok);
|
|
7
|
+
* `email` = only an email claim, so the name binds to an address not a token
|
|
8
|
+
* (Muse); `opaque` = a stable but non-human identifier from an OAuth/JWT blob
|
|
9
|
+
* with no email (the device-scoped harnesses); `none` = no inspectable identity.
|
|
10
|
+
* - `scope`: `version` = auth lives per installed version home; `device` = one
|
|
11
|
+
* login per device shared by every install; `unsupported` = agents-cli must not
|
|
12
|
+
* name/attach this harness's native login.
|
|
13
|
+
* - `status`: `supported` = name + attach safely; `conditional` = supported only
|
|
14
|
+
* when the weaker (email) identity is present; `discovery-only` = shown in the
|
|
15
|
+
* list but not nameable; `unsupported` = neither.
|
|
16
|
+
*/
|
|
17
|
+
export interface NativeAccountCapability {
|
|
18
|
+
inspection: 'strong' | 'email' | 'opaque' | 'none';
|
|
19
|
+
scope: 'version' | 'device' | 'unsupported';
|
|
20
|
+
status: 'supported' | 'conditional' | 'discovery-only' | 'unsupported';
|
|
21
|
+
}
|
|
22
|
+
/** Canonical truth for native-account naming and attachment semantics. */
|
|
23
|
+
export declare const NATIVE_ACCOUNT_CAPABILITIES: Record<AgentId, NativeAccountCapability>;
|
|
24
|
+
export declare function nativeAccountCapability(agent: AgentId): NativeAccountCapability;
|
|
25
|
+
/** Whether a harness's native login can be named/attached (supported or conditional). */
|
|
26
|
+
export declare function nativeAccountNameable(agent: AgentId): boolean;
|
|
27
|
+
/**
|
|
28
|
+
* The single identity key used at `accounts name`, attach, exec validation,
|
|
29
|
+
* view, and inventory. Prefer the harness's stable `accountKey`. For an
|
|
30
|
+
* email-only (`conditional`) harness, email is a presence gate — the stored
|
|
31
|
+
* key is still `accountKey` (e.g. `muse:email=user@x.com`), never the bare
|
|
32
|
+
* address, so `run`/`view` compare against the same value `getAccountInfo`
|
|
33
|
+
* returns.
|
|
34
|
+
*/
|
|
35
|
+
export declare function nativeIdentityKey(info: {
|
|
36
|
+
signedIn?: boolean;
|
|
37
|
+
email?: string | null;
|
|
38
|
+
accountKey?: string | null;
|
|
39
|
+
}, capability: NativeAccountCapability): string | null;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/** Canonical truth for native-account naming and attachment semantics. */
|
|
2
|
+
export const NATIVE_ACCOUNT_CAPABILITIES = {
|
|
3
|
+
// Version-scoped with a strong account key — the only harnesses whose native
|
|
4
|
+
// identity is safe to pin per installed version.
|
|
5
|
+
claude: { inspection: 'strong', scope: 'version', status: 'supported' },
|
|
6
|
+
codex: { inspection: 'strong', scope: 'version', status: 'supported' },
|
|
7
|
+
grok: { inspection: 'strong', scope: 'version', status: 'supported' },
|
|
8
|
+
// Version-scoped but only an email identity — nameable only when that email is
|
|
9
|
+
// present (the resolver rejects an emailless Muse login).
|
|
10
|
+
muse: { inspection: 'email', scope: 'version', status: 'conditional' },
|
|
11
|
+
// Device-scoped, opaque identity (an OAuth/JWT blob). These are recorded as
|
|
12
|
+
// device-scoped opaque, but marked UNSUPPORTED for naming: a NativeAccount has
|
|
13
|
+
// no device-id discriminator, so an opaque/singleton identity cannot be proven
|
|
14
|
+
// to distinguish accounts across synced metadata — Droid exposes no account key
|
|
15
|
+
// at all, and Antigravity (singleton) / OpenCode (provider-set) can read two
|
|
16
|
+
// different credentials as the same identity on another device. A truthful
|
|
17
|
+
// "unsupported" is correct until a device-scoped identity key (with a stable
|
|
18
|
+
// device id) exists to validate against.
|
|
19
|
+
antigravity: { inspection: 'opaque', scope: 'device', status: 'unsupported' },
|
|
20
|
+
kimi: { inspection: 'opaque', scope: 'device', status: 'unsupported' },
|
|
21
|
+
droid: { inspection: 'opaque', scope: 'device', status: 'unsupported' },
|
|
22
|
+
opencode: { inspection: 'opaque', scope: 'device', status: 'unsupported' },
|
|
23
|
+
// Cursor multi-account isolation is unresolved (RUSH-2400) — blocked from
|
|
24
|
+
// native naming/attachment; its API-key path is a provider account instead.
|
|
25
|
+
cursor: { inspection: 'none', scope: 'unsupported', status: 'unsupported' },
|
|
26
|
+
// Discoverable in the list, but not nameable.
|
|
27
|
+
gemini: { inspection: 'email', scope: 'unsupported', status: 'discovery-only' },
|
|
28
|
+
copilot: { inspection: 'none', scope: 'unsupported', status: 'unsupported' },
|
|
29
|
+
openclaw: { inspection: 'none', scope: 'unsupported', status: 'unsupported' },
|
|
30
|
+
amp: { inspection: 'none', scope: 'unsupported', status: 'unsupported' },
|
|
31
|
+
kiro: { inspection: 'none', scope: 'unsupported', status: 'unsupported' },
|
|
32
|
+
goose: { inspection: 'none', scope: 'unsupported', status: 'unsupported' },
|
|
33
|
+
hermes: { inspection: 'none', scope: 'unsupported', status: 'unsupported' },
|
|
34
|
+
pi: { inspection: 'none', scope: 'unsupported', status: 'unsupported' },
|
|
35
|
+
warp: { inspection: 'none', scope: 'unsupported', status: 'unsupported' },
|
|
36
|
+
};
|
|
37
|
+
export function nativeAccountCapability(agent) {
|
|
38
|
+
return NATIVE_ACCOUNT_CAPABILITIES[agent];
|
|
39
|
+
}
|
|
40
|
+
/** Whether a harness's native login can be named/attached (supported or conditional). */
|
|
41
|
+
export function nativeAccountNameable(agent) {
|
|
42
|
+
const cap = NATIVE_ACCOUNT_CAPABILITIES[agent];
|
|
43
|
+
return (cap.status === 'supported' || cap.status === 'conditional') && cap.scope !== 'unsupported';
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* The single identity key used at `accounts name`, attach, exec validation,
|
|
47
|
+
* view, and inventory. Prefer the harness's stable `accountKey`. For an
|
|
48
|
+
* email-only (`conditional`) harness, email is a presence gate — the stored
|
|
49
|
+
* key is still `accountKey` (e.g. `muse:email=user@x.com`), never the bare
|
|
50
|
+
* address, so `run`/`view` compare against the same value `getAccountInfo`
|
|
51
|
+
* returns.
|
|
52
|
+
*/
|
|
53
|
+
export function nativeIdentityKey(info, capability) {
|
|
54
|
+
if (!info.signedIn)
|
|
55
|
+
return null;
|
|
56
|
+
if (capability.inspection === 'email' && !info.email)
|
|
57
|
+
return null;
|
|
58
|
+
return info.accountKey ?? info.email?.toLowerCase() ?? null;
|
|
59
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ALL_AGENT_IDS, getAccountInfo, supportsAccountInspection } from './agents.js';
|
|
2
|
-
import { getVersionHomePath, listInstalledVersions } from './versions.js';
|
|
2
|
+
import { getVersionHomePath, listInstalledVersions } from './installations/versions.js';
|
|
3
3
|
export function groupNativeAccountRows(rows) {
|
|
4
4
|
const grouped = new Map();
|
|
5
5
|
for (const row of rows) {
|
|
@@ -19,12 +19,42 @@ export interface ResolvedCredentialAccount {
|
|
|
19
19
|
auth: AccountAuthKind;
|
|
20
20
|
env: Record<string, string>;
|
|
21
21
|
}
|
|
22
|
+
export interface NativeAccount {
|
|
23
|
+
id: string;
|
|
24
|
+
name: string;
|
|
25
|
+
kind: 'native';
|
|
26
|
+
agent: AgentId;
|
|
27
|
+
identityKey: string;
|
|
28
|
+
identityLabel?: string;
|
|
29
|
+
scope: 'version' | 'device';
|
|
30
|
+
}
|
|
31
|
+
export type UnifiedAccount = (CredentialAccount & {
|
|
32
|
+
kind: 'provider';
|
|
33
|
+
}) | NativeAccount;
|
|
22
34
|
export declare function accountRegistryPath(base?: string): string;
|
|
23
35
|
export declare function readAccountRegistry(base?: string): AccountRegistryDocument;
|
|
24
36
|
export declare function findAccount(name: string, doc?: AccountRegistryDocument): CredentialAccount | null;
|
|
37
|
+
export declare function listNativeAccounts(meta: Pick<Meta, 'accounts'>): NativeAccount[];
|
|
38
|
+
/**
|
|
39
|
+
* Resolve one account by name or id across both stores, native first.
|
|
40
|
+
*
|
|
41
|
+
* `doc` is optional and read LAZILY: a native match returns without ever reading
|
|
42
|
+
* the provider bundle registry — so a native view/attach/run never triggers a
|
|
43
|
+
* bundle read, legacy-`accounts.yaml` migration, or a keychain decrypt (which
|
|
44
|
+
* would surface a Touch ID prompt or crash on an undecryptable legacy item). A
|
|
45
|
+
* default-evaluated `doc = readAccountRegistry()` argument would defeat this by
|
|
46
|
+
* running before the body, so callers that only need a native lookup must be
|
|
47
|
+
* able to omit it.
|
|
48
|
+
*/
|
|
49
|
+
export declare function findUnifiedAccount(nameOrId: string, meta: Pick<Meta, 'accounts'>, doc?: AccountRegistryDocument): UnifiedAccount | null;
|
|
50
|
+
export declare function addNativeAccount(name: string, agent: AgentId, identityKey: string, identityLabel: string | undefined, scope: 'version' | 'device'): NativeAccount;
|
|
51
|
+
export declare function bindAccount(nameOrId: string, target: string): UnifiedAccount;
|
|
52
|
+
export declare function unbindAccount(nameOrId: string, target: string): void;
|
|
53
|
+
export declare function accountBindings(accountId: string, meta: Pick<Meta, 'accounts'>): string[];
|
|
25
54
|
/** Explicit selection wins over a configured per-harness default. */
|
|
26
55
|
export declare function resolveAccountSelection(explicit: string | undefined, agent: AgentId, meta: Pick<Meta, 'accounts'>, opts?: {
|
|
27
56
|
useDefault?: boolean;
|
|
57
|
+
target?: string;
|
|
28
58
|
}): string | undefined;
|
|
29
59
|
export interface AddAccountOptions {
|
|
30
60
|
baseUrl?: string;
|
|
@@ -38,3 +68,39 @@ export declare function inspectAccount(name: string, base?: string): CredentialA
|
|
|
38
68
|
policy: 'never';
|
|
39
69
|
};
|
|
40
70
|
export declare function resolveCredentialAccount(name: string, host: AgentId, expectedProvider?: string, base?: string): ResolvedCredentialAccount;
|
|
71
|
+
/** The account a spawn should launch under, classified for the exec path. */
|
|
72
|
+
export type SpawnAccount = {
|
|
73
|
+
kind: 'provider';
|
|
74
|
+
id: string;
|
|
75
|
+
name: string;
|
|
76
|
+
agent: AgentId;
|
|
77
|
+
env: Record<string, string>;
|
|
78
|
+
} | {
|
|
79
|
+
kind: 'native';
|
|
80
|
+
id: string;
|
|
81
|
+
name: string;
|
|
82
|
+
agent: AgentId;
|
|
83
|
+
identityKey: string;
|
|
84
|
+
scope: 'version' | 'device';
|
|
85
|
+
};
|
|
86
|
+
/**
|
|
87
|
+
* Resolve the account a run should launch under, following the binding order
|
|
88
|
+
* (explicit → exact `agent@version` → device-scoped `agent` → per-harness
|
|
89
|
+
* default) and classifying the result:
|
|
90
|
+
*
|
|
91
|
+
* - **provider** → the injected env is resolved here (fails closed when the
|
|
92
|
+
* credential is absent or the provider cannot authenticate the host).
|
|
93
|
+
* - **native** → returns the identity the caller must confirm is live on the
|
|
94
|
+
* execution device; **no secret or env is produced**, because a native login
|
|
95
|
+
* is owned by the harness and read from its own home. The caller validates the
|
|
96
|
+
* live fingerprint against the installed version before spawn.
|
|
97
|
+
*
|
|
98
|
+
* A native account bound to a different harness than the one being launched
|
|
99
|
+
* fails loudly (EXEC-ACCOUNT-4). Returns null when nothing is selected.
|
|
100
|
+
*/
|
|
101
|
+
export declare function resolveSpawnAccount(explicit: string | undefined, agent: AgentId, version: string | undefined, meta: Pick<Meta, 'accounts'>, opts?: {
|
|
102
|
+
useDefault?: boolean;
|
|
103
|
+
provider?: string;
|
|
104
|
+
base?: string;
|
|
105
|
+
target?: string;
|
|
106
|
+
}): SpawnAccount | null;
|
|
@@ -19,7 +19,7 @@ import * as path from 'node:path';
|
|
|
19
19
|
import * as crypto from 'node:crypto';
|
|
20
20
|
import * as yaml from 'yaml';
|
|
21
21
|
import { atomicWriteFileSync } from './fs-atomic.js';
|
|
22
|
-
import { getUserAgentsDir } from './state.js';
|
|
22
|
+
import { getUserAgentsDir, readMeta, updateMeta } from './state.js';
|
|
23
23
|
import { deleteKeychainToken, getKeychainToken, hasKeychainToken } from './secrets/index.js';
|
|
24
24
|
import { bundleExists, deleteBundle, listBundles, readBundle, renameBundle, writeBundleWithItems } from './secrets/bundles.js';
|
|
25
25
|
import { getAccountProvider } from './account-provider-registry.js';
|
|
@@ -128,10 +128,85 @@ export function readAccountRegistry(base = getUserAgentsDir()) {
|
|
|
128
128
|
export function findAccount(name, doc = readAccountRegistry()) {
|
|
129
129
|
return doc.accounts[name] ?? Object.values(doc.accounts).find(account => account.name === name) ?? null;
|
|
130
130
|
}
|
|
131
|
+
export function listNativeAccounts(meta) {
|
|
132
|
+
return Object.values(meta.accounts?.native ?? {}).map(account => ({ ...account, kind: 'native' }));
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Resolve one account by name or id across both stores, native first.
|
|
136
|
+
*
|
|
137
|
+
* `doc` is optional and read LAZILY: a native match returns without ever reading
|
|
138
|
+
* the provider bundle registry — so a native view/attach/run never triggers a
|
|
139
|
+
* bundle read, legacy-`accounts.yaml` migration, or a keychain decrypt (which
|
|
140
|
+
* would surface a Touch ID prompt or crash on an undecryptable legacy item). A
|
|
141
|
+
* default-evaluated `doc = readAccountRegistry()` argument would defeat this by
|
|
142
|
+
* running before the body, so callers that only need a native lookup must be
|
|
143
|
+
* able to omit it.
|
|
144
|
+
*/
|
|
145
|
+
export function findUnifiedAccount(nameOrId, meta, doc) {
|
|
146
|
+
const native = listNativeAccounts(meta).find(account => account.id === nameOrId || account.name === nameOrId);
|
|
147
|
+
if (native)
|
|
148
|
+
return native;
|
|
149
|
+
const provider = findAccount(nameOrId, doc ?? readAccountRegistry());
|
|
150
|
+
return provider ? { ...provider, kind: 'provider' } : null;
|
|
151
|
+
}
|
|
152
|
+
function assertUniqueUnifiedName(name, meta, doc) {
|
|
153
|
+
if (findUnifiedAccount(name, meta, doc))
|
|
154
|
+
throw new Error(`Account '${name}' already exists.`);
|
|
155
|
+
}
|
|
156
|
+
export function addNativeAccount(name, agent, identityKey, identityLabel, scope) {
|
|
157
|
+
assertName(name);
|
|
158
|
+
const meta = readMeta();
|
|
159
|
+
assertUniqueUnifiedName(name, meta);
|
|
160
|
+
const duplicate = listNativeAccounts(meta).find(account => account.agent === agent && account.identityKey === identityKey);
|
|
161
|
+
if (duplicate)
|
|
162
|
+
throw new Error(`This ${agent} login is already named '${duplicate.name}'.`);
|
|
163
|
+
const account = { id: crypto.randomUUID(), name, kind: 'native', agent, identityKey, identityLabel, scope };
|
|
164
|
+
updateMeta(current => ({
|
|
165
|
+
...current,
|
|
166
|
+
accounts: {
|
|
167
|
+
...current.accounts,
|
|
168
|
+
native: { ...current.accounts?.native, [account.id]: { id: account.id, name, agent, identityKey, identityLabel, scope } },
|
|
169
|
+
},
|
|
170
|
+
}));
|
|
171
|
+
return account;
|
|
172
|
+
}
|
|
173
|
+
export function bindAccount(nameOrId, target) {
|
|
174
|
+
const meta = readMeta();
|
|
175
|
+
const account = findUnifiedAccount(nameOrId, meta);
|
|
176
|
+
if (!account)
|
|
177
|
+
throw new Error(`Unknown account '${nameOrId}'.`);
|
|
178
|
+
updateMeta(current => ({
|
|
179
|
+
...current,
|
|
180
|
+
accounts: { ...current.accounts, bindings: { ...current.accounts?.bindings, [target]: account.id } },
|
|
181
|
+
}));
|
|
182
|
+
return account;
|
|
183
|
+
}
|
|
184
|
+
export function unbindAccount(nameOrId, target) {
|
|
185
|
+
const meta = readMeta();
|
|
186
|
+
const account = findUnifiedAccount(nameOrId, meta);
|
|
187
|
+
if (!account)
|
|
188
|
+
throw new Error(`Unknown account '${nameOrId}'.`);
|
|
189
|
+
if (meta.accounts?.bindings?.[target] !== account.id)
|
|
190
|
+
throw new Error(`Account '${account.name}' is not attached to '${target}'.`);
|
|
191
|
+
updateMeta(current => {
|
|
192
|
+
const bindings = { ...current.accounts?.bindings };
|
|
193
|
+
delete bindings[target];
|
|
194
|
+
return { ...current, accounts: { ...current.accounts, bindings } };
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
export function accountBindings(accountId, meta) {
|
|
198
|
+
return Object.entries(meta.accounts?.bindings ?? {}).filter(([, id]) => id === accountId).map(([target]) => target).sort();
|
|
199
|
+
}
|
|
131
200
|
/** Explicit selection wins over a configured per-harness default. */
|
|
132
201
|
export function resolveAccountSelection(explicit, agent, meta, opts = {}) {
|
|
133
202
|
if (explicit)
|
|
134
203
|
return explicit;
|
|
204
|
+
const bound = opts.target ? meta.accounts?.bindings?.[opts.target] : undefined;
|
|
205
|
+
if (bound)
|
|
206
|
+
return bound;
|
|
207
|
+
const deviceScoped = meta.accounts?.bindings?.[agent];
|
|
208
|
+
if (deviceScoped)
|
|
209
|
+
return deviceScoped;
|
|
135
210
|
return opts.useDefault === false ? undefined : meta.accounts?.defaults?.[agent];
|
|
136
211
|
}
|
|
137
212
|
function profileConsumers(name, base) {
|
|
@@ -158,12 +233,11 @@ function renameProfileConsumers(oldName, newName, base) {
|
|
|
158
233
|
}
|
|
159
234
|
export function addAccount(name, provider, auth, secret, base = getUserAgentsDir(), opts = {}) {
|
|
160
235
|
assertName(name);
|
|
236
|
+
assertUniqueUnifiedName(name, readMeta(), readAccountRegistry(base));
|
|
161
237
|
const adapter = getAccountProvider(provider);
|
|
162
238
|
adapter.validate(auth, secret);
|
|
163
239
|
if (bundleExists(name))
|
|
164
240
|
throw new Error(`Secrets bundle '${name}' already exists. Choose a different account name.`);
|
|
165
|
-
if (findAccount(name, readAccountRegistry(base)))
|
|
166
|
-
throw new Error(`Account '${name}' already exists.`);
|
|
167
241
|
const record = { id: crypto.randomUUID(), name, provider: adapter.provider, auth, baseUrl: opts.baseUrl };
|
|
168
242
|
const { bundle, items } = buildAccountBundle(record, secret);
|
|
169
243
|
writeBundleWithItems(bundle, items);
|
|
@@ -182,18 +256,49 @@ export function setAccountSecret(name, secret, base = getUserAgentsDir()) {
|
|
|
182
256
|
export function renameAccount(oldName, newName, base = getUserAgentsDir()) {
|
|
183
257
|
assertName(newName);
|
|
184
258
|
const doc = readAccountRegistry(base);
|
|
259
|
+
const meta = readMeta();
|
|
260
|
+
const native = listNativeAccounts(meta).find(account => account.id === oldName || account.name === oldName);
|
|
261
|
+
if (native) {
|
|
262
|
+
assertUniqueUnifiedName(newName, meta, doc);
|
|
263
|
+
updateMeta(current => ({
|
|
264
|
+
...current,
|
|
265
|
+
accounts: {
|
|
266
|
+
...current.accounts,
|
|
267
|
+
native: { ...current.accounts?.native, [native.id]: { ...current.accounts?.native?.[native.id], name: newName } },
|
|
268
|
+
},
|
|
269
|
+
}));
|
|
270
|
+
return;
|
|
271
|
+
}
|
|
185
272
|
const account = findAccount(oldName, doc);
|
|
186
273
|
if (!account)
|
|
187
274
|
throw new Error(`Unknown account '${oldName}'.`);
|
|
188
|
-
|
|
189
|
-
throw new Error(`Account '${newName}' already exists.`);
|
|
275
|
+
assertUniqueUnifiedName(newName, meta, doc);
|
|
190
276
|
renameBundle(account.name, newName); // moves metadata + secret, preserves ACCOUNT_ID
|
|
191
277
|
renameProfileConsumers(account.name, newName, base);
|
|
192
278
|
}
|
|
193
279
|
export function removeAccount(name, base = getUserAgentsDir()) {
|
|
280
|
+
const meta = readMeta();
|
|
281
|
+
const native = listNativeAccounts(meta).find(account => account.id === name || account.name === name);
|
|
282
|
+
if (native) {
|
|
283
|
+
const bindings = accountBindings(native.id, meta);
|
|
284
|
+
if (bindings.length)
|
|
285
|
+
throw new Error(`Account '${native.name}' is attached to: ${bindings.join(', ')}. Detach it before removing it.`);
|
|
286
|
+
updateMeta(current => {
|
|
287
|
+
const accounts = { ...current.accounts?.native };
|
|
288
|
+
delete accounts[native.id];
|
|
289
|
+
return { ...current, accounts: { ...current.accounts, native: accounts } };
|
|
290
|
+
});
|
|
291
|
+
return;
|
|
292
|
+
}
|
|
194
293
|
const account = findAccount(name, readAccountRegistry(base));
|
|
195
294
|
if (!account)
|
|
196
295
|
throw new Error(`Unknown account '${name}'.`);
|
|
296
|
+
const bindings = accountBindings(account.id, meta);
|
|
297
|
+
const defaults = Object.entries(meta.accounts?.defaults ?? {}).filter(([, id]) => id === account.id).map(([agent]) => agent);
|
|
298
|
+
if (bindings.length || defaults.length) {
|
|
299
|
+
const refs = [...bindings.map(target => `binding ${target}`), ...defaults.map(agent => `default ${agent}`)];
|
|
300
|
+
throw new Error(`Account '${account.name}' is still referenced by: ${refs.join(', ')}. Detach or clear those references before removing it.`);
|
|
301
|
+
}
|
|
197
302
|
const consumers = [...new Set([...profileConsumers(account.name, base), ...profileConsumers(account.id, base)])].sort();
|
|
198
303
|
if (consumers.length)
|
|
199
304
|
throw new Error(`Account '${account.name}' is used by harness${consumers.length === 1 ? '' : 'es'}: ${consumers.join(', ')}. Reassign them before removing it.`);
|
|
@@ -237,3 +342,44 @@ export function resolveCredentialAccount(name, host, expectedProvider, base = ge
|
|
|
237
342
|
env: { ...connectionEnv, [envVar]: getKeychainToken(account.secretRef) },
|
|
238
343
|
};
|
|
239
344
|
}
|
|
345
|
+
/**
|
|
346
|
+
* Resolve the account a run should launch under, following the binding order
|
|
347
|
+
* (explicit → exact `agent@version` → device-scoped `agent` → per-harness
|
|
348
|
+
* default) and classifying the result:
|
|
349
|
+
*
|
|
350
|
+
* - **provider** → the injected env is resolved here (fails closed when the
|
|
351
|
+
* credential is absent or the provider cannot authenticate the host).
|
|
352
|
+
* - **native** → returns the identity the caller must confirm is live on the
|
|
353
|
+
* execution device; **no secret or env is produced**, because a native login
|
|
354
|
+
* is owned by the harness and read from its own home. The caller validates the
|
|
355
|
+
* live fingerprint against the installed version before spawn.
|
|
356
|
+
*
|
|
357
|
+
* A native account bound to a different harness than the one being launched
|
|
358
|
+
* fails loudly (EXEC-ACCOUNT-4). Returns null when nothing is selected.
|
|
359
|
+
*/
|
|
360
|
+
export function resolveSpawnAccount(explicit, agent, version, meta, opts = {}) {
|
|
361
|
+
// The binding lookup key. A custom harness passes its own profile/harness name
|
|
362
|
+
// (a run of `deepseek` must find a binding on `deepseek`, not `claude@x`); a
|
|
363
|
+
// native/global run keys on the exact `agent@version` installation.
|
|
364
|
+
const target = opts.target ?? (version ? `${agent}@${version}` : agent);
|
|
365
|
+
const selection = resolveAccountSelection(explicit, agent, meta, { useDefault: opts.useDefault, target });
|
|
366
|
+
if (!selection)
|
|
367
|
+
return null;
|
|
368
|
+
const unified = findUnifiedAccount(selection, meta);
|
|
369
|
+
if (!unified)
|
|
370
|
+
throw new Error(`Unknown account '${selection}'.`);
|
|
371
|
+
if (unified.kind === 'native') {
|
|
372
|
+
if (unified.agent !== agent) {
|
|
373
|
+
throw new Error(`Account '${unified.name}' is a ${unified.agent} login and cannot authenticate the ${agent} harness.`);
|
|
374
|
+
}
|
|
375
|
+
// A provider-backed custom harness still injects its provider auth env, so a
|
|
376
|
+
// native identity claim over it is incoherent — reject before spawn even when
|
|
377
|
+
// the account is chosen explicitly with --account (which bypasses `attach`).
|
|
378
|
+
if (opts.provider) {
|
|
379
|
+
throw new Error(`Account '${unified.name}' is a native ${unified.agent} login and cannot run under a provider-backed harness (${opts.provider}); the harness's ${opts.provider} credentials would still be injected. Use a matching provider account.`);
|
|
380
|
+
}
|
|
381
|
+
return { kind: 'native', id: unified.id, name: unified.name, agent, identityKey: unified.identityKey, scope: unified.scope };
|
|
382
|
+
}
|
|
383
|
+
const resolved = resolveCredentialAccount(unified.name, agent, opts.provider, opts.base ?? getUserAgentsDir());
|
|
384
|
+
return { kind: 'provider', id: resolved.id, name: resolved.name, agent, env: resolved.env };
|
|
385
|
+
}
|
|
@@ -4,11 +4,11 @@
|
|
|
4
4
|
* Detects which installed versions have expired credentials and rotates
|
|
5
5
|
* authentication tokens so users maintain active sessions across version switches.
|
|
6
6
|
*/
|
|
7
|
-
import type { AgentId, RunStrategy } from '
|
|
8
|
-
import type { FallbackEntry } from '
|
|
9
|
-
import { type AccountInfo, type CredentialPresence } from '
|
|
7
|
+
import type { AgentId, RunStrategy } from '../types.js';
|
|
8
|
+
import type { FallbackEntry } from '../exec.js';
|
|
9
|
+
import { type AccountInfo, type CredentialPresence } from '../agents.js';
|
|
10
10
|
import { type UsageSnapshot } from './usage.js';
|
|
11
|
-
import { type AuthVerdict } from '
|
|
11
|
+
import { type AuthVerdict } from '../auth-health.js';
|
|
12
12
|
export interface RotateCandidate {
|
|
13
13
|
agent: AgentId;
|
|
14
14
|
version: string;
|
|
@@ -6,15 +6,15 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import * as fs from 'fs';
|
|
8
8
|
import * as path from 'path';
|
|
9
|
-
import { accountDisplayLabel, getAccountInfo, credentialPresence, ALL_AGENT_IDS, } from '
|
|
10
|
-
import { readMeta, writeMeta, getHelpersDir } from '
|
|
11
|
-
import { listInstalledVersions, getVersionHomePath, resolveVersion } from '
|
|
12
|
-
import { getProjectRunConfigs } from '
|
|
13
|
-
import { emit } from '
|
|
9
|
+
import { accountDisplayLabel, getAccountInfo, credentialPresence, ALL_AGENT_IDS, } from '../agents.js';
|
|
10
|
+
import { readMeta, writeMeta, getHelpersDir } from '../state.js';
|
|
11
|
+
import { listInstalledVersions, getVersionHomePath, resolveVersion } from '../installations/versions.js';
|
|
12
|
+
import { getProjectRunConfigs } from '../run-config.js';
|
|
13
|
+
import { emit } from '../feed/events.js';
|
|
14
14
|
import { getUsageInfoByIdentity, getUsageLookupKey, deriveUsageStatusFromSnapshot, } from './usage.js';
|
|
15
|
-
import { readAccountHeadroom } from '
|
|
16
|
-
import { machineId } from '
|
|
17
|
-
import { readAuthHealthCache, authCacheKey, isDeadVerdict } from '
|
|
15
|
+
import { readAccountHeadroom } from '../fleet-cache.js';
|
|
16
|
+
import { machineId } from '../machine-id.js';
|
|
17
|
+
import { readAuthHealthCache, authCacheKey, isDeadVerdict } from '../auth-health.js';
|
|
18
18
|
function getRotateDir() {
|
|
19
19
|
const dir = path.join(getHelpersDir(), 'rotate');
|
|
20
20
|
fs.mkdirSync(dir, { recursive: true });
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { type AccountInfo } from '
|
|
2
|
-
import type { AgentId } from '
|
|
1
|
+
import { type AccountInfo } from '../agents.js';
|
|
2
|
+
import type { AgentId } from '../types.js';
|
|
3
3
|
/**
|
|
4
4
|
* Why a usage read produced no snapshot, when the cause is the credential or the
|
|
5
5
|
* server rather than the payload. Every provider used to return `error: null`
|
|
@@ -460,14 +460,14 @@ export declare function normalizeDroidWindows(data: DroidBillingLimitsResponse):
|
|
|
460
460
|
* 1. The OS keychain (`getKeychainToken`). Canonical on macOS — Claude Code
|
|
461
461
|
* writes the token to the login keychain and we read it via `/usr/bin/security`.
|
|
462
462
|
* 2. `<home>/.claude/.credentials.json`. On a headless Linux box (the
|
|
463
|
-
* `agents view --
|
|
463
|
+
* `agents view --device <linux>` case) there is no reachable Secret Service, so
|
|
464
464
|
* the Claude CLI stores its OAuth token in this plaintext file instead. The
|
|
465
465
|
* keychain read above finds nothing on that platform, so we fall back to the
|
|
466
466
|
* file. Same wrapped `{ claudeAiOauth }` shape, so one parser handles both.
|
|
467
467
|
* Mirrors `readClaudeCredentialsBlob` (cloud/rush.ts), the proven pattern.
|
|
468
468
|
*
|
|
469
469
|
* Without step 2 the live usage fetch got no token on Linux, so `agents view`
|
|
470
|
-
* (run remotely over SSH by `--
|
|
470
|
+
* (run remotely over SSH by `--device`) rendered no usage bars even though the
|
|
471
471
|
* account + plan — read from the plaintext `.claude.json` — showed fine.
|
|
472
472
|
*
|
|
473
473
|
* `opts.accessTokenCache` marks a read-only, access-token-only consumer (the
|
|
@@ -17,15 +17,15 @@ import * as path from 'path';
|
|
|
17
17
|
import * as readline from 'readline';
|
|
18
18
|
import { promisify } from 'util';
|
|
19
19
|
import chalk from 'chalk';
|
|
20
|
-
import { decodeJwtPayload, decryptDroidAuthPayload } from '
|
|
21
|
-
import { walkForFiles } from '
|
|
22
|
-
import { getKeychainToken, setKeychainToken, deleteKeychainToken, isKeychainBackendOverridden, } from '
|
|
23
|
-
import { resolveClaudeSetupToken } from '
|
|
24
|
-
import { formatBackoffRemaining, noteUsageRateLimited, usageRateLimitedUntil, } from '
|
|
25
|
-
import { getCacheDir } from '
|
|
26
|
-
import { mapBounded } from '
|
|
27
|
-
import { atomicWriteFileSync, ensureLockTarget, withFileLock } from '
|
|
28
|
-
import { withRefreshLease } from '
|
|
20
|
+
import { decodeJwtPayload, decryptDroidAuthPayload } from '../agents.js';
|
|
21
|
+
import { walkForFiles } from '../fs-walk.js';
|
|
22
|
+
import { getKeychainToken, setKeychainToken, deleteKeychainToken, isKeychainBackendOverridden, } from '../secrets/index.js';
|
|
23
|
+
import { resolveClaudeSetupToken } from '../claude-account-token.js';
|
|
24
|
+
import { formatBackoffRemaining, noteUsageRateLimited, usageRateLimitedUntil, } from '../usage-backoff.js';
|
|
25
|
+
import { getCacheDir } from '../state.js';
|
|
26
|
+
import { mapBounded } from '../concurrency.js';
|
|
27
|
+
import { atomicWriteFileSync, ensureLockTarget, withFileLock } from '../fs-atomic.js';
|
|
28
|
+
import { withRefreshLease } from '../refresh-coordinator.js';
|
|
29
29
|
const execFileAsync = promisify(execFile);
|
|
30
30
|
const CLAUDE_USAGE_URL = 'https://api.anthropic.com/api/oauth/usage';
|
|
31
31
|
const CLAUDE_TOKEN_URL = 'https://platform.claude.com/v1/oauth/token';
|
|
@@ -1282,14 +1282,14 @@ function deleteCachedClaudeOauth(service) {
|
|
|
1282
1282
|
* 1. The OS keychain (`getKeychainToken`). Canonical on macOS — Claude Code
|
|
1283
1283
|
* writes the token to the login keychain and we read it via `/usr/bin/security`.
|
|
1284
1284
|
* 2. `<home>/.claude/.credentials.json`. On a headless Linux box (the
|
|
1285
|
-
* `agents view --
|
|
1285
|
+
* `agents view --device <linux>` case) there is no reachable Secret Service, so
|
|
1286
1286
|
* the Claude CLI stores its OAuth token in this plaintext file instead. The
|
|
1287
1287
|
* keychain read above finds nothing on that platform, so we fall back to the
|
|
1288
1288
|
* file. Same wrapped `{ claudeAiOauth }` shape, so one parser handles both.
|
|
1289
1289
|
* Mirrors `readClaudeCredentialsBlob` (cloud/rush.ts), the proven pattern.
|
|
1290
1290
|
*
|
|
1291
1291
|
* Without step 2 the live usage fetch got no token on Linux, so `agents view`
|
|
1292
|
-
* (run remotely over SSH by `--
|
|
1292
|
+
* (run remotely over SSH by `--device`) rendered no usage bars even though the
|
|
1293
1293
|
* account + plan — read from the plaintext `.claude.json` — showed fine.
|
|
1294
1294
|
*
|
|
1295
1295
|
* `opts.accessTokenCache` marks a read-only, access-token-only consumer (the
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// The production VersionProvider: the only fs/meta-coupled file in the engine.
|
|
2
2
|
// Everything else in this module is pure and testable without it.
|
|
3
|
-
import { listInstalledVersions, getGlobalDefault, getIsolatedDefault, getProjectVersion, isVersionInstalled, } from '../versions.js';
|
|
3
|
+
import { listInstalledVersions, getGlobalDefault, getIsolatedDefault, getProjectVersion, isVersionInstalled, } from '../installations/versions.js';
|
|
4
4
|
export const defaultVersionProvider = {
|
|
5
5
|
listInstalled: (agent) => listInstalledVersions(agent),
|
|
6
6
|
getProjectVersion: (agent, cwd) => getProjectVersion(agent, cwd),
|