@phnx-labs/agents-cli 1.22.46 → 1.22.49
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 +663 -0
- package/LICENSE +102 -182
- package/README.md +96 -49
- package/dist/bootstrap.js +4 -2
- package/dist/cli/command-registry.d.ts +2 -1
- package/dist/cli/command-registry.js +6 -2
- package/dist/commands/accounts.d.ts +58 -0
- package/dist/commands/accounts.js +243 -25
- package/dist/commands/artifacts.js +7 -6
- package/dist/commands/attach.js +1 -1
- package/dist/commands/auth.js +7 -5
- package/dist/commands/browser-sessions-picker.js +9 -7
- package/dist/commands/browser.js +711 -62
- package/dist/commands/config.d.ts +0 -1
- package/dist/commands/config.js +26 -24
- package/dist/commands/cost.d.ts +1 -1
- package/dist/commands/daemon.d.ts +21 -0
- package/dist/commands/daemon.js +147 -12
- package/dist/commands/detach.d.ts +13 -0
- package/dist/commands/detach.js +11 -8
- package/dist/commands/exec.js +107 -53
- package/dist/commands/feed-watch.d.ts +2 -0
- package/dist/commands/feed-watch.js +28 -0
- package/dist/commands/feed.js +27 -0
- package/dist/commands/feedback.js +3 -19
- package/dist/commands/focus.d.ts +14 -0
- package/dist/commands/focus.js +48 -5
- package/dist/commands/go.d.ts +3 -0
- package/dist/commands/go.js +16 -3
- package/dist/commands/insights.d.ts +1 -1
- package/dist/commands/insights.js +2 -2
- package/dist/commands/inspect.js +2 -2
- package/dist/commands/lease.d.ts +1 -1
- package/dist/commands/lease.js +7 -6
- package/dist/commands/mailboxes.js +4 -3
- package/dist/commands/menubar.js +11 -4
- package/dist/commands/projects.d.ts +16 -1
- package/dist/commands/projects.js +58 -64
- package/dist/commands/resume.js +1 -1
- package/dist/commands/route.js +4 -4
- package/dist/commands/routines.js +4 -3
- package/dist/commands/run-broadcast.d.ts +1 -1
- package/dist/commands/run-broadcast.js +1 -1
- package/dist/commands/sessions-picker-factory.d.ts +2 -1
- package/dist/commands/sessions-picker-factory.js +1 -1
- package/dist/commands/sessions-picker.d.ts +22 -0
- package/dist/commands/sessions-picker.js +48 -9
- package/dist/commands/sessions-stop.d.ts +24 -0
- package/dist/commands/sessions-stop.js +66 -0
- package/dist/commands/sessions-trace.d.ts +82 -0
- package/dist/commands/sessions-trace.js +387 -0
- package/dist/commands/sessions.js +5 -0
- package/dist/commands/setup-secrets.js +23 -0
- package/dist/commands/share.d.ts +20 -5
- package/dist/commands/share.js +152 -52
- package/dist/commands/ssh.d.ts +15 -0
- package/dist/commands/ssh.js +243 -18
- package/dist/commands/teams.js +34 -2
- package/dist/commands/traces.d.ts +2 -0
- package/dist/commands/traces.js +184 -0
- package/dist/commands/view.d.ts +2 -0
- package/dist/commands/view.js +32 -62
- package/dist/commands/watchdog.js +9 -14
- package/dist/index.d.ts +1 -0
- package/dist/index.js +5 -0
- package/dist/lib/account-capabilities.d.ts +4 -0
- package/dist/lib/account-capabilities.js +13 -9
- package/dist/lib/account-registry.d.ts +2 -0
- package/dist/lib/account-registry.js +30 -2
- package/dist/lib/accounting/rotate.d.ts +9 -0
- package/dist/lib/accounting/rotate.js +12 -2
- package/dist/lib/accounting/usage.d.ts +84 -6
- package/dist/lib/accounting/usage.js +293 -75
- package/dist/lib/agent-modes.js +29 -1
- package/dist/lib/agent-spec/agents.d.ts +4 -3
- package/dist/lib/agent-spec/agents.js +25 -15
- package/dist/lib/analytics/mix-commands.d.ts +1 -1
- package/dist/lib/analytics/mix-commands.js +2 -2
- package/dist/lib/auth-health.d.ts +13 -3
- package/dist/lib/auth-health.js +50 -8
- package/dist/lib/browser/devices.d.ts +19 -0
- package/dist/lib/browser/devices.js +23 -0
- package/dist/lib/browser/drivers/ssh.d.ts +16 -2
- package/dist/lib/browser/drivers/ssh.js +36 -9
- package/dist/lib/browser/ipc.d.ts +1 -1
- package/dist/lib/browser/ipc.js +40 -9
- package/dist/lib/browser/profiles.d.ts +104 -65
- package/dist/lib/browser/profiles.js +277 -165
- package/dist/lib/browser/registry.d.ts +39 -0
- package/dist/lib/browser/registry.js +149 -0
- package/dist/lib/browser/remote-control.d.ts +28 -2
- package/dist/lib/browser/remote-control.js +35 -3
- package/dist/lib/browser/resolve-target.d.ts +68 -0
- package/dist/lib/browser/resolve-target.js +250 -0
- package/dist/lib/browser/runtime-state.d.ts +44 -11
- package/dist/lib/browser/runtime-state.js +98 -15
- package/dist/lib/browser/service.d.ts +65 -9
- package/dist/lib/browser/service.js +196 -61
- package/dist/lib/browser/sessions-list.d.ts +1 -3
- package/dist/lib/browser/sessions-list.js +3 -16
- package/dist/lib/browser/task-index.d.ts +70 -0
- package/dist/lib/browser/task-index.js +180 -0
- package/dist/lib/browser/types.d.ts +12 -1
- package/dist/lib/byok-usage.js +2 -2
- package/dist/lib/claude-statusline.d.ts +29 -0
- package/dist/lib/claude-statusline.js +139 -0
- package/dist/lib/cloud/host.d.ts +1 -1
- package/dist/lib/cloud/host.js +1 -1
- package/dist/lib/cloud/rush.js +1 -1
- package/dist/lib/codex-policy.d.ts +11 -1
- package/dist/lib/codex-policy.js +20 -5
- package/dist/lib/computer/computer-rpc.js +2 -2
- package/dist/lib/computer/download.d.ts +15 -15
- package/dist/lib/computer/download.js +35 -98
- package/dist/lib/computer/ssh-tunnel.d.ts +0 -3
- package/dist/lib/computer/ssh-tunnel.js +12 -22
- package/dist/lib/config-keys.d.ts +6 -11
- package/dist/lib/config-keys.js +18 -19
- package/dist/lib/crabbox/cli.d.ts +1 -1
- package/dist/lib/crabbox/cli.js +2 -2
- package/dist/lib/crabbox/lease.d.ts +9 -0
- package/dist/lib/crabbox/lease.js +70 -15
- package/dist/lib/crabbox/runtimes.js +1 -1
- package/dist/lib/daemon/account-state-daemon-service.d.ts +16 -0
- package/dist/lib/daemon/account-state-daemon-service.js +26 -0
- package/dist/lib/daemon/browser-ipc-service.d.ts +20 -0
- package/dist/lib/daemon/browser-ipc-service.js +46 -0
- package/dist/lib/daemon/daemon.d.ts +3 -0
- package/dist/lib/daemon/daemon.js +212 -444
- package/dist/lib/daemon/device-probe-service.d.ts +26 -0
- package/dist/lib/daemon/device-probe-service.js +47 -0
- package/dist/lib/daemon/keychain-reap-service.d.ts +17 -0
- package/dist/lib/daemon/keychain-reap-service.js +32 -0
- package/dist/lib/daemon/monitor-engine-service.d.ts +22 -0
- package/dist/lib/daemon/monitor-engine-service.js +29 -0
- package/dist/lib/daemon/runner.js +15 -2
- package/dist/lib/daemon/secrets-broker-service.d.ts +20 -0
- package/dist/lib/daemon/secrets-broker-service.js +66 -0
- package/dist/lib/daemon/self-heal-service.d.ts +27 -0
- package/dist/lib/daemon/self-heal-service.js +48 -0
- package/dist/lib/daemon/service.d.ts +102 -0
- package/dist/lib/daemon/service.js +98 -0
- package/dist/lib/daemon/session-index-service.d.ts +22 -0
- package/dist/lib/daemon/session-index-service.js +40 -0
- package/dist/lib/daemon/state-dir-check-service.d.ts +43 -0
- package/dist/lib/daemon/state-dir-check-service.js +63 -0
- package/dist/lib/daemon/supervisor.d.ts +87 -0
- package/dist/lib/daemon/supervisor.js +298 -0
- package/dist/lib/daemon/watchdog-service.d.ts +19 -0
- package/dist/lib/daemon/watchdog-service.js +40 -0
- package/dist/lib/daemon-health.d.ts +15 -0
- package/dist/lib/daemon-health.js +29 -5
- package/dist/lib/daemon-services.d.ts +8 -1
- package/dist/lib/daemon-services.js +55 -0
- package/dist/lib/daemon-ticks.d.ts +13 -2
- package/dist/lib/daemon-ticks.js +22 -20
- package/dist/lib/device-config.d.ts +25 -10
- package/dist/lib/device-config.js +90 -39
- package/dist/lib/devices/config-migration.d.ts +7 -0
- package/dist/lib/devices/config-migration.js +67 -3
- package/dist/lib/devices/health.d.ts +27 -2
- package/dist/lib/devices/health.js +39 -9
- package/dist/lib/devices/interactive-host.d.ts +15 -0
- package/dist/lib/devices/interactive-host.js +53 -0
- package/dist/lib/devices/registry.d.ts +61 -4
- package/dist/lib/devices/registry.js +94 -38
- package/dist/lib/devices/stats-cache.d.ts +26 -0
- package/dist/lib/devices/stats-cache.js +59 -7
- package/dist/lib/devices/worker-pick.d.ts +48 -0
- package/dist/lib/devices/worker-pick.js +113 -0
- package/dist/lib/exec.d.ts +70 -14
- package/dist/lib/exec.js +110 -38
- package/dist/lib/feed/answer.d.ts +29 -0
- package/dist/lib/feed/answer.js +145 -0
- package/dist/lib/feed/attention.d.ts +83 -0
- package/dist/lib/feed/attention.js +0 -0
- package/dist/lib/feed/feed.d.ts +109 -0
- package/dist/lib/feed/feed.js +154 -3
- package/dist/lib/feed/pr-status.d.ts +14 -0
- package/dist/lib/feed/pr-status.js +47 -0
- package/dist/lib/feed/watch.d.ts +59 -0
- package/dist/lib/feed/watch.js +180 -0
- package/dist/lib/fleet/capture.js +6 -0
- package/dist/lib/fleet/remote-login.js +8 -3
- package/dist/lib/fleet/types.d.ts +17 -0
- package/dist/lib/harness/adapter.d.ts +11 -0
- package/dist/lib/harness/adapters/claude.js +38 -24
- package/dist/lib/harness/adapters/codex.js +2 -4
- package/dist/lib/harness/adapters/cursor.js +8 -11
- package/dist/lib/helper-download.d.ts +108 -0
- package/dist/lib/helper-download.js +194 -0
- package/dist/lib/helper-versions.d.ts +52 -0
- package/dist/lib/helper-versions.js +58 -0
- package/dist/lib/hooks/cache.js +19 -0
- package/dist/lib/hooks/install.js +2 -2
- package/dist/lib/hooks/match.d.ts +3 -0
- package/dist/lib/hooks/match.js +25 -0
- package/dist/lib/hosts/credentials.d.ts +1 -1
- package/dist/lib/hosts/credentials.js +1 -1
- package/dist/lib/hosts/dispatch.d.ts +7 -1
- package/dist/lib/hosts/dispatch.js +24 -5
- package/dist/lib/hosts/passthrough.d.ts +8 -15
- package/dist/lib/hosts/passthrough.js +35 -16
- package/dist/lib/hosts/providers/devices.d.ts +1 -1
- package/dist/lib/hosts/providers/devices.js +1 -1
- package/dist/lib/hosts/reconnect.d.ts +179 -21
- package/dist/lib/hosts/reconnect.js +266 -45
- package/dist/lib/hosts/registry.js +7 -0
- package/dist/lib/installations/migrate.d.ts +4 -5
- package/dist/lib/installations/migrate.js +6 -7
- package/dist/lib/installations/shims.d.ts +1 -1
- package/dist/lib/installations/shims.js +23 -13
- package/dist/lib/installations/versions.js +25 -2
- package/dist/lib/linear-autoclose.d.ts +1 -1
- package/dist/lib/linear-autoclose.js +1 -1
- package/dist/lib/loop.d.ts +2 -2
- package/dist/lib/loop.js +1 -1
- package/dist/lib/menubar/download-menubar.d.ts +47 -0
- package/dist/lib/menubar/download-menubar.js +60 -0
- package/dist/lib/menubar/install-menubar.d.ts +44 -7
- package/dist/lib/menubar/install-menubar.js +105 -23
- package/dist/lib/menubar/notify-desktop.d.ts +3 -3
- package/dist/lib/menubar/notify-desktop.js +6 -6
- package/dist/lib/model-tiers.d.ts +1 -1
- package/dist/lib/open-url.d.ts +60 -2
- package/dist/lib/open-url.js +167 -12
- package/dist/lib/project-probe.d.ts +1 -1
- package/dist/lib/project-probe.js +1 -1
- package/dist/lib/project-pull.d.ts +1 -1
- package/dist/lib/project-pull.js +2 -2
- package/dist/lib/projects.d.ts +1 -1
- package/dist/lib/projects.js +1 -1
- package/dist/lib/refresh-coordinator.d.ts +1 -1
- package/dist/lib/refresh-coordinator.js +1 -1
- package/dist/lib/sandbox.js +6 -7
- package/dist/lib/secrets/download-keychain.d.ts +47 -0
- package/dist/lib/secrets/download-keychain.js +70 -0
- package/dist/lib/secrets/install-helper.d.ts +20 -1
- package/dist/lib/secrets/install-helper.js +44 -3
- package/dist/lib/session/active.d.ts +67 -0
- package/dist/lib/session/active.js +86 -2
- package/dist/lib/session/db.d.ts +11 -1
- package/dist/lib/session/db.js +142 -8
- package/dist/lib/session/discover.d.ts +23 -1
- package/dist/lib/session/discover.js +44 -10
- package/dist/lib/session/highlights.d.ts +49 -1
- package/dist/lib/session/highlights.js +95 -0
- package/dist/lib/session/host-link.d.ts +16 -2
- package/dist/lib/session/host-link.js +7 -1
- package/dist/lib/session/parse.js +33 -1
- package/dist/lib/session/prompt.d.ts +35 -0
- package/dist/lib/session/prompt.js +56 -0
- package/dist/lib/session/remote/remote-list.d.ts +9 -0
- package/dist/lib/session/remote/remote-list.js +19 -2
- package/dist/lib/session/remote/watch.d.ts +1 -1
- package/dist/lib/session/remote/watch.js +17 -3
- package/dist/lib/session/render.js +7 -3
- package/dist/lib/session/session-cache.d.ts +53 -0
- package/dist/lib/session/session-cache.js +93 -1
- package/dist/lib/session/state.js +1 -1
- package/dist/lib/session/tool-calls.d.ts +2 -0
- package/dist/lib/session/tool-calls.js +1 -1
- package/dist/lib/session/trajectory-compare.d.ts +47 -0
- package/dist/lib/session/trajectory-compare.js +116 -0
- package/dist/lib/session/trajectory-html.d.ts +19 -0
- package/dist/lib/session/trajectory-html.js +770 -0
- package/dist/lib/session/trajectory-lineage.d.ts +92 -0
- package/dist/lib/session/trajectory-lineage.js +195 -0
- package/dist/lib/session/trajectory-text.d.ts +37 -0
- package/dist/lib/session/trajectory-text.js +284 -0
- package/dist/lib/session/trajectory.d.ts +102 -0
- package/dist/lib/session/trajectory.js +384 -0
- package/dist/lib/session/types.d.ts +15 -0
- package/dist/lib/sha256-asset.d.ts +26 -0
- package/dist/lib/sha256-asset.js +41 -0
- package/dist/lib/share/backend.d.ts +95 -0
- package/dist/lib/share/backend.js +139 -0
- package/dist/lib/share/delete.d.ts +6 -2
- package/dist/lib/share/delete.js +8 -9
- package/dist/lib/share/html.d.ts +22 -0
- package/dist/lib/share/html.js +88 -0
- package/dist/lib/share/provision.d.ts +18 -4
- package/dist/lib/share/provision.js +38 -4
- package/dist/lib/share/publish.d.ts +39 -15
- package/dist/lib/share/publish.js +55 -26
- package/dist/lib/share/worker-template.js +171 -11
- package/dist/lib/sqlite.js +16 -3
- package/dist/lib/ssh-exec.d.ts +65 -0
- package/dist/lib/ssh-exec.js +120 -4
- package/dist/lib/startup/command-registry.d.ts +3 -1
- package/dist/lib/startup/command-registry.js +6 -3
- package/dist/lib/startup/dev-build.js +3 -3
- package/dist/lib/state.d.ts +2 -2
- package/dist/lib/state.js +11 -5
- package/dist/lib/subagents-registry.js +1 -1
- package/dist/lib/teams/agents.js +9 -0
- package/dist/lib/terminal/index.d.ts +1 -1
- package/dist/lib/terminal/inject.d.ts +19 -0
- package/dist/lib/terminal/inject.js +19 -9
- package/dist/lib/terminal/types.d.ts +1 -1
- package/dist/lib/terminal/types.js +1 -1
- package/dist/lib/tmux/orphan-reap.js +1 -1
- package/dist/lib/tmux/session.d.ts +46 -13
- package/dist/lib/tmux/session.js +204 -27
- package/dist/lib/traces/backend.d.ts +29 -0
- package/dist/lib/traces/backend.js +46 -0
- package/dist/lib/traces/classify.d.ts +52 -0
- package/dist/lib/traces/classify.js +72 -0
- package/dist/lib/traces/config.d.ts +10 -0
- package/dist/lib/traces/config.js +2 -0
- package/dist/lib/traces/provision.d.ts +19 -0
- package/dist/lib/traces/provision.js +30 -0
- package/dist/lib/traces/sync.d.ts +150 -0
- package/dist/lib/traces/sync.js +447 -0
- package/dist/lib/traces/worker-template.d.ts +4 -0
- package/dist/lib/traces/worker-template.js +159 -0
- package/dist/lib/types.d.ts +34 -19
- package/dist/lib/types.js +14 -0
- package/dist/lib/usage-backoff.d.ts +2 -1
- package/dist/lib/usage-backoff.js +60 -19
- package/dist/lib/usage-refresh.d.ts +18 -4
- package/dist/lib/usage-refresh.js +68 -19
- package/dist/lib/watchdog/log.d.ts +1 -1
- package/dist/lib/watchdog/log.js +1 -1
- package/dist/lib/watchdog/runner.d.ts +36 -45
- package/dist/lib/watchdog/runner.js +150 -119
- package/dist/lib/watchdog/service.d.ts +0 -1
- package/dist/lib/watchdog/service.js +0 -1
- package/dist/lib/watchdog/watchdog-agent.d.ts +38 -0
- package/dist/lib/watchdog/watchdog-agent.js +59 -0
- package/dist/lib/watchdog/watchdog.d.ts +11 -2
- package/dist/lib/watchdog/watchdog.js +37 -104
- package/dist/lib/workflows.d.ts +1 -1
- package/package.json +5 -7
- package/dist/commands/usage.d.ts +0 -27
- package/dist/commands/usage.js +0 -96
- package/dist/lib/menubar/MenubarHelper.app/Contents/CodeResources +0 -0
- package/dist/lib/menubar/MenubarHelper.app/Contents/Info.plist +0 -24
- package/dist/lib/menubar/MenubarHelper.app/Contents/MacOS/MenubarHelper +0 -0
- package/dist/lib/menubar/MenubarHelper.app/Contents/Resources/AppIcon.icns +0 -0
- package/dist/lib/menubar/MenubarHelper.app/Contents/_CodeSignature/CodeResources +0 -128
- package/dist/lib/secrets/Agents CLI.app/Contents/CodeResources +0 -0
- package/dist/lib/secrets/Agents CLI.app/Contents/Info.plist +0 -24
- package/dist/lib/secrets/Agents CLI.app/Contents/MacOS/Agents CLI +0 -0
- package/dist/lib/secrets/Agents CLI.app/Contents/_CodeSignature/CodeResources +0 -123
- package/dist/lib/secrets/Agents CLI.app/Contents/embedded.provisionprofile +0 -0
- package/dist/lib/usage-fleet.d.ts +0 -32
- package/dist/lib/usage-fleet.js +0 -125
|
@@ -22,7 +22,7 @@ import { terminalWidth, stringWidth } from '../lib/session/width.js';
|
|
|
22
22
|
import { itemPicker } from '../lib/picker.js';
|
|
23
23
|
import { createMemoryCache } from '../lib/memory-cache.js';
|
|
24
24
|
import { classifyFileChanges, changeCounts, toolHistogram, detectTestResult } from '../lib/session/digest.js';
|
|
25
|
-
import { extractArtifacts, extractHooks, extractLinks, extractRepos, extractSkills } from '../lib/session/highlights.js';
|
|
25
|
+
import { extractArtifacts, extractHooks, extractLinks, extractRepos, extractSkills, harnessTracksBackgroundShells, isBackgroundShellStart, isSubAgentTool, } from '../lib/session/highlights.js';
|
|
26
26
|
import { getSessionPlugins, readSessionPreviewCache, writeSessionPreviewCache, readSessionContent, readArchivedSessionPreview } from '../lib/session/db.js';
|
|
27
27
|
/** A session whose transcript FILE is on another machine (folded in over the
|
|
28
28
|
* live cross-machine fan-out): its `filePath` is on that peer's disk, so the
|
|
@@ -222,6 +222,10 @@ export function sanitizeRemoteDigest(raw) {
|
|
|
222
222
|
planFile: str(d.planFile),
|
|
223
223
|
todos,
|
|
224
224
|
subAgentCount: num(d.subAgentCount),
|
|
225
|
+
// optNum, not num: a peer's JSON is untrusted, and the undefined-vs-0
|
|
226
|
+
// distinction is load-bearing here — num() would coerce a malformed value
|
|
227
|
+
// to 0, which reads as "scanned, none running".
|
|
228
|
+
backgroundShellCount: optNum(d.backgroundShellCount),
|
|
225
229
|
toolTags: strList(d.toolTags),
|
|
226
230
|
changes,
|
|
227
231
|
dirs: strList(d.dirs),
|
|
@@ -472,6 +476,37 @@ function formatHeader(session, events) {
|
|
|
472
476
|
* machine — far too much for a pane that repaints as the cursor moves. The line
|
|
473
477
|
* names the command that does report them instead.
|
|
474
478
|
*/
|
|
479
|
+
/**
|
|
480
|
+
* The "what did this session leave running" segments of the Doing line.
|
|
481
|
+
*
|
|
482
|
+
* Prefers a DERIVED count (fresh, from the transcript the caller just parsed)
|
|
483
|
+
* and falls back to the PERSISTED column, which is what lets a remote/unindexed
|
|
484
|
+
* row — rendered from `SessionMeta` alone, with no events — show fan-out at all.
|
|
485
|
+
* That fallback is the whole reason the counts are columns (RUSH-3091/3095).
|
|
486
|
+
*
|
|
487
|
+
* A count of 0 or undefined renders NOTHING. Both are real states — "scanned,
|
|
488
|
+
* none found" and "this harness cannot report it" — and a literal "0 background
|
|
489
|
+
* shells" would assert "nothing is running" for a harness that simply does not
|
|
490
|
+
* record them.
|
|
491
|
+
*
|
|
492
|
+
* Wording is "left behind", not "running": a transcript records a start and
|
|
493
|
+
* never a death (see extractBackgroundShells).
|
|
494
|
+
*/
|
|
495
|
+
export function formatFanOut(session, derived) {
|
|
496
|
+
// DERIVED wins when the caller has one. It is computed from the transcript as
|
|
497
|
+
// it stands right now, whereas the persisted column is only as fresh as the
|
|
498
|
+
// last scan — for a live session those disagree within seconds. The persisted
|
|
499
|
+
// value is the fallback that makes a remote/unindexed row (no events, so no
|
|
500
|
+
// derived value) render at all, which is the whole reason it is a column.
|
|
501
|
+
const subAgents = derived?.subAgentCount ?? session.subAgentCount ?? 0;
|
|
502
|
+
const shells = derived?.backgroundShellCount ?? session.backgroundShellCount ?? 0;
|
|
503
|
+
const out = [];
|
|
504
|
+
if (subAgents > 0)
|
|
505
|
+
out.push(chalk.gray(`${subAgents} sub-agent${subAgents === 1 ? '' : 's'}`));
|
|
506
|
+
if (shells > 0)
|
|
507
|
+
out.push(chalk.gray(`${shells} background shell${shells === 1 ? '' : 's'}`));
|
|
508
|
+
return out;
|
|
509
|
+
}
|
|
475
510
|
export function formatTeamLineage(session) {
|
|
476
511
|
const origin = session.teamOrigin;
|
|
477
512
|
if (origin) {
|
|
@@ -505,7 +540,7 @@ function formatMetaOnlyBody(session) {
|
|
|
505
540
|
}
|
|
506
541
|
const compact = formatTodoCompact(session.todos);
|
|
507
542
|
const teamLine = formatTeamLineage(session);
|
|
508
|
-
const doing = [compact ? chalk.white(compact) : '', teamLine].filter(Boolean);
|
|
543
|
+
const doing = [compact ? chalk.white(compact) : '', teamLine, ...formatFanOut(session)].filter(Boolean);
|
|
509
544
|
if (doing.length) {
|
|
510
545
|
lines.push(verbLabel('Doing') + doing.join(DOT));
|
|
511
546
|
}
|
|
@@ -630,6 +665,12 @@ export function buildSessionPreviewDigest(events, session) {
|
|
|
630
665
|
/** Latest checklist from the transcript (Claude TodoWrite / Codex update_plan). */
|
|
631
666
|
let latestTodos;
|
|
632
667
|
let subAgentCount = 0;
|
|
668
|
+
// undefined, not 0, when the harness records no background-shell concept —
|
|
669
|
+
// formatFanOut renders absence for both, but conflating them here would let a
|
|
670
|
+
// later consumer read "0 shells" as a positive "none running" claim.
|
|
671
|
+
let backgroundShellCount = harnessTracksBackgroundShells(session.agent)
|
|
672
|
+
? 0
|
|
673
|
+
: undefined;
|
|
633
674
|
const toolTags = new Set();
|
|
634
675
|
// usedBrowser/usedComputer are computed at scan time from a sessionId-scoped
|
|
635
676
|
// events-log read (session/db.ts detectToolUsage), NOT a transcript regex —
|
|
@@ -658,6 +699,8 @@ export function buildSessionPreviewDigest(events, session) {
|
|
|
658
699
|
}
|
|
659
700
|
if (isSubAgentTool(tool, command))
|
|
660
701
|
subAgentCount++;
|
|
702
|
+
if (backgroundShellCount !== undefined && isBackgroundShellStart(event))
|
|
703
|
+
backgroundShellCount++;
|
|
661
704
|
const p = event.path || event.args?.file_path || event.args?.path || '';
|
|
662
705
|
if (['Read', 'read_file', 'view_file', 'cat_file', 'get_file'].includes(tool) && p) {
|
|
663
706
|
filesRead.add(p);
|
|
@@ -700,6 +743,7 @@ export function buildSessionPreviewDigest(events, session) {
|
|
|
700
743
|
planFile,
|
|
701
744
|
todos,
|
|
702
745
|
subAgentCount,
|
|
746
|
+
backgroundShellCount,
|
|
703
747
|
toolTags: [...toolTags],
|
|
704
748
|
changes: chg,
|
|
705
749
|
dirs: directoriesTouched(session, events, changes),
|
|
@@ -722,7 +766,7 @@ function verbLabel(v) {
|
|
|
722
766
|
return chalk.cyan(v.padEnd(VERB_GUTTER)) + ' ';
|
|
723
767
|
}
|
|
724
768
|
function formatCompactPreview(digest, session, events) {
|
|
725
|
-
const { firstUser, lastAssistant, filesRead, toolCalls, planFile, todos, subAgentCount, toolTags, changes: chg, dirs, repos, artifacts, skills, plugins, hooks, links, errorCount, firstError, toolHistogram: hist, test, } = digest;
|
|
769
|
+
const { firstUser, lastAssistant, filesRead, toolCalls, planFile, todos, subAgentCount, backgroundShellCount, toolTags, changes: chg, dirs, repos, artifacts, skills, plugins, hooks, links, errorCount, firstError, toolHistogram: hist, test, } = digest;
|
|
726
770
|
const lines = [];
|
|
727
771
|
const termWidth = process.stdout.columns || 80;
|
|
728
772
|
const valueWidth = termWidth - VERB_GUTTER - 5;
|
|
@@ -740,7 +784,7 @@ function formatCompactPreview(digest, session, events) {
|
|
|
740
784
|
const doing = [
|
|
741
785
|
compact ? chalk.white(compact) : '',
|
|
742
786
|
teamLine,
|
|
743
|
-
|
|
787
|
+
...formatFanOut(session, { subAgentCount, backgroundShellCount }),
|
|
744
788
|
].filter(Boolean);
|
|
745
789
|
if (doing.length) {
|
|
746
790
|
lines.push(verbLabel('Doing') + doing.join(DOT));
|
|
@@ -854,11 +898,6 @@ function classifySessionTool(tool, command) {
|
|
|
854
898
|
tags.push('computer');
|
|
855
899
|
return tags;
|
|
856
900
|
}
|
|
857
|
-
function isSubAgentTool(tool, command) {
|
|
858
|
-
if (/^(Agent|Task)$/i.test(tool))
|
|
859
|
-
return true;
|
|
860
|
-
return /\b(?:agents|ag)\b[^\n;&|]*\b(?:run|cloud\s+run|teams\s+(?:add|start))\b/.test(command);
|
|
861
|
-
}
|
|
862
901
|
/**
|
|
863
902
|
* Unique directories the session touched, compact and human-readable.
|
|
864
903
|
* Prefer `session.recentDirectoriesTouched` — the scan records it on the row, so
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `agents sessions stop <id>` — end a live agent session outright: stop its
|
|
3
|
+
* interactive process and tear down its tmux/mux session, so the session becomes
|
|
4
|
+
* done/closed rather than an orphaned idle background process.
|
|
5
|
+
*
|
|
6
|
+
* The lifecycle sibling of `detach` that does NOT resume headless. `detach`
|
|
7
|
+
* backgrounds a still-wanted agent (stop the terminal, keep it working); `stop`
|
|
8
|
+
* is for when the work is over — the agent's editor tab was closed, or you want
|
|
9
|
+
* it gone. Both reuse the same live-session resolution and the same
|
|
10
|
+
* `stopInteractive` teardown (tmux `kill-session`, else SIGTERM→SIGKILL the pid),
|
|
11
|
+
* so a session killed here reaps its helpers exactly as `detach` does before it
|
|
12
|
+
* resumes.
|
|
13
|
+
*
|
|
14
|
+
* The primary caller is AGI EXT: when a user genuinely closes an agent tab
|
|
15
|
+
* (Cmd+W), the extension runs this so the underlying agent + its mux are shut
|
|
16
|
+
* down instead of being left running detached (the "Cmd+W orphans an idle
|
|
17
|
+
* session" bug). A window RELOAD does NOT call this — the extension distinguishes
|
|
18
|
+
* the two via `terminal.exitStatus.reason` and only a real user close tears down.
|
|
19
|
+
*/
|
|
20
|
+
import type { Command } from 'commander';
|
|
21
|
+
export declare function registerSessionsStopCommand(program: Command): void;
|
|
22
|
+
export declare function stopSessionAction(id: string, opts?: {
|
|
23
|
+
local?: boolean;
|
|
24
|
+
}): Promise<void>;
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { gatherLiveTargets } from './go.js';
|
|
3
|
+
import { resolveDetachTarget, resolveOne } from './detach-core.js';
|
|
4
|
+
import { stopInteractive } from './detach.js';
|
|
5
|
+
import { runOnPeer } from '../lib/session/remote-list.js';
|
|
6
|
+
import { setHelpSections } from '../lib/help.js';
|
|
7
|
+
export function registerSessionsStopCommand(program) {
|
|
8
|
+
const cmd = program
|
|
9
|
+
.command('stop')
|
|
10
|
+
.argument('<id>', 'Short or full id of the live session to stop')
|
|
11
|
+
.option('--local', 'Only this machine (skip the cross-host sweep)')
|
|
12
|
+
.description('Stop a live agent outright — end its process and tear down its tmux/mux session')
|
|
13
|
+
.action(async (id, opts) => {
|
|
14
|
+
await stopSessionAction(id, opts);
|
|
15
|
+
});
|
|
16
|
+
setHelpSections(cmd, {
|
|
17
|
+
examples: `
|
|
18
|
+
# Stop a live session by a short id prefix
|
|
19
|
+
agents sessions stop 4b2f1a9c
|
|
20
|
+
|
|
21
|
+
# Only look on this machine (skip the fleet sweep)
|
|
22
|
+
agents sessions stop 4b2f1a9c --local
|
|
23
|
+
`,
|
|
24
|
+
notes: `
|
|
25
|
+
stop ENDS the session; it does not background it. To keep an agent working
|
|
26
|
+
unattended instead, use \`agents sessions detach <id>\`, and bring it back
|
|
27
|
+
with \`agents sessions resume <id>\`.
|
|
28
|
+
|
|
29
|
+
A session that lives on another machine is stopped THERE over SSH — its pid
|
|
30
|
+
and tmux socket only mean something where it actually runs.
|
|
31
|
+
`,
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
export async function stopSessionAction(id, opts = {}) {
|
|
35
|
+
const { self, activeById } = await gatherLiveTargets(!!opts.local, { includeCloud: true });
|
|
36
|
+
const resolved = resolveOne(activeById, id);
|
|
37
|
+
if ('error' in resolved) {
|
|
38
|
+
console.error(chalk.red(resolved.error));
|
|
39
|
+
process.exitCode = 1;
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
const s = resolved;
|
|
43
|
+
const target = resolveDetachTarget(s, self);
|
|
44
|
+
// Cloud/team/id-less sessions have their own lifecycles — refuse rather than
|
|
45
|
+
// half-stopping one from here (same boundary `detach` enforces).
|
|
46
|
+
if (target.kind === 'refuse') {
|
|
47
|
+
console.error(chalk.red(target.reason));
|
|
48
|
+
process.exitCode = 1;
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
const short = target.sessionId.slice(0, 8);
|
|
52
|
+
// A session on another host: its pid/tmux socket only mean something where it
|
|
53
|
+
// runs, so stop it THERE over SSH — never kill locally. Mirrors detach/focus.
|
|
54
|
+
if (target.kind === 'remote') {
|
|
55
|
+
console.log(chalk.gray(`${short} lives on ${target.machine} — stopping it there over SSH…`));
|
|
56
|
+
const rc = await runOnPeer(['sessions', 'stop', target.sessionId, '--local'], target.machine);
|
|
57
|
+
if (rc === 'no-target') {
|
|
58
|
+
console.error(chalk.red(`Can't reach ${target.machine} to stop ${short}.`));
|
|
59
|
+
process.exitCode = 1;
|
|
60
|
+
}
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
// Local: end the interactive process and tear down its tmux/mux session.
|
|
64
|
+
await stopInteractive(s);
|
|
65
|
+
console.log(chalk.green(`■ Stopped ${s.kind} ${short}`) + chalk.gray(' — process ended, session closed.'));
|
|
66
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import type { Command } from 'commander';
|
|
2
|
+
import type { SessionTrajectory } from '../lib/session/trajectory.js';
|
|
3
|
+
import type { TrajectoryComparison, TrajectoryDivergence, TrajectorySummary } from '../lib/session/trajectory-compare.js';
|
|
4
|
+
import type { TrajectoryStep } from '../lib/session/trajectory.js';
|
|
5
|
+
import type { LineageEdge, LineageNode, SessionLineage } from '../lib/session/trajectory-lineage.js';
|
|
6
|
+
/** Versioned envelope emitted by `--json` — the stable contract for consumers. */
|
|
7
|
+
export declare const SESSIONS_TRACE_SCHEMA_VERSION = 1;
|
|
8
|
+
/** The `diff` block of a `layout: 'compare'` envelope — everything but the two full trajectories, which already ride `sessions`. */
|
|
9
|
+
export interface SessionsTraceDiffEnvelope {
|
|
10
|
+
divergence?: TrajectoryDivergence;
|
|
11
|
+
added: TrajectoryStep[];
|
|
12
|
+
removed: TrajectoryStep[];
|
|
13
|
+
summaryA: TrajectorySummary;
|
|
14
|
+
summaryB: TrajectorySummary;
|
|
15
|
+
truncatedA: number;
|
|
16
|
+
truncatedB: number;
|
|
17
|
+
}
|
|
18
|
+
/** The `lineage` block of a `layout: 'lineage'` envelope — the delegation graph. */
|
|
19
|
+
export interface SessionsTraceLineageEnvelope {
|
|
20
|
+
rootId: string;
|
|
21
|
+
nodes: LineageNode[];
|
|
22
|
+
edges: LineageEdge[];
|
|
23
|
+
teams: string[];
|
|
24
|
+
unresolvedParentIds: string[];
|
|
25
|
+
}
|
|
26
|
+
/** The `--json` envelope: the versioned contract for the ext / triaging agents. */
|
|
27
|
+
export interface SessionsTraceEnvelope {
|
|
28
|
+
schemaVersion: typeof SESSIONS_TRACE_SCHEMA_VERSION;
|
|
29
|
+
kind: 'sessions-trace';
|
|
30
|
+
layout: 'single' | 'compare' | 'lineage';
|
|
31
|
+
sessions: SessionTrajectory[];
|
|
32
|
+
diff?: SessionsTraceDiffEnvelope;
|
|
33
|
+
lineage?: SessionsTraceLineageEnvelope;
|
|
34
|
+
}
|
|
35
|
+
/** Build the versioned `--json` envelope for a single-session trajectory. */
|
|
36
|
+
export declare function buildTraceEnvelope(models: SessionTrajectory[]): SessionsTraceEnvelope;
|
|
37
|
+
/** Build the versioned `--json` envelope for a two-session compare. */
|
|
38
|
+
export declare function buildCompareTraceEnvelope(cmp: TrajectoryComparison): SessionsTraceEnvelope;
|
|
39
|
+
/**
|
|
40
|
+
* Build the versioned `--json` envelope for a lineage. `sessions` carries the
|
|
41
|
+
* ROOT's trajectory only: the graph's own numbers come from the indexed session
|
|
42
|
+
* rows, so a consumer pays one transcript parse instead of one per teammate —
|
|
43
|
+
* `agents sessions trace <child>` is how you get a child's full trajectory.
|
|
44
|
+
*/
|
|
45
|
+
export declare function buildLineageTraceEnvelope(lineage: SessionLineage, rootTrajectory: SessionTrajectory): SessionsTraceEnvelope;
|
|
46
|
+
interface TraceOptions {
|
|
47
|
+
html?: boolean;
|
|
48
|
+
text?: boolean;
|
|
49
|
+
json?: boolean;
|
|
50
|
+
output?: string;
|
|
51
|
+
open?: boolean;
|
|
52
|
+
errorsOnly?: boolean;
|
|
53
|
+
redact?: boolean;
|
|
54
|
+
all?: boolean;
|
|
55
|
+
since?: string;
|
|
56
|
+
limit?: string;
|
|
57
|
+
agent?: string;
|
|
58
|
+
compare?: boolean;
|
|
59
|
+
tree?: boolean;
|
|
60
|
+
}
|
|
61
|
+
export type RenderFormat = 'html' | 'text' | 'json';
|
|
62
|
+
/**
|
|
63
|
+
* Pick the rendering by audience: explicit `--html/--text/--json` win; otherwise
|
|
64
|
+
* a person at a TTY gets the visual HTML and a piped/headless caller (an agent)
|
|
65
|
+
* gets the compact text trajectory.
|
|
66
|
+
*/
|
|
67
|
+
export declare function chooseFormat(options: TraceOptions, isTTY: boolean): RenderFormat;
|
|
68
|
+
/**
|
|
69
|
+
* Decide the trace layout from what the user TYPED (`selectorCount`) vs what
|
|
70
|
+
* those selectors RESOLVED to (`resolvedCount`). Keyed on selector count so a
|
|
71
|
+
* single content-search selector that happens to match two sessions never
|
|
72
|
+
* silently becomes a compare — every unsupported combination fails loud with a
|
|
73
|
+
* clear message. Pure, so the boundaries are unit-tested without the command.
|
|
74
|
+
*/
|
|
75
|
+
export declare function decideTraceLayout(options: Pick<TraceOptions, 'tree' | 'compare'>, selectorCount: number, resolvedCount: number): 'single' | 'compare' | 'lineage';
|
|
76
|
+
/** Attach the trace behaviour to a command node (canonical or top-level alias). */
|
|
77
|
+
export declare function configureTraceCommand(cmd: Command): Command;
|
|
78
|
+
/** Canonical `agents sessions trace <selectors...>`. */
|
|
79
|
+
export declare function registerSessionsTraceCommand(sessionsCmd: Command): void;
|
|
80
|
+
/** Top-level alias `agents trace <selectors...>` (mirrors `agents insights`). */
|
|
81
|
+
export declare function registerTraceCommand(program: Command): void;
|
|
82
|
+
export {};
|