@phnx-labs/agents-cli 1.22.35 → 1.22.37
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 +666 -2
- package/README.md +75 -35
- package/dist/bin/agents +0 -0
- package/dist/bootstrap.d.ts +15 -0
- package/dist/bootstrap.js +1211 -0
- package/dist/commands/accounts.d.ts +4 -11
- package/dist/commands/accounts.js +159 -27
- package/dist/commands/attach.js +17 -4
- package/dist/commands/audit.d.ts +8 -8
- package/dist/commands/audit.js +57 -47
- package/dist/commands/browser.js +15 -11
- package/dist/commands/cloud.js +1 -1
- package/dist/commands/commands.js +0 -11
- package/dist/commands/computer-actions.js +33 -0
- package/dist/commands/computer-sessions-picker.d.ts +21 -0
- package/dist/commands/computer-sessions-picker.js +141 -0
- package/dist/commands/computer.d.ts +16 -0
- package/dist/commands/computer.js +37 -0
- package/dist/commands/config.d.ts +17 -0
- package/dist/commands/config.js +401 -0
- package/dist/commands/cp.d.ts +84 -0
- package/dist/commands/cp.js +231 -0
- package/dist/commands/daemon.js +243 -14
- package/dist/commands/detach-core.d.ts +1 -1
- package/dist/commands/detach-core.js +12 -2
- package/dist/commands/detach.js +1 -1
- package/dist/commands/doctor.js +64 -5
- package/dist/commands/events.d.ts +24 -12
- package/dist/commands/events.js +144 -28
- package/dist/commands/exec.js +85 -41
- package/dist/commands/feed.d.ts +1 -1
- package/dist/commands/feed.js +16 -8
- package/dist/commands/focus.d.ts +33 -1
- package/dist/commands/focus.js +177 -17
- package/dist/commands/funnel.d.ts +1 -1
- package/dist/commands/go.js +9 -8
- package/dist/commands/harness-wizard.d.ts +1 -0
- package/dist/commands/harness-wizard.js +18 -20
- package/dist/commands/harness.d.ts +2 -0
- package/dist/commands/harness.js +59 -26
- package/dist/commands/hooks.js +0 -11
- package/dist/commands/inspect.d.ts +94 -1
- package/dist/commands/inspect.js +866 -40
- package/dist/commands/lease.d.ts +4 -4
- package/dist/commands/lease.js +6 -6
- package/dist/commands/login.js +0 -13
- package/dist/commands/logs.d.ts +2 -2
- package/dist/commands/logs.js +2 -2
- package/dist/commands/mcp.js +7 -2
- package/dist/commands/memory.js +7 -2
- package/dist/commands/message.d.ts +1 -1
- package/dist/commands/message.js +37 -6
- package/dist/commands/models.js +4 -0
- package/dist/commands/monitors.d.ts +0 -1
- package/dist/commands/monitors.js +199 -16
- package/dist/commands/open.d.ts +18 -0
- package/dist/commands/open.js +57 -0
- package/dist/commands/packages.js +2 -107
- package/dist/commands/plugins.js +6 -3
- package/dist/commands/profiles.d.ts +1 -0
- package/dist/commands/profiles.js +16 -160
- package/dist/commands/projects.d.ts +28 -0
- package/dist/commands/projects.js +125 -5
- package/dist/commands/reconnect.js +9 -3
- package/dist/commands/repo.js +42 -1
- package/dist/commands/resource-view.d.ts +17 -0
- package/dist/commands/resource-view.js +36 -14
- package/dist/commands/resume.js +9 -2
- package/dist/commands/routines.d.ts +0 -2
- package/dist/commands/routines.js +473 -289
- package/dist/commands/secrets.js +52 -9
- package/dist/commands/sessions-export.d.ts +47 -0
- package/dist/commands/sessions-export.js +116 -6
- package/dist/commands/sessions-import.d.ts +17 -0
- package/dist/commands/sessions-import.js +114 -6
- package/dist/commands/sessions-migrate.d.ts +27 -0
- package/dist/commands/sessions-migrate.js +50 -9
- package/dist/commands/sessions-picker.js +23 -4
- package/dist/commands/sessions-resume.d.ts +5 -3
- package/dist/commands/sessions-resume.js +30 -8
- package/dist/commands/sessions-watch.d.ts +2 -0
- package/dist/commands/sessions-watch.js +53 -0
- package/dist/commands/sessions.d.ts +66 -3
- package/dist/commands/sessions.js +298 -47
- package/dist/commands/set.d.ts +1 -1
- package/dist/commands/set.js +2 -2
- package/dist/commands/setup-browser.js +2 -2
- package/dist/commands/setup-mine.js +0 -1
- package/dist/commands/setup-preferences.js +1 -1
- package/dist/commands/setup-share.js +34 -4
- package/dist/commands/setup.d.ts +5 -0
- package/dist/commands/setup.js +26 -0
- package/dist/commands/share.d.ts +67 -0
- package/dist/commands/share.js +275 -12
- package/dist/commands/skills.js +0 -11
- package/dist/commands/snapshot.js +1 -1
- package/dist/commands/ssh.d.ts +18 -0
- package/dist/commands/ssh.js +549 -210
- package/dist/commands/sync.d.ts +5 -0
- package/dist/commands/sync.js +212 -32
- package/dist/commands/teams.d.ts +13 -0
- package/dist/commands/teams.js +187 -30
- package/dist/commands/tickets.d.ts +2 -0
- package/dist/commands/tickets.js +43 -0
- package/dist/commands/update.js +2 -4
- package/dist/commands/usage.js +5 -3
- package/dist/commands/versions.js +11 -5
- package/dist/commands/view.js +15 -7
- package/dist/commands/webhook.d.ts +2 -2
- package/dist/commands/webhook.js +7 -7
- package/dist/index.d.ts +18 -2
- package/dist/index.js +53 -1264
- package/dist/lib/account-catalog.d.ts +18 -0
- package/dist/lib/account-catalog.js +38 -0
- package/dist/lib/account-provider-registry.d.ts +18 -0
- package/dist/lib/account-provider-registry.js +59 -0
- package/dist/lib/account-registry.d.ts +40 -0
- package/dist/lib/account-registry.js +239 -0
- package/dist/lib/account-schema.d.ts +44 -0
- package/dist/lib/account-schema.js +91 -0
- package/dist/lib/account-state-service.d.ts +21 -0
- package/dist/lib/account-state-service.js +60 -0
- package/dist/lib/activity.d.ts +1 -1
- package/dist/lib/activity.js +8 -1
- package/dist/lib/add-dir.d.ts +80 -0
- package/dist/lib/add-dir.js +241 -0
- package/dist/lib/agent-cli-commands.d.ts +11 -0
- package/dist/lib/agent-cli-commands.js +30 -0
- package/dist/lib/agents.js +44 -36
- package/dist/lib/answer-router.js +1 -1
- package/dist/lib/audit/log.d.ts +10 -27
- package/dist/lib/audit/log.js +20 -33
- package/dist/lib/auth-health.d.ts +9 -2
- package/dist/lib/auth-health.js +42 -9
- package/dist/lib/auto-pull-worker.js +7 -3
- package/dist/lib/auto-pull.d.ts +44 -3
- package/dist/lib/auto-pull.js +88 -5
- package/dist/lib/binary-shadow.d.ts +28 -0
- package/dist/lib/binary-shadow.js +121 -0
- package/dist/lib/brand.js +9 -3
- package/dist/lib/browser/ipc.d.ts +30 -0
- package/dist/lib/browser/ipc.js +81 -4
- package/dist/lib/browser/profiles.d.ts +3 -2
- package/dist/lib/browser/profiles.js +65 -22
- package/dist/lib/browser/service.d.ts +4 -0
- package/dist/lib/browser/service.js +30 -3
- package/dist/lib/browser/sessions-list.d.ts +22 -2
- package/dist/lib/browser/sessions-list.js +54 -6
- package/dist/lib/browser/stream.d.ts +2 -0
- package/dist/lib/browser/stream.js +1 -0
- package/dist/lib/browser/types.d.ts +19 -0
- package/dist/lib/byok-usage.d.ts +9 -2
- package/dist/lib/byok-usage.js +133 -31
- package/dist/lib/cli-entry.d.ts +11 -0
- package/dist/lib/cli-entry.js +46 -0
- package/dist/lib/cloud/host.d.ts +1 -1
- package/dist/lib/cloud/host.js +2 -2
- package/dist/lib/cloud/registry.js +1 -1
- package/dist/lib/cloud/types.d.ts +1 -1
- package/dist/lib/commands.d.ts +2 -0
- package/dist/lib/commands.js +2 -0
- package/dist/lib/computer/sessions-list.d.ts +150 -0
- package/dist/lib/computer/sessions-list.js +363 -0
- package/dist/lib/config-keys.d.ts +86 -0
- package/dist/lib/config-keys.js +193 -0
- package/dist/lib/config-machine-keys.d.ts +12 -0
- package/dist/lib/config-machine-keys.js +17 -0
- package/dist/lib/config-transfer.js +3 -4
- package/dist/lib/crabbox/cli.d.ts +2 -2
- package/dist/lib/crabbox/cli.js +3 -3
- package/dist/lib/daemon-health.d.ts +22 -0
- package/dist/lib/daemon-health.js +33 -3
- package/dist/lib/daemon-services.d.ts +50 -0
- package/dist/lib/daemon-services.js +147 -0
- package/dist/lib/daemon-ticks.d.ts +35 -66
- package/dist/lib/daemon-ticks.js +77 -159
- package/dist/lib/daemon.d.ts +72 -4
- package/dist/lib/daemon.js +792 -202
- package/dist/lib/deeplink/register.d.ts +49 -0
- package/dist/lib/deeplink/register.js +253 -0
- package/dist/lib/deeplink/url.d.ts +34 -0
- package/dist/lib/deeplink/url.js +78 -0
- package/dist/lib/device-config.d.ts +124 -29
- package/dist/lib/device-config.js +346 -141
- package/dist/lib/devices/config-migration.d.ts +42 -0
- package/dist/lib/devices/config-migration.js +203 -0
- package/dist/lib/devices/connect.js +14 -7
- package/dist/lib/devices/doctor-findings.d.ts +4 -1
- package/dist/lib/devices/doctor-findings.js +20 -1
- package/dist/lib/devices/harness-inventory.d.ts +11 -2
- package/dist/lib/devices/harness-inventory.js +0 -0
- package/dist/lib/devices/health.d.ts +1 -1
- package/dist/lib/devices/health.js +1 -1
- package/dist/lib/devices/pending.d.ts +22 -1
- package/dist/lib/devices/pending.js +67 -2
- package/dist/lib/devices/registry.d.ts +0 -25
- package/dist/lib/devices/registry.js +2 -83
- package/dist/lib/devices/resolve-profile.d.ts +20 -0
- package/dist/lib/devices/resolve-profile.js +44 -0
- package/dist/lib/devices/rollout-verify.d.ts +101 -0
- package/dist/lib/devices/rollout-verify.js +193 -0
- package/dist/lib/devices/ssh-config.js +10 -6
- package/dist/lib/event-families.d.ts +28 -0
- package/dist/lib/event-families.js +159 -0
- package/dist/lib/event-stream.d.ts +9 -1
- package/dist/lib/event-stream.js +26 -9
- package/dist/lib/events.d.ts +9 -1
- package/dist/lib/events.js +21 -6
- package/dist/lib/exec.d.ts +30 -0
- package/dist/lib/exec.js +219 -121
- package/dist/lib/feed-broadcast.d.ts +25 -0
- package/dist/lib/feed-broadcast.js +33 -0
- package/dist/lib/feed.d.ts +1 -1
- package/dist/lib/feed.js +12 -2
- package/dist/lib/fleet/capture.js +15 -0
- package/dist/lib/fleet/manifest.js +9 -0
- package/dist/lib/fleet/types.d.ts +9 -0
- package/dist/lib/fleet-status.js +10 -8
- package/dist/lib/git.d.ts +20 -6
- package/dist/lib/git.js +121 -17
- package/dist/lib/hosts/dispatch.d.ts +8 -3
- package/dist/lib/hosts/dispatch.js +29 -3
- package/dist/lib/hosts/logs.d.ts +2 -2
- package/dist/lib/hosts/logs.js +2 -2
- package/dist/lib/hosts/option.js +1 -1
- package/dist/lib/hosts/passthrough.d.ts +2 -3
- package/dist/lib/hosts/passthrough.js +10 -24
- package/dist/lib/hosts/progress.js +2 -2
- package/dist/lib/hosts/providers/devices.d.ts +3 -3
- package/dist/lib/hosts/providers/devices.js +18 -12
- package/dist/lib/hosts/ready.d.ts +5 -1
- package/dist/lib/hosts/ready.js +9 -3
- package/dist/lib/hosts/reconcile.d.ts +2 -2
- package/dist/lib/hosts/reconcile.js +2 -2
- package/dist/lib/hosts/registry.js +14 -9
- package/dist/lib/hosts/remote-cmd.js +1 -1
- package/dist/lib/hosts/remote-os.d.ts +9 -6
- package/dist/lib/hosts/remote-os.js +13 -6
- package/dist/lib/hosts/routing-flag.d.ts +23 -0
- package/dist/lib/hosts/routing-flag.js +41 -0
- package/dist/lib/hosts/run-target.js +1 -1
- package/dist/lib/hosts/session-index.js +1 -1
- package/dist/lib/hosts/tasks.d.ts +6 -6
- package/dist/lib/hosts/tasks.js +4 -4
- package/dist/lib/hosts/types.js +1 -2
- package/dist/lib/installations/resolve.js +2 -8
- package/dist/lib/isolation-boundary-report.js +0 -1
- package/dist/lib/linear-cache.d.ts +7 -0
- package/dist/lib/linear-cache.js +31 -4
- package/dist/lib/linear-project-counts.d.ts +1 -1
- package/dist/lib/linear-project-counts.js +2 -3
- package/dist/lib/linear-projects.js +1 -1
- package/dist/lib/loop.d.ts +2 -2
- package/dist/lib/loop.js +1 -1
- package/dist/lib/mailbox-target.d.ts +1 -1
- package/dist/lib/mailbox-target.js +1 -1
- package/dist/lib/manifest.js +7 -4
- 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/snapshot.d.ts +3 -2
- package/dist/lib/menubar/snapshot.js +6 -2
- package/dist/lib/migrate-fold.d.ts +33 -0
- package/dist/lib/migrate-fold.js +130 -0
- package/dist/lib/migrate.d.ts +34 -34
- package/dist/lib/migrate.js +106 -128
- package/dist/lib/model-tier-overrides.d.ts +1 -1
- package/dist/lib/model-tier-overrides.js +15 -2
- package/dist/lib/monitors/config.d.ts +17 -3
- package/dist/lib/monitors/config.js +52 -18
- package/dist/lib/monitors/engine.d.ts +32 -1
- package/dist/lib/monitors/engine.js +94 -11
- package/dist/lib/monitors/fingerprint.d.ts +46 -0
- package/dist/lib/monitors/fingerprint.js +100 -0
- package/dist/lib/monitors/remote.d.ts +47 -0
- package/dist/lib/monitors/remote.js +81 -0
- package/dist/lib/monitors/state.d.ts +39 -0
- package/dist/lib/monitors/state.js +56 -0
- package/dist/lib/onepassword.d.ts +17 -0
- package/dist/lib/onepassword.js +52 -22
- package/dist/lib/open-url.js +1 -1
- package/dist/lib/picker.d.ts +14 -2
- package/dist/lib/picker.js +35 -13
- package/dist/lib/placement.d.ts +1 -1
- package/dist/lib/placement.js +1 -1
- package/dist/lib/pr-land-detach.d.ts +32 -0
- package/dist/lib/pr-land-detach.js +79 -0
- package/dist/lib/profiles-presets.js +13 -0
- package/dist/lib/profiles.d.ts +2 -0
- package/dist/lib/profiles.js +44 -1
- package/dist/lib/project-focus.d.ts +1 -1
- package/dist/lib/project-focus.js +1 -1
- package/dist/lib/project-probe.d.ts +4 -1
- package/dist/lib/project-probe.js +5 -4
- package/dist/lib/project-resources.js +2 -18
- package/dist/lib/project-root.d.ts +16 -0
- package/dist/lib/project-root.js +20 -2
- package/dist/lib/projects.d.ts +20 -1
- package/dist/lib/projects.js +78 -1
- package/dist/lib/refresh-coordinator.d.ts +24 -0
- package/dist/lib/refresh-coordinator.js +52 -0
- package/dist/lib/registry.d.ts +2 -2
- package/dist/lib/registry.js +1 -1
- package/dist/lib/resource-aliases.d.ts +13 -0
- package/dist/lib/resource-aliases.js +26 -0
- package/dist/lib/resources/types.d.ts +1 -1
- package/dist/lib/resources.d.ts +16 -0
- package/dist/lib/resources.js +66 -10
- package/dist/lib/rotate.d.ts +3 -4
- package/dist/lib/rotate.js +4 -5
- package/dist/lib/routine-activation.d.ts +22 -2
- package/dist/lib/routine-activation.js +63 -16
- package/dist/lib/routine-context.d.ts +9 -2
- package/dist/lib/routine-context.js +21 -6
- package/dist/lib/routines-project.d.ts +58 -48
- package/dist/lib/routines-project.js +190 -159
- package/dist/lib/routines.d.ts +41 -6
- package/dist/lib/routines.js +92 -34
- package/dist/lib/run-defaults.d.ts +5 -0
- package/dist/lib/run-defaults.js +11 -1
- package/dist/lib/runner.d.ts +10 -8
- package/dist/lib/runner.js +122 -39
- 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.d.ts +10 -3
- package/dist/lib/secrets/agent.js +43 -8
- package/dist/lib/secrets/bundles.d.ts +1 -0
- package/dist/lib/secrets/bundles.js +92 -80
- package/dist/lib/secrets/index.js +32 -9
- package/dist/lib/secrets/install-helper.d.ts +4 -4
- package/dist/lib/secrets/install-helper.js +4 -4
- package/dist/lib/secrets/push.d.ts +40 -6
- package/dist/lib/secrets/push.js +58 -11
- package/dist/lib/secrets/read-backoff.d.ts +1 -1
- package/dist/lib/secrets/read-backoff.js +1 -1
- package/dist/lib/secrets/remote.d.ts +24 -0
- package/dist/lib/secrets/remote.js +54 -4
- package/dist/lib/self-update.d.ts +108 -0
- package/dist/lib/self-update.js +276 -1
- package/dist/lib/session/active.d.ts +89 -5
- package/dist/lib/session/active.js +165 -10
- package/dist/lib/session/actor-sidecar.d.ts +1 -1
- package/dist/lib/session/actor-sidecar.js +2 -1
- package/dist/lib/session/db.d.ts +176 -2
- package/dist/lib/session/db.js +484 -17
- package/dist/lib/session/discover.js +27 -4
- package/dist/lib/session/hook-sessions.js +2 -2
- package/dist/lib/session/host-link.d.ts +2 -2
- package/dist/lib/session/host-link.js +2 -2
- package/dist/lib/session/pid-registry.d.ts +21 -0
- package/dist/lib/session/pid-registry.js +57 -0
- package/dist/lib/session/remote-active.js +15 -1
- package/dist/lib/session/remote.js +2 -2
- package/dist/lib/session/session-cache.d.ts +14 -7
- package/dist/lib/session/session-cache.js +51 -9
- package/dist/lib/session/state.d.ts +2 -2
- package/dist/lib/session/state.js +1 -1
- package/dist/lib/session/sync/config.d.ts +10 -10
- package/dist/lib/session/sync/config.js +10 -10
- package/dist/lib/session/sync/r2.d.ts +34 -0
- package/dist/lib/session/sync/r2.js +123 -0
- package/dist/lib/session/throughput.d.ts +1 -1
- package/dist/lib/session/throughput.js +1 -1
- package/dist/lib/session/types.d.ts +23 -1
- package/dist/lib/session/types.js +15 -0
- package/dist/lib/session/viewing-in.d.ts +1 -1
- package/dist/lib/session/viewing-in.js +1 -1
- package/dist/lib/session/watch.d.ts +101 -0
- package/dist/lib/session/watch.js +242 -0
- package/dist/lib/share/config.d.ts +4 -0
- package/dist/lib/share/config.js +1 -0
- package/dist/lib/share/provision.d.ts +38 -0
- package/dist/lib/share/provision.js +50 -0
- package/dist/lib/share/publish.d.ts +40 -1
- package/dist/lib/share/publish.js +116 -3
- package/dist/lib/share/worker-template.js +71 -6
- package/dist/lib/shims.d.ts +17 -3
- package/dist/lib/shims.js +98 -26
- package/dist/lib/signin-badge.js +3 -2
- package/dist/lib/skills.js +2 -0
- package/dist/lib/smart-launch.d.ts +8 -8
- package/dist/lib/smart-launch.js +80 -59
- package/dist/lib/ssh-exec.d.ts +1 -1
- package/dist/lib/ssh-exec.js +1 -1
- package/dist/lib/staleness/prune.d.ts +88 -0
- package/dist/lib/staleness/prune.js +69 -0
- package/dist/lib/staleness/registry.d.ts +1 -1
- package/dist/lib/staleness/writers/commands.js +34 -2
- package/dist/lib/staleness/writers/hooks.js +16 -0
- package/dist/lib/staleness/writers/kinds.d.ts +6 -0
- package/dist/lib/staleness/writers/skills.js +19 -0
- package/dist/lib/staleness/writers/subagents.d.ts +2 -3
- package/dist/lib/staleness/writers/subagents.js +0 -4
- package/dist/lib/staleness/writers/types.d.ts +32 -0
- package/dist/lib/startup/command-registry.d.ts +6 -12
- package/dist/lib/startup/command-registry.js +11 -31
- package/dist/lib/startup/dev-build.d.ts +10 -0
- package/dist/lib/startup/dev-build.js +13 -1
- package/dist/lib/startup/spellcheck.d.ts +18 -0
- package/dist/lib/startup/spellcheck.js +45 -0
- package/dist/lib/state.d.ts +36 -9
- package/dist/lib/state.js +96 -46
- package/dist/lib/subagents-registry.d.ts +0 -7
- package/dist/lib/subagents-registry.js +38 -65
- package/dist/lib/subagents.d.ts +0 -33
- package/dist/lib/subagents.js +0 -75
- package/dist/lib/sync-umbrella.js +1 -1
- package/dist/lib/teams/agents.d.ts +41 -1
- package/dist/lib/teams/agents.js +187 -9
- package/dist/lib/teams/api.d.ts +11 -1
- package/dist/lib/teams/api.js +11 -2
- package/dist/lib/teams/delivery.d.ts +41 -0
- package/dist/lib/teams/delivery.js +60 -0
- package/dist/lib/teams/registry.d.ts +14 -0
- package/dist/lib/teams/registry.js +51 -1
- package/dist/lib/teams/remoteWorktree.d.ts +19 -0
- package/dist/lib/teams/remoteWorktree.js +29 -0
- package/dist/lib/teams/scheduler.d.ts +1 -1
- package/dist/lib/teams/scheduler.js +1 -1
- package/dist/lib/teams/worktree.d.ts +24 -0
- package/dist/lib/teams/worktree.js +42 -0
- package/dist/lib/terminal/backends/vscodium-agent.d.ts +10 -1
- package/dist/lib/terminal/backends/vscodium-agent.js +16 -5
- package/dist/lib/terminal/engine.d.ts +4 -0
- package/dist/lib/terminal/engine.js +8 -2
- package/dist/lib/terminal/types.d.ts +21 -2
- package/dist/lib/testdata/refresh-coordinator-worker.d.ts +1 -0
- package/dist/lib/testdata/refresh-coordinator-worker.js +23 -0
- package/dist/lib/tickets/list.d.ts +53 -0
- package/dist/lib/tickets/list.js +153 -0
- package/dist/lib/tmux/orphan-reap.d.ts +320 -0
- package/dist/lib/tmux/orphan-reap.js +644 -0
- package/dist/lib/tmux/session.d.ts +68 -3
- package/dist/lib/tmux/session.js +95 -5
- package/dist/lib/triggers/handlers.d.ts +20 -0
- package/dist/lib/triggers/handlers.js +6 -1
- package/dist/lib/types.d.ts +46 -34
- package/dist/lib/usage-fleet.d.ts +32 -0
- package/dist/lib/usage-fleet.js +125 -0
- package/dist/lib/usage-refresh.d.ts +3 -3
- package/dist/lib/usage-refresh.js +19 -16
- package/dist/lib/usage.d.ts +51 -47
- package/dist/lib/usage.js +145 -153
- package/dist/lib/version-duplicates.js +2 -2
- package/dist/lib/versions.d.ts +56 -13
- package/dist/lib/versions.js +195 -45
- package/dist/lib/watchdog/log.d.ts +1 -1
- package/dist/lib/watchdog/log.js +3 -3
- package/dist/lib/watchdog/rotate.d.ts +6 -6
- package/dist/lib/watchdog/rotate.js +6 -6
- package/dist/lib/workflows.d.ts +1 -1
- package/dist/lib/yaml-io.d.ts +47 -0
- package/dist/lib/yaml-io.js +55 -0
- package/package.json +2 -1
- package/scripts/install-helper.js +2 -2
- package/scripts/postinstall.js +23 -20
- package/dist/commands/defaults.d.ts +0 -7
- package/dist/commands/defaults.js +0 -107
- package/dist/commands/export.d.ts +0 -11
- package/dist/commands/export.js +0 -215
- package/dist/commands/helper.d.ts +0 -12
- package/dist/commands/helper.js +0 -87
- package/dist/commands/hosts.d.ts +0 -11
- package/dist/commands/hosts.js +0 -330
- package/dist/commands/lock.d.ts +0 -12
- package/dist/commands/lock.js +0 -70
- package/dist/commands/pull.d.ts +0 -17
- package/dist/commands/pull.js +0 -39
- package/dist/commands/push.d.ts +0 -14
- package/dist/commands/push.js +0 -30
- package/dist/commands/wallet.d.ts +0 -20
- package/dist/commands/wallet.js +0 -216
- package/dist/commands/worktree.d.ts +0 -19
- package/dist/commands/worktree.js +0 -272
- package/dist/lib/account-labels.d.ts +0 -24
- package/dist/lib/account-labels.js +0 -72
- package/dist/lib/auto-dispatch-linear.d.ts +0 -18
- package/dist/lib/auto-dispatch-linear.js +0 -107
- package/dist/lib/auto-dispatch-provider.d.ts +0 -10
- package/dist/lib/auto-dispatch-provider.js +0 -30
- package/dist/lib/auto-dispatch.d.ts +0 -93
- package/dist/lib/auto-dispatch.js +0 -128
- package/dist/lib/export.d.ts +0 -72
- package/dist/lib/export.js +0 -269
- package/dist/lib/lock.d.ts +0 -93
- package/dist/lib/lock.js +0 -207
- package/dist/lib/wallet/index.d.ts +0 -78
- package/dist/lib/wallet/index.js +0 -253
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Interactive, task-first `agents computer sessions` / `agents sessions
|
|
3
|
+
* --computer` view (RUSH-2432) — the computer counterpart of
|
|
4
|
+
* `browser-sessions-picker.ts` (RUSH-2407). Backs the TTY path only —
|
|
5
|
+
* non-TTY, `--json`, and `--no-interactive` all fall straight through to the
|
|
6
|
+
* flat printer in `lib/computer/sessions-list.ts` (unchanged, so `--json`
|
|
7
|
+
* stays a stable surface).
|
|
8
|
+
*
|
|
9
|
+
* Reuses the same `itemPicker` + `buildPreview` primitives as the ordinary
|
|
10
|
+
* session picker (`sessions-picker.ts`) and the browser task picker — same
|
|
11
|
+
* search/filter/quit help, and the preview pane for a linked run IS the
|
|
12
|
+
* canonical session digest, not a second renderer. Unlike a browser task, a
|
|
13
|
+
* computer run has no on-disk artifact of its own to open (see
|
|
14
|
+
* `lib/computer/sessions-list.ts`'s module docblock), so `enter` prints the
|
|
15
|
+
* run's full action list rather than opening a file, and the picker keeps
|
|
16
|
+
* browsing afterward instead of exiting.
|
|
17
|
+
*/
|
|
18
|
+
import chalk from 'chalk';
|
|
19
|
+
import { itemPicker } from '../lib/picker.js';
|
|
20
|
+
import { isInteractiveTerminal, isPromptCancelled } from './utils.js';
|
|
21
|
+
import { buildPreview } from './sessions-picker.js';
|
|
22
|
+
import { runComputerSessions, printComputerSessionRows, buildComputerSessionRows, matchesComputerSessionRow, formatRowActions, } from '../lib/computer/sessions-list.js';
|
|
23
|
+
import { formatRelativeTime } from '../lib/session/relative-time.js';
|
|
24
|
+
/** True when the interactive picker should open instead of the printed table:
|
|
25
|
+
* a real TTY, no `--json`, and `--no-interactive` not set. */
|
|
26
|
+
export function shouldOpenInteractiveComputerSessions(opts, isTTY) {
|
|
27
|
+
return opts.interactive !== false && !opts.json && isTTY;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Shared entry point for `agents computer sessions` and `agents sessions
|
|
31
|
+
* --computer`. Mirrors `runBrowserSessionsCommand`'s interactive-routing
|
|
32
|
+
* split so both call sites stay in lockstep.
|
|
33
|
+
*/
|
|
34
|
+
export async function runComputerSessionsCommand(opts) {
|
|
35
|
+
if (!shouldOpenInteractiveComputerSessions(opts, isInteractiveTerminal())) {
|
|
36
|
+
if (opts.rows)
|
|
37
|
+
printComputerSessionRows(opts.rows, { limit: opts.limit, json: opts.json });
|
|
38
|
+
else
|
|
39
|
+
runComputerSessions({ machine: opts.machine, limit: opts.limit, json: opts.json });
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
const rows = opts.rows ?? buildComputerSessionRows({ machine: opts.machine });
|
|
43
|
+
if (rows.length === 0) {
|
|
44
|
+
console.log(`No computer actions recorded${opts.machine ? ` for machine "${opts.machine}"` : ''}.`);
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
await browseComputerSessions(rows);
|
|
48
|
+
}
|
|
49
|
+
function rowLinkSummary(row) {
|
|
50
|
+
if (row.linkStatus === 'linked' && row.linkedSession) {
|
|
51
|
+
const s = row.linkedSession;
|
|
52
|
+
return chalk.cyan(s.agent) + ' — ' + (s.label || s.topic || s.shortId);
|
|
53
|
+
}
|
|
54
|
+
if (row.linkStatus === 'unresolved') {
|
|
55
|
+
return chalk.yellow(`owner ${row.agent ?? 'unknown'} (session not indexed here)`);
|
|
56
|
+
}
|
|
57
|
+
return chalk.gray('unlinked');
|
|
58
|
+
}
|
|
59
|
+
function formatRowLabel(row) {
|
|
60
|
+
// Pad the raw text first, THEN colorize — padEnd on an already-chalked
|
|
61
|
+
// string counts the ANSI escape bytes as width and misaligns the column.
|
|
62
|
+
const rawName = row.task ?? row.bundle ?? (row.pid ? `pid ${row.pid}` : 'recovered run');
|
|
63
|
+
const name = rawName.slice(0, 40).padEnd(40);
|
|
64
|
+
const coloredName = row.task ? name : chalk.gray(name);
|
|
65
|
+
const where = (row.remoteHost ? `${row.machine} -> ${row.remoteHost}` : row.machine).padEnd(24);
|
|
66
|
+
const age = formatRelativeTime(new Date(row.endMs).toISOString());
|
|
67
|
+
const counts = formatRowActions(row);
|
|
68
|
+
return [coloredName, where, age.padEnd(11), counts.padEnd(24), rowLinkSummary(row)].join(' ');
|
|
69
|
+
}
|
|
70
|
+
const PREVIEW_ACTION_LIMIT = 12;
|
|
71
|
+
function buildRowPreview(row) {
|
|
72
|
+
const parts = [];
|
|
73
|
+
if (row.linkStatus === 'linked' && row.linkedSession) {
|
|
74
|
+
parts.push(buildPreview(row.linkedSession));
|
|
75
|
+
}
|
|
76
|
+
else if (row.linkStatus === 'unresolved') {
|
|
77
|
+
parts.push(chalk.yellow(`owner ${row.agent ?? 'unknown'} — session ${row.sessionId ?? row.launchId} has no indexed session on this machine.`));
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
parts.push(chalk.gray('Unlinked — no owning agent session is known for this run (no session/launch identity recorded).'));
|
|
81
|
+
}
|
|
82
|
+
if (row.task) {
|
|
83
|
+
parts.push('');
|
|
84
|
+
parts.push(chalk.bold('Task:') + ` ${row.task}`);
|
|
85
|
+
}
|
|
86
|
+
parts.push('');
|
|
87
|
+
parts.push(chalk.bold(`Actions (${row.recoveredActionCount ?? row.actions.length})`) + ` ${formatRowActions(row)}`);
|
|
88
|
+
for (const a of row.actions.slice(0, PREVIEW_ACTION_LIMIT)) {
|
|
89
|
+
parts.push(` ${formatActionLabel(a)}`);
|
|
90
|
+
}
|
|
91
|
+
const more = row.actions.length - PREVIEW_ACTION_LIMIT;
|
|
92
|
+
if (more > 0)
|
|
93
|
+
parts.push(chalk.gray(` … (${more} more)`));
|
|
94
|
+
return parts.join('\n');
|
|
95
|
+
}
|
|
96
|
+
function formatActionLabel(a) {
|
|
97
|
+
const age = formatRelativeTime(new Date(a.tsMs).toISOString());
|
|
98
|
+
const target = a.bundle ?? (a.targetPid != null ? `pid ${a.targetPid}` : '-');
|
|
99
|
+
return `${age.padEnd(11)} ${a.verb.padEnd(14)} ${target}`;
|
|
100
|
+
}
|
|
101
|
+
/** Print one run's full action list (no truncation) — the `enter` action,
|
|
102
|
+
* since a computer run has no on-disk artifact to open. */
|
|
103
|
+
function printRunDetail(row) {
|
|
104
|
+
console.log('');
|
|
105
|
+
console.log(chalk.bold(row.task ?? row.bundle ?? `pid ${row.pid}`));
|
|
106
|
+
console.log(row.remoteHost ? `${row.machine} -> ${row.remoteHost}` : row.machine);
|
|
107
|
+
console.log('');
|
|
108
|
+
for (const a of row.actions)
|
|
109
|
+
console.log(formatActionLabel(a));
|
|
110
|
+
if (row.actions.length === 0)
|
|
111
|
+
console.log('(no driving actions recorded)');
|
|
112
|
+
console.log('');
|
|
113
|
+
}
|
|
114
|
+
/** Run-level picker with an action-list preview. Loops until the user quits
|
|
115
|
+
* (esc) so a session's whole run history can be browsed repeatedly in one
|
|
116
|
+
* sitting — mirroring `browseAndOpen`'s loop, minus the artifact drill-down
|
|
117
|
+
* a computer run has none of. */
|
|
118
|
+
async function browseComputerSessions(rows) {
|
|
119
|
+
for (;;) {
|
|
120
|
+
let picked;
|
|
121
|
+
try {
|
|
122
|
+
picked = await itemPicker({
|
|
123
|
+
message: 'Computer sessions:',
|
|
124
|
+
items: rows,
|
|
125
|
+
filter: (query) => (query.trim() ? rows.filter((r) => matchesComputerSessionRow(r, query)) : rows),
|
|
126
|
+
labelFor: (row) => formatRowLabel(row),
|
|
127
|
+
buildPreview: (row) => buildRowPreview(row),
|
|
128
|
+
emptyMessage: 'No computer sessions match.',
|
|
129
|
+
enterHint: 'view actions',
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
catch (err) {
|
|
133
|
+
if (isPromptCancelled(err))
|
|
134
|
+
return;
|
|
135
|
+
throw err;
|
|
136
|
+
}
|
|
137
|
+
if (!picked)
|
|
138
|
+
return;
|
|
139
|
+
printRunDetail(picked.item);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
@@ -38,6 +38,22 @@ export declare function reconcileScreenshotExt(outPath: string, buf: Buffer): {
|
|
|
38
38
|
export declare function registerComputerCommand(program: Command): void;
|
|
39
39
|
export declare function registerComputerSubcommands(program: Command): void;
|
|
40
40
|
export declare function buildRestartTaskScript(taskName: string, exeName: string): string;
|
|
41
|
+
/**
|
|
42
|
+
* Emit a `computer.action` marker for `computer run`'s whole loop process, so
|
|
43
|
+
* `agents computer sessions` groups every verb the loop drives under one
|
|
44
|
+
* task-labeled row instead of a bare pid with no task text (see
|
|
45
|
+
* lib/computer/sessions-list.ts's "Grouping key" docblock note). The task
|
|
46
|
+
* text is bounded to `TASK_PREVIEW_MAX_CHARS` — never the full unbounded
|
|
47
|
+
* `--task` string — matching that module's retention/privacy note. Exported
|
|
48
|
+
* so the truncation behavior is directly unit-testable against the real
|
|
49
|
+
* event ledger, the same seam `computer-actions.test.ts` already uses for
|
|
50
|
+
* `emitComputerAction`.
|
|
51
|
+
*/
|
|
52
|
+
export declare function emitComputerRunTaskMarker(opts: {
|
|
53
|
+
task: string;
|
|
54
|
+
bundle?: string;
|
|
55
|
+
host?: string;
|
|
56
|
+
}): void;
|
|
41
57
|
/**
|
|
42
58
|
* Install the macOS helper locally: resolve (or download + verify) the signed,
|
|
43
59
|
* notarized .app, copy it to /Applications, verify the destination signature,
|
|
@@ -11,6 +11,9 @@ import { registerActionCommands, withClient, unwrap, pickTarget, emitComputerAct
|
|
|
11
11
|
import { runComputerLoop } from '../lib/computer/loop.js';
|
|
12
12
|
import { makeVerbDispatcher } from '../lib/computer/dispatch.js';
|
|
13
13
|
import { makeClaudeResponder, resolveApiKey, DEFAULT_CLAUDE_MODEL, DEFAULT_CLAUDE_BASE_URL } from '../lib/computer/model.js';
|
|
14
|
+
import { TASK_PREVIEW_MAX_CHARS } from '../lib/computer/sessions-list.js';
|
|
15
|
+
import { runComputerSessionsCommand } from './computer-sessions-picker.js';
|
|
16
|
+
import { truncate } from '../lib/events.js';
|
|
14
17
|
// Help groups — mirror `agents browser` so the mental model carries over.
|
|
15
18
|
const COMPUTER_HELP_GROUPS = [
|
|
16
19
|
{ title: 'Installation', names: ['setup'] },
|
|
@@ -18,6 +21,7 @@ const COMPUTER_HELP_GROUPS = [
|
|
|
18
21
|
{ title: 'Autonomous', names: ['run'] },
|
|
19
22
|
{ title: 'Observe', names: ['apps', 'describe', 'screenshot', 'get-text'] },
|
|
20
23
|
{ title: 'Interact', names: ['launch', 'raise', 'click', 'right-click', 'type', 'type-text', 'key', 'drag', 'scroll', 'ax-action', 'focus', 'wait'] },
|
|
24
|
+
{ title: 'History and discovery', names: ['sessions'] },
|
|
21
25
|
];
|
|
22
26
|
// Subcommands that manage the `--host` remote path themselves (provisioning /
|
|
23
27
|
// tunnel lifecycle, or daemon-state reporting that must degrade gracefully
|
|
@@ -109,6 +113,7 @@ export function registerComputerSubcommands(program) {
|
|
|
109
113
|
registerRunCommand(program);
|
|
110
114
|
registerScreenshotCommand(program);
|
|
111
115
|
registerActionCommands(program);
|
|
116
|
+
registerSessionsCommand(program);
|
|
112
117
|
registerCommandGroups(program, COMPUTER_HELP_GROUPS);
|
|
113
118
|
}
|
|
114
119
|
function registerStatusCommand(program) {
|
|
@@ -300,6 +305,7 @@ function registerRunCommand(program) {
|
|
|
300
305
|
model: opts.model,
|
|
301
306
|
maxTokens: opts.maxTokens,
|
|
302
307
|
});
|
|
308
|
+
emitComputerRunTaskMarker({ task: opts.task, bundle: opts.bundle, host: opts.host });
|
|
303
309
|
await withClient(async (client) => {
|
|
304
310
|
const dispatch = makeVerbDispatcher(client, { host: opts.host });
|
|
305
311
|
const targetInput = opts.bundle ? { bundle: opts.bundle } : {};
|
|
@@ -324,6 +330,37 @@ function registerRunCommand(program) {
|
|
|
324
330
|
});
|
|
325
331
|
});
|
|
326
332
|
}
|
|
333
|
+
// sessions — task-first history over the computer.action event ledger (RUSH-2432),
|
|
334
|
+
// the computer counterpart of `agents browser sessions` (RUSH-2407). `agents
|
|
335
|
+
// sessions --computer` (sessions.ts) routes to the same runComputerSessionsCommand.
|
|
336
|
+
function registerSessionsCommand(program) {
|
|
337
|
+
program
|
|
338
|
+
.command('sessions')
|
|
339
|
+
.description('Browse computer-driving history, grouped by run — one row per `agents computer` invocation')
|
|
340
|
+
.option('--machine <name>', 'Only rows invoked from/driving this machine (hostname, machineId, or --host device)')
|
|
341
|
+
.option('--limit <n>', 'Cap the flat/--no-interactive table at this many rows (default 50; --json is unbounded)', (v) => parseInt(v, 10))
|
|
342
|
+
.option('--json', 'Emit machine-readable JSON')
|
|
343
|
+
.option('--no-interactive', 'Print the flat listing instead of opening the interactive run browser')
|
|
344
|
+
.action(async (opts) => {
|
|
345
|
+
await runComputerSessionsCommand({ machine: opts.machine, limit: opts.limit, json: opts.json, interactive: opts.interactive });
|
|
346
|
+
});
|
|
347
|
+
}
|
|
348
|
+
/**
|
|
349
|
+
* Emit a `computer.action` marker for `computer run`'s whole loop process, so
|
|
350
|
+
* `agents computer sessions` groups every verb the loop drives under one
|
|
351
|
+
* task-labeled row instead of a bare pid with no task text (see
|
|
352
|
+
* lib/computer/sessions-list.ts's "Grouping key" docblock note). The task
|
|
353
|
+
* text is bounded to `TASK_PREVIEW_MAX_CHARS` — never the full unbounded
|
|
354
|
+
* `--task` string — matching that module's retention/privacy note. Exported
|
|
355
|
+
* so the truncation behavior is directly unit-testable against the real
|
|
356
|
+
* event ledger, the same seam `computer-actions.test.ts` already uses for
|
|
357
|
+
* `emitComputerAction`.
|
|
358
|
+
*/
|
|
359
|
+
export function emitComputerRunTaskMarker(opts) {
|
|
360
|
+
emitComputerAction('run', undefined, { bundle: opts.bundle, host: opts.host }, {
|
|
361
|
+
task: truncate(opts.task, TASK_PREVIEW_MAX_CHARS),
|
|
362
|
+
});
|
|
363
|
+
}
|
|
327
364
|
// Fold the target bundle into the task text so the model biases toward it.
|
|
328
365
|
function describeTaskWithTarget(task, bundle) {
|
|
329
366
|
return bundle ? `${task}\n(Target app bundle id: ${bundle})` : task;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unified configuration command barrel.
|
|
3
|
+
*
|
|
4
|
+
* `agents config` consolidates the fragmented config surface into one namespace:
|
|
5
|
+
* - run defaults (model, mode, effort)
|
|
6
|
+
* - tier overrides (folded into the run namespace)
|
|
7
|
+
* - interactive host
|
|
8
|
+
* - usage primary host
|
|
9
|
+
* - browser profile
|
|
10
|
+
* - local projects root
|
|
11
|
+
* - per-device config keys
|
|
12
|
+
*
|
|
13
|
+
* The underlying YAML schema is unchanged; this command translates the new key
|
|
14
|
+
* grammar into reads/writes of the existing stores.
|
|
15
|
+
*/
|
|
16
|
+
import type { Command } from 'commander';
|
|
17
|
+
export declare function registerConfigCommand(program: Command): void;
|
|
@@ -0,0 +1,401 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unified configuration command barrel.
|
|
3
|
+
*
|
|
4
|
+
* `agents config` consolidates the fragmented config surface into one namespace:
|
|
5
|
+
* - run defaults (model, mode, effort)
|
|
6
|
+
* - tier overrides (folded into the run namespace)
|
|
7
|
+
* - interactive host
|
|
8
|
+
* - usage primary host
|
|
9
|
+
* - browser profile
|
|
10
|
+
* - local projects root
|
|
11
|
+
* - per-device config keys
|
|
12
|
+
*
|
|
13
|
+
* The underlying YAML schema is unchanged; this command translates the new key
|
|
14
|
+
* grammar into reads/writes of the existing stores.
|
|
15
|
+
*/
|
|
16
|
+
import chalk from 'chalk';
|
|
17
|
+
import { setHelpSections } from '../lib/help.js';
|
|
18
|
+
import { parseConfigKey, formatAgentVersion, devicePropertyToConfigName, configKeyStorageHint, } from '../lib/config-keys.js';
|
|
19
|
+
import { resolveRunDefaults, setRunDefaultModel, setRunDefaultMode, setRunDefaultEffort, unsetRunDefault, } from '../lib/run-defaults.js';
|
|
20
|
+
import { resolveTierOverride, setTierOverride, clearTierOverride } from '../lib/model-tier-overrides.js';
|
|
21
|
+
import { getConfigValue, setConfigValue, unsetConfigValue, listConfig, } from '../lib/device-config.js';
|
|
22
|
+
import { readMeta, updateMeta } from '../lib/state.js';
|
|
23
|
+
import { MODEL_TIERS } from '../lib/model-tiers.js';
|
|
24
|
+
import { machineId } from '../lib/machine-id.js';
|
|
25
|
+
import { getProjectRoot, setProjectRoot } from '../lib/project-root.js';
|
|
26
|
+
/** Parse a boolean value the same way `agents devices configure` does. */
|
|
27
|
+
function parseBool(value, key) {
|
|
28
|
+
const v = value.trim().toLowerCase();
|
|
29
|
+
if (v === 'on' || v === 'true')
|
|
30
|
+
return true;
|
|
31
|
+
if (v === 'off' || v === 'false')
|
|
32
|
+
return false;
|
|
33
|
+
throw new Error(`Config key '${key}' expects a boolean ('on' or 'off'), got '${value}'.`);
|
|
34
|
+
}
|
|
35
|
+
/** Parse the value for a given key, enforcing type rules. */
|
|
36
|
+
function parseValue(key, parsed, raw) {
|
|
37
|
+
switch (parsed.scope) {
|
|
38
|
+
case 'run':
|
|
39
|
+
return raw.trim();
|
|
40
|
+
case 'interactive':
|
|
41
|
+
return raw.trim();
|
|
42
|
+
case 'usage':
|
|
43
|
+
return raw.trim();
|
|
44
|
+
case 'browser':
|
|
45
|
+
return raw.trim();
|
|
46
|
+
case 'project':
|
|
47
|
+
return raw.trim();
|
|
48
|
+
case 'device': {
|
|
49
|
+
switch (parsed.property) {
|
|
50
|
+
case 'max-agents':
|
|
51
|
+
if (!/^\d+$/.test(raw.trim())) {
|
|
52
|
+
throw new Error(`Config key '${key}' expects an integer, got '${raw}'.`);
|
|
53
|
+
}
|
|
54
|
+
return Number.parseInt(raw.trim(), 10);
|
|
55
|
+
case 'scheduler':
|
|
56
|
+
case 'daemon':
|
|
57
|
+
case 'watchdog':
|
|
58
|
+
case 'browser.remote-control':
|
|
59
|
+
return parseBool(raw, key);
|
|
60
|
+
case 'notes':
|
|
61
|
+
return raw.trim();
|
|
62
|
+
case 'browser.profile':
|
|
63
|
+
return raw.trim();
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
/** Write a value for a parsed config key. */
|
|
69
|
+
function setConfig(parsed, value) {
|
|
70
|
+
switch (parsed.scope) {
|
|
71
|
+
case 'run': {
|
|
72
|
+
const selector = `${parsed.agent}:${parsed.version}`;
|
|
73
|
+
if (parsed.property === 'tier') {
|
|
74
|
+
setTierOverride(selector, parsed.tier, value);
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
if (parsed.property === 'model') {
|
|
78
|
+
setRunDefaultModel(selector, value);
|
|
79
|
+
}
|
|
80
|
+
else if (parsed.property === 'mode') {
|
|
81
|
+
setRunDefaultMode(selector, value);
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
setRunDefaultEffort(selector, value);
|
|
85
|
+
}
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
case 'interactive': {
|
|
89
|
+
setConfigValue('interactive.host', value);
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
case 'usage': {
|
|
93
|
+
setConfigValue('usage.primary-host', value);
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
case 'browser': {
|
|
97
|
+
// Device-local default lives in the central fleet.devices.<name>.config
|
|
98
|
+
// block (same store `agents devices config` / getConfigValue use). Bare
|
|
99
|
+
// browser.profile targets this machine; devices.<name>.browser.profile
|
|
100
|
+
// targets a peer.
|
|
101
|
+
setConfigValue('browser.profile', value, parsed.device ? { device: parsed.device } : undefined);
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
case 'project':
|
|
105
|
+
setProjectRoot(value);
|
|
106
|
+
return;
|
|
107
|
+
case 'device': {
|
|
108
|
+
const configName = devicePropertyToConfigName(parsed.property);
|
|
109
|
+
if (parsed.property === 'notes') {
|
|
110
|
+
const existing = getConfigValue('notes', { device: parsed.device }).value ?? [];
|
|
111
|
+
setConfigValue('notes', [...existing, value], { device: parsed.device });
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
setConfigValue(configName, value, { device: parsed.device });
|
|
115
|
+
}
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
/** Unset a parsed config key. */
|
|
121
|
+
function unsetConfig(parsed) {
|
|
122
|
+
switch (parsed.scope) {
|
|
123
|
+
case 'run': {
|
|
124
|
+
const selector = `${parsed.agent}:${parsed.version}`;
|
|
125
|
+
if (parsed.property === 'tier') {
|
|
126
|
+
return clearTierOverride(selector, parsed.tier);
|
|
127
|
+
}
|
|
128
|
+
return unsetRunDefault(selector);
|
|
129
|
+
}
|
|
130
|
+
case 'interactive': {
|
|
131
|
+
const had = getConfigValue('interactive.host').value !== undefined;
|
|
132
|
+
unsetConfigValue('interactive.host');
|
|
133
|
+
return had;
|
|
134
|
+
}
|
|
135
|
+
case 'usage': {
|
|
136
|
+
const had = getConfigValue('usage.primary-host').value !== undefined;
|
|
137
|
+
unsetConfigValue('usage.primary-host');
|
|
138
|
+
return had;
|
|
139
|
+
}
|
|
140
|
+
case 'browser': {
|
|
141
|
+
const target = parsed.device ? { device: parsed.device } : undefined;
|
|
142
|
+
const had = getConfigValue('browser.profile', target).value !== undefined;
|
|
143
|
+
unsetConfigValue('browser.profile', target);
|
|
144
|
+
return had;
|
|
145
|
+
}
|
|
146
|
+
case 'project': {
|
|
147
|
+
const had = getProjectRoot() !== undefined;
|
|
148
|
+
updateMeta((meta) => {
|
|
149
|
+
const { projectRoot: _projectRoot, ...rest } = meta;
|
|
150
|
+
return rest;
|
|
151
|
+
});
|
|
152
|
+
return had;
|
|
153
|
+
}
|
|
154
|
+
case 'device': {
|
|
155
|
+
const configName = devicePropertyToConfigName(parsed.property);
|
|
156
|
+
const had = getConfigValue(configName, { device: parsed.device }).value !== undefined;
|
|
157
|
+
unsetConfigValue(configName, { device: parsed.device });
|
|
158
|
+
return had;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
/** Read the stored value for a parsed config key. */
|
|
163
|
+
function getConfig(parsed) {
|
|
164
|
+
switch (parsed.scope) {
|
|
165
|
+
case 'run': {
|
|
166
|
+
const defaults = resolveRunDefaults(parsed.agent, parsed.version);
|
|
167
|
+
if (parsed.property === 'tier') {
|
|
168
|
+
return resolveTierOverride(parsed.agent, parsed.version)[parsed.tier];
|
|
169
|
+
}
|
|
170
|
+
return defaults[parsed.property];
|
|
171
|
+
}
|
|
172
|
+
case 'interactive':
|
|
173
|
+
return getConfigValue('interactive.host').value;
|
|
174
|
+
case 'usage':
|
|
175
|
+
return getConfigValue('usage.primary-host').value;
|
|
176
|
+
case 'browser': {
|
|
177
|
+
return getConfigValue('browser.profile', parsed.device ? { device: parsed.device } : undefined).value;
|
|
178
|
+
}
|
|
179
|
+
case 'project':
|
|
180
|
+
return getProjectRoot();
|
|
181
|
+
case 'device': {
|
|
182
|
+
const configName = devicePropertyToConfigName(parsed.property);
|
|
183
|
+
return getConfigValue(configName, { device: parsed.device }).value;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
/** Format a config value for display. */
|
|
188
|
+
function formatValue(value) {
|
|
189
|
+
if (value === undefined)
|
|
190
|
+
return chalk.gray('(unset)');
|
|
191
|
+
if (typeof value === 'boolean')
|
|
192
|
+
return value ? chalk.green('true') : chalk.red('false');
|
|
193
|
+
return chalk.cyan(JSON.stringify(value));
|
|
194
|
+
}
|
|
195
|
+
/** Collect all set config entries for a given device scope (self or peer). */
|
|
196
|
+
function* listRunConfigEntries() {
|
|
197
|
+
const meta = readMeta();
|
|
198
|
+
for (const [selector, defaults] of Object.entries(meta.run?.defaults ?? {})) {
|
|
199
|
+
const [agent, version] = selector.split(':');
|
|
200
|
+
if (!agent || !version)
|
|
201
|
+
continue;
|
|
202
|
+
const base = `run.${formatAgentVersion(agent, version)}`;
|
|
203
|
+
const d = defaults;
|
|
204
|
+
for (const prop of ['model', 'mode', 'effort']) {
|
|
205
|
+
if (d[prop] !== undefined) {
|
|
206
|
+
const key = `${base}.${prop}`;
|
|
207
|
+
yield { key, value: d[prop], hint: configKeyStorageHint(parseConfigKey(key)) };
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
for (const [selector, tiers] of Object.entries(meta.model?.tiers ?? {})) {
|
|
212
|
+
const [agent, version] = selector.split(':');
|
|
213
|
+
if (!agent || !version)
|
|
214
|
+
continue;
|
|
215
|
+
const base = `run.${formatAgentVersion(agent, version)}.tier`;
|
|
216
|
+
for (const tier of MODEL_TIERS) {
|
|
217
|
+
const value = tiers[tier];
|
|
218
|
+
if (value !== undefined) {
|
|
219
|
+
const key = `${base}.${tier}`;
|
|
220
|
+
yield { key, value, hint: configKeyStorageHint(parseConfigKey(key)) };
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
/** Collect central non-run config entries. */
|
|
226
|
+
function* listCentralConfigEntries() {
|
|
227
|
+
const meta = readMeta();
|
|
228
|
+
if (meta.config?.interactiveHost !== undefined) {
|
|
229
|
+
yield { key: 'interactive.host', value: meta.config.interactiveHost, hint: 'config.interactiveHost' };
|
|
230
|
+
}
|
|
231
|
+
if (meta.config?.usagePrimaryHost !== undefined) {
|
|
232
|
+
yield { key: 'usage.primary-host', value: meta.config.usagePrimaryHost, hint: 'config.usagePrimaryHost' };
|
|
233
|
+
}
|
|
234
|
+
if (meta.projectRoot !== undefined) {
|
|
235
|
+
yield { key: 'project.root', value: meta.projectRoot, hint: 'devices.<self>.projectRoot' };
|
|
236
|
+
}
|
|
237
|
+
// This machine's default browser profile lives in fleet.devices.<self>.config
|
|
238
|
+
// (device-config), not the legacy top-level Meta.defaultBrowserProfile field.
|
|
239
|
+
const browserProfile = getConfigValue('browser.profile').value;
|
|
240
|
+
if (browserProfile !== undefined) {
|
|
241
|
+
const key = 'browser.profile';
|
|
242
|
+
yield { key, value: browserProfile, hint: configKeyStorageHint(parseConfigKey(key)) };
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
/** Collect device-scope config entries. */
|
|
246
|
+
function* listDeviceConfigEntries(device) {
|
|
247
|
+
for (const entry of listConfig({ device })) {
|
|
248
|
+
if (entry.value === undefined)
|
|
249
|
+
continue;
|
|
250
|
+
const prefix = `devices.${device}.`;
|
|
251
|
+
let key;
|
|
252
|
+
switch (entry.spec.name) {
|
|
253
|
+
case 'agents.max-concurrent':
|
|
254
|
+
key = `${prefix}max-agents`;
|
|
255
|
+
break;
|
|
256
|
+
case 'scheduler.enabled':
|
|
257
|
+
key = `${prefix}scheduler`;
|
|
258
|
+
break;
|
|
259
|
+
case 'daemon.enabled':
|
|
260
|
+
key = `${prefix}daemon`;
|
|
261
|
+
break;
|
|
262
|
+
case 'watchdog.enabled':
|
|
263
|
+
key = `${prefix}watchdog`;
|
|
264
|
+
break;
|
|
265
|
+
case 'browser.remote-control':
|
|
266
|
+
key = `${prefix}browser.remote-control`;
|
|
267
|
+
break;
|
|
268
|
+
case 'notes':
|
|
269
|
+
key = `${prefix}notes`;
|
|
270
|
+
break;
|
|
271
|
+
case 'browser.profile':
|
|
272
|
+
// The self device's default browser profile is already surfaced as the
|
|
273
|
+
// top-level `browser.profile` key; skip it here to avoid duplication.
|
|
274
|
+
if (device === machineId())
|
|
275
|
+
continue;
|
|
276
|
+
key = `${prefix}browser.profile`;
|
|
277
|
+
break;
|
|
278
|
+
default:
|
|
279
|
+
continue;
|
|
280
|
+
}
|
|
281
|
+
yield { key, value: entry.value, hint: configKeyStorageHint(parseConfigKey(key)) };
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
export function registerConfigCommand(program) {
|
|
285
|
+
const config = program
|
|
286
|
+
.command('config')
|
|
287
|
+
.description('Get, set, list, and unset run defaults, tier overrides, the projects root, and device options.');
|
|
288
|
+
setHelpSections(config, {
|
|
289
|
+
examples: `
|
|
290
|
+
agents config set run.claude@*.model best
|
|
291
|
+
agents config set run.claude@*.tier.best claude-opus-4-8
|
|
292
|
+
agents config set run.claude@2.1.45.model claude-opus-4-8
|
|
293
|
+
agents config set run.claude@*.mode auto
|
|
294
|
+
agents config set interactive.host zion
|
|
295
|
+
agents config set usage.primary-host zion
|
|
296
|
+
agents config set browser.profile work
|
|
297
|
+
agents config set project.root ~/src/github.com/<you>
|
|
298
|
+
agents config set devices.mac-mini.max-agents 4
|
|
299
|
+
agents config get run.claude@*.model
|
|
300
|
+
agents config get usage.primary-host
|
|
301
|
+
agents config unset run.claude@*.tier.best
|
|
302
|
+
agents config unset usage.primary-host
|
|
303
|
+
agents config list
|
|
304
|
+
`,
|
|
305
|
+
notes: `
|
|
306
|
+
Every agent/harness reference uses agent@version. Use * for all versions.
|
|
307
|
+
Tier overrides are part of the run namespace: run.<agent@version>.tier.<tier>.
|
|
308
|
+
Project root is auto-inferred from the current Git repository when unset.
|
|
309
|
+
`,
|
|
310
|
+
});
|
|
311
|
+
config
|
|
312
|
+
.command('list')
|
|
313
|
+
.description('List configured config keys and their values')
|
|
314
|
+
.option('--device <name>', 'List config for a specific device instead of this machine')
|
|
315
|
+
.option('--json', 'Output machine-readable JSON')
|
|
316
|
+
.action((opts) => {
|
|
317
|
+
try {
|
|
318
|
+
const entries = [];
|
|
319
|
+
if (!opts.device) {
|
|
320
|
+
entries.push(...listRunConfigEntries());
|
|
321
|
+
entries.push(...listCentralConfigEntries());
|
|
322
|
+
entries.push(...listDeviceConfigEntries(machineId()));
|
|
323
|
+
}
|
|
324
|
+
else {
|
|
325
|
+
entries.push(...listDeviceConfigEntries(opts.device));
|
|
326
|
+
}
|
|
327
|
+
entries.sort((a, b) => a.key.localeCompare(b.key));
|
|
328
|
+
if (opts.json) {
|
|
329
|
+
process.stdout.write(JSON.stringify(entries, null, 2) + '\n');
|
|
330
|
+
return;
|
|
331
|
+
}
|
|
332
|
+
if (entries.length === 0) {
|
|
333
|
+
console.log(chalk.gray('No config values set.'));
|
|
334
|
+
console.log(chalk.gray("Set one with: agents config set run.claude@*.model best"));
|
|
335
|
+
return;
|
|
336
|
+
}
|
|
337
|
+
console.log(chalk.bold('Config\n'));
|
|
338
|
+
for (const { key, value, hint } of entries) {
|
|
339
|
+
console.log(` ${chalk.cyan(key.padEnd(42))} ${formatValue(value)}`);
|
|
340
|
+
console.log(` ${''.padEnd(42)} ${chalk.gray(hint)}`);
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
catch (err) {
|
|
344
|
+
console.error(chalk.red(err.message));
|
|
345
|
+
process.exit(1);
|
|
346
|
+
}
|
|
347
|
+
});
|
|
348
|
+
config
|
|
349
|
+
.command('get <key>')
|
|
350
|
+
.description('Get the current value of a config key')
|
|
351
|
+
.option('--json', 'Output machine-readable JSON')
|
|
352
|
+
.action((key, opts) => {
|
|
353
|
+
try {
|
|
354
|
+
const parsed = parseConfigKey(key);
|
|
355
|
+
const value = getConfig(parsed);
|
|
356
|
+
if (opts.json) {
|
|
357
|
+
process.stdout.write(JSON.stringify({ key, value: value ?? null }, null, 2) + '\n');
|
|
358
|
+
return;
|
|
359
|
+
}
|
|
360
|
+
console.log(`${chalk.cyan(key)} = ${formatValue(value)}`);
|
|
361
|
+
}
|
|
362
|
+
catch (err) {
|
|
363
|
+
console.error(chalk.red(err.message));
|
|
364
|
+
process.exit(1);
|
|
365
|
+
}
|
|
366
|
+
});
|
|
367
|
+
config
|
|
368
|
+
.command('set <key> <value>')
|
|
369
|
+
.description('Set a config key')
|
|
370
|
+
.action((key, value) => {
|
|
371
|
+
try {
|
|
372
|
+
const parsed = parseConfigKey(key);
|
|
373
|
+
const typed = parseValue(key, parsed, value);
|
|
374
|
+
setConfig(parsed, typed);
|
|
375
|
+
console.log(chalk.green('Set:') + ` ${chalk.cyan(key)} = ${formatValue(typed)}`);
|
|
376
|
+
}
|
|
377
|
+
catch (err) {
|
|
378
|
+
console.error(chalk.red(err.message));
|
|
379
|
+
process.exit(1);
|
|
380
|
+
}
|
|
381
|
+
});
|
|
382
|
+
config
|
|
383
|
+
.command('unset <key>')
|
|
384
|
+
.description('Unset a config key (restore default behavior)')
|
|
385
|
+
.action((key) => {
|
|
386
|
+
try {
|
|
387
|
+
const parsed = parseConfigKey(key);
|
|
388
|
+
const removed = unsetConfig(parsed);
|
|
389
|
+
if (removed) {
|
|
390
|
+
console.log(chalk.green(`Unset ${key}`));
|
|
391
|
+
}
|
|
392
|
+
else {
|
|
393
|
+
console.log(chalk.gray(`No value set for ${key}`));
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
catch (err) {
|
|
397
|
+
console.error(chalk.red(err.message));
|
|
398
|
+
process.exit(1);
|
|
399
|
+
}
|
|
400
|
+
});
|
|
401
|
+
}
|