@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
package/dist/lib/secrets/push.js
CHANGED
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
import { sshExec } from '../ssh-exec.js';
|
|
23
23
|
import { remoteShellFor, buildWindowsStdinImportCommand } from '../hosts/remote-cmd.js';
|
|
24
24
|
import { resolveRemoteOsSync } from '../hosts/remote-os.js';
|
|
25
|
-
import { remoteSecretsRaw, verifyRemoteKeychainPush, keychainWriteFailureMessage, buildRemoteFileImportCommand, } from './remote.js';
|
|
25
|
+
import { remoteSecretsRaw, verifyRemoteKeychainPush, keychainWriteFailureMessage, buildRemoteFileImportCommand, credentialTransportSshOpts, } from './remote.js';
|
|
26
26
|
import { readAndResolveBundleEnv } from './bundles.js';
|
|
27
27
|
/**
|
|
28
28
|
* Serialize a resolved env map to `.env` lines that round-trip losslessly through
|
|
@@ -42,15 +42,35 @@ export function bundleEnvToDotenv(env) {
|
|
|
42
42
|
}
|
|
43
43
|
return lines.join('\n') + '\n';
|
|
44
44
|
}
|
|
45
|
+
/** Preserve the literal-vs-secret schema that dotenv transport cannot encode. */
|
|
46
|
+
export function planLiteralRestoration(bundle, literalValues = {}) {
|
|
47
|
+
return Object.entries(literalValues).map(([key, value]) => ({
|
|
48
|
+
key,
|
|
49
|
+
removeArgs: ['remove', bundle, key, '--yes'],
|
|
50
|
+
addArgs: ['add', bundle, key, '--value', value],
|
|
51
|
+
}));
|
|
52
|
+
}
|
|
45
53
|
/**
|
|
46
54
|
* Read and resolve a bundle once, for pushing to one or more hosts.
|
|
47
55
|
*
|
|
48
|
-
* `
|
|
49
|
-
*
|
|
50
|
-
*
|
|
56
|
+
* `keyMode: 'storage'` is fixed — a push always sends storage-shaped values.
|
|
57
|
+
*
|
|
58
|
+
* `agentOnly` is the caller's to decide, and it is NOT a security level: it
|
|
59
|
+
* selects the broker-only read (fail fast with the `agents secrets unlock` hint)
|
|
60
|
+
* over the interactive read (macOS may raise a Touch ID sheet). The headless
|
|
61
|
+
* guard exists because an AGENT LAUNCH must never enumerate the keychain — a
|
|
62
|
+
* per-bundle prefix becomes a broad `agents-cli.` scan after service-name
|
|
63
|
+
* hashing, and macOS evaluates unrelated biometry ACLs during it, one sheet per
|
|
64
|
+
* installed version (bundles.ts, RUSH-2440). A human at a TTY is not that case:
|
|
65
|
+
* they can answer one prompt, and the interactive sibling reads (`view --reveal`,
|
|
66
|
+
* `exec`) already let them. NOT `get` — it is unconditionally `agentOnly` on
|
|
67
|
+
* purpose, because prompting would hang a `$(agents secrets get …)` capture
|
|
68
|
+
* mid-pipeline (SEC-13b). It defaults to `true` so an automated caller that says
|
|
69
|
+
* nothing stays broker-only.
|
|
51
70
|
*/
|
|
52
|
-
export function resolveBundleForPush(bundle, caller) {
|
|
53
|
-
const
|
|
71
|
+
export function resolveBundleForPush(bundle, caller, opts = {}) {
|
|
72
|
+
const agentOnly = opts.agentOnly ?? true;
|
|
73
|
+
const { env } = readAndResolveBundleEnv(bundle, { caller, keyMode: 'storage', agentOnly });
|
|
54
74
|
return { env, dotenv: bundleEnvToDotenv(env), keyCount: Object.keys(env).length };
|
|
55
75
|
}
|
|
56
76
|
function isPowershellTarget(host) {
|
|
@@ -70,7 +90,7 @@ export function planPushTransport(resolved, bundle, host, opts) {
|
|
|
70
90
|
passphrase: opts.passphrase ?? '',
|
|
71
91
|
force: opts.force,
|
|
72
92
|
});
|
|
73
|
-
return { kind: 'ssh', remoteCmd, input };
|
|
93
|
+
return { kind: 'ssh', remoteCmd, input, multiplex: false };
|
|
74
94
|
}
|
|
75
95
|
if (powershell) {
|
|
76
96
|
// Keychain on a Windows target: the `agents.ps1` shim doesn't forward
|
|
@@ -82,6 +102,7 @@ export function planPushTransport(resolved, bundle, host, opts) {
|
|
|
82
102
|
kind: 'ssh',
|
|
83
103
|
remoteCmd: buildWindowsStdinImportCommand(bundle, { force: opts.force }),
|
|
84
104
|
input: resolved.dotenv,
|
|
105
|
+
multiplex: false,
|
|
85
106
|
};
|
|
86
107
|
}
|
|
87
108
|
// Keychain on a POSIX target: OS-aware wrapping + the hardened ssh engine
|
|
@@ -91,6 +112,7 @@ export function planPushTransport(resolved, bundle, host, opts) {
|
|
|
91
112
|
kind: 'remote-secrets',
|
|
92
113
|
args: ['import', bundle, '--from', '-', ...(opts.force ? ['--force'] : [])],
|
|
93
114
|
input: resolved.dotenv,
|
|
115
|
+
multiplex: false,
|
|
94
116
|
};
|
|
95
117
|
}
|
|
96
118
|
/**
|
|
@@ -105,9 +127,15 @@ export function pushResolvedBundleToHost(resolved, bundle, host, opts) {
|
|
|
105
127
|
const plan = planPushTransport(resolved, bundle, host, opts);
|
|
106
128
|
if (plan.kind === 'refuse')
|
|
107
129
|
return fail(plan.message);
|
|
130
|
+
// Every ssh below rides the credential-transport posture: the managed host key
|
|
131
|
+
// is pinned (a changed key is refused) and the connection never reuses or
|
|
132
|
+
// leaves a persistent authenticated control master to the destination
|
|
133
|
+
// (RUSH-2527, `credentialTransportSshOpts`). The plan's `multiplex: false` is
|
|
134
|
+
// the raw-`ssh` branch's half of that; the `remote-secrets` branch and the
|
|
135
|
+
// read-back/policy/literal follow-ups pass `secret: true` for the same posture.
|
|
108
136
|
const res = plan.kind === 'ssh'
|
|
109
|
-
? sshExec(host, plan.remoteCmd, { input: plan.input })
|
|
110
|
-
: remoteSecretsRaw(host, plan.args, { input: plan.input, osLookupName: host });
|
|
137
|
+
? sshExec(host, plan.remoteCmd, { input: plan.input, hostKeyOpts: credentialTransportSshOpts(host).hostKeyOpts, multiplex: plan.multiplex })
|
|
138
|
+
: remoteSecretsRaw(host, plan.args, { input: plan.input, osLookupName: host, secret: true });
|
|
111
139
|
if (res.code === null) {
|
|
112
140
|
return fail(res.stderr.trim() || (res.timedOut ? 'ssh timed out' : 'ssh failed'));
|
|
113
141
|
}
|
|
@@ -123,13 +151,32 @@ export function pushResolvedBundleToHost(resolved, bundle, host, opts) {
|
|
|
123
151
|
// metadata-only bundle that breaks later with "stored item not found". The
|
|
124
152
|
// file backend is headless-readable by construction, so it is skipped.
|
|
125
153
|
if (opts.remoteBackend === 'keychain') {
|
|
126
|
-
const verdict = verifyRemoteKeychainPush(host, bundle, Object.keys(resolved.env), { osLookupName: host });
|
|
154
|
+
const verdict = verifyRemoteKeychainPush(host, bundle, Object.keys(resolved.env), { osLookupName: host, secret: true });
|
|
127
155
|
if (!verdict.ok) {
|
|
128
156
|
return fail(verdict.kind === 'locked-keychain'
|
|
129
157
|
? keychainWriteFailureMessage(host, bundle, verdict.reason)
|
|
130
158
|
: `pushed '${bundle}' but could not verify it on the remote: ${verdict.reason}`);
|
|
131
159
|
}
|
|
132
160
|
}
|
|
161
|
+
if (opts.policyNever) {
|
|
162
|
+
const policy = remoteSecretsRaw(host, ['policy', bundle, 'never', '--i-understand'], { osLookupName: host, secret: true });
|
|
163
|
+
if (policy.code !== 0) {
|
|
164
|
+
const msg = (policy.stderr || policy.stdout || '').trim();
|
|
165
|
+
return fail(`pushed '${bundle}' but could not set remote policy never${msg ? `: ${msg}` : ''}`);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
for (const step of planLiteralRestoration(bundle, opts.literalValues)) {
|
|
169
|
+
const removed = remoteSecretsRaw(host, step.removeArgs, { osLookupName: host, secret: true });
|
|
170
|
+
if (removed.code !== 0) {
|
|
171
|
+
const msg = (removed.stderr || removed.stdout || '').trim();
|
|
172
|
+
return fail(`pushed '${bundle}' but could not replace transported ${step.key}${msg ? `: ${msg}` : ''}`);
|
|
173
|
+
}
|
|
174
|
+
const literal = remoteSecretsRaw(host, step.addArgs, { osLookupName: host, secret: true });
|
|
175
|
+
if (literal.code !== 0) {
|
|
176
|
+
const msg = (literal.stderr || literal.stdout || '').trim();
|
|
177
|
+
return fail(`pushed '${bundle}' but could not preserve literal ${step.key}${msg ? `: ${msg}` : ''}`);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
133
180
|
const remoteMsg = (res.stdout || '').trim().split('\n').map((l) => l.trim()).filter(Boolean).pop();
|
|
134
181
|
return {
|
|
135
182
|
ok: true,
|
|
@@ -141,5 +188,5 @@ export function pushResolvedBundleToHost(resolved, bundle, host, opts) {
|
|
|
141
188
|
}
|
|
142
189
|
/** Resolve and push in one call — for a single host. */
|
|
143
190
|
export function pushBundleToHost(bundle, host, opts) {
|
|
144
|
-
return pushResolvedBundleToHost(resolveBundleForPush(bundle, opts.operation), bundle, host, opts);
|
|
191
|
+
return pushResolvedBundleToHost(resolveBundleForPush(bundle, opts.operation, { agentOnly: opts.agentOnly }), bundle, host, opts);
|
|
145
192
|
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Negative memo for failed/cancelled macOS keychain reads (the "back-off").
|
|
3
3
|
*
|
|
4
4
|
* A cancelled Touch ID sheet is the user saying "not now" — but a polling
|
|
5
|
-
* caller (
|
|
5
|
+
* caller (AGI EXT host's `agents view` loop, a watch script)
|
|
6
6
|
* retries the same read a few seconds later and pops the sheet again, forever.
|
|
7
7
|
* The headless guard (index.ts `assertRawKeychainReadAllowed`) covers the
|
|
8
8
|
* no-TTY case; this memo covers a context that CAN prompt but just had its
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Negative memo for failed/cancelled macOS keychain reads (the "back-off").
|
|
3
3
|
*
|
|
4
4
|
* A cancelled Touch ID sheet is the user saying "not now" — but a polling
|
|
5
|
-
* caller (
|
|
5
|
+
* caller (AGI EXT host's `agents view` loop, a watch script)
|
|
6
6
|
* retries the same read a few seconds later and pops the sheet again, forever.
|
|
7
7
|
* The headless guard (index.ts `assertRawKeychainReadAllowed`) covers the
|
|
8
8
|
* no-TTY case; this memo covers a context that CAN prompt but just had its
|
|
@@ -16,6 +16,28 @@
|
|
|
16
16
|
* in argv / `ps` / remote shell history. Nothing is persisted locally.
|
|
17
17
|
*/
|
|
18
18
|
import { type SshExecResult } from '../ssh-exec.js';
|
|
19
|
+
/**
|
|
20
|
+
* SSH options for a SECRET-carrying transport (RUSH-2527). Every `agents secrets
|
|
21
|
+
* --host` operation moves credential bytes — over ssh stdin (push) or ssh stdout
|
|
22
|
+
* (resolve/read-back) — so it MUST NOT ride the shared `accept-new` baseline
|
|
23
|
+
* against the user's own `~/.ssh/known_hosts` with a reusable control socket.
|
|
24
|
+
* Two hardenings over that baseline, matching the posture the `--copy-creds`
|
|
25
|
+
* dispatch already uses (`hosts/dispatch.ts` -> `hostKeyCheckingOpts`):
|
|
26
|
+
*
|
|
27
|
+
* - **Managed pinned host keys.** Verify against the CLI-owned known_hosts
|
|
28
|
+
* store (`known-hosts.ts`), not `~/.ssh/known_hosts`. A CHANGED key on a
|
|
29
|
+
* known host is refused (`StrictHostKeyChecking` `yes` once pinned,
|
|
30
|
+
* `accept-new` — which still refuses a changed key, only learns a genuinely
|
|
31
|
+
* new one — before that). So a machine-in-the-middle swapping a pinned host's
|
|
32
|
+
* key can never receive or return a secret.
|
|
33
|
+
* - **No multiplex reuse.** `multiplex: false` — a credential channel never
|
|
34
|
+
* leaves a persistent `ControlMaster` socket lingering (60s `ControlPersist`)
|
|
35
|
+
* that any other `agents` invocation to that host would silently reuse.
|
|
36
|
+
*/
|
|
37
|
+
export declare function credentialTransportSshOpts(target: string): {
|
|
38
|
+
hostKeyOpts: string[];
|
|
39
|
+
multiplex: false;
|
|
40
|
+
};
|
|
19
41
|
/**
|
|
20
42
|
* Trust boundary for a remote-resolved env map. A peer's `secrets export` output
|
|
21
43
|
* is untrusted input: a compromised or misconfigured host could return keys that
|
|
@@ -76,6 +98,7 @@ export declare function remoteSecretsRaw(target: string, args: string[], opts?:
|
|
|
76
98
|
tty?: boolean;
|
|
77
99
|
input?: string;
|
|
78
100
|
osLookupName?: string;
|
|
101
|
+
secret?: boolean;
|
|
79
102
|
}): SshExecResult;
|
|
80
103
|
/**
|
|
81
104
|
* Run a remote `agents secrets <args>` FOREGROUND, with the local stdio wired
|
|
@@ -176,6 +199,7 @@ export declare function keychainWriteFailureMessage(host: string, bundle: string
|
|
|
176
199
|
*/
|
|
177
200
|
export declare function verifyRemoteKeychainPush(target: string, bundle: string, pushedKeys: string[], opts?: {
|
|
178
201
|
osLookupName?: string;
|
|
202
|
+
secret?: boolean;
|
|
179
203
|
}): RemoteKeychainWriteVerification;
|
|
180
204
|
/**
|
|
181
205
|
* The `bash -lc` command + stdin payload that drives a **file-backed** remote
|
|
@@ -22,7 +22,33 @@ import { sshTargetFor } from '../hosts/types.js';
|
|
|
22
22
|
import { buildRemoteAgentsInvocation } from '../hosts/remote-cmd.js';
|
|
23
23
|
import { resolveRemoteOsSync } from '../hosts/remote-os.js';
|
|
24
24
|
import { isLoaderOrInterpreterEnv } from './bundles.js';
|
|
25
|
+
import { isHostPinned, hostKeyCheckingOpts } from '../devices/known-hosts.js';
|
|
25
26
|
const REMOTE_TIMEOUT_MS = 30_000;
|
|
27
|
+
/** The host part of an ssh target (`user@host` -> `host`) for known_hosts matching. */
|
|
28
|
+
function hostKeyLookupName(target) {
|
|
29
|
+
return target.split('@').pop() ?? target;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* SSH options for a SECRET-carrying transport (RUSH-2527). Every `agents secrets
|
|
33
|
+
* --host` operation moves credential bytes — over ssh stdin (push) or ssh stdout
|
|
34
|
+
* (resolve/read-back) — so it MUST NOT ride the shared `accept-new` baseline
|
|
35
|
+
* against the user's own `~/.ssh/known_hosts` with a reusable control socket.
|
|
36
|
+
* Two hardenings over that baseline, matching the posture the `--copy-creds`
|
|
37
|
+
* dispatch already uses (`hosts/dispatch.ts` -> `hostKeyCheckingOpts`):
|
|
38
|
+
*
|
|
39
|
+
* - **Managed pinned host keys.** Verify against the CLI-owned known_hosts
|
|
40
|
+
* store (`known-hosts.ts`), not `~/.ssh/known_hosts`. A CHANGED key on a
|
|
41
|
+
* known host is refused (`StrictHostKeyChecking` `yes` once pinned,
|
|
42
|
+
* `accept-new` — which still refuses a changed key, only learns a genuinely
|
|
43
|
+
* new one — before that). So a machine-in-the-middle swapping a pinned host's
|
|
44
|
+
* key can never receive or return a secret.
|
|
45
|
+
* - **No multiplex reuse.** `multiplex: false` — a credential channel never
|
|
46
|
+
* leaves a persistent `ControlMaster` socket lingering (60s `ControlPersist`)
|
|
47
|
+
* that any other `agents` invocation to that host would silently reuse.
|
|
48
|
+
*/
|
|
49
|
+
export function credentialTransportSshOpts(target) {
|
|
50
|
+
return { hostKeyOpts: hostKeyCheckingOpts(isHostPinned(hostKeyLookupName(target))), multiplex: false };
|
|
51
|
+
}
|
|
26
52
|
/**
|
|
27
53
|
* Trust boundary for a remote-resolved env map. A peer's `secrets export` output
|
|
28
54
|
* is untrusted input: a compromised or misconfigured host could return keys that
|
|
@@ -128,11 +154,21 @@ export function splitBundleRef(ref) {
|
|
|
128
154
|
*/
|
|
129
155
|
export function remoteSecretsRaw(target, args, opts = {}) {
|
|
130
156
|
const remoteCmd = buildRemoteAgentsInvocation(['secrets', ...args], undefined, osForTarget(target, opts.osLookupName));
|
|
157
|
+
// A secret-bearing call (`secret: true`) pins the managed host key and refuses
|
|
158
|
+
// to multiplex — see `credentialTransportSshOpts` (RUSH-2527). A `-tt` session
|
|
159
|
+
// (a remote reveal/passphrase prompt) additionally allocates a PTY and never
|
|
160
|
+
// multiplexes, and it COMPOSES with the secret posture: a `view --reveal` over
|
|
161
|
+
// `--host` both prompts AND streams the plaintext value back over ssh stdout,
|
|
162
|
+
// so it needs the managed host-key pin too — `tty` must not short-circuit past
|
|
163
|
+
// `secret`. A plain browse `list` passes neither and keeps the shared baseline.
|
|
164
|
+
const posture = opts.secret ? credentialTransportSshOpts(target) : {};
|
|
165
|
+
const conn = opts.tty
|
|
166
|
+
? { ...posture, extraSshArgs: ['-tt'], multiplex: false }
|
|
167
|
+
: posture;
|
|
131
168
|
return sshExec(target, remoteCmd, {
|
|
132
169
|
timeoutMs: REMOTE_TIMEOUT_MS,
|
|
133
170
|
input: opts.input,
|
|
134
|
-
|
|
135
|
-
multiplex: opts.tty ? false : undefined,
|
|
171
|
+
...conn,
|
|
136
172
|
});
|
|
137
173
|
}
|
|
138
174
|
/**
|
|
@@ -150,7 +186,10 @@ export function remoteSecretsRaw(target, args, opts = {}) {
|
|
|
150
186
|
*/
|
|
151
187
|
export function remoteSecretsStream(target, args, opts = {}) {
|
|
152
188
|
const remoteCmd = buildRemoteAgentsInvocation(['secrets', ...args], undefined, osForTarget(target, opts.osLookupName));
|
|
153
|
-
|
|
189
|
+
// `unlock --host` carries the remote bundle's passphrase to the destination over
|
|
190
|
+
// this interactive channel, so it is secret-bearing: pin the managed host key
|
|
191
|
+
// (a changed key is refused) and never multiplex (RUSH-2527).
|
|
192
|
+
return sshStream(target, remoteCmd, { tty: true, ...credentialTransportSshOpts(target) });
|
|
154
193
|
}
|
|
155
194
|
/**
|
|
156
195
|
* Resolve a remote bundle to a plaintext env map by driving the remote's
|
|
@@ -168,8 +207,12 @@ export function remoteSecretsStream(target, args, opts = {}) {
|
|
|
168
207
|
export async function remoteResolveEnv(target, bundle, opts = {}) {
|
|
169
208
|
assertValidSshTarget(target);
|
|
170
209
|
const remoteCmd = buildRemoteAgentsInvocation(['secrets', 'export', bundle, '--plaintext', '--format', 'json'], undefined, osForTarget(target, opts.osLookupName));
|
|
210
|
+
// Resolving a remote bundle streams its plaintext values back over ssh stdout,
|
|
211
|
+
// so this read is secret-bearing: pin the managed host key and never leave a
|
|
212
|
+
// reusable control master to the source (RUSH-2527, `credentialTransportSshOpts`).
|
|
171
213
|
const res = sshExec(target, remoteCmd, {
|
|
172
214
|
timeoutMs: REMOTE_TIMEOUT_MS,
|
|
215
|
+
...credentialTransportSshOpts(target),
|
|
173
216
|
});
|
|
174
217
|
if (res.code !== 0) {
|
|
175
218
|
const msg = (res.stderr || res.stdout || '').trim();
|
|
@@ -317,7 +360,14 @@ export function keychainWriteFailureMessage(host, bundle, reason) {
|
|
|
317
360
|
*/
|
|
318
361
|
export function verifyRemoteKeychainPush(target, bundle, pushedKeys, opts = {}) {
|
|
319
362
|
const remoteCmd = buildRemoteAgentsInvocation(['secrets', 'export', bundle, '--plaintext', '--format', 'json'], undefined, osForTarget(target, opts.osLookupName));
|
|
320
|
-
|
|
363
|
+
// This read-back streams the just-pushed plaintext over ssh stdout, so it is
|
|
364
|
+
// as secret-bearing as the push itself — the push path passes `secret: true`
|
|
365
|
+
// so it too pins the managed host key and leaves no reusable control master to
|
|
366
|
+
// the destination (RUSH-2527).
|
|
367
|
+
const res = sshExec(target, remoteCmd, {
|
|
368
|
+
timeoutMs: REMOTE_TIMEOUT_MS,
|
|
369
|
+
...(opts.secret ? credentialTransportSshOpts(target) : {}),
|
|
370
|
+
});
|
|
321
371
|
if (res.code !== 0) {
|
|
322
372
|
const why = res.timedOut ? 'timed out' : res.code === null ? 'ssh failed' : `exit ${res.code}`;
|
|
323
373
|
const stderr = `${why}${(res.stderr || res.stdout || '').trim() ? `: ${(res.stderr || res.stdout).trim()}` : ''}`;
|
|
@@ -12,6 +12,14 @@
|
|
|
12
12
|
* to PATH resolution.
|
|
13
13
|
*/
|
|
14
14
|
export declare const NPM_PACKAGE_NAME = "@phnx-labs/agents-cli";
|
|
15
|
+
/**
|
|
16
|
+
* First published release that stopped the usage/auth-health probe from reading
|
|
17
|
+
* Claude Code's interactive login (commit 3f3554c51). Pre-this versions on a
|
|
18
|
+
* macOS box re-introduce the Touch ID storm + fleet-wide revocation class
|
|
19
|
+
* (RUSH-2415 / RUSH-1822). Anything older is a latent regression while a fixed
|
|
20
|
+
* copy sits next to it.
|
|
21
|
+
*/
|
|
22
|
+
export declare const TOUCH_ID_STORM_FIXED_SINCE = "1.22.30";
|
|
15
23
|
export type PackageManager = 'npm' | 'bun';
|
|
16
24
|
/**
|
|
17
25
|
* The directory bun installs global packages into:
|
|
@@ -55,6 +63,44 @@ export declare function saveUpdateCheck(file: string, latestVersion: string): vo
|
|
|
55
63
|
export declare function dismissUpdateVersion(file: string, version: string): void;
|
|
56
64
|
/** Whether the cached state warrants an upgrade prompt for a copy running `currentVersion`. */
|
|
57
65
|
export declare function shouldPromptUpgrade(cache: UpdateCheckCache | null, currentVersion: string): boolean;
|
|
66
|
+
/**
|
|
67
|
+
* Short TTL for the multi-install PATH scan cache (RUSH-2324). The full
|
|
68
|
+
* `findAgentsCliInstalls` walk over PATH + known roots costs ~1ms on a warm
|
|
69
|
+
* box and runs on every ordinary CLI invocation via `maybeWarnMultiInstall`.
|
|
70
|
+
* Same 5-minute window as the detached-sync spawn gate so both bootstrap
|
|
71
|
+
* savings share one recency policy.
|
|
72
|
+
*/
|
|
73
|
+
export declare const MULTI_INSTALL_SCAN_TTL_MS: number;
|
|
74
|
+
/** On-disk shape for the multi-install scan cache (beside `.update-check`). */
|
|
75
|
+
export interface MultiInstallScanCache {
|
|
76
|
+
scannedAt: number;
|
|
77
|
+
/** Full PATH string at scan time — any change invalidates the cache. */
|
|
78
|
+
pathEnv: string;
|
|
79
|
+
runningRoot: string;
|
|
80
|
+
runningVersion: string;
|
|
81
|
+
inventory: MultiInstallInventoryEntry[];
|
|
82
|
+
}
|
|
83
|
+
/** Read a multi-install scan cache. Returns null if missing or corrupt. */
|
|
84
|
+
export declare function readMultiInstallScanCache(file: string): MultiInstallScanCache | null;
|
|
85
|
+
/** Persist a multi-install scan result. Best-effort. */
|
|
86
|
+
export declare function writeMultiInstallScanCache(file: string, cache: MultiInstallScanCache): void;
|
|
87
|
+
/**
|
|
88
|
+
* Whether a multi-install scan cache is still usable for this invocation.
|
|
89
|
+
* Invalid when missing, past TTL, PATH changed, or the running copy identity
|
|
90
|
+
* (root / version) changed — those are exactly the cases where a re-scan can
|
|
91
|
+
* surface a different inventory and re-fire the warning.
|
|
92
|
+
*/
|
|
93
|
+
export declare function isMultiInstallScanFresh(cache: MultiInstallScanCache | null, pathEnv: string, runningRoot: string, runningVersion: string, now?: number, ttlMs?: number): boolean;
|
|
94
|
+
/**
|
|
95
|
+
* Resolve the multi-install inventory, hitting the on-disk scan cache when
|
|
96
|
+
* fresh. Callers that only need the inventory (the bootstrap multi-install
|
|
97
|
+
* warning) avoid the ~1ms PATH walk on the warm path (RUSH-2324).
|
|
98
|
+
*/
|
|
99
|
+
export declare function resolveMultiInstallInventory(runningRoot: string, runningVersion: string, pathEnv: string, cacheFile: string, opts?: {
|
|
100
|
+
now?: number;
|
|
101
|
+
ttlMs?: number;
|
|
102
|
+
findOpts?: FindAgentsCliInstallsOptions;
|
|
103
|
+
}): MultiInstallInventoryEntry[];
|
|
58
104
|
/**
|
|
59
105
|
* The on-disk package root of the copy that is currently running.
|
|
60
106
|
*
|
|
@@ -156,6 +202,68 @@ export interface MultiInstallInventoryEntry {
|
|
|
156
202
|
note: string;
|
|
157
203
|
}
|
|
158
204
|
export declare function buildMultiInstallInventory(runningRoot: string, runningVersion: string, installs: AgentsCliInstall[]): MultiInstallInventoryEntry[];
|
|
205
|
+
/** Why a discovered install is safe to delete without an interactive confirm. */
|
|
206
|
+
export type RemovableInstallReason = 'npx-cache' | 'unsafe-legacy-helper' | 'pre-fixed-version';
|
|
207
|
+
export interface RemovableAgentsCliInstall {
|
|
208
|
+
packageRoot: string;
|
|
209
|
+
version: string;
|
|
210
|
+
reasons: RemovableInstallReason[];
|
|
211
|
+
}
|
|
212
|
+
export interface PurgeRemovableInstallsResult {
|
|
213
|
+
removed: RemovableAgentsCliInstall[];
|
|
214
|
+
failed: Array<RemovableAgentsCliInstall & {
|
|
215
|
+
error: string;
|
|
216
|
+
}>;
|
|
217
|
+
skippedRunning: number;
|
|
218
|
+
}
|
|
219
|
+
/** True when the package root lives under npm's `_npx` cache (ephemeral runs). */
|
|
220
|
+
export declare function isNpxCacheInstall(packageRoot: string): boolean;
|
|
221
|
+
/**
|
|
222
|
+
* A release string that is at least TOUCH_ID_STORM_FIXED_SINCE, or a side-by-side
|
|
223
|
+
* dev build (`0.0.0-dev.*`) which tracks main and therefore carries the fix.
|
|
224
|
+
* Non-semver junk never qualifies as "fixed" — better to leave a weird copy
|
|
225
|
+
* alone than delete the only working install.
|
|
226
|
+
*/
|
|
227
|
+
export declare function isTouchIdStormFixedVersion(version: string): boolean;
|
|
228
|
+
/**
|
|
229
|
+
* Classify discovered installs that doctor --fix / upgrade may delete.
|
|
230
|
+
*
|
|
231
|
+
* Never marks the running package root. Auto-purge is limited to copies that
|
|
232
|
+
* cannot be the intended primary install:
|
|
233
|
+
* - npx-cache trees (ephemeral)
|
|
234
|
+
* - pre-atomic-helper-installer trees ("unsafe legacy helper installer")
|
|
235
|
+
* - pre-TOUCH_ID_STORM_FIXED_SINCE trees, but only when at least one fixed
|
|
236
|
+
* copy already exists on the box (so we never strand the machine)
|
|
237
|
+
*
|
|
238
|
+
* A pre-fixed copy that is also the only install stays — the user must upgrade
|
|
239
|
+
* it in place rather than delete it.
|
|
240
|
+
*/
|
|
241
|
+
export declare function classifyRemovableAgentsCliInstalls(runningRoot: string, installs: AgentsCliInstall[], opts?: {
|
|
242
|
+
fixedSince?: string;
|
|
243
|
+
}): RemovableAgentsCliInstall[];
|
|
244
|
+
/**
|
|
245
|
+
* Delete classified removable package roots from disk. Re-reads package.json
|
|
246
|
+
* immediately before the unlink so a path that is no longer @phnx-labs/agents-cli
|
|
247
|
+
* is never removed. Best-effort: one failure does not stop the rest.
|
|
248
|
+
*/
|
|
249
|
+
export declare function purgeRemovableAgentsCliInstalls(candidates: RemovableAgentsCliInstall[], opts?: {
|
|
250
|
+
dryRun?: boolean;
|
|
251
|
+
runningRoot?: string;
|
|
252
|
+
}): PurgeRemovableInstallsResult;
|
|
253
|
+
/**
|
|
254
|
+
* Scan + classify + purge in one call. Used by `agents doctor --fix` and
|
|
255
|
+
* `agents upgrade` so both paths remediate the same set of latent copies.
|
|
256
|
+
*/
|
|
257
|
+
export declare function remediateStaleAgentsCliInstalls(opts: {
|
|
258
|
+
runningRoot: string;
|
|
259
|
+
runningVersion?: string;
|
|
260
|
+
pathEnv?: string;
|
|
261
|
+
findOpts?: FindAgentsCliInstallsOptions;
|
|
262
|
+
dryRun?: boolean;
|
|
263
|
+
}): PurgeRemovableInstallsResult & {
|
|
264
|
+
inventory: MultiInstallInventoryEntry[];
|
|
265
|
+
candidates: RemovableAgentsCliInstall[];
|
|
266
|
+
};
|
|
159
267
|
/**
|
|
160
268
|
* Resolve every `agents` entrypoint on PATH, then inspect the bounded global
|
|
161
269
|
* install layouts used by NVM, fnm, Volta, Bun, npm, and npx. More than one
|