@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/lib/browser/ipc.js
CHANGED
|
@@ -3,8 +3,53 @@ import * as fs from 'fs';
|
|
|
3
3
|
import * as path from 'path';
|
|
4
4
|
import { IS_WINDOWS, ipcEndpoint } from '../platform/index.js';
|
|
5
5
|
import { getHelpersDir } from '../state.js';
|
|
6
|
-
import {
|
|
6
|
+
import { resolveBrowserTaskIdleMs } from '../device-config.js';
|
|
7
|
+
import { startDaemon, stopDaemon } from '../daemon/daemon.js';
|
|
7
8
|
import { getCliVersion } from '../version.js';
|
|
9
|
+
import { compareVersions } from '../agent-spec/primitives.js';
|
|
10
|
+
import { getDaemonLogPath } from '../daemon/daemon.js';
|
|
11
|
+
import { resolveCallerIdentity } from './caller-identity.js';
|
|
12
|
+
import { actionable } from './service.js';
|
|
13
|
+
/**
|
|
14
|
+
* Verbs that imply a page and may CREATE a task when none resolves.
|
|
15
|
+
* Observation-only verbs (console/logs/…) resolve but never create — an
|
|
16
|
+
* empty `agents browser logs` must not open a browser just to return [].
|
|
17
|
+
*/
|
|
18
|
+
const PAGE_CREATE_VERBS = new Set([
|
|
19
|
+
'navigate',
|
|
20
|
+
'tab-add',
|
|
21
|
+
'evaluate',
|
|
22
|
+
'screenshot',
|
|
23
|
+
'pdf',
|
|
24
|
+
'refs',
|
|
25
|
+
'click',
|
|
26
|
+
'type',
|
|
27
|
+
'press',
|
|
28
|
+
'hover',
|
|
29
|
+
'scroll',
|
|
30
|
+
'set-viewport',
|
|
31
|
+
'set-device',
|
|
32
|
+
'wait',
|
|
33
|
+
'set-download-path',
|
|
34
|
+
'wait-download',
|
|
35
|
+
'upload',
|
|
36
|
+
'record-start',
|
|
37
|
+
]);
|
|
38
|
+
/** Task-scoped verbs that resolve identity but never create. */
|
|
39
|
+
const PAGE_RESOLVE_VERBS = new Set([
|
|
40
|
+
...PAGE_CREATE_VERBS,
|
|
41
|
+
'tab-focus',
|
|
42
|
+
'tab-close',
|
|
43
|
+
'tab-list',
|
|
44
|
+
'console',
|
|
45
|
+
'errors',
|
|
46
|
+
'requests',
|
|
47
|
+
'response-body',
|
|
48
|
+
'getAppLogs',
|
|
49
|
+
'record-stop',
|
|
50
|
+
]);
|
|
51
|
+
/** Close verbs never create a task. */
|
|
52
|
+
const CLOSE_VERBS = new Set(['done', 'stop']);
|
|
8
53
|
const SOCKET_NAME = 'browser.sock';
|
|
9
54
|
/**
|
|
10
55
|
* Backstop for {@link BrowserIPCServer.stop} — how long to wait for the socket
|
|
@@ -102,7 +147,8 @@ export class BrowserIPCConnection {
|
|
|
102
147
|
});
|
|
103
148
|
}
|
|
104
149
|
request(request) {
|
|
105
|
-
const
|
|
150
|
+
const stamped = stampCallerIdentity(request);
|
|
151
|
+
const result = this.tail.then(() => this.requestOnce(stamped));
|
|
106
152
|
this.tail = result.then(() => undefined, () => undefined);
|
|
107
153
|
return result;
|
|
108
154
|
}
|
|
@@ -318,6 +364,44 @@ export class BrowserIPCServer {
|
|
|
318
364
|
this.connections.clear();
|
|
319
365
|
});
|
|
320
366
|
}
|
|
367
|
+
/**
|
|
368
|
+
* Resolve `request.task` from caller identity when omitted. Page verbs may
|
|
369
|
+
* create; done/stop never create. Returns an error response to short-circuit
|
|
370
|
+
* the action, or undefined when the request is ready (task filled in).
|
|
371
|
+
*/
|
|
372
|
+
async bindTask(request) {
|
|
373
|
+
const createIfMissing = PAGE_CREATE_VERBS.has(request.action);
|
|
374
|
+
const isClose = CLOSE_VERBS.has(request.action);
|
|
375
|
+
// stop with --profile only (no task) is handled by the stop case itself.
|
|
376
|
+
if (request.action === 'stop' && request.profile && !request.task)
|
|
377
|
+
return undefined;
|
|
378
|
+
try {
|
|
379
|
+
const resolved = await this.service.resolveOrCreateTask({
|
|
380
|
+
task: request.task,
|
|
381
|
+
profile: request.profile,
|
|
382
|
+
actor: request.actor,
|
|
383
|
+
launchId: request.launchId,
|
|
384
|
+
sessionId: request.sessionId,
|
|
385
|
+
createIfMissing,
|
|
386
|
+
title: request.title,
|
|
387
|
+
url: request.url,
|
|
388
|
+
});
|
|
389
|
+
if (!resolved) {
|
|
390
|
+
if (isClose) {
|
|
391
|
+
return { ok: true, message: 'nothing to close' };
|
|
392
|
+
}
|
|
393
|
+
return {
|
|
394
|
+
ok: false,
|
|
395
|
+
error: actionable('No browser task for this session.', 'Next: agents browser navigate <url> | agents browser start'),
|
|
396
|
+
};
|
|
397
|
+
}
|
|
398
|
+
request.task = resolved.task.name;
|
|
399
|
+
return undefined;
|
|
400
|
+
}
|
|
401
|
+
catch (err) {
|
|
402
|
+
return { ok: false, error: err instanceof Error ? err.message : String(err) };
|
|
403
|
+
}
|
|
404
|
+
}
|
|
321
405
|
async handleRequest(request) {
|
|
322
406
|
if (request.action === 'upload-stage') {
|
|
323
407
|
const source = request.source;
|
|
@@ -327,13 +411,19 @@ export class BrowserIPCServer {
|
|
|
327
411
|
const result = this.service.stageUpload(source);
|
|
328
412
|
return { ok: true, path: result.path };
|
|
329
413
|
}
|
|
414
|
+
// Task-scoped actions: resolve identity / create / refuse once here.
|
|
415
|
+
if (PAGE_RESOLVE_VERBS.has(request.action) || CLOSE_VERBS.has(request.action)) {
|
|
416
|
+
const early = await this.bindTask(request);
|
|
417
|
+
if (early)
|
|
418
|
+
return early;
|
|
419
|
+
}
|
|
330
420
|
switch (request.action) {
|
|
331
421
|
case 'version': {
|
|
332
422
|
return { ok: true, version: getCliVersion() };
|
|
333
423
|
}
|
|
334
424
|
case 'start': {
|
|
335
425
|
if (!request.profile) {
|
|
336
|
-
return { ok: false, error: 'Profile required' };
|
|
426
|
+
return { ok: false, error: actionable('Profile required.', 'Next: agents browser profiles list') };
|
|
337
427
|
}
|
|
338
428
|
const result = await this.service.start(request.profile, {
|
|
339
429
|
taskName: request.taskName,
|
|
@@ -344,6 +434,7 @@ export class BrowserIPCServer {
|
|
|
344
434
|
actor: request.actor,
|
|
345
435
|
launchId: request.launchId,
|
|
346
436
|
sessionId: request.sessionId,
|
|
437
|
+
title: request.title,
|
|
347
438
|
});
|
|
348
439
|
return {
|
|
349
440
|
ok: true,
|
|
@@ -358,29 +449,48 @@ export class BrowserIPCServer {
|
|
|
358
449
|
// only reach `reapAbandoned` through IPC. The daemon's own periodic tick
|
|
359
450
|
// calls the service method directly.
|
|
360
451
|
case 'gc': {
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
452
|
+
// 0 is the "disable idle reaping" signal (browser.task-idle-minutes),
|
|
453
|
+
// not a zero-ms window — translate it to reapAbandoned's `null` rather
|
|
454
|
+
// than let it hit the idleMs<=0 guard. Omitting the flag falls back to
|
|
455
|
+
// this box's own configured default (or 30 minutes when unset).
|
|
456
|
+
const idleMs = request.idleMinutes !== undefined
|
|
457
|
+
? (request.idleMinutes === 0 ? null : request.idleMinutes * 60_000)
|
|
458
|
+
: resolveBrowserTaskIdleMs();
|
|
459
|
+
const reaped = await this.service.reapAbandoned({ idleMs, dryRun: request.dryRun });
|
|
365
460
|
return { ok: true, reaped };
|
|
366
461
|
}
|
|
367
462
|
case 'done': {
|
|
368
463
|
if (!request.task) {
|
|
369
|
-
return { ok:
|
|
464
|
+
return { ok: true, message: 'nothing to close' };
|
|
370
465
|
}
|
|
371
466
|
const result = await this.service.done(request.task);
|
|
372
|
-
return {
|
|
467
|
+
return {
|
|
468
|
+
ok: result.ok,
|
|
469
|
+
error: result.ok
|
|
470
|
+
? undefined
|
|
471
|
+
: actionable(`Task "${request.task}" not found.`, 'Next: agents browser status'),
|
|
472
|
+
task: result.ok ? request.task : undefined,
|
|
473
|
+
};
|
|
373
474
|
}
|
|
374
475
|
case 'stop': {
|
|
375
476
|
if (request.task) {
|
|
376
477
|
const result = await this.service.stop(request.task);
|
|
377
|
-
return {
|
|
478
|
+
return {
|
|
479
|
+
ok: result.ok,
|
|
480
|
+
error: result.ok
|
|
481
|
+
? undefined
|
|
482
|
+
: actionable(`Task "${request.task}" not found.`, 'Next: agents browser status'),
|
|
483
|
+
task: result.ok ? request.task : undefined,
|
|
484
|
+
};
|
|
378
485
|
}
|
|
379
486
|
if (request.profile) {
|
|
380
487
|
await this.service.stopProfile(request.profile);
|
|
381
488
|
return { ok: true };
|
|
382
489
|
}
|
|
383
|
-
return {
|
|
490
|
+
return {
|
|
491
|
+
ok: false,
|
|
492
|
+
error: actionable('Task or profile required.', 'Next: agents browser status | agents browser stop --profile <name>'),
|
|
493
|
+
};
|
|
384
494
|
}
|
|
385
495
|
case 'status': {
|
|
386
496
|
const profiles = await this.service.status(request.profile);
|
|
@@ -391,11 +501,20 @@ export class BrowserIPCServer {
|
|
|
391
501
|
return { ok: true, history };
|
|
392
502
|
}
|
|
393
503
|
case 'navigate': {
|
|
394
|
-
if (!request.
|
|
395
|
-
return {
|
|
504
|
+
if (!request.url) {
|
|
505
|
+
return {
|
|
506
|
+
ok: false,
|
|
507
|
+
error: actionable('URL required.', 'Next: agents browser navigate <url>'),
|
|
508
|
+
};
|
|
509
|
+
}
|
|
510
|
+
if (!request.task) {
|
|
511
|
+
return {
|
|
512
|
+
ok: false,
|
|
513
|
+
error: actionable('No browser task for this session.', 'Next: agents browser navigate <url> | agents browser start'),
|
|
514
|
+
};
|
|
396
515
|
}
|
|
397
516
|
const result = await this.service.navigate(request.task, request.url, request.profile);
|
|
398
|
-
return { ok: true, tabId: result.tabId };
|
|
517
|
+
return { ok: true, tabId: result.tabId, task: request.task };
|
|
399
518
|
}
|
|
400
519
|
case 'tab-add': {
|
|
401
520
|
if (!request.task || !request.url) {
|
|
@@ -460,10 +579,20 @@ export class BrowserIPCServer {
|
|
|
460
579
|
}
|
|
461
580
|
case 'screenshot': {
|
|
462
581
|
if (!request.task) {
|
|
463
|
-
return {
|
|
582
|
+
return {
|
|
583
|
+
ok: false,
|
|
584
|
+
error: actionable('No browser task for this session.', 'Next: agents browser navigate <url> | agents browser start'),
|
|
585
|
+
};
|
|
464
586
|
}
|
|
465
587
|
const shot = await this.service.screenshot(request.task, request.tabId, request.path, request.quality);
|
|
466
|
-
return {
|
|
588
|
+
return {
|
|
589
|
+
ok: true,
|
|
590
|
+
path: shot.path,
|
|
591
|
+
bytes: shot.bytes,
|
|
592
|
+
width: shot.width,
|
|
593
|
+
height: shot.height,
|
|
594
|
+
task: request.task,
|
|
595
|
+
};
|
|
467
596
|
}
|
|
468
597
|
case 'pdf': {
|
|
469
598
|
if (!request.task) {
|
|
@@ -658,15 +787,32 @@ export class BrowserIPCServer {
|
|
|
658
787
|
}
|
|
659
788
|
let versionReconciledThisProcess = false;
|
|
660
789
|
/**
|
|
661
|
-
* Decide whether a running daemon is stale and must be restarted.
|
|
662
|
-
*
|
|
790
|
+
* Decide whether a running daemon is stale and must be restarted.
|
|
791
|
+
*
|
|
792
|
+
* FORWARD ONLY: restart when the daemon is *older* than this CLI so a newer
|
|
793
|
+
* install loads current code. An older CLI rides a newer daemon instead of
|
|
794
|
+
* evicting it — two installs sharing one daemon dir (keyed off $HOME) must
|
|
795
|
+
* not flap the daemon indefinitely.
|
|
796
|
+
*
|
|
663
797
|
* `undefined`/`'unknown'` means the daemon is too old to answer the `version`
|
|
664
798
|
* action reliably — don't churn it on that ambiguous signal.
|
|
799
|
+
*
|
|
800
|
+
* When numeric compare cannot order two distinct strings (e.g. two
|
|
801
|
+
* `0.0.0-dev.*` builds), treat the mismatch as a restart so a concrete
|
|
802
|
+
* code change still loads.
|
|
665
803
|
*/
|
|
666
804
|
export function shouldRestartStaleDaemon(daemonVersion, clientVersion) {
|
|
667
805
|
if (!daemonVersion || daemonVersion === 'unknown')
|
|
668
806
|
return false;
|
|
669
|
-
|
|
807
|
+
if (daemonVersion === clientVersion)
|
|
808
|
+
return false;
|
|
809
|
+
const cmp = compareVersions(daemonVersion, clientVersion);
|
|
810
|
+
if (cmp < 0)
|
|
811
|
+
return true; // daemon older than client → upgrade forward
|
|
812
|
+
if (cmp > 0)
|
|
813
|
+
return false; // daemon newer → older CLI rides it
|
|
814
|
+
// cmp === 0 but strings differ (unorderable tails like 0.0.0-dev.abc)
|
|
815
|
+
return true;
|
|
670
816
|
}
|
|
671
817
|
/**
|
|
672
818
|
* Reconcile the running daemon's version with ours. If the daemon is serving
|
|
@@ -700,7 +846,25 @@ async function reconcileDaemonVersion(socketPath) {
|
|
|
700
846
|
await new Promise((r) => setTimeout(r, 300));
|
|
701
847
|
}
|
|
702
848
|
export async function sendIPCRequest(request, opts = {}) {
|
|
703
|
-
|
|
849
|
+
// Stamp caller identity ONCE here so the 28+ call sites don't each have to.
|
|
850
|
+
// The daemon cannot resolve the caller's actor/session itself.
|
|
851
|
+
const stamped = stampCallerIdentity(request);
|
|
852
|
+
return sendRawIPCRequest(stamped, opts);
|
|
853
|
+
}
|
|
854
|
+
/**
|
|
855
|
+
* Fill actor / launchId / sessionId from the calling process when the request
|
|
856
|
+
* left them blank. Explicit values on the request always win.
|
|
857
|
+
*/
|
|
858
|
+
export function stampCallerIdentity(request) {
|
|
859
|
+
if (request.actor && request.launchId && request.sessionId)
|
|
860
|
+
return request;
|
|
861
|
+
const id = resolveCallerIdentity();
|
|
862
|
+
return {
|
|
863
|
+
...request,
|
|
864
|
+
actor: request.actor ?? id.actor,
|
|
865
|
+
launchId: request.launchId ?? id.launchId,
|
|
866
|
+
sessionId: request.sessionId ?? id.sessionId,
|
|
867
|
+
};
|
|
704
868
|
}
|
|
705
869
|
/**
|
|
706
870
|
* Open one connection that can serve many browser operations. This uses the
|
|
@@ -776,7 +940,7 @@ async function prepareIPC(action, opts) {
|
|
|
776
940
|
await waitForSocket(socketPath, 6000);
|
|
777
941
|
}
|
|
778
942
|
if (!(await isDaemonReachable())) {
|
|
779
|
-
throw new Error('Failed to start browser daemon');
|
|
943
|
+
throw new Error(actionable('Failed to start browser daemon.', `Log: ${getDaemonLogPath()}`, 'Next: agents doctor (checks for a second agents-cli install)'));
|
|
780
944
|
}
|
|
781
945
|
await new Promise((r) => setTimeout(r, 300));
|
|
782
946
|
}
|
|
@@ -1,13 +1,24 @@
|
|
|
1
1
|
import type { BrowserProfile } from './types.js';
|
|
2
2
|
export type { BrowserProfile } from './types.js';
|
|
3
3
|
export declare const DEFAULT_BROWSER_PROFILE_NAME = "default";
|
|
4
|
+
/**
|
|
5
|
+
* Where a profile is stored, and therefore who sees it:
|
|
6
|
+
* - `local` — this machine's `devices/<machine>/agents.yaml` (`deviceBrowser`)
|
|
7
|
+
* - `fleet` — the synced `~/.agents/agents.yaml` (`browser`), visible on every box
|
|
8
|
+
*/
|
|
9
|
+
export type ProfileScope = 'local' | 'fleet';
|
|
10
|
+
/** A profile plus the store it actually lives in. */
|
|
11
|
+
export interface ScopedBrowserProfile {
|
|
12
|
+
profile: BrowserProfile;
|
|
13
|
+
scope: ProfileScope;
|
|
14
|
+
}
|
|
4
15
|
/**
|
|
5
16
|
* The device-local configured default profile name (set via
|
|
6
17
|
* `agents browser profiles set-default`), or undefined when unset. When set, it
|
|
7
18
|
* is the profile `agents browser start` resolves to for BOTH the no-`--profile`
|
|
8
19
|
* path and an explicit `--profile default`. Stored as this machine's
|
|
9
|
-
* `browser.profile` device-config key (
|
|
10
|
-
*
|
|
20
|
+
* `browser.profile` device-config key (the per-device doc's `config:` block —
|
|
21
|
+
* see lib/device-config.ts).
|
|
11
22
|
*/
|
|
12
23
|
export declare function getConfiguredDefaultProfileName(): string | undefined;
|
|
13
24
|
export declare function getBrowserRuntimeDir(): string;
|
|
@@ -26,6 +37,12 @@ export declare function getProfileDownloadsDir(name: string): string;
|
|
|
26
37
|
*/
|
|
27
38
|
export declare function getProfileSessionsDir(name: string, task: string): string;
|
|
28
39
|
export declare function listProfiles(): Promise<BrowserProfile[]>;
|
|
40
|
+
/**
|
|
41
|
+
* Every visible profile paired with the store it lives in. Same precedence as
|
|
42
|
+
* {@link listProfiles} — a machine-local entry wins a name collision, so a name
|
|
43
|
+
* present in both maps reports `local`, which is the copy that is actually used.
|
|
44
|
+
*/
|
|
45
|
+
export declare function listProfilesWithScope(): Promise<ScopedBrowserProfile[]>;
|
|
29
46
|
export declare function getProfile(name: string): Promise<BrowserProfile | null>;
|
|
30
47
|
/**
|
|
31
48
|
* True when `profile` can actually launch or attach on THIS machine.
|
|
@@ -77,9 +94,56 @@ export declare function effectiveLocalPort(profile: BrowserProfile): number | un
|
|
|
77
94
|
* skip remote profiles in this scan.
|
|
78
95
|
*/
|
|
79
96
|
export declare function findFreeProfilePort(): Promise<number>;
|
|
80
|
-
|
|
97
|
+
/**
|
|
98
|
+
* Create a profile. **It lands in this machine's own store by default** — pass
|
|
99
|
+
* `{ fleet: true }` (the CLI's `--fleet`) to put it in the synced `agents.yaml`
|
|
100
|
+
* where every box will see it.
|
|
101
|
+
*
|
|
102
|
+
* Local-by-default is the RUSH-2716 fix. A profile is a local browser install
|
|
103
|
+
* (`binary:` is an absolute path for one OS) bound to a locally chosen free port,
|
|
104
|
+
* so the fleet-synced copy is wrong on every other machine to begin with; and
|
|
105
|
+
* because agents mint throwaway profiles freely, every ad-hoc one was syncing to
|
|
106
|
+
* every machine as junk that nothing cleaned up (`agents browser profiles prune`
|
|
107
|
+
* is the other half of that fix). Opting in with `--fleet` is for a profile that
|
|
108
|
+
* really is fleet config — a remote `ssh://` endpoint, or a named profile whose
|
|
109
|
+
* shape you want on every box.
|
|
110
|
+
*
|
|
111
|
+
* Existing profiles are NOT migrated: this only decides where a NEW entry is
|
|
112
|
+
* written, so a fleet profile created before this change keeps syncing.
|
|
113
|
+
*/
|
|
114
|
+
export declare function createProfile(profile: BrowserProfile, opts?: {
|
|
115
|
+
fleet?: boolean;
|
|
116
|
+
}): Promise<void>;
|
|
81
117
|
export declare function updateProfile(profile: BrowserProfile): Promise<void>;
|
|
82
118
|
export declare function deleteProfile(name: string): Promise<void>;
|
|
119
|
+
/**
|
|
120
|
+
* Pad `text` to exactly `width` visible characters, truncating with an ellipsis
|
|
121
|
+
* when it does not fit. `padEnd` alone does NOT bound a long value — it returns
|
|
122
|
+
* the string unchanged when it already exceeds the width, which is what pushed
|
|
123
|
+
* every later column out of alignment on a name longer than 20 characters
|
|
124
|
+
* (RUSH-2710). Every column here goes through this, never a bare `padEnd`.
|
|
125
|
+
*/
|
|
126
|
+
export declare function padColumn(text: string, width: number): string;
|
|
127
|
+
/**
|
|
128
|
+
* Render the `agents browser profiles list` table.
|
|
129
|
+
*
|
|
130
|
+
* Pure (no fs, no config reads) so the alignment and the default-marking rules
|
|
131
|
+
* are unit-testable without a configured machine.
|
|
132
|
+
*
|
|
133
|
+
* Two things used to be called "default" in this listing with no way to tell
|
|
134
|
+
* them apart (RUSH-2710): the profile literally NAMED `default` (the
|
|
135
|
+
* auto-detected one), and whichever profile this machine resolves a bare
|
|
136
|
+
* `agents browser start` to (`agents config set browser.profile <name>`). They
|
|
137
|
+
* are frequently different profiles. Now only the second is a marker — a `*` in
|
|
138
|
+
* a leading column, explained by a legend line — so the name column carries just
|
|
139
|
+
* the name and `default` in it always means the profile of that name.
|
|
140
|
+
*
|
|
141
|
+
* The SCOPE column is the RUSH-2716 companion: it says whether an entry lives on
|
|
142
|
+
* this machine only (`local`) or in the fleet-synced `agents.yaml` (`fleet`), so
|
|
143
|
+
* "why does this box have a profile I never made here?" is answerable at a
|
|
144
|
+
* glance.
|
|
145
|
+
*/
|
|
146
|
+
export declare function formatProfilesTable(rows: ScopedBrowserProfile[], configuredDefault?: string): string[];
|
|
83
147
|
/**
|
|
84
148
|
* Resolve a profile's endpoint presets into a normalized map regardless of
|
|
85
149
|
* whether the YAML uses the legacy `string[]` shape or the new map shape.
|
|
@@ -8,12 +8,17 @@ export const DEFAULT_BROWSER_PROFILE_NAME = 'default';
|
|
|
8
8
|
* True for a profile whose contents only make sense on THIS machine, so it must
|
|
9
9
|
* live in the per-machine doc rather than the fleet-synced agents.yaml.
|
|
10
10
|
*
|
|
11
|
-
*
|
|
11
|
+
* The auto-detected `default` always qualifies: it is generated by probing local
|
|
12
12
|
* browser installs and a free local port, so its `binary:` is an absolute path
|
|
13
13
|
* for one OS. Shared fleet-wide it caused a permanent rewrite loop — a macOS box
|
|
14
14
|
* wrote `/Applications/...`, a Linux box rewrote `/usr/bin/chromium-browser`,
|
|
15
|
-
* each on every `agents browser start`.
|
|
16
|
-
*
|
|
15
|
+
* each on every `agents browser start`.
|
|
16
|
+
*
|
|
17
|
+
* As of RUSH-2716 it is not the only one: EVERY newly created profile is
|
|
18
|
+
* machine-local unless the caller explicitly asks for the fleet-synced store
|
|
19
|
+
* (`createProfile(p, { fleet: true })` / `--fleet`). See {@link createProfile}.
|
|
20
|
+
* This predicate is what keeps an existing `default` that an older version wrote
|
|
21
|
+
* into central from being written back there by {@link updateProfile}.
|
|
17
22
|
*/
|
|
18
23
|
function isMachineLocalProfile(name) {
|
|
19
24
|
return name === DEFAULT_BROWSER_PROFILE_NAME;
|
|
@@ -23,8 +28,8 @@ function isMachineLocalProfile(name) {
|
|
|
23
28
|
* `agents browser profiles set-default`), or undefined when unset. When set, it
|
|
24
29
|
* is the profile `agents browser start` resolves to for BOTH the no-`--profile`
|
|
25
30
|
* path and an explicit `--profile default`. Stored as this machine's
|
|
26
|
-
* `browser.profile` device-config key (
|
|
27
|
-
*
|
|
31
|
+
* `browser.profile` device-config key (the per-device doc's `config:` block —
|
|
32
|
+
* see lib/device-config.ts).
|
|
28
33
|
*/
|
|
29
34
|
export function getConfiguredDefaultProfileName() {
|
|
30
35
|
return getConfigValue('browser.profile').value || undefined;
|
|
@@ -112,6 +117,19 @@ export async function listProfiles() {
|
|
|
112
117
|
const configs = allProfileConfigs();
|
|
113
118
|
return Object.entries(configs).map(([name, config]) => configToProfile(name, config));
|
|
114
119
|
}
|
|
120
|
+
/**
|
|
121
|
+
* Every visible profile paired with the store it lives in. Same precedence as
|
|
122
|
+
* {@link listProfiles} — a machine-local entry wins a name collision, so a name
|
|
123
|
+
* present in both maps reports `local`, which is the copy that is actually used.
|
|
124
|
+
*/
|
|
125
|
+
export async function listProfilesWithScope() {
|
|
126
|
+
const meta = readMeta();
|
|
127
|
+
const local = meta.deviceBrowser ?? {};
|
|
128
|
+
return Object.entries(allProfileConfigs()).map(([name, config]) => ({
|
|
129
|
+
profile: configToProfile(name, config),
|
|
130
|
+
scope: (local[name] ? 'local' : 'fleet'),
|
|
131
|
+
}));
|
|
132
|
+
}
|
|
115
133
|
export async function getProfile(name) {
|
|
116
134
|
const config = allProfileConfigs()[name];
|
|
117
135
|
if (!config)
|
|
@@ -292,7 +310,24 @@ function hasSshEndpoint(endpoints) {
|
|
|
292
310
|
}
|
|
293
311
|
});
|
|
294
312
|
}
|
|
295
|
-
|
|
313
|
+
/**
|
|
314
|
+
* Create a profile. **It lands in this machine's own store by default** — pass
|
|
315
|
+
* `{ fleet: true }` (the CLI's `--fleet`) to put it in the synced `agents.yaml`
|
|
316
|
+
* where every box will see it.
|
|
317
|
+
*
|
|
318
|
+
* Local-by-default is the RUSH-2716 fix. A profile is a local browser install
|
|
319
|
+
* (`binary:` is an absolute path for one OS) bound to a locally chosen free port,
|
|
320
|
+
* so the fleet-synced copy is wrong on every other machine to begin with; and
|
|
321
|
+
* because agents mint throwaway profiles freely, every ad-hoc one was syncing to
|
|
322
|
+
* every machine as junk that nothing cleaned up (`agents browser profiles prune`
|
|
323
|
+
* is the other half of that fix). Opting in with `--fleet` is for a profile that
|
|
324
|
+
* really is fleet config — a remote `ssh://` endpoint, or a named profile whose
|
|
325
|
+
* shape you want on every box.
|
|
326
|
+
*
|
|
327
|
+
* Existing profiles are NOT migrated: this only decides where a NEW entry is
|
|
328
|
+
* written, so a fleet profile created before this change keeps syncing.
|
|
329
|
+
*/
|
|
330
|
+
export async function createProfile(profile, opts = {}) {
|
|
296
331
|
const meta = readMeta();
|
|
297
332
|
const existingConfigs = allProfileConfigs();
|
|
298
333
|
if (existingConfigs[profile.name]) {
|
|
@@ -327,7 +362,11 @@ export async function createProfile(profile) {
|
|
|
327
362
|
findBrowserPath(profile.browser, profile.binary);
|
|
328
363
|
}
|
|
329
364
|
const config = profileToConfig(profile);
|
|
330
|
-
|
|
365
|
+
// Machine-local unless the caller explicitly asked for the fleet store. The
|
|
366
|
+
// auto `default` is always local regardless of what a caller passes — its
|
|
367
|
+
// binary path and port are this box's, and fleet-syncing it is the rewrite
|
|
368
|
+
// loop RUSH-2161 fixed.
|
|
369
|
+
if (!opts.fleet || isMachineLocalProfile(profile.name)) {
|
|
331
370
|
updateMeta((m) => ({ ...m, deviceBrowser: { ...m.deviceBrowser, [profile.name]: config } }));
|
|
332
371
|
return;
|
|
333
372
|
}
|
|
@@ -365,6 +404,89 @@ export async function deleteProfile(name) {
|
|
|
365
404
|
return { ...m, browser: Object.keys(next).length > 0 ? next : undefined };
|
|
366
405
|
});
|
|
367
406
|
}
|
|
407
|
+
/** Widest NAME column we will grow to before truncating instead. */
|
|
408
|
+
const MAX_NAME_COLUMN = 28;
|
|
409
|
+
/**
|
|
410
|
+
* Pad `text` to exactly `width` visible characters, truncating with an ellipsis
|
|
411
|
+
* when it does not fit. `padEnd` alone does NOT bound a long value — it returns
|
|
412
|
+
* the string unchanged when it already exceeds the width, which is what pushed
|
|
413
|
+
* every later column out of alignment on a name longer than 20 characters
|
|
414
|
+
* (RUSH-2710). Every column here goes through this, never a bare `padEnd`.
|
|
415
|
+
*/
|
|
416
|
+
export function padColumn(text, width) {
|
|
417
|
+
if (width <= 0)
|
|
418
|
+
return '';
|
|
419
|
+
if (text.length <= width)
|
|
420
|
+
return text.padEnd(width);
|
|
421
|
+
if (width === 1)
|
|
422
|
+
return '…';
|
|
423
|
+
return text.slice(0, width - 1) + '…';
|
|
424
|
+
}
|
|
425
|
+
/**
|
|
426
|
+
* Render the `agents browser profiles list` table.
|
|
427
|
+
*
|
|
428
|
+
* Pure (no fs, no config reads) so the alignment and the default-marking rules
|
|
429
|
+
* are unit-testable without a configured machine.
|
|
430
|
+
*
|
|
431
|
+
* Two things used to be called "default" in this listing with no way to tell
|
|
432
|
+
* them apart (RUSH-2710): the profile literally NAMED `default` (the
|
|
433
|
+
* auto-detected one), and whichever profile this machine resolves a bare
|
|
434
|
+
* `agents browser start` to (`agents config set browser.profile <name>`). They
|
|
435
|
+
* are frequently different profiles. Now only the second is a marker — a `*` in
|
|
436
|
+
* a leading column, explained by a legend line — so the name column carries just
|
|
437
|
+
* the name and `default` in it always means the profile of that name.
|
|
438
|
+
*
|
|
439
|
+
* The SCOPE column is the RUSH-2716 companion: it says whether an entry lives on
|
|
440
|
+
* this machine only (`local`) or in the fleet-synced `agents.yaml` (`fleet`), so
|
|
441
|
+
* "why does this box have a profile I never made here?" is answerable at a
|
|
442
|
+
* glance.
|
|
443
|
+
*/
|
|
444
|
+
export function formatProfilesTable(rows, configuredDefault) {
|
|
445
|
+
const cells = rows.map(({ profile, scope }) => {
|
|
446
|
+
const presets = getEndpointPresets(profile);
|
|
447
|
+
const endpoints = Object.entries(presets)
|
|
448
|
+
.map(([name, ep]) => (name.startsWith('endpoint-') ? ep.target : `${name}=${ep.target}`))
|
|
449
|
+
.join(', ');
|
|
450
|
+
return {
|
|
451
|
+
marker: profile.name === configuredDefault ? '*' : ' ',
|
|
452
|
+
name: profile.name,
|
|
453
|
+
browser: profile.browser || '-',
|
|
454
|
+
scope,
|
|
455
|
+
description: profile.description ?? '',
|
|
456
|
+
endpoints,
|
|
457
|
+
};
|
|
458
|
+
});
|
|
459
|
+
const nameWidth = Math.min(MAX_NAME_COLUMN, Math.max('NAME'.length, ...cells.map((c) => c.name.length)));
|
|
460
|
+
const browserWidth = Math.max('BROWSER'.length, ...cells.map((c) => c.browser.length));
|
|
461
|
+
// 'local' / 'fleet' are both 5 chars, so the header is the widest value.
|
|
462
|
+
const scopeWidth = 'SCOPE'.length;
|
|
463
|
+
const hasDescriptions = cells.some((c) => c.description);
|
|
464
|
+
const descWidth = hasDescriptions
|
|
465
|
+
? Math.min(36, Math.max('DESCRIPTION'.length, ...cells.map((c) => c.description.length)))
|
|
466
|
+
: 0;
|
|
467
|
+
const row = (marker, name, browser, scope, desc, endpoints) => `${marker} ` +
|
|
468
|
+
padColumn(name, nameWidth) + ' ' +
|
|
469
|
+
padColumn(browser, browserWidth) + ' ' +
|
|
470
|
+
padColumn(scope, scopeWidth) + ' ' +
|
|
471
|
+
(hasDescriptions ? padColumn(desc, descWidth) + ' ' : '') +
|
|
472
|
+
endpoints;
|
|
473
|
+
const header = row(' ', 'NAME', 'BROWSER', 'SCOPE', 'DESCRIPTION', 'ENDPOINTS');
|
|
474
|
+
const lines = [header, '-'.repeat(header.length)];
|
|
475
|
+
for (const c of cells) {
|
|
476
|
+
lines.push(row(c.marker, c.name, c.browser, c.scope, c.description, c.endpoints));
|
|
477
|
+
}
|
|
478
|
+
if (configuredDefault) {
|
|
479
|
+
lines.push('');
|
|
480
|
+
lines.push(`* = this machine's default profile (${configuredDefault}) — what a bare \`agents browser start\` uses.`);
|
|
481
|
+
}
|
|
482
|
+
lines.push(hasFleetRow(rows)
|
|
483
|
+
? 'scope: local = this machine only · fleet = synced to every machine (agents.yaml).'
|
|
484
|
+
: 'scope: local = this machine only. Create a synced one with: agents browser profiles create <name> --fleet');
|
|
485
|
+
return lines;
|
|
486
|
+
}
|
|
487
|
+
function hasFleetRow(rows) {
|
|
488
|
+
return rows.some((r) => r.scope === 'fleet');
|
|
489
|
+
}
|
|
368
490
|
/**
|
|
369
491
|
* Resolve a profile's endpoint presets into a normalized map regardless of
|
|
370
492
|
* whether the YAML uses the legacy `string[]` shape or the new map shape.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Consent gate for driving THIS machine's browser from another fleet machine.
|
|
3
3
|
*
|
|
4
|
-
* `browser --
|
|
4
|
+
* `browser --device <device>` routes a browser command to `<device>` over SSH (the
|
|
5
5
|
* fleet passthrough) and runs `agents browser ...` there. Every such remote
|
|
6
6
|
* invocation carries the {@link FLEET_REMOTE_ENV} marker, set once at the fleet
|
|
7
7
|
* dispatch site (`maybeRunOnHost`). A machine only accepts being driven when its
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
*/
|
|
15
15
|
/** Env marker set on every remote `agents` invocation by `buildRemoteAgentsInvocation`. */
|
|
16
16
|
export declare const FLEET_REMOTE_ENV = "AGENTS_FLEET_REMOTE";
|
|
17
|
-
/** True when this process was dispatched to this machine by a fleet `--
|
|
17
|
+
/** True when this process was dispatched to this machine by a fleet `--device` run. */
|
|
18
18
|
export declare function isFleetRemoteInvocation(env?: NodeJS.ProcessEnv): boolean;
|
|
19
19
|
/**
|
|
20
20
|
* Whether this machine allows other fleet machines to drive its browser. Reads
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Consent gate for driving THIS machine's browser from another fleet machine.
|
|
3
3
|
*
|
|
4
|
-
* `browser --
|
|
4
|
+
* `browser --device <device>` routes a browser command to `<device>` over SSH (the
|
|
5
5
|
* fleet passthrough) and runs `agents browser ...` there. Every such remote
|
|
6
6
|
* invocation carries the {@link FLEET_REMOTE_ENV} marker, set once at the fleet
|
|
7
7
|
* dispatch site (`maybeRunOnHost`). A machine only accepts being driven when its
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
import { getConfigValue } from '../device-config.js';
|
|
16
16
|
/** Env marker set on every remote `agents` invocation by `buildRemoteAgentsInvocation`. */
|
|
17
17
|
export const FLEET_REMOTE_ENV = 'AGENTS_FLEET_REMOTE';
|
|
18
|
-
/** True when this process was dispatched to this machine by a fleet `--
|
|
18
|
+
/** True when this process was dispatched to this machine by a fleet `--device` run. */
|
|
19
19
|
export function isFleetRemoteInvocation(env = process.env) {
|
|
20
20
|
return env[FLEET_REMOTE_ENV] === '1';
|
|
21
21
|
}
|
|
@@ -42,7 +42,7 @@ export function assertRemoteControlAllowed(opts) {
|
|
|
42
42
|
if (enabled)
|
|
43
43
|
return;
|
|
44
44
|
const who = env.AGENTS_ACTOR_HOST || env.AGENTS_ACTOR || 'A fleet machine';
|
|
45
|
-
throw new Error(`${who} tried to drive this machine's browser over \`browser --
|
|
45
|
+
throw new Error(`${who} tried to drive this machine's browser over \`browser --device\`, but remote ` +
|
|
46
46
|
`browser control is off here. To allow it, run on THIS machine:\n` +
|
|
47
47
|
` agents browser remote-control on`);
|
|
48
48
|
}
|