@phnx-labs/agents-cli 1.22.35 → 1.22.38
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +708 -2
- package/README.md +83 -43
- package/dist/bin/agents +0 -0
- package/dist/bootstrap.d.ts +15 -0
- package/dist/bootstrap.js +1212 -0
- package/dist/commands/accounts.d.ts +4 -11
- package/dist/commands/accounts.js +159 -27
- package/dist/commands/artifacts-setup.d.ts +53 -0
- package/dist/commands/artifacts-setup.js +161 -0
- package/dist/commands/artifacts.d.ts +18 -0
- package/dist/commands/artifacts.js +58 -0
- package/dist/commands/attach.js +17 -4
- package/dist/commands/audit.d.ts +8 -8
- package/dist/commands/audit.js +57 -47
- package/dist/commands/browser.js +17 -11
- package/dist/commands/cloud.js +1 -1
- package/dist/commands/commands.js +0 -11
- package/dist/commands/computer-actions.js +33 -0
- package/dist/commands/computer-sessions-picker.d.ts +21 -0
- package/dist/commands/computer-sessions-picker.js +141 -0
- package/dist/commands/computer.d.ts +16 -0
- package/dist/commands/computer.js +37 -0
- package/dist/commands/config.d.ts +17 -0
- package/dist/commands/config.js +401 -0
- package/dist/commands/cp.d.ts +84 -0
- package/dist/commands/cp.js +231 -0
- package/dist/commands/daemon.js +243 -14
- package/dist/commands/detach-core.d.ts +1 -1
- package/dist/commands/detach-core.js +12 -2
- package/dist/commands/detach.js +1 -1
- package/dist/commands/doctor.js +64 -5
- package/dist/commands/events.d.ts +24 -12
- package/dist/commands/events.js +144 -28
- package/dist/commands/exec.js +86 -42
- package/dist/commands/feed.d.ts +1 -1
- package/dist/commands/feed.js +16 -8
- package/dist/commands/focus.d.ts +33 -1
- package/dist/commands/focus.js +177 -17
- package/dist/commands/funnel.d.ts +1 -1
- package/dist/commands/go.js +9 -8
- package/dist/commands/harness-wizard.d.ts +1 -0
- package/dist/commands/harness-wizard.js +18 -20
- package/dist/commands/harness.d.ts +2 -0
- package/dist/commands/harness.js +59 -26
- package/dist/commands/hooks.js +0 -11
- package/dist/commands/inspect.d.ts +94 -1
- package/dist/commands/inspect.js +866 -40
- package/dist/commands/lease.d.ts +4 -4
- package/dist/commands/lease.js +6 -6
- package/dist/commands/login.js +0 -13
- package/dist/commands/logs.d.ts +2 -2
- package/dist/commands/logs.js +2 -2
- package/dist/commands/mcp.js +7 -2
- package/dist/commands/memory.js +7 -2
- package/dist/commands/message.d.ts +1 -1
- package/dist/commands/message.js +37 -6
- package/dist/commands/models.js +71 -0
- package/dist/commands/monitors.d.ts +0 -1
- package/dist/commands/monitors.js +199 -16
- package/dist/commands/open.d.ts +18 -0
- package/dist/commands/open.js +57 -0
- package/dist/commands/packages.js +2 -107
- package/dist/commands/plugins.js +6 -3
- package/dist/commands/profiles.d.ts +1 -0
- package/dist/commands/profiles.js +16 -160
- package/dist/commands/projects.d.ts +28 -0
- package/dist/commands/projects.js +125 -5
- package/dist/commands/reconnect.js +9 -3
- package/dist/commands/repo.js +42 -1
- package/dist/commands/resource-view.d.ts +17 -0
- package/dist/commands/resource-view.js +36 -14
- package/dist/commands/resume.js +9 -2
- package/dist/commands/routines.d.ts +0 -2
- package/dist/commands/routines.js +473 -289
- package/dist/commands/secrets.js +52 -9
- package/dist/commands/sessions-export.d.ts +47 -0
- package/dist/commands/sessions-export.js +116 -6
- package/dist/commands/sessions-import.d.ts +17 -0
- package/dist/commands/sessions-import.js +114 -6
- package/dist/commands/sessions-migrate.d.ts +27 -0
- package/dist/commands/sessions-migrate.js +50 -9
- package/dist/commands/sessions-picker.js +23 -4
- package/dist/commands/sessions-resume.d.ts +5 -3
- package/dist/commands/sessions-resume.js +30 -8
- package/dist/commands/sessions-watch.d.ts +2 -0
- package/dist/commands/sessions-watch.js +53 -0
- package/dist/commands/sessions.d.ts +66 -3
- package/dist/commands/sessions.js +298 -47
- package/dist/commands/setup-browser.js +2 -2
- package/dist/commands/setup-mine.js +0 -1
- package/dist/commands/setup-preferences.js +1 -1
- package/dist/commands/setup.d.ts +5 -0
- package/dist/commands/setup.js +31 -5
- package/dist/commands/share.d.ts +87 -7
- package/dist/commands/share.js +320 -58
- package/dist/commands/skills.js +0 -11
- package/dist/commands/snapshot.js +1 -1
- package/dist/commands/ssh.d.ts +18 -0
- package/dist/commands/ssh.js +549 -210
- package/dist/commands/sync.d.ts +5 -0
- package/dist/commands/sync.js +212 -32
- package/dist/commands/teams.d.ts +13 -0
- package/dist/commands/teams.js +187 -30
- package/dist/commands/tickets.d.ts +2 -0
- package/dist/commands/tickets.js +43 -0
- package/dist/commands/update.js +2 -4
- package/dist/commands/usage.js +5 -3
- package/dist/commands/versions.js +11 -5
- package/dist/commands/view.js +15 -7
- package/dist/commands/webhook.d.ts +2 -2
- package/dist/commands/webhook.js +7 -7
- package/dist/index.d.ts +18 -2
- package/dist/index.js +53 -1264
- package/dist/lib/account-catalog.d.ts +18 -0
- package/dist/lib/account-catalog.js +38 -0
- package/dist/lib/account-provider-registry.d.ts +18 -0
- package/dist/lib/account-provider-registry.js +59 -0
- package/dist/lib/account-registry.d.ts +40 -0
- package/dist/lib/account-registry.js +239 -0
- package/dist/lib/account-schema.d.ts +44 -0
- package/dist/lib/account-schema.js +91 -0
- package/dist/lib/account-state-service.d.ts +21 -0
- package/dist/lib/account-state-service.js +60 -0
- package/dist/lib/activity.d.ts +1 -1
- package/dist/lib/activity.js +8 -1
- package/dist/lib/add-dir.d.ts +80 -0
- package/dist/lib/add-dir.js +241 -0
- package/dist/lib/agent-cli-commands.d.ts +11 -0
- package/dist/lib/agent-cli-commands.js +30 -0
- package/dist/lib/agents.js +44 -36
- package/dist/lib/answer-router.js +1 -1
- package/dist/lib/audit/log.d.ts +10 -27
- package/dist/lib/audit/log.js +20 -33
- package/dist/lib/auth-health.d.ts +9 -2
- package/dist/lib/auth-health.js +42 -9
- package/dist/lib/auto-pull-worker.js +7 -3
- package/dist/lib/auto-pull.d.ts +44 -3
- package/dist/lib/auto-pull.js +88 -5
- package/dist/lib/binary-shadow.d.ts +28 -0
- package/dist/lib/binary-shadow.js +121 -0
- package/dist/lib/brand.js +9 -3
- package/dist/lib/browser/hygiene.d.ts +90 -0
- package/dist/lib/browser/hygiene.js +146 -0
- package/dist/lib/browser/ipc.d.ts +30 -0
- package/dist/lib/browser/ipc.js +93 -4
- package/dist/lib/browser/profiles.d.ts +3 -2
- package/dist/lib/browser/profiles.js +65 -22
- package/dist/lib/browser/service.d.ts +79 -1
- package/dist/lib/browser/service.js +231 -14
- package/dist/lib/browser/sessions-list.d.ts +22 -2
- package/dist/lib/browser/sessions-list.js +54 -6
- package/dist/lib/browser/stream.d.ts +2 -0
- package/dist/lib/browser/stream.js +1 -0
- package/dist/lib/browser/types.d.ts +63 -1
- package/dist/lib/byok-usage.d.ts +9 -2
- package/dist/lib/byok-usage.js +133 -31
- package/dist/lib/cli-entry.d.ts +11 -0
- package/dist/lib/cli-entry.js +46 -0
- package/dist/lib/cloud/host.d.ts +1 -1
- package/dist/lib/cloud/host.js +2 -2
- package/dist/lib/cloud/registry.js +1 -1
- package/dist/lib/cloud/types.d.ts +1 -1
- package/dist/lib/commands.d.ts +2 -0
- package/dist/lib/commands.js +2 -0
- package/dist/lib/computer/sessions-list.d.ts +150 -0
- package/dist/lib/computer/sessions-list.js +363 -0
- package/dist/lib/config-keys.d.ts +86 -0
- package/dist/lib/config-keys.js +193 -0
- package/dist/lib/config-machine-keys.d.ts +12 -0
- package/dist/lib/config-machine-keys.js +17 -0
- package/dist/lib/config-transfer.js +3 -4
- package/dist/lib/crabbox/cli.d.ts +2 -2
- package/dist/lib/crabbox/cli.js +3 -3
- package/dist/lib/daemon-health.d.ts +22 -0
- package/dist/lib/daemon-health.js +33 -3
- package/dist/lib/daemon-services.d.ts +50 -0
- package/dist/lib/daemon-services.js +147 -0
- package/dist/lib/daemon-ticks.d.ts +35 -66
- package/dist/lib/daemon-ticks.js +77 -159
- package/dist/lib/daemon.d.ts +72 -4
- package/dist/lib/daemon.js +792 -202
- package/dist/lib/deeplink/register.d.ts +49 -0
- package/dist/lib/deeplink/register.js +253 -0
- package/dist/lib/deeplink/url.d.ts +34 -0
- package/dist/lib/deeplink/url.js +78 -0
- package/dist/lib/device-config.d.ts +124 -29
- package/dist/lib/device-config.js +346 -141
- package/dist/lib/devices/config-migration.d.ts +42 -0
- package/dist/lib/devices/config-migration.js +203 -0
- package/dist/lib/devices/connect.js +14 -7
- package/dist/lib/devices/doctor-findings.d.ts +4 -1
- package/dist/lib/devices/doctor-findings.js +20 -1
- package/dist/lib/devices/harness-inventory.d.ts +11 -2
- package/dist/lib/devices/harness-inventory.js +0 -0
- package/dist/lib/devices/health.d.ts +1 -1
- package/dist/lib/devices/health.js +1 -1
- package/dist/lib/devices/pending.d.ts +22 -1
- package/dist/lib/devices/pending.js +67 -2
- package/dist/lib/devices/registry.d.ts +0 -25
- package/dist/lib/devices/registry.js +2 -83
- package/dist/lib/devices/resolve-profile.d.ts +20 -0
- package/dist/lib/devices/resolve-profile.js +44 -0
- package/dist/lib/devices/rollout-verify.d.ts +101 -0
- package/dist/lib/devices/rollout-verify.js +193 -0
- package/dist/lib/devices/ssh-config.js +10 -6
- package/dist/lib/event-families.d.ts +28 -0
- package/dist/lib/event-families.js +159 -0
- package/dist/lib/event-stream.d.ts +9 -1
- package/dist/lib/event-stream.js +26 -9
- package/dist/lib/events.d.ts +9 -1
- package/dist/lib/events.js +21 -6
- package/dist/lib/exec.d.ts +30 -0
- package/dist/lib/exec.js +219 -121
- package/dist/lib/feed-broadcast.d.ts +25 -0
- package/dist/lib/feed-broadcast.js +33 -0
- package/dist/lib/feed.d.ts +1 -1
- package/dist/lib/feed.js +12 -2
- package/dist/lib/fleet/capture.js +15 -0
- package/dist/lib/fleet/manifest.js +9 -0
- package/dist/lib/fleet/types.d.ts +9 -0
- package/dist/lib/fleet-status.js +10 -8
- package/dist/lib/git.d.ts +21 -7
- package/dist/lib/git.js +122 -18
- package/dist/lib/hosts/dispatch.d.ts +8 -3
- package/dist/lib/hosts/dispatch.js +29 -3
- package/dist/lib/hosts/logs.d.ts +2 -2
- package/dist/lib/hosts/logs.js +2 -2
- package/dist/lib/hosts/option.js +1 -1
- package/dist/lib/hosts/passthrough.d.ts +2 -3
- package/dist/lib/hosts/passthrough.js +10 -24
- package/dist/lib/hosts/progress.js +2 -2
- package/dist/lib/hosts/providers/devices.d.ts +3 -3
- package/dist/lib/hosts/providers/devices.js +18 -12
- package/dist/lib/hosts/ready.d.ts +5 -1
- package/dist/lib/hosts/ready.js +9 -3
- package/dist/lib/hosts/reconcile.d.ts +2 -2
- package/dist/lib/hosts/reconcile.js +2 -2
- package/dist/lib/hosts/registry.js +14 -9
- package/dist/lib/hosts/remote-cmd.js +1 -1
- package/dist/lib/hosts/remote-os.d.ts +9 -6
- package/dist/lib/hosts/remote-os.js +13 -6
- package/dist/lib/hosts/routing-flag.d.ts +23 -0
- package/dist/lib/hosts/routing-flag.js +41 -0
- package/dist/lib/hosts/run-target.js +1 -1
- package/dist/lib/hosts/session-index.js +1 -1
- package/dist/lib/hosts/tasks.d.ts +6 -6
- package/dist/lib/hosts/tasks.js +4 -4
- package/dist/lib/hosts/types.js +1 -2
- package/dist/lib/installations/resolve.js +2 -8
- package/dist/lib/isolation-boundary-report.js +0 -1
- package/dist/lib/linear-cache.d.ts +7 -0
- package/dist/lib/linear-cache.js +31 -4
- package/dist/lib/linear-project-counts.d.ts +1 -1
- package/dist/lib/linear-project-counts.js +2 -3
- package/dist/lib/linear-projects.js +1 -1
- package/dist/lib/loop.d.ts +2 -2
- package/dist/lib/loop.js +1 -1
- package/dist/lib/mailbox-target.d.ts +1 -1
- package/dist/lib/mailbox-target.js +1 -1
- package/dist/lib/manifest.js +7 -4
- package/dist/lib/menubar/MenubarHelper.app/Contents/CodeResources +0 -0
- package/dist/lib/menubar/MenubarHelper.app/Contents/MacOS/MenubarHelper +0 -0
- package/dist/lib/menubar/snapshot.d.ts +3 -2
- package/dist/lib/menubar/snapshot.js +6 -2
- package/dist/lib/migrate-fold.d.ts +33 -0
- package/dist/lib/migrate-fold.js +130 -0
- package/dist/lib/migrate.d.ts +34 -34
- package/dist/lib/migrate.js +106 -128
- package/dist/lib/model-tier-overrides.d.ts +1 -1
- package/dist/lib/model-tier-overrides.js +15 -2
- package/dist/lib/monitors/config.d.ts +17 -3
- package/dist/lib/monitors/config.js +52 -18
- package/dist/lib/monitors/engine.d.ts +32 -1
- package/dist/lib/monitors/engine.js +94 -11
- package/dist/lib/monitors/fingerprint.d.ts +46 -0
- package/dist/lib/monitors/fingerprint.js +100 -0
- package/dist/lib/monitors/remote.d.ts +47 -0
- package/dist/lib/monitors/remote.js +81 -0
- package/dist/lib/monitors/state.d.ts +39 -0
- package/dist/lib/monitors/state.js +56 -0
- package/dist/lib/onepassword.d.ts +17 -0
- package/dist/lib/onepassword.js +52 -22
- package/dist/lib/open-url.js +1 -1
- package/dist/lib/picker.d.ts +14 -2
- package/dist/lib/picker.js +35 -13
- package/dist/lib/placement.d.ts +1 -1
- package/dist/lib/placement.js +1 -1
- package/dist/lib/pr-land-detach.d.ts +32 -0
- package/dist/lib/pr-land-detach.js +79 -0
- package/dist/lib/profiles-presets.js +13 -0
- package/dist/lib/profiles.d.ts +2 -0
- package/dist/lib/profiles.js +44 -1
- package/dist/lib/project-focus.d.ts +1 -1
- package/dist/lib/project-focus.js +1 -1
- package/dist/lib/project-probe.d.ts +4 -1
- package/dist/lib/project-probe.js +5 -4
- package/dist/lib/project-resources.js +2 -18
- package/dist/lib/project-root.d.ts +16 -0
- package/dist/lib/project-root.js +20 -2
- package/dist/lib/projects.d.ts +20 -1
- package/dist/lib/projects.js +78 -1
- package/dist/lib/refresh-coordinator.d.ts +24 -0
- package/dist/lib/refresh-coordinator.js +52 -0
- package/dist/lib/registry.d.ts +2 -2
- package/dist/lib/registry.js +1 -1
- package/dist/lib/resource-aliases.d.ts +13 -0
- package/dist/lib/resource-aliases.js +26 -0
- package/dist/lib/resources/types.d.ts +1 -1
- package/dist/lib/resources.d.ts +16 -0
- package/dist/lib/resources.js +66 -10
- package/dist/lib/rotate.d.ts +3 -4
- package/dist/lib/rotate.js +4 -5
- package/dist/lib/routine-activation.d.ts +22 -2
- package/dist/lib/routine-activation.js +63 -16
- package/dist/lib/routine-context.d.ts +9 -2
- package/dist/lib/routine-context.js +21 -6
- package/dist/lib/routines-project.d.ts +58 -48
- package/dist/lib/routines-project.js +190 -159
- package/dist/lib/routines.d.ts +44 -7
- package/dist/lib/routines.js +92 -34
- package/dist/lib/run-defaults.d.ts +5 -0
- package/dist/lib/run-defaults.js +11 -1
- package/dist/lib/runner.d.ts +10 -8
- package/dist/lib/runner.js +122 -39
- package/dist/lib/secrets/Agents CLI.app/Contents/CodeResources +0 -0
- package/dist/lib/secrets/Agents CLI.app/Contents/MacOS/Agents CLI +0 -0
- package/dist/lib/secrets/agent.d.ts +10 -3
- package/dist/lib/secrets/agent.js +43 -8
- package/dist/lib/secrets/bundles.d.ts +1 -0
- package/dist/lib/secrets/bundles.js +92 -80
- package/dist/lib/secrets/index.js +32 -9
- package/dist/lib/secrets/install-helper.d.ts +4 -4
- package/dist/lib/secrets/install-helper.js +4 -4
- package/dist/lib/secrets/push.d.ts +40 -6
- package/dist/lib/secrets/push.js +58 -11
- package/dist/lib/secrets/read-backoff.d.ts +1 -1
- package/dist/lib/secrets/read-backoff.js +1 -1
- package/dist/lib/secrets/remote.d.ts +24 -0
- package/dist/lib/secrets/remote.js +54 -4
- package/dist/lib/self-update.d.ts +108 -0
- package/dist/lib/self-update.js +276 -1
- package/dist/lib/session/active.d.ts +89 -5
- package/dist/lib/session/active.js +165 -10
- package/dist/lib/session/actor-sidecar.d.ts +1 -1
- package/dist/lib/session/actor-sidecar.js +2 -1
- package/dist/lib/session/db.d.ts +176 -2
- package/dist/lib/session/db.js +484 -17
- package/dist/lib/session/discover.js +27 -4
- package/dist/lib/session/hook-sessions.js +2 -2
- package/dist/lib/session/host-link.d.ts +2 -2
- package/dist/lib/session/host-link.js +2 -2
- package/dist/lib/session/pid-registry.d.ts +21 -0
- package/dist/lib/session/pid-registry.js +57 -0
- package/dist/lib/session/remote-active.js +15 -1
- package/dist/lib/session/remote.js +2 -2
- package/dist/lib/session/session-cache.d.ts +14 -7
- package/dist/lib/session/session-cache.js +51 -9
- package/dist/lib/session/state.d.ts +2 -2
- package/dist/lib/session/state.js +1 -1
- package/dist/lib/session/sync/config.d.ts +10 -10
- package/dist/lib/session/sync/config.js +10 -10
- package/dist/lib/session/sync/r2.d.ts +34 -0
- package/dist/lib/session/sync/r2.js +123 -0
- package/dist/lib/session/throughput.d.ts +1 -1
- package/dist/lib/session/throughput.js +1 -1
- package/dist/lib/session/types.d.ts +23 -1
- package/dist/lib/session/types.js +15 -0
- package/dist/lib/session/viewing-in.d.ts +1 -1
- package/dist/lib/session/viewing-in.js +1 -1
- package/dist/lib/session/watch.d.ts +101 -0
- package/dist/lib/session/watch.js +242 -0
- package/dist/lib/share/analytics.js +1 -1
- package/dist/lib/share/capture.d.ts +1 -1
- package/dist/lib/share/capture.js +3 -3
- package/dist/lib/share/config.d.ts +6 -2
- package/dist/lib/share/config.js +6 -5
- package/dist/lib/share/delete.js +3 -3
- package/dist/lib/share/provision.d.ts +38 -0
- package/dist/lib/share/provision.js +51 -1
- package/dist/lib/share/publish.d.ts +40 -1
- package/dist/lib/share/publish.js +119 -6
- package/dist/lib/share/worker-template.d.ts +12 -1
- package/dist/lib/share/worker-template.js +83 -7
- package/dist/lib/shims.d.ts +17 -3
- package/dist/lib/shims.js +98 -26
- package/dist/lib/signin-badge.js +3 -2
- package/dist/lib/skills.js +2 -0
- package/dist/lib/smart-launch.d.ts +8 -8
- package/dist/lib/smart-launch.js +80 -59
- package/dist/lib/ssh-exec.d.ts +1 -1
- package/dist/lib/ssh-exec.js +1 -1
- package/dist/lib/staleness/prune.d.ts +88 -0
- package/dist/lib/staleness/prune.js +69 -0
- package/dist/lib/staleness/registry.d.ts +1 -1
- package/dist/lib/staleness/writers/commands.js +34 -2
- package/dist/lib/staleness/writers/hooks.js +16 -0
- package/dist/lib/staleness/writers/kinds.d.ts +6 -0
- package/dist/lib/staleness/writers/skills.js +19 -0
- package/dist/lib/staleness/writers/subagents.d.ts +2 -3
- package/dist/lib/staleness/writers/subagents.js +0 -4
- package/dist/lib/staleness/writers/types.d.ts +32 -0
- package/dist/lib/startup/command-registry.d.ts +16 -14
- package/dist/lib/startup/command-registry.js +26 -37
- package/dist/lib/startup/dev-build.d.ts +10 -0
- package/dist/lib/startup/dev-build.js +13 -1
- package/dist/lib/startup/spellcheck.d.ts +18 -0
- package/dist/lib/startup/spellcheck.js +45 -0
- package/dist/lib/state.d.ts +36 -9
- package/dist/lib/state.js +96 -46
- package/dist/lib/subagents-registry.d.ts +0 -7
- package/dist/lib/subagents-registry.js +38 -65
- package/dist/lib/subagents.d.ts +0 -33
- package/dist/lib/subagents.js +0 -75
- package/dist/lib/sync-umbrella.js +1 -1
- package/dist/lib/teams/agents.d.ts +41 -1
- package/dist/lib/teams/agents.js +187 -9
- package/dist/lib/teams/api.d.ts +11 -1
- package/dist/lib/teams/api.js +11 -2
- package/dist/lib/teams/delivery.d.ts +41 -0
- package/dist/lib/teams/delivery.js +60 -0
- package/dist/lib/teams/registry.d.ts +14 -0
- package/dist/lib/teams/registry.js +51 -1
- package/dist/lib/teams/remoteWorktree.d.ts +19 -0
- package/dist/lib/teams/remoteWorktree.js +29 -0
- package/dist/lib/teams/scheduler.d.ts +1 -1
- package/dist/lib/teams/scheduler.js +1 -1
- package/dist/lib/teams/worktree.d.ts +24 -0
- package/dist/lib/teams/worktree.js +42 -0
- package/dist/lib/terminal/backends/vscodium-agent.d.ts +10 -1
- package/dist/lib/terminal/backends/vscodium-agent.js +16 -5
- package/dist/lib/terminal/engine.d.ts +4 -0
- package/dist/lib/terminal/engine.js +8 -2
- package/dist/lib/terminal/types.d.ts +21 -2
- package/dist/lib/testdata/refresh-coordinator-worker.d.ts +1 -0
- package/dist/lib/testdata/refresh-coordinator-worker.js +23 -0
- package/dist/lib/tickets/list.d.ts +53 -0
- package/dist/lib/tickets/list.js +153 -0
- package/dist/lib/tmux/orphan-reap.d.ts +316 -0
- package/dist/lib/tmux/orphan-reap.js +638 -0
- package/dist/lib/tmux/session.d.ts +68 -3
- package/dist/lib/tmux/session.js +96 -5
- package/dist/lib/triggers/handlers.d.ts +20 -0
- package/dist/lib/triggers/handlers.js +16 -1
- package/dist/lib/triggers/webhook.js +10 -0
- package/dist/lib/types.d.ts +47 -35
- package/dist/lib/usage-fleet.d.ts +32 -0
- package/dist/lib/usage-fleet.js +125 -0
- package/dist/lib/usage-refresh.d.ts +3 -3
- package/dist/lib/usage-refresh.js +19 -16
- package/dist/lib/usage.d.ts +51 -47
- package/dist/lib/usage.js +145 -153
- package/dist/lib/version-duplicates.js +2 -2
- package/dist/lib/versions.d.ts +56 -13
- package/dist/lib/versions.js +195 -45
- package/dist/lib/watchdog/log.d.ts +1 -1
- package/dist/lib/watchdog/log.js +3 -3
- package/dist/lib/watchdog/rotate.d.ts +6 -6
- package/dist/lib/watchdog/rotate.js +6 -6
- package/dist/lib/workflows.d.ts +1 -1
- package/dist/lib/yaml-io.d.ts +47 -0
- package/dist/lib/yaml-io.js +55 -0
- package/package.json +2 -1
- package/scripts/install-helper.js +2 -2
- package/scripts/postinstall.js +23 -20
- package/dist/commands/defaults.d.ts +0 -7
- package/dist/commands/defaults.js +0 -107
- package/dist/commands/export.d.ts +0 -11
- package/dist/commands/export.js +0 -215
- package/dist/commands/helper.d.ts +0 -12
- package/dist/commands/helper.js +0 -87
- package/dist/commands/hosts.d.ts +0 -11
- package/dist/commands/hosts.js +0 -330
- package/dist/commands/lock.d.ts +0 -12
- package/dist/commands/lock.js +0 -70
- package/dist/commands/pull.d.ts +0 -17
- package/dist/commands/pull.js +0 -39
- package/dist/commands/push.d.ts +0 -14
- package/dist/commands/push.js +0 -30
- package/dist/commands/set.d.ts +0 -15
- package/dist/commands/set.js +0 -79
- package/dist/commands/setup-share.d.ts +0 -17
- package/dist/commands/setup-share.js +0 -85
- package/dist/commands/wallet.d.ts +0 -20
- package/dist/commands/wallet.js +0 -216
- package/dist/commands/worktree.d.ts +0 -19
- package/dist/commands/worktree.js +0 -272
- package/dist/lib/account-labels.d.ts +0 -24
- package/dist/lib/account-labels.js +0 -72
- package/dist/lib/auto-dispatch-linear.d.ts +0 -18
- package/dist/lib/auto-dispatch-linear.js +0 -107
- package/dist/lib/auto-dispatch-provider.d.ts +0 -10
- package/dist/lib/auto-dispatch-provider.js +0 -30
- package/dist/lib/auto-dispatch.d.ts +0 -93
- package/dist/lib/auto-dispatch.js +0 -128
- package/dist/lib/export.d.ts +0 -72
- package/dist/lib/export.js +0 -269
- package/dist/lib/lock.d.ts +0 -93
- package/dist/lib/lock.js +0 -207
- package/dist/lib/wallet/index.d.ts +0 -78
- package/dist/lib/wallet/index.js +0 -253
package/dist/lib/session/db.js
CHANGED
|
@@ -16,17 +16,18 @@ import { query as queryEvents, queryToolUsageForSessions } from '../events.js';
|
|
|
16
16
|
import { machineForSessionFile } from './origin-machine.js';
|
|
17
17
|
import { loadSessionActorIndex, readSessionActorRecord } from './actor-sidecar.js';
|
|
18
18
|
import { toolCallsFromEvents } from './tool-calls.js';
|
|
19
|
-
import { persistToolCalls,
|
|
19
|
+
import { persistToolCalls, toolEvidenceSourcePath } from './tool-store.js';
|
|
20
20
|
import { buildClaudeAccountIndex, resolveClaudeAccount } from './claude-accounts.js';
|
|
21
21
|
import { extractSkills, extractSlashCommands } from './highlights.js';
|
|
22
22
|
import { resolveResource } from '../resources.js';
|
|
23
23
|
import { discoverPlugins } from '../plugins.js';
|
|
24
|
+
import { machineId } from '../machine-id.js';
|
|
24
25
|
const SESSIONS_DIR = getSessionsDir();
|
|
25
26
|
const DB_PATH = getSessionsDbPath();
|
|
26
27
|
/** Current schema version; bumped when migrations are added. Exported so tests
|
|
27
28
|
* assert against the constant instead of hardcoding a number that every bump
|
|
28
|
-
* then has to chase (docs/
|
|
29
|
-
export const SCHEMA_VERSION =
|
|
29
|
+
* then has to chase (docs/sessions.md calls the constant the source of truth). */
|
|
30
|
+
export const SCHEMA_VERSION = 39;
|
|
30
31
|
/**
|
|
31
32
|
* Bump to force `agents sessions backfill resources` to re-derive every
|
|
32
33
|
* session's skill/slash-command tallies on its next run (resource_scan_ledger
|
|
@@ -108,7 +109,14 @@ CREATE TABLE IF NOT EXISTS sessions (
|
|
|
108
109
|
actor TEXT,
|
|
109
110
|
initiated_by TEXT,
|
|
110
111
|
used_browser INTEGER,
|
|
111
|
-
used_computer INTEGER
|
|
112
|
+
used_computer INTEGER,
|
|
113
|
+
-- Epoch ms of the first time a previously-scanned transcript was confirmed
|
|
114
|
+
-- gone from disk while its user-turn content still lives in session_text
|
|
115
|
+
-- (RUSH-2436). Non-NULL means "archived": the row is served/rendered from the
|
|
116
|
+
-- DB and flagged, instead of being dropped when the file vanishes. A row whose
|
|
117
|
+
-- file is missing but which has NO cached content is a phantom (a stale/moved
|
|
118
|
+
-- file_path), never stamped, still suppressed — see querySessions.
|
|
119
|
+
archived_at INTEGER
|
|
112
120
|
);
|
|
113
121
|
CREATE INDEX IF NOT EXISTS idx_sessions_timestamp ON sessions(timestamp DESC);
|
|
114
122
|
CREATE INDEX IF NOT EXISTS idx_sessions_cwd ON sessions(cwd);
|
|
@@ -317,6 +325,69 @@ CREATE TABLE IF NOT EXISTS session_preview_cache (
|
|
|
317
325
|
computed_at INTEGER NOT NULL,
|
|
318
326
|
preview_json TEXT NOT NULL
|
|
319
327
|
);
|
|
328
|
+
|
|
329
|
+
-- Durable metadata for one browser task (RUSH-2549). The browser daemon's
|
|
330
|
+
-- tasks.json is LIVE state: saveTaskState writes the in-memory task map, so
|
|
331
|
+
-- stopping a task drops its entry and a daemon restart empties the file. That is
|
|
332
|
+
-- correct for live state and useless as history, which is why every finished task
|
|
333
|
+
-- listed as "unlinked". This row is written once at task start and is never
|
|
334
|
+
-- deleted, so the link from a capture back to the agent session that drove it
|
|
335
|
+
-- survives the task, the daemon, and a reboot.
|
|
336
|
+
--
|
|
337
|
+
-- METADATA ONLY: capture bytes are never stored here. capture_dir points at the
|
|
338
|
+
-- on-disk directory (.cache/browser/<profile>/sessions/<task>/) that already holds
|
|
339
|
+
-- them, and the per-kind counts are what a listing needs to render a row without
|
|
340
|
+
-- walking that tree. captures_remote is set only when the optional offload has
|
|
341
|
+
-- copied them through the existing encrypted r2.backups sync.
|
|
342
|
+
--
|
|
343
|
+
-- session_id is the agent session (AGENT_SESSION_ID, which every agent carries);
|
|
344
|
+
-- launch_id stays as the secondary join key for a caller that has only that. actor
|
|
345
|
+
-- is the HUMAN/tailnet identity and is deliberately NOT an agent id -- resolveActor
|
|
346
|
+
-- answers UNRESOLVED@<host> for any local run by design (lib/actor.ts).
|
|
347
|
+
CREATE TABLE IF NOT EXISTS browser_sessions (
|
|
348
|
+
task TEXT NOT NULL,
|
|
349
|
+
profile TEXT NOT NULL,
|
|
350
|
+
session_id TEXT,
|
|
351
|
+
launch_id TEXT,
|
|
352
|
+
actor TEXT,
|
|
353
|
+
machine TEXT NOT NULL,
|
|
354
|
+
started_at INTEGER NOT NULL,
|
|
355
|
+
last_activity INTEGER,
|
|
356
|
+
screenshot_count INTEGER NOT NULL DEFAULT 0,
|
|
357
|
+
pdf_count INTEGER NOT NULL DEFAULT 0,
|
|
358
|
+
recording_count INTEGER NOT NULL DEFAULT 0,
|
|
359
|
+
download_count INTEGER NOT NULL DEFAULT 0,
|
|
360
|
+
capture_dir TEXT,
|
|
361
|
+
captures_remote TEXT,
|
|
362
|
+
PRIMARY KEY (profile, task)
|
|
363
|
+
);
|
|
364
|
+
CREATE INDEX IF NOT EXISTS idx_browser_sessions_session ON browser_sessions(session_id);
|
|
365
|
+
CREATE INDEX IF NOT EXISTS idx_browser_sessions_started ON browser_sessions(started_at DESC);
|
|
366
|
+
|
|
367
|
+
-- Durable metadata for one "agents computer" invocation (RUSH-2549). Computer-use
|
|
368
|
+
-- already resolves identity correctly -- stampProvenance stamps AGENT_SESSION_ID
|
|
369
|
+
-- straight onto each computer.action event -- but those events live in the bounded
|
|
370
|
+
-- audit ledger, which prunes at 7 days / 50 MiB (events.ts). So a run's history
|
|
371
|
+
-- silently vanished on day 8. This row carries the same identity into the durable
|
|
372
|
+
-- store; the ledger is untouched and remains the audit log, with no second pruner.
|
|
373
|
+
--
|
|
374
|
+
-- Keyed on invocation_id, the id emitComputerAction stamps once per emitting CLI
|
|
375
|
+
-- process: one explicit verb is one row, and a whole "computer run" observe/act
|
|
376
|
+
-- loop is also one row. task_preview is already bounded by events.ts truncate()
|
|
377
|
+
-- before it is ever written, and typed-text content is never captured at all.
|
|
378
|
+
CREATE TABLE IF NOT EXISTS computer_sessions (
|
|
379
|
+
invocation_id TEXT PRIMARY KEY,
|
|
380
|
+
session_id TEXT,
|
|
381
|
+
launch_id TEXT,
|
|
382
|
+
actor TEXT,
|
|
383
|
+
machine TEXT NOT NULL,
|
|
384
|
+
started_at INTEGER NOT NULL,
|
|
385
|
+
last_activity INTEGER,
|
|
386
|
+
action_count INTEGER NOT NULL DEFAULT 0,
|
|
387
|
+
task_preview TEXT
|
|
388
|
+
);
|
|
389
|
+
CREATE INDEX IF NOT EXISTS idx_computer_sessions_session ON computer_sessions(session_id);
|
|
390
|
+
CREATE INDEX IF NOT EXISTS idx_computer_sessions_started ON computer_sessions(started_at DESC);
|
|
320
391
|
`;
|
|
321
392
|
/**
|
|
322
393
|
* Bumping this invalidates every cached facet row without touching the schema
|
|
@@ -912,6 +983,60 @@ function migrateSchema(db, fromVersion) {
|
|
|
912
983
|
if (!cols.has('cost_usd_nocache'))
|
|
913
984
|
db.exec(`ALTER TABLE sessions ADD COLUMN cost_usd_nocache REAL`);
|
|
914
985
|
}
|
|
986
|
+
if (fromVersion < 38) {
|
|
987
|
+
// v37 -> v38: archived_at (RUSH-2436). Makes the local DB authoritative for
|
|
988
|
+
// content: a session whose transcript file is gone but whose user turns still
|
|
989
|
+
// live in session_text is kept (flagged archived) instead of dropped from
|
|
990
|
+
// listings. New nullable column, so no ledger flush — it is populated lazily
|
|
991
|
+
// by querySessions the first time it confirms a scanned file is gone.
|
|
992
|
+
const cols = db.prepare(`PRAGMA table_info(sessions)`).all();
|
|
993
|
+
if (!cols.some((c) => c.name === 'archived_at'))
|
|
994
|
+
db.exec(`ALTER TABLE sessions ADD COLUMN archived_at INTEGER`);
|
|
995
|
+
}
|
|
996
|
+
if (fromVersion < 39) {
|
|
997
|
+
// v38 -> v39: durable tool-session metadata (RUSH-2549). Browser task identity
|
|
998
|
+
// lived only in the daemon's tasks.json, which is rewritten from the live task
|
|
999
|
+
// map -- so stopping a task erased the link to the agent session that drove it
|
|
1000
|
+
// and every finished task listed as "unlinked". Computer-use had the identity
|
|
1001
|
+
// right but wrote it to the 7-day event ledger, so its history expired instead.
|
|
1002
|
+
// Both now persist metadata here. Pure additions, so no ledger flush: nothing
|
|
1003
|
+
// already indexed is invalidated, and the tables populate going forward.
|
|
1004
|
+
db.exec(`
|
|
1005
|
+
CREATE TABLE IF NOT EXISTS browser_sessions (
|
|
1006
|
+
task TEXT NOT NULL,
|
|
1007
|
+
profile TEXT NOT NULL,
|
|
1008
|
+
session_id TEXT,
|
|
1009
|
+
launch_id TEXT,
|
|
1010
|
+
actor TEXT,
|
|
1011
|
+
machine TEXT NOT NULL,
|
|
1012
|
+
started_at INTEGER NOT NULL,
|
|
1013
|
+
last_activity INTEGER,
|
|
1014
|
+
screenshot_count INTEGER NOT NULL DEFAULT 0,
|
|
1015
|
+
pdf_count INTEGER NOT NULL DEFAULT 0,
|
|
1016
|
+
recording_count INTEGER NOT NULL DEFAULT 0,
|
|
1017
|
+
download_count INTEGER NOT NULL DEFAULT 0,
|
|
1018
|
+
capture_dir TEXT,
|
|
1019
|
+
captures_remote TEXT,
|
|
1020
|
+
PRIMARY KEY (profile, task)
|
|
1021
|
+
);
|
|
1022
|
+
CREATE INDEX IF NOT EXISTS idx_browser_sessions_session ON browser_sessions(session_id);
|
|
1023
|
+
CREATE INDEX IF NOT EXISTS idx_browser_sessions_started ON browser_sessions(started_at DESC);
|
|
1024
|
+
|
|
1025
|
+
CREATE TABLE IF NOT EXISTS computer_sessions (
|
|
1026
|
+
invocation_id TEXT PRIMARY KEY,
|
|
1027
|
+
session_id TEXT,
|
|
1028
|
+
launch_id TEXT,
|
|
1029
|
+
actor TEXT,
|
|
1030
|
+
machine TEXT NOT NULL,
|
|
1031
|
+
started_at INTEGER NOT NULL,
|
|
1032
|
+
last_activity INTEGER,
|
|
1033
|
+
action_count INTEGER NOT NULL DEFAULT 0,
|
|
1034
|
+
task_preview TEXT
|
|
1035
|
+
);
|
|
1036
|
+
CREATE INDEX IF NOT EXISTS idx_computer_sessions_session ON computer_sessions(session_id);
|
|
1037
|
+
CREATE INDEX IF NOT EXISTS idx_computer_sessions_started ON computer_sessions(started_at DESC);
|
|
1038
|
+
`);
|
|
1039
|
+
}
|
|
915
1040
|
}
|
|
916
1041
|
/**
|
|
917
1042
|
* Stamp `account_key` / `account_org` / `account` on every Claude row from its
|
|
@@ -2134,6 +2259,11 @@ function rowToMeta(row) {
|
|
|
2134
2259
|
// instead of trusting a false "never used browser/computer".
|
|
2135
2260
|
usedBrowser: row.used_browser === null ? undefined : row.used_browser === 1,
|
|
2136
2261
|
usedComputer: row.used_computer === null ? undefined : row.used_computer === 1,
|
|
2262
|
+
// A stamped archived_at means the transcript file is gone but the session's
|
|
2263
|
+
// user turns still live in session_text — the row is served from the DB and
|
|
2264
|
+
// flagged, never dropped (RUSH-2436). NULL leaves both undefined (live row).
|
|
2265
|
+
archivedAt: row.archived_at ?? undefined,
|
|
2266
|
+
archived: row.archived_at != null ? true : undefined,
|
|
2137
2267
|
};
|
|
2138
2268
|
}
|
|
2139
2269
|
function isSessionRunMode(value) {
|
|
@@ -2399,23 +2529,61 @@ export function querySessions(options = {}) {
|
|
|
2399
2529
|
const trimmed = options.limit ? rows.slice(0, options.limit) : rows;
|
|
2400
2530
|
return trimmed.map(rowToMeta);
|
|
2401
2531
|
}
|
|
2402
|
-
//
|
|
2403
|
-
//
|
|
2404
|
-
//
|
|
2405
|
-
//
|
|
2406
|
-
//
|
|
2407
|
-
//
|
|
2532
|
+
// A row whose transcript file is gone from disk is one of two things, and the
|
|
2533
|
+
// local DB is now authoritative for telling them apart (RUSH-2436):
|
|
2534
|
+
// - ARCHIVED — its user turns still live in session_text. The session is
|
|
2535
|
+
// real; the file was just removed (agents remove trash, a manual rm, a
|
|
2536
|
+
// .history rotation, a box reimage). Keep it, stamped `archived`, so it
|
|
2537
|
+
// still lists and renders from the DB instead of silently vanishing.
|
|
2538
|
+
// - PHANTOM — a stale/moved file_path with NO cached content (#136), e.g. a
|
|
2539
|
+
// path a scan forgot to rewrite. There is nothing durable to serve, so it
|
|
2540
|
+
// stays suppressed exactly as before.
|
|
2541
|
+
// We NO LONGER purge tool-call evidence here: merely listing a file-gone
|
|
2542
|
+
// session used to DELETE its redacted tool calls (purgeToolCalls), destroying
|
|
2543
|
+
// durable data on a read. Synthetic rows (OpenClaw channels/cron — see
|
|
2544
|
+
// scanOpenClawIncremental) carry an empty file_path and are exempt.
|
|
2408
2545
|
const missingPaths = findMissingFilePaths(rows.map(r => r.file_path).filter((p) => !!p));
|
|
2409
2546
|
const missing = rows.filter(r => r.file_path && missingPaths.has(r.file_path));
|
|
2547
|
+
const missingIds = new Set(missing.map(r => r.id));
|
|
2548
|
+
const phantomIds = new Set();
|
|
2410
2549
|
if (missing.length > 0) {
|
|
2411
|
-
const
|
|
2412
|
-
|
|
2413
|
-
|
|
2550
|
+
const readContent = db.prepare(`SELECT content FROM session_text WHERE session_id = ?`);
|
|
2551
|
+
const markArchived = db.prepare(`UPDATE sessions SET archived_at = ? WHERE id = ? AND archived_at IS NULL`);
|
|
2552
|
+
const now = Date.now();
|
|
2553
|
+
const classify = db.transaction(() => {
|
|
2554
|
+
for (const row of missing) {
|
|
2555
|
+
const content = readContent.get(row.id)?.content;
|
|
2556
|
+
if (content && content.trim() !== '') {
|
|
2557
|
+
// Genuine archived session: stamp archived_at the first time we confirm
|
|
2558
|
+
// the file is gone, and reflect it on the in-memory row we return.
|
|
2559
|
+
if (row.archived_at == null) {
|
|
2560
|
+
markArchived.run(now, row.id);
|
|
2561
|
+
row.archived_at = now;
|
|
2562
|
+
}
|
|
2563
|
+
}
|
|
2564
|
+
else {
|
|
2565
|
+
phantomIds.add(row.id);
|
|
2566
|
+
}
|
|
2567
|
+
}
|
|
2414
2568
|
});
|
|
2415
|
-
|
|
2569
|
+
classify();
|
|
2570
|
+
}
|
|
2571
|
+
// Un-archive a row whose file came back (a recoverable-trash restore, a re-sync):
|
|
2572
|
+
// it is present on disk now, so it must not keep reporting `archived` to a
|
|
2573
|
+
// machine consumer reading the --json listing. Rare, so the write only fires when
|
|
2574
|
+
// such a row actually exists (RUSH-2436).
|
|
2575
|
+
const resurrected = rows.filter(r => r.archived_at != null && !missingIds.has(r.id));
|
|
2576
|
+
if (resurrected.length > 0) {
|
|
2577
|
+
const clearArchived = db.prepare(`UPDATE sessions SET archived_at = NULL WHERE id = ?`);
|
|
2578
|
+
const clear = db.transaction(() => {
|
|
2579
|
+
for (const row of resurrected) {
|
|
2580
|
+
clearArchived.run(row.id);
|
|
2581
|
+
row.archived_at = null;
|
|
2582
|
+
}
|
|
2583
|
+
});
|
|
2584
|
+
clear();
|
|
2416
2585
|
}
|
|
2417
|
-
const
|
|
2418
|
-
const live = rows.filter(r => !r.file_path || !missingIds.has(r.id));
|
|
2586
|
+
const live = rows.filter(r => !phantomIds.has(r.id));
|
|
2419
2587
|
const trimmed = options.limit ? live.slice(0, options.limit) : live;
|
|
2420
2588
|
return trimmed.map(rowToMeta);
|
|
2421
2589
|
}
|
|
@@ -2534,6 +2702,47 @@ export function writeSessionPreviewCache(entry) {
|
|
|
2534
2702
|
preview_json = excluded.preview_json
|
|
2535
2703
|
`).run(entry.id, entry.fileMtimeMs, entry.fileSize, PREVIEW_EXTRACTOR_VERSION, Date.now(), JSON.stringify(entry.preview));
|
|
2536
2704
|
}
|
|
2705
|
+
/**
|
|
2706
|
+
* The session's durable user-turn text, as stored in the `session_text` FTS
|
|
2707
|
+
* `content` column at scan time (all harnesses, keyed by session_id). This is
|
|
2708
|
+
* the content that survives the transcript file being deleted (RUSH-2436): the
|
|
2709
|
+
* render path reads it so a file-gone session still shows its user prompts, and
|
|
2710
|
+
* querySessions uses its presence to tell a genuine archived session (has
|
|
2711
|
+
* content) from a phantom (a stale/moved file_path with none). Returns undefined
|
|
2712
|
+
* when no row exists; an empty string when a row exists but carried no content.
|
|
2713
|
+
*/
|
|
2714
|
+
export function readSessionContent(id) {
|
|
2715
|
+
const row = getDB().prepare(`SELECT content FROM session_text WHERE session_id = ?`).get(id);
|
|
2716
|
+
return row?.content;
|
|
2717
|
+
}
|
|
2718
|
+
/**
|
|
2719
|
+
* Read the last-computed preview digest for a session by id, validated against
|
|
2720
|
+
* the session row's OWN stored file stamp rather than a live `fs.stat` — the
|
|
2721
|
+
* transcript file is gone, so there is nothing on disk to stat, but the preview
|
|
2722
|
+
* cache was written with the same `file_mtime_ms`/`file_size` the sessions row
|
|
2723
|
+
* still records, so the join re-establishes that stamp. Backs the file-gone
|
|
2724
|
+
* render/preview path (RUSH-2436). Returns undefined when no cached digest
|
|
2725
|
+
* survives for this session.
|
|
2726
|
+
*/
|
|
2727
|
+
export function readArchivedSessionPreview(id) {
|
|
2728
|
+
const row = getDB().prepare(`
|
|
2729
|
+
SELECT pc.preview_json AS previewJson
|
|
2730
|
+
FROM session_preview_cache pc
|
|
2731
|
+
JOIN sessions s ON s.id = pc.session_id
|
|
2732
|
+
WHERE pc.session_id = ?
|
|
2733
|
+
AND pc.extractor_version = ?
|
|
2734
|
+
AND pc.file_mtime_ms IS s.file_mtime_ms
|
|
2735
|
+
AND pc.file_size IS s.file_size
|
|
2736
|
+
`).get(id, PREVIEW_EXTRACTOR_VERSION);
|
|
2737
|
+
if (!row)
|
|
2738
|
+
return undefined;
|
|
2739
|
+
try {
|
|
2740
|
+
return JSON.parse(row.previewJson);
|
|
2741
|
+
}
|
|
2742
|
+
catch {
|
|
2743
|
+
return undefined;
|
|
2744
|
+
}
|
|
2745
|
+
}
|
|
2537
2746
|
/** Plugin provenance already indexed for resources used by one session. */
|
|
2538
2747
|
export function getSessionPlugins(id) {
|
|
2539
2748
|
const rows = getDB().prepare(`
|
|
@@ -2862,7 +3071,38 @@ export function topSessionsByCost(n, options = {}) {
|
|
|
2862
3071
|
// Over-fetch a small buffer to survive the on-disk liveness filter below.
|
|
2863
3072
|
const sql = `SELECT * FROM sessions ${whereCost} ORDER BY cost_usd DESC, timestamp DESC LIMIT ${limit + 16}`;
|
|
2864
3073
|
const rows = db.prepare(sql).all(...params);
|
|
2865
|
-
|
|
3074
|
+
// Keep a row whose file is present OR whose transcript is already archived
|
|
3075
|
+
// (file gone but user turns still in session_text) — an expensive, real
|
|
3076
|
+
// session must not drop out of the cost rollup just because its file was
|
|
3077
|
+
// removed (RUSH-2436). A file-gone row with no durable content (a phantom) is
|
|
3078
|
+
// still excluded. archived_at is the persisted signal; stamp it here too (once)
|
|
3079
|
+
// so a session first surfaced through the cost rollup reports `archived`
|
|
3080
|
+
// consistently with the listing path.
|
|
3081
|
+
const readContent = db.prepare(`SELECT content FROM session_text WHERE session_id = ?`);
|
|
3082
|
+
const markArchived = db.prepare(`UPDATE sessions SET archived_at = ? WHERE id = ? AND archived_at IS NULL`);
|
|
3083
|
+
const now = Date.now();
|
|
3084
|
+
const toStamp = [];
|
|
3085
|
+
const live = rows.filter(r => {
|
|
3086
|
+
if (!r.file_path || fs.existsSync(sessionFilePathContainer(r.file_path)))
|
|
3087
|
+
return true;
|
|
3088
|
+
if (r.archived_at != null)
|
|
3089
|
+
return true;
|
|
3090
|
+
const content = readContent.get(r.id)?.content;
|
|
3091
|
+
if (!!content && content.trim() !== '') {
|
|
3092
|
+
toStamp.push(r);
|
|
3093
|
+
return true;
|
|
3094
|
+
}
|
|
3095
|
+
return false;
|
|
3096
|
+
});
|
|
3097
|
+
if (toStamp.length > 0) {
|
|
3098
|
+
const stamp = db.transaction(() => {
|
|
3099
|
+
for (const r of toStamp) {
|
|
3100
|
+
markArchived.run(now, r.id);
|
|
3101
|
+
r.archived_at = now;
|
|
3102
|
+
}
|
|
3103
|
+
});
|
|
3104
|
+
stamp();
|
|
3105
|
+
}
|
|
2866
3106
|
return live.slice(0, limit).map(r => ({
|
|
2867
3107
|
meta: rowToMeta(r),
|
|
2868
3108
|
costUsd: r.cost_usd ?? 0,
|
|
@@ -2870,6 +3110,39 @@ export function topSessionsByCost(n, options = {}) {
|
|
|
2870
3110
|
}));
|
|
2871
3111
|
}
|
|
2872
3112
|
/** Look up a single session by its unique ID. */
|
|
3113
|
+
/**
|
|
3114
|
+
* Batch-resolve session ids to the machine each one runs on, in ONE indexed
|
|
3115
|
+
* query. `getActiveSessions` needs only this column for every live row, and
|
|
3116
|
+
* `getSessionById` would re-`prepare` a `SELECT *` and materialize a full
|
|
3117
|
+
* `SessionMeta` per id to read it — mirrors {@link findSessionsByShortIds}'s
|
|
3118
|
+
* single-round-trip pattern. Ids absent from the index are simply absent from
|
|
3119
|
+
* the map. Best-effort: an unavailable DB yields an empty map, so the live view
|
|
3120
|
+
* still renders (the caller then leaves rows attributed to this box).
|
|
3121
|
+
*/
|
|
3122
|
+
export function findSessionMachinesByIds(ids) {
|
|
3123
|
+
const out = new Map();
|
|
3124
|
+
const uniq = [...new Set(ids.filter(Boolean))];
|
|
3125
|
+
if (uniq.length === 0)
|
|
3126
|
+
return out;
|
|
3127
|
+
try {
|
|
3128
|
+
const db = getDB();
|
|
3129
|
+
const CHUNK = 500; // stay well under SQLite's default 999-variable limit
|
|
3130
|
+
for (let i = 0; i < uniq.length; i += CHUNK) {
|
|
3131
|
+
const batch = uniq.slice(i, i + CHUNK);
|
|
3132
|
+
const placeholders = batch.map(() => '?').join(',');
|
|
3133
|
+
const rows = db
|
|
3134
|
+
.prepare(`SELECT id, machine FROM sessions WHERE id IN (${placeholders})`)
|
|
3135
|
+
.all(...batch);
|
|
3136
|
+
for (const r of rows)
|
|
3137
|
+
if (r.machine)
|
|
3138
|
+
out.set(r.id, r.machine);
|
|
3139
|
+
}
|
|
3140
|
+
}
|
|
3141
|
+
catch {
|
|
3142
|
+
/* index read is best-effort — an unavailable DB leaves rows un-attributed */
|
|
3143
|
+
}
|
|
3144
|
+
return out;
|
|
3145
|
+
}
|
|
2873
3146
|
export function getSessionById(id) {
|
|
2874
3147
|
const db = getDB();
|
|
2875
3148
|
const row = db.prepare(`SELECT * FROM sessions WHERE id = ?`).get(id);
|
|
@@ -2882,6 +3155,12 @@ export function getSessionById(id) {
|
|
|
2882
3155
|
* short id. An exact hit short-circuits so a complete id never also drags in its
|
|
2883
3156
|
* prefix siblings. `scope` narrows by agent / version / project (cwd) so an
|
|
2884
3157
|
* ambiguous prefix disambiguates against the caller's context.
|
|
3158
|
+
*
|
|
3159
|
+
* Routes through the full querySessions existence check (NOT skipExistenceCheck)
|
|
3160
|
+
* on purpose (RUSH-2436): that check now KEEPS a file-gone session whose user
|
|
3161
|
+
* turns still live in session_text (flagged archived) and only suppresses a
|
|
3162
|
+
* contentless phantom — so `agents sessions <id>` resolves an archived session
|
|
3163
|
+
* instead of failing with "No session found", while a phantom id still misses.
|
|
2885
3164
|
*/
|
|
2886
3165
|
export function findSessionsById(idQuery, scope = {}) {
|
|
2887
3166
|
const q = idQuery.trim();
|
|
@@ -3100,3 +3379,191 @@ export function updateSessionFilePaths(oldPrefix, newPrefix) {
|
|
|
3100
3379
|
txn();
|
|
3101
3380
|
return rows.length;
|
|
3102
3381
|
}
|
|
3382
|
+
/**
|
|
3383
|
+
* Upsert one browser task's durable metadata.
|
|
3384
|
+
*
|
|
3385
|
+
* Called at task START. This executes INSIDE the browser daemon (daemon.ts
|
|
3386
|
+
* constructs BrowserService; ipc.ts dispatches `start` to it), which makes the
|
|
3387
|
+
* shared daemon a writer of this DB — but the identity it writes is RESOLVED IN
|
|
3388
|
+
* THE CALLING CLI PROCESS and forwarded over IPC, never resolved here. That
|
|
3389
|
+
* distinction is the whole fix: resolving it daemon-side would attribute every
|
|
3390
|
+
* task to the daemon's own actor (the RUSH-2020 bug).
|
|
3391
|
+
*
|
|
3392
|
+
* `agents browser stop` deliberately does NOT delete this row: the whole point
|
|
3393
|
+
* is that the link outlives the task.
|
|
3394
|
+
*
|
|
3395
|
+
* Identity fields are only ever widened, never blanked. A later capture-count
|
|
3396
|
+
* update carries no session id, and `COALESCE(excluded.…, browser_sessions.…)`
|
|
3397
|
+
* keeps the one recorded at start rather than overwriting it with NULL --
|
|
3398
|
+
* otherwise the second write would undo exactly what the first was for.
|
|
3399
|
+
*/
|
|
3400
|
+
export function recordBrowserSession(record) {
|
|
3401
|
+
const db = getDB();
|
|
3402
|
+
const now = Date.now();
|
|
3403
|
+
db.prepare(`
|
|
3404
|
+
INSERT INTO browser_sessions (
|
|
3405
|
+
task, profile, session_id, launch_id, actor, machine,
|
|
3406
|
+
started_at, last_activity,
|
|
3407
|
+
screenshot_count, pdf_count, recording_count, download_count,
|
|
3408
|
+
capture_dir, captures_remote
|
|
3409
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
3410
|
+
ON CONFLICT(profile, task) DO UPDATE SET
|
|
3411
|
+
session_id = COALESCE(excluded.session_id, browser_sessions.session_id),
|
|
3412
|
+
launch_id = COALESCE(excluded.launch_id, browser_sessions.launch_id),
|
|
3413
|
+
actor = COALESCE(excluded.actor, browser_sessions.actor),
|
|
3414
|
+
last_activity = excluded.last_activity,
|
|
3415
|
+
screenshot_count = excluded.screenshot_count,
|
|
3416
|
+
pdf_count = excluded.pdf_count,
|
|
3417
|
+
recording_count = excluded.recording_count,
|
|
3418
|
+
download_count = excluded.download_count,
|
|
3419
|
+
capture_dir = COALESCE(excluded.capture_dir, browser_sessions.capture_dir),
|
|
3420
|
+
captures_remote = COALESCE(excluded.captures_remote, browser_sessions.captures_remote)
|
|
3421
|
+
`).run(record.task, record.profile, record.sessionId ?? null, record.launchId ?? null, record.actor ?? null, record.machine ?? machineId(), record.startedAt ?? now, record.lastActivity ?? now, record.counts?.screenshot ?? 0, record.counts?.pdf ?? 0, record.counts?.recording ?? 0, record.counts?.download ?? 0, record.captureDir ?? null, record.capturesRemote ?? null);
|
|
3422
|
+
}
|
|
3423
|
+
/**
|
|
3424
|
+
* Upsert one computer-use invocation's durable metadata.
|
|
3425
|
+
*
|
|
3426
|
+
* `action_count` accumulates: a `computer run` loop emits many actions under one
|
|
3427
|
+
* invocation id, and each arrives as its own call, so the count is incremented
|
|
3428
|
+
* rather than replaced. Identity is widened-only, for the same reason as above.
|
|
3429
|
+
*/
|
|
3430
|
+
export function recordComputerSession(record) {
|
|
3431
|
+
const db = getDB();
|
|
3432
|
+
const now = Date.now();
|
|
3433
|
+
db.prepare(`
|
|
3434
|
+
INSERT INTO computer_sessions (
|
|
3435
|
+
invocation_id, session_id, launch_id, actor, machine,
|
|
3436
|
+
started_at, last_activity, action_count, task_preview
|
|
3437
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
3438
|
+
ON CONFLICT(invocation_id) DO UPDATE SET
|
|
3439
|
+
session_id = COALESCE(excluded.session_id, computer_sessions.session_id),
|
|
3440
|
+
launch_id = COALESCE(excluded.launch_id, computer_sessions.launch_id),
|
|
3441
|
+
actor = COALESCE(excluded.actor, computer_sessions.actor),
|
|
3442
|
+
last_activity = excluded.last_activity,
|
|
3443
|
+
action_count = computer_sessions.action_count + excluded.action_count,
|
|
3444
|
+
task_preview = COALESCE(excluded.task_preview, computer_sessions.task_preview)
|
|
3445
|
+
`).run(record.invocationId, record.sessionId ?? null, record.launchId ?? null, record.actor ?? null, record.machine ?? machineId(), record.startedAt ?? now, record.lastActivity ?? now, record.actionCount ?? 1, record.taskPreview ?? null);
|
|
3446
|
+
}
|
|
3447
|
+
function toStoredBrowserSession(row) {
|
|
3448
|
+
return {
|
|
3449
|
+
task: row.task,
|
|
3450
|
+
profile: row.profile,
|
|
3451
|
+
sessionId: row.session_id ?? undefined,
|
|
3452
|
+
launchId: row.launch_id ?? undefined,
|
|
3453
|
+
actor: row.actor ?? undefined,
|
|
3454
|
+
machine: row.machine,
|
|
3455
|
+
startedAt: row.started_at,
|
|
3456
|
+
lastActivity: row.last_activity ?? undefined,
|
|
3457
|
+
counts: {
|
|
3458
|
+
screenshot: row.screenshot_count,
|
|
3459
|
+
pdf: row.pdf_count,
|
|
3460
|
+
recording: row.recording_count,
|
|
3461
|
+
download: row.download_count,
|
|
3462
|
+
},
|
|
3463
|
+
captureDir: row.capture_dir ?? undefined,
|
|
3464
|
+
capturesRemote: row.captures_remote ?? undefined,
|
|
3465
|
+
};
|
|
3466
|
+
}
|
|
3467
|
+
/**
|
|
3468
|
+
* Stored browser tasks, newest first; optionally scoped to one profile.
|
|
3469
|
+
*
|
|
3470
|
+
* A PROFILE-SCOPED read is deliberately unbounded. These rows are the identity
|
|
3471
|
+
* for capture dirs that still exist on disk, and dropping the oldest ones would
|
|
3472
|
+
* silently regress exactly those tasks to `unlinked` — the symptom this whole
|
|
3473
|
+
* change removes, reappearing at a higher threshold. The row count is already
|
|
3474
|
+
* bounded by the tasks that profile has ever run, and each row is a short
|
|
3475
|
+
* metadata record. Only the unscoped read (every profile, used for overviews)
|
|
3476
|
+
* takes a ceiling, since that one has no natural bound.
|
|
3477
|
+
*/
|
|
3478
|
+
export function listBrowserSessionRecords(profile, opts = {}) {
|
|
3479
|
+
const db = getDB();
|
|
3480
|
+
const rows = (profile
|
|
3481
|
+
? db.prepare(`SELECT * FROM browser_sessions WHERE profile = ? ORDER BY started_at DESC`).all(profile)
|
|
3482
|
+
: db.prepare(`SELECT * FROM browser_sessions ORDER BY started_at DESC LIMIT ?`)
|
|
3483
|
+
.all(opts.limit ?? TOOL_SESSION_LIST_LIMIT));
|
|
3484
|
+
return rows.map(toStoredBrowserSession);
|
|
3485
|
+
}
|
|
3486
|
+
/** One stored browser task by its (profile, task) key, or null. */
|
|
3487
|
+
export function getBrowserSessionRecord(profile, task) {
|
|
3488
|
+
const db = getDB();
|
|
3489
|
+
const row = db
|
|
3490
|
+
.prepare(`SELECT * FROM browser_sessions WHERE profile = ? AND task = ?`)
|
|
3491
|
+
.get(profile, task);
|
|
3492
|
+
return row ? toStoredBrowserSession(row) : null;
|
|
3493
|
+
}
|
|
3494
|
+
/**
|
|
3495
|
+
* Retention for the tool-session tables.
|
|
3496
|
+
*
|
|
3497
|
+
* These are the durable answer to a ledger that prunes at 7 days, so they are
|
|
3498
|
+
* deliberately long-lived — but "durable" is not "unbounded". `computer_sessions`
|
|
3499
|
+
* takes one row per `agents computer` CLI PROCESS (`COMPUTER_INVOCATION_ID` is
|
|
3500
|
+
* minted per process), and an agent driving a desktop invokes that hundreds of
|
|
3501
|
+
* times a day, so an unbounded table would grow without limit and be read in
|
|
3502
|
+
* full on every listing.
|
|
3503
|
+
*/
|
|
3504
|
+
export const TOOL_SESSION_MAX_AGE_DAYS = 365;
|
|
3505
|
+
/** Default ceiling on rows one listing will read. */
|
|
3506
|
+
export const TOOL_SESSION_LIST_LIMIT = 2000;
|
|
3507
|
+
/**
|
|
3508
|
+
* Drop tool-session rows past {@link TOOL_SESSION_MAX_AGE_DAYS}.
|
|
3509
|
+
*
|
|
3510
|
+
* Called from the listing path, never from the write hot path: an
|
|
3511
|
+
* `agents computer` action must not pay for a table sweep (see the fail-soft
|
|
3512
|
+
* note on `recordComputerSession`'s caller). Returns rows deleted.
|
|
3513
|
+
*/
|
|
3514
|
+
export function pruneToolSessions(maxAgeDays = TOOL_SESSION_MAX_AGE_DAYS) {
|
|
3515
|
+
const db = getDB();
|
|
3516
|
+
const cutoff = Date.now() - maxAgeDays * 24 * 60 * 60 * 1000;
|
|
3517
|
+
// Cheap indexed guard first, so the common case is one lookup rather than a
|
|
3518
|
+
// write transaction (the same shape as the account repair below). Every
|
|
3519
|
+
// listing calls this, and on any table younger than the retention window
|
|
3520
|
+
// there is nothing to delete — but a bare DELETE still opens a write
|
|
3521
|
+
// transaction, which under `busy_timeout = 30000` can make a read-only
|
|
3522
|
+
// listing wait on the session indexer for no reason at all.
|
|
3523
|
+
const stale = db.prepare(`
|
|
3524
|
+
SELECT 1 FROM computer_sessions WHERE started_at < ?
|
|
3525
|
+
UNION ALL
|
|
3526
|
+
SELECT 1 FROM browser_sessions WHERE started_at < ?
|
|
3527
|
+
LIMIT 1
|
|
3528
|
+
`).get(cutoff, cutoff);
|
|
3529
|
+
if (!stale)
|
|
3530
|
+
return 0;
|
|
3531
|
+
const computer = db.prepare(`DELETE FROM computer_sessions WHERE started_at < ?`).run(cutoff);
|
|
3532
|
+
const browser = db.prepare(`DELETE FROM browser_sessions WHERE started_at < ?`).run(cutoff);
|
|
3533
|
+
return Number(computer.changes ?? 0) + Number(browser.changes ?? 0);
|
|
3534
|
+
}
|
|
3535
|
+
/**
|
|
3536
|
+
* Stored computer-use invocations, newest first, bounded.
|
|
3537
|
+
*
|
|
3538
|
+
* The limit is a real ceiling, not a nicety: `--json` serializes whatever this
|
|
3539
|
+
* returns, so an unbounded read would dump the entire table on every call.
|
|
3540
|
+
*/
|
|
3541
|
+
export function listComputerSessionRecords(opts = {}) {
|
|
3542
|
+
const db = getDB();
|
|
3543
|
+
const limit = opts.limit ?? TOOL_SESSION_LIST_LIMIT;
|
|
3544
|
+
// `startedBeforeMs` selects the COMPLEMENT of the caller's other source
|
|
3545
|
+
// rather than the newest N. The caller that recovers pruned runs already
|
|
3546
|
+
// holds every recent invocation from the event ledger and discards any row
|
|
3547
|
+
// it has seen — so a bare newest-N read hands it 2000 rows it is guaranteed
|
|
3548
|
+
// to throw away, and returns nothing at all once the table passes that size.
|
|
3549
|
+
// Bounding by "older than the ledger reaches" truncates the TAIL of
|
|
3550
|
+
// recoverable history instead of deleting all of it.
|
|
3551
|
+
const rows = (opts.startedBeforeMs === undefined
|
|
3552
|
+
? db
|
|
3553
|
+
.prepare(`SELECT * FROM computer_sessions ORDER BY started_at DESC LIMIT ?`)
|
|
3554
|
+
.all(limit)
|
|
3555
|
+
: db
|
|
3556
|
+
.prepare(`SELECT * FROM computer_sessions WHERE started_at < ? ORDER BY started_at DESC LIMIT ?`)
|
|
3557
|
+
.all(opts.startedBeforeMs, limit));
|
|
3558
|
+
return rows.map((row) => ({
|
|
3559
|
+
invocationId: row.invocation_id,
|
|
3560
|
+
sessionId: row.session_id ?? undefined,
|
|
3561
|
+
launchId: row.launch_id ?? undefined,
|
|
3562
|
+
actor: row.actor ?? undefined,
|
|
3563
|
+
machine: row.machine,
|
|
3564
|
+
startedAt: row.started_at,
|
|
3565
|
+
lastActivity: row.last_activity ?? undefined,
|
|
3566
|
+
actionCount: row.action_count,
|
|
3567
|
+
taskPreview: row.task_preview ?? undefined,
|
|
3568
|
+
}));
|
|
3569
|
+
}
|
|
@@ -36,7 +36,7 @@ export { machineForSessionFile } from './origin-machine.js';
|
|
|
36
36
|
import { mapBounded } from '../concurrency.js';
|
|
37
37
|
import { getDB, getScanStampByPath, getScanStampsForPaths, getParserStatesForPaths, getDirLedgerForPaths, recordDirScans, recordScans, syncLabels, seedLabelsFromNames, syncTopics, upsertSessionsBatch, querySessions, countSessions, ftsSearch, tryClaimScan, releaseScan, cacheLinearProject, } from './db.js';
|
|
38
38
|
import { buildRunNameMap } from './run-names.js';
|
|
39
|
-
import { resolveLinearApiKey } from '../
|
|
39
|
+
import { resolveLinearApiKey } from '../linear-cache.js';
|
|
40
40
|
import { ToolCallCollector, collectClaudeToolCalls, collectCodexToolCalls, } from './tool-calls.js';
|
|
41
41
|
import { purgeMissingToolCallsInDirectory } from './tool-store.js';
|
|
42
42
|
const HOME = os.homedir();
|
|
@@ -187,8 +187,19 @@ export async function queryIndexedSessions(options, indexedOptions = {}) {
|
|
|
187
187
|
const sessions = querySessions(buildQueryOptions({ ...options, skipExistenceCheck: indexedOptions.skipExistenceCheck ?? true }, agents, { includeLimit: true }));
|
|
188
188
|
if (indexedOptions.resolveLinear !== false)
|
|
189
189
|
await resolveLinearProjects(sessions);
|
|
190
|
-
for (const s of sessions)
|
|
191
|
-
|
|
190
|
+
for (const s of sessions) {
|
|
191
|
+
// A non-empty transcript path is authoritative for origin (a live-home file
|
|
192
|
+
// is this box; `backups/<agent>/<machine>/…` names that peer), so derive
|
|
193
|
+
// there. An EMPTY file_path carries no such signal — `machineForSessionFile`
|
|
194
|
+
// falls back to THIS box — so keep the machine the row was recorded with
|
|
195
|
+
// instead: a host dispatch stamps the EXECUTION host on its empty-file index
|
|
196
|
+
// row (`registerHostSession`), and re-deriving re-attributed the dispatcher's
|
|
197
|
+
// own pool row to itself, splitting it from the executing peer's fan-out row
|
|
198
|
+
// and making resume-by-id read as "ambiguous (2 sessions)" (RUSH-2486 /
|
|
199
|
+
// RUSH-2479 criterion 2). A recorded-less empty-file row still falls back.
|
|
200
|
+
if (s.filePath || !s.machine?.trim())
|
|
201
|
+
s.machine = machineForSessionFile(s.filePath, s.agent);
|
|
202
|
+
}
|
|
192
203
|
return scopeToManaged(sessions, agents, options);
|
|
193
204
|
}
|
|
194
205
|
const linearProjectCache = new Map();
|
|
@@ -760,7 +771,7 @@ export function getAgentSessionDirs(agent, subdir) {
|
|
|
760
771
|
* The (agent, subdir) pairs `discoverSessions` walks for JSONL transcripts —
|
|
761
772
|
* the single source of truth for which directories hold live session files.
|
|
762
773
|
* `getSessionRoots` expands each pair to its concrete directories so a consumer
|
|
763
|
-
* (
|
|
774
|
+
* (AGI EXT's fs.watch, see issue #741) can configure its watcher
|
|
764
775
|
* from the CLI instead of hardcoding `~/.claude|.codex|.gemini`. Adding a new
|
|
765
776
|
* on-disk agent here makes every consumer watch it automatically.
|
|
766
777
|
*/
|
|
@@ -3568,6 +3579,18 @@ export function applyCodexLine(state, parsed) {
|
|
|
3568
3579
|
state.model = payload.model || state.model;
|
|
3569
3580
|
return;
|
|
3570
3581
|
}
|
|
3582
|
+
// Codex rollouts put per-turn metadata (including the model) on
|
|
3583
|
+
// `turn_context` events. Use them as a fallback when session_meta itself
|
|
3584
|
+
// does not carry the field, otherwise `agents sessions` shows blank model
|
|
3585
|
+
// info for Codex.
|
|
3586
|
+
if (parsed.type === 'turn_context') {
|
|
3587
|
+
const payload = parsed.payload || {};
|
|
3588
|
+
if (!state.model && typeof payload.model === 'string')
|
|
3589
|
+
state.model = payload.model;
|
|
3590
|
+
if (!state.cwd && typeof payload.cwd === 'string')
|
|
3591
|
+
state.cwd = payload.cwd;
|
|
3592
|
+
return;
|
|
3593
|
+
}
|
|
3571
3594
|
if (parsed.type === 'response_item' && parsed.payload?.type === 'message') {
|
|
3572
3595
|
const role = parsed.payload.role === 'user' || parsed.payload.role === 'developer'
|
|
3573
3596
|
? 'user'
|
|
@@ -17,8 +17,8 @@
|
|
|
17
17
|
* This module lets `sessions --active` reconcile a `ps`-discovered pid to that
|
|
18
18
|
* authoritative id. It is deliberately a small hand-rolled reader — the CLI does
|
|
19
19
|
* NOT import the session-tracker package (a separate, workspace-less package;
|
|
20
|
-
* see packages/session-tracker/CLAUDE.md) — mirroring
|
|
21
|
-
* hand-copied reader in apps/
|
|
20
|
+
* see packages/session-tracker/CLAUDE.md) — mirroring AGI EXT's own
|
|
21
|
+
* hand-copied reader in apps/ext/src/core/liveSession.ts. It only READS the
|
|
22
22
|
* existing dir/schema; it never writes or moves anything, so it is safe across a
|
|
23
23
|
* fleet where old hooks and a new CLI coexist.
|
|
24
24
|
*
|
|
@@ -33,8 +33,8 @@ export type HostLink =
|
|
|
33
33
|
| 'host-gone';
|
|
34
34
|
/**
|
|
35
35
|
* How long an IDE window's registry slice may go without a refresh before we
|
|
36
|
-
* treat that window as gone.
|
|
37
|
-
* every 4 minutes (`KEEPALIVE_FORCE_MS` in `apps/
|
|
36
|
+
* treat that window as gone. AGI EXT force-republishes its slice
|
|
37
|
+
* every 4 minutes (`KEEPALIVE_FORCE_MS` in `apps/ext/src/vscode/foreman.registry.ts`)
|
|
38
38
|
* and on every terminal open/close, so a slice this old means the window is no
|
|
39
39
|
* longer running — it is not merely quiet. Deliberately the same 10 minutes the
|
|
40
40
|
* extension itself uses to garbage-collect a peer window's slice, so the CLI and
|