@phnx-labs/agents-cli 1.22.35 → 1.22.37
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 +666 -2
- package/README.md +75 -35
- package/dist/bin/agents +0 -0
- package/dist/bootstrap.d.ts +15 -0
- package/dist/bootstrap.js +1211 -0
- package/dist/commands/accounts.d.ts +4 -11
- package/dist/commands/accounts.js +159 -27
- 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 +15 -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 +85 -41
- 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 +4 -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/set.d.ts +1 -1
- package/dist/commands/set.js +2 -2
- 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-share.js +34 -4
- package/dist/commands/setup.d.ts +5 -0
- package/dist/commands/setup.js +26 -0
- package/dist/commands/share.d.ts +67 -0
- package/dist/commands/share.js +275 -12
- 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/ipc.d.ts +30 -0
- package/dist/lib/browser/ipc.js +81 -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 +4 -0
- package/dist/lib/browser/service.js +30 -3
- 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 +19 -0
- 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 +20 -6
- package/dist/lib/git.js +121 -17
- 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 +41 -6
- 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/config.d.ts +4 -0
- package/dist/lib/share/config.js +1 -0
- package/dist/lib/share/provision.d.ts +38 -0
- package/dist/lib/share/provision.js +50 -0
- package/dist/lib/share/publish.d.ts +40 -1
- package/dist/lib/share/publish.js +116 -3
- package/dist/lib/share/worker-template.js +71 -6
- 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 +6 -12
- package/dist/lib/startup/command-registry.js +11 -31
- 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 +320 -0
- package/dist/lib/tmux/orphan-reap.js +644 -0
- package/dist/lib/tmux/session.d.ts +68 -3
- package/dist/lib/tmux/session.js +95 -5
- package/dist/lib/triggers/handlers.d.ts +20 -0
- package/dist/lib/triggers/handlers.js +6 -1
- package/dist/lib/types.d.ts +46 -34
- 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/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/commands/events.js
CHANGED
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* `agents events` — read the unified event stream.
|
|
2
|
+
* `agents events` — read the unified event stream (the one ops/timeline product).
|
|
3
3
|
*
|
|
4
|
-
* One stream over BOTH operational events (`~/.agents/.history/events/YYYY-MM-DD/`:
|
|
5
|
-
* `agents <module> <cmd>` invocation plus typed events like secrets access,
|
|
6
|
-
* version installs) AND agent-semantic events
|
|
7
|
-
* plans, PRs, worktrees, sub-agents, artifacts).
|
|
8
|
-
*
|
|
9
|
-
* created a team" AND the activity trail for "what did the agents just do".
|
|
4
|
+
* One stream over BOTH operational events (`~/.agents/.history/events/YYYY-MM-DD/`:
|
|
5
|
+
* every `agents <module> <cmd>` invocation plus typed events like secrets access,
|
|
6
|
+
* browser/computer, daemon lifecycle, version installs) AND agent-semantic events
|
|
7
|
+
* (per-session activity: plans, PRs, worktrees, sub-agents, artifacts). Run-dispatch
|
|
8
|
+
* outcomes land here as `run.dispatched` (readable via `--include runs`).
|
|
10
9
|
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
10
|
+
* `agents audit` and `agents logs` are thin aliases of this command.
|
|
11
|
+
*
|
|
12
|
+
* Filter with sessions-style `--include` / `--exclude` families (ops, activity,
|
|
13
|
+
* commands, runs, security) plus field filters (`--module`, `--event`, …).
|
|
15
14
|
*/
|
|
16
15
|
import chalk from 'chalk';
|
|
17
16
|
import * as fs from 'fs';
|
|
18
|
-
import { getLogsPath } from '../lib/events.js';
|
|
17
|
+
import { getLogsPath, stats, rotate } from '../lib/events.js';
|
|
19
18
|
import { readUnifiedEvents } from '../lib/event-stream.js';
|
|
19
|
+
import { parseFamilyList, EVENT_FAMILIES } from '../lib/event-families.js';
|
|
20
20
|
import { ingestBatch } from '../lib/events-ingest.js';
|
|
21
21
|
import { setHelpSections } from '../lib/help.js';
|
|
22
22
|
/**
|
|
@@ -86,6 +86,15 @@ function detailFor(r) {
|
|
|
86
86
|
bits.push(`skill=${r.skill}`);
|
|
87
87
|
if (typeof r.version === 'string')
|
|
88
88
|
bits.push(`v=${r.version}`);
|
|
89
|
+
// run.dispatched (and similar) — mode / outcome / exit / repo are the audit line.
|
|
90
|
+
if (typeof r.mode === 'string')
|
|
91
|
+
bits.push(`mode=${r.mode}`);
|
|
92
|
+
if (typeof r.outcome === 'string')
|
|
93
|
+
bits.push(`outcome=${r.outcome}`);
|
|
94
|
+
if (typeof r.exitCode === 'number')
|
|
95
|
+
bits.push(`exit=${r.exitCode}`);
|
|
96
|
+
if (typeof r.repo === 'string')
|
|
97
|
+
bits.push(chalk.gray(r.repo));
|
|
89
98
|
if (typeof r.profile === 'string')
|
|
90
99
|
bits.push(`profile=${r.profile}`);
|
|
91
100
|
if (typeof r.error === 'string')
|
|
@@ -187,9 +196,11 @@ function registerEmitSubcommand(events) {
|
|
|
187
196
|
/** Add the one canonical event-reader option surface to a command or alias. */
|
|
188
197
|
export function addEventsReadOptions(command, includeAuditFlag = true) {
|
|
189
198
|
command
|
|
190
|
-
.option('--
|
|
199
|
+
.option('--include <families>', `Only these families (comma-sep): ${EVENT_FAMILIES.join(', ')}`)
|
|
200
|
+
.option('--exclude <families>', `Drop these families (comma-sep): ${EVENT_FAMILIES.join(', ')}`)
|
|
201
|
+
.option('--module <name>', 'Only events from this group (e.g. teams, secrets, activity, daemon, routine, watchdog, browser)')
|
|
191
202
|
.option('--command <path>', 'Only this command path — prefix match (e.g. "teams create")')
|
|
192
|
-
.option('--event <type>', 'Only this typed event (repeatable, e.g. secrets.get,
|
|
203
|
+
.option('--event <type>', 'Only this typed event (repeatable, e.g. secrets.get, run.dispatched, pr.opened)', collect, [])
|
|
193
204
|
.option('--agent <name>', 'Only events tagged with this agent')
|
|
194
205
|
.option('--caller <kind>', 'Only this caller kind (claude-code, codex, gemini, cursor, terminal, script)')
|
|
195
206
|
.option('--level <level>', 'Only this level: audit, warn, info, debug')
|
|
@@ -199,11 +210,12 @@ export function addEventsReadOptions(command, includeAuditFlag = true) {
|
|
|
199
210
|
.option('--limit <n>', 'Max records to show; 0 for no cap (default 50)', '50')
|
|
200
211
|
.option('--json', 'Output raw records as JSON')
|
|
201
212
|
.option('-f, --follow', "Tail today's operational log live");
|
|
202
|
-
if (includeAuditFlag)
|
|
203
|
-
command.option('--audit', '
|
|
213
|
+
if (includeAuditFlag) {
|
|
214
|
+
command.option('--audit', 'Deprecated: operational events only — prefer --include ops or --exclude activity');
|
|
215
|
+
}
|
|
204
216
|
return command;
|
|
205
217
|
}
|
|
206
|
-
/** Canonical reader used by
|
|
218
|
+
/** Canonical reader used by `agents events`, `agents audit`, and `agents logs`. */
|
|
207
219
|
export async function runEventsCommand(options, forceAudit = false) {
|
|
208
220
|
if (options.follow) {
|
|
209
221
|
await followLog();
|
|
@@ -211,15 +223,29 @@ export async function runEventsCommand(options, forceAudit = false) {
|
|
|
211
223
|
}
|
|
212
224
|
let limit;
|
|
213
225
|
let startDate;
|
|
226
|
+
let includeFamilies;
|
|
227
|
+
let excludeFamilies;
|
|
214
228
|
try {
|
|
215
229
|
limit = resolveEventsLimit(options.limit);
|
|
216
230
|
startDate = options.since ? parseSince(options.since) : undefined;
|
|
231
|
+
if (options.include && options.exclude) {
|
|
232
|
+
throw new Error('--include and --exclude are mutually exclusive');
|
|
233
|
+
}
|
|
234
|
+
if (options.include)
|
|
235
|
+
includeFamilies = parseFamilyList(options.include, '--include');
|
|
236
|
+
if (options.exclude)
|
|
237
|
+
excludeFamilies = parseFamilyList(options.exclude, '--exclude');
|
|
217
238
|
}
|
|
218
239
|
catch (err) {
|
|
219
240
|
console.error(chalk.red(err.message));
|
|
220
241
|
process.exitCode = 2;
|
|
221
242
|
return;
|
|
222
243
|
}
|
|
244
|
+
// --audit / forceAudit = ops-only when no family flags. Families own the
|
|
245
|
+
// source selection via applyFamilies — never override includeActivity after.
|
|
246
|
+
const includeActivity = (includeFamilies !== undefined || excludeFamilies !== undefined)
|
|
247
|
+
? true
|
|
248
|
+
: !(forceAudit || options.audit);
|
|
223
249
|
const fetched = readUnifiedEvents({
|
|
224
250
|
startDate,
|
|
225
251
|
eventTypes: options.event && options.event.length ? options.event : undefined,
|
|
@@ -231,7 +257,9 @@ export async function runEventsCommand(options, forceAudit = false) {
|
|
|
231
257
|
command: options.command,
|
|
232
258
|
module: options.module,
|
|
233
259
|
limit: limit === undefined ? undefined : limit + 1,
|
|
234
|
-
includeActivity
|
|
260
|
+
includeActivity,
|
|
261
|
+
includeFamilies,
|
|
262
|
+
excludeFamilies,
|
|
235
263
|
});
|
|
236
264
|
const { records, truncated } = capRecords(fetched, limit);
|
|
237
265
|
const capNote = `Showing the newest ${limit} — more events matched. Pass --limit 0 for all.`;
|
|
@@ -251,29 +279,117 @@ export async function runEventsCommand(options, forceAudit = false) {
|
|
|
251
279
|
if (truncated)
|
|
252
280
|
console.log(chalk.yellow(capNote));
|
|
253
281
|
}
|
|
282
|
+
function humanBytes(bytes) {
|
|
283
|
+
if (bytes < 1024)
|
|
284
|
+
return `${bytes} B`;
|
|
285
|
+
if (bytes < 1024 * 1024)
|
|
286
|
+
return `${(bytes / 1024).toFixed(1)} KB`;
|
|
287
|
+
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
288
|
+
}
|
|
289
|
+
function levelColor(level) {
|
|
290
|
+
if (level === 'audit')
|
|
291
|
+
return chalk.magenta(level);
|
|
292
|
+
if (level === 'warn')
|
|
293
|
+
return chalk.yellow(level);
|
|
294
|
+
if (level === 'debug')
|
|
295
|
+
return chalk.gray(level);
|
|
296
|
+
return chalk.blue(level);
|
|
297
|
+
}
|
|
298
|
+
/** Shared by `events stats` and the `logs stats` alias. */
|
|
299
|
+
export async function runEventsStats(opts) {
|
|
300
|
+
let days = 7;
|
|
301
|
+
if (opts.since) {
|
|
302
|
+
try {
|
|
303
|
+
const d = parseSince(opts.since);
|
|
304
|
+
days = Math.max(1, Math.ceil((Date.now() - d.getTime()) / 86_400_000));
|
|
305
|
+
}
|
|
306
|
+
catch (err) {
|
|
307
|
+
console.error(chalk.red(err.message));
|
|
308
|
+
process.exitCode = 2;
|
|
309
|
+
return;
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
const s = stats({ days });
|
|
313
|
+
if (opts.json) {
|
|
314
|
+
console.log(JSON.stringify(s, null, 2));
|
|
315
|
+
return;
|
|
316
|
+
}
|
|
317
|
+
console.log(chalk.bold(`Event statistics (last ${days} day${days === 1 ? '' : 's'})\n`));
|
|
318
|
+
console.log(` Total events: ${s.totalEvents}`);
|
|
319
|
+
console.log(` Log files: ${s.fileCount} (${humanBytes(s.totalBytes)})`);
|
|
320
|
+
console.log(` Log path: ${chalk.gray(getLogsPath())}`);
|
|
321
|
+
if (Object.keys(s.byLevel).length) {
|
|
322
|
+
console.log(chalk.bold('\n By level:'));
|
|
323
|
+
for (const [k, v] of Object.entries(s.byLevel).sort((a, b) => b[1] - a[1])) {
|
|
324
|
+
console.log(` ${levelColor(k).padEnd(20)} ${v}`);
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
if (Object.keys(s.byEvent).length) {
|
|
328
|
+
console.log(chalk.bold('\n By event (top 15):'));
|
|
329
|
+
for (const [k, v] of Object.entries(s.byEvent).sort((a, b) => b[1] - a[1]).slice(0, 15)) {
|
|
330
|
+
console.log(` ${chalk.cyan(k).padEnd(30)} ${v}`);
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
if (Object.keys(s.byModule).length) {
|
|
334
|
+
console.log(chalk.bold('\n By module:'));
|
|
335
|
+
for (const [k, v] of Object.entries(s.byModule).sort((a, b) => b[1] - a[1])) {
|
|
336
|
+
console.log(` ${k.padEnd(20)} ${v}`);
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
console.log();
|
|
340
|
+
}
|
|
254
341
|
export function registerEventsCommand(program) {
|
|
255
342
|
const events = addEventsReadOptions(program
|
|
256
343
|
.command('events')
|
|
257
|
-
.description('Read the unified event stream (
|
|
344
|
+
.description('Read the unified event stream (ops + activity + run dispatch)'))
|
|
258
345
|
.addHelpText('after', `
|
|
259
346
|
Examples:
|
|
260
347
|
agents events Everything — ops + agent activity
|
|
261
|
-
agents events --
|
|
262
|
-
agents events --
|
|
263
|
-
agents events --
|
|
348
|
+
agents events --exclude commands Drop CLI command.start/end noise
|
|
349
|
+
agents events --include runs Dispatched-run outcomes (was audit list)
|
|
350
|
+
agents events --include activity Agent milestones only
|
|
351
|
+
agents events --include ops Operational events only
|
|
352
|
+
agents events --include security Audit-level (secrets, command.*, daemon, …)
|
|
264
353
|
agents events --module secrets Every secret accessed or revealed
|
|
265
354
|
agents events --module secrets --bundle share
|
|
266
|
-
|
|
267
|
-
agents events --bundle share --session <id>
|
|
268
|
-
Trace one session's reads of a bundle
|
|
355
|
+
agents events --event pr.opened --since 7d
|
|
269
356
|
agents events -f Live tail (operational)
|
|
270
|
-
agents events
|
|
271
|
-
|
|
272
|
-
|
|
357
|
+
agents events stats
|
|
358
|
+
agents events rotate --days 7
|
|
359
|
+
|
|
360
|
+
agents audit Alias of: events --include runs
|
|
361
|
+
agents logs Alias of: events`)
|
|
273
362
|
.action((_options, command) => runEventsCommand(command.optsWithGlobals()));
|
|
274
363
|
// `events` both reads (its own action, above) and writes (this subcommand) —
|
|
275
364
|
// the same shape as `feed` / `feed post`.
|
|
276
365
|
registerEmitSubcommand(events);
|
|
366
|
+
events
|
|
367
|
+
.command('stats')
|
|
368
|
+
.description('Show aggregate event statistics')
|
|
369
|
+
.option('--since <time>', 'Window size (e.g. 7d, 30d; default 7d)')
|
|
370
|
+
.option('--json', 'Output stats as JSON')
|
|
371
|
+
.action(async (opts) => runEventsStats(opts));
|
|
372
|
+
events
|
|
373
|
+
.command('rotate')
|
|
374
|
+
.description('Apply event retention and the storage ceiling immediately')
|
|
375
|
+
.option('--days <n>', 'Retention period in days (default 7)', '7')
|
|
376
|
+
.option('--max-mb <n>', 'Total event storage ceiling in MiB (default 50)', '50')
|
|
377
|
+
.action((opts) => runEventsRotate(opts));
|
|
378
|
+
}
|
|
379
|
+
/** Shared by `events rotate` and the `logs rotate` alias. */
|
|
380
|
+
export function runEventsRotate(opts) {
|
|
381
|
+
const days = Math.max(1, parseInt(opts.days ?? '7', 10) || 7);
|
|
382
|
+
const maxMb = Math.max(1, parseInt(opts.maxMb ?? '50', 10) || 50);
|
|
383
|
+
const result = rotate(days, maxMb * 1024 * 1024);
|
|
384
|
+
const removed = result.removedByAge + result.removedBySize;
|
|
385
|
+
if (removed > 0) {
|
|
386
|
+
console.log(`Removed ${removed} event file${removed === 1 ? '' : 's'} ` +
|
|
387
|
+
`(${result.removedByAge} by age, ${result.removedBySize} by size); ` +
|
|
388
|
+
`reclaimed ${humanBytes(result.bytesReclaimed)}.`);
|
|
389
|
+
}
|
|
390
|
+
else {
|
|
391
|
+
console.log(chalk.gray(`No event files removed (retention ${days} days, ceiling ${maxMb} MiB).`));
|
|
392
|
+
}
|
|
277
393
|
}
|
|
278
394
|
/** commander repeatable-option collector. */
|
|
279
395
|
function collect(value, previous) {
|
package/dist/commands/exec.js
CHANGED
|
@@ -11,12 +11,13 @@ import { isTierToken } from '../lib/model-tiers.js';
|
|
|
11
11
|
import { RUN_AUTO_KEYWORD } from '../lib/types.js';
|
|
12
12
|
import { setHelpSections } from '../lib/help.js';
|
|
13
13
|
import { isInteractiveTerminal, isPromptCancelled, requireInteractiveSelection } from './utils.js';
|
|
14
|
-
import { getUserAgentsDir } from '../lib/state.js';
|
|
14
|
+
import { getUserAgentsDir, readMeta } from '../lib/state.js';
|
|
15
15
|
import { parseLoopInterval } from '../lib/loop.js';
|
|
16
16
|
import { AGENTS, resolveAgentName, isAgentHardDeprecated, hardDeprecationError } from '../lib/agents.js';
|
|
17
17
|
import { recordDispatchedRun } from '../lib/audit/log.js';
|
|
18
18
|
import { maybeShowStarNudge } from '../lib/star-nudge.js';
|
|
19
19
|
import { warnUnpushedWork, shouldWarnUnpushed } from '../lib/warn-unpushed.js';
|
|
20
|
+
import { warnOrphanedOpenPr } from '../lib/pr-land-detach.js';
|
|
20
21
|
import { isHostPinned, pinHostKey, managedKnownHostsPath } from '../lib/devices/known-hosts.js';
|
|
21
22
|
import { sshResolve } from '../lib/hosts/ssh-config.js';
|
|
22
23
|
import * as fs from 'fs';
|
|
@@ -401,6 +402,13 @@ export async function runWorkflowForEach(spec, opts) {
|
|
|
401
402
|
* the directory and is mutually exclusive with `--cwd`/`--remote-cwd`; both the
|
|
402
403
|
* main dispatch and the `--terminal` handoff need the same answer, so the rule
|
|
403
404
|
* and its error live here once instead of in two places that can drift.
|
|
405
|
+
*
|
|
406
|
+
* A project that binds several directories also contributes the ones it is not
|
|
407
|
+
* landing in as `--add-dir` grants, so an agent on a multi-repo project can
|
|
408
|
+
* actually reach the sibling checkouts. Claude / Cursor / Kimi take the native
|
|
409
|
+
* flag; Codex folds them into workspace_roots; Grok widens its sandbox profile
|
|
410
|
+
* (and always injects a rules note). Other harnesses have no multi-root surface
|
|
411
|
+
* and ignore the grants (cwd only).
|
|
404
412
|
*/
|
|
405
413
|
async function resolveRunCwd(options, opts) {
|
|
406
414
|
if (!options.project)
|
|
@@ -409,9 +417,18 @@ async function resolveRunCwd(options, opts) {
|
|
|
409
417
|
console.error(chalk.red('Pass --project alone — not with --cwd or --remote-cwd.'));
|
|
410
418
|
process.exit(1);
|
|
411
419
|
}
|
|
412
|
-
const {
|
|
420
|
+
const { resolveProjectDirs } = await import('../lib/project-root.js');
|
|
413
421
|
try {
|
|
414
|
-
|
|
422
|
+
const { cwd, extraDirs } = await resolveProjectDirs(options.project, {
|
|
423
|
+
forRemote: opts.forRemote,
|
|
424
|
+
});
|
|
425
|
+
// Explicit --add-dir values keep their position; a directory the project
|
|
426
|
+
// already contributes is not passed twice.
|
|
427
|
+
if (extraDirs.length > 0) {
|
|
428
|
+
const seen = new Set(options.addDir ?? []);
|
|
429
|
+
options.addDir = [...(options.addDir ?? []), ...extraDirs.filter((d) => !seen.has(d))];
|
|
430
|
+
}
|
|
431
|
+
return cwd;
|
|
415
432
|
}
|
|
416
433
|
catch (err) {
|
|
417
434
|
console.error(chalk.red(err.message));
|
|
@@ -527,7 +544,7 @@ export function registerRunCommand(program) {
|
|
|
527
544
|
.option('--allow-expired', 'Inject secrets even if their expiry date has passed (overrides the pre-run expiry abort).')
|
|
528
545
|
.option('--cwd <dir>', 'Working directory for the agent (defaults to current directory). With --host, the directory ON the host.')
|
|
529
546
|
.option('-P, --project <ref>', 'Project shorthand <slug>[@worktree], resolved against your projects root (auto-inferred, cached). Sets the cwd locally or on --host.')
|
|
530
|
-
.option('--add-dir <dir>', 'Grant access to an additional directory outside the project (Claude
|
|
547
|
+
.option('--add-dir <dir>', 'Grant access to an additional directory outside the project (Claude, Codex, Cursor, Kimi, Grok; repeatable)', (val, prev) => [...prev, val], [])
|
|
531
548
|
.option('--json', 'Stream events as JSON lines (for parsing by other tools)')
|
|
532
549
|
.option('--quiet', 'Suppress preamble (rotation banner, "Running:" line). Useful when piping JSON events to a parser.', false)
|
|
533
550
|
.option('--headless', 'Force headless mode. Auto-enabled when a prompt is provided; pass explicitly to stay headless with no prompt (reads the prompt from stdin).', false)
|
|
@@ -535,7 +552,7 @@ export function registerRunCommand(program) {
|
|
|
535
552
|
.option('-i, --interactive', 'Force interactive mode even when a prompt is provided. Mutually exclusive with --headless.')
|
|
536
553
|
.option('--resume [id]', 'Recover a previous conversation on its origin device. The exact healthy origin uses native resume; otherwise a healthy version of the same harness replays via /continue. Pair with a prompt to continue headlessly.')
|
|
537
554
|
.option('--session-id <id>', 'Force a NEW conversation to use this exact session UUID (Claude only). This CREATES a session — to resume an existing one, use --resume.')
|
|
538
|
-
.option('--name <slug>', 'Name the run — seeds the session label so it shows up as `<name>` in `agents sessions` and resolves by it (and `agents
|
|
555
|
+
.option('--name <slug>', 'Name the run — seeds the session label so it shows up as `<name>` in `agents sessions` and resolves by it (and `agents logs <name>` for --host runs) instead of an opaque id. An agent-generated title later refines the label; your name shows until then. Optional.')
|
|
539
556
|
.option('--notify', 'Post a desktop notification when a headless run finishes. Fired by this process on exit, so it survives whatever launched the run (the menu bar dispatching it, a terminal you closed).')
|
|
540
557
|
.option('--terminal [backend]', "Open this run in a real terminal tab instead of here. Without a value the terminal is detected from your live sessions (`agents sessions --active` host), so it lands where you already work — Ghostty for a Ghostty user, iTerm for an iTerm user. Name one to force it: iterm | ghostty | terminal | tmux | vscodium-agent. This is how the menu bar's New Session opens.")
|
|
541
558
|
.option('--verbose', 'Show detailed execution logs')
|
|
@@ -546,7 +563,7 @@ export function registerRunCommand(program) {
|
|
|
546
563
|
.option('--fallback <agents>', 'Comma-separated agents to try on rate-limit failure. Each entry accepts an optional @version pin (e.g., codex@0.116.0,antigravity). The primary runs first; if it exits with a rate-limit error, the next agent picks up via /continue handoff.')
|
|
547
564
|
.option('-b, --balanced', 'Shortcut for --strategy balanced. Ignored when @version is pinned.')
|
|
548
565
|
.option('--strategy <strategy>', 'Version/account selection strategy: pinned | available | balanced. Defaults to run.<agent>.strategy, then balanced (spreads load across healthy accounts and skips any that are rate-limited). (Legacy `rotate` accepted as alias for `balanced`.)')
|
|
549
|
-
.option('--account <
|
|
566
|
+
.option('--account <name>', 'Use this durable provider credential for the run')
|
|
550
567
|
.option('--acp', 'Route through the Agent Client Protocol instead of direct exec. Supported for claude via @zed-industries/claude-code-acp adapter. Unified event stream; emits ndjson when --json.')
|
|
551
568
|
.option('-y, --yes', 'Skip the interactive budget-confirm prompt (require_confirm_over). Never skips a hard budget block.', false)
|
|
552
569
|
.option('--loop', 'Re-inject the prompt/entrypoint each iteration until a stop condition (issue #332). Guards (--max-iterations, --budget, --until) are enforced outside the agent. Writes a checkpoint after every iteration for --resume-checkpoint.')
|
|
@@ -555,11 +572,11 @@ export function registerRunCommand(program) {
|
|
|
555
572
|
.option('--budget <tokens>', 'Loop token hard-cap: stop once cumulative tokens reach this (stoppedBy: budget), enforced outside the agent. Loop only.')
|
|
556
573
|
.option('--until <signal>', 'Loop stop condition. `signal` reads <runDir>/loop-signal.json {continue,reason} each iteration; absent or continue:false stops (fail-closed). Loop only.')
|
|
557
574
|
.option('--interval <dur>', 'Loop delay between iterations ("0" back-to-back, "30m" paces). Loop only.')
|
|
558
|
-
.option('--where <spec>', 'Where this run\'s body executes (one placement door): local | device:<name> | auto | lease[:backend] | cloud[:provider]. Expands to --host/--lease/--cloud. Do not combine with those flags. See docs/
|
|
559
|
-
.option('--host <name>', 'Offload this run onto another machine over SSH — a device name, registered host, or user@host. Pass "auto" to pick the least-loaded reachable device
|
|
560
|
-
.option('--device <name>', 'Alias of --host. Pass "auto" for
|
|
575
|
+
.option('--where <spec>', 'Where this run\'s body executes (one placement door): local | device:<name> | auto | lease[:backend] | cloud[:provider]. Expands to --host/--lease/--cloud. Do not combine with those flags. See docs/concepts.md#placement.')
|
|
576
|
+
.option('--host <name>', 'Offload this run onto another machine over SSH — a device name, registered host, or user@host. Pass "auto" to pick the least-loaded reachable device with an eligible account; an unavailable or capped pool fails loud. Same as --where device:<name>. See `agents devices`.')
|
|
577
|
+
.option('--device <name>', 'Alias of --host. Pass "auto" for live health/account-aware device placement.')
|
|
561
578
|
.option('--remote-cwd <dir>', "Explicit host working directory for --host runs, used VERBATIM (overrides --cwd; usually --cwd suffices — it re-roots a local-home path onto the remote home). Pass a single-quoted '$HOME/…' or a valid remote absolute path; a local ~ expands here and won't exist there (/Users/you vs /home/you).")
|
|
562
|
-
.option('--no-follow', 'With --host, dispatch detached and return immediately (track via `agents
|
|
579
|
+
.option('--no-follow', 'With --host, dispatch detached and return immediately (track via `agents devices ps` and `agents logs`).')
|
|
563
580
|
.option('--any', 'With --host <cap> (a capability tag), pick any matching host instead of erroring when several match.')
|
|
564
581
|
.option('--copy-creds', 'With --host, copy the picked runtime credentials (and Claude OAuth token) to the host, then shred them after the run. Opt-in per run.')
|
|
565
582
|
.option('--lease [backend]', "Run on a cloud box (via crabbox) and tear it down after — reuses a warm box from the repo's profile pool when one is ready (--fresh forces a new box). Optional backend selects the cloud (hetzner/aws/do). Same as --where lease[:backend]. Unlike --host, no machine is registered.")
|
|
@@ -609,6 +626,7 @@ export function registerRunCommand(program) {
|
|
|
609
626
|
# account headroom, then a balanced account on it
|
|
610
627
|
agents run auto "fix the flaky test" --mode edit
|
|
611
628
|
agents run auto --host yosemite-s0 "fix the flaky test" # pin the host
|
|
629
|
+
agents run auto --interactive --device auto --strategy balanced --mode auto
|
|
612
630
|
|
|
613
631
|
# Placement (one door — where the body runs). Old flags still work.
|
|
614
632
|
agents run claude "…" --where device:yosemite-s0 # = --host yosemite-s0
|
|
@@ -741,7 +759,7 @@ export function registerRunCommand(program) {
|
|
|
741
759
|
}
|
|
742
760
|
// Placement: --where expands into --host / --lease / --cloud before any
|
|
743
761
|
// dispatch. One door for "where does the body run?" — old flags remain
|
|
744
|
-
// aliases. See lib/placement.ts and docs/
|
|
762
|
+
// aliases. See lib/placement.ts and docs/concepts.md#placement.
|
|
745
763
|
{
|
|
746
764
|
const { placementFromRunFlags, expandPlacementToRunFlags, PlacementError } = await import('../lib/placement.js');
|
|
747
765
|
try {
|
|
@@ -862,8 +880,15 @@ export function registerRunCommand(program) {
|
|
|
862
880
|
? { kind: 'resolved', session: injectedSource }
|
|
863
881
|
: await (await import('./sessions.js')).resolveSessionMetadataValue(selector);
|
|
864
882
|
if (outcome.kind === 'partial') {
|
|
865
|
-
|
|
866
|
-
|
|
883
|
+
// RUSH-2492: an unreachable peer is a warning, not a hard failure. The
|
|
884
|
+
// resolver already resolves an id found on the reachable fleet (SES-9a),
|
|
885
|
+
// so reaching here means the session was not found on any device we
|
|
886
|
+
// COULD reach — it may live on an unreachable peer we could not check.
|
|
887
|
+
const offline = outcome.failedPeers;
|
|
888
|
+
console.error(chalk.yellow(`Warning: ${offline.length} device(s) unreachable, not checked: ${offline.join(', ')}`));
|
|
889
|
+
console.error(chalk.red(`No session matching "${selector}" on any reachable device (${offline.length} unreachable, not checked).`));
|
|
890
|
+
console.error(chalk.gray(' If it lives on an offline box, wake it (agents devices) or run there: agents ssh <device>'));
|
|
891
|
+
process.exit(1);
|
|
867
892
|
}
|
|
868
893
|
if (outcome.kind === 'not-found') {
|
|
869
894
|
console.error(chalk.red(`No session matching "${selector}".`));
|
|
@@ -953,7 +978,7 @@ export function registerRunCommand(program) {
|
|
|
953
978
|
}
|
|
954
979
|
// --device auto / --host auto (and deprecated --smart): live fleet pick.
|
|
955
980
|
// Harness is always the agent the user typed — never auto-picked.
|
|
956
|
-
//
|
|
981
|
+
// Placement failure propagates; an automatic request never becomes local.
|
|
957
982
|
{
|
|
958
983
|
const { applyDeviceAutoToOptions } = await import('../lib/smart-launch.js');
|
|
959
984
|
const result = await applyDeviceAutoToOptions(options, {
|
|
@@ -967,9 +992,6 @@ export function registerRunCommand(program) {
|
|
|
967
992
|
if (!options.quiet && result.deprecationSmart) {
|
|
968
993
|
process.stderr.write(chalk.yellow('[agents] --smart is deprecated; use --device auto\n'));
|
|
969
994
|
}
|
|
970
|
-
if (!options.quiet && result.skipped) {
|
|
971
|
-
process.stderr.write(chalk.yellow(`[agents] device=auto skipped: ${result.skipped} (running local)\n`));
|
|
972
|
-
}
|
|
973
995
|
if (!options.quiet && result.banner) {
|
|
974
996
|
const { hostLabel, deviceHint, acctNote } = result.banner;
|
|
975
997
|
process.stderr.write(chalk.gray(`[agents] device=auto → ${hostLabel}` +
|
|
@@ -1014,7 +1036,7 @@ export function registerRunCommand(program) {
|
|
|
1014
1036
|
const { runLeaseSetup } = await import('./lease.js');
|
|
1015
1037
|
const ok = await runLeaseSetup({ provider: backend ?? 'hetzner' });
|
|
1016
1038
|
if (!ok) {
|
|
1017
|
-
console.error(chalk.yellow('Leasing needs a cloud provider set up. Run `agents lease setup` and retry.'));
|
|
1039
|
+
console.error(chalk.yellow('Leasing needs a cloud provider set up. Run `agents devices lease setup` and retry.'));
|
|
1018
1040
|
process.exit(1);
|
|
1019
1041
|
}
|
|
1020
1042
|
}
|
|
@@ -1108,7 +1130,7 @@ export function registerRunCommand(program) {
|
|
|
1108
1130
|
}
|
|
1109
1131
|
if (!hasKey) {
|
|
1110
1132
|
console.error(chalk.yellow('Tailscale requested but no auth key is configured — falling back to a public-IP lease.'));
|
|
1111
|
-
console.error(chalk.gray('Set one up with `agents lease setup` (mint an EPHEMERAL, pre-authorized, tag:crabbox key), or store CRABBOX_TAILSCALE_AUTH_KEY in a secrets bundle.'));
|
|
1133
|
+
console.error(chalk.gray('Set one up with `agents devices lease setup` (mint an EPHEMERAL, pre-authorized, tag:crabbox key), or store CRABBOX_TAILSCALE_AUTH_KEY in a secrets bundle.'));
|
|
1112
1134
|
netMode = 'public';
|
|
1113
1135
|
}
|
|
1114
1136
|
}
|
|
@@ -1331,7 +1353,7 @@ export function registerRunCommand(program) {
|
|
|
1331
1353
|
process.stderr.write(chalk.dim(log.join('\n')) + '\n');
|
|
1332
1354
|
}
|
|
1333
1355
|
const keptAddr = boxAddress(box);
|
|
1334
|
-
console.error(chalk.gray(toreDown ? `Box ${box.slug} destroyed.` : `Box ${box.slug} kept${keptAddr ? ` (${keptAddr})` : ''}. Stop it: agents lease stop ${box.slug}`));
|
|
1356
|
+
console.error(chalk.gray(toreDown ? `Box ${box.slug} destroyed.` : `Box ${box.slug} kept${keptAddr ? ` (${keptAddr})` : ''}. Stop it: agents devices lease stop ${box.slug}`));
|
|
1335
1357
|
process.exit(exitCode === null ? 1 : exitCode);
|
|
1336
1358
|
}
|
|
1337
1359
|
catch (err) {
|
|
@@ -1567,6 +1589,9 @@ export function registerRunCommand(program) {
|
|
|
1567
1589
|
const isRaw = options.raw || options.tmux === false || options.disableTmux === true;
|
|
1568
1590
|
const { modeForRemoteDispatch } = await import('../lib/codex-policy.js');
|
|
1569
1591
|
const forwardedMode = modeForRemoteDispatch(options.mode, command.getOptionValueSource('mode'));
|
|
1592
|
+
if (process.env.AGENTS_DISPATCH_DEBUG || options.verbose) {
|
|
1593
|
+
process.stderr.write(chalk.gray(`[hosts] dispatch interactive ${runAgent}${runVersion ? `@${runVersion}` : ''} -> ${host.name}\n`));
|
|
1594
|
+
}
|
|
1570
1595
|
const exitCode = await runInteractiveOnHost(host, {
|
|
1571
1596
|
agent: runAgent,
|
|
1572
1597
|
version: resumeId ? undefined : runVersion,
|
|
@@ -1655,6 +1680,9 @@ export function registerRunCommand(program) {
|
|
|
1655
1680
|
// registration all live in the shared helper (lib/hosts/run-target.ts).
|
|
1656
1681
|
const { modeForRemoteDispatch } = await import('../lib/codex-policy.js');
|
|
1657
1682
|
const forwardedMode = modeForRemoteDispatch(options.mode, command.getOptionValueSource('mode'));
|
|
1683
|
+
if (process.env.AGENTS_DISPATCH_DEBUG || options.verbose) {
|
|
1684
|
+
process.stderr.write(chalk.gray(`[hosts] dispatch headless ${runAgent}${runVersion ? `@${runVersion}` : ''} -> ${host.name}\n`));
|
|
1685
|
+
}
|
|
1658
1686
|
const { task, exitCode } = await dispatchPromptToHost(host, {
|
|
1659
1687
|
agent: runAgent,
|
|
1660
1688
|
version: resumeId ? undefined : runVersion,
|
|
@@ -1694,7 +1722,7 @@ export function registerRunCommand(program) {
|
|
|
1694
1722
|
const handle = task.name ?? task.id;
|
|
1695
1723
|
console.log(chalk.green(`Dispatched to ${host.name}${task.name ? ` as "${task.name}"` : ''}.`) + '\n' +
|
|
1696
1724
|
chalk.gray(` Status: agents sessions ${handle}`) + chalk.gray(' (compact digest — use this)') + '\n' +
|
|
1697
|
-
chalk.gray(` Raw log: agents
|
|
1725
|
+
chalk.gray(` Raw log: agents logs ${handle} -f`) + chalk.gray(' (heavy, only if needed)'));
|
|
1698
1726
|
process.exit(0);
|
|
1699
1727
|
}
|
|
1700
1728
|
// -1 = the follow window closed but the run continues on the host (the
|
|
@@ -1796,12 +1824,16 @@ export function registerRunCommand(program) {
|
|
|
1796
1824
|
cwd: resumeExec.cwd ?? process.cwd(),
|
|
1797
1825
|
exitCode: resumeExit,
|
|
1798
1826
|
});
|
|
1799
|
-
// A resumed loop is always headless; surface any commits it left unpushed
|
|
1800
|
-
|
|
1801
|
-
|
|
1827
|
+
// A resumed loop is always headless; surface any commits it left unpushed
|
|
1828
|
+
// and any open PR it left unattended (RUSH-2394).
|
|
1829
|
+
if (shouldWarnUnpushed(resumeExec.mode ?? 'auto', false)) {
|
|
1830
|
+
const resumeCwd = resumeExec.cwd ?? process.cwd();
|
|
1831
|
+
await warnUnpushedWork(resumeCwd);
|
|
1832
|
+
await warnOrphanedOpenPr(resumeCwd);
|
|
1833
|
+
}
|
|
1802
1834
|
process.exit(resumeExit);
|
|
1803
1835
|
}
|
|
1804
|
-
const [{ buildExecCommand, parseExecEnv, execAgent, runWithFallback, normalizeMode, resolveMode, implicitModeFor, headlessPlanStallCommand, nativeResume, resolveInteractive, inferredInteractiveWithoutTty }, { ALL_AGENT_IDS, ACCOUNT_INSPECTION_AGENT_IDS, agentLabel, supportsAccountInspection }, { profileExists, resolveProfileForRun }, { readAndResolveBundleEnv, describeBundle, assertRemoteBundleFlagsUnsupported }, { splitBundleRef, resolveHostSshTarget, remoteResolveEnv }, { getConfiguredRunStrategy, normalizeRunStrategy, resolveRunVersion, rotationFailoverChain, shouldArmRotationFailover, RUN_STRATEGIES, collectHarnessCandidates, pickHarnessWeighted, classifyHarnessCandidates, formatHarnessPickBanner, formatNoHealthyHarnessError, formatNoHealthyAccountError, signInRecoverableCandidates }, { getGlobalDefault, getVersionHomePath, resolveVersion, resolveVersionAlias, ensureAgentRunnable }, { buildDiscoveredPlugin, loadPluginManifest, syncPluginToVersion }, { parseWorkflowFrontmatter, resolveWorkflowRef, resolveAllowedSubagents, pruneStaleWorkflowSubagents, ensureSubagentDispatchTool }, { resolveRunDefaults }, { getMcpServersByName, buildWorkflowMcpConfig }, { supports, capableAgents }, { shareRuntimeEnv },] = await Promise.all([
|
|
1836
|
+
const [{ buildExecCommand, parseExecEnv, execAgent, runWithFallback, normalizeMode, resolveMode, implicitModeFor, headlessPlanStallCommand, nativeResume, resolveInteractive, inferredInteractiveWithoutTty }, { ALL_AGENT_IDS, ACCOUNT_INSPECTION_AGENT_IDS, agentLabel, supportsAccountInspection }, { profileExists, readProfile, resolveProfileForRun }, { readAndResolveBundleEnv, describeBundle, assertRemoteBundleFlagsUnsupported }, { splitBundleRef, resolveHostSshTarget, remoteResolveEnv }, { getConfiguredRunStrategy, normalizeRunStrategy, resolveRunVersion, rotationFailoverChain, shouldArmRotationFailover, RUN_STRATEGIES, collectHarnessCandidates, pickHarnessWeighted, classifyHarnessCandidates, formatHarnessPickBanner, formatNoHealthyHarnessError, formatNoHealthyAccountError, signInRecoverableCandidates }, { getGlobalDefault, getVersionHomePath, resolveVersion, resolveVersionAlias, ensureAgentRunnable }, { buildDiscoveredPlugin, loadPluginManifest, syncPluginToVersion }, { parseWorkflowFrontmatter, resolveWorkflowRef, resolveAllowedSubagents, pruneStaleWorkflowSubagents, ensureSubagentDispatchTool }, { resolveRunDefaults }, { getMcpServersByName, buildWorkflowMcpConfig }, { supports, capableAgents }, { shareRuntimeEnv },] = await Promise.all([
|
|
1805
1837
|
import('../lib/exec.js'),
|
|
1806
1838
|
import('../lib/agents.js'),
|
|
1807
1839
|
import('../lib/profiles.js'),
|
|
@@ -1822,6 +1854,8 @@ export function registerRunCommand(program) {
|
|
|
1822
1854
|
let agent;
|
|
1823
1855
|
let version = rawVersion || undefined;
|
|
1824
1856
|
let profileEnv;
|
|
1857
|
+
let accountEnv;
|
|
1858
|
+
let profileProvider;
|
|
1825
1859
|
let fromProfile = false;
|
|
1826
1860
|
let profileFallbackModel;
|
|
1827
1861
|
let workflowModel;
|
|
@@ -1903,6 +1937,7 @@ export function registerRunCommand(program) {
|
|
|
1903
1937
|
if (!version)
|
|
1904
1938
|
version = resolved.version;
|
|
1905
1939
|
profileEnv = resolved.env;
|
|
1940
|
+
profileProvider = readProfile(rawAgent).provider;
|
|
1906
1941
|
profileFallbackModel = resolved.fallbackModel;
|
|
1907
1942
|
fromProfile = true;
|
|
1908
1943
|
process.stderr.write(chalk.gray(`Resolved custom harness '${resolved.profileName}' -> ${agent}${version ? `@${version}` : ''}\n`));
|
|
@@ -2154,17 +2189,16 @@ export function registerRunCommand(program) {
|
|
|
2154
2189
|
}
|
|
2155
2190
|
}
|
|
2156
2191
|
version = resolveVersionAlias(agent, version);
|
|
2157
|
-
|
|
2192
|
+
const { resolveAccountSelection } = await import('../lib/account-registry.js');
|
|
2193
|
+
const configuredAccount = resolveAccountSelection(options.account, agent, readMeta(), { useDefault: !fromProfile });
|
|
2194
|
+
if (configuredAccount) {
|
|
2158
2195
|
if (options.cloud || options.provider || options.lease) {
|
|
2159
|
-
console.error(chalk.red('--account selects a local
|
|
2196
|
+
console.error(chalk.red('--account selects a device-local credential and cannot be combined with cloud or lease placement.'));
|
|
2160
2197
|
process.exit(1);
|
|
2161
2198
|
}
|
|
2162
|
-
const {
|
|
2199
|
+
const { resolveCredentialAccount } = await import('../lib/account-registry.js');
|
|
2163
2200
|
try {
|
|
2164
|
-
|
|
2165
|
-
if (version && version !== selected)
|
|
2166
|
-
throw new Error(`${agent}@${version} is not a healthy match for account '${options.account}'.`);
|
|
2167
|
-
version ??= selected;
|
|
2201
|
+
accountEnv = resolveCredentialAccount(configuredAccount, agent, profileProvider).env;
|
|
2168
2202
|
}
|
|
2169
2203
|
catch (err) {
|
|
2170
2204
|
console.error(chalk.red(err.message));
|
|
@@ -2343,7 +2377,7 @@ export function registerRunCommand(program) {
|
|
|
2343
2377
|
// the bare primary still resolves through the strategy — otherwise every
|
|
2344
2378
|
// `agents run claude --fallback codex` run lands on the pinned default
|
|
2345
2379
|
// account and account rotation silently stops (the gh-monitor heal bug).
|
|
2346
|
-
if (!accountPickerRequested && !
|
|
2380
|
+
if (!accountPickerRequested && !configuredAccount && (strategy !== 'pinned' || options.balanced || explicitStrategy)) {
|
|
2347
2381
|
if (version) {
|
|
2348
2382
|
process.stderr.write(chalk.yellow(`[agents] strategy ${strategy} ignored: version ${version} is pinned\n`));
|
|
2349
2383
|
}
|
|
@@ -2661,14 +2695,14 @@ export function registerRunCommand(program) {
|
|
|
2661
2695
|
const autoShareEnv = options.autoSecrets !== false
|
|
2662
2696
|
? shareRuntimeEnv()
|
|
2663
2697
|
: undefined;
|
|
2664
|
-
// Merge order (later wins): profile env < auto share token < secrets bundles < --env K=V.
|
|
2698
|
+
// Merge order (later wins): profile env < selected account < auto share token < secrets bundles < --env K=V.
|
|
2665
2699
|
// Profile carries provider auth; secrets bundles carry user-defined
|
|
2666
2700
|
// values; --env is the per-invocation override. The share token is
|
|
2667
2701
|
// best-effort: if it is not already in env or an unlocked bundle, unrelated
|
|
2668
2702
|
// runs keep working, and `agents share` itself still fails loudly on use.
|
|
2669
|
-
const hasOverrides = profileEnv || autoShareEnv || options.secrets.length > 0 || userEnv;
|
|
2703
|
+
const hasOverrides = profileEnv || accountEnv || autoShareEnv || options.secrets.length > 0 || userEnv;
|
|
2670
2704
|
const env = hasOverrides
|
|
2671
|
-
? { ...(profileEnv ?? {}), ...(autoShareEnv ?? {}), ...secretsEnv, ...(userEnv ?? {}) }
|
|
2705
|
+
? { ...(profileEnv ?? {}), ...(accountEnv ?? {}), ...(autoShareEnv ?? {}), ...secretsEnv, ...(userEnv ?? {}) }
|
|
2672
2706
|
: undefined;
|
|
2673
2707
|
const modelSource = runCmd.getOptionValueSource('model');
|
|
2674
2708
|
let model = options.model
|
|
@@ -2839,9 +2873,12 @@ export function registerRunCommand(program) {
|
|
|
2839
2873
|
// Governance chokepoint (#347): the --acp path exits here, bypassing
|
|
2840
2874
|
// the normal finalize below — record its one audit entry.
|
|
2841
2875
|
recordDispatchedRun({ agent, version: defaultVersion ?? 'unknown', mode, cwd, exitCode });
|
|
2842
|
-
// ACP headless run always has a prompt; surface any unpushed commits
|
|
2843
|
-
|
|
2876
|
+
// ACP headless run always has a prompt; surface any unpushed commits
|
|
2877
|
+
// and any open PR left unattended (RUSH-2394).
|
|
2878
|
+
if (shouldWarnUnpushed(mode, false)) {
|
|
2844
2879
|
await warnUnpushedWork(cwd);
|
|
2880
|
+
await warnOrphanedOpenPr(cwd);
|
|
2881
|
+
}
|
|
2845
2882
|
process.exit(exitCode);
|
|
2846
2883
|
}
|
|
2847
2884
|
catch (err) {
|
|
@@ -2998,9 +3035,12 @@ export function registerRunCommand(program) {
|
|
|
2998
3035
|
// the normal finalize below — record its one audit entry.
|
|
2999
3036
|
const loopExit = loopExitCode(result.stoppedBy);
|
|
3000
3037
|
recordDispatchedRun({ agent, version: defaultVersion ?? 'unknown', mode, cwd, exitCode: loopExit });
|
|
3001
|
-
// A loop is always headless; surface any commits it left unpushed
|
|
3002
|
-
|
|
3038
|
+
// A loop is always headless; surface any commits it left unpushed
|
|
3039
|
+
// and any open PR left without a durable lander (RUSH-2394).
|
|
3040
|
+
if (shouldWarnUnpushed(mode, false)) {
|
|
3003
3041
|
await warnUnpushedWork(cwd);
|
|
3042
|
+
await warnOrphanedOpenPr(cwd);
|
|
3043
|
+
}
|
|
3004
3044
|
process.exit(loopExit);
|
|
3005
3045
|
}
|
|
3006
3046
|
catch (err) {
|
|
@@ -3045,11 +3085,14 @@ export function registerRunCommand(program) {
|
|
|
3045
3085
|
cleanupWorkflowMcpConfig();
|
|
3046
3086
|
cleanupWorkflowSubagents();
|
|
3047
3087
|
// Surface committed-but-unpushed work a headless writable run left
|
|
3048
|
-
// behind, so it isn't silently stranded in a worktree.
|
|
3088
|
+
// behind, so it isn't silently stranded in a worktree. Also warn when
|
|
3089
|
+
// the branch still has an OPEN PR (RUSH-2394) — a background
|
|
3090
|
+
// `gh pr checks --watch` dies with the agent. Advisory only,
|
|
3049
3091
|
// never throws; skipped for interactive runs (the human sees the shell)
|
|
3050
3092
|
// and read-only plan mode (can't commit).
|
|
3051
3093
|
if (shouldWarnUnpushed(mode, resolveInteractive(execOptions))) {
|
|
3052
3094
|
await warnUnpushedWork(cwd);
|
|
3095
|
+
await warnOrphanedOpenPr(cwd);
|
|
3053
3096
|
}
|
|
3054
3097
|
// Governance chokepoint (#347): every dispatched run finalizes here.
|
|
3055
3098
|
// ONE tamper-evident audit record per run — non-fatal by contract.
|
|
@@ -3067,6 +3110,7 @@ export function registerRunCommand(program) {
|
|
|
3067
3110
|
// matters most — warn before exiting the error path too.
|
|
3068
3111
|
if (shouldWarnUnpushed(mode, resolveInteractive(execOptions))) {
|
|
3069
3112
|
await warnUnpushedWork(cwd);
|
|
3113
|
+
await warnOrphanedOpenPr(cwd);
|
|
3070
3114
|
}
|
|
3071
3115
|
console.error(chalk.red(`Failed to execute ${agent}: ${err.message}`));
|
|
3072
3116
|
process.exit(1);
|
package/dist/commands/feed.d.ts
CHANGED
|
@@ -20,7 +20,7 @@ import { type OpenBlock } from '../lib/feed.js';
|
|
|
20
20
|
import { type OutcomeGroup, type SessionOutcomeHint } from '../lib/feed-outcome.js';
|
|
21
21
|
import { filterBlocksForFeed } from '../lib/ask-classifier.js';
|
|
22
22
|
import { type FeedSessionSignal } from '../lib/feed-ranking.js';
|
|
23
|
-
export declare const FEED_POST_HELP = "\nExamples:\n # Title (subject) + body. Phone broadcasts put title first, body after a\n # blank line, then a \"Sent from agent/session on host\" footer.\n agents feed post --title \"CHANGELOG pushed\" \"Watching CI and mac-mini E2E\"\n agents feed post --title \"Cover ready\" \"render at ./out/cover.png\" --attach ./out/cover.png\n agents feed post --title \"Ready for review\" \"PR opened, waiting on prix-cloud\" --json\n\n # Worth interrupting someone over - reaches sinks gated on minLevel: important:\n agents feed post --title \"npm token expired\" \"Cannot publish the release\" --level important\n\n # Stuck: opens a needs-you block and always broadcasts at important:\n agents feed post --title \"Force-push denied\" \"git-guard blocked PR #1749\" --blocked\n agents feed post --title \"Publish or wait?\" \"npm publish now or after review\" --blocked --option publish --option wait\n agents feed post --title \"Delete preview env?\" \"stale preview still running\" --blocked --default \"leave it\"\n\n # Exhaust self-serve FIRST. A block is for what you genuinely cannot do:\n # a credential only the user holds, a decision only they can make, an\n # approval only they can give. Not \"should I do the obvious next step?\".\n\n # Outside a run, pass the session explicitly:\n agents feed post --title \"Manual note\" \"context for the next agent\" --session 00998b0e-2d15-4d2f-a58b-974a886c9b47\n\nIdentity (session, agent, host, runtime, pid, launchId) is stamped automatically\nand rides the phone footer of feed.broadcast {message}. Domain facts (tickets,\nPRs) are not CLI flags - the ticket is joined from the session index at post\ntime. No em-dashes in title/body - they are scrubbed on the way out.\n\nConfigure where a post is mirrored under feed.broadcast in agents.yaml - see\ndocs/
|
|
23
|
+
export declare const FEED_POST_HELP = "\nExamples:\n # Title (subject) + body. Phone broadcasts put title first, body after a\n # blank line, then a \"Sent from agent/session on host\" footer.\n agents feed post --title \"CHANGELOG pushed\" \"Watching CI and mac-mini E2E\"\n agents feed post --title \"Cover ready\" \"render at ./out/cover.png\" --attach ./out/cover.png\n agents feed post --title \"Ready for review\" \"PR opened, waiting on prix-cloud\" --json\n\n # Worth interrupting someone over - reaches sinks gated on minLevel: important:\n agents feed post --title \"npm token expired\" \"Cannot publish the release\" --level important\n\n # Also raise a local desktop banner on THIS machine (same notifier as run\n # --notify), on top of any configured broadcast - useful when you are at the box:\n agents feed post --title \"Build green\" \"all checks passed\" --notify\n\n # Stuck: opens a needs-you block and always broadcasts at important:\n agents feed post --title \"Force-push denied\" \"git-guard blocked PR #1749\" --blocked\n agents feed post --title \"Publish or wait?\" \"npm publish now or after review\" --blocked --option publish --option wait\n agents feed post --title \"Delete preview env?\" \"stale preview still running\" --blocked --default \"leave it\"\n\n # Exhaust self-serve FIRST. A block is for what you genuinely cannot do:\n # a credential only the user holds, a decision only they can make, an\n # approval only they can give. Not \"should I do the obvious next step?\".\n\n # Outside a run, pass the session explicitly:\n agents feed post --title \"Manual note\" \"context for the next agent\" --session 00998b0e-2d15-4d2f-a58b-974a886c9b47\n\nIdentity (session, agent, host, runtime, pid, launchId) is stamped automatically\nand rides the phone footer of feed.broadcast {message}. Domain facts (tickets,\nPRs) are not CLI flags - the ticket is joined from the session index at post\ntime. No em-dashes in title/body - they are scrubbed on the way out.\n\nConfigure where a post is mirrored under feed.broadcast in agents.yaml - see\ndocs/observability.md. A milestone is always recorded, but it does not text\nthe owner when the sink has minLevel: important. Add --level important for a\nphone-worthy successful update. Use --blocked only when work cannot continue.\nThe owner destination comes from humans.yaml; do not duplicate it in agents.yaml.\n";
|
|
24
24
|
export declare const FEED_NO_FANOUT_ENV = "AGENTS_FEED_LOCAL";
|
|
25
25
|
/** Right-hand masthead summary: `N blocks · M agents`. */
|
|
26
26
|
export declare function formatFeedMastheadRight(blocks: OpenBlock[]): string;
|