@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
|
@@ -1,41 +1,43 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Device/user config keys — typed read/write over the
|
|
2
|
+
* Device/user config keys — typed read/write over the three-layer store.
|
|
3
3
|
*
|
|
4
4
|
* One registry (`CONFIG_KEYS`) maps each CLI dotted name to where it lives:
|
|
5
|
-
* - user scope
|
|
6
|
-
*
|
|
7
|
-
* - device scope
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* browser.remote-control, scheduler.enabled,
|
|
16
|
-
* daemon.enabled).
|
|
5
|
+
* - user scope → central `~/.agents/agents.yaml` under `config:` (syncs
|
|
6
|
+
* fleet-wide via `agents repo push/pull`)
|
|
7
|
+
* - device scope → the per-device TRACKED doc
|
|
8
|
+
* `~/.agents/devices/<name>/agents.yaml` under `config:` —
|
|
9
|
+
* conflict-free by construction (each machine writes only
|
|
10
|
+
* its own folder, and the churny auto-written pins no longer
|
|
11
|
+
* share the file)
|
|
12
|
+
* - fleet layer → central `~/.agents/agents.yaml` under
|
|
13
|
+
* `fleet.defaults.config` — fleet-wide defaults written by
|
|
14
|
+
* `agents devices config --fleet <key> <value>`
|
|
17
15
|
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
* not just churn.
|
|
16
|
+
* Read order for a device-scope key: built-in default < fleet.defaults.config
|
|
17
|
+
* < per-device config:. Names and non-secret values only (a secrets-bundle
|
|
18
|
+
* NAME is fine; a credential never is).
|
|
22
19
|
*
|
|
23
20
|
* The device registry (`~/.agents/.history/devices/registry.json`) stays the
|
|
24
21
|
* DISCOVERY cache (address, tailscale snapshot, reachability); the profile
|
|
25
22
|
* fields config can override (ssh.*, platform, user) are overlaid onto it at
|
|
26
23
|
* read time by `lib/devices/resolve-profile.ts`.
|
|
27
24
|
*
|
|
28
|
-
* Legacy stores (
|
|
29
|
-
*
|
|
30
|
-
* by `lib/devices/config-migration.ts`, invoked on the first
|
|
31
|
-
* process — after migration there is ONE read path
|
|
25
|
+
* Legacy stores (central `fleet.devices.<name>.config`, legacy auto-launch.json,
|
|
26
|
+
* doc-level defaultBrowserProfile, pins in tracked docs) are folded into this
|
|
27
|
+
* layout once by `lib/devices/config-migration.ts`, invoked on the first
|
|
28
|
+
* read/write in a process — after migration there is ONE read path per layer,
|
|
29
|
+
* no fallback branches.
|
|
32
30
|
*
|
|
33
31
|
* Unset always means today's behavior (the documented default).
|
|
34
32
|
*/
|
|
35
|
-
import
|
|
33
|
+
import * as fs from 'fs';
|
|
34
|
+
import * as path from 'path';
|
|
35
|
+
import * as yaml from 'yaml';
|
|
36
|
+
import { META_HEADER, getUserAgentsDir, readMeta, updateMeta, withMetaLock } from './state.js';
|
|
37
|
+
import { atomicWriteFileSync } from './fs-atomic.js';
|
|
36
38
|
import { machineId } from './machine-id.js';
|
|
37
39
|
import { assertValidDeviceName } from './devices/registry.js';
|
|
38
|
-
import {
|
|
40
|
+
import { migrateDeviceConfigStores } from './devices/config-migration.js';
|
|
39
41
|
const DEVICE_PLATFORMS = ['windows', 'linux', 'macos', 'unknown'];
|
|
40
42
|
const SSH_AUTH_METHODS = ['key', 'password'];
|
|
41
43
|
/** Roles a device can be marked with — see the `role` key below. */
|
|
@@ -155,9 +157,22 @@ export const CONFIG_KEYS = [
|
|
|
155
157
|
visibility: 'machine',
|
|
156
158
|
type: 'bool',
|
|
157
159
|
defaultValue: false,
|
|
158
|
-
description: "Whether other fleet machines may drive THIS device's browser over `browser --
|
|
160
|
+
description: "Whether other fleet machines may drive THIS device's browser over `browser --device <this-device>`. " +
|
|
159
161
|
'Default off — a fleet-remote drive is refused until the owner runs `agents browser remote-control on`.',
|
|
160
162
|
},
|
|
163
|
+
{
|
|
164
|
+
name: 'browser.task-idle-minutes',
|
|
165
|
+
yamlKey: 'browserTaskIdleMinutes',
|
|
166
|
+
scope: 'device',
|
|
167
|
+
visibility: 'machine',
|
|
168
|
+
type: 'int',
|
|
169
|
+
defaultValue: 30,
|
|
170
|
+
description: 'Minutes a browser task may sit with no IPC action (navigate, click, type, screenshot, …) before the daemon\'s ' +
|
|
171
|
+
'abandoned-task reaper closes its tabs and marks it done (RUSH-2622). 0 disables idle reaping — the reaper still ' +
|
|
172
|
+
"closes a task whose owning agent session has exited, whatever this is set to. Read only on THIS box's own " +
|
|
173
|
+
'reaper tick and `agents browser gc`, so it never applies to a peer.',
|
|
174
|
+
validate: (v) => v >= 0 ? null : 'browser.task-idle-minutes must be >= 0 (0 disables idle reaping).',
|
|
175
|
+
},
|
|
161
176
|
{
|
|
162
177
|
name: 'notes',
|
|
163
178
|
yamlKey: 'notes',
|
|
@@ -292,57 +307,106 @@ function assertValidValue(spec, value) {
|
|
|
292
307
|
// ─── Migration hook ───────────────────────────────────────────────────────────
|
|
293
308
|
let migrationDone = false;
|
|
294
309
|
/**
|
|
295
|
-
* Fold the legacy
|
|
310
|
+
* Fold the legacy config/pins stores into the current layout, once per
|
|
296
311
|
* process. A failure is loud but non-fatal — config reads must keep working,
|
|
297
312
|
* and the next process retries the fold. Honors AGENTS_SKIP_MIGRATION=1, the
|
|
298
313
|
* same gate bootstrap's runMigration uses (tests pin it so a fork never folds
|
|
299
314
|
* the developer's real ~/.agents as a side effect).
|
|
300
|
-
*
|
|
301
|
-
* Call this ONLY from a lifecycle entry point (daemon boot, `runMigration`).
|
|
302
|
-
* It must never hang off a config read or write: `~/.agents/agents.yaml` is a
|
|
303
|
-
* tracked file shared by every machine in the fleet, so a migration on the read
|
|
304
|
-
* path means an ordinary `agents config get` can dirty the shared file. That is
|
|
305
|
-
* what left yosemite-s0 unable to pull — 13 machines each rewriting one tracked
|
|
306
|
-
* path, on nearly every command.
|
|
307
315
|
*/
|
|
308
316
|
export function ensureDeviceConfigMigrated() {
|
|
309
317
|
if (migrationDone || process.env.AGENTS_SKIP_MIGRATION === '1')
|
|
310
318
|
return;
|
|
311
319
|
try {
|
|
312
|
-
|
|
320
|
+
migrateDeviceConfigStores();
|
|
313
321
|
migrationDone = true;
|
|
314
322
|
}
|
|
315
323
|
catch (err) {
|
|
316
324
|
console.error(`device config migration failed (${err?.message ?? err}); a later run retries`);
|
|
317
325
|
}
|
|
318
326
|
}
|
|
319
|
-
// ───
|
|
327
|
+
// ─── Layer reads ──────────────────────────────────────────────────────────────
|
|
328
|
+
/** Path to a device's tracked operator doc (`devices/<name>/agents.yaml`). */
|
|
329
|
+
function deviceDocPath(device) {
|
|
330
|
+
return path.join(getUserAgentsDir(), 'devices', device, 'agents.yaml');
|
|
331
|
+
}
|
|
320
332
|
/**
|
|
321
|
-
*
|
|
322
|
-
*
|
|
323
|
-
*
|
|
324
|
-
* goes through here. Deliberately does NOT auto-trigger the migration: it
|
|
325
|
-
* serves the hot dial/render paths, and the keys it resolves (ssh.*, platform)
|
|
326
|
-
* are new — they never existed in the legacy stores. Keys with legacy data are
|
|
327
|
-
* read through the public API below, which triggers the fold.
|
|
333
|
+
* Read a device's doc. Returns null when the file does not exist. A malformed
|
|
334
|
+
* file is a hard error — silently returning null would let the next write wipe
|
|
335
|
+
* the device's routines/config (same contract as routine-activation's reader).
|
|
328
336
|
*/
|
|
329
|
-
|
|
330
|
-
const
|
|
331
|
-
|
|
337
|
+
function readDeviceDoc(device) {
|
|
338
|
+
const p = deviceDocPath(device);
|
|
339
|
+
let raw;
|
|
340
|
+
try {
|
|
341
|
+
raw = fs.readFileSync(p, 'utf-8');
|
|
342
|
+
}
|
|
343
|
+
catch (err) {
|
|
344
|
+
if (err && err.code === 'ENOENT')
|
|
345
|
+
return null;
|
|
346
|
+
throw err;
|
|
347
|
+
}
|
|
348
|
+
const corrupted = (detail) => new Error(`Device config corrupted at ${p}: ${detail}. Inspect and restore from backup.`);
|
|
349
|
+
let parsed;
|
|
350
|
+
try {
|
|
351
|
+
parsed = yaml.parse(raw);
|
|
352
|
+
}
|
|
353
|
+
catch (err) {
|
|
354
|
+
throw corrupted(err?.message ?? String(err));
|
|
355
|
+
}
|
|
356
|
+
if (parsed === null || parsed === undefined)
|
|
332
357
|
return {};
|
|
333
|
-
|
|
358
|
+
if (typeof parsed !== 'object' || Array.isArray(parsed)) {
|
|
359
|
+
throw corrupted(`expected a YAML map, got ${Array.isArray(parsed) ? 'a list' : JSON.stringify(parsed)}`);
|
|
360
|
+
}
|
|
361
|
+
const doc = parsed;
|
|
362
|
+
if (doc.config !== undefined && (typeof doc.config !== 'object' || doc.config === null || Array.isArray(doc.config))) {
|
|
363
|
+
throw corrupted('config: must be a mapping');
|
|
364
|
+
}
|
|
365
|
+
return doc;
|
|
366
|
+
}
|
|
367
|
+
/** Write a device doc (atomic), preserving keys this module does not own
|
|
368
|
+
* (`routines:`). A doc left empty is removed instead of leaving an empty
|
|
369
|
+
* tracked file behind. */
|
|
370
|
+
function writeDeviceDoc(device, doc) {
|
|
371
|
+
const p = deviceDocPath(device);
|
|
372
|
+
if (Object.keys(doc).length === 0) {
|
|
373
|
+
try {
|
|
374
|
+
fs.rmSync(p, { force: true });
|
|
375
|
+
fs.rmdirSync(path.dirname(p));
|
|
376
|
+
}
|
|
377
|
+
catch { /* dir not empty, or the file was already gone */ }
|
|
378
|
+
return;
|
|
379
|
+
}
|
|
380
|
+
fs.mkdirSync(path.dirname(p), { recursive: true });
|
|
381
|
+
atomicWriteFileSync(p, META_HEADER + yaml.stringify(doc));
|
|
382
|
+
}
|
|
383
|
+
/** The fleet-defaults config layer (central `fleet.defaults.config`; {} when unset). */
|
|
384
|
+
export function readFleetConfigDefaults() {
|
|
385
|
+
const config = readMeta().fleet?.defaults?.config;
|
|
334
386
|
return config && typeof config === 'object' && !Array.isArray(config) ? config : {};
|
|
335
387
|
}
|
|
388
|
+
/** The device layer only: the doc's `config:` block ({} when unset). */
|
|
389
|
+
function readDeviceDocConfig(device) {
|
|
390
|
+
return readDeviceDoc(device)?.config ?? {};
|
|
391
|
+
}
|
|
392
|
+
/**
|
|
393
|
+
* The effective device-scope config block for `device`: fleet.defaults.config
|
|
394
|
+
* overlaid with the per-device doc's config:. This is the single read path
|
|
395
|
+
* post-migration — the profile resolver (`lib/devices/resolve-profile.ts`)
|
|
396
|
+
* goes through here. Deliberately does NOT auto-trigger the migration: it
|
|
397
|
+
* serves the hot dial/render paths. Sync and cheap (small local files).
|
|
398
|
+
*/
|
|
399
|
+
export function readDeviceConfigValues(device) {
|
|
400
|
+
return { ...readFleetConfigDefaults(), ...readDeviceDocConfig(device) };
|
|
401
|
+
}
|
|
336
402
|
/** The device a targeted read/write applies to (default: this machine). */
|
|
337
403
|
function targetDevice(opts) {
|
|
338
404
|
return opts?.device ?? machineId();
|
|
339
405
|
}
|
|
340
406
|
/**
|
|
341
|
-
* A machine-visibility key is only ever readable for THIS box
|
|
342
|
-
*
|
|
343
|
-
*
|
|
344
|
-
* for another machine — that would make `agents devices config <peer>
|
|
345
|
-
* browser.remote-control` look like it reported the peer's consent state.
|
|
407
|
+
* A machine-visibility key is only ever readable for THIS box. Asking for a
|
|
408
|
+
* peer's value is a mistake with a concrete fix, so say so rather than
|
|
409
|
+
* silently returning this machine's answer for another machine.
|
|
346
410
|
*/
|
|
347
411
|
function assertLocalTarget(spec, device) {
|
|
348
412
|
if (spec.scope !== 'device' || spec.visibility !== 'machine')
|
|
@@ -350,39 +414,39 @@ function assertLocalTarget(spec, device) {
|
|
|
350
414
|
if (device === machineId())
|
|
351
415
|
return;
|
|
352
416
|
throw new Error(`${spec.name} is machine-local, so it can only be read or set on the device itself.\n` +
|
|
353
|
-
`Run it on ${device}, e.g.: agents ssh ${device} 'agents config ${spec.name} <value>'`);
|
|
417
|
+
`Run it on ${device}, e.g.: agents ssh ${device} 'agents devices config ${device} ${spec.name} <value>'`);
|
|
354
418
|
}
|
|
355
|
-
/** Get one config key's value and the layer that set it. */
|
|
419
|
+
/** Get one config key's effective value and the layer that set it. */
|
|
356
420
|
export function getConfigValue(name, opts) {
|
|
421
|
+
ensureDeviceConfigMigrated();
|
|
357
422
|
const spec = configKeySpec(name);
|
|
358
423
|
if (spec.scope === 'user') {
|
|
359
424
|
const value = readMeta().config?.[spec.yamlKey];
|
|
360
|
-
return { spec, value,
|
|
425
|
+
return { spec, value, source: value !== undefined ? 'user' : 'default' };
|
|
426
|
+
}
|
|
427
|
+
if (opts?.fleet) {
|
|
428
|
+
const value = readFleetConfigDefaults()[spec.yamlKey];
|
|
429
|
+
return { spec, value, source: value !== undefined ? 'fleet' : 'default' };
|
|
361
430
|
}
|
|
362
431
|
const device = targetDevice(opts);
|
|
363
432
|
assertLocalTarget(spec, device);
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
}
|
|
372
|
-
const value = readDeviceConfigValues(device)[spec.yamlKey];
|
|
373
|
-
return { spec, value, layer: value !== undefined ? 'device' : undefined };
|
|
433
|
+
const docConfig = readDeviceDocConfig(device);
|
|
434
|
+
if (spec.yamlKey in docConfig)
|
|
435
|
+
return { spec, value: docConfig[spec.yamlKey], source: 'device' };
|
|
436
|
+
const fleetConfig = readFleetConfigDefaults();
|
|
437
|
+
if (spec.yamlKey in fleetConfig)
|
|
438
|
+
return { spec, value: fleetConfig[spec.yamlKey], source: 'fleet' };
|
|
439
|
+
return { spec, value: undefined, source: 'default' };
|
|
374
440
|
}
|
|
375
441
|
/**
|
|
376
|
-
* List every known key with its value and the layer that set it.
|
|
442
|
+
* List every known key with its effective value and the layer that set it.
|
|
377
443
|
*
|
|
378
|
-
* Listing a PEER omits its machine-local keys rather than throwing
|
|
379
|
-
* live
|
|
380
|
-
*
|
|
381
|
-
* `agents devices config <peer>` should still show everything it CAN resolve.
|
|
382
|
-
* Asking for such a key by name still errors, with the `agents ssh` fix named.
|
|
444
|
+
* Listing a PEER omits its machine-local keys rather than throwing — those
|
|
445
|
+
* values live on that box and are unknowable from here, but a bulk listing
|
|
446
|
+
* must not hard-fail. Asking for such a key by name still errors.
|
|
383
447
|
*/
|
|
384
448
|
export function listConfig(opts) {
|
|
385
|
-
const isPeer = targetDevice(opts) !== machineId();
|
|
449
|
+
const isPeer = !opts?.fleet && targetDevice(opts) !== machineId();
|
|
386
450
|
const visible = isPeer
|
|
387
451
|
? CONFIG_KEYS.filter((spec) => spec.scope !== 'device' || spec.visibility !== 'machine')
|
|
388
452
|
: CONFIG_KEYS;
|
|
@@ -400,38 +464,42 @@ export function resolveUsagePrimaryHost() {
|
|
|
400
464
|
?? null;
|
|
401
465
|
}
|
|
402
466
|
// ─── Writes ───────────────────────────────────────────────────────────────────
|
|
403
|
-
|
|
467
|
+
/** The fleet manifest for a defaults write: `devices` materializes as an
|
|
468
|
+
* explicit empty map (NOT 'all') so `agents apply` targets nothing until the
|
|
469
|
+
* operator declares a roster. */
|
|
470
|
+
function fleetForDefaultsWrite(fleet) {
|
|
471
|
+
return { ...fleet, devices: fleet && fleet.devices !== undefined ? fleet.devices : {} };
|
|
472
|
+
}
|
|
473
|
+
function setInFleetDefaults(spec, value) {
|
|
404
474
|
updateMeta((m) => {
|
|
405
|
-
const
|
|
406
|
-
const
|
|
407
|
-
|
|
408
|
-
return { ...m, fleet: { ...m.fleet, devices } };
|
|
475
|
+
const fleet = fleetForDefaultsWrite(m.fleet);
|
|
476
|
+
const defaults = { ...fleet.defaults, config: { ...fleet.defaults?.config, [spec.yamlKey]: value } };
|
|
477
|
+
return { ...m, fleet: { ...fleet, defaults } };
|
|
409
478
|
});
|
|
410
479
|
}
|
|
411
|
-
function
|
|
480
|
+
function unsetInFleetDefaults(spec) {
|
|
412
481
|
updateMeta((m) => {
|
|
413
|
-
const stored = m.fleet?.
|
|
414
|
-
if (!stored ||
|
|
415
|
-
return m; // nothing stored —
|
|
416
|
-
const
|
|
417
|
-
if (!prev?.config || !(spec.yamlKey in prev.config))
|
|
418
|
-
return m; // key not present — no write needed
|
|
419
|
-
const config = { ...prev.config };
|
|
482
|
+
const stored = m.fleet?.defaults?.config;
|
|
483
|
+
if (!stored || !(spec.yamlKey in stored))
|
|
484
|
+
return m; // nothing stored — no-op
|
|
485
|
+
const config = { ...stored };
|
|
420
486
|
delete config[spec.yamlKey];
|
|
421
|
-
const
|
|
487
|
+
const defaults = { ...m.fleet.defaults };
|
|
422
488
|
if (Object.keys(config).length > 0)
|
|
423
|
-
|
|
489
|
+
defaults.config = config;
|
|
424
490
|
else
|
|
425
|
-
delete
|
|
426
|
-
const
|
|
427
|
-
if (Object.keys(
|
|
428
|
-
|
|
491
|
+
delete defaults.config;
|
|
492
|
+
const fleet = { ...m.fleet, devices: m.fleet.devices };
|
|
493
|
+
if (Object.keys(defaults).length > 0)
|
|
494
|
+
fleet.defaults = defaults;
|
|
429
495
|
else
|
|
430
|
-
delete
|
|
431
|
-
const fleet = { ...m.fleet, devices };
|
|
496
|
+
delete fleet.defaults;
|
|
432
497
|
// Drop the fleet block entirely when the unset emptied a block that holds
|
|
433
498
|
// nothing else — don't leave a vestigial `fleet: {devices: {}}` behind.
|
|
434
|
-
|
|
499
|
+
const devicesEmpty = fleet.devices == null || fleet.devices === 'all'
|
|
500
|
+
? false
|
|
501
|
+
: Object.keys(fleet.devices).length === 0;
|
|
502
|
+
if (devicesEmpty && !fleet.defaults && !fleet.secrets && !fleet.routines) {
|
|
435
503
|
const { fleet: _, ...rest } = m;
|
|
436
504
|
void _;
|
|
437
505
|
return rest;
|
|
@@ -439,26 +507,65 @@ function unsetInCentralBlock(device, spec) {
|
|
|
439
507
|
return { ...m, fleet };
|
|
440
508
|
});
|
|
441
509
|
}
|
|
442
|
-
|
|
510
|
+
function setInDeviceDoc(device, spec, value) {
|
|
511
|
+
// The doc is shared with writeMetaUnlocked (which owns routines:) — the
|
|
512
|
+
// read-modify-write runs under the meta lock so the two writers can't lose
|
|
513
|
+
// each other's update across processes.
|
|
514
|
+
withMetaLock(() => {
|
|
515
|
+
const doc = readDeviceDoc(device) ?? {};
|
|
516
|
+
doc.config = { ...doc.config, [spec.yamlKey]: value };
|
|
517
|
+
writeDeviceDoc(device, doc);
|
|
518
|
+
});
|
|
519
|
+
}
|
|
520
|
+
function unsetInDeviceDoc(device, spec) {
|
|
521
|
+
withMetaLock(() => {
|
|
522
|
+
const doc = readDeviceDoc(device);
|
|
523
|
+
if (!doc)
|
|
524
|
+
return; // nothing stored — unset is a no-op
|
|
525
|
+
const config = doc.config;
|
|
526
|
+
if (!config || !(spec.yamlKey in config))
|
|
527
|
+
return; // key not present — no write needed
|
|
528
|
+
delete config[spec.yamlKey];
|
|
529
|
+
if (Object.keys(config).length > 0)
|
|
530
|
+
doc.config = config;
|
|
531
|
+
else
|
|
532
|
+
delete doc.config;
|
|
533
|
+
writeDeviceDoc(device, doc);
|
|
534
|
+
});
|
|
535
|
+
}
|
|
536
|
+
/**
|
|
537
|
+
* Set a config key (validated). Device-scope keys target this machine unless
|
|
538
|
+
* `opts.device` names a peer; `opts.fleet` writes the fleet-wide defaults layer
|
|
539
|
+
* instead. User-scope keys reject `fleet` (they are already fleet-wide).
|
|
540
|
+
*/
|
|
443
541
|
export function setConfigValue(name, value, opts) {
|
|
542
|
+
ensureDeviceConfigMigrated();
|
|
444
543
|
const spec = configKeySpec(name);
|
|
445
544
|
assertValidValue(spec, value);
|
|
446
545
|
if (spec.scope === 'user') {
|
|
546
|
+
if (opts?.fleet) {
|
|
547
|
+
throw new Error(`Config key '${spec.name}' is user-scope (already fleet-wide) — --fleet does not apply.`);
|
|
548
|
+
}
|
|
447
549
|
updateMeta((m) => ({ ...m, config: { ...m.config, [spec.yamlKey]: value } }));
|
|
448
550
|
return;
|
|
449
551
|
}
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
if (spec.visibility === 'machine') {
|
|
453
|
-
updateMeta((m) => ({ ...m, deviceConfig: { ...m.deviceConfig, [spec.yamlKey]: value } }));
|
|
552
|
+
if (opts?.fleet) {
|
|
553
|
+
setInFleetDefaults(spec, value);
|
|
454
554
|
return;
|
|
455
555
|
}
|
|
456
|
-
|
|
556
|
+
const device = targetDevice(opts);
|
|
557
|
+
assertLocalTarget(spec, device);
|
|
558
|
+
setInDeviceDoc(device, spec, value);
|
|
457
559
|
}
|
|
458
|
-
/** Unset a config key — restores
|
|
560
|
+
/** Unset a config key — restores the next layer down (fleet default, then the
|
|
561
|
+
* built-in default). No-op when already unset at that layer. */
|
|
459
562
|
export function unsetConfigValue(name, opts) {
|
|
563
|
+
ensureDeviceConfigMigrated();
|
|
460
564
|
const spec = configKeySpec(name);
|
|
461
565
|
if (spec.scope === 'user') {
|
|
566
|
+
if (opts?.fleet) {
|
|
567
|
+
throw new Error(`Config key '${spec.name}' is user-scope (already fleet-wide) — --fleet does not apply.`);
|
|
568
|
+
}
|
|
462
569
|
updateMeta((m) => {
|
|
463
570
|
if (!m.config || !(spec.yamlKey in m.config))
|
|
464
571
|
return m;
|
|
@@ -468,22 +575,13 @@ export function unsetConfigValue(name, opts) {
|
|
|
468
575
|
});
|
|
469
576
|
return;
|
|
470
577
|
}
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
if (spec.visibility === 'machine') {
|
|
474
|
-
updateMeta((m) => {
|
|
475
|
-
if (!m.deviceConfig || !(spec.yamlKey in m.deviceConfig))
|
|
476
|
-
return m;
|
|
477
|
-
const next = { ...m.deviceConfig };
|
|
478
|
-
delete next[spec.yamlKey];
|
|
479
|
-
return { ...m, deviceConfig: Object.keys(next).length > 0 ? next : undefined };
|
|
480
|
-
});
|
|
481
|
-
// Also clear any copy an older CLI left centrally, so the unset is not
|
|
482
|
-
// shadowed by the fallback read above.
|
|
483
|
-
unsetInCentralBlock(device, spec);
|
|
578
|
+
if (opts?.fleet) {
|
|
579
|
+
unsetInFleetDefaults(spec);
|
|
484
580
|
return;
|
|
485
581
|
}
|
|
486
|
-
|
|
582
|
+
const device = targetDevice(opts);
|
|
583
|
+
assertLocalTarget(spec, device);
|
|
584
|
+
unsetInDeviceDoc(device, spec);
|
|
487
585
|
}
|
|
488
586
|
/**
|
|
489
587
|
* The role marked on one device, or undefined when the operator never marked it.
|
|
@@ -505,17 +603,31 @@ export function setConfiguredDeviceRole(name, role) {
|
|
|
505
603
|
setConfigValue('role', role, { device: name });
|
|
506
604
|
}
|
|
507
605
|
/**
|
|
508
|
-
* Every device an
|
|
509
|
-
*
|
|
606
|
+
* Every device with an effective role, keyed by device name. Layers like every
|
|
607
|
+
* other device-scope key: the fleet default (central fleet.defaults.config)
|
|
608
|
+
* applies fleet-wide and the per-device doc wins on conflict. `roster` (the
|
|
609
|
+
* registered device names) lets a fleet default reach devices that have no doc
|
|
610
|
+
* of their own; without it only devices with docs are considered — so a
|
|
611
|
+
* fleet-wide `role` default would silently miss a doc-less device and drop it
|
|
612
|
+
* from the worker allowlist. Mirrors {@link loadAutoLaunchPreferences}.
|
|
510
613
|
*/
|
|
511
|
-
export function listConfiguredDeviceRoles() {
|
|
614
|
+
export function listConfiguredDeviceRoles(roster) {
|
|
512
615
|
ensureDeviceConfigMigrated();
|
|
513
|
-
const devices = readMeta().fleet?.devices;
|
|
514
616
|
const out = {};
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
const
|
|
617
|
+
const fleetRole = readFleetConfigDefaults().role;
|
|
618
|
+
const names = new Set(roster ?? []);
|
|
619
|
+
if (!roster) {
|
|
620
|
+
const devicesRoot = path.join(getUserAgentsDir(), 'devices');
|
|
621
|
+
try {
|
|
622
|
+
for (const entry of fs.readdirSync(devicesRoot, { withFileTypes: true })) {
|
|
623
|
+
if (entry.isDirectory())
|
|
624
|
+
names.add(entry.name);
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
catch { /* no devices/ tree — roster stays empty */ }
|
|
628
|
+
}
|
|
629
|
+
for (const name of names) {
|
|
630
|
+
const role = readDeviceDocConfig(name).role ?? fleetRole;
|
|
519
631
|
if (typeof role === 'string' && DEVICE_ROLES.includes(role)) {
|
|
520
632
|
out[name] = role;
|
|
521
633
|
}
|
|
@@ -533,7 +645,7 @@ export function isAutoLaunchEnabled(name) {
|
|
|
533
645
|
return getConfigValue('auto-launch.enabled', { device: name }).value !== false;
|
|
534
646
|
}
|
|
535
647
|
/** Set whether a device is enabled for auto-launch. Setting the default
|
|
536
|
-
* (enabled) removes the key to keep the
|
|
648
|
+
* (enabled) removes the key to keep the doc minimal. */
|
|
537
649
|
export function setAutoLaunchEnabled(name, enabled) {
|
|
538
650
|
assertValidDeviceName(name);
|
|
539
651
|
if (enabled)
|
|
@@ -547,7 +659,7 @@ export function isAutoLaunchPreferred(name) {
|
|
|
547
659
|
return getConfigValue('auto-launch.preferred', { device: name }).value === true;
|
|
548
660
|
}
|
|
549
661
|
/** Set whether a device is preferred for auto-launch. Setting the default
|
|
550
|
-
* (not preferred) removes the key to keep the
|
|
662
|
+
* (not preferred) removes the key to keep the doc minimal. */
|
|
551
663
|
export function setAutoLaunchPreferred(name, preferred) {
|
|
552
664
|
assertValidDeviceName(name);
|
|
553
665
|
if (preferred)
|
|
@@ -555,22 +667,37 @@ export function setAutoLaunchPreferred(name, preferred) {
|
|
|
555
667
|
else
|
|
556
668
|
unsetConfigValue('auto-launch.preferred', { device: name });
|
|
557
669
|
}
|
|
558
|
-
/**
|
|
559
|
-
*
|
|
560
|
-
|
|
670
|
+
/**
|
|
671
|
+
* Every device's effective auto-launch flags, keyed by device name — the shape
|
|
672
|
+
* the menu-bar snapshot consumes. Layers like every other device-scope key: the
|
|
673
|
+
* fleet default (central fleet.defaults.config) applies fleet-wide and the
|
|
674
|
+
* per-device doc wins on conflict. `roster` (the registered device names) lets
|
|
675
|
+
* a fleet default reach devices that have no doc of their own; without it only
|
|
676
|
+
* devices with docs are listed.
|
|
677
|
+
*/
|
|
678
|
+
export function loadAutoLaunchPreferences(roster) {
|
|
561
679
|
ensureDeviceConfigMigrated();
|
|
562
|
-
const
|
|
680
|
+
const fleet = readFleetConfigDefaults();
|
|
681
|
+
const names = new Set(roster ?? []);
|
|
682
|
+
if (!roster) {
|
|
683
|
+
const devicesRoot = path.join(getUserAgentsDir(), 'devices');
|
|
684
|
+
try {
|
|
685
|
+
for (const entry of fs.readdirSync(devicesRoot, { withFileTypes: true })) {
|
|
686
|
+
if (entry.isDirectory())
|
|
687
|
+
names.add(entry.name);
|
|
688
|
+
}
|
|
689
|
+
}
|
|
690
|
+
catch { /* no devices/ tree — roster stays empty */ }
|
|
691
|
+
}
|
|
563
692
|
const out = {};
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
const
|
|
568
|
-
if (!config)
|
|
569
|
-
continue;
|
|
693
|
+
for (const name of names) {
|
|
694
|
+
const doc = readDeviceDocConfig(name);
|
|
695
|
+
const enabled = (doc.autoLaunchEnabled ?? fleet.autoLaunchEnabled);
|
|
696
|
+
const preferred = (doc.autoLaunchPreferred ?? fleet.autoLaunchPreferred);
|
|
570
697
|
const pref = {};
|
|
571
|
-
if (
|
|
698
|
+
if (enabled === false)
|
|
572
699
|
pref.enabled = false;
|
|
573
|
-
if (
|
|
700
|
+
if (preferred === true)
|
|
574
701
|
pref.preferred = true;
|
|
575
702
|
if (pref.enabled !== undefined || pref.preferred !== undefined)
|
|
576
703
|
out[name] = pref;
|
|
@@ -591,7 +718,7 @@ export function isSchedulerEnabled() {
|
|
|
591
718
|
export function assertSchedulerEnabled() {
|
|
592
719
|
if (isSchedulerEnabled())
|
|
593
720
|
return;
|
|
594
|
-
throw new Error(`The routines scheduler is disabled on this device (scheduler.enabled=false in ~/.agents/
|
|
721
|
+
throw new Error(`The routines scheduler is disabled on this device (scheduler.enabled=false in ~/.agents/devices/${machineId()}/agents.yaml). ` +
|
|
595
722
|
`Re-enable with: agents devices config ${machineId()} scheduler.enabled on`);
|
|
596
723
|
}
|
|
597
724
|
/**
|
|
@@ -619,14 +746,25 @@ export function isDaemonEnabled() {
|
|
|
619
746
|
export function assertDaemonEnabled() {
|
|
620
747
|
if (isDaemonEnabled())
|
|
621
748
|
return;
|
|
622
|
-
throw new Error(`The daemon is disabled on this device (daemon.enabled=false in ~/.agents/
|
|
749
|
+
throw new Error(`The daemon is disabled on this device (daemon.enabled=false in ~/.agents/devices/${machineId()}/agents.yaml). ` +
|
|
623
750
|
`Re-enable with: agents daemon enable`);
|
|
624
751
|
}
|
|
625
752
|
/**
|
|
626
|
-
*
|
|
627
|
-
*
|
|
628
|
-
*
|
|
629
|
-
*
|
|
753
|
+
* Idle window (ms) the browser-task reaper (`browser/hygiene.ts`) uses on THIS
|
|
754
|
+
* machine, or `null` when idle reaping is off (`browser.task-idle-minutes=0`)
|
|
755
|
+
* — session-dead reaping is unaffected either way. Unset means the default 30
|
|
756
|
+
* minutes. Read by the daemon's periodic tick and, as the fallback when a
|
|
757
|
+
* caller omits `--idle-minutes`, by the `gc` IPC action.
|
|
758
|
+
*/
|
|
759
|
+
export function resolveBrowserTaskIdleMs() {
|
|
760
|
+
const minutes = getConfigValue('browser.task-idle-minutes').value ?? 30;
|
|
761
|
+
return minutes === 0 ? null : minutes * 60_000;
|
|
762
|
+
}
|
|
763
|
+
/**
|
|
764
|
+
* Read the effective `agents.max-concurrent` cap for each named device (fleet
|
|
765
|
+
* defaults layered under the per-device doc; no SSH). Devices without a cap
|
|
766
|
+
* are omitted — uncapped is the default. Used as an input to host ranking
|
|
767
|
+
* (teams placement, AGI EXT auto-launch), never as a remote probe.
|
|
630
768
|
*/
|
|
631
769
|
export function readMaxConcurrentCaps(devices) {
|
|
632
770
|
const caps = {};
|