@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
|
@@ -37,6 +37,7 @@ import { injectIntoTerminal } from '../lib/terminal/index.js';
|
|
|
37
37
|
import { iLoginShell } from '../lib/terminal/shell.js';
|
|
38
38
|
import { shellQuote as quoteArg } from '../lib/terminal/quote.js';
|
|
39
39
|
import { killSession } from '../lib/tmux/session.js';
|
|
40
|
+
import { getDefaultSocketPath } from '../lib/tmux/paths.js';
|
|
40
41
|
import { listAllHosts, resolveHost } from '../lib/hosts/registry.js';
|
|
41
42
|
import { sshTargetFor } from '../lib/hosts/types.js';
|
|
42
43
|
import { readyProbe, bootstrapAgentsCli, viewHasAgent } from '../lib/hosts/ready.js';
|
|
@@ -406,6 +407,44 @@ function prepareEphemeralCwd(sshTarget, source, branch) {
|
|
|
406
407
|
}
|
|
407
408
|
return dir;
|
|
408
409
|
}
|
|
410
|
+
/**
|
|
411
|
+
* Pure. The remote shell commands that create the target's tmux session on the
|
|
412
|
+
* SAME socket its reaper queries, and that probe its liveness afterward.
|
|
413
|
+
*
|
|
414
|
+
* `homeRelSocketPath` is `getDefaultSocketPath()` expressed relative to the
|
|
415
|
+
* LOCAL home dir (`path.relative(os.homedir(), getDefaultSocketPath())`) — a
|
|
416
|
+
* portable suffix, not a resolved absolute path, because the local and remote
|
|
417
|
+
* HOME can differ (different user, different OS). It is spliced in after a
|
|
418
|
+
* literal, unquoted `$HOME/` so the REMOTE shell resolves it; `$HOME` MUST
|
|
419
|
+
* NEVER be resolved locally (see AGENTS.md's remote-path guidance).
|
|
420
|
+
*
|
|
421
|
+
* Extracted as a pure function so the "does the migrated session land on the
|
|
422
|
+
* agents socket, not tmux's bare default socket" invariant is unit-testable
|
|
423
|
+
* without an SSH round-trip (RUSH-2521 review — a bare `tmux` here made the
|
|
424
|
+
* migrated agent's helpers invisible to `readAllPaneOwners`, so the reaper's
|
|
425
|
+
* next tick killed the still-live, just-migrated agent as `tmux-session-gone`).
|
|
426
|
+
*/
|
|
427
|
+
export function buildMigrateResumeCommands(opts) {
|
|
428
|
+
const socketDirRelToHome = path.dirname(opts.homeRelSocketPath);
|
|
429
|
+
const socketFlag = `-S "$HOME/${opts.homeRelSocketPath}"`;
|
|
430
|
+
const argv = ['set-option', '-g', 'remain-on-exit', 'on', ';', 'new-session', '-d', '-s', opts.sessionName];
|
|
431
|
+
if (opts.cwd && opts.cwd !== '~')
|
|
432
|
+
argv.push('-c', opts.cwd);
|
|
433
|
+
argv.push(opts.inner);
|
|
434
|
+
// Mirror createSession's second half: keep remain-on-exit on THIS pane (the
|
|
435
|
+
// liveness probe below reads `pane_dead`), then put the server-wide default
|
|
436
|
+
// back to off. Leaving `-g on` set made every later pane on the target — user
|
|
437
|
+
// splits included — retain a corpse when its command finished.
|
|
438
|
+
argv.push(';', 'set-option', '-t', opts.sessionName, '-p', 'remain-on-exit', 'on');
|
|
439
|
+
argv.push(';', 'set-option', '-g', 'remain-on-exit', 'off');
|
|
440
|
+
// Unlike tmux's own scratch dir (auto-created under /tmp), the agents socket's
|
|
441
|
+
// parent may not exist yet on a fresh worker or ephemeral box that never ran a
|
|
442
|
+
// tmux-backed `agents` command — `mkdir -p` it before tmux tries to bind there.
|
|
443
|
+
const launchCmd = `mkdir -p "$HOME/${socketDirRelToHome}" && tmux ${socketFlag} ` + argv.map(shellQuote).join(' ');
|
|
444
|
+
const q = shellQuote(opts.sessionName);
|
|
445
|
+
const probeCmd = `sleep 3; tmux ${socketFlag} has-session -t ${q} 2>/dev/null || exit 3; test "$(tmux ${socketFlag} list-panes -t ${q} -F '#{pane_dead}' 2>/dev/null | head -n1)" = 0 || exit 4`;
|
|
446
|
+
return { launchCmd, probeCmd, socketFlag };
|
|
447
|
+
}
|
|
409
448
|
/**
|
|
410
449
|
* Resume the session on the target through the SAME host path as
|
|
411
450
|
* `sessions resume --host` (tmux backend). Returns true when the resume launched.
|
|
@@ -426,14 +465,18 @@ async function resumeOnTarget(sshTarget, source, remoteCwd, mode) {
|
|
|
426
465
|
// carries spaces or backticks (the rehydrate prompt) reaches the agent as one
|
|
427
466
|
// clean argument — an unquoted join would let the target shell split it and
|
|
428
467
|
// run its backticks.
|
|
468
|
+
//
|
|
469
|
+
// The pane exports AGENT_TMUX_SESSION_NAME the way a local `createSession`
|
|
470
|
+
// pane does, so the target's reaper can attribute the helpers this agent
|
|
471
|
+
// spawns and collect them when it exits (RUSH-2521, `lib/tmux/orphan-reap.ts`)
|
|
472
|
+
// — see {@link buildMigrateResumeCommands} for why the session MUST land on
|
|
473
|
+
// the agents socket rather than tmux's bare default socket.
|
|
429
474
|
const sessionName = `migrate-${source.shortId}`;
|
|
430
|
-
const
|
|
431
|
-
const
|
|
475
|
+
const homeRelSocketPath = path.relative(os.homedir(), getDefaultSocketPath());
|
|
476
|
+
const inner = iLoginShell(`export AGENT_TMUX_SESSION_NAME=${sessionName}; exec ${command.map(quoteArg).join(' ')}`);
|
|
432
477
|
const cwd = remoteCwd ?? source.cwd;
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
argv.push(inner);
|
|
436
|
-
const launch = sshExec(sshTarget, argv.map(shellQuote).join(' '), { timeoutMs: 60000 });
|
|
478
|
+
const { launchCmd, probeCmd } = buildMigrateResumeCommands({ sessionName, homeRelSocketPath, inner, cwd });
|
|
479
|
+
const launch = sshExec(sshTarget, launchCmd, { timeoutMs: 60000 });
|
|
437
480
|
if (launch.code !== 0) {
|
|
438
481
|
console.log(chalk.red(` Resume on ${sshTarget} failed: ${launch.stderr.trim().split('\n').pop() || `tmux exited ${launch.code}`}`));
|
|
439
482
|
return false;
|
|
@@ -441,9 +484,7 @@ async function resumeOnTarget(sshTarget, source, remoteCwd, mode) {
|
|
|
441
484
|
// Liveness gate for the invariant: give the agent a moment to boot, then require
|
|
442
485
|
// the pane to be ALIVE (not merely the session to exist) before the caller may
|
|
443
486
|
// stop the source. An agent that dies on launch → we refuse to move.
|
|
444
|
-
const
|
|
445
|
-
const probe = `sleep 3; tmux has-session -t ${q} 2>/dev/null || exit 3; test "$(tmux list-panes -t ${q} -F '#{pane_dead}' 2>/dev/null | head -n1)" = 0 || exit 4`;
|
|
446
|
-
const check = sshExec(sshTarget, probe, { timeoutMs: 30000 });
|
|
487
|
+
const check = sshExec(sshTarget, probeCmd, { timeoutMs: 30000 });
|
|
447
488
|
if (check.code !== 0) {
|
|
448
489
|
const why = check.code === 4 ? 'the agent exited immediately on the target'
|
|
449
490
|
: check.code === 3 ? 'the session did not start'
|
|
@@ -20,7 +20,7 @@ import { itemPicker } from '../lib/picker.js';
|
|
|
20
20
|
import { createMemoryCache } from '../lib/memory-cache.js';
|
|
21
21
|
import { classifyFileChanges, changeCounts, toolHistogram, detectTestResult } from '../lib/session/digest.js';
|
|
22
22
|
import { extractArtifacts, extractHooks, extractLinks, extractRepos, extractSkills } from '../lib/session/highlights.js';
|
|
23
|
-
import { getSessionPlugins, readSessionPreviewCache, writeSessionPreviewCache } from '../lib/session/db.js';
|
|
23
|
+
import { getSessionPlugins, readSessionPreviewCache, writeSessionPreviewCache, readSessionContent, readArchivedSessionPreview } from '../lib/session/db.js';
|
|
24
24
|
/** A session whose transcript FILE is on another machine (folded in over the
|
|
25
25
|
* live cross-machine fan-out): its `filePath` is on that peer's disk, so the
|
|
26
26
|
* preview can't parse it locally — it shows metadata + a "resume there" note
|
|
@@ -130,8 +130,17 @@ export function clearPreviewMemoryCacheForTest() {
|
|
|
130
130
|
previewCache.clear();
|
|
131
131
|
}
|
|
132
132
|
export function loadSessionPreviewDigest(session) {
|
|
133
|
-
if (!session.filePath || !fs.existsSync(session.filePath))
|
|
133
|
+
if (!session.filePath || !fs.existsSync(session.filePath)) {
|
|
134
|
+
// File gone, but an archived session (RUSH-2436) keeps its last-computed
|
|
135
|
+
// digest in the DB — serve that so the picker preview still shows its turns
|
|
136
|
+
// instead of a bare "not indexed here" note. No events to replay.
|
|
137
|
+
const archived = readArchivedSessionPreview(session.id);
|
|
138
|
+
if (archived) {
|
|
139
|
+
archived.plugins = getSessionPlugins(session.id);
|
|
140
|
+
return { digest: archived, events: [] };
|
|
141
|
+
}
|
|
134
142
|
return { events: [] };
|
|
143
|
+
}
|
|
135
144
|
const safe = sanitizeMeta(session);
|
|
136
145
|
let events = [];
|
|
137
146
|
let sourceStamp;
|
|
@@ -182,9 +191,19 @@ export function buildPreview(session) {
|
|
|
182
191
|
previewCache.set(cacheKey, output);
|
|
183
192
|
return output;
|
|
184
193
|
}
|
|
185
|
-
// No transcript on disk —
|
|
186
|
-
//
|
|
194
|
+
// No transcript on disk — either an archived session (file gone, user turns
|
|
195
|
+
// still in the DB — RUSH-2436), a live session not indexed locally, or a
|
|
196
|
+
// synthesized entry (e.g. `sessions go`). Show the header + a clean note.
|
|
187
197
|
if (!session.filePath || !fs.existsSync(session.filePath)) {
|
|
198
|
+
const archivedContent = readSessionContent(session.id);
|
|
199
|
+
if (archivedContent && archivedContent.trim() !== '') {
|
|
200
|
+
const note = ' ' + chalk.yellow('archived — transcript file removed; served from the local DB');
|
|
201
|
+
const { digest } = loadSessionPreviewDigest(session);
|
|
202
|
+
const body = digest ? formatCompactPreview(digest, safe) : formatMetaOnlyBody(safe);
|
|
203
|
+
const output = [formatHeader(safe, []), '', note, body].filter(Boolean).join('\n');
|
|
204
|
+
previewCache.set(cacheKey, output);
|
|
205
|
+
return output;
|
|
206
|
+
}
|
|
188
207
|
const note = ' ' + chalk.gray('Live session — full transcript not indexed here.');
|
|
189
208
|
const metaBody = formatMetaOnlyBody(safe);
|
|
190
209
|
const output = [formatHeader(safe, []), '', note, metaBody].filter(Boolean).join('\n');
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Command } from 'commander';
|
|
2
|
-
import type
|
|
2
|
+
import { type SessionMeta } from '../lib/session/types.js';
|
|
3
3
|
import { type Backend, type EngineContext, type Packing } from '../lib/terminal/index.js';
|
|
4
4
|
/** Opening more than this many live sessions at once asks for confirmation first. */
|
|
5
5
|
export declare const CONFIRM_THRESHOLD = 5;
|
|
@@ -17,6 +17,8 @@ export interface ResumeOptions {
|
|
|
17
17
|
/** --terminal-app: force macOS Terminal.app. Named to avoid reading as `run --terminal`. */
|
|
18
18
|
terminalApp?: boolean;
|
|
19
19
|
splits?: boolean;
|
|
20
|
+
attachOnly?: boolean;
|
|
21
|
+
local?: boolean;
|
|
20
22
|
}
|
|
21
23
|
export declare function registerSessionsResumeCommand(sessionsCmd: Command): void;
|
|
22
24
|
/** IDs and tmux aliases are actions, not picker search text. Human phrases keep
|
|
@@ -28,8 +30,8 @@ export declare function resumeSelectorInPlace(selector: string): Promise<void>;
|
|
|
28
30
|
/** Direct identities use focus as the lifecycle dispatcher: it rechecks the
|
|
29
31
|
* live fleet, attaches a healthy pane, and falls through to `agents resume`
|
|
30
32
|
* only when the process is no longer attachable. */
|
|
31
|
-
export declare function dispatchSessionLifecycleInPlace(selector: string, hosts?: string[]): Promise<void>;
|
|
32
|
-
export declare function buildSessionLifecycleArgs(selector: string, hosts?: string[]): string[];
|
|
33
|
+
export declare function dispatchSessionLifecycleInPlace(selector: string, hosts?: string[], attachOnly?: boolean, local?: boolean): Promise<void>;
|
|
34
|
+
export declare function buildSessionLifecycleArgs(selector: string, hosts?: string[], attachOnly?: boolean, local?: boolean): string[];
|
|
33
35
|
export declare function resolveResumePacking(options: Pick<ResumeOptions, 'splits'>): Packing;
|
|
34
36
|
export declare function resumeHostMismatch(session: Pick<SessionMeta, 'shortId' | 'machine'>, requestedHost: string, self?: string): string | null;
|
|
35
37
|
/**
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
*/
|
|
11
11
|
import * as fs from 'fs';
|
|
12
12
|
import chalk from 'chalk';
|
|
13
|
+
import { isAgentTmuxAlias } from '../lib/session/types.js';
|
|
13
14
|
import { discoverSessions } from '../lib/session/discover.js';
|
|
14
15
|
import { filterTeamSessions } from '../lib/session/team-filter.js';
|
|
15
16
|
import { multiItemPicker, itemPicker } from '../lib/picker.js';
|
|
@@ -42,6 +43,8 @@ export function registerSessionsResumeCommand(sessionsCmd) {
|
|
|
42
43
|
.option('--tmux', 'Force the tmux backend')
|
|
43
44
|
.option('--vscodium', 'Force the VSCodium agent-terminal backend (swarm-ext)')
|
|
44
45
|
.option('--terminal-app', 'Force macOS Terminal.app (no split support — panes become tabs)')
|
|
46
|
+
.option('--local', 'Only this machine (skip the cross-host sweep)')
|
|
47
|
+
.option('--attach-only', 'With an id/alias: attach a living pane only — never resume a copy')
|
|
45
48
|
.option('--splits', 'Pack two sessions side by side per tab (default: one tab per session)');
|
|
46
49
|
setHelpSections(cmd, {
|
|
47
50
|
examples: `
|
|
@@ -55,6 +58,9 @@ export function registerSessionsResumeCommand(sessionsCmd) {
|
|
|
55
58
|
agents sessions resume 019fd114
|
|
56
59
|
agents sessions resume ag-codex-c1f3d813
|
|
57
60
|
|
|
61
|
+
# Attach a living pane only — never resume a copy (the old go)
|
|
62
|
+
agents sessions resume 019fd114 --attach-only
|
|
63
|
+
|
|
58
64
|
# Force a backend / side-by-side splits / a remote host
|
|
59
65
|
agents sessions resume --ghostty
|
|
60
66
|
agents sessions resume --vscodium
|
|
@@ -62,7 +68,10 @@ export function registerSessionsResumeCommand(sessionsCmd) {
|
|
|
62
68
|
agents sessions resume --host zion --tmux
|
|
63
69
|
`,
|
|
64
70
|
notes: `
|
|
65
|
-
-
|
|
71
|
+
- This is the ONE verb for getting back in. It detects the state: a live tmux pane is attached, a headless session comes to the foreground, an ended one recovers on its owning device.
|
|
72
|
+
- A UUID/prefix or ag-<agent>-<suffix> alias bypasses the picker. A live alias attaches by name even when the session index cannot attribute it.
|
|
73
|
+
- Retired spellings still work for one release and print the replacement: sessions attach, sessions go, reconnect.
|
|
74
|
+
- Going the other way (foreground -> background) is 'agents sessions detach <id>'.
|
|
66
75
|
- With no identity selector, space toggles a session, enter confirms, and tab toggles the preview pane.
|
|
67
76
|
- Layout: one tab per session by default. --splits packs session pairs side by side in each tab.
|
|
68
77
|
- Backend: auto-detected from the terminal you're in (iTerm / Ghostty / tmux); override with --iterm/--ghostty/--tmux/--vscodium.
|
|
@@ -82,7 +91,7 @@ async function sessionsResumeAction(query, options) {
|
|
|
82
91
|
return;
|
|
83
92
|
}
|
|
84
93
|
if (query && isDirectResumeSelector(query)) {
|
|
85
|
-
await dispatchSessionLifecycleInPlace(query.trim(), options.host ? [options.host] : []);
|
|
94
|
+
await dispatchSessionLifecycleInPlace(query.trim(), options.host ? [options.host] : [], options.attachOnly === true, options.local === true);
|
|
86
95
|
return;
|
|
87
96
|
}
|
|
88
97
|
const { agent, version } = parseAgentFilter(options.agent);
|
|
@@ -182,7 +191,15 @@ async function sessionsResumeAction(query, options) {
|
|
|
182
191
|
console.log(chalk.yellow('Terminal.app cannot split panes — opening one tab per session instead.'));
|
|
183
192
|
}
|
|
184
193
|
console.log(chalk.gray(`Opening ${items.length} session${items.length === 1 ? '' : 's'} in ${where} (${packing})…`));
|
|
185
|
-
|
|
194
|
+
// agent + sessionId ride the SurfaceItem into the vscodium-agent spawn URI
|
|
195
|
+
// so the extension can set the tab chip without process-tree sniffing (#2478).
|
|
196
|
+
const results = await openSurfaces(items.map((it) => ({
|
|
197
|
+
cwd: it.cwd,
|
|
198
|
+
command: it.command,
|
|
199
|
+
agent: it.session.agent || undefined,
|
|
200
|
+
sessionId: it.session.id || undefined,
|
|
201
|
+
title: it.session.label || it.session.topic || undefined,
|
|
202
|
+
})), { backend, host: options.host, packing });
|
|
186
203
|
let opened = 0;
|
|
187
204
|
results.forEach((r, i) => {
|
|
188
205
|
const s = items[i].session;
|
|
@@ -201,7 +218,7 @@ async function sessionsResumeAction(query, options) {
|
|
|
201
218
|
* the existing pre-filtered picker, while an explicit identity resumes directly. */
|
|
202
219
|
export function isDirectResumeSelector(query) {
|
|
203
220
|
const selector = query.trim();
|
|
204
|
-
return looksLikeSessionId(selector) ||
|
|
221
|
+
return looksLikeSessionId(selector) || isAgentTmuxAlias(selector);
|
|
205
222
|
}
|
|
206
223
|
/** Re-enter through the top-level command so fleet routing and harness policy
|
|
207
224
|
* stay centralized. The child inherits this terminal for a real interactive resume. */
|
|
@@ -211,11 +228,16 @@ export async function resumeSelectorInPlace(selector) {
|
|
|
211
228
|
/** Direct identities use focus as the lifecycle dispatcher: it rechecks the
|
|
212
229
|
* live fleet, attaches a healthy pane, and falls through to `agents resume`
|
|
213
230
|
* only when the process is no longer attachable. */
|
|
214
|
-
export async function dispatchSessionLifecycleInPlace(selector, hosts = []) {
|
|
215
|
-
await spawnCliInPlace(buildSessionLifecycleArgs(selector, hosts));
|
|
231
|
+
export async function dispatchSessionLifecycleInPlace(selector, hosts = [], attachOnly = false, local = false) {
|
|
232
|
+
await spawnCliInPlace(buildSessionLifecycleArgs(selector, hosts, attachOnly, local));
|
|
216
233
|
}
|
|
217
|
-
export function buildSessionLifecycleArgs(selector, hosts = []) {
|
|
218
|
-
return [
|
|
234
|
+
export function buildSessionLifecycleArgs(selector, hosts = [], attachOnly = false, local = false) {
|
|
235
|
+
return [
|
|
236
|
+
'sessions', 'focus', selector,
|
|
237
|
+
...hosts.flatMap(host => ['--host', host]),
|
|
238
|
+
...(attachOnly ? ['--attach-only'] : []),
|
|
239
|
+
...(local ? ['--local'] : []),
|
|
240
|
+
];
|
|
219
241
|
}
|
|
220
242
|
function asyncExitCode(child) {
|
|
221
243
|
return new Promise((resolve) => {
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { machineId } from '../lib/machine-id.js';
|
|
2
|
+
import { setHelpSections } from '../lib/help.js';
|
|
3
|
+
import { watchFleetSessions, watchLocalSessions } from '../lib/session/watch.js';
|
|
4
|
+
export function registerSessionsWatchCommand(parent) {
|
|
5
|
+
const command = parent.command('watch')
|
|
6
|
+
.description('Stream canonical live and recoverable session row changes as NDJSON')
|
|
7
|
+
.option('--json', 'Emit versioned NDJSON envelopes')
|
|
8
|
+
.option('--local', 'Watch only this machine');
|
|
9
|
+
setHelpSections(command, {
|
|
10
|
+
examples: `
|
|
11
|
+
# Subscribe to session changes for a long-lived UI consumer
|
|
12
|
+
agents sessions watch --json
|
|
13
|
+
|
|
14
|
+
# Subscribe only to this machine
|
|
15
|
+
agents sessions watch --json --local
|
|
16
|
+
`,
|
|
17
|
+
notes: `
|
|
18
|
+
- Each line is one versioned reset, upsert, remove, scope, or heartbeat envelope.
|
|
19
|
+
- rowKey is opaque. Order changes by streamId + sequence.
|
|
20
|
+
- An unavailable scope retains its last rows until that scope reconnects.
|
|
21
|
+
`,
|
|
22
|
+
});
|
|
23
|
+
command.action(async (_options, invoked) => {
|
|
24
|
+
const options = invoked.optsWithGlobals();
|
|
25
|
+
if (!options.json)
|
|
26
|
+
invoked.error('error: required option \'--json\' not specified');
|
|
27
|
+
const controller = new AbortController();
|
|
28
|
+
const stop = () => controller.abort();
|
|
29
|
+
const stopOnClosedConsumer = (error) => {
|
|
30
|
+
if (error.code === 'EPIPE')
|
|
31
|
+
controller.abort();
|
|
32
|
+
else {
|
|
33
|
+
process.exitCode = 1;
|
|
34
|
+
controller.abort(error);
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
process.once('SIGINT', stop);
|
|
38
|
+
process.once('SIGTERM', stop);
|
|
39
|
+
process.stdout.on('error', stopOnClosedConsumer);
|
|
40
|
+
try {
|
|
41
|
+
const emit = (event) => process.stdout.write(`${JSON.stringify(event)}\n`);
|
|
42
|
+
if (options.local)
|
|
43
|
+
await watchLocalSessions({ scope: machineId(), signal: controller.signal, emit });
|
|
44
|
+
else
|
|
45
|
+
await watchFleetSessions({ signal: controller.signal, emit });
|
|
46
|
+
}
|
|
47
|
+
finally {
|
|
48
|
+
process.off('SIGINT', stop);
|
|
49
|
+
process.off('SIGTERM', stop);
|
|
50
|
+
process.stdout.off('error', stopOnClosedConsumer);
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
}
|
|
@@ -3,8 +3,10 @@ import { type ProjectDef } from '../lib/projects.js';
|
|
|
3
3
|
import type { SessionAgentId, SessionMeta, ViewMode } from '../lib/session/types.js';
|
|
4
4
|
import { type ActiveSession } from '../lib/session/active.js';
|
|
5
5
|
import { gatherRemoteList, runOnPeer } from '../lib/session/remote-list.js';
|
|
6
|
+
import { type RemoteAgentsJsonParseResult } from '../lib/remote-agents-json.js';
|
|
6
7
|
import { type RunMeta } from '../lib/routines.js';
|
|
7
8
|
import { type PickedSession } from './sessions-picker.js';
|
|
9
|
+
import { type ComputerRunRow } from '../lib/computer/sessions-list.js';
|
|
8
10
|
import { type ToolSearchEnvelope, type ToolProgramCountEnvelope } from '../lib/session/tool-index.js';
|
|
9
11
|
interface SessionFilterOptions {
|
|
10
12
|
agent?: string;
|
|
@@ -254,6 +256,22 @@ export declare function serializeActiveSessionsForJson(sessions: ActiveSession[]
|
|
|
254
256
|
prLink: string | null;
|
|
255
257
|
viewingIn: string | null;
|
|
256
258
|
}>;
|
|
259
|
+
export interface SessionPickerJsonRow extends SessionMeta {
|
|
260
|
+
state: ActiveSession['status'] | 'inactive';
|
|
261
|
+
resumable: boolean;
|
|
262
|
+
unwatched: boolean;
|
|
263
|
+
viewingIn: string | null;
|
|
264
|
+
sourceDevice: string;
|
|
265
|
+
lastActivityMs: number;
|
|
266
|
+
pid: number | null;
|
|
267
|
+
recovery: {
|
|
268
|
+
command: 'agents';
|
|
269
|
+
args: string[];
|
|
270
|
+
cwd?: string;
|
|
271
|
+
} | null;
|
|
272
|
+
}
|
|
273
|
+
/** Canonical JSON row consumed by resume pickers and other session UIs. */
|
|
274
|
+
export declare function serializeSessionPickerRows(sessions: SessionMeta[], liveSessions: ActiveSession[], self?: string): SessionPickerJsonRow[];
|
|
257
275
|
/**
|
|
258
276
|
* Build the (one or two) rendered lines for a single active-session row.
|
|
259
277
|
* Indent is the leading whitespace (2 spaces for flat groups, 4 inside a window
|
|
@@ -332,6 +350,15 @@ export declare function groupSessionsByMachine(sessions: ActiveSession[], localM
|
|
|
332
350
|
* correlated, so they're all kept.
|
|
333
351
|
*/
|
|
334
352
|
export declare function dedupeByMachineSession(sessions: ActiveSession[]): ActiveSession[];
|
|
353
|
+
/**
|
|
354
|
+
* Narrow a gathered live set to the machines an explicit `--host`/`--device`
|
|
355
|
+
* scope named. The gather picks which boxes to ASK; this asserts what the answer
|
|
356
|
+
* may contain, and the two are not the same question: a host-dispatched run is
|
|
357
|
+
* reported by the box that dispatched it while executing somewhere else, so
|
|
358
|
+
* `--device <dispatcher>` used to list sessions that were not running there at
|
|
359
|
+
* all (RUSH-2479). No scope → unchanged. Pure; exported for unit testing.
|
|
360
|
+
*/
|
|
361
|
+
export declare function filterActiveSessionsByHostScope(sessions: ActiveSession[], hosts: string[] | undefined, self: string): ActiveSession[];
|
|
335
362
|
/**
|
|
336
363
|
* Order a merged listing so the local machine's sessions come first, then each
|
|
337
364
|
* remote machine as a contiguous block (more sessions first, then name), with
|
|
@@ -356,6 +383,14 @@ export declare function serializeSessionsJson(sessions: SessionMeta[]): string;
|
|
|
356
383
|
* It includes only launch identity needed to route/resume. Transcript paths,
|
|
357
384
|
* extracted plans, costs, and content stay on the machine that owns them. */
|
|
358
385
|
export declare function serializeResolvedSessionsJson(sessions: SessionMeta[]): string;
|
|
386
|
+
/** Parse one peer's computer-run array without accepting banners or partial
|
|
387
|
+
* JSON. The fan-out boundary supplies the machine name when an older peer row
|
|
388
|
+
* omitted it. */
|
|
389
|
+
export declare function parseRemoteComputerSessionRows(stdout: string, machine: string): RemoteAgentsJsonParseResult<ComputerRunRow>;
|
|
390
|
+
/** Collect computer history from named peers, or every automatic peer when
|
|
391
|
+
* hosts is omitted. Every peer is forced to JSON and receives the recursion
|
|
392
|
+
* guard through the shared fleet transport. */
|
|
393
|
+
export declare function gatherRemoteComputerSessionRows(hosts?: string[]): Promise<ComputerRunRow[]>;
|
|
359
394
|
/**
|
|
360
395
|
* Whether the local machine's sessions belong in an `--active` view. Local is
|
|
361
396
|
* included by default; an explicit `--host`/`--device` list scopes the view to
|
|
@@ -829,6 +864,11 @@ export type MetadataResolveOutcome = {
|
|
|
829
864
|
* the wrong session (whichever peer replied first). Labels therefore stay
|
|
830
865
|
* all-settle so a cross-machine label conflict surfaces as an ambiguity, and a
|
|
831
866
|
* short-id PREFIX stays all-settle for the same reason (RUSH-2203).
|
|
867
|
+
*
|
|
868
|
+
* This is about cancelling a sweep that is still IN FLIGHT, where a peer that
|
|
869
|
+
* has not answered yet is still expected to. It is deliberately stricter than
|
|
870
|
+
* `isUniqueEnoughSelector`, which decides what to do once the sweep is OVER and
|
|
871
|
+
* a peer has definitively not answered — see SES-9a.
|
|
832
872
|
*/
|
|
833
873
|
export declare function isDefinitiveMatch(session: SessionMeta, selector: string): boolean;
|
|
834
874
|
/**
|
|
@@ -849,9 +889,20 @@ export declare function fleetCandidatesByQuery(rows: SessionMeta[], query: strin
|
|
|
849
889
|
export declare function metadataResolveForwardedArgs(selector: string, scope: Pick<SessionFilterOptions, 'agent' | 'project'>): string[];
|
|
850
890
|
/** Build the local-only peer argv for a distributed tool search. */
|
|
851
891
|
export declare function toolSearchForwardedArgs(argv: string[], hosts: string[]): string[];
|
|
852
|
-
/**
|
|
853
|
-
*
|
|
854
|
-
*
|
|
892
|
+
/**
|
|
893
|
+
* Whether a selector names ONE session precisely enough to resolve from the
|
|
894
|
+
* reachable fleet alone when some peer did not answer (SES-9a).
|
|
895
|
+
*
|
|
896
|
+
* Deliberately stricter than `looksLikeSessionId`, which accepts any 6+ char
|
|
897
|
+
* `[0-9a-f-]` run and so matches ordinary words (`facade`, `decade`, `beaded`).
|
|
898
|
+
* Those are keywords a user typed as a search, not identifiers, and they must
|
|
899
|
+
* keep waiting for every peer.
|
|
900
|
+
*/
|
|
901
|
+
export declare function isUniqueEnoughSelector(selector: string): boolean;
|
|
902
|
+
/** Resolution fails closed for keywords and labels when a peer did not answer.
|
|
903
|
+
* An id-shaped selector at least `SHORT_SESSION_ID_WIDTH` hex chars wide (or a
|
|
904
|
+
* complete id) resolves from a single reachable hit even when an unrelated
|
|
905
|
+
* registered device is offline — see SES-9a for the accepted collision risk. */
|
|
855
906
|
export declare function metadataResolveOutcome(localMatches: SessionMeta[], remote: {
|
|
856
907
|
sessions: SessionMeta[];
|
|
857
908
|
unreachable: string[];
|
|
@@ -864,6 +915,18 @@ export declare function resolveSessionMetadataValue(selector: string, scope?: {
|
|
|
864
915
|
local?: boolean;
|
|
865
916
|
hosts?: string[];
|
|
866
917
|
}, deps?: Pick<FleetResolveDeps, 'gatherRemoteList'>): Promise<MetadataResolveOutcome>;
|
|
918
|
+
/** Resolve one selector to indexed metadata across the fleet without reading or
|
|
919
|
+
* rendering transcript events. A peer answering the parent sweep returns every
|
|
920
|
+
* local candidate; the parent performs the one logical-session uniqueness gate.
|
|
921
|
+
* Backs `agents sessions --resolve <selector> --json`. Exported (deps already
|
|
922
|
+
* injectable) so tests can drive this real call site against a fake fan-out
|
|
923
|
+
* instead of only the pure resolver it wraps. */
|
|
924
|
+
export declare function resolveSessionMetadata(selector: string, scope: {
|
|
925
|
+
agent?: string;
|
|
926
|
+
project?: string;
|
|
927
|
+
local?: boolean;
|
|
928
|
+
hosts?: string[];
|
|
929
|
+
}, deps?: Pick<FleetResolveDeps, 'gatherRemoteList'>): Promise<void>;
|
|
867
930
|
/**
|
|
868
931
|
* Locate a full session id or short id prefix across the online fleet and render it from the machine
|
|
869
932
|
* that holds it. The local disk already missed; this fans `sessions <id> --json
|