@phnx-labs/agents-cli 1.22.35 → 1.22.38
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 +708 -2
- package/README.md +83 -43
- package/dist/bin/agents +0 -0
- package/dist/bootstrap.d.ts +15 -0
- package/dist/bootstrap.js +1212 -0
- package/dist/commands/accounts.d.ts +4 -11
- package/dist/commands/accounts.js +159 -27
- package/dist/commands/artifacts-setup.d.ts +53 -0
- package/dist/commands/artifacts-setup.js +161 -0
- package/dist/commands/artifacts.d.ts +18 -0
- package/dist/commands/artifacts.js +58 -0
- package/dist/commands/attach.js +17 -4
- package/dist/commands/audit.d.ts +8 -8
- package/dist/commands/audit.js +57 -47
- package/dist/commands/browser.js +17 -11
- package/dist/commands/cloud.js +1 -1
- package/dist/commands/commands.js +0 -11
- package/dist/commands/computer-actions.js +33 -0
- package/dist/commands/computer-sessions-picker.d.ts +21 -0
- package/dist/commands/computer-sessions-picker.js +141 -0
- package/dist/commands/computer.d.ts +16 -0
- package/dist/commands/computer.js +37 -0
- package/dist/commands/config.d.ts +17 -0
- package/dist/commands/config.js +401 -0
- package/dist/commands/cp.d.ts +84 -0
- package/dist/commands/cp.js +231 -0
- package/dist/commands/daemon.js +243 -14
- package/dist/commands/detach-core.d.ts +1 -1
- package/dist/commands/detach-core.js +12 -2
- package/dist/commands/detach.js +1 -1
- package/dist/commands/doctor.js +64 -5
- package/dist/commands/events.d.ts +24 -12
- package/dist/commands/events.js +144 -28
- package/dist/commands/exec.js +86 -42
- package/dist/commands/feed.d.ts +1 -1
- package/dist/commands/feed.js +16 -8
- package/dist/commands/focus.d.ts +33 -1
- package/dist/commands/focus.js +177 -17
- package/dist/commands/funnel.d.ts +1 -1
- package/dist/commands/go.js +9 -8
- package/dist/commands/harness-wizard.d.ts +1 -0
- package/dist/commands/harness-wizard.js +18 -20
- package/dist/commands/harness.d.ts +2 -0
- package/dist/commands/harness.js +59 -26
- package/dist/commands/hooks.js +0 -11
- package/dist/commands/inspect.d.ts +94 -1
- package/dist/commands/inspect.js +866 -40
- package/dist/commands/lease.d.ts +4 -4
- package/dist/commands/lease.js +6 -6
- package/dist/commands/login.js +0 -13
- package/dist/commands/logs.d.ts +2 -2
- package/dist/commands/logs.js +2 -2
- package/dist/commands/mcp.js +7 -2
- package/dist/commands/memory.js +7 -2
- package/dist/commands/message.d.ts +1 -1
- package/dist/commands/message.js +37 -6
- package/dist/commands/models.js +71 -0
- package/dist/commands/monitors.d.ts +0 -1
- package/dist/commands/monitors.js +199 -16
- package/dist/commands/open.d.ts +18 -0
- package/dist/commands/open.js +57 -0
- package/dist/commands/packages.js +2 -107
- package/dist/commands/plugins.js +6 -3
- package/dist/commands/profiles.d.ts +1 -0
- package/dist/commands/profiles.js +16 -160
- package/dist/commands/projects.d.ts +28 -0
- package/dist/commands/projects.js +125 -5
- package/dist/commands/reconnect.js +9 -3
- package/dist/commands/repo.js +42 -1
- package/dist/commands/resource-view.d.ts +17 -0
- package/dist/commands/resource-view.js +36 -14
- package/dist/commands/resume.js +9 -2
- package/dist/commands/routines.d.ts +0 -2
- package/dist/commands/routines.js +473 -289
- package/dist/commands/secrets.js +52 -9
- package/dist/commands/sessions-export.d.ts +47 -0
- package/dist/commands/sessions-export.js +116 -6
- package/dist/commands/sessions-import.d.ts +17 -0
- package/dist/commands/sessions-import.js +114 -6
- package/dist/commands/sessions-migrate.d.ts +27 -0
- package/dist/commands/sessions-migrate.js +50 -9
- package/dist/commands/sessions-picker.js +23 -4
- package/dist/commands/sessions-resume.d.ts +5 -3
- package/dist/commands/sessions-resume.js +30 -8
- package/dist/commands/sessions-watch.d.ts +2 -0
- package/dist/commands/sessions-watch.js +53 -0
- package/dist/commands/sessions.d.ts +66 -3
- package/dist/commands/sessions.js +298 -47
- package/dist/commands/setup-browser.js +2 -2
- package/dist/commands/setup-mine.js +0 -1
- package/dist/commands/setup-preferences.js +1 -1
- package/dist/commands/setup.d.ts +5 -0
- package/dist/commands/setup.js +31 -5
- package/dist/commands/share.d.ts +87 -7
- package/dist/commands/share.js +320 -58
- package/dist/commands/skills.js +0 -11
- package/dist/commands/snapshot.js +1 -1
- package/dist/commands/ssh.d.ts +18 -0
- package/dist/commands/ssh.js +549 -210
- package/dist/commands/sync.d.ts +5 -0
- package/dist/commands/sync.js +212 -32
- package/dist/commands/teams.d.ts +13 -0
- package/dist/commands/teams.js +187 -30
- package/dist/commands/tickets.d.ts +2 -0
- package/dist/commands/tickets.js +43 -0
- package/dist/commands/update.js +2 -4
- package/dist/commands/usage.js +5 -3
- package/dist/commands/versions.js +11 -5
- package/dist/commands/view.js +15 -7
- package/dist/commands/webhook.d.ts +2 -2
- package/dist/commands/webhook.js +7 -7
- package/dist/index.d.ts +18 -2
- package/dist/index.js +53 -1264
- package/dist/lib/account-catalog.d.ts +18 -0
- package/dist/lib/account-catalog.js +38 -0
- package/dist/lib/account-provider-registry.d.ts +18 -0
- package/dist/lib/account-provider-registry.js +59 -0
- package/dist/lib/account-registry.d.ts +40 -0
- package/dist/lib/account-registry.js +239 -0
- package/dist/lib/account-schema.d.ts +44 -0
- package/dist/lib/account-schema.js +91 -0
- package/dist/lib/account-state-service.d.ts +21 -0
- package/dist/lib/account-state-service.js +60 -0
- package/dist/lib/activity.d.ts +1 -1
- package/dist/lib/activity.js +8 -1
- package/dist/lib/add-dir.d.ts +80 -0
- package/dist/lib/add-dir.js +241 -0
- package/dist/lib/agent-cli-commands.d.ts +11 -0
- package/dist/lib/agent-cli-commands.js +30 -0
- package/dist/lib/agents.js +44 -36
- package/dist/lib/answer-router.js +1 -1
- package/dist/lib/audit/log.d.ts +10 -27
- package/dist/lib/audit/log.js +20 -33
- package/dist/lib/auth-health.d.ts +9 -2
- package/dist/lib/auth-health.js +42 -9
- package/dist/lib/auto-pull-worker.js +7 -3
- package/dist/lib/auto-pull.d.ts +44 -3
- package/dist/lib/auto-pull.js +88 -5
- package/dist/lib/binary-shadow.d.ts +28 -0
- package/dist/lib/binary-shadow.js +121 -0
- package/dist/lib/brand.js +9 -3
- package/dist/lib/browser/hygiene.d.ts +90 -0
- package/dist/lib/browser/hygiene.js +146 -0
- package/dist/lib/browser/ipc.d.ts +30 -0
- package/dist/lib/browser/ipc.js +93 -4
- package/dist/lib/browser/profiles.d.ts +3 -2
- package/dist/lib/browser/profiles.js +65 -22
- package/dist/lib/browser/service.d.ts +79 -1
- package/dist/lib/browser/service.js +231 -14
- package/dist/lib/browser/sessions-list.d.ts +22 -2
- package/dist/lib/browser/sessions-list.js +54 -6
- package/dist/lib/browser/stream.d.ts +2 -0
- package/dist/lib/browser/stream.js +1 -0
- package/dist/lib/browser/types.d.ts +63 -1
- package/dist/lib/byok-usage.d.ts +9 -2
- package/dist/lib/byok-usage.js +133 -31
- package/dist/lib/cli-entry.d.ts +11 -0
- package/dist/lib/cli-entry.js +46 -0
- package/dist/lib/cloud/host.d.ts +1 -1
- package/dist/lib/cloud/host.js +2 -2
- package/dist/lib/cloud/registry.js +1 -1
- package/dist/lib/cloud/types.d.ts +1 -1
- package/dist/lib/commands.d.ts +2 -0
- package/dist/lib/commands.js +2 -0
- package/dist/lib/computer/sessions-list.d.ts +150 -0
- package/dist/lib/computer/sessions-list.js +363 -0
- package/dist/lib/config-keys.d.ts +86 -0
- package/dist/lib/config-keys.js +193 -0
- package/dist/lib/config-machine-keys.d.ts +12 -0
- package/dist/lib/config-machine-keys.js +17 -0
- package/dist/lib/config-transfer.js +3 -4
- package/dist/lib/crabbox/cli.d.ts +2 -2
- package/dist/lib/crabbox/cli.js +3 -3
- package/dist/lib/daemon-health.d.ts +22 -0
- package/dist/lib/daemon-health.js +33 -3
- package/dist/lib/daemon-services.d.ts +50 -0
- package/dist/lib/daemon-services.js +147 -0
- package/dist/lib/daemon-ticks.d.ts +35 -66
- package/dist/lib/daemon-ticks.js +77 -159
- package/dist/lib/daemon.d.ts +72 -4
- package/dist/lib/daemon.js +792 -202
- package/dist/lib/deeplink/register.d.ts +49 -0
- package/dist/lib/deeplink/register.js +253 -0
- package/dist/lib/deeplink/url.d.ts +34 -0
- package/dist/lib/deeplink/url.js +78 -0
- package/dist/lib/device-config.d.ts +124 -29
- package/dist/lib/device-config.js +346 -141
- package/dist/lib/devices/config-migration.d.ts +42 -0
- package/dist/lib/devices/config-migration.js +203 -0
- package/dist/lib/devices/connect.js +14 -7
- package/dist/lib/devices/doctor-findings.d.ts +4 -1
- package/dist/lib/devices/doctor-findings.js +20 -1
- package/dist/lib/devices/harness-inventory.d.ts +11 -2
- package/dist/lib/devices/harness-inventory.js +0 -0
- package/dist/lib/devices/health.d.ts +1 -1
- package/dist/lib/devices/health.js +1 -1
- package/dist/lib/devices/pending.d.ts +22 -1
- package/dist/lib/devices/pending.js +67 -2
- package/dist/lib/devices/registry.d.ts +0 -25
- package/dist/lib/devices/registry.js +2 -83
- package/dist/lib/devices/resolve-profile.d.ts +20 -0
- package/dist/lib/devices/resolve-profile.js +44 -0
- package/dist/lib/devices/rollout-verify.d.ts +101 -0
- package/dist/lib/devices/rollout-verify.js +193 -0
- package/dist/lib/devices/ssh-config.js +10 -6
- package/dist/lib/event-families.d.ts +28 -0
- package/dist/lib/event-families.js +159 -0
- package/dist/lib/event-stream.d.ts +9 -1
- package/dist/lib/event-stream.js +26 -9
- package/dist/lib/events.d.ts +9 -1
- package/dist/lib/events.js +21 -6
- package/dist/lib/exec.d.ts +30 -0
- package/dist/lib/exec.js +219 -121
- package/dist/lib/feed-broadcast.d.ts +25 -0
- package/dist/lib/feed-broadcast.js +33 -0
- package/dist/lib/feed.d.ts +1 -1
- package/dist/lib/feed.js +12 -2
- package/dist/lib/fleet/capture.js +15 -0
- package/dist/lib/fleet/manifest.js +9 -0
- package/dist/lib/fleet/types.d.ts +9 -0
- package/dist/lib/fleet-status.js +10 -8
- package/dist/lib/git.d.ts +21 -7
- package/dist/lib/git.js +122 -18
- package/dist/lib/hosts/dispatch.d.ts +8 -3
- package/dist/lib/hosts/dispatch.js +29 -3
- package/dist/lib/hosts/logs.d.ts +2 -2
- package/dist/lib/hosts/logs.js +2 -2
- package/dist/lib/hosts/option.js +1 -1
- package/dist/lib/hosts/passthrough.d.ts +2 -3
- package/dist/lib/hosts/passthrough.js +10 -24
- package/dist/lib/hosts/progress.js +2 -2
- package/dist/lib/hosts/providers/devices.d.ts +3 -3
- package/dist/lib/hosts/providers/devices.js +18 -12
- package/dist/lib/hosts/ready.d.ts +5 -1
- package/dist/lib/hosts/ready.js +9 -3
- package/dist/lib/hosts/reconcile.d.ts +2 -2
- package/dist/lib/hosts/reconcile.js +2 -2
- package/dist/lib/hosts/registry.js +14 -9
- package/dist/lib/hosts/remote-cmd.js +1 -1
- package/dist/lib/hosts/remote-os.d.ts +9 -6
- package/dist/lib/hosts/remote-os.js +13 -6
- package/dist/lib/hosts/routing-flag.d.ts +23 -0
- package/dist/lib/hosts/routing-flag.js +41 -0
- package/dist/lib/hosts/run-target.js +1 -1
- package/dist/lib/hosts/session-index.js +1 -1
- package/dist/lib/hosts/tasks.d.ts +6 -6
- package/dist/lib/hosts/tasks.js +4 -4
- package/dist/lib/hosts/types.js +1 -2
- package/dist/lib/installations/resolve.js +2 -8
- package/dist/lib/isolation-boundary-report.js +0 -1
- package/dist/lib/linear-cache.d.ts +7 -0
- package/dist/lib/linear-cache.js +31 -4
- package/dist/lib/linear-project-counts.d.ts +1 -1
- package/dist/lib/linear-project-counts.js +2 -3
- package/dist/lib/linear-projects.js +1 -1
- package/dist/lib/loop.d.ts +2 -2
- package/dist/lib/loop.js +1 -1
- package/dist/lib/mailbox-target.d.ts +1 -1
- package/dist/lib/mailbox-target.js +1 -1
- package/dist/lib/manifest.js +7 -4
- package/dist/lib/menubar/MenubarHelper.app/Contents/CodeResources +0 -0
- package/dist/lib/menubar/MenubarHelper.app/Contents/MacOS/MenubarHelper +0 -0
- package/dist/lib/menubar/snapshot.d.ts +3 -2
- package/dist/lib/menubar/snapshot.js +6 -2
- package/dist/lib/migrate-fold.d.ts +33 -0
- package/dist/lib/migrate-fold.js +130 -0
- package/dist/lib/migrate.d.ts +34 -34
- package/dist/lib/migrate.js +106 -128
- package/dist/lib/model-tier-overrides.d.ts +1 -1
- package/dist/lib/model-tier-overrides.js +15 -2
- package/dist/lib/monitors/config.d.ts +17 -3
- package/dist/lib/monitors/config.js +52 -18
- package/dist/lib/monitors/engine.d.ts +32 -1
- package/dist/lib/monitors/engine.js +94 -11
- package/dist/lib/monitors/fingerprint.d.ts +46 -0
- package/dist/lib/monitors/fingerprint.js +100 -0
- package/dist/lib/monitors/remote.d.ts +47 -0
- package/dist/lib/monitors/remote.js +81 -0
- package/dist/lib/monitors/state.d.ts +39 -0
- package/dist/lib/monitors/state.js +56 -0
- package/dist/lib/onepassword.d.ts +17 -0
- package/dist/lib/onepassword.js +52 -22
- package/dist/lib/open-url.js +1 -1
- package/dist/lib/picker.d.ts +14 -2
- package/dist/lib/picker.js +35 -13
- package/dist/lib/placement.d.ts +1 -1
- package/dist/lib/placement.js +1 -1
- package/dist/lib/pr-land-detach.d.ts +32 -0
- package/dist/lib/pr-land-detach.js +79 -0
- package/dist/lib/profiles-presets.js +13 -0
- package/dist/lib/profiles.d.ts +2 -0
- package/dist/lib/profiles.js +44 -1
- package/dist/lib/project-focus.d.ts +1 -1
- package/dist/lib/project-focus.js +1 -1
- package/dist/lib/project-probe.d.ts +4 -1
- package/dist/lib/project-probe.js +5 -4
- package/dist/lib/project-resources.js +2 -18
- package/dist/lib/project-root.d.ts +16 -0
- package/dist/lib/project-root.js +20 -2
- package/dist/lib/projects.d.ts +20 -1
- package/dist/lib/projects.js +78 -1
- package/dist/lib/refresh-coordinator.d.ts +24 -0
- package/dist/lib/refresh-coordinator.js +52 -0
- package/dist/lib/registry.d.ts +2 -2
- package/dist/lib/registry.js +1 -1
- package/dist/lib/resource-aliases.d.ts +13 -0
- package/dist/lib/resource-aliases.js +26 -0
- package/dist/lib/resources/types.d.ts +1 -1
- package/dist/lib/resources.d.ts +16 -0
- package/dist/lib/resources.js +66 -10
- package/dist/lib/rotate.d.ts +3 -4
- package/dist/lib/rotate.js +4 -5
- package/dist/lib/routine-activation.d.ts +22 -2
- package/dist/lib/routine-activation.js +63 -16
- package/dist/lib/routine-context.d.ts +9 -2
- package/dist/lib/routine-context.js +21 -6
- package/dist/lib/routines-project.d.ts +58 -48
- package/dist/lib/routines-project.js +190 -159
- package/dist/lib/routines.d.ts +44 -7
- package/dist/lib/routines.js +92 -34
- package/dist/lib/run-defaults.d.ts +5 -0
- package/dist/lib/run-defaults.js +11 -1
- package/dist/lib/runner.d.ts +10 -8
- package/dist/lib/runner.js +122 -39
- package/dist/lib/secrets/Agents CLI.app/Contents/CodeResources +0 -0
- package/dist/lib/secrets/Agents CLI.app/Contents/MacOS/Agents CLI +0 -0
- package/dist/lib/secrets/agent.d.ts +10 -3
- package/dist/lib/secrets/agent.js +43 -8
- package/dist/lib/secrets/bundles.d.ts +1 -0
- package/dist/lib/secrets/bundles.js +92 -80
- package/dist/lib/secrets/index.js +32 -9
- package/dist/lib/secrets/install-helper.d.ts +4 -4
- package/dist/lib/secrets/install-helper.js +4 -4
- package/dist/lib/secrets/push.d.ts +40 -6
- package/dist/lib/secrets/push.js +58 -11
- package/dist/lib/secrets/read-backoff.d.ts +1 -1
- package/dist/lib/secrets/read-backoff.js +1 -1
- package/dist/lib/secrets/remote.d.ts +24 -0
- package/dist/lib/secrets/remote.js +54 -4
- package/dist/lib/self-update.d.ts +108 -0
- package/dist/lib/self-update.js +276 -1
- package/dist/lib/session/active.d.ts +89 -5
- package/dist/lib/session/active.js +165 -10
- package/dist/lib/session/actor-sidecar.d.ts +1 -1
- package/dist/lib/session/actor-sidecar.js +2 -1
- package/dist/lib/session/db.d.ts +176 -2
- package/dist/lib/session/db.js +484 -17
- package/dist/lib/session/discover.js +27 -4
- package/dist/lib/session/hook-sessions.js +2 -2
- package/dist/lib/session/host-link.d.ts +2 -2
- package/dist/lib/session/host-link.js +2 -2
- package/dist/lib/session/pid-registry.d.ts +21 -0
- package/dist/lib/session/pid-registry.js +57 -0
- package/dist/lib/session/remote-active.js +15 -1
- package/dist/lib/session/remote.js +2 -2
- package/dist/lib/session/session-cache.d.ts +14 -7
- package/dist/lib/session/session-cache.js +51 -9
- package/dist/lib/session/state.d.ts +2 -2
- package/dist/lib/session/state.js +1 -1
- package/dist/lib/session/sync/config.d.ts +10 -10
- package/dist/lib/session/sync/config.js +10 -10
- package/dist/lib/session/sync/r2.d.ts +34 -0
- package/dist/lib/session/sync/r2.js +123 -0
- package/dist/lib/session/throughput.d.ts +1 -1
- package/dist/lib/session/throughput.js +1 -1
- package/dist/lib/session/types.d.ts +23 -1
- package/dist/lib/session/types.js +15 -0
- package/dist/lib/session/viewing-in.d.ts +1 -1
- package/dist/lib/session/viewing-in.js +1 -1
- package/dist/lib/session/watch.d.ts +101 -0
- package/dist/lib/session/watch.js +242 -0
- package/dist/lib/share/analytics.js +1 -1
- package/dist/lib/share/capture.d.ts +1 -1
- package/dist/lib/share/capture.js +3 -3
- package/dist/lib/share/config.d.ts +6 -2
- package/dist/lib/share/config.js +6 -5
- package/dist/lib/share/delete.js +3 -3
- package/dist/lib/share/provision.d.ts +38 -0
- package/dist/lib/share/provision.js +51 -1
- package/dist/lib/share/publish.d.ts +40 -1
- package/dist/lib/share/publish.js +119 -6
- package/dist/lib/share/worker-template.d.ts +12 -1
- package/dist/lib/share/worker-template.js +83 -7
- package/dist/lib/shims.d.ts +17 -3
- package/dist/lib/shims.js +98 -26
- package/dist/lib/signin-badge.js +3 -2
- package/dist/lib/skills.js +2 -0
- package/dist/lib/smart-launch.d.ts +8 -8
- package/dist/lib/smart-launch.js +80 -59
- package/dist/lib/ssh-exec.d.ts +1 -1
- package/dist/lib/ssh-exec.js +1 -1
- package/dist/lib/staleness/prune.d.ts +88 -0
- package/dist/lib/staleness/prune.js +69 -0
- package/dist/lib/staleness/registry.d.ts +1 -1
- package/dist/lib/staleness/writers/commands.js +34 -2
- package/dist/lib/staleness/writers/hooks.js +16 -0
- package/dist/lib/staleness/writers/kinds.d.ts +6 -0
- package/dist/lib/staleness/writers/skills.js +19 -0
- package/dist/lib/staleness/writers/subagents.d.ts +2 -3
- package/dist/lib/staleness/writers/subagents.js +0 -4
- package/dist/lib/staleness/writers/types.d.ts +32 -0
- package/dist/lib/startup/command-registry.d.ts +16 -14
- package/dist/lib/startup/command-registry.js +26 -37
- package/dist/lib/startup/dev-build.d.ts +10 -0
- package/dist/lib/startup/dev-build.js +13 -1
- package/dist/lib/startup/spellcheck.d.ts +18 -0
- package/dist/lib/startup/spellcheck.js +45 -0
- package/dist/lib/state.d.ts +36 -9
- package/dist/lib/state.js +96 -46
- package/dist/lib/subagents-registry.d.ts +0 -7
- package/dist/lib/subagents-registry.js +38 -65
- package/dist/lib/subagents.d.ts +0 -33
- package/dist/lib/subagents.js +0 -75
- package/dist/lib/sync-umbrella.js +1 -1
- package/dist/lib/teams/agents.d.ts +41 -1
- package/dist/lib/teams/agents.js +187 -9
- package/dist/lib/teams/api.d.ts +11 -1
- package/dist/lib/teams/api.js +11 -2
- package/dist/lib/teams/delivery.d.ts +41 -0
- package/dist/lib/teams/delivery.js +60 -0
- package/dist/lib/teams/registry.d.ts +14 -0
- package/dist/lib/teams/registry.js +51 -1
- package/dist/lib/teams/remoteWorktree.d.ts +19 -0
- package/dist/lib/teams/remoteWorktree.js +29 -0
- package/dist/lib/teams/scheduler.d.ts +1 -1
- package/dist/lib/teams/scheduler.js +1 -1
- package/dist/lib/teams/worktree.d.ts +24 -0
- package/dist/lib/teams/worktree.js +42 -0
- package/dist/lib/terminal/backends/vscodium-agent.d.ts +10 -1
- package/dist/lib/terminal/backends/vscodium-agent.js +16 -5
- package/dist/lib/terminal/engine.d.ts +4 -0
- package/dist/lib/terminal/engine.js +8 -2
- package/dist/lib/terminal/types.d.ts +21 -2
- package/dist/lib/testdata/refresh-coordinator-worker.d.ts +1 -0
- package/dist/lib/testdata/refresh-coordinator-worker.js +23 -0
- package/dist/lib/tickets/list.d.ts +53 -0
- package/dist/lib/tickets/list.js +153 -0
- package/dist/lib/tmux/orphan-reap.d.ts +316 -0
- package/dist/lib/tmux/orphan-reap.js +638 -0
- package/dist/lib/tmux/session.d.ts +68 -3
- package/dist/lib/tmux/session.js +96 -5
- package/dist/lib/triggers/handlers.d.ts +20 -0
- package/dist/lib/triggers/handlers.js +16 -1
- package/dist/lib/triggers/webhook.js +10 -0
- package/dist/lib/types.d.ts +47 -35
- package/dist/lib/usage-fleet.d.ts +32 -0
- package/dist/lib/usage-fleet.js +125 -0
- package/dist/lib/usage-refresh.d.ts +3 -3
- package/dist/lib/usage-refresh.js +19 -16
- package/dist/lib/usage.d.ts +51 -47
- package/dist/lib/usage.js +145 -153
- package/dist/lib/version-duplicates.js +2 -2
- package/dist/lib/versions.d.ts +56 -13
- package/dist/lib/versions.js +195 -45
- package/dist/lib/watchdog/log.d.ts +1 -1
- package/dist/lib/watchdog/log.js +3 -3
- package/dist/lib/watchdog/rotate.d.ts +6 -6
- package/dist/lib/watchdog/rotate.js +6 -6
- package/dist/lib/workflows.d.ts +1 -1
- package/dist/lib/yaml-io.d.ts +47 -0
- package/dist/lib/yaml-io.js +55 -0
- package/package.json +2 -1
- package/scripts/install-helper.js +2 -2
- package/scripts/postinstall.js +23 -20
- package/dist/commands/defaults.d.ts +0 -7
- package/dist/commands/defaults.js +0 -107
- package/dist/commands/export.d.ts +0 -11
- package/dist/commands/export.js +0 -215
- package/dist/commands/helper.d.ts +0 -12
- package/dist/commands/helper.js +0 -87
- package/dist/commands/hosts.d.ts +0 -11
- package/dist/commands/hosts.js +0 -330
- package/dist/commands/lock.d.ts +0 -12
- package/dist/commands/lock.js +0 -70
- package/dist/commands/pull.d.ts +0 -17
- package/dist/commands/pull.js +0 -39
- package/dist/commands/push.d.ts +0 -14
- package/dist/commands/push.js +0 -30
- package/dist/commands/set.d.ts +0 -15
- package/dist/commands/set.js +0 -79
- package/dist/commands/setup-share.d.ts +0 -17
- package/dist/commands/setup-share.js +0 -85
- package/dist/commands/wallet.d.ts +0 -20
- package/dist/commands/wallet.js +0 -216
- package/dist/commands/worktree.d.ts +0 -19
- package/dist/commands/worktree.js +0 -272
- package/dist/lib/account-labels.d.ts +0 -24
- package/dist/lib/account-labels.js +0 -72
- package/dist/lib/auto-dispatch-linear.d.ts +0 -18
- package/dist/lib/auto-dispatch-linear.js +0 -107
- package/dist/lib/auto-dispatch-provider.d.ts +0 -10
- package/dist/lib/auto-dispatch-provider.js +0 -30
- package/dist/lib/auto-dispatch.d.ts +0 -93
- package/dist/lib/auto-dispatch.js +0 -128
- package/dist/lib/export.d.ts +0 -72
- package/dist/lib/export.js +0 -269
- package/dist/lib/lock.d.ts +0 -93
- package/dist/lib/lock.js +0 -207
- package/dist/lib/wallet/index.d.ts +0 -78
- package/dist/lib/wallet/index.js +0 -253
|
@@ -18,7 +18,7 @@ import * as fsSync from 'fs';
|
|
|
18
18
|
import * as path from 'path';
|
|
19
19
|
import { randomBytes } from 'crypto';
|
|
20
20
|
import lockfile from 'proper-lockfile';
|
|
21
|
-
import { getDevicesRegistryPath, getDevicesIgnoredPath
|
|
21
|
+
import { getDevicesRegistryPath, getDevicesIgnoredPath } from '../state.js';
|
|
22
22
|
/** A device's effective role, defaulting to `worker` when unset. */
|
|
23
23
|
export function deviceRole(d) {
|
|
24
24
|
return d.role ?? 'worker';
|
|
@@ -56,7 +56,7 @@ export function isDialableDevice(d) {
|
|
|
56
56
|
// every session on that box unresolvable from any other machine.
|
|
57
57
|
//
|
|
58
58
|
// So: no tailscale block at all is unknown-not-offline (the rule `ssh.ts`
|
|
59
|
-
// renderDeviceTable and
|
|
59
|
+
// renderDeviceTable and the ext's `isDeviceOnline` already use, so the picker
|
|
60
60
|
// and the sweep agree on who exists), and a positive probe rescues a device
|
|
61
61
|
// whose snapshot says offline. The cost of dialing a box that is actually
|
|
62
62
|
// asleep is one ConnectTimeout — the pre-existing behaviour, not a regression.
|
|
@@ -325,84 +325,3 @@ export async function removeIgnored(name) {
|
|
|
325
325
|
return true;
|
|
326
326
|
});
|
|
327
327
|
}
|
|
328
|
-
function autoLaunchPath() {
|
|
329
|
-
return getDevicesAutoLaunchPath();
|
|
330
|
-
}
|
|
331
|
-
/** Load auto-launch preferences. Missing or malformed file => empty map. */
|
|
332
|
-
export async function loadAutoLaunchPreferences() {
|
|
333
|
-
const p = autoLaunchPath();
|
|
334
|
-
let raw;
|
|
335
|
-
try {
|
|
336
|
-
raw = await fs.readFile(p, 'utf-8');
|
|
337
|
-
}
|
|
338
|
-
catch (err) {
|
|
339
|
-
if (err && err.code === 'ENOENT')
|
|
340
|
-
return {};
|
|
341
|
-
throw err;
|
|
342
|
-
}
|
|
343
|
-
try {
|
|
344
|
-
const parsed = JSON.parse(raw);
|
|
345
|
-
return parsed.devices && typeof parsed.devices === 'object' ? parsed.devices : {};
|
|
346
|
-
}
|
|
347
|
-
catch (err) {
|
|
348
|
-
throw new Error(`Device auto-launch preferences corrupted at ${p}: ${err?.message ?? err}. Inspect and restore from backup.`);
|
|
349
|
-
}
|
|
350
|
-
}
|
|
351
|
-
/** True if the device is enabled for auto-launch. Missing entry defaults to true. */
|
|
352
|
-
export async function isAutoLaunchEnabled(name) {
|
|
353
|
-
assertValidDeviceName(name);
|
|
354
|
-
const prefs = await loadAutoLaunchPreferences();
|
|
355
|
-
return prefs[name]?.enabled !== false;
|
|
356
|
-
}
|
|
357
|
-
/** Set whether a device is enabled for auto-launch. Setting to the default
|
|
358
|
-
* (enabled) removes the entry to keep the file minimal. */
|
|
359
|
-
export async function setAutoLaunchEnabled(name, enabled) {
|
|
360
|
-
assertValidDeviceName(name);
|
|
361
|
-
const p = autoLaunchPath();
|
|
362
|
-
await withRegistryLock(p, async () => {
|
|
363
|
-
const prefs = await loadAutoLaunchPreferences();
|
|
364
|
-
if (enabled) {
|
|
365
|
-
if (prefs[name]) {
|
|
366
|
-
const { enabled: _, ...rest } = prefs[name];
|
|
367
|
-
if (Object.keys(rest).length === 0) {
|
|
368
|
-
delete prefs[name];
|
|
369
|
-
}
|
|
370
|
-
else {
|
|
371
|
-
prefs[name] = rest;
|
|
372
|
-
}
|
|
373
|
-
}
|
|
374
|
-
}
|
|
375
|
-
else {
|
|
376
|
-
prefs[name] = { ...prefs[name], enabled: false };
|
|
377
|
-
}
|
|
378
|
-
await atomicWriteJson(p, { devices: prefs, updatedAt: new Date().toISOString() });
|
|
379
|
-
});
|
|
380
|
-
}
|
|
381
|
-
/** True if the device is preferred for auto-launch ranking. */
|
|
382
|
-
export async function isAutoLaunchPreferred(name) {
|
|
383
|
-
assertValidDeviceName(name);
|
|
384
|
-
const prefs = await loadAutoLaunchPreferences();
|
|
385
|
-
return prefs[name]?.preferred === true;
|
|
386
|
-
}
|
|
387
|
-
/** Set whether a device is preferred for auto-launch. Setting to the default
|
|
388
|
-
* (not preferred) removes the flag to keep the file minimal. */
|
|
389
|
-
export async function setAutoLaunchPreferred(name, preferred) {
|
|
390
|
-
assertValidDeviceName(name);
|
|
391
|
-
const p = autoLaunchPath();
|
|
392
|
-
await withRegistryLock(p, async () => {
|
|
393
|
-
const prefs = await loadAutoLaunchPreferences();
|
|
394
|
-
if (preferred) {
|
|
395
|
-
prefs[name] = { ...prefs[name], preferred: true };
|
|
396
|
-
}
|
|
397
|
-
else if (prefs[name]) {
|
|
398
|
-
const { preferred: _, ...rest } = prefs[name];
|
|
399
|
-
if (Object.keys(rest).length === 0) {
|
|
400
|
-
delete prefs[name];
|
|
401
|
-
}
|
|
402
|
-
else {
|
|
403
|
-
prefs[name] = rest;
|
|
404
|
-
}
|
|
405
|
-
}
|
|
406
|
-
await atomicWriteJson(p, { devices: prefs, updatedAt: new Date().toISOString() });
|
|
407
|
-
});
|
|
408
|
-
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The effective device profile: the registry's discovery record overlaid with
|
|
3
|
+
* the operator's central config (`fleet.devices.<name>.config` in
|
|
4
|
+
* `~/.agents/agents.yaml`).
|
|
5
|
+
*
|
|
6
|
+
* The registry (`~/.agents/.history/devices/registry.json`) stays the
|
|
7
|
+
* discovery cache — address, Tailscale snapshot, reachability, createdAt. The
|
|
8
|
+
* central config owns the operator-set profile fields: `ssh.user`, `ssh.auth`,
|
|
9
|
+
* `ssh.bundle`, `ssh.bundle-key`, `ssh.identity-file`, and `platform`. A config
|
|
10
|
+
* value WINS over the registry field so `agents devices config <name>` takes
|
|
11
|
+
* effect from any box without re-discovery; an unset key falls back to the
|
|
12
|
+
* registry value.
|
|
13
|
+
*
|
|
14
|
+
* Sync and cheap (readMeta is cached), so dial/render call sites apply it at
|
|
15
|
+
* their entry point rather than threading a resolved profile through every
|
|
16
|
+
* signature. Resolving an already-resolved profile is idempotent.
|
|
17
|
+
*/
|
|
18
|
+
import { type DeviceProfile } from './registry.js';
|
|
19
|
+
/** Overlay the central config's ssh.* / platform / user keys onto a registry profile. */
|
|
20
|
+
export declare function resolveDeviceProfile(device: DeviceProfile): DeviceProfile;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The effective device profile: the registry's discovery record overlaid with
|
|
3
|
+
* the operator's central config (`fleet.devices.<name>.config` in
|
|
4
|
+
* `~/.agents/agents.yaml`).
|
|
5
|
+
*
|
|
6
|
+
* The registry (`~/.agents/.history/devices/registry.json`) stays the
|
|
7
|
+
* discovery cache — address, Tailscale snapshot, reachability, createdAt. The
|
|
8
|
+
* central config owns the operator-set profile fields: `ssh.user`, `ssh.auth`,
|
|
9
|
+
* `ssh.bundle`, `ssh.bundle-key`, `ssh.identity-file`, and `platform`. A config
|
|
10
|
+
* value WINS over the registry field so `agents devices config <name>` takes
|
|
11
|
+
* effect from any box without re-discovery; an unset key falls back to the
|
|
12
|
+
* registry value.
|
|
13
|
+
*
|
|
14
|
+
* Sync and cheap (readMeta is cached), so dial/render call sites apply it at
|
|
15
|
+
* their entry point rather than threading a resolved profile through every
|
|
16
|
+
* signature. Resolving an already-resolved profile is idempotent.
|
|
17
|
+
*/
|
|
18
|
+
import { shellForPlatform, } from './registry.js';
|
|
19
|
+
import { readDeviceConfigValues } from '../device-config.js';
|
|
20
|
+
/** Overlay the central config's ssh.* / platform / user keys onto a registry profile. */
|
|
21
|
+
export function resolveDeviceProfile(device) {
|
|
22
|
+
const config = readDeviceConfigValues(device.name);
|
|
23
|
+
const platform = config.platform ?? device.platform;
|
|
24
|
+
const method = config.sshAuth ?? device.auth.method;
|
|
25
|
+
const user = config.sshUser ?? device.user;
|
|
26
|
+
const identityFile = config.sshIdentityFile ?? device.auth.identityFile;
|
|
27
|
+
const bundle = config.sshBundle ?? device.auth.bundle;
|
|
28
|
+
const bundleKey = config.sshBundleKey ?? device.auth.bundleKey;
|
|
29
|
+
if (platform === device.platform &&
|
|
30
|
+
method === device.auth.method &&
|
|
31
|
+
user === device.user &&
|
|
32
|
+
identityFile === device.auth.identityFile &&
|
|
33
|
+
bundle === device.auth.bundle &&
|
|
34
|
+
bundleKey === device.auth.bundleKey) {
|
|
35
|
+
return device;
|
|
36
|
+
}
|
|
37
|
+
return {
|
|
38
|
+
...device,
|
|
39
|
+
platform,
|
|
40
|
+
shell: shellForPlatform(platform),
|
|
41
|
+
user,
|
|
42
|
+
auth: { method, identityFile, bundle, bundleKey },
|
|
43
|
+
};
|
|
44
|
+
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Post-rollout verification for `agents fleet update` / `agents devices update`.
|
|
3
|
+
*
|
|
4
|
+
* The rollout runs `agents upgrade --yes` per box and calls a box `ok` on
|
|
5
|
+
* `exit 0` alone ({@link ../devices/fleet.js runFleet}, `fleet.ts:262`), rendered
|
|
6
|
+
* as `ok exit 0` (`commands/ssh.ts:416`). That exit code says the npm global was
|
|
7
|
+
* upgraded — it says nothing about **which copy `agents` resolves to on that
|
|
8
|
+
* box**. Any install earlier on PATH than the npm global — a stale copy in
|
|
9
|
+
* another node prefix, a Homebrew shim, a hand-made symlink — keeps winning the
|
|
10
|
+
* name after the upgrade. The upgrade then succeeds, the rollout prints `ok`,
|
|
11
|
+
* and every `agents` command on that box still runs the old code (RUSH-2446).
|
|
12
|
+
*
|
|
13
|
+
* `scripts/install.sh` used to be the usual culprit, linking its side-by-side
|
|
14
|
+
* dev build over `~/.local/bin/agents`; it now publishes `agents-dev` instead and
|
|
15
|
+
* cleans up the links it left. This probe stays as the general backstop — it is
|
|
16
|
+
* name-based (`command -v agents`), so it catches every other cause too.
|
|
17
|
+
*
|
|
18
|
+
* So the rollout asks each box one more question after upgrading: what does
|
|
19
|
+
* `agents` resolve to here, and what version does it report? A box whose
|
|
20
|
+
* resolved `agents` is not on the target is reported as **not upgraded**, and a
|
|
21
|
+
* dev stamp is named as such — never counted as a success.
|
|
22
|
+
*
|
|
23
|
+
* Everything below the probe argv is pure: the shell output is parsed and
|
|
24
|
+
* classified without touching a filesystem or a network, so the verdicts are
|
|
25
|
+
* unit-tested against real probe output rather than a mocked fleet.
|
|
26
|
+
*/
|
|
27
|
+
import { runLocalCommand, runOnDevice, type FleetRunResult, type FleetTarget } from './fleet.js';
|
|
28
|
+
/**
|
|
29
|
+
* Argv for the verification probe, run on each box right after its upgrade.
|
|
30
|
+
*
|
|
31
|
+
* Space-joined and evaluated by a shell on both fleet paths — `runOnDevice`
|
|
32
|
+
* hands the tokens to ssh (the remote shell parses them) and `runLocalCommand`
|
|
33
|
+
* joins them under `shell: true` (`fleet.ts:runLocalCommand` docblock) — so the
|
|
34
|
+
* quoting here is the same on the self target and every peer.
|
|
35
|
+
*
|
|
36
|
+
* POSIX only, deliberately: the two `sh` builtins it needs (`command -v`,
|
|
37
|
+
* parameter substitution) do not exist in cmd.exe, so a Windows box yields no
|
|
38
|
+
* parseable output and {@link classifyRolloutVerification} reports it
|
|
39
|
+
* `unverified` rather than silently passing it.
|
|
40
|
+
*
|
|
41
|
+
* `command -v agents` is the resolution the user's own shell performs;
|
|
42
|
+
* `readlink -f` follows the npm/dev bin symlink to the copy that actually runs,
|
|
43
|
+
* falling back to the unresolved path where `readlink -f` is unavailable.
|
|
44
|
+
*/
|
|
45
|
+
export declare function rolloutVerifyCommand(): string[];
|
|
46
|
+
export interface RolloutProbe {
|
|
47
|
+
/** Path the box's own `agents` resolves to, symlinks followed. */
|
|
48
|
+
resolvedPath?: string;
|
|
49
|
+
/** Version that resolved copy reports. */
|
|
50
|
+
reportedVersion?: string;
|
|
51
|
+
}
|
|
52
|
+
/** Parse the probe's stdout. Unlabelled lines (shell banners, motd) are ignored. */
|
|
53
|
+
export declare function parseRolloutVerifyOutput(stdout: string): RolloutProbe;
|
|
54
|
+
export type RolloutVerdict =
|
|
55
|
+
/** The resolved `agents` reports the target version. */
|
|
56
|
+
'on-target'
|
|
57
|
+
/** The resolved `agents` is a `scripts/install.sh` dev build shadowing the upgraded global. */
|
|
58
|
+
| 'dev-shadowed'
|
|
59
|
+
/** The resolved `agents` reports some other version — the upgrade did not reach it. */
|
|
60
|
+
| 'not-upgraded'
|
|
61
|
+
/** The probe produced no usable answer, so upgraded-ness is unknown. */
|
|
62
|
+
| 'unverified';
|
|
63
|
+
export interface RolloutVerification extends RolloutProbe {
|
|
64
|
+
verdict: RolloutVerdict;
|
|
65
|
+
/** One-line human reason, always set for a non-`on-target` verdict. */
|
|
66
|
+
detail: string;
|
|
67
|
+
}
|
|
68
|
+
/** A verdict other than `on-target` MUST NOT be reported as a successful rollout. */
|
|
69
|
+
export declare function isRolloutSuccess(verdict: RolloutVerdict): boolean;
|
|
70
|
+
/**
|
|
71
|
+
* Resolve the version the rollout was aiming at.
|
|
72
|
+
*
|
|
73
|
+
* An explicit `agents fleet update <version>` names it. A bare
|
|
74
|
+
* `agents fleet update` resolves the `latest` dist-tag independently on every
|
|
75
|
+
* box, so the aggregator never sees a number — it is derived here as the highest
|
|
76
|
+
* **released** version any probed box reports. Dev stamps are excluded from that
|
|
77
|
+
* derivation: a fleet of dev builds must not elect one of them as the target and
|
|
78
|
+
* report itself upgraded. Returns undefined when nothing released was observed,
|
|
79
|
+
* which makes every box `unverified` rather than falsely `on-target`.
|
|
80
|
+
*/
|
|
81
|
+
export declare function resolveRolloutTarget(explicitVersion: string | undefined, probes: RolloutProbe[]): string | undefined;
|
|
82
|
+
/** Classify one box's probe against the rollout target. */
|
|
83
|
+
export declare function classifyRolloutVerification(probe: RolloutProbe, targetVersion: string | undefined): RolloutVerification;
|
|
84
|
+
export interface VerifyFleetRolloutOptions {
|
|
85
|
+
/** Name of THIS machine; its target is probed locally, mirroring `runFleet`. */
|
|
86
|
+
self?: string;
|
|
87
|
+
/** Injectable ssh runner (tests). */
|
|
88
|
+
runner?: typeof runOnDevice;
|
|
89
|
+
/** Injectable local runner (tests). */
|
|
90
|
+
localRunner?: typeof runLocalCommand;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Probe every box the upgrade reported `ok` and classify what its `agents`
|
|
94
|
+
* actually resolves to. Keyed by device name.
|
|
95
|
+
*
|
|
96
|
+
* Only `ok` boxes are probed: a `skipped` or `failed` row already reports itself
|
|
97
|
+
* loudly, and re-probing it would add a second confusing line for one fault.
|
|
98
|
+
* A probe that throws or exits non-zero yields `unverified`, never `on-target` —
|
|
99
|
+
* "we could not check" and "it is upgraded" are different answers.
|
|
100
|
+
*/
|
|
101
|
+
export declare function verifyFleetRollout(targets: FleetTarget[], results: FleetRunResult[], explicitVersion: string | undefined, opts?: VerifyFleetRolloutOptions): Map<string, RolloutVerification>;
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Post-rollout verification for `agents fleet update` / `agents devices update`.
|
|
3
|
+
*
|
|
4
|
+
* The rollout runs `agents upgrade --yes` per box and calls a box `ok` on
|
|
5
|
+
* `exit 0` alone ({@link ../devices/fleet.js runFleet}, `fleet.ts:262`), rendered
|
|
6
|
+
* as `ok exit 0` (`commands/ssh.ts:416`). That exit code says the npm global was
|
|
7
|
+
* upgraded — it says nothing about **which copy `agents` resolves to on that
|
|
8
|
+
* box**. Any install earlier on PATH than the npm global — a stale copy in
|
|
9
|
+
* another node prefix, a Homebrew shim, a hand-made symlink — keeps winning the
|
|
10
|
+
* name after the upgrade. The upgrade then succeeds, the rollout prints `ok`,
|
|
11
|
+
* and every `agents` command on that box still runs the old code (RUSH-2446).
|
|
12
|
+
*
|
|
13
|
+
* `scripts/install.sh` used to be the usual culprit, linking its side-by-side
|
|
14
|
+
* dev build over `~/.local/bin/agents`; it now publishes `agents-dev` instead and
|
|
15
|
+
* cleans up the links it left. This probe stays as the general backstop — it is
|
|
16
|
+
* name-based (`command -v agents`), so it catches every other cause too.
|
|
17
|
+
*
|
|
18
|
+
* So the rollout asks each box one more question after upgrading: what does
|
|
19
|
+
* `agents` resolve to here, and what version does it report? A box whose
|
|
20
|
+
* resolved `agents` is not on the target is reported as **not upgraded**, and a
|
|
21
|
+
* dev stamp is named as such — never counted as a success.
|
|
22
|
+
*
|
|
23
|
+
* Everything below the probe argv is pure: the shell output is parsed and
|
|
24
|
+
* classified without touching a filesystem or a network, so the verdicts are
|
|
25
|
+
* unit-tested against real probe output rather than a mocked fleet.
|
|
26
|
+
*/
|
|
27
|
+
import { compareVersions } from '../agent-spec/primitives.js';
|
|
28
|
+
import { isDevVersionStamp } from '../startup/dev-build.js';
|
|
29
|
+
import { runLocalCommand, runOnDevice, } from './fleet.js';
|
|
30
|
+
import { isSelfHost } from './self-host.js';
|
|
31
|
+
/**
|
|
32
|
+
* Line prefixes the probe emits. Prefixed rather than positional because a
|
|
33
|
+
* login shell can print its own banner lines into the same stdout, and a
|
|
34
|
+
* rollout that mis-reads a motd line as a version would report a false verdict.
|
|
35
|
+
*/
|
|
36
|
+
const PATH_PREFIX = 'agents-rollout-path=';
|
|
37
|
+
const VERSION_PREFIX = 'agents-rollout-version=';
|
|
38
|
+
/**
|
|
39
|
+
* Argv for the verification probe, run on each box right after its upgrade.
|
|
40
|
+
*
|
|
41
|
+
* Space-joined and evaluated by a shell on both fleet paths — `runOnDevice`
|
|
42
|
+
* hands the tokens to ssh (the remote shell parses them) and `runLocalCommand`
|
|
43
|
+
* joins them under `shell: true` (`fleet.ts:runLocalCommand` docblock) — so the
|
|
44
|
+
* quoting here is the same on the self target and every peer.
|
|
45
|
+
*
|
|
46
|
+
* POSIX only, deliberately: the two `sh` builtins it needs (`command -v`,
|
|
47
|
+
* parameter substitution) do not exist in cmd.exe, so a Windows box yields no
|
|
48
|
+
* parseable output and {@link classifyRolloutVerification} reports it
|
|
49
|
+
* `unverified` rather than silently passing it.
|
|
50
|
+
*
|
|
51
|
+
* `command -v agents` is the resolution the user's own shell performs;
|
|
52
|
+
* `readlink -f` follows the npm/dev bin symlink to the copy that actually runs,
|
|
53
|
+
* falling back to the unresolved path where `readlink -f` is unavailable.
|
|
54
|
+
*/
|
|
55
|
+
export function rolloutVerifyCommand() {
|
|
56
|
+
const script = [
|
|
57
|
+
'p=$(command -v agents || true)',
|
|
58
|
+
'r=$(readlink -f "$p" 2>/dev/null || echo "$p")',
|
|
59
|
+
`echo ${PATH_PREFIX}$r`,
|
|
60
|
+
`echo ${VERSION_PREFIX}$(agents --version 2>/dev/null || true)`,
|
|
61
|
+
].join('; ');
|
|
62
|
+
return ['sh', '-c', `'${script}'`];
|
|
63
|
+
}
|
|
64
|
+
/** Parse the probe's stdout. Unlabelled lines (shell banners, motd) are ignored. */
|
|
65
|
+
export function parseRolloutVerifyOutput(stdout) {
|
|
66
|
+
const probe = {};
|
|
67
|
+
for (const raw of stdout.split('\n')) {
|
|
68
|
+
const line = raw.trim();
|
|
69
|
+
if (line.startsWith(PATH_PREFIX)) {
|
|
70
|
+
const value = line.slice(PATH_PREFIX.length).trim();
|
|
71
|
+
if (value)
|
|
72
|
+
probe.resolvedPath = value;
|
|
73
|
+
}
|
|
74
|
+
else if (line.startsWith(VERSION_PREFIX)) {
|
|
75
|
+
const value = line.slice(VERSION_PREFIX.length).trim();
|
|
76
|
+
if (value)
|
|
77
|
+
probe.reportedVersion = value;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return probe;
|
|
81
|
+
}
|
|
82
|
+
/** A verdict other than `on-target` MUST NOT be reported as a successful rollout. */
|
|
83
|
+
export function isRolloutSuccess(verdict) {
|
|
84
|
+
return verdict === 'on-target';
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Resolve the version the rollout was aiming at.
|
|
88
|
+
*
|
|
89
|
+
* An explicit `agents fleet update <version>` names it. A bare
|
|
90
|
+
* `agents fleet update` resolves the `latest` dist-tag independently on every
|
|
91
|
+
* box, so the aggregator never sees a number — it is derived here as the highest
|
|
92
|
+
* **released** version any probed box reports. Dev stamps are excluded from that
|
|
93
|
+
* derivation: a fleet of dev builds must not elect one of them as the target and
|
|
94
|
+
* report itself upgraded. Returns undefined when nothing released was observed,
|
|
95
|
+
* which makes every box `unverified` rather than falsely `on-target`.
|
|
96
|
+
*/
|
|
97
|
+
export function resolveRolloutTarget(explicitVersion, probes) {
|
|
98
|
+
if (explicitVersion && !isDistTag(explicitVersion))
|
|
99
|
+
return explicitVersion;
|
|
100
|
+
let best;
|
|
101
|
+
for (const probe of probes) {
|
|
102
|
+
const version = probe.reportedVersion;
|
|
103
|
+
if (!version || isDevVersionStamp(version))
|
|
104
|
+
continue;
|
|
105
|
+
if (best === undefined || compareVersions(version, best) > 0)
|
|
106
|
+
best = version;
|
|
107
|
+
}
|
|
108
|
+
return best;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* A dist-tag (`latest`, `next`) is not a comparable version. `agents fleet update`
|
|
112
|
+
* accepts either (`fleet.ts:upgradeCommand`), so a tag argument is treated the
|
|
113
|
+
* same as no argument: derive the number from what the fleet reports.
|
|
114
|
+
*/
|
|
115
|
+
function isDistTag(version) {
|
|
116
|
+
return !/^\d/.test(version);
|
|
117
|
+
}
|
|
118
|
+
/** Classify one box's probe against the rollout target. */
|
|
119
|
+
export function classifyRolloutVerification(probe, targetVersion) {
|
|
120
|
+
const { resolvedPath, reportedVersion } = probe;
|
|
121
|
+
if (!reportedVersion) {
|
|
122
|
+
return {
|
|
123
|
+
...probe,
|
|
124
|
+
verdict: 'unverified',
|
|
125
|
+
detail: resolvedPath
|
|
126
|
+
? `resolved ${resolvedPath} but it reported no version`
|
|
127
|
+
: 'could not resolve `agents` on this box',
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
if (!targetVersion) {
|
|
131
|
+
return {
|
|
132
|
+
...probe,
|
|
133
|
+
verdict: 'unverified',
|
|
134
|
+
detail: `runs ${reportedVersion}; no target version to compare against`,
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
if (reportedVersion === targetVersion) {
|
|
138
|
+
return { ...probe, verdict: 'on-target', detail: `runs ${reportedVersion}` };
|
|
139
|
+
}
|
|
140
|
+
if (isDevVersionStamp(reportedVersion)) {
|
|
141
|
+
return {
|
|
142
|
+
...probe,
|
|
143
|
+
verdict: 'dev-shadowed',
|
|
144
|
+
detail: `NOT upgraded — \`agents\` resolves to a dev build (${reportedVersion})` +
|
|
145
|
+
`${resolvedPath ? ` at ${resolvedPath}` : ''}, shadowing the upgraded ${targetVersion} global`,
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
return {
|
|
149
|
+
...probe,
|
|
150
|
+
verdict: 'not-upgraded',
|
|
151
|
+
detail: `NOT upgraded — \`agents\` runs ${reportedVersion}, target ${targetVersion}` +
|
|
152
|
+
`${resolvedPath ? ` (resolves to ${resolvedPath})` : ''}`,
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
/** Probe deadline. The probe is two shell builtins plus `agents --version`. */
|
|
156
|
+
const VERIFY_TIMEOUT_MS = 60_000;
|
|
157
|
+
/**
|
|
158
|
+
* Probe every box the upgrade reported `ok` and classify what its `agents`
|
|
159
|
+
* actually resolves to. Keyed by device name.
|
|
160
|
+
*
|
|
161
|
+
* Only `ok` boxes are probed: a `skipped` or `failed` row already reports itself
|
|
162
|
+
* loudly, and re-probing it would add a second confusing line for one fault.
|
|
163
|
+
* A probe that throws or exits non-zero yields `unverified`, never `on-target` —
|
|
164
|
+
* "we could not check" and "it is upgraded" are different answers.
|
|
165
|
+
*/
|
|
166
|
+
export function verifyFleetRollout(targets, results, explicitVersion, opts = {}) {
|
|
167
|
+
const runner = opts.runner ?? runOnDevice;
|
|
168
|
+
const localRunner = opts.localRunner ?? runLocalCommand;
|
|
169
|
+
const upgraded = new Set(results.filter((r) => r.status === 'ok').map((r) => r.name));
|
|
170
|
+
const cmd = rolloutVerifyCommand();
|
|
171
|
+
const probes = new Map();
|
|
172
|
+
for (const t of targets) {
|
|
173
|
+
const name = t.device.name;
|
|
174
|
+
if (t.skip || !upgraded.has(name))
|
|
175
|
+
continue;
|
|
176
|
+
try {
|
|
177
|
+
const isSelf = (opts.self !== undefined && name === opts.self) || isSelfHost(name);
|
|
178
|
+
const res = isSelf
|
|
179
|
+
? localRunner(cmd, { timeoutMs: VERIFY_TIMEOUT_MS })
|
|
180
|
+
: runner(t.device, cmd, { timeoutMs: VERIFY_TIMEOUT_MS });
|
|
181
|
+
probes.set(name, parseRolloutVerifyOutput(res.stdout));
|
|
182
|
+
}
|
|
183
|
+
catch {
|
|
184
|
+
probes.set(name, {});
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
const target = resolveRolloutTarget(explicitVersion, [...probes.values()]);
|
|
188
|
+
const out = new Map();
|
|
189
|
+
for (const [name, probe] of probes) {
|
|
190
|
+
out.set(name, classifyRolloutVerification(probe, target));
|
|
191
|
+
}
|
|
192
|
+
return out;
|
|
193
|
+
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { resolveDeviceProfile } from './resolve-profile.js';
|
|
1
2
|
const HEADER = [
|
|
2
3
|
'# Managed by `agents devices` — do not edit by hand.',
|
|
3
4
|
'# Regenerate with: agents devices render',
|
|
@@ -9,14 +10,17 @@ export function hostNameFor(device) {
|
|
|
9
10
|
}
|
|
10
11
|
/** Render a single device into an ssh_config `Host` stanza, or null if it has no address. */
|
|
11
12
|
function renderHost(device) {
|
|
12
|
-
|
|
13
|
+
// Effective profile: operator config (ssh.user / ssh.identity-file) overlaid
|
|
14
|
+
// on the discovery record, so the rendered stanza matches what `agents ssh` dials.
|
|
15
|
+
const resolved = resolveDeviceProfile(device);
|
|
16
|
+
const hostName = hostNameFor(resolved);
|
|
13
17
|
if (!hostName)
|
|
14
18
|
return null;
|
|
15
|
-
const lines = [`Host ${
|
|
16
|
-
if (
|
|
17
|
-
lines.push(` User ${
|
|
18
|
-
if (
|
|
19
|
-
lines.push(` IdentityFile ${
|
|
19
|
+
const lines = [`Host ${resolved.name}`, ` HostName ${hostName}`];
|
|
20
|
+
if (resolved.user)
|
|
21
|
+
lines.push(` User ${resolved.user}`);
|
|
22
|
+
if (resolved.auth.method === 'key' && resolved.auth.identityFile) {
|
|
23
|
+
lines.push(` IdentityFile ${resolved.auth.identityFile}`, ' IdentitiesOnly yes');
|
|
20
24
|
}
|
|
21
25
|
return lines.join('\n');
|
|
22
26
|
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Event stream families — sessions-style --include / --exclude for the unified
|
|
3
|
+
* event reader. One vocabulary maps onto existing filters (includeActivity,
|
|
4
|
+
* eventTypes, level) so the engine stays single-path.
|
|
5
|
+
*/
|
|
6
|
+
import type { EventType } from './events.js';
|
|
7
|
+
import type { UnifiedQuery } from './event-stream.js';
|
|
8
|
+
export declare const EVENT_FAMILIES: readonly ["ops", "activity", "commands", "runs", "security"];
|
|
9
|
+
export type EventFamily = (typeof EVENT_FAMILIES)[number];
|
|
10
|
+
export declare function isEventFamily(value: string): value is EventFamily;
|
|
11
|
+
/**
|
|
12
|
+
* Parse a comma-separated family list. Throws on unknown names or empty list
|
|
13
|
+
* after split (same discipline as sessions role lists).
|
|
14
|
+
*/
|
|
15
|
+
export declare function parseFamilyList(raw: string, flagName: string): EventFamily[];
|
|
16
|
+
/** Command-churn event kinds. */
|
|
17
|
+
export declare const COMMAND_EVENT_TYPES: readonly EventType[];
|
|
18
|
+
/** Run-dispatch outcome kinds (replaces the separate audit/log.jsonl product). */
|
|
19
|
+
export declare const RUN_EVENT_TYPES: readonly EventType[];
|
|
20
|
+
/**
|
|
21
|
+
* Fold family include/exclude into a UnifiedQuery.
|
|
22
|
+
* Precedence: family narrows sources/types; field filters (module, event, …)
|
|
23
|
+
* still apply on top.
|
|
24
|
+
*
|
|
25
|
+
* --include and --exclude are mutually exclusive at the CLI layer; this
|
|
26
|
+
* function accepts only one of includeFamilies / excludeFamilies.
|
|
27
|
+
*/
|
|
28
|
+
export declare function applyFamilies(q: UnifiedQuery): UnifiedQuery;
|