@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
|
@@ -25,8 +25,8 @@
|
|
|
25
25
|
*/
|
|
26
26
|
/**
|
|
27
27
|
* How long an IDE window's registry slice may go without a refresh before we
|
|
28
|
-
* treat that window as gone.
|
|
29
|
-
* every 4 minutes (`KEEPALIVE_FORCE_MS` in `apps/
|
|
28
|
+
* treat that window as gone. AGI EXT force-republishes its slice
|
|
29
|
+
* every 4 minutes (`KEEPALIVE_FORCE_MS` in `apps/ext/src/vscode/foreman.registry.ts`)
|
|
30
30
|
* and on every terminal open/close, so a slice this old means the window is no
|
|
31
31
|
* longer running — it is not merely quiet. Deliberately the same 10 minutes the
|
|
32
32
|
* extension itself uses to garbage-collect a peer window's slice, so the CLI and
|
|
@@ -43,7 +43,28 @@ export interface PidSessionEntry {
|
|
|
43
43
|
tmuxPane?: string;
|
|
44
44
|
startedAtMs: number;
|
|
45
45
|
}
|
|
46
|
+
export declare function isSessionIdShape(value: string): boolean;
|
|
46
47
|
export declare function extractSessionIdArg(args: string[]): string | undefined;
|
|
48
|
+
/**
|
|
49
|
+
* Read a live process's original argv (best-effort).
|
|
50
|
+
*
|
|
51
|
+
* Linux: NUL-separated `/proc/<pid>/cmdline`. Darwin: `ps -ww -o args=` then
|
|
52
|
+
* whitespace-split (good enough for Claude's `--session-id <uuid>` tokens;
|
|
53
|
+
* not a full shell-quote parser). Other platforms: undefined.
|
|
54
|
+
*
|
|
55
|
+
* RUSH-2384: the by-pid registry is often empty mid-run (launch pid was a
|
|
56
|
+
* wrapper that exited, prune wiped it, or the agent was not launched via
|
|
57
|
+
* `agents run`). The live process still carries `--session-id` on its argv —
|
|
58
|
+
* the same signal the incident used to prove the session was alive — so the
|
|
59
|
+
* active scan and `agents message` can recover identity without the registry.
|
|
60
|
+
*/
|
|
61
|
+
export declare function readProcessArgv(pid: number): string[] | undefined;
|
|
62
|
+
/**
|
|
63
|
+
* Exact session id a live agent process was launched with, read from its
|
|
64
|
+
* current argv. Undefined when the process is gone, the platform can't expose
|
|
65
|
+
* argv, or the vector carries no `--session-id`.
|
|
66
|
+
*/
|
|
67
|
+
export declare function sessionIdFromLivePid(pid: number): string | undefined;
|
|
47
68
|
/** Record a launched agent process. Never throws — the registry is an optimization. */
|
|
48
69
|
export declare function writePidSessionEntry(entry: PidSessionEntry): void;
|
|
49
70
|
/** Look up a live pid's recorded session. Returns undefined if absent/corrupt. */
|
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
*/
|
|
19
19
|
import fs from 'fs';
|
|
20
20
|
import path from 'path';
|
|
21
|
+
import { execFileSync } from 'child_process';
|
|
21
22
|
import { getTerminalsDir } from '../state.js';
|
|
22
23
|
/**
|
|
23
24
|
* Pull an explicit `--session-id <uuid>` (or `--session-id=<uuid>`) out of a
|
|
@@ -27,6 +28,9 @@ import { getTerminalsDir } from '../state.js';
|
|
|
27
28
|
* gets from generating the id itself.
|
|
28
29
|
*/
|
|
29
30
|
const SESSION_ID_VALUE_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
31
|
+
export function isSessionIdShape(value) {
|
|
32
|
+
return SESSION_ID_VALUE_RE.test(value);
|
|
33
|
+
}
|
|
30
34
|
export function extractSessionIdArg(args) {
|
|
31
35
|
for (let i = 0; i < args.length; i++) {
|
|
32
36
|
const a = args[i];
|
|
@@ -43,6 +47,59 @@ export function extractSessionIdArg(args) {
|
|
|
43
47
|
}
|
|
44
48
|
return undefined;
|
|
45
49
|
}
|
|
50
|
+
/**
|
|
51
|
+
* Read a live process's original argv (best-effort).
|
|
52
|
+
*
|
|
53
|
+
* Linux: NUL-separated `/proc/<pid>/cmdline`. Darwin: `ps -ww -o args=` then
|
|
54
|
+
* whitespace-split (good enough for Claude's `--session-id <uuid>` tokens;
|
|
55
|
+
* not a full shell-quote parser). Other platforms: undefined.
|
|
56
|
+
*
|
|
57
|
+
* RUSH-2384: the by-pid registry is often empty mid-run (launch pid was a
|
|
58
|
+
* wrapper that exited, prune wiped it, or the agent was not launched via
|
|
59
|
+
* `agents run`). The live process still carries `--session-id` on its argv —
|
|
60
|
+
* the same signal the incident used to prove the session was alive — so the
|
|
61
|
+
* active scan and `agents message` can recover identity without the registry.
|
|
62
|
+
*/
|
|
63
|
+
export function readProcessArgv(pid) {
|
|
64
|
+
if (!pid || pid < 1)
|
|
65
|
+
return undefined;
|
|
66
|
+
if (process.platform === 'linux') {
|
|
67
|
+
try {
|
|
68
|
+
const buf = fs.readFileSync(`/proc/${pid}/cmdline`);
|
|
69
|
+
const parts = buf.toString('utf8').split('\0').filter(Boolean);
|
|
70
|
+
return parts.length > 0 ? parts : undefined;
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
return undefined;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
if (process.platform === 'darwin') {
|
|
77
|
+
try {
|
|
78
|
+
const out = execFileSync('ps', ['-ww', '-p', String(pid), '-o', 'args='], {
|
|
79
|
+
encoding: 'utf-8',
|
|
80
|
+
stdio: ['ignore', 'pipe', 'ignore'],
|
|
81
|
+
}).trim();
|
|
82
|
+
if (!out)
|
|
83
|
+
return undefined;
|
|
84
|
+
return out.split(/\s+/);
|
|
85
|
+
}
|
|
86
|
+
catch {
|
|
87
|
+
return undefined;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return undefined;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Exact session id a live agent process was launched with, read from its
|
|
94
|
+
* current argv. Undefined when the process is gone, the platform can't expose
|
|
95
|
+
* argv, or the vector carries no `--session-id`.
|
|
96
|
+
*/
|
|
97
|
+
export function sessionIdFromLivePid(pid) {
|
|
98
|
+
const argv = readProcessArgv(pid);
|
|
99
|
+
if (!argv)
|
|
100
|
+
return undefined;
|
|
101
|
+
return extractSessionIdArg(argv);
|
|
102
|
+
}
|
|
46
103
|
function pidRegistryDir() {
|
|
47
104
|
return path.join(getTerminalsDir(), 'by-pid');
|
|
48
105
|
}
|
|
@@ -44,7 +44,21 @@ export function parseRemoteActive(stdout, machine) {
|
|
|
44
44
|
const out = [];
|
|
45
45
|
for (const x of parsed) {
|
|
46
46
|
if (x && typeof x === 'object' && !Array.isArray(x)) {
|
|
47
|
-
|
|
47
|
+
// The dialed machine still wins by default. That is deliberate: the peer
|
|
48
|
+
// reports `machineId()` (its hostname) while we key on the REGISTERED
|
|
49
|
+
// device name, and stamping ours is the only thing reconciling the two —
|
|
50
|
+
// drop it and a device whose registered name differs from its hostname
|
|
51
|
+
// silently answers a `--device <name>` scope with zero rows.
|
|
52
|
+
//
|
|
53
|
+
// The one row that must keep its own answer is an offloaded run, whose
|
|
54
|
+
// execution host is a THIRD box, not the peer we dialed
|
|
55
|
+
// (foldExecutionMachine, RUSH-2479). `offloadedFrom` marks exactly that
|
|
56
|
+
// row, so it is the discriminator rather than "the peer said something".
|
|
57
|
+
const reported = x;
|
|
58
|
+
const row = {
|
|
59
|
+
...reported,
|
|
60
|
+
machine: reported.offloadedFrom && reported.machine ? reported.machine : machine,
|
|
61
|
+
};
|
|
48
62
|
row.viewingIn = parseViewingIn(x.viewingIn);
|
|
49
63
|
out.push(row);
|
|
50
64
|
}
|
|
@@ -58,7 +58,7 @@ export function buildForwardedArgs(argv, hosts = new Set()) {
|
|
|
58
58
|
const out = [];
|
|
59
59
|
for (let i = 0; i < args.length; i++) {
|
|
60
60
|
const a = args[i];
|
|
61
|
-
if (a === '--host' || a === '-H' || a === '--device') {
|
|
61
|
+
if (a === '--host' || a === '-H' || a === '--device' || a === '--devices') {
|
|
62
62
|
// Commander's `<target...>` variadic accepts both `--host a --host b` and
|
|
63
63
|
// `--host a b` — consume every consecutive token that is a known host so
|
|
64
64
|
// the variadic form doesn't leak the extra hosts into the remote argv.
|
|
@@ -75,7 +75,7 @@ export function buildForwardedArgs(argv, hosts = new Set()) {
|
|
|
75
75
|
}
|
|
76
76
|
continue;
|
|
77
77
|
}
|
|
78
|
-
if (a.startsWith('--host=') || a.startsWith('-H=') || a.startsWith('--device='))
|
|
78
|
+
if (a.startsWith('--host=') || a.startsWith('-H=') || a.startsWith('--device=') || a.startsWith('--devices='))
|
|
79
79
|
continue;
|
|
80
80
|
if (/^-H.+/.test(a))
|
|
81
81
|
continue; // glued short form: -Hyosemite-s1
|
|
@@ -1,15 +1,11 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type ActiveSession } from './active.js';
|
|
2
2
|
/**
|
|
3
3
|
* How long a snapshot may be served before a reader re-gathers.
|
|
4
4
|
* Short on purpose: live status (running/idle/waiting) must not go stale.
|
|
5
|
-
*
|
|
6
|
-
*
|
|
5
|
+
* One-shot readers may re-gather after this ceiling. Long-lived watchers never
|
|
6
|
+
* do: they read one reset then tail the canonical writer journal.
|
|
7
7
|
*/
|
|
8
8
|
export declare const DEFAULT_ACTIVE_CACHE_MAX_AGE_MS = 15000;
|
|
9
|
-
/** Daemon warm interval — below the freshness ceiling to avoid an expiry gap. */
|
|
10
|
-
export declare const SESSION_CACHE_WARM_INTERVAL_MS = 10000;
|
|
11
|
-
/** Kick off the first warm shortly after daemon start, staggered off bootstrap. */
|
|
12
|
-
export declare const SESSION_CACHE_WARM_KICKOFF_MS = 5000;
|
|
13
9
|
/** Snapshot scope: this host only, or a fleet-wide merge written by a reader. */
|
|
14
10
|
export type ActiveCacheScope = 'local' | 'fleet';
|
|
15
11
|
export interface ActiveSessionsSnapshot {
|
|
@@ -21,6 +17,14 @@ export interface ActiveSessionsSnapshot {
|
|
|
21
17
|
/** Peer count from the last fleet gather (fleet scope only). */
|
|
22
18
|
remoteDeviceCount?: number;
|
|
23
19
|
}
|
|
20
|
+
export interface ActiveSessionsJournalRecord {
|
|
21
|
+
version: 1;
|
|
22
|
+
scope: ActiveCacheScope;
|
|
23
|
+
capturedAt: number;
|
|
24
|
+
upserts: ActiveSession[];
|
|
25
|
+
removes: string[];
|
|
26
|
+
}
|
|
27
|
+
export declare function activeSessionJournalIdentity(row: ActiveSession): string;
|
|
24
28
|
/**
|
|
25
29
|
* Per-session fields that are stable until the transcript changes. Keyed on
|
|
26
30
|
* transcript mtime so a rewrite invalidates them. Live status is intentionally
|
|
@@ -61,6 +65,9 @@ export declare function setActiveSessionsSnapshotPathForTest(p: string | null):
|
|
|
61
65
|
export declare function clearActiveSnapshotMemoryForTest(): void;
|
|
62
66
|
/** Test seam: redirect the immutable-memo file. Returns the previous override. */
|
|
63
67
|
export declare function setImmutableMemoPathForTest(p: string | null): string | null;
|
|
68
|
+
/** Test seam: redirect the append-only live-state journal. */
|
|
69
|
+
export declare function setActiveSessionsJournalPathForTest(p: string | null): string | null;
|
|
70
|
+
export declare function activeSessionsJournalPath(): string;
|
|
64
71
|
/** Read one scope from the snapshot file (best-effort; missing/corrupt → null). */
|
|
65
72
|
export declare function readActiveSessionsCache(scope: ActiveCacheScope): ActiveSessionsSnapshot | null;
|
|
66
73
|
/**
|
|
@@ -8,8 +8,9 @@
|
|
|
8
8
|
*
|
|
9
9
|
* Pattern mirrors {@link ../devices/stats-cache.ts} / {@link ../fleet-status.ts}:
|
|
10
10
|
*
|
|
11
|
-
* - **Daemon
|
|
12
|
-
*
|
|
11
|
+
* - **Daemon publish:** each daemon publishes THIS host's local active sessions
|
|
12
|
+
* (`publishLocalActiveSessions`). Each write appends row deltas to the journal
|
|
13
|
+
* consumed by long-lived watchers. Publish-own only — no
|
|
13
14
|
* cross-host SSH from the daemon (avoids the N² fan-out of RUSH-2061).
|
|
14
15
|
* - **Readers** (`loadLocalActiveSessions`, fleet path in `gatherActiveSessions`)
|
|
15
16
|
* serve the warm snapshot when it is within {@link DEFAULT_ACTIVE_CACHE_MAX_AGE_MS};
|
|
@@ -26,21 +27,22 @@ import * as fs from 'fs';
|
|
|
26
27
|
import * as path from 'path';
|
|
27
28
|
import { createMemoryCache } from '../memory-cache.js';
|
|
28
29
|
import { getCacheDir } from '../state.js';
|
|
30
|
+
import { sessionProcessIsLocal } from './active.js';
|
|
29
31
|
/** Snapshot file under `getCacheDir()` (regenerable, gitignored). */
|
|
30
32
|
const SNAPSHOT_FILE = '.active-sessions.json';
|
|
31
33
|
/** Immutable-field memo file (keyed by sessionId + transcript mtime). */
|
|
32
34
|
const IMMUTABLE_FILE = '.active-session-immutable.json';
|
|
35
|
+
const JOURNAL_FILE = '.active-sessions.journal.jsonl';
|
|
33
36
|
/**
|
|
34
37
|
* How long a snapshot may be served before a reader re-gathers.
|
|
35
38
|
* Short on purpose: live status (running/idle/waiting) must not go stale.
|
|
36
|
-
*
|
|
37
|
-
*
|
|
39
|
+
* One-shot readers may re-gather after this ceiling. Long-lived watchers never
|
|
40
|
+
* do: they read one reset then tail the canonical writer journal.
|
|
38
41
|
*/
|
|
39
42
|
export const DEFAULT_ACTIVE_CACHE_MAX_AGE_MS = 15_000;
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
export const SESSION_CACHE_WARM_KICKOFF_MS = 5_000;
|
|
43
|
+
export function activeSessionJournalIdentity(row) {
|
|
44
|
+
return row.sessionId ?? `${row.context}:${row.kind}:${row.pid ?? ''}:${row.startedAtMs ?? ''}`;
|
|
45
|
+
}
|
|
44
46
|
/** Process-local L1. The atomic snapshot remains the cross-process source. */
|
|
45
47
|
const activeSnapshotMemory = createMemoryCache({
|
|
46
48
|
max: 2,
|
|
@@ -95,6 +97,7 @@ export const LIVE_STATUS_KEYS = [
|
|
|
95
97
|
// ── path overrides (test seam) ─────────────────────────────────────────────
|
|
96
98
|
let snapshotPathOverride = null;
|
|
97
99
|
let immutablePathOverride = null;
|
|
100
|
+
let journalPathOverride = null;
|
|
98
101
|
/** Test seam: redirect the snapshot file. Returns the previous override. */
|
|
99
102
|
export function setActiveSessionsSnapshotPathForTest(p) {
|
|
100
103
|
const prev = snapshotPathOverride;
|
|
@@ -112,12 +115,22 @@ export function setImmutableMemoPathForTest(p) {
|
|
|
112
115
|
immutablePathOverride = p;
|
|
113
116
|
return prev;
|
|
114
117
|
}
|
|
118
|
+
/** Test seam: redirect the append-only live-state journal. */
|
|
119
|
+
export function setActiveSessionsJournalPathForTest(p) {
|
|
120
|
+
const prev = journalPathOverride;
|
|
121
|
+
journalPathOverride = p;
|
|
122
|
+
return prev;
|
|
123
|
+
}
|
|
115
124
|
function snapshotPath() {
|
|
116
125
|
return snapshotPathOverride ?? path.join(getCacheDir(), SNAPSHOT_FILE);
|
|
117
126
|
}
|
|
118
127
|
function immutablePath() {
|
|
119
128
|
return immutablePathOverride ?? path.join(getCacheDir(), IMMUTABLE_FILE);
|
|
120
129
|
}
|
|
130
|
+
export function activeSessionsJournalPath() {
|
|
131
|
+
return journalPathOverride
|
|
132
|
+
?? (snapshotPathOverride ? `${snapshotPathOverride}.journal.jsonl` : path.join(getCacheDir(), JOURNAL_FILE));
|
|
133
|
+
}
|
|
121
134
|
// ── snapshot read / write ──────────────────────────────────────────────────
|
|
122
135
|
/** Read one scope from the snapshot file (best-effort; missing/corrupt → null). */
|
|
123
136
|
export function readActiveSessionsCache(scope) {
|
|
@@ -163,12 +176,34 @@ export function writeActiveSessionsCache(scope, sessions, opts = {}) {
|
|
|
163
176
|
catch {
|
|
164
177
|
// empty
|
|
165
178
|
}
|
|
179
|
+
const hadPrevious = Boolean(entries[scope]);
|
|
180
|
+
const previousSessions = entries[scope]?.sessions ?? [];
|
|
166
181
|
entries[scope] = snap;
|
|
167
182
|
const body = { version: 1, entries };
|
|
168
183
|
// Atomic replace so a concurrent reader never sees a partial write.
|
|
169
184
|
const tmp = `${snapshotPath()}.tmp`;
|
|
170
185
|
fs.writeFileSync(tmp, JSON.stringify(body));
|
|
171
186
|
fs.renameSync(tmp, snapshotPath());
|
|
187
|
+
// The snapshot writer is the canonical publisher. Watchers tail this
|
|
188
|
+
// append-only journal and compute stream deltas; they never trigger their
|
|
189
|
+
// own full active-session gather on a timer.
|
|
190
|
+
const previous = new Map(previousSessions.map((row) => [activeSessionJournalIdentity(row), row]));
|
|
191
|
+
const next = new Map(sessions.map((row) => [activeSessionJournalIdentity(row), row]));
|
|
192
|
+
const upserts = sessions.filter((row) => {
|
|
193
|
+
const before = previous.get(activeSessionJournalIdentity(row));
|
|
194
|
+
return !before || JSON.stringify(before) !== JSON.stringify(row);
|
|
195
|
+
});
|
|
196
|
+
const removes = [...previous.keys()].filter((key) => !next.has(key));
|
|
197
|
+
try {
|
|
198
|
+
if (!hadPrevious || upserts.length > 0 || removes.length > 0) {
|
|
199
|
+
fs.appendFileSync(activeSessionsJournalPath(), `${JSON.stringify({
|
|
200
|
+
version: 1, scope, capturedAt: snap.capturedAt, upserts, removes,
|
|
201
|
+
})}\n`);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
catch {
|
|
205
|
+
// Journal delivery is best-effort; the canonical snapshot remains valid.
|
|
206
|
+
}
|
|
172
207
|
activeSnapshotMemory.set(scope, snap);
|
|
173
208
|
}
|
|
174
209
|
catch {
|
|
@@ -392,7 +427,14 @@ export async function loadFleetActiveSessions(opts) {
|
|
|
392
427
|
// with ghost rows would make watchdog / `--local` report sessions that are
|
|
393
428
|
// gone (review on RUSH-2062 / PR #2116).
|
|
394
429
|
if (self !== undefined) {
|
|
395
|
-
|
|
430
|
+
// "Local" here means the PROCESS is on this box, which is not `machine ===
|
|
431
|
+
// self` for an offloaded run: its shim runs here while the agent executes on
|
|
432
|
+
// the peer (RUSH-2479). The other writer of this same key,
|
|
433
|
+
// `loadLocalActiveSessions`, seeds from `getActiveSessions({localOnly:true})`
|
|
434
|
+
// and keeps that shim — so comparing `machine` here would make the two
|
|
435
|
+
// disagree and leave `--local` showing or hiding the row depending on which
|
|
436
|
+
// surface last warmed the 15s cache.
|
|
437
|
+
const localOnly = live.sessions.filter((s) => sessionProcessIsLocal(s, self));
|
|
396
438
|
writeCache('local', localOnly, { capturedAt: now });
|
|
397
439
|
}
|
|
398
440
|
return {
|
|
@@ -60,7 +60,7 @@ export interface DetectedTicket {
|
|
|
60
60
|
}
|
|
61
61
|
/**
|
|
62
62
|
* Detect per-session rate-limit / usage-limit signals in assistant or error
|
|
63
|
-
* text (RUSH-1523). Matches the same shapes
|
|
63
|
+
* text (RUSH-1523). Matches the same shapes the ext's prewarm detectBlockingPrompt
|
|
64
64
|
* uses, plus common Claude/Codex/Gemini limit strings.
|
|
65
65
|
*/
|
|
66
66
|
export declare function detectRateLimited(text?: string): boolean;
|
|
@@ -91,7 +91,7 @@ export interface SessionState {
|
|
|
91
91
|
plan?: string;
|
|
92
92
|
/**
|
|
93
93
|
* Live plan progress from the most recent `TodoWrite` (RUSH-1380). Present when
|
|
94
|
-
* the session has written a todo list; drives the
|
|
94
|
+
* the session has written a todo list; drives the Fleet N/M pill +
|
|
95
95
|
* checklist, notably for remote/device-dispatched agents with no local stream.
|
|
96
96
|
*/
|
|
97
97
|
todos?: TodoProgress;
|
|
@@ -18,7 +18,7 @@ import * as path from 'path';
|
|
|
18
18
|
import { isCompletedTodoStatus, SNAPSHOT_TODO_TOOLS, summarizeToolUse } from './parse.js';
|
|
19
19
|
/**
|
|
20
20
|
* Detect per-session rate-limit / usage-limit signals in assistant or error
|
|
21
|
-
* text (RUSH-1523). Matches the same shapes
|
|
21
|
+
* text (RUSH-1523). Matches the same shapes the ext's prewarm detectBlockingPrompt
|
|
22
22
|
* uses, plus common Claude/Codex/Gemini limit strings.
|
|
23
23
|
*/
|
|
24
24
|
export function detectRateLimited(text) {
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* R2 credential resolution + this machine's stable identity.
|
|
3
|
-
* `agents sessions export --encrypt` / `import`
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
2
|
+
* R2 credential resolution + this machine's stable identity. Two consumers read
|
|
3
|
+
* these fields: `agents sessions export --encrypt` / `import` use only the shared
|
|
4
|
+
* `R2_SYNC_ENC_KEY` transcript key (`resolveSyncEncKey`), falling back to an
|
|
5
|
+
* ephemeral key when no bundle is configured; and the off-box backup target
|
|
6
|
+
* (`agents sessions export --to-r2` / `import --from-r2`, RUSH-2437) uses the full
|
|
7
|
+
* credential set (account/bucket/access keys/endpoint) to talk to R2 through the
|
|
8
|
+
* network client in `./r2.ts`. The `--to-r2`/`--from-r2` paths gate on
|
|
9
|
+
* `isSyncConfigured()` and fail loud when the bundle is absent (no silent
|
|
10
|
+
* fallback). This is a pure on-demand backup target, NOT the retired R2/CRDT
|
|
11
|
+
* background sync. Credentials come from the `r2.backups` secrets bundle (OS
|
|
12
12
|
* keychain on macOS, libsecret on Linux) — never from env or disk.
|
|
13
13
|
*/
|
|
14
14
|
/** Secrets bundle holding the R2 credentials. */
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* R2 credential resolution + this machine's stable identity.
|
|
3
|
-
* `agents sessions export --encrypt` / `import`
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
2
|
+
* R2 credential resolution + this machine's stable identity. Two consumers read
|
|
3
|
+
* these fields: `agents sessions export --encrypt` / `import` use only the shared
|
|
4
|
+
* `R2_SYNC_ENC_KEY` transcript key (`resolveSyncEncKey`), falling back to an
|
|
5
|
+
* ephemeral key when no bundle is configured; and the off-box backup target
|
|
6
|
+
* (`agents sessions export --to-r2` / `import --from-r2`, RUSH-2437) uses the full
|
|
7
|
+
* credential set (account/bucket/access keys/endpoint) to talk to R2 through the
|
|
8
|
+
* network client in `./r2.ts`. The `--to-r2`/`--from-r2` paths gate on
|
|
9
|
+
* `isSyncConfigured()` and fail loud when the bundle is absent (no silent
|
|
10
|
+
* fallback). This is a pure on-demand backup target, NOT the retired R2/CRDT
|
|
11
|
+
* background sync. Credentials come from the `r2.backups` secrets bundle (OS
|
|
12
12
|
* keychain on macOS, libsecret on Linux) — never from env or disk.
|
|
13
13
|
*/
|
|
14
14
|
import { readAndResolveBundleEnv } from '../../secrets/bundles.js';
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal S3-compatible client for Cloudflare R2, built on aws4fetch (SigV4
|
|
3
|
+
* over the platform `fetch` + WebCrypto — works identically under Bun and
|
|
4
|
+
* Node >= 22). Only the verbs the backup target needs: put / get / head / list /
|
|
5
|
+
* delete.
|
|
6
|
+
*
|
|
7
|
+
* No mounting, no FUSE: this is a plain object-store client driven on demand by
|
|
8
|
+
* `agents sessions export --to-r2` / `import --from-r2`, which is the only
|
|
9
|
+
* approach that is seamless on both macOS and Linux (Mountpoint for S3 is
|
|
10
|
+
* Linux-only; rclone-mount needs macFUSE).
|
|
11
|
+
*/
|
|
12
|
+
import type { R2Config } from './config.js';
|
|
13
|
+
export interface HeadResult {
|
|
14
|
+
size: number;
|
|
15
|
+
etag: string;
|
|
16
|
+
}
|
|
17
|
+
export declare class R2Client {
|
|
18
|
+
private aws;
|
|
19
|
+
private base;
|
|
20
|
+
constructor(cfg: R2Config);
|
|
21
|
+
private url;
|
|
22
|
+
/** Upload an object. Overwrites unconditionally. */
|
|
23
|
+
put(key: string, body: string | Uint8Array, contentType?: string): Promise<void>;
|
|
24
|
+
/** Fetch an object as text, or null if it does not exist (404). */
|
|
25
|
+
get(key: string): Promise<string | null>;
|
|
26
|
+
/** HEAD an object for size + etag, or null if it does not exist. */
|
|
27
|
+
head(key: string): Promise<HeadResult | null>;
|
|
28
|
+
/** Delete an object (no error if it is already absent). */
|
|
29
|
+
delete(key: string): Promise<void>;
|
|
30
|
+
/** List immediate sub-prefixes under a prefix (delimiter '/'), e.g. machine dirs. */
|
|
31
|
+
listPrefixes(prefix: string): Promise<string[]>;
|
|
32
|
+
/** List all object keys under a prefix (handles pagination). */
|
|
33
|
+
list(prefix: string): Promise<string[]>;
|
|
34
|
+
}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal S3-compatible client for Cloudflare R2, built on aws4fetch (SigV4
|
|
3
|
+
* over the platform `fetch` + WebCrypto — works identically under Bun and
|
|
4
|
+
* Node >= 22). Only the verbs the backup target needs: put / get / head / list /
|
|
5
|
+
* delete.
|
|
6
|
+
*
|
|
7
|
+
* No mounting, no FUSE: this is a plain object-store client driven on demand by
|
|
8
|
+
* `agents sessions export --to-r2` / `import --from-r2`, which is the only
|
|
9
|
+
* approach that is seamless on both macOS and Linux (Mountpoint for S3 is
|
|
10
|
+
* Linux-only; rclone-mount needs macFUSE).
|
|
11
|
+
*/
|
|
12
|
+
import { AwsClient } from 'aws4fetch';
|
|
13
|
+
export class R2Client {
|
|
14
|
+
aws;
|
|
15
|
+
base;
|
|
16
|
+
constructor(cfg) {
|
|
17
|
+
this.aws = new AwsClient({
|
|
18
|
+
accessKeyId: cfg.accessKeyId,
|
|
19
|
+
secretAccessKey: cfg.secretAccessKey,
|
|
20
|
+
service: 's3',
|
|
21
|
+
region: 'auto',
|
|
22
|
+
});
|
|
23
|
+
this.base = `${cfg.endpoint}/${encodeURIComponent(cfg.bucket)}`;
|
|
24
|
+
}
|
|
25
|
+
url(key) {
|
|
26
|
+
const encoded = key.split('/').map(encodeURIComponent).join('/');
|
|
27
|
+
return `${this.base}/${encoded}`;
|
|
28
|
+
}
|
|
29
|
+
/** Upload an object. Overwrites unconditionally. */
|
|
30
|
+
async put(key, body, contentType = 'application/octet-stream') {
|
|
31
|
+
const res = await this.aws.fetch(this.url(key), {
|
|
32
|
+
method: 'PUT',
|
|
33
|
+
body,
|
|
34
|
+
headers: { 'content-type': contentType },
|
|
35
|
+
});
|
|
36
|
+
if (!res.ok)
|
|
37
|
+
throw new Error(`R2 PUT ${key} failed: ${res.status} ${await safeText(res)}`);
|
|
38
|
+
}
|
|
39
|
+
/** Fetch an object as text, or null if it does not exist (404). */
|
|
40
|
+
async get(key) {
|
|
41
|
+
const res = await this.aws.fetch(this.url(key), { method: 'GET' });
|
|
42
|
+
if (res.status === 404)
|
|
43
|
+
return null;
|
|
44
|
+
if (!res.ok)
|
|
45
|
+
throw new Error(`R2 GET ${key} failed: ${res.status} ${await safeText(res)}`);
|
|
46
|
+
return await res.text();
|
|
47
|
+
}
|
|
48
|
+
/** HEAD an object for size + etag, or null if it does not exist. */
|
|
49
|
+
async head(key) {
|
|
50
|
+
const res = await this.aws.fetch(this.url(key), { method: 'HEAD' });
|
|
51
|
+
if (res.status === 404)
|
|
52
|
+
return null;
|
|
53
|
+
if (!res.ok)
|
|
54
|
+
throw new Error(`R2 HEAD ${key} failed: ${res.status}`);
|
|
55
|
+
return {
|
|
56
|
+
size: Number(res.headers.get('content-length') ?? '0'),
|
|
57
|
+
etag: (res.headers.get('etag') ?? '').replace(/"/g, ''),
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
/** Delete an object (no error if it is already absent). */
|
|
61
|
+
async delete(key) {
|
|
62
|
+
const res = await this.aws.fetch(this.url(key), { method: 'DELETE' });
|
|
63
|
+
if (!res.ok && res.status !== 404) {
|
|
64
|
+
throw new Error(`R2 DELETE ${key} failed: ${res.status}`);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
/** List immediate sub-prefixes under a prefix (delimiter '/'), e.g. machine dirs. */
|
|
68
|
+
async listPrefixes(prefix) {
|
|
69
|
+
const prefixes = [];
|
|
70
|
+
let token;
|
|
71
|
+
do {
|
|
72
|
+
const params = new URLSearchParams({ 'list-type': '2', prefix, delimiter: '/' });
|
|
73
|
+
if (token)
|
|
74
|
+
params.set('continuation-token', token);
|
|
75
|
+
const res = await this.aws.fetch(`${this.base}?${params.toString()}`, { method: 'GET' });
|
|
76
|
+
if (!res.ok)
|
|
77
|
+
throw new Error(`R2 LIST(prefixes) ${prefix} failed: ${res.status} ${await safeText(res)}`);
|
|
78
|
+
const xml = await res.text();
|
|
79
|
+
for (const m of xml.matchAll(/<CommonPrefixes><Prefix>([^<]+)<\/Prefix><\/CommonPrefixes>/g)) {
|
|
80
|
+
prefixes.push(decodeXml(m[1]));
|
|
81
|
+
}
|
|
82
|
+
const truncated = /<IsTruncated>true<\/IsTruncated>/.test(xml);
|
|
83
|
+
token = truncated ? xml.match(/<NextContinuationToken>([^<]+)<\/NextContinuationToken>/)?.[1] : undefined;
|
|
84
|
+
} while (token);
|
|
85
|
+
return prefixes;
|
|
86
|
+
}
|
|
87
|
+
/** List all object keys under a prefix (handles pagination). */
|
|
88
|
+
async list(prefix) {
|
|
89
|
+
const keys = [];
|
|
90
|
+
let token;
|
|
91
|
+
do {
|
|
92
|
+
const params = new URLSearchParams({ 'list-type': '2', prefix });
|
|
93
|
+
if (token)
|
|
94
|
+
params.set('continuation-token', token);
|
|
95
|
+
const res = await this.aws.fetch(`${this.base}?${params.toString()}`, { method: 'GET' });
|
|
96
|
+
if (!res.ok)
|
|
97
|
+
throw new Error(`R2 LIST ${prefix} failed: ${res.status} ${await safeText(res)}`);
|
|
98
|
+
const xml = await res.text();
|
|
99
|
+
for (const m of xml.matchAll(/<Key>([^<]+)<\/Key>/g)) {
|
|
100
|
+
keys.push(decodeXml(m[1]));
|
|
101
|
+
}
|
|
102
|
+
const truncated = /<IsTruncated>true<\/IsTruncated>/.test(xml);
|
|
103
|
+
token = truncated ? xml.match(/<NextContinuationToken>([^<]+)<\/NextContinuationToken>/)?.[1] : undefined;
|
|
104
|
+
} while (token);
|
|
105
|
+
return keys;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
function decodeXml(s) {
|
|
109
|
+
return s
|
|
110
|
+
.replace(/&/g, '&')
|
|
111
|
+
.replace(/</g, '<')
|
|
112
|
+
.replace(/>/g, '>')
|
|
113
|
+
.replace(/"/g, '"')
|
|
114
|
+
.replace(/'/g, "'");
|
|
115
|
+
}
|
|
116
|
+
async function safeText(res) {
|
|
117
|
+
try {
|
|
118
|
+
return (await res.text()).slice(0, 200);
|
|
119
|
+
}
|
|
120
|
+
catch {
|
|
121
|
+
return '';
|
|
122
|
+
}
|
|
123
|
+
}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Computes a rolling tokens-per-second readout from a session transcript's raw
|
|
5
5
|
* content. This is the single source of truth for the throughput number the
|
|
6
|
-
*
|
|
6
|
+
* Fleet shows next to a running agent — the extension used to carry its
|
|
7
7
|
* own copy of this math (`computeOutputTokensPerSec`); it now reads `tokPerSec`
|
|
8
8
|
* straight off `agents sessions --active --json` instead (issue #741).
|
|
9
9
|
*/
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Computes a rolling tokens-per-second readout from a session transcript's raw
|
|
5
5
|
* content. This is the single source of truth for the throughput number the
|
|
6
|
-
*
|
|
6
|
+
* Fleet shows next to a running agent — the extension used to carry its
|
|
7
7
|
* own copy of this math (`computeOutputTokensPerSec`); it now reads `tokPerSec`
|
|
8
8
|
* straight off `agents sessions --active --json` instead (issue #741).
|
|
9
9
|
*/
|
|
@@ -17,6 +17,19 @@ export declare const SESSION_AGENTS: SessionAgentId[];
|
|
|
17
17
|
* of {@link SESSION_AGENTS}). The single predicate every session-index writer
|
|
18
18
|
* gates on, so "is this a trackable agent?" is decided in exactly one place.
|
|
19
19
|
*/
|
|
20
|
+
/**
|
|
21
|
+
* The tmux session name the CLI mints for an agent run: `ag-<agent>-<shortid>`.
|
|
22
|
+
*
|
|
23
|
+
* ONE definition. This shape was independently re-written as a regex literal in
|
|
24
|
+
* five places (focus's selector test, sessions-resume's direct-selector test,
|
|
25
|
+
* active's name parsers, actor-sidecar, and the deeplink parser); they drifted —
|
|
26
|
+
* focus accepted a 6+ hex suffix while the others required exactly 8 — which is
|
|
27
|
+
* how the same alias could be an "identity" to one code path and a keyword query
|
|
28
|
+
* to the next.
|
|
29
|
+
*/
|
|
30
|
+
export declare const AG_TMUX_NAME_RE: RegExp;
|
|
31
|
+
/** Whether `name` is an `ag-<agent>-<shortid>` tmux session name. */
|
|
32
|
+
export declare function isAgentTmuxAlias(name: string): boolean;
|
|
20
33
|
export declare function isSessionTrackedAgent(agent: string): agent is SessionAgentId;
|
|
21
34
|
/** A single normalized event within a session (message, tool call, thinking, etc.). */
|
|
22
35
|
export interface SessionEvent {
|
|
@@ -239,7 +252,7 @@ export interface SessionMeta {
|
|
|
239
252
|
* (Claude sessions only), captured at scan time. Present whenever the session
|
|
240
253
|
* ever entered plan-review; consumers can pair it with a live
|
|
241
254
|
* `awaitingReason === 'plan_review'` to decide whether it is still pending.
|
|
242
|
-
* Fills the gap that forced
|
|
255
|
+
* Fills the gap that forced AGI EXT to re-read raw JSONL to
|
|
243
256
|
* recover the plan text — the CLI now carries it on the metadata row.
|
|
244
257
|
*/
|
|
245
258
|
plan?: string;
|
|
@@ -326,6 +339,15 @@ export interface SessionMeta {
|
|
|
326
339
|
* `parseRemoteList`; transient (never persisted, stripped from --json).
|
|
327
340
|
*/
|
|
328
341
|
_remote?: boolean;
|
|
342
|
+
/**
|
|
343
|
+
* True when the transcript file is gone from disk but the session's user turns
|
|
344
|
+
* still live in the local DB (session_text), so the row is served and rendered
|
|
345
|
+
* from the DB instead of vanishing (RUSH-2436). Absent for a live session whose
|
|
346
|
+
* file is present. Backed by the persisted `archived_at` column.
|
|
347
|
+
*/
|
|
348
|
+
archived?: boolean;
|
|
349
|
+
/** Epoch ms the transcript file was first confirmed gone (pairs with {@link archived}). */
|
|
350
|
+
archivedAt?: number;
|
|
329
351
|
/** Terms that matched the current search query */
|
|
330
352
|
_matchedTerms?: string[];
|
|
331
353
|
/** BM25 relevance score from the most recent content-index search */
|