@phnx-labs/agents-cli 1.22.39 → 1.22.40
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +294 -0
- package/README.md +111 -70
- package/dist/bin/agents +0 -0
- package/dist/bootstrap.js +45 -26
- package/dist/browser.js +2 -2
- package/dist/cli/command-registry.d.ts +135 -0
- package/dist/cli/command-registry.js +260 -0
- package/dist/commands/accounts.d.ts +20 -0
- package/dist/commands/accounts.js +186 -25
- package/dist/commands/apply.d.ts +3 -3
- package/dist/commands/apply.js +20 -63
- package/dist/commands/browser.js +206 -94
- package/dist/commands/budget.d.ts +7 -6
- package/dist/commands/budget.js +8 -7
- package/dist/commands/cloud.js +17 -20
- package/dist/commands/commands.js +1 -1
- package/dist/commands/computer-actions.d.ts +1 -35
- package/dist/commands/computer-actions.js +13 -181
- package/dist/commands/computer.d.ts +28 -3
- package/dist/commands/computer.js +93 -65
- package/dist/commands/config.js +16 -3
- package/dist/commands/cost.d.ts +2 -1
- package/dist/commands/cost.js +7 -6
- package/dist/commands/daemon.js +151 -4
- package/dist/commands/detach.js +1 -1
- package/dist/commands/doctor.js +19 -11
- package/dist/commands/events.js +1 -1
- package/dist/commands/exec.d.ts +2 -50
- package/dist/commands/exec.js +160 -215
- package/dist/commands/factory.js +1 -1
- package/dist/commands/feed.d.ts +2 -2
- package/dist/commands/feed.js +9 -12
- package/dist/commands/fleet-capture.js +25 -27
- package/dist/commands/focus.d.ts +2 -3
- package/dist/commands/focus.js +34 -9
- package/dist/commands/go.js +15 -5
- package/dist/commands/harness.d.ts +3 -3
- package/dist/commands/harness.js +53 -5
- package/dist/commands/hooks.js +1 -1
- package/dist/commands/import.js +2 -2
- package/dist/commands/insights.d.ts +5 -5
- package/dist/commands/insights.js +15 -9
- package/dist/commands/inspect.d.ts +2 -3
- package/dist/commands/inspect.js +4 -16
- package/dist/commands/logs.d.ts +2 -2
- package/dist/commands/logs.js +9 -9
- package/dist/commands/mcp.js +2 -2
- package/dist/commands/memory.js +1 -1
- package/dist/commands/message.d.ts +1 -1
- package/dist/commands/message.js +7 -7
- package/dist/commands/mine.d.ts +11 -8
- package/dist/commands/mine.js +11 -10
- package/dist/commands/models.js +1 -1
- package/dist/commands/modes.js +1 -1
- package/dist/commands/monitors.js +23 -6
- package/dist/commands/output.d.ts +7 -6
- package/dist/commands/output.js +11 -10
- package/dist/commands/packages.js +4 -4
- package/dist/commands/perf.js +1 -1
- package/dist/commands/permissions.js +49 -32
- package/dist/commands/plugins.d.ts +1 -1
- package/dist/commands/plugins.js +3 -3
- package/dist/commands/profiles.d.ts +6 -9
- package/dist/commands/profiles.js +8 -321
- package/dist/commands/projects.d.ts +9 -0
- package/dist/commands/projects.js +140 -8
- package/dist/commands/prune.js +5 -13
- package/dist/commands/refresh-rules.js +1 -1
- package/dist/commands/repo.d.ts +5 -7
- package/dist/commands/repo.js +34 -18
- package/dist/commands/resource-view.js +4 -0
- package/dist/commands/resume.d.ts +11 -7
- package/dist/commands/resume.js +82 -98
- package/dist/commands/route.d.ts +12 -0
- package/dist/commands/route.js +261 -0
- package/dist/commands/routines.d.ts +2 -3
- package/dist/commands/routines.js +120 -145
- package/dist/commands/rules.js +1 -1
- package/dist/commands/run-account-picker.d.ts +1 -1
- package/dist/commands/run-account-picker.js +2 -2
- package/dist/commands/run-broadcast.d.ts +21 -0
- package/dist/commands/run-broadcast.js +89 -0
- package/dist/commands/run-cloud.js +1 -1
- package/dist/commands/secrets-vault.d.ts +10 -0
- package/dist/commands/{login.js → secrets-vault.js} +34 -14
- package/dist/commands/secrets.d.ts +4 -4
- package/dist/commands/secrets.js +72 -63
- package/dist/commands/sessions-backfill.js +1 -1
- package/dist/commands/sessions-browser.d.ts +1 -1
- package/dist/commands/sessions-browser.js +9 -5
- package/dist/commands/sessions-export.js +2 -2
- package/dist/commands/sessions-inject.js +4 -5
- package/dist/commands/sessions-migrate.js +16 -27
- package/dist/commands/sessions-picker.d.ts +13 -0
- package/dist/commands/sessions-picker.js +182 -8
- package/dist/commands/sessions-resume.d.ts +7 -3
- package/dist/commands/sessions-resume.js +81 -33
- package/dist/commands/sessions-stats.js +2 -2
- package/dist/commands/sessions.d.ts +75 -68
- package/dist/commands/sessions.js +142 -180
- package/dist/commands/setup-computer.js +1 -1
- package/dist/commands/setup-fleet.js +3 -0
- package/dist/commands/setup-mine.d.ts +7 -3
- package/dist/commands/setup-mine.js +13 -8
- package/dist/commands/setup-secrets.js +2 -2
- package/dist/commands/setup-watchdog.js +2 -2
- package/dist/commands/setup.js +7 -2
- package/dist/commands/share.d.ts +65 -0
- package/dist/commands/share.js +253 -20
- package/dist/commands/skills.js +3 -3
- package/dist/commands/snapshot.d.ts +2 -2
- package/dist/commands/snapshot.js +9 -9
- package/dist/commands/ssh.d.ts +1 -1
- package/dist/commands/ssh.js +186 -64
- package/dist/commands/subagents.js +1 -1
- package/dist/commands/sync.js +24 -9
- package/dist/commands/teams.d.ts +2 -2
- package/dist/commands/teams.js +9 -18
- package/dist/commands/tmux.js +5 -1
- package/dist/commands/trash.js +1 -1
- package/dist/commands/usage.d.ts +1 -1
- package/dist/commands/usage.js +2 -2
- package/dist/commands/utils.d.ts +4 -14
- package/dist/commands/utils.js +6 -27
- package/dist/commands/versions.js +2 -2
- package/dist/commands/view.d.ts +9 -77
- package/dist/commands/view.js +23 -8
- package/dist/commands/watchdog.js +1 -1
- package/dist/commands/webhook.js +11 -25
- package/dist/commands/workflows.js +1 -1
- package/dist/index.js +1 -1
- package/dist/lib/account-capabilities.d.ts +39 -0
- package/dist/lib/account-capabilities.js +59 -0
- package/dist/lib/account-catalog.js +1 -1
- package/dist/lib/account-registry.d.ts +66 -0
- package/dist/lib/account-registry.js +151 -5
- package/dist/lib/{rotate.d.ts → accounting/rotate.d.ts} +4 -4
- package/dist/lib/{rotate.js → accounting/rotate.js} +8 -8
- package/dist/lib/{usage.d.ts → accounting/usage.d.ts} +4 -4
- package/dist/lib/{usage.js → accounting/usage.js} +11 -11
- package/dist/lib/agent-spec/provider.js +1 -1
- package/dist/lib/agents.d.ts +72 -4
- package/dist/lib/agents.js +231 -199
- package/dist/lib/answer-router.d.ts +2 -2
- package/dist/lib/ask-classifier.d.ts +1 -1
- package/dist/lib/ask-classifier.js +1 -1
- package/dist/lib/audit/log.js +1 -1
- package/dist/lib/auth-health.d.ts +1 -1
- package/dist/lib/auth-health.js +2 -2
- package/dist/lib/brand.js +1 -1
- package/dist/lib/browser/caller-identity.d.ts +28 -0
- package/dist/lib/browser/caller-identity.js +156 -0
- package/dist/lib/browser/cdp.js +1 -1
- package/dist/lib/browser/drivers/ssh.d.ts +1 -1
- package/dist/lib/browser/drivers/ssh.js +2 -2
- package/dist/lib/browser/hygiene.d.ts +10 -2
- package/dist/lib/browser/hygiene.js +7 -4
- package/dist/lib/browser/ipc.d.ts +22 -2
- package/dist/lib/browser/ipc.js +185 -21
- package/dist/lib/browser/profiles.d.ts +67 -3
- package/dist/lib/browser/profiles.js +129 -7
- package/dist/lib/browser/remote-control.d.ts +2 -2
- package/dist/lib/browser/remote-control.js +3 -3
- package/dist/lib/browser/runtime-state.d.ts +79 -0
- package/dist/lib/browser/runtime-state.js +119 -1
- package/dist/lib/browser/service.d.ts +113 -1
- package/dist/lib/browser/service.js +454 -40
- package/dist/lib/browser/sessions-list.d.ts +2 -1
- package/dist/lib/browser/sessions-list.js +4 -13
- package/dist/lib/browser/types.d.ts +18 -0
- package/dist/lib/budget/config.js +1 -1
- package/dist/lib/budget/ledger.js +1 -1
- package/dist/lib/byok-usage.js +1 -1
- package/dist/lib/capabilities.js +3 -15
- package/dist/lib/catchup.d.ts +1 -1
- package/dist/lib/catchup.js +1 -1
- package/dist/lib/cloud/dispatch.js +1 -1
- package/dist/lib/cloud/host.d.ts +3 -3
- package/dist/lib/cloud/host.js +5 -5
- package/dist/lib/cloud/rush.d.ts +9 -21
- package/dist/lib/cloud/rush.js +33 -120
- package/dist/lib/cloud/types.d.ts +2 -2
- package/dist/lib/commands.js +3 -13
- package/dist/lib/computer/actions.d.ts +36 -0
- package/dist/lib/computer/actions.js +162 -0
- package/dist/lib/computer/dispatch.d.ts +2 -2
- package/dist/lib/computer/dispatch.js +2 -2
- package/dist/lib/computer/sessions-list.d.ts +3 -3
- package/dist/lib/computer/sessions-list.js +2 -2
- package/dist/lib/config-keys.d.ts +2 -1
- package/dist/lib/config-keys.js +8 -4
- package/dist/lib/config-machine-keys.d.ts +4 -2
- package/dist/lib/config-machine-keys.js +5 -2
- package/dist/lib/crabbox/lease.js +9 -1
- package/dist/lib/crabbox/runtimes.d.ts +32 -7
- package/dist/lib/crabbox/runtimes.js +72 -30
- package/dist/lib/{daemon.d.ts → daemon/daemon.d.ts} +59 -1
- package/dist/lib/{daemon.js → daemon/daemon.js} +237 -49
- package/dist/lib/daemon-services.d.ts +1 -1
- package/dist/lib/daemon-services.js +5 -0
- package/dist/lib/daemon-ticks.d.ts +25 -0
- package/dist/lib/daemon-ticks.js +31 -1
- package/dist/lib/daemon-webhooks.d.ts +102 -0
- package/dist/lib/daemon-webhooks.js +210 -0
- package/dist/lib/device-config.d.ts +85 -75
- package/dist/lib/device-config.js +279 -141
- package/dist/lib/devices/config-migration.d.ts +29 -34
- package/dist/lib/devices/config-migration.js +209 -130
- package/dist/lib/devices/connect.d.ts +2 -2
- package/dist/lib/devices/connect.js +2 -2
- package/dist/lib/devices/discovery-policy.d.ts +30 -0
- package/dist/lib/devices/discovery-policy.js +101 -0
- package/dist/lib/devices/fleet-inventory.js +8 -3
- package/dist/lib/devices/harness-inventory.d.ts +1 -1
- package/dist/lib/devices/harness-inventory.js +12 -3
- package/dist/lib/devices/known-hosts.js +1 -1
- package/dist/lib/devices/pool.d.ts +10 -5
- package/dist/lib/devices/pool.js +5 -7
- package/dist/lib/devices/registry.d.ts +1 -1
- package/dist/lib/devices/registry.js +1 -1
- package/dist/lib/devices/resolve-profile.d.ts +2 -2
- package/dist/lib/devices/resolve-profile.js +2 -2
- package/dist/lib/devices/resolve-target.d.ts +1 -1
- package/dist/lib/devices/resolve-target.js +4 -4
- package/dist/lib/devices/self-host.d.ts +1 -1
- package/dist/lib/devices/self-host.js +3 -3
- package/dist/lib/devices/ssh-config.d.ts +1 -1
- package/dist/lib/devices/stats-cache.js +1 -1
- package/dist/lib/devices/sync.d.ts +3 -1
- package/dist/lib/devices/sync.js +3 -3
- package/dist/lib/doctor-diff.js +4 -4
- package/dist/lib/drift-sync.js +2 -2
- package/dist/lib/drift.js +2 -2
- package/dist/lib/event-families.d.ts +1 -1
- package/dist/lib/event-stream.d.ts +1 -1
- package/dist/lib/event-stream.js +2 -2
- package/dist/lib/events-ingest.js +2 -2
- package/dist/lib/exec.d.ts +4 -4
- package/dist/lib/exec.js +11 -11
- package/dist/lib/factory/snapshot.d.ts +1 -1
- package/dist/lib/factory/snapshot.js +1 -1
- package/dist/lib/{activity.d.ts → feed/activity.d.ts} +1 -1
- package/dist/lib/{activity.js → feed/activity.js} +7 -7
- package/dist/lib/{events.d.ts → feed/events.d.ts} +2 -2
- package/dist/lib/{events.js → feed/events.js} +5 -5
- package/dist/lib/{feed.js → feed/feed.js} +4 -4
- package/dist/lib/feed-outcome.d.ts +1 -1
- package/dist/lib/feed-policy.d.ts +1 -1
- package/dist/lib/feed-policy.js +1 -1
- package/dist/lib/feed-post.d.ts +1 -1
- package/dist/lib/feed-post.js +1 -1
- package/dist/lib/feed-ranking.d.ts +1 -1
- package/dist/lib/fleet/apply.d.ts +0 -6
- package/dist/lib/fleet/apply.js +18 -45
- package/dist/lib/fleet/auth-sync.d.ts +16 -35
- package/dist/lib/fleet/auth-sync.js +16 -75
- package/dist/lib/fleet/capture.js +8 -6
- package/dist/lib/fleet/manifest.js +23 -11
- package/dist/lib/fleet/types.d.ts +19 -7
- package/dist/lib/fleet-cache.d.ts +1 -1
- package/dist/lib/fleet-cache.js +1 -1
- package/dist/lib/format.d.ts +19 -0
- package/dist/lib/format.js +44 -1
- package/dist/lib/friction-heuristics.d.ts +1 -1
- package/dist/lib/git.d.ts +24 -1
- package/dist/lib/git.js +82 -38
- package/dist/lib/heal.js +3 -3
- package/dist/lib/hooks.d.ts +18 -0
- package/dist/lib/hooks.js +113 -1
- package/dist/lib/hosts/credentials.d.ts +30 -10
- package/dist/lib/hosts/credentials.js +38 -26
- package/dist/lib/hosts/dispatch.d.ts +3 -3
- package/dist/lib/hosts/dispatch.js +3 -3
- package/dist/lib/hosts/option.d.ts +3 -3
- package/dist/lib/hosts/option.js +7 -8
- package/dist/lib/hosts/passthrough.d.ts +17 -17
- package/dist/lib/hosts/passthrough.js +67 -50
- package/dist/lib/hosts/providers/devices.d.ts +1 -1
- package/dist/lib/hosts/providers/devices.js +1 -1
- package/dist/lib/hosts/reconcile.d.ts +1 -1
- package/dist/lib/hosts/reconcile.js +1 -1
- package/dist/lib/hosts/reconnect.d.ts +1 -1
- package/dist/lib/hosts/reconnect.js +2 -2
- package/dist/lib/hosts/registry.d.ts +5 -5
- package/dist/lib/hosts/registry.js +5 -5
- package/dist/lib/hosts/remote-cmd.d.ts +10 -10
- package/dist/lib/hosts/remote-cmd.js +25 -18
- package/dist/lib/hosts/remote-os.d.ts +4 -4
- package/dist/lib/hosts/remote-os.js +4 -4
- package/dist/lib/hosts/remote-session-id.d.ts +2 -2
- package/dist/lib/hosts/remote-session-id.js +2 -2
- package/dist/lib/hosts/routing-flag.d.ts +3 -3
- package/dist/lib/hosts/routing-flag.js +4 -5
- package/dist/lib/hosts/run-target.d.ts +4 -4
- package/dist/lib/hosts/run-target.js +4 -4
- package/dist/lib/hosts/session-index.d.ts +2 -2
- package/dist/lib/hosts/session-index.js +1 -1
- package/dist/lib/hosts/session-marker.d.ts +1 -1
- package/dist/lib/hosts/session-marker.js +1 -1
- package/dist/lib/hosts/types.d.ts +2 -2
- package/dist/lib/hosts/types.js +2 -2
- package/dist/lib/import.js +1 -1
- package/dist/lib/{migrate.d.ts → installations/migrate.d.ts} +13 -1
- package/dist/lib/{migrate.js → installations/migrate.js} +160 -40
- package/dist/lib/installations/resolve.js +1 -1
- package/dist/lib/installations/strategies.js +1 -1
- package/dist/lib/installations/update.js +2 -2
- package/dist/lib/{versions.d.ts → installations/versions.d.ts} +12 -3
- package/dist/lib/{versions.js → installations/versions.js} +51 -31
- package/dist/lib/isolation-boundary-report.js +1 -1
- package/dist/lib/linear-projects.d.ts +28 -0
- package/dist/lib/linear-projects.js +30 -0
- package/dist/lib/loop.js +1 -1
- package/dist/lib/mailbox-gc.js +1 -1
- package/dist/lib/mailbox.js +1 -1
- package/dist/lib/mcp-registry.d.ts +62 -0
- package/dist/lib/mcp-registry.js +177 -0
- package/dist/lib/mcp.d.ts +5 -0
- package/dist/lib/mcp.js +124 -307
- package/dist/lib/menubar/MenubarHelper.app/Contents/CodeResources +0 -0
- package/dist/lib/menubar/MenubarHelper.app/Contents/MacOS/MenubarHelper +0 -0
- package/dist/lib/menubar/install-menubar.d.ts +7 -0
- package/dist/lib/menubar/install-menubar.js +24 -6
- package/dist/lib/menubar/snapshot.d.ts +7 -0
- package/dist/lib/menubar/snapshot.js +8 -6
- package/dist/lib/models.js +1 -1
- package/dist/lib/monitors/config.d.ts +12 -0
- package/dist/lib/monitors/config.js +3 -0
- package/dist/lib/monitors/dispatch.js +26 -5
- package/dist/lib/monitors/engine.js +10 -0
- package/dist/lib/monitors/sources/webhook.d.ts +1 -1
- package/dist/lib/monitors/state.d.ts +42 -0
- package/dist/lib/monitors/state.js +30 -0
- package/dist/lib/notify.d.ts +1 -1
- package/dist/lib/observe-aliases.d.ts +2 -2
- package/dist/lib/observe-aliases.js +2 -11
- package/dist/lib/output/git-output.js +2 -2
- package/dist/lib/overdue.d.ts +1 -1
- package/dist/lib/overdue.js +1 -1
- package/dist/lib/permissions-registry.d.ts +65 -0
- package/dist/lib/permissions-registry.js +599 -0
- package/dist/lib/permissions.d.ts +24 -13
- package/dist/lib/permissions.js +52 -271
- package/dist/lib/picker.d.ts +16 -0
- package/dist/lib/picker.js +33 -3
- package/dist/lib/placement.d.ts +1 -1
- package/dist/lib/placement.js +4 -4
- package/dist/lib/platform/paths.d.ts +8 -0
- package/dist/lib/platform/paths.js +11 -0
- package/dist/lib/platform/posixpath.js +3 -3
- package/dist/lib/{plugin-marketplace.d.ts → plugins/plugin-marketplace.d.ts} +1 -1
- package/dist/lib/{plugin-marketplace.js → plugins/plugin-marketplace.js} +2 -2
- package/dist/lib/{plugins.d.ts → plugins/plugins.d.ts} +1 -1
- package/dist/lib/{plugins.js → plugins/plugins.js} +7 -7
- package/dist/lib/{skills.d.ts → plugins/skills.d.ts} +1 -1
- package/dist/lib/{skills.js → plugins/skills.js} +7 -7
- package/dist/lib/pricing/cost.d.ts +1 -1
- package/dist/lib/pricing/cost.js +1 -1
- package/dist/lib/profiles-presets.d.ts +1 -1
- package/dist/lib/profiles-presets.js +1 -1
- package/dist/lib/profiles.js +2 -2
- package/dist/lib/project-import.js +4 -1
- package/dist/lib/project-launch.d.ts +1 -1
- package/dist/lib/project-launch.js +3 -3
- package/dist/lib/project-pull.d.ts +128 -0
- package/dist/lib/project-pull.js +384 -0
- package/dist/lib/project-root.d.ts +2 -2
- package/dist/lib/project-root.js +2 -2
- package/dist/lib/project-status.js +1 -1
- package/dist/lib/projects.d.ts +23 -0
- package/dist/lib/projects.js +29 -6
- package/dist/lib/refresh.d.ts +12 -1
- package/dist/lib/refresh.js +16 -9
- package/dist/lib/registry.d.ts +9 -2
- package/dist/lib/registry.js +11 -4
- package/dist/lib/resources.d.ts +2 -2
- package/dist/lib/resources.js +2 -2
- package/dist/lib/routers.d.ts +81 -0
- package/dist/lib/routers.js +153 -0
- package/dist/lib/routine-context.d.ts +1 -0
- package/dist/lib/routine-context.js +7 -2
- package/dist/lib/routine-notify-owner.d.ts +1 -1
- package/dist/lib/routine-notify.d.ts +1 -1
- package/dist/lib/routine-notify.js +1 -1
- package/dist/lib/routine-process-cleanup.d.ts +1 -1
- package/dist/lib/routine-readiness.d.ts +1 -1
- package/dist/lib/routine-readiness.js +11 -4
- package/dist/lib/routines-placement.d.ts +12 -2
- package/dist/lib/routines-placement.js +20 -3
- package/dist/lib/routines-project.d.ts +1 -1
- package/dist/lib/routines-project.js +1 -1
- package/dist/lib/rules/compile.d.ts +1 -0
- package/dist/lib/rules/compile.js +10 -2
- package/dist/lib/rules/rules.js +1 -1
- package/dist/lib/run-notify.js +1 -1
- package/dist/lib/runner.d.ts +80 -2
- package/dist/lib/runner.js +241 -62
- package/dist/lib/sandbox.d.ts +1 -1
- package/dist/lib/scheduler.d.ts +1 -1
- package/dist/lib/scheduler.js +1 -1
- package/dist/lib/{routines.d.ts → scheduling/routines.d.ts} +54 -9
- package/dist/lib/{routines.js → scheduling/routines.js} +173 -14
- package/dist/lib/secrets/Agents CLI.app/Contents/CodeResources +0 -0
- package/dist/lib/secrets/Agents CLI.app/Contents/MacOS/Agents CLI +0 -0
- package/dist/lib/secrets/agent.js +2 -2
- package/dist/lib/secrets/audit.js +1 -1
- package/dist/lib/secrets/bundles.d.ts +3 -3
- package/dist/lib/secrets/bundles.js +7 -7
- package/dist/lib/secrets/index.js +1 -1
- package/dist/lib/secrets/list-filter.d.ts +1 -1
- package/dist/lib/secrets/list-filter.js +2 -2
- package/dist/lib/secrets/push.d.ts +1 -1
- package/dist/lib/secrets/push.js +10 -12
- package/dist/lib/secrets/remote.d.ts +12 -10
- package/dist/lib/secrets/remote.js +21 -14
- package/dist/lib/secrets/vault.js +2 -2
- package/dist/lib/self-heal/checks/shadowing.js +1 -1
- package/dist/lib/self-heal/checks/shims.js +1 -1
- package/dist/lib/self-update.d.ts +39 -4
- package/dist/lib/self-update.js +78 -25
- package/dist/lib/serve/control.d.ts +1 -1
- package/dist/lib/serve/control.js +4 -4
- package/dist/lib/serve/data.d.ts +1 -1
- package/dist/lib/serve/data.js +1 -1
- package/dist/lib/serve/stream.js +1 -1
- package/dist/lib/service-manifest.d.ts +29 -0
- package/dist/lib/service-manifest.js +80 -0
- package/dist/lib/session/active.d.ts +59 -7
- package/dist/lib/session/active.js +158 -17
- package/dist/lib/session/bash-command.js +1 -1
- package/dist/lib/session/claude-accounts.d.ts +1 -1
- package/dist/lib/session/claude-accounts.js +1 -1
- package/dist/lib/session/db.d.ts +10 -2
- package/dist/lib/session/db.js +25 -6
- package/dist/lib/session/discover.d.ts +77 -0
- package/dist/lib/session/discover.js +130 -25
- package/dist/lib/session/fork.js +1 -1
- package/dist/lib/session/inject.d.ts +1 -1
- package/dist/lib/session/insights.d.ts +1 -1
- package/dist/lib/session/insights.js +1 -1
- package/dist/lib/session/live-metadata.d.ts +15 -0
- package/dist/lib/session/live-metadata.js +76 -0
- package/dist/lib/session/migrate-targets.d.ts +1 -1
- package/dist/lib/session/recovery.d.ts +1 -1
- package/dist/lib/session/recovery.js +2 -2
- package/dist/lib/session/remote-active.d.ts +10 -1
- package/dist/lib/session/remote-active.js +8 -3
- package/dist/lib/session/remote-bundle.d.ts +1 -1
- package/dist/lib/session/remote-bundle.js +2 -2
- package/dist/lib/session/remote-list.d.ts +15 -4
- package/dist/lib/session/remote-list.js +40 -3
- package/dist/lib/session/remote.d.ts +5 -5
- package/dist/lib/session/remote.js +13 -17
- package/dist/lib/session/resume-command.d.ts +3 -2
- package/dist/lib/session/resume-command.js +4 -3
- package/dist/lib/session/resume-owner.d.ts +3 -3
- package/dist/lib/session/resume-owner.js +3 -3
- package/dist/lib/session/session-cache.d.ts +12 -0
- package/dist/lib/session/session-cache.js +2 -0
- package/dist/lib/session/shell-programs.js +1 -1
- package/dist/lib/session/state.js +5 -5
- package/dist/lib/session/team-filter.d.ts +1 -1
- package/dist/lib/session/team-filter.js +1 -1
- package/dist/lib/session/types.d.ts +3 -3
- package/dist/lib/session/width.d.ts +2 -2
- package/dist/lib/session/width.js +2 -2
- package/dist/lib/share/delete.d.ts +21 -0
- package/dist/lib/share/delete.js +42 -0
- package/dist/lib/share/publish.d.ts +82 -0
- package/dist/lib/share/publish.js +170 -18
- package/dist/lib/share/worker-template.js +172 -9
- package/dist/lib/shims.js +35 -7
- package/dist/lib/smart-launch.d.ts +4 -4
- package/dist/lib/smart-launch.js +6 -4
- package/dist/lib/snapshot.d.ts +4 -4
- package/dist/lib/snapshot.js +2 -2
- package/dist/lib/ssh-exec.d.ts +1 -1
- package/dist/lib/ssh-exec.js +2 -2
- package/dist/lib/ssh-tunnel.d.ts +10 -10
- package/dist/lib/ssh-tunnel.js +12 -12
- package/dist/lib/staleness/checkers/hooks.d.ts +1 -1
- package/dist/lib/staleness/checkers/hooks.js +1 -1
- package/dist/lib/staleness/detectors/permissions.js +0 -23
- package/dist/lib/staleness/detectors/plugins.js +1 -1
- package/dist/lib/staleness/fingerprint.js +1 -1
- package/dist/lib/staleness/layers.d.ts +1 -1
- package/dist/lib/staleness/layers.js +1 -1
- package/dist/lib/staleness/writers/mcp.js +3 -1
- package/dist/lib/staleness/writers/plugins.js +1 -1
- package/dist/lib/staleness/writers/types.d.ts +8 -0
- package/dist/lib/startup/command-registry.d.ts +5 -147
- package/dist/lib/startup/command-registry.js +38 -303
- package/dist/lib/startup/dev-build.d.ts +0 -21
- package/dist/lib/startup/dev-build.js +29 -8
- package/dist/lib/state.d.ts +19 -1
- package/dist/lib/state.js +120 -51
- package/dist/lib/subagents.js +1 -1
- package/dist/lib/sync-status.js +1 -1
- package/dist/lib/sync-umbrella.d.ts +6 -1
- package/dist/lib/sync-umbrella.js +9 -4
- package/dist/lib/teams/agents.js +2 -2
- package/dist/lib/teams/registry.js +1 -1
- package/dist/lib/terminal/backends/vscodium-agent.js +1 -1
- package/dist/lib/terminal/engine.js +1 -1
- package/dist/lib/terminal/index.d.ts +4 -0
- package/dist/lib/terminal/index.js +3 -0
- package/dist/lib/terminal/inject.d.ts +2 -2
- package/dist/lib/terminal/inject.js +2 -2
- package/dist/lib/terminal/transport.js +1 -1
- package/dist/lib/tmux/index.d.ts +1 -1
- package/dist/lib/tmux/index.js +1 -1
- package/dist/lib/tmux/session.d.ts +21 -5
- package/dist/lib/tmux/session.js +76 -22
- package/dist/lib/triggers/handlers.d.ts +1 -1
- package/dist/lib/triggers/handlers.js +2 -2
- package/dist/lib/triggers/webhook.d.ts +36 -2
- package/dist/lib/triggers/webhook.js +97 -42
- package/dist/lib/types.d.ts +18 -6
- package/dist/lib/usage-fleet.d.ts +1 -1
- package/dist/lib/usage-fleet.js +1 -1
- package/dist/lib/usage-refresh.d.ts +1 -1
- package/dist/lib/usage-refresh.js +3 -3
- package/dist/lib/version-duplicates.js +2 -2
- package/dist/lib/view-types.d.ts +56 -0
- package/dist/lib/view-types.js +1 -0
- package/dist/lib/watchdog/rotate.d.ts +2 -2
- package/dist/lib/watchdog/rotate.js +3 -3
- package/dist/lib/watchdog/runner.d.ts +2 -3
- package/dist/lib/watchdog/runner.js +3 -4
- package/dist/lib/workflows.js +1 -1
- package/package.json +2 -1
- package/scripts/postinstall.js +2 -2
- package/dist/commands/bench.d.ts +0 -2
- package/dist/commands/bench.js +0 -101
- package/dist/commands/cp.d.ts +0 -84
- package/dist/commands/cp.js +0 -231
- package/dist/commands/login.d.ts +0 -2
- package/dist/lib/resources/commands.d.ts +0 -46
- package/dist/lib/resources/commands.js +0 -211
- package/dist/lib/resources/hooks.d.ts +0 -16
- package/dist/lib/resources/hooks.js +0 -153
- package/dist/lib/resources/mcp.d.ts +0 -34
- package/dist/lib/resources/mcp.js +0 -250
- package/dist/lib/resources/memory.d.ts +0 -15
- package/dist/lib/resources/memory.js +0 -46
- package/dist/lib/resources/permissions.d.ts +0 -13
- package/dist/lib/resources/permissions.js +0 -202
- package/dist/lib/resources/rules.d.ts +0 -46
- package/dist/lib/resources/rules.js +0 -179
- package/dist/lib/resources/skills.d.ts +0 -37
- package/dist/lib/resources/skills.js +0 -247
- package/dist/lib/resources/subagents.d.ts +0 -46
- package/dist/lib/resources/subagents.js +0 -202
- /package/dist/lib/{feed.d.ts → feed/feed.d.ts} +0 -0
package/dist/commands/skills.js
CHANGED
|
@@ -7,8 +7,8 @@ import { select, checkbox } from '@inquirer/prompts';
|
|
|
7
7
|
import { AGENTS, resolveAgentName, formatAgentError, agentLabel, } from '../lib/agents.js';
|
|
8
8
|
import { capableAgents } from '../lib/capabilities.js';
|
|
9
9
|
import { cloneRepo } from '../lib/git.js';
|
|
10
|
-
import { discoverSkillsFromRepo, installSkillCentrally, listInstalledSkills, listInstalledSkillsWithScope, getSkillInfo, getSkillRules, getSkillsDir, countSkillFiles, tryParseSkillMetadata, diffVersionSkills, iterSkillsCapableVersions, removeSkillFromVersion, } from '../lib/skills.js';
|
|
11
|
-
import { getGlobalDefault, syncResourcesToVersion, promptAgentVersionSelection, getVersionHomePath, } from '../lib/versions.js';
|
|
10
|
+
import { discoverSkillsFromRepo, installSkillCentrally, listInstalledSkills, listInstalledSkillsWithScope, getSkillInfo, getSkillRules, getSkillsDir, countSkillFiles, tryParseSkillMetadata, diffVersionSkills, iterSkillsCapableVersions, removeSkillFromVersion, } from '../lib/plugins/skills.js';
|
|
11
|
+
import { getGlobalDefault, syncResourcesToVersion, promptAgentVersionSelection, getVersionHomePath, } from '../lib/installations/versions.js';
|
|
12
12
|
import { recordVersionResources } from '../lib/state.js';
|
|
13
13
|
import { isPromptCancelled, isInteractiveTerminal, parseCommaSeparatedList, printWithPager, requireInteractiveSelection, resolveAgentTargetsAutoInstalling, promptRemovalTargets, resolveListFilterOrExit, } from './utils.js';
|
|
14
14
|
import { showResourceList, buildTargetsSection, } from './resource-view.js';
|
|
@@ -180,7 +180,7 @@ Examples:
|
|
|
180
180
|
const skillMdPath = path.join(localPath, 'SKILL.md');
|
|
181
181
|
if (fs.existsSync(skillMdPath)) {
|
|
182
182
|
const skillName = path.basename(localPath);
|
|
183
|
-
const { validateSkillMetadata, countSkillRules } = await import('../lib/skills.js');
|
|
183
|
+
const { validateSkillMetadata, countSkillRules } = await import('../lib/plugins/skills.js');
|
|
184
184
|
const parseResult = tryParseSkillMetadata(localPath);
|
|
185
185
|
const validation = validateSkillMetadata(parseResult.metadata, skillName);
|
|
186
186
|
// Warn if YAML is invalid
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* `agents snapshot` — one-process consumer snapshot for pollers.
|
|
2
|
+
* `agents devices snapshot` — one-process consumer snapshot for pollers.
|
|
3
3
|
*
|
|
4
4
|
* Replaces the N× `view --json` + `sessions --active --json` (+ optional feed)
|
|
5
5
|
* fork storm with a single command. Does NOT replace `agents status`, which
|
|
@@ -8,4 +8,4 @@
|
|
|
8
8
|
* JSON shape: {@link FleetSnapshot} in `lib/snapshot.ts` (version: 1).
|
|
9
9
|
*/
|
|
10
10
|
import type { Command } from 'commander';
|
|
11
|
-
export declare function registerSnapshotCommand(
|
|
11
|
+
export declare function registerSnapshotCommand(devicesCmd: Command): void;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* `agents snapshot` — one-process consumer snapshot for pollers.
|
|
2
|
+
* `agents devices snapshot` — one-process consumer snapshot for pollers.
|
|
3
3
|
*
|
|
4
4
|
* Replaces the N× `view --json` + `sessions --active --json` (+ optional feed)
|
|
5
5
|
* fork storm with a single command. Does NOT replace `agents status`, which
|
|
@@ -59,11 +59,11 @@ function renderHuman(snap) {
|
|
|
59
59
|
: 'system ok';
|
|
60
60
|
console.log(` ${'Sync'.padEnd(12)} ${sys} · ${need} version${need === 1 ? '' : 's'} need sync`);
|
|
61
61
|
}
|
|
62
|
-
console.log(chalk.gray('\n Machine-readable: agents snapshot --json\n' +
|
|
62
|
+
console.log(chalk.gray('\n Machine-readable: agents devices snapshot --json\n' +
|
|
63
63
|
' Sync-only (unchanged): agents status --json'));
|
|
64
64
|
}
|
|
65
|
-
export function registerSnapshotCommand(
|
|
66
|
-
const cmd = addHostOption(
|
|
65
|
+
export function registerSnapshotCommand(devicesCmd) {
|
|
66
|
+
const cmd = addHostOption(devicesCmd
|
|
67
67
|
.command('snapshot')
|
|
68
68
|
.description('One-process poll snapshot: install inventory + active sessions (optional feed/sync). Not the sync-status command — use `agents status` for drift.'))
|
|
69
69
|
.option('--json', 'Emit the machine-readable FleetSnapshot contract (version 1)')
|
|
@@ -74,19 +74,19 @@ export function registerSnapshotCommand(program) {
|
|
|
74
74
|
setHelpSections(cmd, {
|
|
75
75
|
examples: `
|
|
76
76
|
# One-shot inventory + local active sessions (JSON)
|
|
77
|
-
agents snapshot --json
|
|
77
|
+
agents devices snapshot --json
|
|
78
78
|
|
|
79
79
|
# Same, plus open feed blocks for needs-you polls
|
|
80
|
-
agents snapshot --json --with-feed
|
|
80
|
+
agents devices snapshot --json --with-feed
|
|
81
81
|
|
|
82
82
|
# Fleet-wide active sessions (matches sessions --active scope)
|
|
83
|
-
agents snapshot --json --all-hosts
|
|
83
|
+
agents devices snapshot --json --all-hosts
|
|
84
84
|
|
|
85
85
|
# Inventory for one harness only (an AGI EXT-style usage poll)
|
|
86
|
-
agents snapshot --json --agent claude
|
|
86
|
+
agents devices snapshot --json --agent claude
|
|
87
87
|
|
|
88
88
|
# Run the whole snapshot on another device
|
|
89
|
-
agents snapshot --json --
|
|
89
|
+
agents devices snapshot --json --device yosemite-s0
|
|
90
90
|
`,
|
|
91
91
|
});
|
|
92
92
|
cmd.action(async (opts, command) => {
|
package/dist/commands/ssh.d.ts
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* (offline → fail fast instead of a 2-minute hang), platform-aware exec
|
|
8
8
|
* (PowerShell on Windows), and password-from-bundle auth via an askpass shim.
|
|
9
9
|
* Rendering the registry to an ssh_config include also lets plain ssh / scp /
|
|
10
|
-
* rsync / `agents sessions --
|
|
10
|
+
* rsync / `agents sessions --device` resolve the same logical names.
|
|
11
11
|
*/
|
|
12
12
|
import type { Command } from 'commander';
|
|
13
13
|
import { type FanOutDeviceTarget } from '../lib/devices/fleet.js';
|
package/dist/commands/ssh.js
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* (offline → fail fast instead of a 2-minute hang), platform-aware exec
|
|
8
8
|
* (PowerShell on Windows), and password-from-bundle auth via an askpass shim.
|
|
9
9
|
* Rendering the registry to an ssh_config include also lets plain ssh / scp /
|
|
10
|
-
* rsync / `agents sessions --
|
|
10
|
+
* rsync / `agents sessions --device` resolve the same logical names.
|
|
11
11
|
*/
|
|
12
12
|
import { spawnSync } from 'child_process';
|
|
13
13
|
import * as fs from 'fs';
|
|
@@ -31,6 +31,7 @@ import { defaultPickerChecked, localLoginUser, planDeviceReconciliation, runDevi
|
|
|
31
31
|
import { resolveDeviceTarget, splitUserHost } from '../lib/devices/resolve-target.js';
|
|
32
32
|
import { deriveMirroredCwd } from '../lib/project-root.js';
|
|
33
33
|
import { clearPendingSentinel } from '../lib/devices/pending.js';
|
|
34
|
+
import { getDeviceDiscoveryStatus, setDeviceDiscoveryStatus } from '../lib/devices/discovery-policy.js';
|
|
34
35
|
import { isInteractiveTerminal, isPromptCancelled } from './utils.js';
|
|
35
36
|
import { hostNameFor, renderSshConfig } from '../lib/devices/ssh-config.js';
|
|
36
37
|
import { ASKPASS_BUNDLE_ENV, ASKPASS_KEY_ENV, buildSshInvocation, deviceIdentityArgs, fleetDialTarget, writeAskpassShim, } from '../lib/devices/connect.js';
|
|
@@ -54,6 +55,7 @@ import { ALL_AGENT_IDS } from '../lib/agents.js';
|
|
|
54
55
|
import { collectLocalHarnessInventory, groupByAccount, renderAccountsMatrix, renderHarnessMatrix, } from '../lib/devices/harness-inventory.js';
|
|
55
56
|
import { crabboxList, crabboxFind, crabboxSshArgv } from '../lib/crabbox/cli.js';
|
|
56
57
|
import { boxAddress, boxStatus, fmtIdleShort, fmtExpiresShort, registerLeaseCommand } from './lease.js';
|
|
58
|
+
import { registerSnapshotCommand } from './snapshot.js';
|
|
57
59
|
import { authCellColor, formatCheckedAge, isDeadVerdict, readAuthHealthCache, summarizeHostAuth, summarizeVerdicts, verdictColor, verdictLabel, writeFleetAuthRows, } from '../lib/auth-health.js';
|
|
58
60
|
import { runFleetLogin } from '../lib/fleet/remote-login.js';
|
|
59
61
|
import { getConfigValue, listConfig, setConfigValue, unsetConfigValue, configKeySpec, autoPoolMode, configuredDeviceRole, listConfiguredDeviceRoles, setConfiguredDeviceRole, } from '../lib/device-config.js';
|
|
@@ -62,7 +64,7 @@ import { registerCommandGroups, setHelpSections } from '../lib/help.js';
|
|
|
62
64
|
/** One-line summary of a device for `list`. `isSelf` marks the machine this
|
|
63
65
|
* command is running on so it stands out from the rest of the tailnet.
|
|
64
66
|
* `isInteractive` marks the configured interactive host (`devices config <name> interactive.host`). */
|
|
65
|
-
function deviceSummary(d, isSelf = false, stats, isInteractive = false) {
|
|
67
|
+
function deviceSummary(d, isSelf = false, stats, isInteractive = false, roles) {
|
|
66
68
|
d = resolveDeviceProfile(d);
|
|
67
69
|
const addr = hostNameFor(d) ?? chalk.gray('no address');
|
|
68
70
|
// Prefer a fresh live verdict (this run's probe, else the written-back
|
|
@@ -78,7 +80,9 @@ function deviceSummary(d, isSelf = false, stats, isInteractive = false) {
|
|
|
78
80
|
const name = isSelf ? chalk.bold.cyan(d.name.padEnd(16)) : chalk.bold(d.name.padEnd(16));
|
|
79
81
|
const here = isSelf ? chalk.cyan(' ← this machine') : '';
|
|
80
82
|
const interactive = isInteractive ? chalk.yellow(' ★ interactive') : '';
|
|
81
|
-
|
|
83
|
+
// `roles` defaults to a single-device roster so a fleet-wide `role` default
|
|
84
|
+
// still reaches this device even when it has no per-device doc of its own.
|
|
85
|
+
const role = roleTag(d.name, roles ?? listConfiguredDeviceRoles([d.name]));
|
|
82
86
|
return `${marker}${name} ${String(d.platform).padEnd(8)} ${(d.user ? d.user + '@' : '') + addr} ${online}${reach}${here}${interactive}${role}`;
|
|
83
87
|
}
|
|
84
88
|
/** The fleet-wide role mark, rendered for a device row. Empty when unmarked —
|
|
@@ -119,9 +123,11 @@ function pctCell(v, width) {
|
|
|
119
123
|
* capacity summary is appended whenever stats were gathered.
|
|
120
124
|
*/
|
|
121
125
|
function renderDeviceTable(reg, names, self, statsMap, full = false, interactiveHost) {
|
|
122
|
-
if (!statsMap)
|
|
123
|
-
|
|
124
|
-
|
|
126
|
+
if (!statsMap) {
|
|
127
|
+
const roles = listConfiguredDeviceRoles(names);
|
|
128
|
+
return names.map((n) => deviceSummary(reg[n], n === self, undefined, n === interactiveHost, roles));
|
|
129
|
+
}
|
|
130
|
+
const deviceRoles = listConfiguredDeviceRoles(names);
|
|
125
131
|
const lines = [];
|
|
126
132
|
const head = ' ' +
|
|
127
133
|
chalk.gray('device'.padEnd(16)) +
|
|
@@ -319,13 +325,16 @@ async function runInteractiveDeviceSync() {
|
|
|
319
325
|
for (const name of plan.toRegister) {
|
|
320
326
|
const input = withDefaultUser(nodeToDeviceInput(byName.get(name)), reg[name]?.user, localUser);
|
|
321
327
|
await upsertDevice(name, input);
|
|
328
|
+
setDeviceDiscoveryStatus(name, 'approved');
|
|
322
329
|
}
|
|
323
330
|
for (const name of plan.toUnignore)
|
|
324
331
|
await removeIgnored(name);
|
|
325
332
|
for (const name of plan.toRemove)
|
|
326
333
|
await removeDevice(name);
|
|
327
|
-
for (const name of plan.toIgnore)
|
|
334
|
+
for (const name of plan.toIgnore) {
|
|
328
335
|
await addIgnored(name);
|
|
336
|
+
setDeviceDiscoveryStatus(name, 'ignored');
|
|
337
|
+
}
|
|
329
338
|
const parts = [
|
|
330
339
|
chalk.green(`${plan.toRegister.length} registered`),
|
|
331
340
|
plan.toRemove.length ? chalk.yellow(`${plan.toRemove.length} removed`) : null,
|
|
@@ -435,11 +444,14 @@ async function probeRemoteHealth(target) {
|
|
|
435
444
|
inventory: parsed.fleet,
|
|
436
445
|
};
|
|
437
446
|
}
|
|
438
|
-
/**
|
|
447
|
+
/** Device-layer config only (not fleet defaults), keyed by the canonical YAML key. */
|
|
439
448
|
function deviceConfigJson(name) {
|
|
440
449
|
const config = {};
|
|
441
450
|
for (const entry of listConfig({ device: name })) {
|
|
442
|
-
|
|
451
|
+
// The device's OWN layer only — a fleet-default value is not this
|
|
452
|
+
// device's setting (the effective profile fields already carry the
|
|
453
|
+
// merged view via resolveDeviceProfile).
|
|
454
|
+
if (entry.source !== 'device')
|
|
443
455
|
continue;
|
|
444
456
|
config[entry.spec.yamlKey] = entry.value;
|
|
445
457
|
}
|
|
@@ -982,9 +994,10 @@ function registerDevicesCommands(program) {
|
|
|
982
994
|
notes: '`agents fleet` is an alias for `agents devices` — same subcommands.',
|
|
983
995
|
});
|
|
984
996
|
registerLeaseCommand(devicesCmd);
|
|
997
|
+
registerSnapshotCommand(devicesCmd);
|
|
985
998
|
registerCommandGroups(devicesCmd, [
|
|
986
999
|
{ title: 'Discover & register', names: ['sync', 'register', 'add', 'ignore', 'unignore', 'rm'] },
|
|
987
|
-
{ title: 'Inspect', names: ['list', 'show', 'status', 'ping', 'harnesses', 'accounts'] },
|
|
1000
|
+
{ title: 'Inspect', names: ['list', 'show', 'status', 'ping', 'harnesses', 'accounts', 'snapshot'] },
|
|
988
1001
|
{ title: 'Disposable devices', names: ['lease'] },
|
|
989
1002
|
{ title: 'Configure a device', names: ['config', 'render'] },
|
|
990
1003
|
{ title: 'Fleet operations', names: ['update', 'run', 'login', 'pair-ios', 'capture', 'apply'] },
|
|
@@ -1001,6 +1014,8 @@ function registerDevicesCommands(program) {
|
|
|
1001
1014
|
const spinner = ora('Reading tailscale status...').start();
|
|
1002
1015
|
try {
|
|
1003
1016
|
const res = await runDeviceSync();
|
|
1017
|
+
for (const name of res.syncedNames)
|
|
1018
|
+
setDeviceDiscoveryStatus(name, 'approved');
|
|
1004
1019
|
const extra = res.pending.length ? chalk.gray(` (${res.pending.length} new)`) : '';
|
|
1005
1020
|
spinner.succeed(`Synced ${res.synced} device${res.synced === 1 ? '' : 's'} from Tailscale${extra}`);
|
|
1006
1021
|
}
|
|
@@ -1016,7 +1031,7 @@ function registerDevicesCommands(program) {
|
|
|
1016
1031
|
registerFleetApplyAlias(devicesCmd);
|
|
1017
1032
|
devicesCmd
|
|
1018
1033
|
.command('register <name>')
|
|
1019
|
-
.description('Register a discovered
|
|
1034
|
+
.description('Register a discovered node and sync the approval through agents.yaml fleet.discovery.')
|
|
1020
1035
|
.action(async (name) => {
|
|
1021
1036
|
try {
|
|
1022
1037
|
const nodes = parseTailscaleStatus(tailscaleStatusJson());
|
|
@@ -1027,6 +1042,7 @@ function registerDevicesCommands(program) {
|
|
|
1027
1042
|
}
|
|
1028
1043
|
await removeIgnored(name); // a re-registered node is no longer dismissed
|
|
1029
1044
|
const d = await upsertDevice(name, nodeToDeviceInput(node));
|
|
1045
|
+
setDeviceDiscoveryStatus(name, 'approved');
|
|
1030
1046
|
clearPendingSentinel(name); // drop the notification immediately
|
|
1031
1047
|
console.log(chalk.green(`Registered '${name}'`) + chalk.gray(` (${d.platform})`));
|
|
1032
1048
|
}
|
|
@@ -1037,11 +1053,12 @@ function registerDevicesCommands(program) {
|
|
|
1037
1053
|
});
|
|
1038
1054
|
devicesCmd
|
|
1039
1055
|
.command('ignore <name>')
|
|
1040
|
-
.description('Dismiss a node
|
|
1056
|
+
.description('Dismiss a node and sync the decision through agents.yaml fleet.discovery (also removes it locally).')
|
|
1041
1057
|
.action(async (name) => {
|
|
1042
1058
|
try {
|
|
1043
1059
|
await removeDevice(name);
|
|
1044
1060
|
await addIgnored(name);
|
|
1061
|
+
setDeviceDiscoveryStatus(name, 'ignored');
|
|
1045
1062
|
clearPendingSentinel(name); // drop the notification immediately
|
|
1046
1063
|
console.log(chalk.green(`Ignored '${name}'`) + chalk.gray(" — it won't be suggested again. Undo with `agents devices unignore`."));
|
|
1047
1064
|
}
|
|
@@ -1054,11 +1071,13 @@ function registerDevicesCommands(program) {
|
|
|
1054
1071
|
.command('unignore <name>')
|
|
1055
1072
|
.description('Undo `ignore`: allow a node to be discovered and registered again.')
|
|
1056
1073
|
.action(async (name) => {
|
|
1074
|
+
const portableWasIgnored = getDeviceDiscoveryStatus(name) === 'ignored';
|
|
1057
1075
|
const ok = await removeIgnored(name);
|
|
1058
|
-
if (!ok) {
|
|
1076
|
+
if (!ok && !portableWasIgnored) {
|
|
1059
1077
|
console.error(chalk.gray(`'${name}' was not ignored.`));
|
|
1060
1078
|
return;
|
|
1061
1079
|
}
|
|
1080
|
+
setDeviceDiscoveryStatus(name, undefined);
|
|
1062
1081
|
console.log(chalk.green(`No longer ignoring '${name}'`) + chalk.gray(' — run `agents devices sync` to register it.'));
|
|
1063
1082
|
});
|
|
1064
1083
|
// ─── devices config (unified settings surface) ────────────────────────────
|
|
@@ -1094,18 +1113,39 @@ function registerDevicesCommands(program) {
|
|
|
1094
1113
|
};
|
|
1095
1114
|
/** The device-scope config entries for `name` (what the config surface edits). */
|
|
1096
1115
|
const deviceConfigEntries = (name) => listConfig({ device: name }).filter((e) => e.spec.scope === 'device');
|
|
1116
|
+
/** Render one entry's effective value with its layer tag. */
|
|
1117
|
+
const entryValueText = (e) => {
|
|
1118
|
+
if (e.source === 'default')
|
|
1119
|
+
return chalk.gray('— (default)');
|
|
1120
|
+
const tag = e.source === 'fleet' ? chalk.yellow(' (fleet default)') : e.source === 'user' ? chalk.gray(' (user scope)') : '';
|
|
1121
|
+
return chalk.cyan(JSON.stringify(e.value)) + tag;
|
|
1122
|
+
};
|
|
1097
1123
|
/** Print the full resolved config for a device (bare invocation, non-menu). */
|
|
1098
1124
|
const printDevicesConfig = (name, json) => {
|
|
1099
1125
|
const entries = deviceConfigEntries(name);
|
|
1100
1126
|
if (json) {
|
|
1101
1127
|
const config = {};
|
|
1102
1128
|
for (const e of entries)
|
|
1103
|
-
|
|
1104
|
-
config[e.spec.name] = e.value;
|
|
1129
|
+
config[e.spec.name] = { value: e.value ?? null, source: e.source };
|
|
1105
1130
|
writeJson({ device: name, config });
|
|
1106
1131
|
return;
|
|
1107
1132
|
}
|
|
1108
1133
|
console.log(chalk.bold(`Config for '${name}'`));
|
|
1134
|
+
for (const e of entries) {
|
|
1135
|
+
console.log(` ${e.spec.name.padEnd(24)} ${entryValueText(e)}${chalk.gray(` ${e.spec.description}`)}`);
|
|
1136
|
+
}
|
|
1137
|
+
};
|
|
1138
|
+
/** Print the fleet-wide defaults layer (`config --fleet`, bare). */
|
|
1139
|
+
const printFleetConfig = (json) => {
|
|
1140
|
+
const entries = listConfig({ fleet: true }).filter((e) => e.spec.scope === 'device');
|
|
1141
|
+
if (json) {
|
|
1142
|
+
const config = {};
|
|
1143
|
+
for (const e of entries)
|
|
1144
|
+
config[e.spec.name] = { value: e.value ?? null, source: e.source };
|
|
1145
|
+
writeJson({ fleet: true, config });
|
|
1146
|
+
return;
|
|
1147
|
+
}
|
|
1148
|
+
console.log(chalk.bold('Fleet-wide config defaults') + chalk.gray(' (every device inherits these unless it overrides the key)'));
|
|
1109
1149
|
for (const e of entries) {
|
|
1110
1150
|
const value = e.value === undefined ? chalk.gray('— (default)') : chalk.cyan(JSON.stringify(e.value));
|
|
1111
1151
|
console.log(` ${e.spec.name.padEnd(24)} ${value}${chalk.gray(` ${e.spec.description}`)}`);
|
|
@@ -1114,11 +1154,60 @@ function registerDevicesCommands(program) {
|
|
|
1114
1154
|
/**
|
|
1115
1155
|
* The `devices config` engine — shared by the config command's action and
|
|
1116
1156
|
* every tombstone. `quiet` performs the write with no output (a tombstone
|
|
1117
|
-
* that prints its own legacy shape).
|
|
1118
|
-
*
|
|
1157
|
+
* that prints its own legacy shape). `fleet` targets the fleet-wide defaults
|
|
1158
|
+
* layer instead of a device (`name` is then unused). Throws on a bad
|
|
1159
|
+
* key/value; callers map that to exit 1.
|
|
1119
1160
|
*/
|
|
1120
1161
|
const runDevicesConfig = async (name, key, valueParts, opts) => {
|
|
1121
1162
|
const spec = key ? configKeySpec(key) : undefined; // unknown key → throw listing the valid keys
|
|
1163
|
+
// ── Fleet-defaults layer (`--fleet`): no device involved.
|
|
1164
|
+
if (opts.fleet) {
|
|
1165
|
+
if (spec && spec.scope === 'user') {
|
|
1166
|
+
throw new Error(`Config key '${spec.name}' is user-scope (already fleet-wide) — --fleet does not apply.`);
|
|
1167
|
+
}
|
|
1168
|
+
if (opts.unset) {
|
|
1169
|
+
if (!spec)
|
|
1170
|
+
throw new Error('--unset needs a key: agents devices config --fleet <key> --unset');
|
|
1171
|
+
unsetConfigValue(spec.name, { fleet: true });
|
|
1172
|
+
if (opts.quiet)
|
|
1173
|
+
return;
|
|
1174
|
+
if (opts.json)
|
|
1175
|
+
writeJson({ fleet: true, key: spec.name, value: null, source: 'default' });
|
|
1176
|
+
else
|
|
1177
|
+
console.log(chalk.green(`Unset ${spec.name}`) + chalk.gray(' in the fleet defaults.'));
|
|
1178
|
+
return;
|
|
1179
|
+
}
|
|
1180
|
+
if (spec && valueParts.length > 0) {
|
|
1181
|
+
let value;
|
|
1182
|
+
if (spec.type === 'string-list') {
|
|
1183
|
+
const existing = getConfigValue(spec.name, { fleet: true }).value ?? [];
|
|
1184
|
+
value = [...existing, valueParts.join(' ')];
|
|
1185
|
+
}
|
|
1186
|
+
else {
|
|
1187
|
+
value = parseConfigValueInput(spec, valueParts.join(' '));
|
|
1188
|
+
}
|
|
1189
|
+
setConfigValue(spec.name, value, { fleet: true });
|
|
1190
|
+
if (opts.quiet)
|
|
1191
|
+
return;
|
|
1192
|
+
if (opts.json)
|
|
1193
|
+
writeJson({ fleet: true, key: spec.name, value, source: 'fleet' });
|
|
1194
|
+
else
|
|
1195
|
+
console.log(chalk.green(`Set ${spec.name} = ${JSON.stringify(value)}`) + chalk.gray(' as the fleet-wide default.'));
|
|
1196
|
+
return;
|
|
1197
|
+
}
|
|
1198
|
+
if (spec) {
|
|
1199
|
+
const entry = getConfigValue(spec.name, { fleet: true });
|
|
1200
|
+
if (opts.quiet)
|
|
1201
|
+
return;
|
|
1202
|
+
if (opts.json)
|
|
1203
|
+
writeJson({ fleet: true, key: spec.name, value: entry.value ?? null, source: entry.source });
|
|
1204
|
+
else
|
|
1205
|
+
console.log(` ${spec.name.padEnd(24)} ${entryValueText(entry)}${chalk.gray(` ${spec.description}`)}`);
|
|
1206
|
+
return;
|
|
1207
|
+
}
|
|
1208
|
+
printFleetConfig(Boolean(opts.json));
|
|
1209
|
+
return;
|
|
1210
|
+
}
|
|
1122
1211
|
// User-scope keys (interactive.host) are stored centrally — the device name
|
|
1123
1212
|
// is syntax only, so an unregistered name is not an error for them.
|
|
1124
1213
|
if (!spec || spec.scope === 'device')
|
|
@@ -1130,9 +1219,9 @@ function registerDevicesCommands(program) {
|
|
|
1130
1219
|
if (opts.quiet)
|
|
1131
1220
|
return;
|
|
1132
1221
|
if (opts.json)
|
|
1133
|
-
writeJson({ device: name, key: spec.name, value: null });
|
|
1222
|
+
writeJson({ device: name, key: spec.name, value: null, source: 'default' });
|
|
1134
1223
|
else
|
|
1135
|
-
console.log(chalk.green(`Unset ${spec.name}`) + chalk.gray(` on '${name}' — back to the default.`));
|
|
1224
|
+
console.log(chalk.green(`Unset ${spec.name}`) + chalk.gray(` on '${name}' — falls back to the fleet default / built-in behavior.`));
|
|
1136
1225
|
return;
|
|
1137
1226
|
}
|
|
1138
1227
|
if (spec && valueParts.length > 0) {
|
|
@@ -1149,7 +1238,7 @@ function registerDevicesCommands(program) {
|
|
|
1149
1238
|
if (opts.quiet)
|
|
1150
1239
|
return;
|
|
1151
1240
|
if (opts.json)
|
|
1152
|
-
writeJson({ device: name, key: spec.name, value });
|
|
1241
|
+
writeJson({ device: name, key: spec.name, value, source: 'device' });
|
|
1153
1242
|
else
|
|
1154
1243
|
console.log(chalk.green(`Set ${spec.name} = ${JSON.stringify(value)}`) + chalk.gray(` on '${name}'.`));
|
|
1155
1244
|
return;
|
|
@@ -1159,13 +1248,10 @@ function registerDevicesCommands(program) {
|
|
|
1159
1248
|
if (opts.quiet)
|
|
1160
1249
|
return;
|
|
1161
1250
|
if (opts.json) {
|
|
1162
|
-
writeJson({ device: name, key: spec.name, value: entry.value ?? null });
|
|
1163
|
-
}
|
|
1164
|
-
else if (entry.value === undefined) {
|
|
1165
|
-
console.log(` ${spec.name.padEnd(24)} ${chalk.gray('— (default)')}${chalk.gray(` ${spec.description}`)}`);
|
|
1251
|
+
writeJson({ device: name, key: spec.name, value: entry.value ?? null, source: entry.source });
|
|
1166
1252
|
}
|
|
1167
1253
|
else {
|
|
1168
|
-
console.log(` ${spec.name.padEnd(24)} ${
|
|
1254
|
+
console.log(` ${spec.name.padEnd(24)} ${entryValueText(entry)}${chalk.gray(` ${spec.description}`)}`);
|
|
1169
1255
|
}
|
|
1170
1256
|
return;
|
|
1171
1257
|
}
|
|
@@ -1180,22 +1266,26 @@ function registerDevicesCommands(program) {
|
|
|
1180
1266
|
* The `devices role` engine — read or write the fleet-wide role mark, and say
|
|
1181
1267
|
* what it does to automatic placement.
|
|
1182
1268
|
*
|
|
1183
|
-
* A role written here lands in
|
|
1184
|
-
*
|
|
1185
|
-
* `worker | personal` only: a
|
|
1186
|
-
*
|
|
1187
|
-
*
|
|
1188
|
-
* `
|
|
1189
|
-
*
|
|
1190
|
-
*
|
|
1269
|
+
* A role written here lands in that device's tracked per-device doc
|
|
1270
|
+
* (`devices/<name>/agents.yaml` `config.role`) and syncs with repo
|
|
1271
|
+
* push/pull. The vocabulary is deliberately `worker | personal` only: a
|
|
1272
|
+
* paired cockpit's `control` role lives in the per-machine device registry,
|
|
1273
|
+
* is written by `agents devices pair-ios`, and is what the existing
|
|
1274
|
+
* dial-exclusion filters (`isControlDevice`) read. Accepting `control` here
|
|
1275
|
+
* too would promise a fleet-wide dial exclusion this key cannot deliver —
|
|
1276
|
+
* those filters read each box's own registry, so the mark would only hold
|
|
1277
|
+
* on the machine that ran the command.
|
|
1191
1278
|
*/
|
|
1192
1279
|
const runDevicesRole = async (name, role, opts) => {
|
|
1193
1280
|
if (!name) {
|
|
1194
1281
|
if (role)
|
|
1195
1282
|
throw new Error('Name a device: agents devices role <name> <worker|personal>');
|
|
1196
|
-
const roles = listConfiguredDeviceRoles();
|
|
1197
|
-
const mode = autoPoolMode();
|
|
1198
1283
|
const reg = await loadDevices();
|
|
1284
|
+
// The full registered roster, not just online — a fleet-wide `role`
|
|
1285
|
+
// default must reach a registered device even when it has no per-device
|
|
1286
|
+
// doc of its own, or it silently falls out of the worker allowlist.
|
|
1287
|
+
const roles = listConfiguredDeviceRoles(Object.keys(reg));
|
|
1288
|
+
const mode = autoPoolMode();
|
|
1199
1289
|
const online = Object.entries(reg)
|
|
1200
1290
|
.filter(([, d]) => d?.tailscale?.online !== false)
|
|
1201
1291
|
.map(([n]) => n);
|
|
@@ -1240,12 +1330,17 @@ function registerDevicesCommands(program) {
|
|
|
1240
1330
|
// configuredDeviceRole's key spec validates the value; a bad one throws with
|
|
1241
1331
|
// the accepted list, which the command's catch turns into exit 1.
|
|
1242
1332
|
setConfiguredDeviceRole(name, role);
|
|
1333
|
+
// Full registered roster, mirroring the bare-listing branch above — a
|
|
1334
|
+
// fleet-wide `role` default must reach a doc-less registered device here
|
|
1335
|
+
// too, or `autoPoolWorkers` under-reports the allowlist right after this
|
|
1336
|
+
// write changed it.
|
|
1337
|
+
const roles = listConfiguredDeviceRoles(Object.keys(await loadDevices()));
|
|
1243
1338
|
if (opts.json) {
|
|
1244
|
-
writeJson({ device: name, role, autoPoolWorkers: listWorkerDevices() });
|
|
1339
|
+
writeJson({ device: name, role, autoPoolWorkers: listWorkerDevices({ roles }) });
|
|
1245
1340
|
return;
|
|
1246
1341
|
}
|
|
1247
1342
|
console.log(chalk.green(`Marked '${name}' role=${role}.`));
|
|
1248
|
-
const workers = listWorkerDevices();
|
|
1343
|
+
const workers = listWorkerDevices({ roles });
|
|
1249
1344
|
if (workers.length > 0) {
|
|
1250
1345
|
console.log(chalk.gray(`\`--device auto\` now picks only from: ${workers.join(', ')}`));
|
|
1251
1346
|
}
|
|
@@ -1254,7 +1349,9 @@ function registerDevicesCommands(program) {
|
|
|
1254
1349
|
}
|
|
1255
1350
|
console.log(chalk.gray('Sync it to the fleet with `agents repo push`.'));
|
|
1256
1351
|
};
|
|
1257
|
-
/** The interactive settings menu: pick a key, edit it, repeat. TTY-only.
|
|
1352
|
+
/** The interactive settings menu: pick a key, edit it, repeat. TTY-only.
|
|
1353
|
+
* Shows EFFECTIVE values (with a fleet tag when inherited); edits always
|
|
1354
|
+
* write the device layer. */
|
|
1258
1355
|
const runDevicesConfigMenu = async (name) => {
|
|
1259
1356
|
const { select, input, confirm } = await import('@inquirer/prompts');
|
|
1260
1357
|
const DONE = '__done__';
|
|
@@ -1262,12 +1359,12 @@ function registerDevicesCommands(program) {
|
|
|
1262
1359
|
for (;;) {
|
|
1263
1360
|
const entries = deviceConfigEntries(name);
|
|
1264
1361
|
const picked = await select({
|
|
1265
|
-
message: `Config for '${name}' — pick a key to edit:`,
|
|
1362
|
+
message: `Config for '${name}' — pick a key to edit (writes the device layer):`,
|
|
1266
1363
|
pageSize: Math.min(entries.length + 1, 20),
|
|
1267
1364
|
choices: [
|
|
1268
1365
|
...entries.map((e) => {
|
|
1269
|
-
const value = e.
|
|
1270
|
-
?
|
|
1366
|
+
const value = e.source !== 'default'
|
|
1367
|
+
? entryValueText(e)
|
|
1271
1368
|
: chalk.gray(e.spec.defaultValue !== undefined
|
|
1272
1369
|
? `default: ${JSON.stringify(e.spec.defaultValue)}`
|
|
1273
1370
|
: 'unset (default)');
|
|
@@ -1317,14 +1414,25 @@ function registerDevicesCommands(program) {
|
|
|
1317
1414
|
}
|
|
1318
1415
|
};
|
|
1319
1416
|
const configCmd = devicesCmd
|
|
1320
|
-
.command('config
|
|
1417
|
+
.command('config [name] [key] [value...]')
|
|
1321
1418
|
.description('Get, set, or unset a device’s settings (scheduler, agent cap, ssh overrides, auto-launch, notes). ' +
|
|
1322
1419
|
'Bare opens an interactive settings menu (TTY) or prints the resolved config (piped). ' +
|
|
1323
|
-
'
|
|
1324
|
-
|
|
1325
|
-
.option('--
|
|
1420
|
+
'Per-device values live in the tracked devices/<name>/agents.yaml config: block; --fleet targets the ' +
|
|
1421
|
+
'fleet-wide defaults (central fleet.defaults.config) every device inherits unless it overrides the key.')
|
|
1422
|
+
.option('--fleet', 'target the fleet-wide defaults layer instead of a device (first positional is the key)')
|
|
1423
|
+
.option('--unset', 'reset the key at that layer (a device key then inherits the fleet default)')
|
|
1424
|
+
.option('--json', 'output machine-readable JSON (each key carries its source: device | fleet | default)')
|
|
1326
1425
|
.action(async (name, key, valueParts, opts) => {
|
|
1327
1426
|
try {
|
|
1427
|
+
if (opts.fleet) {
|
|
1428
|
+
// Positionals shift left: the first one is the key, the rest the value.
|
|
1429
|
+
const fleetValue = [key, ...(valueParts ?? [])].filter((v) => v !== undefined);
|
|
1430
|
+
await runDevicesConfig(undefined, name, fleetValue, opts);
|
|
1431
|
+
return;
|
|
1432
|
+
}
|
|
1433
|
+
if (!name) {
|
|
1434
|
+
throw new Error('Missing device name. Usage: agents devices config <name> [key] [value] — or --fleet <key> <value> for the fleet-wide defaults.');
|
|
1435
|
+
}
|
|
1328
1436
|
await runDevicesConfig(name, key, valueParts ?? [], opts);
|
|
1329
1437
|
}
|
|
1330
1438
|
catch (err) {
|
|
@@ -1335,10 +1443,13 @@ function registerDevicesCommands(program) {
|
|
|
1335
1443
|
setHelpSections(configCmd, {
|
|
1336
1444
|
examples: `
|
|
1337
1445
|
agents devices config mac-mini # settings menu (TTY) / print config (piped)
|
|
1338
|
-
agents devices config mac-mini agents.max-concurrent 4 # cap concurrent agents
|
|
1446
|
+
agents devices config mac-mini agents.max-concurrent 4 # cap concurrent agents on mac-mini
|
|
1339
1447
|
agents devices config mac-mini scheduler.enabled off # no routines firing there
|
|
1340
|
-
agents devices config mac-mini scheduler.enabled # read
|
|
1341
|
-
agents devices config mac-mini scheduler.enabled --unset #
|
|
1448
|
+
agents devices config mac-mini scheduler.enabled # read the effective value back
|
|
1449
|
+
agents devices config mac-mini scheduler.enabled --unset # inherit the fleet default again
|
|
1450
|
+
agents devices config --fleet scheduler.enabled off # fleet-wide default (all devices)
|
|
1451
|
+
agents devices config --fleet agents.max-concurrent 2 # every box caps at 2 unless it overrides
|
|
1452
|
+
agents devices config --fleet # print the fleet defaults layer
|
|
1342
1453
|
agents devices config mac-mini notes "runs the releases" # append an operator note
|
|
1343
1454
|
agents devices config win-mini ssh.auth password # password auth…
|
|
1344
1455
|
agents devices config win-mini ssh.bundle muqsit # …from this secrets bundle
|
|
@@ -1347,26 +1458,33 @@ function registerDevicesCommands(program) {
|
|
|
1347
1458
|
agents devices config mac-mini auto-launch.enabled off # exclude from AGI EXT auto-launch
|
|
1348
1459
|
agents devices config mac-mini auto-launch.preferred on # boost in auto-launch ranking
|
|
1349
1460
|
agents devices config zion interactive.host zion # user scope: where agents show YOU artifacts
|
|
1350
|
-
agents devices config mac-mini --json # machine-readable
|
|
1461
|
+
agents devices config mac-mini --json # machine-readable, per-key source
|
|
1351
1462
|
`,
|
|
1352
1463
|
notes: `
|
|
1353
1464
|
Keys: role (worker|personal), see 'agents devices role',
|
|
1354
1465
|
agents.max-concurrent, scheduler.enabled, daemon.enabled,
|
|
1355
|
-
watchdog.enabled, tmux.enabled, browser.remote-control,
|
|
1466
|
+
watchdog.enabled, tmux.enabled, browser.remote-control,
|
|
1467
|
+
browser.task-idle-minutes, browser.profile,
|
|
1356
1468
|
notes, ssh.user, ssh.auth (key|password), ssh.bundle, ssh.bundle-key,
|
|
1357
1469
|
ssh.identity-file, platform (windows|linux|macos|unknown),
|
|
1358
1470
|
auto-launch.enabled, auto-launch.preferred — plus the user-scope
|
|
1359
1471
|
interactive.host (stored centrally; the device name is syntax only).
|
|
1360
1472
|
|
|
1473
|
+
Three layers, read in order — built-in default < fleet default
|
|
1474
|
+
(--fleet, central fleet.defaults.config) < per-device value
|
|
1475
|
+
(devices/<name>/agents.yaml config:). Both files are tracked and sync
|
|
1476
|
+
with 'agents repo push/pull'; per-device files are conflict-free because
|
|
1477
|
+
each machine writes only its own folder. --unset removes the value at
|
|
1478
|
+
the targeted layer, so a device key falls back to the fleet default.
|
|
1479
|
+
|
|
1361
1480
|
Booleans take on/off (or true/false). 'notes' appends one entry per
|
|
1362
|
-
invocation.
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
tmux.enabled, browser.remote-control,
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
reloads or restarts on that device.
|
|
1481
|
+
invocation. ssh.* / platform / user overlay the discovered registry
|
|
1482
|
+
profile at dial time. scheduler.enabled / daemon.enabled take effect
|
|
1483
|
+
when the daemon reloads or restarts on that device. Machine-local keys
|
|
1484
|
+
(scheduler.enabled, daemon.enabled, tmux.enabled, browser.remote-control,
|
|
1485
|
+
browser.task-idle-minutes, browser.profile) can only be read or set on
|
|
1486
|
+
the device itself; --fleet still writes a fleet-wide default those boxes
|
|
1487
|
+
inherit until they override.
|
|
1370
1488
|
|
|
1371
1489
|
The retired subcommands still work and forward here: configure, note,
|
|
1372
1490
|
set, set-interactive, enable, disable, prefer, unprefer.
|
|
@@ -1397,9 +1515,10 @@ function registerDevicesCommands(program) {
|
|
|
1397
1515
|
agents devices role --json # machine-readable
|
|
1398
1516
|
`,
|
|
1399
1517
|
notes: `
|
|
1400
|
-
Roles
|
|
1401
|
-
|
|
1402
|
-
so a mark set on one box is the whole fleet's
|
|
1518
|
+
Roles live in that device's tracked per-device doc
|
|
1519
|
+
(devices/<name>/agents.yaml config.role) and travel with
|
|
1520
|
+
'agents repo push/pull', so a mark set on one box is the whole fleet's
|
|
1521
|
+
answer.
|
|
1403
1522
|
|
|
1404
1523
|
Effect on '--device auto' (agents run, teams, agents ssh auto, and the AGI
|
|
1405
1524
|
EXT launch commands, which all resolve placement through the CLI):
|
|
@@ -1634,7 +1753,7 @@ function registerDevicesCommands(program) {
|
|
|
1634
1753
|
await writeReachability(collectReachabilityWriteBacks(reg, statsMap)).catch(() => { });
|
|
1635
1754
|
}
|
|
1636
1755
|
if (opts.json) {
|
|
1637
|
-
const jsonRoles = listConfiguredDeviceRoles();
|
|
1756
|
+
const jsonRoles = listConfiguredDeviceRoles(names);
|
|
1638
1757
|
const autoPool = new Set(filterAutoPool(names, { roles: jsonRoles }));
|
|
1639
1758
|
process.stdout.write(JSON.stringify(names.map((name) => {
|
|
1640
1759
|
const config = deviceConfigJson(name);
|
|
@@ -1817,6 +1936,7 @@ email) into a single row. Use \`agents devices harnesses\` for the per-install v
|
|
|
1817
1936
|
user,
|
|
1818
1937
|
address: { via: 'manual', dnsName: isIp ? undefined : host, ip: isIp ? host : undefined },
|
|
1819
1938
|
});
|
|
1939
|
+
setDeviceDiscoveryStatus(name, 'approved');
|
|
1820
1940
|
console.log(chalk.green(`Added device '${name}'`) + chalk.gray(` (${d.platform}, ${user ? user + '@' : ''}${host})`));
|
|
1821
1941
|
}
|
|
1822
1942
|
catch (err) {
|
|
@@ -1888,6 +2008,7 @@ email) into a single row. Use \`agents devices harnesses\` for the per-install v
|
|
|
1888
2008
|
const existing = await getDevice(name);
|
|
1889
2009
|
if (existing) {
|
|
1890
2010
|
await upsertDevice(name, { role: 'control' });
|
|
2011
|
+
setDeviceDiscoveryStatus(name, 'approved');
|
|
1891
2012
|
marked = true;
|
|
1892
2013
|
}
|
|
1893
2014
|
else {
|
|
@@ -1922,6 +2043,7 @@ email) into a single row. Use \`agents devices harnesses\` for the per-install v
|
|
|
1922
2043
|
console.error(chalk.red(`Unknown device '${name}'.`));
|
|
1923
2044
|
process.exit(1);
|
|
1924
2045
|
}
|
|
2046
|
+
setDeviceDiscoveryStatus(name, undefined);
|
|
1925
2047
|
console.log(chalk.green(`Removed device '${name}'`));
|
|
1926
2048
|
});
|
|
1927
2049
|
devicesCmd
|
|
@@ -2097,7 +2219,7 @@ is refused with a clear message instead of self-dialing.
|
|
|
2097
2219
|
An interactive login with no command mirrors the home-relative directory you
|
|
2098
2220
|
launched from — 'agents ssh yosemite-s0' from ~/src/app lands in ~/src/app on
|
|
2099
2221
|
the target when it exists, else the remote home. Same portable-cwd rule as
|
|
2100
|
-
'agents run --
|
|
2222
|
+
'agents run --device'. Passing a command keeps the remote home.
|
|
2101
2223
|
`)
|
|
2102
2224
|
.action(async (name, cmd) => {
|
|
2103
2225
|
// Hidden askpass bridge: ssh execs the shim, which re-invokes us here.
|
|
@@ -2160,7 +2282,7 @@ the target when it exists, else the remote home. Same portable-cwd rule as
|
|
|
2160
2282
|
const pinned = addr ? isHostPinned(addr) : false;
|
|
2161
2283
|
// Interactive login (no cmd): mirror the caller's project directory on
|
|
2162
2284
|
// the target when the same home-relative checkout exists there, matching
|
|
2163
|
-
// `agents run --
|
|
2285
|
+
// `agents run --device` (deriveMirroredCwd). Best-effort — a missing dir
|
|
2164
2286
|
// falls back to the remote home. An explicit `cmd` keeps its cwd (RUSH-2412).
|
|
2165
2287
|
const mirrorCwd = cmd.length === 0 ? deriveMirroredCwd(process.cwd()) : undefined;
|
|
2166
2288
|
const { args, env } = buildSshInvocation(device, cmd, shim, { pinned }, { interactiveCwd: mirrorCwd });
|