@phnx-labs/agents-cli 1.22.39 → 1.22.40
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 +294 -0
- package/README.md +111 -70
- package/dist/bin/agents +0 -0
- package/dist/bootstrap.js +45 -26
- package/dist/browser.js +2 -2
- package/dist/cli/command-registry.d.ts +135 -0
- package/dist/cli/command-registry.js +260 -0
- package/dist/commands/accounts.d.ts +20 -0
- package/dist/commands/accounts.js +186 -25
- package/dist/commands/apply.d.ts +3 -3
- package/dist/commands/apply.js +20 -63
- package/dist/commands/browser.js +206 -94
- package/dist/commands/budget.d.ts +7 -6
- package/dist/commands/budget.js +8 -7
- package/dist/commands/cloud.js +17 -20
- package/dist/commands/commands.js +1 -1
- package/dist/commands/computer-actions.d.ts +1 -35
- package/dist/commands/computer-actions.js +13 -181
- package/dist/commands/computer.d.ts +28 -3
- package/dist/commands/computer.js +93 -65
- package/dist/commands/config.js +16 -3
- package/dist/commands/cost.d.ts +2 -1
- package/dist/commands/cost.js +7 -6
- package/dist/commands/daemon.js +151 -4
- package/dist/commands/detach.js +1 -1
- package/dist/commands/doctor.js +19 -11
- package/dist/commands/events.js +1 -1
- package/dist/commands/exec.d.ts +2 -50
- package/dist/commands/exec.js +160 -215
- package/dist/commands/factory.js +1 -1
- package/dist/commands/feed.d.ts +2 -2
- package/dist/commands/feed.js +9 -12
- package/dist/commands/fleet-capture.js +25 -27
- package/dist/commands/focus.d.ts +2 -3
- package/dist/commands/focus.js +34 -9
- package/dist/commands/go.js +15 -5
- package/dist/commands/harness.d.ts +3 -3
- package/dist/commands/harness.js +53 -5
- package/dist/commands/hooks.js +1 -1
- package/dist/commands/import.js +2 -2
- package/dist/commands/insights.d.ts +5 -5
- package/dist/commands/insights.js +15 -9
- package/dist/commands/inspect.d.ts +2 -3
- package/dist/commands/inspect.js +4 -16
- package/dist/commands/logs.d.ts +2 -2
- package/dist/commands/logs.js +9 -9
- package/dist/commands/mcp.js +2 -2
- package/dist/commands/memory.js +1 -1
- package/dist/commands/message.d.ts +1 -1
- package/dist/commands/message.js +7 -7
- package/dist/commands/mine.d.ts +11 -8
- package/dist/commands/mine.js +11 -10
- package/dist/commands/models.js +1 -1
- package/dist/commands/modes.js +1 -1
- package/dist/commands/monitors.js +23 -6
- package/dist/commands/output.d.ts +7 -6
- package/dist/commands/output.js +11 -10
- package/dist/commands/packages.js +4 -4
- package/dist/commands/perf.js +1 -1
- package/dist/commands/permissions.js +49 -32
- package/dist/commands/plugins.d.ts +1 -1
- package/dist/commands/plugins.js +3 -3
- package/dist/commands/profiles.d.ts +6 -9
- package/dist/commands/profiles.js +8 -321
- package/dist/commands/projects.d.ts +9 -0
- package/dist/commands/projects.js +140 -8
- package/dist/commands/prune.js +5 -13
- package/dist/commands/refresh-rules.js +1 -1
- package/dist/commands/repo.d.ts +5 -7
- package/dist/commands/repo.js +34 -18
- package/dist/commands/resource-view.js +4 -0
- package/dist/commands/resume.d.ts +11 -7
- package/dist/commands/resume.js +82 -98
- package/dist/commands/route.d.ts +12 -0
- package/dist/commands/route.js +261 -0
- package/dist/commands/routines.d.ts +2 -3
- package/dist/commands/routines.js +120 -145
- package/dist/commands/rules.js +1 -1
- package/dist/commands/run-account-picker.d.ts +1 -1
- package/dist/commands/run-account-picker.js +2 -2
- package/dist/commands/run-broadcast.d.ts +21 -0
- package/dist/commands/run-broadcast.js +89 -0
- package/dist/commands/run-cloud.js +1 -1
- package/dist/commands/secrets-vault.d.ts +10 -0
- package/dist/commands/{login.js → secrets-vault.js} +34 -14
- package/dist/commands/secrets.d.ts +4 -4
- package/dist/commands/secrets.js +72 -63
- package/dist/commands/sessions-backfill.js +1 -1
- package/dist/commands/sessions-browser.d.ts +1 -1
- package/dist/commands/sessions-browser.js +9 -5
- package/dist/commands/sessions-export.js +2 -2
- package/dist/commands/sessions-inject.js +4 -5
- package/dist/commands/sessions-migrate.js +16 -27
- package/dist/commands/sessions-picker.d.ts +13 -0
- package/dist/commands/sessions-picker.js +182 -8
- package/dist/commands/sessions-resume.d.ts +7 -3
- package/dist/commands/sessions-resume.js +81 -33
- package/dist/commands/sessions-stats.js +2 -2
- package/dist/commands/sessions.d.ts +75 -68
- package/dist/commands/sessions.js +142 -180
- package/dist/commands/setup-computer.js +1 -1
- package/dist/commands/setup-fleet.js +3 -0
- package/dist/commands/setup-mine.d.ts +7 -3
- package/dist/commands/setup-mine.js +13 -8
- package/dist/commands/setup-secrets.js +2 -2
- package/dist/commands/setup-watchdog.js +2 -2
- package/dist/commands/setup.js +7 -2
- package/dist/commands/share.d.ts +65 -0
- package/dist/commands/share.js +253 -20
- package/dist/commands/skills.js +3 -3
- package/dist/commands/snapshot.d.ts +2 -2
- package/dist/commands/snapshot.js +9 -9
- package/dist/commands/ssh.d.ts +1 -1
- package/dist/commands/ssh.js +186 -64
- package/dist/commands/subagents.js +1 -1
- package/dist/commands/sync.js +24 -9
- package/dist/commands/teams.d.ts +2 -2
- package/dist/commands/teams.js +9 -18
- package/dist/commands/tmux.js +5 -1
- package/dist/commands/trash.js +1 -1
- package/dist/commands/usage.d.ts +1 -1
- package/dist/commands/usage.js +2 -2
- package/dist/commands/utils.d.ts +4 -14
- package/dist/commands/utils.js +6 -27
- package/dist/commands/versions.js +2 -2
- package/dist/commands/view.d.ts +9 -77
- package/dist/commands/view.js +23 -8
- package/dist/commands/watchdog.js +1 -1
- package/dist/commands/webhook.js +11 -25
- package/dist/commands/workflows.js +1 -1
- package/dist/index.js +1 -1
- package/dist/lib/account-capabilities.d.ts +39 -0
- package/dist/lib/account-capabilities.js +59 -0
- package/dist/lib/account-catalog.js +1 -1
- package/dist/lib/account-registry.d.ts +66 -0
- package/dist/lib/account-registry.js +151 -5
- package/dist/lib/{rotate.d.ts → accounting/rotate.d.ts} +4 -4
- package/dist/lib/{rotate.js → accounting/rotate.js} +8 -8
- package/dist/lib/{usage.d.ts → accounting/usage.d.ts} +4 -4
- package/dist/lib/{usage.js → accounting/usage.js} +11 -11
- package/dist/lib/agent-spec/provider.js +1 -1
- package/dist/lib/agents.d.ts +72 -4
- package/dist/lib/agents.js +231 -199
- package/dist/lib/answer-router.d.ts +2 -2
- package/dist/lib/ask-classifier.d.ts +1 -1
- package/dist/lib/ask-classifier.js +1 -1
- package/dist/lib/audit/log.js +1 -1
- package/dist/lib/auth-health.d.ts +1 -1
- package/dist/lib/auth-health.js +2 -2
- package/dist/lib/brand.js +1 -1
- package/dist/lib/browser/caller-identity.d.ts +28 -0
- package/dist/lib/browser/caller-identity.js +156 -0
- package/dist/lib/browser/cdp.js +1 -1
- package/dist/lib/browser/drivers/ssh.d.ts +1 -1
- package/dist/lib/browser/drivers/ssh.js +2 -2
- package/dist/lib/browser/hygiene.d.ts +10 -2
- package/dist/lib/browser/hygiene.js +7 -4
- package/dist/lib/browser/ipc.d.ts +22 -2
- package/dist/lib/browser/ipc.js +185 -21
- package/dist/lib/browser/profiles.d.ts +67 -3
- package/dist/lib/browser/profiles.js +129 -7
- package/dist/lib/browser/remote-control.d.ts +2 -2
- package/dist/lib/browser/remote-control.js +3 -3
- package/dist/lib/browser/runtime-state.d.ts +79 -0
- package/dist/lib/browser/runtime-state.js +119 -1
- package/dist/lib/browser/service.d.ts +113 -1
- package/dist/lib/browser/service.js +454 -40
- package/dist/lib/browser/sessions-list.d.ts +2 -1
- package/dist/lib/browser/sessions-list.js +4 -13
- package/dist/lib/browser/types.d.ts +18 -0
- package/dist/lib/budget/config.js +1 -1
- package/dist/lib/budget/ledger.js +1 -1
- package/dist/lib/byok-usage.js +1 -1
- package/dist/lib/capabilities.js +3 -15
- package/dist/lib/catchup.d.ts +1 -1
- package/dist/lib/catchup.js +1 -1
- package/dist/lib/cloud/dispatch.js +1 -1
- package/dist/lib/cloud/host.d.ts +3 -3
- package/dist/lib/cloud/host.js +5 -5
- package/dist/lib/cloud/rush.d.ts +9 -21
- package/dist/lib/cloud/rush.js +33 -120
- package/dist/lib/cloud/types.d.ts +2 -2
- package/dist/lib/commands.js +3 -13
- package/dist/lib/computer/actions.d.ts +36 -0
- package/dist/lib/computer/actions.js +162 -0
- package/dist/lib/computer/dispatch.d.ts +2 -2
- package/dist/lib/computer/dispatch.js +2 -2
- package/dist/lib/computer/sessions-list.d.ts +3 -3
- package/dist/lib/computer/sessions-list.js +2 -2
- package/dist/lib/config-keys.d.ts +2 -1
- package/dist/lib/config-keys.js +8 -4
- package/dist/lib/config-machine-keys.d.ts +4 -2
- package/dist/lib/config-machine-keys.js +5 -2
- package/dist/lib/crabbox/lease.js +9 -1
- package/dist/lib/crabbox/runtimes.d.ts +32 -7
- package/dist/lib/crabbox/runtimes.js +72 -30
- package/dist/lib/{daemon.d.ts → daemon/daemon.d.ts} +59 -1
- package/dist/lib/{daemon.js → daemon/daemon.js} +237 -49
- package/dist/lib/daemon-services.d.ts +1 -1
- package/dist/lib/daemon-services.js +5 -0
- package/dist/lib/daemon-ticks.d.ts +25 -0
- package/dist/lib/daemon-ticks.js +31 -1
- package/dist/lib/daemon-webhooks.d.ts +102 -0
- package/dist/lib/daemon-webhooks.js +210 -0
- package/dist/lib/device-config.d.ts +85 -75
- package/dist/lib/device-config.js +279 -141
- package/dist/lib/devices/config-migration.d.ts +29 -34
- package/dist/lib/devices/config-migration.js +209 -130
- package/dist/lib/devices/connect.d.ts +2 -2
- package/dist/lib/devices/connect.js +2 -2
- package/dist/lib/devices/discovery-policy.d.ts +30 -0
- package/dist/lib/devices/discovery-policy.js +101 -0
- package/dist/lib/devices/fleet-inventory.js +8 -3
- package/dist/lib/devices/harness-inventory.d.ts +1 -1
- package/dist/lib/devices/harness-inventory.js +12 -3
- package/dist/lib/devices/known-hosts.js +1 -1
- package/dist/lib/devices/pool.d.ts +10 -5
- package/dist/lib/devices/pool.js +5 -7
- package/dist/lib/devices/registry.d.ts +1 -1
- package/dist/lib/devices/registry.js +1 -1
- package/dist/lib/devices/resolve-profile.d.ts +2 -2
- package/dist/lib/devices/resolve-profile.js +2 -2
- package/dist/lib/devices/resolve-target.d.ts +1 -1
- package/dist/lib/devices/resolve-target.js +4 -4
- package/dist/lib/devices/self-host.d.ts +1 -1
- package/dist/lib/devices/self-host.js +3 -3
- package/dist/lib/devices/ssh-config.d.ts +1 -1
- package/dist/lib/devices/stats-cache.js +1 -1
- package/dist/lib/devices/sync.d.ts +3 -1
- package/dist/lib/devices/sync.js +3 -3
- package/dist/lib/doctor-diff.js +4 -4
- package/dist/lib/drift-sync.js +2 -2
- package/dist/lib/drift.js +2 -2
- package/dist/lib/event-families.d.ts +1 -1
- package/dist/lib/event-stream.d.ts +1 -1
- package/dist/lib/event-stream.js +2 -2
- package/dist/lib/events-ingest.js +2 -2
- package/dist/lib/exec.d.ts +4 -4
- package/dist/lib/exec.js +11 -11
- package/dist/lib/factory/snapshot.d.ts +1 -1
- package/dist/lib/factory/snapshot.js +1 -1
- package/dist/lib/{activity.d.ts → feed/activity.d.ts} +1 -1
- package/dist/lib/{activity.js → feed/activity.js} +7 -7
- package/dist/lib/{events.d.ts → feed/events.d.ts} +2 -2
- package/dist/lib/{events.js → feed/events.js} +5 -5
- package/dist/lib/{feed.js → feed/feed.js} +4 -4
- package/dist/lib/feed-outcome.d.ts +1 -1
- package/dist/lib/feed-policy.d.ts +1 -1
- package/dist/lib/feed-policy.js +1 -1
- package/dist/lib/feed-post.d.ts +1 -1
- package/dist/lib/feed-post.js +1 -1
- package/dist/lib/feed-ranking.d.ts +1 -1
- package/dist/lib/fleet/apply.d.ts +0 -6
- package/dist/lib/fleet/apply.js +18 -45
- package/dist/lib/fleet/auth-sync.d.ts +16 -35
- package/dist/lib/fleet/auth-sync.js +16 -75
- package/dist/lib/fleet/capture.js +8 -6
- package/dist/lib/fleet/manifest.js +23 -11
- package/dist/lib/fleet/types.d.ts +19 -7
- package/dist/lib/fleet-cache.d.ts +1 -1
- package/dist/lib/fleet-cache.js +1 -1
- package/dist/lib/format.d.ts +19 -0
- package/dist/lib/format.js +44 -1
- package/dist/lib/friction-heuristics.d.ts +1 -1
- package/dist/lib/git.d.ts +24 -1
- package/dist/lib/git.js +82 -38
- package/dist/lib/heal.js +3 -3
- package/dist/lib/hooks.d.ts +18 -0
- package/dist/lib/hooks.js +113 -1
- package/dist/lib/hosts/credentials.d.ts +30 -10
- package/dist/lib/hosts/credentials.js +38 -26
- package/dist/lib/hosts/dispatch.d.ts +3 -3
- package/dist/lib/hosts/dispatch.js +3 -3
- package/dist/lib/hosts/option.d.ts +3 -3
- package/dist/lib/hosts/option.js +7 -8
- package/dist/lib/hosts/passthrough.d.ts +17 -17
- package/dist/lib/hosts/passthrough.js +67 -50
- package/dist/lib/hosts/providers/devices.d.ts +1 -1
- package/dist/lib/hosts/providers/devices.js +1 -1
- package/dist/lib/hosts/reconcile.d.ts +1 -1
- package/dist/lib/hosts/reconcile.js +1 -1
- package/dist/lib/hosts/reconnect.d.ts +1 -1
- package/dist/lib/hosts/reconnect.js +2 -2
- package/dist/lib/hosts/registry.d.ts +5 -5
- package/dist/lib/hosts/registry.js +5 -5
- package/dist/lib/hosts/remote-cmd.d.ts +10 -10
- package/dist/lib/hosts/remote-cmd.js +25 -18
- package/dist/lib/hosts/remote-os.d.ts +4 -4
- package/dist/lib/hosts/remote-os.js +4 -4
- package/dist/lib/hosts/remote-session-id.d.ts +2 -2
- package/dist/lib/hosts/remote-session-id.js +2 -2
- package/dist/lib/hosts/routing-flag.d.ts +3 -3
- package/dist/lib/hosts/routing-flag.js +4 -5
- package/dist/lib/hosts/run-target.d.ts +4 -4
- package/dist/lib/hosts/run-target.js +4 -4
- package/dist/lib/hosts/session-index.d.ts +2 -2
- package/dist/lib/hosts/session-index.js +1 -1
- package/dist/lib/hosts/session-marker.d.ts +1 -1
- package/dist/lib/hosts/session-marker.js +1 -1
- package/dist/lib/hosts/types.d.ts +2 -2
- package/dist/lib/hosts/types.js +2 -2
- package/dist/lib/import.js +1 -1
- package/dist/lib/{migrate.d.ts → installations/migrate.d.ts} +13 -1
- package/dist/lib/{migrate.js → installations/migrate.js} +160 -40
- package/dist/lib/installations/resolve.js +1 -1
- package/dist/lib/installations/strategies.js +1 -1
- package/dist/lib/installations/update.js +2 -2
- package/dist/lib/{versions.d.ts → installations/versions.d.ts} +12 -3
- package/dist/lib/{versions.js → installations/versions.js} +51 -31
- package/dist/lib/isolation-boundary-report.js +1 -1
- package/dist/lib/linear-projects.d.ts +28 -0
- package/dist/lib/linear-projects.js +30 -0
- package/dist/lib/loop.js +1 -1
- package/dist/lib/mailbox-gc.js +1 -1
- package/dist/lib/mailbox.js +1 -1
- package/dist/lib/mcp-registry.d.ts +62 -0
- package/dist/lib/mcp-registry.js +177 -0
- package/dist/lib/mcp.d.ts +5 -0
- package/dist/lib/mcp.js +124 -307
- 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/install-menubar.d.ts +7 -0
- package/dist/lib/menubar/install-menubar.js +24 -6
- package/dist/lib/menubar/snapshot.d.ts +7 -0
- package/dist/lib/menubar/snapshot.js +8 -6
- package/dist/lib/models.js +1 -1
- package/dist/lib/monitors/config.d.ts +12 -0
- package/dist/lib/monitors/config.js +3 -0
- package/dist/lib/monitors/dispatch.js +26 -5
- package/dist/lib/monitors/engine.js +10 -0
- package/dist/lib/monitors/sources/webhook.d.ts +1 -1
- package/dist/lib/monitors/state.d.ts +42 -0
- package/dist/lib/monitors/state.js +30 -0
- package/dist/lib/notify.d.ts +1 -1
- package/dist/lib/observe-aliases.d.ts +2 -2
- package/dist/lib/observe-aliases.js +2 -11
- package/dist/lib/output/git-output.js +2 -2
- package/dist/lib/overdue.d.ts +1 -1
- package/dist/lib/overdue.js +1 -1
- package/dist/lib/permissions-registry.d.ts +65 -0
- package/dist/lib/permissions-registry.js +599 -0
- package/dist/lib/permissions.d.ts +24 -13
- package/dist/lib/permissions.js +52 -271
- package/dist/lib/picker.d.ts +16 -0
- package/dist/lib/picker.js +33 -3
- package/dist/lib/placement.d.ts +1 -1
- package/dist/lib/placement.js +4 -4
- package/dist/lib/platform/paths.d.ts +8 -0
- package/dist/lib/platform/paths.js +11 -0
- package/dist/lib/platform/posixpath.js +3 -3
- package/dist/lib/{plugin-marketplace.d.ts → plugins/plugin-marketplace.d.ts} +1 -1
- package/dist/lib/{plugin-marketplace.js → plugins/plugin-marketplace.js} +2 -2
- package/dist/lib/{plugins.d.ts → plugins/plugins.d.ts} +1 -1
- package/dist/lib/{plugins.js → plugins/plugins.js} +7 -7
- package/dist/lib/{skills.d.ts → plugins/skills.d.ts} +1 -1
- package/dist/lib/{skills.js → plugins/skills.js} +7 -7
- package/dist/lib/pricing/cost.d.ts +1 -1
- package/dist/lib/pricing/cost.js +1 -1
- package/dist/lib/profiles-presets.d.ts +1 -1
- package/dist/lib/profiles-presets.js +1 -1
- package/dist/lib/profiles.js +2 -2
- package/dist/lib/project-import.js +4 -1
- package/dist/lib/project-launch.d.ts +1 -1
- package/dist/lib/project-launch.js +3 -3
- package/dist/lib/project-pull.d.ts +128 -0
- package/dist/lib/project-pull.js +384 -0
- package/dist/lib/project-root.d.ts +2 -2
- package/dist/lib/project-root.js +2 -2
- package/dist/lib/project-status.js +1 -1
- package/dist/lib/projects.d.ts +23 -0
- package/dist/lib/projects.js +29 -6
- package/dist/lib/refresh.d.ts +12 -1
- package/dist/lib/refresh.js +16 -9
- package/dist/lib/registry.d.ts +9 -2
- package/dist/lib/registry.js +11 -4
- package/dist/lib/resources.d.ts +2 -2
- package/dist/lib/resources.js +2 -2
- package/dist/lib/routers.d.ts +81 -0
- package/dist/lib/routers.js +153 -0
- package/dist/lib/routine-context.d.ts +1 -0
- package/dist/lib/routine-context.js +7 -2
- package/dist/lib/routine-notify-owner.d.ts +1 -1
- package/dist/lib/routine-notify.d.ts +1 -1
- package/dist/lib/routine-notify.js +1 -1
- package/dist/lib/routine-process-cleanup.d.ts +1 -1
- package/dist/lib/routine-readiness.d.ts +1 -1
- package/dist/lib/routine-readiness.js +11 -4
- package/dist/lib/routines-placement.d.ts +12 -2
- package/dist/lib/routines-placement.js +20 -3
- package/dist/lib/routines-project.d.ts +1 -1
- package/dist/lib/routines-project.js +1 -1
- package/dist/lib/rules/compile.d.ts +1 -0
- package/dist/lib/rules/compile.js +10 -2
- package/dist/lib/rules/rules.js +1 -1
- package/dist/lib/run-notify.js +1 -1
- package/dist/lib/runner.d.ts +80 -2
- package/dist/lib/runner.js +241 -62
- package/dist/lib/sandbox.d.ts +1 -1
- package/dist/lib/scheduler.d.ts +1 -1
- package/dist/lib/scheduler.js +1 -1
- package/dist/lib/{routines.d.ts → scheduling/routines.d.ts} +54 -9
- package/dist/lib/{routines.js → scheduling/routines.js} +173 -14
- 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.js +2 -2
- package/dist/lib/secrets/audit.js +1 -1
- package/dist/lib/secrets/bundles.d.ts +3 -3
- package/dist/lib/secrets/bundles.js +7 -7
- package/dist/lib/secrets/index.js +1 -1
- package/dist/lib/secrets/list-filter.d.ts +1 -1
- package/dist/lib/secrets/list-filter.js +2 -2
- package/dist/lib/secrets/push.d.ts +1 -1
- package/dist/lib/secrets/push.js +10 -12
- package/dist/lib/secrets/remote.d.ts +12 -10
- package/dist/lib/secrets/remote.js +21 -14
- package/dist/lib/secrets/vault.js +2 -2
- package/dist/lib/self-heal/checks/shadowing.js +1 -1
- package/dist/lib/self-heal/checks/shims.js +1 -1
- package/dist/lib/self-update.d.ts +39 -4
- package/dist/lib/self-update.js +78 -25
- package/dist/lib/serve/control.d.ts +1 -1
- package/dist/lib/serve/control.js +4 -4
- package/dist/lib/serve/data.d.ts +1 -1
- package/dist/lib/serve/data.js +1 -1
- package/dist/lib/serve/stream.js +1 -1
- package/dist/lib/service-manifest.d.ts +29 -0
- package/dist/lib/service-manifest.js +80 -0
- package/dist/lib/session/active.d.ts +59 -7
- package/dist/lib/session/active.js +158 -17
- package/dist/lib/session/bash-command.js +1 -1
- package/dist/lib/session/claude-accounts.d.ts +1 -1
- package/dist/lib/session/claude-accounts.js +1 -1
- package/dist/lib/session/db.d.ts +10 -2
- package/dist/lib/session/db.js +25 -6
- package/dist/lib/session/discover.d.ts +77 -0
- package/dist/lib/session/discover.js +130 -25
- package/dist/lib/session/fork.js +1 -1
- package/dist/lib/session/inject.d.ts +1 -1
- package/dist/lib/session/insights.d.ts +1 -1
- package/dist/lib/session/insights.js +1 -1
- package/dist/lib/session/live-metadata.d.ts +15 -0
- package/dist/lib/session/live-metadata.js +76 -0
- package/dist/lib/session/migrate-targets.d.ts +1 -1
- package/dist/lib/session/recovery.d.ts +1 -1
- package/dist/lib/session/recovery.js +2 -2
- package/dist/lib/session/remote-active.d.ts +10 -1
- package/dist/lib/session/remote-active.js +8 -3
- package/dist/lib/session/remote-bundle.d.ts +1 -1
- package/dist/lib/session/remote-bundle.js +2 -2
- package/dist/lib/session/remote-list.d.ts +15 -4
- package/dist/lib/session/remote-list.js +40 -3
- package/dist/lib/session/remote.d.ts +5 -5
- package/dist/lib/session/remote.js +13 -17
- package/dist/lib/session/resume-command.d.ts +3 -2
- package/dist/lib/session/resume-command.js +4 -3
- package/dist/lib/session/resume-owner.d.ts +3 -3
- package/dist/lib/session/resume-owner.js +3 -3
- package/dist/lib/session/session-cache.d.ts +12 -0
- package/dist/lib/session/session-cache.js +2 -0
- package/dist/lib/session/shell-programs.js +1 -1
- package/dist/lib/session/state.js +5 -5
- package/dist/lib/session/team-filter.d.ts +1 -1
- package/dist/lib/session/team-filter.js +1 -1
- package/dist/lib/session/types.d.ts +3 -3
- package/dist/lib/session/width.d.ts +2 -2
- package/dist/lib/session/width.js +2 -2
- package/dist/lib/share/delete.d.ts +21 -0
- package/dist/lib/share/delete.js +42 -0
- package/dist/lib/share/publish.d.ts +82 -0
- package/dist/lib/share/publish.js +170 -18
- package/dist/lib/share/worker-template.js +172 -9
- package/dist/lib/shims.js +35 -7
- package/dist/lib/smart-launch.d.ts +4 -4
- package/dist/lib/smart-launch.js +6 -4
- package/dist/lib/snapshot.d.ts +4 -4
- package/dist/lib/snapshot.js +2 -2
- package/dist/lib/ssh-exec.d.ts +1 -1
- package/dist/lib/ssh-exec.js +2 -2
- package/dist/lib/ssh-tunnel.d.ts +10 -10
- package/dist/lib/ssh-tunnel.js +12 -12
- package/dist/lib/staleness/checkers/hooks.d.ts +1 -1
- package/dist/lib/staleness/checkers/hooks.js +1 -1
- package/dist/lib/staleness/detectors/permissions.js +0 -23
- package/dist/lib/staleness/detectors/plugins.js +1 -1
- package/dist/lib/staleness/fingerprint.js +1 -1
- package/dist/lib/staleness/layers.d.ts +1 -1
- package/dist/lib/staleness/layers.js +1 -1
- package/dist/lib/staleness/writers/mcp.js +3 -1
- package/dist/lib/staleness/writers/plugins.js +1 -1
- package/dist/lib/staleness/writers/types.d.ts +8 -0
- package/dist/lib/startup/command-registry.d.ts +5 -147
- package/dist/lib/startup/command-registry.js +38 -303
- package/dist/lib/startup/dev-build.d.ts +0 -21
- package/dist/lib/startup/dev-build.js +29 -8
- package/dist/lib/state.d.ts +19 -1
- package/dist/lib/state.js +120 -51
- package/dist/lib/subagents.js +1 -1
- package/dist/lib/sync-status.js +1 -1
- package/dist/lib/sync-umbrella.d.ts +6 -1
- package/dist/lib/sync-umbrella.js +9 -4
- package/dist/lib/teams/agents.js +2 -2
- package/dist/lib/teams/registry.js +1 -1
- package/dist/lib/terminal/backends/vscodium-agent.js +1 -1
- package/dist/lib/terminal/engine.js +1 -1
- package/dist/lib/terminal/index.d.ts +4 -0
- package/dist/lib/terminal/index.js +3 -0
- package/dist/lib/terminal/inject.d.ts +2 -2
- package/dist/lib/terminal/inject.js +2 -2
- package/dist/lib/terminal/transport.js +1 -1
- package/dist/lib/tmux/index.d.ts +1 -1
- package/dist/lib/tmux/index.js +1 -1
- package/dist/lib/tmux/session.d.ts +21 -5
- package/dist/lib/tmux/session.js +76 -22
- package/dist/lib/triggers/handlers.d.ts +1 -1
- package/dist/lib/triggers/handlers.js +2 -2
- package/dist/lib/triggers/webhook.d.ts +36 -2
- package/dist/lib/triggers/webhook.js +97 -42
- package/dist/lib/types.d.ts +18 -6
- package/dist/lib/usage-fleet.d.ts +1 -1
- package/dist/lib/usage-fleet.js +1 -1
- package/dist/lib/usage-refresh.d.ts +1 -1
- package/dist/lib/usage-refresh.js +3 -3
- package/dist/lib/version-duplicates.js +2 -2
- package/dist/lib/view-types.d.ts +56 -0
- package/dist/lib/view-types.js +1 -0
- package/dist/lib/watchdog/rotate.d.ts +2 -2
- package/dist/lib/watchdog/rotate.js +3 -3
- package/dist/lib/watchdog/runner.d.ts +2 -3
- package/dist/lib/watchdog/runner.js +3 -4
- package/dist/lib/workflows.js +1 -1
- package/package.json +2 -1
- package/scripts/postinstall.js +2 -2
- package/dist/commands/bench.d.ts +0 -2
- package/dist/commands/bench.js +0 -101
- package/dist/commands/cp.d.ts +0 -84
- package/dist/commands/cp.js +0 -231
- package/dist/commands/login.d.ts +0 -2
- package/dist/lib/resources/commands.d.ts +0 -46
- package/dist/lib/resources/commands.js +0 -211
- package/dist/lib/resources/hooks.d.ts +0 -16
- package/dist/lib/resources/hooks.js +0 -153
- package/dist/lib/resources/mcp.d.ts +0 -34
- package/dist/lib/resources/mcp.js +0 -250
- package/dist/lib/resources/memory.d.ts +0 -15
- package/dist/lib/resources/memory.js +0 -46
- package/dist/lib/resources/permissions.d.ts +0 -13
- package/dist/lib/resources/permissions.js +0 -202
- package/dist/lib/resources/rules.d.ts +0 -46
- package/dist/lib/resources/rules.js +0 -179
- package/dist/lib/resources/skills.d.ts +0 -37
- package/dist/lib/resources/skills.js +0 -247
- package/dist/lib/resources/subagents.d.ts +0 -46
- package/dist/lib/resources/subagents.js +0 -202
- /package/dist/lib/{feed.d.ts → feed/feed.d.ts} +0 -0
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
* - ship the transcript with the SAME bundle pipeline as
|
|
16
16
|
* `sessions export --stdout | sessions import -`, over `sshExec`;
|
|
17
17
|
* - resume on the target through the SAME `openSurfaces({ backend:'tmux', host })`
|
|
18
|
-
* path `sessions resume --
|
|
18
|
+
* path `sessions resume --device` uses;
|
|
19
19
|
* - only AFTER the target's prompt is confirmed live, kill the source tmux
|
|
20
20
|
* session (`killSession`). --keep skips the kill (copy, not move).
|
|
21
21
|
*
|
|
@@ -33,9 +33,7 @@ import { getActiveSessions } from '../lib/session/active.js';
|
|
|
33
33
|
import { discoverSessions, resolveSessionById } from '../lib/session/discover.js';
|
|
34
34
|
import { buildResumeCommand } from './sessions.js';
|
|
35
35
|
import { injectTargetFromReplyRail } from '../lib/session/inject.js';
|
|
36
|
-
import { injectIntoTerminal } from '../lib/terminal/index.js';
|
|
37
|
-
import { iLoginShell } from '../lib/terminal/shell.js';
|
|
38
|
-
import { shellQuote as quoteArg } from '../lib/terminal/quote.js';
|
|
36
|
+
import { injectIntoTerminal, iLoginShell, shellQuote as quoteArg } from '../lib/terminal/index.js';
|
|
39
37
|
import { killSession } from '../lib/tmux/session.js';
|
|
40
38
|
import { getDefaultSocketPath } from '../lib/tmux/paths.js';
|
|
41
39
|
import { listAllHosts, resolveHost } from '../lib/hosts/registry.js';
|
|
@@ -57,7 +55,7 @@ export function registerSessionsMigrateCommand(sessionsCmd) {
|
|
|
57
55
|
.alias('relocate')
|
|
58
56
|
.description('Relocate a running session onto another machine (fleet worker, device, or ephemeral box), then stop the source here.')
|
|
59
57
|
.option('--auto', 'Pick the best target host automatically (idle fleet worker preferred)')
|
|
60
|
-
.option('--
|
|
58
|
+
.option('--device <name>', 'Explicit target: an enrolled host, device, or a warm ephemeral box slug')
|
|
61
59
|
.option('--lease', 'Provision a fresh ephemeral crabbox box as the target')
|
|
62
60
|
.option('--mode <mode>', 'rehydrate (default: the target agent reads the transported transcript) or resume (best-effort native --resume)', 'rehydrate')
|
|
63
61
|
.option('--keep', 'Copy, not move — do NOT stop the source after resuming on the target')
|
|
@@ -68,13 +66,13 @@ export function registerSessionsMigrateCommand(sessionsCmd) {
|
|
|
68
66
|
agents sessions migrate --auto
|
|
69
67
|
|
|
70
68
|
# Move a specific session onto a named host
|
|
71
|
-
agents sessions migrate a1b2c3d4 --
|
|
69
|
+
agents sessions migrate a1b2c3d4 --device yosemite-s1
|
|
72
70
|
|
|
73
71
|
# Spin up a fresh ephemeral box and move onto it
|
|
74
72
|
agents sessions migrate --lease
|
|
75
73
|
|
|
76
74
|
# Copy (don't stop the source), letting the agent wrap up its own dirty tree
|
|
77
|
-
agents sessions migrate --
|
|
75
|
+
agents sessions migrate --device box-a --keep --agent-wrapup
|
|
78
76
|
`,
|
|
79
77
|
notes: `
|
|
80
78
|
- Without a [session-id], migrate resolves the session running in THIS tmux pane ($TMUX_PANE).
|
|
@@ -87,17 +85,8 @@ export function registerSessionsMigrateCommand(sessionsCmd) {
|
|
|
87
85
|
- Every migrate appends to the ledger — see 'agents sessions migrations' for where each session went.
|
|
88
86
|
`,
|
|
89
87
|
});
|
|
90
|
-
cmd.action(async (sessionId, options
|
|
91
|
-
|
|
92
|
-
// listing fan-out), which shadows this subcommand's own --host — the value
|
|
93
|
-
// lands in the merged globals, not `options.host`. Read it from there so
|
|
94
|
-
// `agents sessions migrate --host <name>` binds.
|
|
95
|
-
const globals = command.optsWithGlobals();
|
|
96
|
-
const hosts = Array.isArray(globals.host) ? globals.host : globals.host ? [globals.host] : [];
|
|
97
|
-
if (hosts.length > 1) {
|
|
98
|
-
console.error(chalk.yellow(`Multiple --host values given; migrating to the first (${hosts[0]}).`));
|
|
99
|
-
}
|
|
100
|
-
await sessionsMigrateAction(sessionId, { ...options, host: hosts[0] });
|
|
88
|
+
cmd.action(async (sessionId, options) => {
|
|
89
|
+
await sessionsMigrateAction(sessionId, options);
|
|
101
90
|
});
|
|
102
91
|
}
|
|
103
92
|
function fail(message) {
|
|
@@ -141,7 +130,7 @@ function statsByName() {
|
|
|
141
130
|
const cache = readStatsCache();
|
|
142
131
|
return new Map(Object.entries(cache));
|
|
143
132
|
}
|
|
144
|
-
/** Enumerate + rank targets, honoring --
|
|
133
|
+
/** Enumerate + rank targets, honoring --device / --auto / --lease. */
|
|
145
134
|
async function resolveTarget(options, source) {
|
|
146
135
|
const selfHostname = os.hostname();
|
|
147
136
|
const ctx = {
|
|
@@ -162,17 +151,17 @@ async function resolveTarget(options, source) {
|
|
|
162
151
|
warm = []; // crabbox not configured — fleet-only targets
|
|
163
152
|
}
|
|
164
153
|
const stats = statsByName();
|
|
165
|
-
if (options.
|
|
154
|
+
if (options.device) {
|
|
166
155
|
// Explicit target: a fleet host/device, or a warm box slug.
|
|
167
|
-
const box = warm.find((b) => b.slug === options.
|
|
156
|
+
const box = warm.find((b) => b.slug === options.device);
|
|
168
157
|
if (box) {
|
|
169
158
|
return { name: box.slug, kind: 'ephemeral', os: 'linux', headroom: 'unknown', box };
|
|
170
159
|
}
|
|
171
|
-
const host = await resolveHost(options.
|
|
160
|
+
const host = await resolveHost(options.device);
|
|
172
161
|
if (!host)
|
|
173
|
-
fail(`No host, device, or warm box named "${options.
|
|
162
|
+
fail(`No host, device, or warm box named "${options.device}".`);
|
|
174
163
|
if (host.name.toLowerCase() === selfHostname.toLowerCase()) {
|
|
175
|
-
fail(`"${options.
|
|
164
|
+
fail(`"${options.device}" is this machine — migrate needs a different target.`);
|
|
176
165
|
}
|
|
177
166
|
return { name: host.name, kind: 'fleet', os: host.os, headroom: 'unknown', host };
|
|
178
167
|
}
|
|
@@ -186,7 +175,7 @@ async function resolveTarget(options, source) {
|
|
|
186
175
|
}
|
|
187
176
|
// Interactive: rank the candidates and let the user pick.
|
|
188
177
|
if (!isInteractiveTerminal()) {
|
|
189
|
-
fail('Pass --auto, --
|
|
178
|
+
fail('Pass --auto, --device <name>, or --lease to choose a target (no interactive picker without a tty).');
|
|
190
179
|
}
|
|
191
180
|
const ranked = rankTargets(enumerateTargets(hosts, warm, stats, ctx), ctx);
|
|
192
181
|
if (ranked.length === 0) {
|
|
@@ -447,7 +436,7 @@ export function buildMigrateResumeCommands(opts) {
|
|
|
447
436
|
}
|
|
448
437
|
/**
|
|
449
438
|
* Resume the session on the target through the SAME host path as
|
|
450
|
-
* `sessions resume --
|
|
439
|
+
* `sessions resume --device` (tmux backend). Returns true when the resume launched.
|
|
451
440
|
*/
|
|
452
441
|
async function resumeOnTarget(sshTarget, source, remoteCwd, mode) {
|
|
453
442
|
const command = mode === 'resume' ? buildResumeCommand(source) : rehydrateCommand(source);
|
|
@@ -459,7 +448,7 @@ async function resumeOnTarget(sshTarget, source, remoteCwd, mode) {
|
|
|
459
448
|
// box has none ("no server running"), so we create the session (and thus the
|
|
460
449
|
// server) directly with `new-session -d`, mirroring the local `createSession`
|
|
461
450
|
// helper (remain-on-exit keeps the pane inspectable if the agent exits), over
|
|
462
|
-
// the same SSH transport as `sessions resume --
|
|
451
|
+
// the same SSH transport as `sessions resume --device`.
|
|
463
452
|
//
|
|
464
453
|
// Each argv element is quoted BEFORE the zsh -ilc wrapper so a command that
|
|
465
454
|
// carries spaces or backticks (the rehydrate prompt) reaches the agent as one
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { SessionEvent, SessionMeta, TodoProgress } from '../lib/session/types.js';
|
|
2
|
+
import { fetchPeerPreviewDigest } from '../lib/session/remote-list.js';
|
|
2
3
|
import { classifyFileChanges, changeCounts, toolHistogram, detectTestResult } from '../lib/session/digest.js';
|
|
3
4
|
import { extractArtifacts, extractHooks, extractLinks, extractSkills } from '../lib/session/highlights.js';
|
|
4
5
|
/**
|
|
@@ -32,6 +33,18 @@ export interface SessionPickerConfig {
|
|
|
32
33
|
/** Lines the caller printed above the prompt (hidden-session footer). */
|
|
33
34
|
linesAbovePrompt?: number;
|
|
34
35
|
}
|
|
36
|
+
export declare function setRemotePreviewRepaint(repaint?: () => void): void;
|
|
37
|
+
export declare function setPeerDigestFetcherForTest(fetcher?: typeof fetchPeerPreviewDigest): void;
|
|
38
|
+
export declare function clearRemoteDigestCacheForTest(): void;
|
|
39
|
+
/**
|
|
40
|
+
* Validate + scrub a peer-supplied preview digest before any of it reaches this
|
|
41
|
+
* terminal. Peer JSON is untrusted at this boundary — the same rule
|
|
42
|
+
* `sanitizeMeta` applies to fan-out rows — so every string is stripped of
|
|
43
|
+
* terminal escapes and every list re-shaped field by field. Anything that
|
|
44
|
+
* doesn't look like the v1 digest is rejected, so a version-skewed peer
|
|
45
|
+
* degrades to the metadata card instead of a corrupted pane.
|
|
46
|
+
*/
|
|
47
|
+
export declare function sanitizeRemoteDigest(raw: unknown): SessionPreviewDigest | undefined;
|
|
35
48
|
export declare function clearPreviewMemoryCacheForTest(): void;
|
|
36
49
|
export declare function loadSessionPreviewDigest(session: SessionMeta): {
|
|
37
50
|
digest?: SessionPreviewDigest;
|
|
@@ -9,6 +9,7 @@ import fs from 'node:fs';
|
|
|
9
9
|
import path from 'node:path';
|
|
10
10
|
import chalk from 'chalk';
|
|
11
11
|
import { truncate, humanDuration } from '../lib/format.js';
|
|
12
|
+
import { fetchPeerPreviewDigest } from '../lib/session/remote-list.js';
|
|
12
13
|
import { parseSession, sanitizeForTerminal, SNAPSHOT_TODO_TOOLS } from '../lib/session/parse.js';
|
|
13
14
|
import { safeTeamText } from '../lib/session/team-filter.js';
|
|
14
15
|
import { cleanSessionPrompt, extractSessionTopic, isSyntheticUserMessage } from '../lib/session/prompt.js';
|
|
@@ -23,9 +24,10 @@ import { extractArtifacts, extractHooks, extractLinks, extractRepos, extractSkil
|
|
|
23
24
|
import { getSessionPlugins, readSessionPreviewCache, writeSessionPreviewCache, readSessionContent, readArchivedSessionPreview } from '../lib/session/db.js';
|
|
24
25
|
/** A session whose transcript FILE is on another machine (folded in over the
|
|
25
26
|
* live cross-machine fan-out): its `filePath` is on that peer's disk, so the
|
|
26
|
-
* preview can't parse it locally — it
|
|
27
|
-
*
|
|
28
|
-
* mirrors still parse their
|
|
27
|
+
* preview can't parse it locally — it fetches the peer's digest over SSH and
|
|
28
|
+
* shows metadata + a "resume there" note until that lands. Keys off `_remote`,
|
|
29
|
+
* not the machine tag, so locally-readable synced mirrors still parse their
|
|
30
|
+
* file normally.
|
|
29
31
|
*
|
|
30
32
|
* This is the READ rule and only the read rule. Whether a session may be
|
|
31
33
|
* RESUMED here is a different question with a different answer — a mirror is
|
|
@@ -106,6 +108,155 @@ const previewCache = createMemoryCache({
|
|
|
106
108
|
max: 256,
|
|
107
109
|
ttlMs: 5 * 60_000,
|
|
108
110
|
});
|
|
111
|
+
const remoteDigestCache = createMemoryCache({
|
|
112
|
+
max: 256,
|
|
113
|
+
ttlMs: 5 * 60_000,
|
|
114
|
+
});
|
|
115
|
+
function remoteDigestKey(sessionId, machine) {
|
|
116
|
+
return `${machine}:${sessionId}`;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* The open picker's repaint trigger. The peer fetch resolves while the pane is
|
|
120
|
+
* already painted, so completion has to nudge the picker into re-rendering —
|
|
121
|
+
* pickers register their trigger here (via `registerPreviewRepaint`) and clear
|
|
122
|
+
* it when they close, making a late fetch after close a no-op.
|
|
123
|
+
*/
|
|
124
|
+
let remotePreviewRepaint;
|
|
125
|
+
export function setRemotePreviewRepaint(repaint) {
|
|
126
|
+
remotePreviewRepaint = repaint;
|
|
127
|
+
}
|
|
128
|
+
/** Seam for tests: the real fetcher opens an SSH connection to the peer. */
|
|
129
|
+
let peerDigestFetcher = fetchPeerPreviewDigest;
|
|
130
|
+
export function setPeerDigestFetcherForTest(fetcher) {
|
|
131
|
+
peerDigestFetcher = fetcher ?? fetchPeerPreviewDigest;
|
|
132
|
+
}
|
|
133
|
+
export function clearRemoteDigestCacheForTest() {
|
|
134
|
+
remoteDigestCache.clear();
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Look up (or start fetching) the peer digest for a remote row. Returns the
|
|
138
|
+
* current entry synchronously — `buildPreview` renders whatever state exists
|
|
139
|
+
* now, and the fetch's completion repaints the pane through the registered
|
|
140
|
+
* trigger.
|
|
141
|
+
*/
|
|
142
|
+
function remoteDigestForPreview(session, machine) {
|
|
143
|
+
const key = remoteDigestKey(session.id, machine);
|
|
144
|
+
const existing = remoteDigestCache.get(key);
|
|
145
|
+
if (existing)
|
|
146
|
+
return existing;
|
|
147
|
+
const pending = { state: 'pending' };
|
|
148
|
+
remoteDigestCache.set(key, pending);
|
|
149
|
+
void peerDigestFetcher(session.id, machine)
|
|
150
|
+
.then((raw) => {
|
|
151
|
+
const digest = sanitizeRemoteDigest(raw);
|
|
152
|
+
remoteDigestCache.set(key, digest ? { state: 'ready', digest } : { state: 'failed' });
|
|
153
|
+
})
|
|
154
|
+
.catch(() => {
|
|
155
|
+
remoteDigestCache.set(key, { state: 'failed' });
|
|
156
|
+
})
|
|
157
|
+
.then(() => remotePreviewRepaint?.());
|
|
158
|
+
return pending;
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Validate + scrub a peer-supplied preview digest before any of it reaches this
|
|
162
|
+
* terminal. Peer JSON is untrusted at this boundary — the same rule
|
|
163
|
+
* `sanitizeMeta` applies to fan-out rows — so every string is stripped of
|
|
164
|
+
* terminal escapes and every list re-shaped field by field. Anything that
|
|
165
|
+
* doesn't look like the v1 digest is rejected, so a version-skewed peer
|
|
166
|
+
* degrades to the metadata card instead of a corrupted pane.
|
|
167
|
+
*/
|
|
168
|
+
export function sanitizeRemoteDigest(raw) {
|
|
169
|
+
if (!raw || typeof raw !== 'object' || Array.isArray(raw))
|
|
170
|
+
return undefined;
|
|
171
|
+
const d = raw;
|
|
172
|
+
if (d.schemaVersion !== 1)
|
|
173
|
+
return undefined;
|
|
174
|
+
const str = (v) => (typeof v === 'string' ? sanitizeForTerminal(v) : '');
|
|
175
|
+
const optStr = (v) => (typeof v === 'string' ? sanitizeForTerminal(v) : undefined);
|
|
176
|
+
const num = (v) => (typeof v === 'number' && Number.isFinite(v) ? v : 0);
|
|
177
|
+
const optNum = (v) => (typeof v === 'number' && Number.isFinite(v) ? v : undefined);
|
|
178
|
+
const strList = (v) => Array.isArray(v) ? v.filter((x) => typeof x === 'string').map(sanitizeForTerminal) : [];
|
|
179
|
+
const objList = (v, map) => Array.isArray(v)
|
|
180
|
+
? v.flatMap((x) => {
|
|
181
|
+
if (!x || typeof x !== 'object' || Array.isArray(x))
|
|
182
|
+
return [];
|
|
183
|
+
const mapped = map(x);
|
|
184
|
+
return mapped === undefined ? [] : [mapped];
|
|
185
|
+
})
|
|
186
|
+
: [];
|
|
187
|
+
let todos;
|
|
188
|
+
if (d.todos && typeof d.todos === 'object' && !Array.isArray(d.todos)) {
|
|
189
|
+
const t = d.todos;
|
|
190
|
+
const items = objList(t.items, (it) => {
|
|
191
|
+
const content = str(it.content ?? it.text);
|
|
192
|
+
if (!content)
|
|
193
|
+
return undefined;
|
|
194
|
+
const status = it.status === 'completed' || it.status === 'in_progress' ? it.status : 'pending';
|
|
195
|
+
return { content, status, activeForm: optStr(it.activeForm) };
|
|
196
|
+
});
|
|
197
|
+
todos = { items, done: num(t.done), total: num(t.total), activeForm: optStr(t.activeForm) };
|
|
198
|
+
}
|
|
199
|
+
const changes = d.changes && typeof d.changes === 'object' && !Array.isArray(d.changes)
|
|
200
|
+
? {
|
|
201
|
+
created: num(d.changes.created),
|
|
202
|
+
modified: num(d.changes.modified),
|
|
203
|
+
deleted: num(d.changes.deleted),
|
|
204
|
+
}
|
|
205
|
+
: { created: 0, modified: 0, deleted: 0 };
|
|
206
|
+
let test;
|
|
207
|
+
if (d.test && typeof d.test === 'object' && !Array.isArray(d.test)) {
|
|
208
|
+
const t = d.test;
|
|
209
|
+
const runner = str(t.runner);
|
|
210
|
+
if (runner) {
|
|
211
|
+
test = { runner, ok: t.ok === true, ts: num(t.ts), passed: optNum(t.passed), failed: optNum(t.failed) };
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
return {
|
|
215
|
+
schemaVersion: 1,
|
|
216
|
+
firstUser: str(d.firstUser),
|
|
217
|
+
lastAssistant: str(d.lastAssistant),
|
|
218
|
+
filesRead: num(d.filesRead),
|
|
219
|
+
toolCalls: num(d.toolCalls),
|
|
220
|
+
planFile: str(d.planFile),
|
|
221
|
+
todos,
|
|
222
|
+
subAgentCount: num(d.subAgentCount),
|
|
223
|
+
toolTags: strList(d.toolTags),
|
|
224
|
+
changes,
|
|
225
|
+
dirs: strList(d.dirs),
|
|
226
|
+
repos: strList(d.repos),
|
|
227
|
+
artifacts: objList(d.artifacts, (a) => {
|
|
228
|
+
const p = str(a.path);
|
|
229
|
+
const basename = str(a.basename);
|
|
230
|
+
if (!p || !basename)
|
|
231
|
+
return undefined;
|
|
232
|
+
const bucket = a.bucket === 'artifacts' || a.bucket === 'plans' || a.bucket === 'reports' ? a.bucket : 'docs';
|
|
233
|
+
return { path: p, basename, bucket };
|
|
234
|
+
}),
|
|
235
|
+
skills: objList(d.skills, (s) => {
|
|
236
|
+
const name = str(s.name);
|
|
237
|
+
return name ? { name, count: num(s.count) } : undefined;
|
|
238
|
+
}),
|
|
239
|
+
plugins: strList(d.plugins),
|
|
240
|
+
hooks: objList(d.hooks, (h) => {
|
|
241
|
+
const name = str(h.name);
|
|
242
|
+
return name ? { name, event: optStr(h.event), count: num(h.count), failed: num(h.failed) } : undefined;
|
|
243
|
+
}),
|
|
244
|
+
links: objList(d.links, (l) => {
|
|
245
|
+
const url = str(l.url);
|
|
246
|
+
const label = str(l.label);
|
|
247
|
+
// Only http(s) URLs render as OSC 8 hyperlinks — anything else a peer
|
|
248
|
+
// sends (file:, a bare payload) is dropped rather than linkified.
|
|
249
|
+
return /^https?:\/\//.test(url) && label ? { kind: 'other', url, label } : undefined;
|
|
250
|
+
}),
|
|
251
|
+
errorCount: num(d.errorCount),
|
|
252
|
+
firstError: optStr(d.firstError),
|
|
253
|
+
toolHistogram: objList(d.toolHistogram, (h) => {
|
|
254
|
+
const tool = str(h.tool);
|
|
255
|
+
return tool ? { tool, count: num(h.count) } : undefined;
|
|
256
|
+
}),
|
|
257
|
+
test,
|
|
258
|
+
};
|
|
259
|
+
}
|
|
109
260
|
function previewCacheKey(session, remote) {
|
|
110
261
|
let fileStamp = '';
|
|
111
262
|
if (!remote && session.filePath) {
|
|
@@ -117,10 +268,16 @@ function previewCacheKey(session, remote) {
|
|
|
117
268
|
fileStamp = 'missing';
|
|
118
269
|
}
|
|
119
270
|
}
|
|
271
|
+
// A remote row's rendered pane depends on the fetched digest's state
|
|
272
|
+
// (none → pending → ready/failed), so the state rides the key — otherwise the
|
|
273
|
+
// memoized metadata-only card would keep serving after the digest arrived.
|
|
274
|
+
const remoteDigestState = remote
|
|
275
|
+
? remoteDigestCache.get(remoteDigestKey(session.id, remote))?.state ?? 'none'
|
|
276
|
+
: '';
|
|
120
277
|
// The transcript stamp invalidates derived activity. Metadata that can change
|
|
121
278
|
// independently (label/ticket/PR/live scanner enrichment) also rides the key.
|
|
122
279
|
return JSON.stringify([
|
|
123
|
-
remote ?? '', session.id, fileStamp, session.lastActivity, session.label,
|
|
280
|
+
remote ?? '', remoteDigestState, session.id, fileStamp, session.lastActivity, session.label,
|
|
124
281
|
session.topic, session.ticketId, session.prUrl, session.messageCount,
|
|
125
282
|
session.tokenCount, session.model, session.todos, session.plan,
|
|
126
283
|
session.recentDirectoriesTouched, session.skillsUsed,
|
|
@@ -181,13 +338,26 @@ export function buildPreview(session) {
|
|
|
181
338
|
return cached;
|
|
182
339
|
const safe = sanitizeMeta(session);
|
|
183
340
|
// Remote session: the transcript is on the peer's disk, so there is nothing to
|
|
184
|
-
// parse here.
|
|
185
|
-
//
|
|
341
|
+
// parse here. Fetch the peer's already-computed digest over SSH (kicked off on
|
|
342
|
+
// first render; the pane repaints when it lands) and render the same compact
|
|
343
|
+
// preview a local row gets. Until it arrives — or when the peer can't answer —
|
|
344
|
+
// show the metadata header (agent, cwd, msgs, tokens — all carried over in the
|
|
345
|
+
// fan-out) plus where it lives and how to open it.
|
|
186
346
|
if (remote) {
|
|
187
347
|
const note = ' ' + chalk.gray(`on `) + chalk.bold.white(remote)
|
|
188
348
|
+ chalk.gray(` — enter to resume there, or space then enter to read it over SSH`);
|
|
349
|
+
const entry = remoteDigestForPreview(session, remote);
|
|
350
|
+
if (entry.state === 'ready') {
|
|
351
|
+
const body = formatCompactPreview(entry.digest, safe);
|
|
352
|
+
const output = [formatHeader(safe, []), '', note, body].filter(Boolean).join('\n');
|
|
353
|
+
previewCache.set(cacheKey, output);
|
|
354
|
+
return output;
|
|
355
|
+
}
|
|
356
|
+
const fetching = entry.state === 'pending'
|
|
357
|
+
? ' ' + chalk.gray(`fetching preview from ${remote} over SSH…`)
|
|
358
|
+
: '';
|
|
189
359
|
const metaBody = formatMetaOnlyBody(safe);
|
|
190
|
-
const output = [formatHeader(safe, []), '', note, metaBody].filter(Boolean).join('\n');
|
|
360
|
+
const output = [formatHeader(safe, []), '', note, fetching, metaBody].filter(Boolean).join('\n');
|
|
191
361
|
previewCache.set(cacheKey, output);
|
|
192
362
|
return output;
|
|
193
363
|
}
|
|
@@ -895,13 +1065,17 @@ export async function sessionPicker(config) {
|
|
|
895
1065
|
filter: config.filter,
|
|
896
1066
|
labelFor: config.labelFor,
|
|
897
1067
|
buildPreview,
|
|
1068
|
+
// A remote row's digest arrives over SSH after the pane painted — this is
|
|
1069
|
+
// what lets its completion swap the metadata card for the full preview.
|
|
1070
|
+
registerPreviewRepaint: setRemotePreviewRepaint,
|
|
898
1071
|
shortIdFor: (s) => s.shortId,
|
|
899
1072
|
pageSize: config.pageSize,
|
|
900
1073
|
initialSearch: config.initialSearch,
|
|
901
1074
|
emptyMessage: 'No sessions match.',
|
|
902
1075
|
enterHint: config.enterHint ?? 'resume',
|
|
903
1076
|
linesAbovePrompt: config.linesAbovePrompt,
|
|
904
|
-
|
|
1077
|
+
// A late digest fetch must not poke a closed prompt.
|
|
1078
|
+
}).finally(() => setRemotePreviewRepaint(undefined));
|
|
905
1079
|
if (!picked)
|
|
906
1080
|
return null;
|
|
907
1081
|
return { session: picked.item, action: 'resume' };
|
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
import type { Command } from 'commander';
|
|
2
2
|
import { type SessionMeta } from '../lib/session/types.js';
|
|
3
3
|
import { type Backend, type EngineContext, type Packing } from '../lib/terminal/index.js';
|
|
4
|
+
import { type StrictResumeOptions } from './resume.js';
|
|
4
5
|
/** Opening more than this many live sessions at once asks for confirmation first. */
|
|
5
6
|
export declare const CONFIRM_THRESHOLD = 5;
|
|
6
|
-
export interface ResumeOptions {
|
|
7
|
+
export interface ResumeOptions extends StrictResumeOptions {
|
|
7
8
|
agent?: string;
|
|
8
9
|
all?: boolean;
|
|
9
10
|
teams?: boolean;
|
|
10
11
|
since?: string;
|
|
11
12
|
limit?: string;
|
|
12
|
-
|
|
13
|
+
device?: string;
|
|
13
14
|
iterm?: boolean;
|
|
14
15
|
ghostty?: boolean;
|
|
15
16
|
tmux?: boolean;
|
|
@@ -24,12 +25,15 @@ export declare function registerSessionsResumeCommand(sessionsCmd: Command): voi
|
|
|
24
25
|
/** IDs and tmux aliases are actions, not picker search text. Human phrases keep
|
|
25
26
|
* the existing pre-filtered picker, while an explicit identity resumes directly. */
|
|
26
27
|
export declare function isDirectResumeSelector(query: string): boolean;
|
|
27
|
-
/** Re-enter through
|
|
28
|
+
/** Re-enter through sessions resume so fleet routing and harness policy
|
|
28
29
|
* stay centralized. The child inherits this terminal for a real interactive resume. */
|
|
29
30
|
export declare function resumeSelectorInPlace(selector: string): Promise<void>;
|
|
30
31
|
/** Direct identities use focus as the lifecycle dispatcher: it rechecks the
|
|
31
32
|
* live fleet, attaches a healthy pane, and falls through to `agents resume`
|
|
32
33
|
* only when the process is no longer attachable. */
|
|
34
|
+
/** True when `sessions resume <id> --attach-only|--local` must go through
|
|
35
|
+
* `sessions focus` instead of `runStrictResume` (which can fork a copy). */
|
|
36
|
+
export declare function resumeUsesLifecycleDispatch(query: string | undefined, prompt: string | undefined, options: Pick<ResumeOptions, 'attachOnly' | 'local' | 'mode' | 'interactive' | 'headless' | 'here'>): boolean;
|
|
33
37
|
export declare function dispatchSessionLifecycleInPlace(selector: string, hosts?: string[], attachOnly?: boolean, local?: boolean): Promise<void>;
|
|
34
38
|
export declare function buildSessionLifecycleArgs(selector: string, hosts?: string[], attachOnly?: boolean, local?: boolean): string[];
|
|
35
39
|
export declare function resolveResumePacking(options: Pick<ResumeOptions, 'splits'>): Packing;
|