@phnx-labs/agents-cli 1.22.23 → 1.22.25
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 +359 -0
- package/README.md +19 -8
- package/dist/bin/agents +0 -0
- package/dist/commands/attach.d.ts +2 -0
- package/dist/commands/attach.js +32 -7
- package/dist/commands/cloud.js +9 -5
- package/dist/commands/defaults.js +2 -0
- package/dist/commands/doctor.d.ts +24 -0
- package/dist/commands/doctor.js +105 -9
- package/dist/commands/exec.js +99 -44
- package/dist/commands/feed.d.ts +23 -0
- package/dist/commands/feed.js +65 -2
- package/dist/commands/focus.d.ts +34 -3
- package/dist/commands/focus.js +301 -57
- package/dist/commands/go.d.ts +14 -1
- package/dist/commands/go.js +49 -5
- package/dist/commands/insights.js +6 -2
- package/dist/commands/inspect.js +39 -5
- package/dist/commands/menubar.js +14 -1
- package/dist/commands/models.js +1 -0
- package/dist/commands/modes.d.ts +12 -0
- package/dist/commands/modes.js +147 -0
- package/dist/commands/routines.d.ts +3 -0
- package/dist/commands/routines.js +70 -47
- package/dist/commands/run-cloud.js +1 -1
- package/dist/commands/secrets-sync.js +11 -13
- package/dist/commands/secrets.d.ts +2 -0
- package/dist/commands/secrets.js +54 -17
- package/dist/commands/sessions-browser.d.ts +36 -1
- package/dist/commands/sessions-browser.js +165 -19
- package/dist/commands/sessions-resume.d.ts +2 -0
- package/dist/commands/sessions-resume.js +28 -12
- package/dist/commands/sessions.d.ts +23 -1
- package/dist/commands/sessions.js +58 -61
- package/dist/commands/setup-secrets.js +1 -1
- package/dist/commands/setup-watchdog.js +5 -10
- package/dist/commands/setup.js +1 -1
- package/dist/commands/sync.js +246 -42
- package/dist/commands/teams.js +3 -2
- package/dist/commands/view.js +2 -0
- package/dist/commands/watchdog.d.ts +3 -4
- package/dist/commands/watchdog.js +26 -66
- package/dist/index.js +38 -2
- package/dist/lib/agent-modes.d.ts +49 -0
- package/dist/lib/agent-modes.js +70 -0
- package/dist/lib/agents.js +126 -21
- package/dist/lib/cloud/cursor.d.ts +79 -0
- package/dist/lib/cloud/cursor.js +228 -0
- package/dist/lib/cloud/registry.js +2 -0
- package/dist/lib/cloud/types.d.ts +7 -2
- package/dist/lib/cloud/types.js +14 -0
- package/dist/lib/crabbox/cli.d.ts +2 -2
- package/dist/lib/crabbox/config.d.ts +7 -8
- package/dist/lib/crabbox/config.js +14 -14
- package/dist/lib/crabbox/lease.d.ts +11 -4
- package/dist/lib/crabbox/lease.js +40 -8
- package/dist/lib/crabbox/setup-copy.d.ts +5 -0
- package/dist/lib/crabbox/setup-copy.js +17 -1
- package/dist/lib/daemon.js +27 -1
- package/dist/lib/device-config.js +7 -0
- package/dist/lib/devices/doctor-findings.d.ts +7 -1
- package/dist/lib/devices/doctor-findings.js +40 -1
- package/dist/lib/doctor-diff.d.ts +3 -0
- package/dist/lib/doctor-diff.js +15 -13
- package/dist/lib/event-stream.d.ts +3 -1
- package/dist/lib/event-stream.js +14 -1
- package/dist/lib/events.d.ts +9 -0
- package/dist/lib/events.js +58 -0
- package/dist/lib/exec.d.ts +15 -3
- package/dist/lib/exec.js +112 -19
- package/dist/lib/feed-outcome.d.ts +3 -0
- package/dist/lib/feed-outcome.js +18 -10
- package/dist/lib/feed.d.ts +4 -0
- package/dist/lib/hooks/cache.js +36 -3
- package/dist/lib/hooks.d.ts +19 -7
- package/dist/lib/hooks.js +88 -38
- package/dist/lib/hosts/passthrough.d.ts +21 -0
- package/dist/lib/hosts/passthrough.js +39 -12
- package/dist/lib/hosts/session-index.d.ts +4 -0
- package/dist/lib/hosts/session-index.js +7 -0
- package/dist/lib/manifest.d.ts +12 -2
- package/dist/lib/manifest.js +60 -5
- package/dist/lib/mcp.js +5 -1
- package/dist/lib/menubar/MenubarHelper.app/Contents/CodeResources +0 -0
- package/dist/lib/menubar/MenubarHelper.app/Contents/Info.plist +5 -1
- 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 +15 -2
- package/dist/lib/menubar/install-menubar.d.ts +52 -2
- package/dist/lib/menubar/install-menubar.js +128 -6
- package/dist/lib/menubar/snapshot.d.ts +15 -0
- package/dist/lib/menubar/snapshot.js +40 -0
- package/dist/lib/plugins.js +13 -1
- package/dist/lib/refresh.d.ts +5 -0
- package/dist/lib/refresh.js +37 -33
- package/dist/lib/resource-inventory.d.ts +79 -0
- package/dist/lib/resource-inventory.js +122 -0
- package/dist/lib/resources/mcp.js +3 -0
- package/dist/lib/resources.js +8 -5
- package/dist/lib/routine-process-cleanup.d.ts +9 -0
- package/dist/lib/routine-process-cleanup.js +73 -0
- package/dist/lib/run-defaults.d.ts +2 -0
- package/dist/lib/run-defaults.js +23 -2
- package/dist/lib/runner.js +27 -22
- package/dist/lib/secrets/Agents CLI.app/Contents/CodeResources +0 -0
- package/dist/lib/secrets/Agents CLI.app/Contents/Info.plist +2 -0
- package/dist/lib/secrets/Agents CLI.app/Contents/MacOS/Agents CLI +0 -0
- package/dist/lib/secrets/Agents CLI.app/Contents/Resources/AppIcon.icns +0 -0
- package/dist/lib/secrets/Agents CLI.app/Contents/_CodeSignature/CodeResources +13 -1
- package/dist/lib/secrets/bundles.js +158 -85
- package/dist/lib/secrets/filestore.d.ts +7 -3
- package/dist/lib/secrets/filestore.js +25 -8
- package/dist/lib/secrets/index.js +34 -8
- package/dist/lib/secrets/rc-hygiene.d.ts +14 -0
- package/dist/lib/secrets/rc-hygiene.js +14 -1
- package/dist/lib/secrets/reaper.d.ts +10 -0
- package/dist/lib/secrets/reaper.js +50 -15
- package/dist/lib/secrets/sync-passphrase.d.ts +27 -0
- package/dist/lib/secrets/sync-passphrase.js +78 -0
- package/dist/lib/session/active.d.ts +4 -0
- package/dist/lib/session/db.js +8 -2
- package/dist/lib/session/recovery.d.ts +37 -0
- package/dist/lib/session/recovery.js +95 -0
- package/dist/lib/session/remote-list.d.ts +2 -0
- package/dist/lib/session/remote-list.js +1 -0
- package/dist/lib/session/session-cache.d.ts +4 -4
- package/dist/lib/session/session-cache.js +4 -4
- package/dist/lib/shims.d.ts +2 -2
- package/dist/lib/shims.js +45 -6
- package/dist/lib/signin-badge.js +2 -0
- package/dist/lib/startup/command-registry.d.ts +16 -0
- package/dist/lib/startup/command-registry.js +44 -0
- package/dist/lib/sync-umbrella.d.ts +5 -0
- package/dist/lib/sync-umbrella.js +5 -4
- package/dist/lib/teams/agents.js +1 -1
- package/dist/lib/teams/parsers.d.ts +1 -1
- package/dist/lib/tmux/session.d.ts +4 -2
- package/dist/lib/tmux/session.js +5 -5
- package/dist/lib/types.d.ts +3 -1
- package/dist/lib/versions.js +16 -1
- package/dist/lib/watchdog/service.d.ts +17 -0
- package/dist/lib/watchdog/service.js +39 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,364 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.22.25
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
issue: 2108
|
|
7
|
+
type: fixed
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
`agents sessions focus ... --active` now excludes closed and crashed registry rows; explicit lifecycle filters such as `--closed` and `--crashed` still select them. Per-device `latest` / `oldest` selectors also wait for the peer's filtered index result instead of widening to live rows whose version is unknown.
|
|
11
|
+
|
|
12
|
+
- **`agents doctor` now reports the file-store master key when it is live in the
|
|
13
|
+
process environment, not just when it is exported from a shell rc file
|
|
14
|
+
(RUSH-1968).** `rc-hygiene.ts` scans FILES, which leaves a real hole: a value
|
|
15
|
+
inherited by a long-lived process outlives the rc line that set it, so an operator
|
|
16
|
+
who deletes `~/.zshenv:8` gets a clean `rc-secret-export` while every shell, editor
|
|
17
|
+
and agent started before the edit still carries the key and hands it to everything
|
|
18
|
+
they spawn. Confirmed on `yosemite-s1`, which has zero rc exports and still had the
|
|
19
|
+
value in its environment. The new `env-secret-export` warning names that state and
|
|
20
|
+
says the deletion is not sufficient; like every other finding it reports only that
|
|
21
|
+
the variable is set, never its value. Expected inside a release sign context
|
|
22
|
+
(`headless-sign-context.sh` sets it deliberately), which the message says so an
|
|
23
|
+
operator on the home base does not chase it. Source:
|
|
24
|
+
`apps/cli/src/lib/secrets/rc-hygiene.ts` (`masterPassphraseInEnv`),
|
|
25
|
+
`apps/cli/src/lib/devices/doctor-findings.ts`, `apps/cli/src/commands/doctor.ts`.
|
|
26
|
+
|
|
27
|
+
- **`agents doctor --devices` now reports a remote box's secret hygiene, and its
|
|
28
|
+
inventory probe no longer times out on a slow box (RUSH-1968).** The fan-out ran
|
|
29
|
+
each remote's own `doctor --json` but parsed only `.fleet`, discarding the
|
|
30
|
+
`findings` the remote had already computed — so a leaking box read as clean from
|
|
31
|
+
anywhere but itself. The remote's `rc-secret-export` / `env-secret-export` rows
|
|
32
|
+
now ride back, but the remote contributes exactly one thing: the **kind**. Severity,
|
|
33
|
+
message and remediation are generated locally, and `device` is overwritten with the
|
|
34
|
+
name that was dialled. Each of those matters separately — a remediation is a command
|
|
35
|
+
a human copies and runs, a message is the one place a secret value could re-enter a
|
|
36
|
+
readout that otherwise never prints one, a severity decides the CRITICAL section, and
|
|
37
|
+
a device name decides which box gets blamed. The cost is detail: the fleet row names
|
|
38
|
+
the box and the kind, and says to run `agents doctor` there for the file and line.
|
|
39
|
+
Only those two kinds forward — sign-in and divergence rows are recomputed centrally
|
|
40
|
+
and would otherwise double.
|
|
41
|
+
|
|
42
|
+
Separately, the probe's 30s timeout was below the real cost of the command it
|
|
43
|
+
runs — `doctor --json` measures 57s on `yosemite-m0` and 136s on an idle box — so
|
|
44
|
+
every slow device silently contributed nothing at all: no inventory, no sign-in,
|
|
45
|
+
no divergence. Raised to 180s, matching `ChildProcess.doctorTimeout`, which was set
|
|
46
|
+
to 180 for this same command for this same reason. Source:
|
|
47
|
+
`apps/cli/src/commands/doctor.ts` (`asRemoteSecretFindings`, `probeFleetInventory`).
|
|
48
|
+
|
|
49
|
+
- **Feed and menu-bar session counts now use the `agents sessions --active` lifecycle model (RUSH-1993).**
|
|
50
|
+
Feed outcome headers count distinct mailbox agents in every state, so repeated
|
|
51
|
+
open blocks from one agent cannot make `needs you` exceed `agents`. Feed rows
|
|
52
|
+
replace generic `terminal` with a known host app and label routine-spawned
|
|
53
|
+
sessions as `routine:<name>`. The menu-bar snapshot backfills the same routine
|
|
54
|
+
metadata as active-session JSON and renders the full canonical status set
|
|
55
|
+
(`working`, `waiting`, `idle`, `queued`, `orphan`, `crashed`, `closed`,
|
|
56
|
+
`abandoned`, `unknown`) without reclassifying warm rows from attention files.
|
|
57
|
+
Source: `apps/cli/src/commands/feed.ts`, `apps/cli/src/commands/sessions.ts`,
|
|
58
|
+
`apps/cli/src/lib/feed-outcome.ts`, `apps/cli/src/lib/menubar/snapshot.ts`,
|
|
59
|
+
`apps/cli/menubar/Sources/MenubarHelper/{LocalState,StatusItemController}.swift`.
|
|
60
|
+
|
|
61
|
+
- **A typo'd command with `--host` said the opposite of the truth (RUSH-2022).** The
|
|
62
|
+
`--host`/`--device` router runs before commander parses, so `agents session resume
|
|
63
|
+
--host <box>` (one letter off `sessions`, which *does* accept `--host`) reported
|
|
64
|
+
`` `agents session` does not support --host/--device `` — a true statement about a
|
|
65
|
+
command nobody typed. Unknown names now fall through to `unknown command '<name>'`
|
|
66
|
+
with a did-you-mean, and the spellcheck can suggest the lazily-registered groups
|
|
67
|
+
(`sessions`/`teams`/`cloud`/…) it previously could not see. A real command with no
|
|
68
|
+
remote semantics still gets the flag-support error. Source:
|
|
69
|
+
`apps/cli/src/lib/hosts/passthrough.ts`, `apps/cli/src/lib/startup/command-registry.ts`.
|
|
70
|
+
|
|
71
|
+
- **`agents publish` is in the lazy command table.** `commands/packages.ts` registers it
|
|
72
|
+
at top level but the registry did not list it, so it only resolved through the
|
|
73
|
+
unknown-command fallback that loads the whole command tree. Found by the new test
|
|
74
|
+
that pins the command-name set against the real tree.
|
|
75
|
+
|
|
76
|
+
- **A mistyped command keeps its `--host`.** The distance-1 auto-correct now re-checks
|
|
77
|
+
routing after correcting the name, so `agents docto --host <box>` corrects to
|
|
78
|
+
`doctor` **and actually routes to `<box>`** — previously the corrected command
|
|
79
|
+
re-parsed locally with a `--host` it silently dropped (a regression caught in review:
|
|
80
|
+
it used to fail loudly with the wrong message, corrected-but-unrouted made it fail
|
|
81
|
+
silently instead). `apps/cli/src/index.ts`.
|
|
82
|
+
|
|
83
|
+
- **Cursor now supports `--mode plan` headless and interactive (RUSH-2101).** The
|
|
84
|
+
capability registry previously listed only `edit` and `skip`, so `agents run cursor --mode plan`
|
|
85
|
+
and routine jobs silently degraded to writable `edit`. `cursor-agent` has supported `--plan`
|
|
86
|
+
since the 2026-01-16 CLI release; the registry, `AGENT_COMMANDS` flag mapping, and the routine
|
|
87
|
+
runner now forward it correctly. Source: `apps/cli/src/lib/agents.ts`, `apps/cli/src/lib/exec.ts`,
|
|
88
|
+
`apps/cli/src/lib/runner.ts`.
|
|
89
|
+
|
|
90
|
+
- **`agents sessions resume` picker now filters in-memory on every keystroke instead of re-querying the database (RUSH-2212).** The `filter` callback in the multi-select picker was calling `filterSessionsByQuery`, which runs a full-text search scan against `sessions.db` on every character typed. It now uses the same cheap in-memory substring match (`sessionMatchesQuery`) the session browser already applies, so the picker stays responsive regardless of library size. Source: `apps/cli/src/commands/sessions-resume.ts`.
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
type: minor
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
Add Cursor Cloud Agents as a native cloud provider so `agents run cursor --cloud` and `agents cloud run --agent cursor` dispatch through Cursor's v1 REST API, with status, streaming, cancellation, and follow-up runs.
|
|
97
|
+
|
|
98
|
+
- **A starved `coreauthd` can no longer hang `secrets list` forever (RUSH-2233).**
|
|
99
|
+
The keychain helper's `list` runs two passes, and the data-protection pass omits
|
|
100
|
+
`kSecUseAuthenticationUI: …Fail` on purpose (that flag drops every biometry-ACL
|
|
101
|
+
item even when authentication is healthy). Omitting it means the query still
|
|
102
|
+
reaches LocalAuthentication/`coreauthd`, which has no deadline of its own — a
|
|
103
|
+
wedged `coreauthd` left `SecItemCopyMatching` blocked for the life of the
|
|
104
|
+
process. That is *why* helpers accumulated for the bounded-spawn + reaper work
|
|
105
|
+
in RUSH-2231/2232 to clean up. The pass now runs on a background thread behind
|
|
106
|
+
a 3-second wait: on timeout the helper logs one line to stderr, skips the pass,
|
|
107
|
+
and prints whatever the file-keychain pass produced — the same handling the
|
|
108
|
+
screen-locked `errSecInteractionNotAllowed` case already got. Set
|
|
109
|
+
`AGENTS_KEYCHAIN_LIST_TIMEOUT_MS` to override the deadline;
|
|
110
|
+
`AGENTS_KEYCHAIN_BOUNDED_TEST=1` runs the helper's headless self-test for the
|
|
111
|
+
bounded wait. Source: `apps/cli/src/lib/secrets/keychain-helper.swift`.
|
|
112
|
+
|
|
113
|
+
- **Use one three-minute AGI Menu snapshot and one watchdog executor (RUSH-2260).**
|
|
114
|
+
The menu bar now reads routines, 40 indexed recent sessions, the daemon-warmed
|
|
115
|
+
active-session cache, and persisted watchdog state in one subprocess every three
|
|
116
|
+
minutes; `doctor --json` remains independently limited to 15 minutes. The menu no
|
|
117
|
+
longer executes watchdog ticks. The daemon is the sole automatic watchdog executor,
|
|
118
|
+
warms active sessions on the same three-minute cadence, is gated by device-local
|
|
119
|
+
`watchdog.enabled`, and cleans failed/timeout routine process groups that are still
|
|
120
|
+
alive before they can overlap a replacement run. Source:
|
|
121
|
+
`apps/cli/src/lib/menubar/snapshot.ts`, `apps/cli/src/lib/daemon.ts`,
|
|
122
|
+
`apps/cli/src/lib/routine-process-cleanup.ts`.
|
|
123
|
+
|
|
124
|
+
- **Add Warp Agent CLI (Oz) as a harness (RUSH-2261).** `warp` is now a
|
|
125
|
+
first-class harness: `agents add warp`, `agents run warp`, `agents teams add
|
|
126
|
+
<team> warp`, resource sync, and `agents view` all work. The CLI command is
|
|
127
|
+
`oz` (the shared Warp binary); install is self-updating via
|
|
128
|
+
`brew install --cask oz` (macOS) / `oz-stable` apt|yum|pacman (Linux), config
|
|
129
|
+
lives under `~/.warp/`, the rules/context file is `AGENTS.md`, and auth is
|
|
130
|
+
`oz login` (browser OAuth) or a `WARP_API_KEY` token for headless/CI.
|
|
131
|
+
Capabilities are truthful and gated by `supports()`: MCP (Claude
|
|
132
|
+
`.mcp.json` schema at `~/.warp/.mcp.json`, stdio + http with headers) and
|
|
133
|
+
skills are on; hooks, allowlist, commands, plugins, subagents, workflows, and
|
|
134
|
+
memory are off (Oz exposes no matching install surface). Sessions are not
|
|
135
|
+
indexed — Oz stores conversations server-side (retrieved with auth via
|
|
136
|
+
`oz run conversation get <id>`), so there is no local transcript for
|
|
137
|
+
`agents sessions`. No usage bar — Oz exposes no usage/limits endpoint.
|
|
138
|
+
Source: `apps/cli/src/lib/{agents,exec,mcp}.ts`.
|
|
139
|
+
|
|
140
|
+
`scripts/release.sh` now runs orchestration in a fresh release-owned worktree, so a dirty shared checkout or feature branch no longer blocks or contaminates a release.
|
|
141
|
+
|
|
142
|
+
- **Plugin discovery warns instead of silently skipping a directory with no
|
|
143
|
+
`.claude-plugin/plugin.json` (RUSH-2270).** A `plugins/<name>/` directory missing
|
|
144
|
+
(or with a malformed) manifest was invisible to `agents plugins list`/`info`/`sync`,
|
|
145
|
+
`agents doctor`, and the marketplace materialize-into-version-homes step, with zero
|
|
146
|
+
diagnostic anywhere in the chain — no `agents sync`/`agents repo pull` could
|
|
147
|
+
surface it, since discovery dropped it before any of those ran. Found via a real
|
|
148
|
+
case: the `work` plugin merged to `phnx-labs/.agents-system` without its manifest
|
|
149
|
+
and sat invisible for a full merge cycle; the same fix run against this box's own
|
|
150
|
+
`~/.agents/plugins/duck` found it missing one too. `discoverPluginsInDir` now
|
|
151
|
+
writes one `agents-cli:` warning to stderr naming the directory and the missing
|
|
152
|
+
manifest path, matching the existing advisory-not-fatal pattern
|
|
153
|
+
`syncMarketplaceManifest` already uses for a malformed (as opposed to missing)
|
|
154
|
+
manifest. Source: `apps/cli/src/lib/plugins.ts`.
|
|
155
|
+
|
|
156
|
+
- **Muse login is recognized under `providers.meta` (balanced no longer signed_out).**
|
|
157
|
+
Live `muse login` writes `~/.config/muse/auth.json` as
|
|
158
|
+
`{ schema_version, providers: { meta: { access_token, user_email, … } } }`.
|
|
159
|
+
The presence detector only walked one object level, so it never saw the token
|
|
160
|
+
under `providers.meta` and reported signed-out after a successful OAuth —
|
|
161
|
+
`agents run muse` under balanced then failed with "excluded: 0.1.0
|
|
162
|
+
(signed_out)". Detection now recurses into nested provider slots and surfaces
|
|
163
|
+
`user_email` when present. Source: `apps/cli/src/lib/agents.ts`.
|
|
164
|
+
|
|
165
|
+
- **File-backed secret resolution now fails on decryption errors instead of treating unreadable ciphertext as an absent value (RUSH-2264).** A wrong `AGENTS_SECRETS_PASSPHRASE` or tampered encrypted value now reports the affected file-store item and stops before launching a consumer with an empty secret such as `HCLOUD_TOKEN`. Source: `apps/cli/src/lib/secrets/filestore.ts`, `apps/cli/src/lib/secrets/bundles.ts`.
|
|
166
|
+
|
|
167
|
+
## 1.22.24
|
|
168
|
+
|
|
169
|
+
- **`agents run --lease` now shares one warm pool across repositories by default (RUSH-2225).** Repo sandbox/CI `profile:` labels no longer split lease reuse into one idle box per repo; a dedicated lease pool is explicit with `.crabbox.yaml` `leaseProfile:`. An empty pool keeps its newly warmed box for later callers. Concurrent runs attach with crabbox `--reclaim` and launch with separate working trees, agent homes, and credential files, so callers share compute without clobbering run state. Switching repos re-syncs the checkout, trading cache latency for lower idle-compute cost. Source: `apps/cli/src/lib/crabbox/config.ts`, `apps/cli/src/lib/crabbox/lease.ts`, `apps/cli/src/commands/exec.ts`.
|
|
170
|
+
|
|
171
|
+
- **`agents sessions focus` recovers dead panes and shares the sessions browser's selectors (GH-2108).** A retained tmux `remain-on-exit` pane is probed through `#{pane_dead}` immediately before attach, so dead or missing panes no longer open a `Pane is dead` screen. `focus` accepts session ids, topic/path searches, `agent@version` selectors (including per-device `latest`/`oldest`), device, project/time, team/routine, skill/plugin, favorites, and the complete live-state union. Focus, resume, attach, and `run --resume` now use one recovery decision on the origin device: a healthy exact origin performs native resume; otherwise balanced selection chooses a healthy version of the same harness and sends `/continue <id>` to read the indexed transcript, including transcripts retained under version trash. Host-dispatched rows persist the dispatch host as their origin, and `attach` routes its detach-record cleanup there before resuming. No usable same-harness version fails with the device, origin version, and account-health reason. Source: `apps/cli/src/commands/focus.ts`, `apps/cli/src/commands/sessions-browser.ts`, `apps/cli/src/lib/session/recovery.ts`.
|
|
172
|
+
|
|
173
|
+
- **`agents secrets setup` no longer tells you to set `AGENTS_SECRETS_PASSPHRASE`, and
|
|
174
|
+
`docs/secrets.md` stops recommending the shell-rc export it flags as a leak
|
|
175
|
+
(RUSH-1968).** The file-backend note read `set AGENTS_SECRETS_PASSPHRASE for headless
|
|
176
|
+
encrypted-file reads`, implying a requirement; headless reads have worked with no
|
|
177
|
+
passphrase since the store began auto-provisioning a 0600 machine-local key, so it now
|
|
178
|
+
says so and names the real path. The docs were worse than merely stale: they called an
|
|
179
|
+
rc export *"Recommended for shared/CI machines"* and the 0600 key file *"identical to"*
|
|
180
|
+
it, which is how a master key ended up in `~/.zshenv` on seven worker boxes. That
|
|
181
|
+
equivalence is inverted — the key file is read by one process, an rc export is inherited
|
|
182
|
+
by every child and readable from `/proc/<pid>/environ` — and the section also named a
|
|
183
|
+
pre-#479 key path (`~/.agents/.cache/secrets/.passphrase`, now
|
|
184
|
+
`~/.agents/.secrets-key/passphrase`) and a TTY prompt step `getPassphrase` no longer
|
|
185
|
+
has. A new `docs-hygiene.test.ts` pins those claims against the shipped doc so the
|
|
186
|
+
advice cannot drift back. Source: `apps/cli/docs/secrets.md`,
|
|
187
|
+
`apps/cli/src/commands/setup-secrets.ts`, `apps/cli/src/lib/secrets/filestore.ts`.
|
|
188
|
+
|
|
189
|
+
- **`agents secrets push`/`pull`, `agents sync --secrets`, and `agents secrets
|
|
190
|
+
export --to-file` / `import --from-file` read `AGENTS_SYNC_PASSPHRASE` now;
|
|
191
|
+
`AGENTS_SECRETS_PASSPHRASE` is the file store's master key and nothing else
|
|
192
|
+
(RUSH-1968).** One variable meant two different secrets: the local file store's master
|
|
193
|
+
key, and the passphrase that seals a bundle for transport. The store stopped needing a
|
|
194
|
+
passphrase once it auto-provisioned a machine-local key, but headless `push`/`pull`
|
|
195
|
+
still hard-failed without one — so the only way to get unattended sync on a worker box
|
|
196
|
+
was to export the **master key** fleet-wide, handing every same-user process the key to
|
|
197
|
+
the whole store. Splitting them means a box that only needs headless sync sets
|
|
198
|
+
`AGENTS_SYNC_PASSPHRASE` and never has the master key in its environment. The old name
|
|
199
|
+
still works for sync as a deprecated fallback — warned exactly once per process, so a
|
|
200
|
+
`push --all` over many bundles does not flood stderr — so scripted CI and release
|
|
201
|
+
automation keep working across the upgrade. The headless error now names the new
|
|
202
|
+
variable (`A sync passphrase is required. Run from a TTY, or set
|
|
203
|
+
AGENTS_SYNC_PASSPHRASE.`), and `agents sync`'s skip line with it — it previously read
|
|
204
|
+
`no passphrase available`, naming nothing an operator could act on. Note the legacy
|
|
205
|
+
fallback only works where that value is also the store's master key, since the old name
|
|
206
|
+
still keys the store; that coupling is the thing being retired. Resolution moved to
|
|
207
|
+
one chokepoint so the once-per-process promise holds rather than being per-call-site. Also
|
|
208
|
+
corrects `SEC-29a`, which claimed the variable applied "exclusively" to the file and
|
|
209
|
+
age-vault backends: the age-vault backend never reads it (it is gated by `agents
|
|
210
|
+
login`), and sync plus the portable `--to-file` envelope were two more consumers — the
|
|
211
|
+
new `SEC-29b` states the split as a normative invariant. Source:
|
|
212
|
+
`apps/cli/src/lib/secrets/sync-passphrase.ts`, `apps/cli/src/commands/secrets-sync.ts`,
|
|
213
|
+
`apps/cli/src/commands/sync.ts`, `apps/cli/src/lib/sync-umbrella.ts`.
|
|
214
|
+
|
|
215
|
+
- Added `--team` as an alias for `agents sessions --teams`. (RUSH-1995)
|
|
216
|
+
- Added absolute `agents secrets unlock --until <date>` expiry, mutually exclusive with relative `--ttl`. (RUSH-1960)
|
|
217
|
+
- Added persisted per-agent-version reasoning effort defaults and surfaced them in `agents view`. (RUSH-2005)
|
|
218
|
+
|
|
219
|
+
- **`agents feed` no longer crashes when the session index is locked (RUSH-2006).**
|
|
220
|
+
Outcome enrichment calls `discoverSessions` against `sessions.db`; under concurrent
|
|
221
|
+
scanner/daemon pressure that open can throw `SQLITE_BUSY` / "database is locked"
|
|
222
|
+
and take down the whole feed. A lock error now degrades to an empty meta set with a
|
|
223
|
+
stderr warning so blocks still render. Source: `apps/cli/src/commands/feed.ts`.
|
|
224
|
+
|
|
225
|
+
- **`agents events --event` / filtered activity reads no longer miss matches under
|
|
226
|
+
`--limit` (RUSH-2093).** The unified reader capped activity records *before*
|
|
227
|
+
applying the event-type filter, so a rare match older than the newest-N routine
|
|
228
|
+
rows (e.g. one `pr.opened` under twenty `file.edited`) was silently dropped. Event
|
|
229
|
+
types are now passed into `readRecentActivity` so the cap counts matching rows; a
|
|
230
|
+
non-`activity` `--module` skips the activity half entirely. Source:
|
|
231
|
+
`apps/cli/src/lib/event-stream.ts`.
|
|
232
|
+
|
|
233
|
+
- **`agents mcp add` no longer strips comments from `agents.yaml`.** The
|
|
234
|
+
write path (`writeManifest` / `serializeManifest` in `src/lib/manifest.ts`)
|
|
235
|
+
used plain `yaml.stringify`, which dropped every hand-written comment on
|
|
236
|
+
every add. It now round-trips via `yaml.parseDocument` and edits only the
|
|
237
|
+
keys that changed — the same approach `serializeCentral` already uses for
|
|
238
|
+
the central meta file (RUSH-2090).
|
|
239
|
+
|
|
240
|
+
- **Hook cache refresh is now single-flight, backs off on failure, and logs its
|
|
241
|
+
real exit code (RUSH-2121).** The background refresh in the hook cache shim
|
|
242
|
+
acquires an atomic `mkdir` lock, so concurrent hook invocations no longer
|
|
243
|
+
stampede into N parallel refreshes; a persistently-failing refresh records a
|
|
244
|
+
failure timestamp and is skipped until a 60s backoff elapses instead of
|
|
245
|
+
re-firing on every invocation; and the refresh now emits a `hook.cache.refresh`
|
|
246
|
+
event carrying the subshell's real exit code instead of a hardcoded `0`.
|
|
247
|
+
Source: `apps/cli/src/lib/hooks/cache.ts`.
|
|
248
|
+
|
|
249
|
+
- **`agents sync --host all` no longer fails every peer with `unknown option
|
|
250
|
+
'--json'`.** Fleet fan-out injects `--json` on each remote so the roster can
|
|
251
|
+
parse per-device results, but `sync` never registered the flag. Register
|
|
252
|
+
`--json` on `agents sync` and emit a machine-readable umbrella/agent/repo
|
|
253
|
+
payload so peers accept the flag and return parseable stdout (RUSH-2216).
|
|
254
|
+
Source: `apps/cli/src/commands/sync.ts`.
|
|
255
|
+
|
|
256
|
+
- **A wedged keychain can no longer pile up `agents` processes (RUSH-2231, RUSH-2232).**
|
|
257
|
+
A stalled macOS `coreauthd` used to hang the signed keychain helper's XPC receive
|
|
258
|
+
forever, so every secrets-touching `agents` command blocked and dozens of helper
|
|
259
|
+
processes plus their `<defunct>` zombies accumulated and made the machine sluggish.
|
|
260
|
+
Two fixes: **(Layer 1)** every keychain-helper `spawnSync` is now bounded and
|
|
261
|
+
hard-killed (SIGKILL) on timeout — 8s for never-prompt verbs (`has`/`set`/`delete`/
|
|
262
|
+
`list*`), 60s for the may-prompt reads (`get`/`get-batch`/`migrate-*`) — surfacing a
|
|
263
|
+
typed timeout error and arming the read back-off instead of hanging.
|
|
264
|
+
**(Layer 3)** the daemon reaps the backlog: a 5-minute tick kills orphaned helpers
|
|
265
|
+
(reparented to PID 1, past a 30s grace) and, two-sweep-debounced, the helper child of
|
|
266
|
+
an `agents` proc stuck past 90s (child first, escalating to the parent only if it
|
|
267
|
+
stays wedged) — never touching a process whose start-time can't be captured or whose
|
|
268
|
+
path doesn't match the helper. Any keychain touch now also opportunistically starts
|
|
269
|
+
the daemon so the reaper runs even on a secrets-only box. Source:
|
|
270
|
+
`apps/cli/src/lib/secrets/index.ts`, `apps/cli/src/lib/secrets/reaper.ts`,
|
|
271
|
+
`apps/cli/src/lib/daemon.ts`.
|
|
272
|
+
|
|
273
|
+
- **`agents inspect` and `agents doctor` now report harness-scoped hook inventory as capable, on-disk, wired, and unmanaged state.** Their JSON output carries the same state sets from `getResourceInventory`, so a harness with hook files or native wiring no longer collapses to a misleading `Hooks (0)` summary. Inventory is keyed by agent harness and installed version, not by configured model. Source: `apps/cli/src/lib/resource-inventory.ts`, `apps/cli/src/commands/inspect.ts`, `apps/cli/src/lib/doctor-diff.ts`.
|
|
274
|
+
|
|
275
|
+
- **Fix: the keychain-helper reaper never reaped on macOS.** The daemon reaper shelled `ps -o etimes` — a GNU/Linux procps keyword that macOS `ps` rejects with a non-zero exit — so `execFileSync` threw on every tick and `reapOrphanedKeychainProcesses` returned `reaped: 0` on its only supported platform, leaving orphaned/wedged `Agents CLI` helper processes to pile up. Switched to the portable BSD `etime` keyword (`[[dd-]hh:]mm:ss`) with a parser to seconds. This also un-quarantines the darwin integration test that #2153 had to `it.skip` to unblock releases: that test's symlink fixture was correct all along — it read `reaped: 0` only because the reaper's own `ps etimes` call threw before parsing anything. Verified on macOS 15.4.1: 20/20 reaper tests pass, the integration test reaping a real orphaned sleeper. Source: `apps/cli/src/lib/secrets/reaper.ts`, `reaper.test.ts`.
|
|
276
|
+
|
|
277
|
+
- **`agents modes [agent[@version]]` lists the permission modes a harness accepts.** The modes analog of `agents models`: for Claude / Codex / Cursor / …, shows which `--mode plan|edit|auto|skip` values work, the native CLI flags, the native default (`*`), any configured `run.defaults` mode, and degrade notes (e.g. plan→edit on Antigravity). `agents inspect` also prints the mode list next to capabilities, and `agents run --help` / `agents models` point at the new command. Source: `apps/cli/src/commands/modes.ts`, `apps/cli/src/lib/agent-modes.ts`.
|
|
278
|
+
|
|
279
|
+
- **`agents insights --all` now works as an alias for `--since all`.** It previously
|
|
280
|
+
exited with `unknown option '--all'` — a hard failure in the middle of a report the
|
|
281
|
+
user asked for, on the spelling most people reach for first. An explicit `--since`
|
|
282
|
+
still wins, so `--all --since 7d` resolves to 7d rather than silently contradicting
|
|
283
|
+
itself. Source: `apps/cli/src/commands/insights.ts`.
|
|
284
|
+
|
|
285
|
+
- **Coexisting agents-cli installs no longer fight over the menu-bar helper.** The
|
|
286
|
+
helper lives at one path in Application Support, but every install on the box runs
|
|
287
|
+
the startup self-heal, and both the version stamp and the plist's baked
|
|
288
|
+
`AGENTS_ENTRY` record whichever copy acted last — so each copy read the others'
|
|
289
|
+
marks as drift and recopied the app bundle over them. Recopying replaces the
|
|
290
|
+
executable under the running helper and kills it, launchd `KeepAlive` restarts it,
|
|
291
|
+
and the next copy repeats it: a new pid every 5-15 seconds, 578 launches in one
|
|
292
|
+
observed helper log, and a status item that never stayed visible while
|
|
293
|
+
`agents menubar status` still reported `running: yes` (a pid always existed). The
|
|
294
|
+
plist's `AGENTS_ENTRY` is now treated as the owner and only the owner reinstalls
|
|
295
|
+
freely; a same-install upgrade keeps its entry path, so `npm update` still installs
|
|
296
|
+
the new helper normally. Another install still gets there — immediately if the
|
|
297
|
+
recorded owner is gone from disk, otherwise at most once an hour — so a stale copy
|
|
298
|
+
that merely still sits on disk can't freeze the menu bar for whichever install the
|
|
299
|
+
user actually upgrades. Repairs (a missing helper executable, a Developer-ID heal)
|
|
300
|
+
are never gated, and `agents menubar setup` bypasses the gate as the immediate
|
|
301
|
+
manual fix. An ad-hoc/dev-signed build never wins the timed takeover — recopying
|
|
302
|
+
an un-notarized bundle over a good one gets it rejected as "damaged" — though it
|
|
303
|
+
can still adopt a helper whose owner is gone. Two installs that are both invoked
|
|
304
|
+
regularly still trade ownership at the cooldown, so the helper restarts about once
|
|
305
|
+
an hour until one is removed; that is bounded rather than converged, and the real
|
|
306
|
+
fix remains a single install. `agents menubar status` no longer promises that a
|
|
307
|
+
stale helper "runs on next `agents` startup", which is not guaranteed on a
|
|
308
|
+
multi-install box. Fixes #2109. Source:
|
|
309
|
+
`apps/cli/src/lib/menubar/install-menubar.ts`.
|
|
310
|
+
|
|
311
|
+
- **Muse Code global binary is visible to `agents view` / `isVersionInstalled`.**
|
|
312
|
+
Muse installs a single self-updating launcher at `~/.local/bin/muse` (same
|
|
313
|
+
shape as droid), but `getBinaryPath` still resolved a version-home
|
|
314
|
+
`node_modules/.bin/muse` that never exists. After `agents import muse` /
|
|
315
|
+
`agents add muse`, version dirs now resolve to that global path so managed
|
|
316
|
+
view, collapse, and live-version bookkeeping match what actually executes;
|
|
317
|
+
install no longer writes a self-referential shim symlink. Source:
|
|
318
|
+
`apps/cli/src/lib/versions.ts`.
|
|
319
|
+
|
|
320
|
+
- **Muse multi-version isolation matches Claude/Codex (XDG pin, not bare symlink).**
|
|
321
|
+
Claude/Codex isolate per version with `CLAUDE_CONFIG_DIR` / `CODEX_HOME`.
|
|
322
|
+
Muse has no dedicated config env; it reads `$XDG_CONFIG_HOME/muse` and
|
|
323
|
+
`$XDG_DATA_HOME/muse`. After `agents import muse`, `~/.config/muse` is a
|
|
324
|
+
symlink into the version home — Muse refuses that path with
|
|
325
|
+
`Agent Definition filesystem source failed: SymlinkOrReparse` and exits 1
|
|
326
|
+
(the Zion `agents run muse@0.1.0` failure). Managed launches now pin
|
|
327
|
+
`XDG_CONFIG_HOME` + `XDG_DATA_HOME` into the version home from `buildExecEnv`,
|
|
328
|
+
the main shim, and versioned aliases (`muse@0.1.0`), the same way Claude pins
|
|
329
|
+
`CLAUDE_CONFIG_DIR`. Muse is also listed in `CONFIG_ENV_ISOLATED_AGENTS` so
|
|
330
|
+
`--isolated` installs are honest. Source: `apps/cli/src/lib/{exec,shims}.ts`.
|
|
331
|
+
|
|
332
|
+
- **Scheduled routines now run on a per-account `claude setup-token` when one is
|
|
333
|
+
provisioned, instead of throwing it away.** `buildRoutineSpawnEnv` unconditionally
|
|
334
|
+
deleted `CLAUDE_CODE_OAUTH_TOKEN`, so even after `buildExecEnv` injected a long-lived,
|
|
335
|
+
non-rotating setup-token from the reserved file-backed `auth` bundle
|
|
336
|
+
(`resolveClaudeSetupToken`), a routine still fell back to the version home's rotating
|
|
337
|
+
`.credentials.json` login. With one Claude account signed into several version homes
|
|
338
|
+
(or several fleet boxes), that rotating login is the single-use-refresh-token
|
|
339
|
+
revocation storm — one home's refresh silently revokes every sibling copy, so an
|
|
340
|
+
unattended routine keeps landing on a just-revoked token and dies with `auth_failed:
|
|
341
|
+
OAuth access token has been revoked` / `Please run /login`, even though `agents view`
|
|
342
|
+
shows the account healthy. The delete now distinguishes the two flavours: a
|
|
343
|
+
per-account setup-token (keyed to this home's own account) is re-asserted and KEPT; an
|
|
344
|
+
inherited *ambient* token (a shared value the daemon env happened to carry — the
|
|
345
|
+
RUSH-1822 fleet-logout path) is still stripped so a routine never runs on it.
|
|
346
|
+
Provision the token with `/fleet:mint-auth`. Source:
|
|
347
|
+
`apps/cli/src/lib/runner.ts` (`buildRoutineSpawnEnv`).
|
|
348
|
+
|
|
349
|
+
- **Resolved secrets no longer appear in `ps` for tmux-launched agents
|
|
350
|
+
(RUSH-2100).** An interactive `agents run` wraps the agent in tmux via
|
|
351
|
+
`exec env K=V … <agent>`, which put the entire exec env — every resolved
|
|
352
|
+
secrets-bundle value — into the pane's command line, readable by any process of
|
|
353
|
+
the same user. On one fleet box six live processes carried
|
|
354
|
+
`AGENTS_SECRETS_PASSPHRASE`, the key that decrypts every file-backed bundle on
|
|
355
|
+
that machine. The pane now sources a `0600` env file and unlinks it before
|
|
356
|
+
`exec`, so only the file path is argv-visible; a missing file aborts the pane
|
|
357
|
+
rather than launching half-configured. Every key routes through the file, not a
|
|
358
|
+
curated "secret-bearing" subset, so a newly added credential is covered without
|
|
359
|
+
anyone maintaining a list. Source: `apps/cli/src/lib/exec.ts`,
|
|
360
|
+
`apps/cli/docs/specifications.md` (SEC-8a).
|
|
361
|
+
|
|
3
362
|
## 1.22.23
|
|
4
363
|
|
|
5
364
|
- **Daemon-warmed cross-surface session-status cache (RUSH-2062).** Menubar,
|
package/README.md
CHANGED
|
@@ -35,6 +35,8 @@
|
|
|
35
35
|
<a href="https://dev.meta.ai/docs/muse-code" title="Meta Muse Code"><strong>Muse</strong></a>
|
|
36
36
|
|
|
37
37
|
<a href="https://omp.sh" title="Oh My Pi"><strong>Pi</strong></a>
|
|
38
|
+
|
|
39
|
+
<a href="https://docs.warp.dev/reference/cli" title="Warp Agent CLI (Oz)"><strong>Warp</strong></a>
|
|
38
40
|
</p>
|
|
39
41
|
|
|
40
42
|
https://agents-cli.sh/demo.mp4
|
|
@@ -147,6 +149,13 @@ agents run antigravity "Write tests for the fixed code"
|
|
|
147
149
|
|
|
148
150
|
Each resolves to the project-pinned version with skills, MCP servers, and permissions already synced. Single-typo names auto-correct across every command — `agents view cladue` resolves to `claude`, `agents add codx@latest` to `codex`.
|
|
149
151
|
|
|
152
|
+
`agents run claude "task" --lease` reuses one shared warm crabbox pool across
|
|
153
|
+
repositories by default. Concurrent runs share the box but execute in isolated
|
|
154
|
+
`~/workspaces/<repo>-<run>` directories with separate agent homes and credential
|
|
155
|
+
files. Add `leaseProfile: private-hot-box` to
|
|
156
|
+
`.crabbox.yaml` only when a repo intentionally needs a dedicated warm pool;
|
|
157
|
+
cross-repo reuse trades re-sync latency for lower idle-compute cost.
|
|
158
|
+
|
|
150
159
|
### Rate-limited? Keep working.
|
|
151
160
|
|
|
152
161
|
```bash
|
|
@@ -303,6 +312,7 @@ agents sessions --idle # stopped between turns (fleet-wide)
|
|
|
303
312
|
agents sessions --orphan # agent outlived its terminal client
|
|
304
313
|
agents sessions --crashed # terminal and agent disappeared uncleanly
|
|
305
314
|
agents sessions focus a1b2c3d4 # jump back into one — attach in place, or resume
|
|
315
|
+
agents sessions focus claude@latest --device yosemite-s0 # pick latest there
|
|
306
316
|
```
|
|
307
317
|
|
|
308
318
|
On a terminal, `agents sessions --active` (and a bare `agents sessions`) open the **interactive session browser** — one filter you drive with single keys, re-pulled live across the fleet:
|
|
@@ -313,7 +323,7 @@ On a terminal, `agents sessions --active` (and a bare `agents sessions`) open th
|
|
|
313
323
|
| `r` | running only | `--active` |
|
|
314
324
|
| `f` | favorites only | `--favorites` |
|
|
315
325
|
| `*` | star / unstar the highlighted session | `agents sessions favorite <id>` |
|
|
316
|
-
| `c` | team sessions | `--teams` |
|
|
326
|
+
| `c` | team sessions | `--team` (alias: `--teams`) |
|
|
317
327
|
| `a` | agent (cycles) | `-a` |
|
|
318
328
|
| `d` | device (cycles) | `--device` |
|
|
319
329
|
| `p` | this repo ↔ all dirs | `--all` |
|
|
@@ -332,7 +342,7 @@ Filters **stack** (they AND together), the active set shows in the header, and t
|
|
|
332
342
|
| --- | --- |
|
|
333
343
|
|  |  |
|
|
334
344
|
|
|
335
|
-
Each live session resolves to `working`, `waiting_input` (with why -- a question, a plan review, or a permission prompt), `idle`, or a lifecycle state such as `orphaned`, `crashed`, `closed`, `abandoned`, `queued`, or `unknown`. Pass the matching flag (`--working`, `--idle`, `--waiting`, `--orphan`, `--crashed`, `--closed`, `--abandoned`, `--queued`, `--unknown`) directly; each implies `--active`, and several flags form a union. The fleet fan-out is already the default; `--local` opts out. `--all` instead widens historical directory and time scope. Rows also carry badges for the PR, worktree, and ticket. `agents sessions focus [
|
|
345
|
+
Each live session resolves to `working`, `waiting_input` (with why -- a question, a plan review, or a permission prompt), `idle`, or a lifecycle state such as `orphaned`, `crashed`, `closed`, `abandoned`, `queued`, or `unknown`. Pass the matching flag (`--working`, `--idle`, `--waiting`, `--orphan`, `--crashed`, `--closed`, `--abandoned`, `--queued`, `--unknown`) directly; each implies `--active`, and several flags form a union. The fleet fan-out is already the default; `--local` opts out. `--all` instead widens historical directory and time scope. Rows also carry badges for the PR, worktree, and ticket. `agents sessions focus [selector]` accepts the same agent/version, device, time, team, project, skill/plugin, favorite, and live-state filters as the session browser. A unique id focuses directly; an agent/version or text selector always opens the preview picker. Immediately before attach it checks the tmux pane process: a living pane is joined in place, while a dead/missing pane enters recovery instead of showing tmux's `Pane is dead` screen.
|
|
336
346
|
|
|
337
347
|
Landing on a session cold? `agents sessions <id>` prints a catch-up digest: an inferred title, files changed grouped by directory (created / modified / deleted), a histogram of which tools did the work (including parsed Bash commands -- `git`, `npm`, `ffmpeg`, `ssh`, and so on), and the last test verdict -- the signals to reload a task in seconds.
|
|
338
348
|
|
|
@@ -351,11 +361,11 @@ agents resume 019fd0c8-b3e9-77a2-a1a4-444698c4d897 # original harness/version/d
|
|
|
351
361
|
agents run auto --resume 019fd0c8-b3e9-77a2-a1a4-444698c4d897 # adapt if its account is unavailable
|
|
352
362
|
```
|
|
353
363
|
|
|
354
|
-
`agents sessions resume` reopens several sessions in whatever terminal you're in -- auto-detected across iTerm, Ghostty, tmux, and the VSCodium agent-terminal, or forced with `--iterm` / `--ghostty` / `--tmux` / `--vscodium`. `agents resume <id>` resumes one session without requiring you to name its harness: exact IDs take a local SQLite fast path, then resolve fleet-wide and
|
|
364
|
+
`agents sessions resume` reopens several sessions in whatever terminal you're in -- auto-detected across iTerm, Ghostty, tmux, and the VSCodium agent-terminal, or forced with `--iterm` / `--ghostty` / `--tmux` / `--vscodium`. `agents resume <id>` resumes one session without requiring you to name its harness: exact IDs take a local SQLite fast path, then resolve fleet-wide and recover on the source device. If the origin version is installed, signed in, and healthy, its isolated home performs native resume. Otherwise a healthy version of the **same harness** starts with `/continue <id>`, which reads the indexed transcript even when the old version home is retained under version trash. It never native-resumes from a different isolated home. Back them with **tmux** and the runs turn durable: detach, close your editor, reboot the GUI -- the session is still alive to `agents tmux attach`. The whole `agents tmux` subsystem (persistent multiplexer sessions that survive editor restarts and can be shared with other tools) sits underneath.
|
|
355
365
|
|
|
356
366
|
### Send an agent to the background — and bring it back
|
|
357
367
|
|
|
358
|
-
Running 30 agents and drowning in terminal tabs? `agents sessions detach <id>` stops a session's interactive process and keeps it working **headless** in the background -- it drives its task to done unattended, no tab, lower cost. `agents sessions attach <id>` brings it back
|
|
368
|
+
Running 30 agents and drowning in terminal tabs? `agents sessions detach <id>` stops a session's interactive process and keeps it working **headless** in the background -- it drives its task to done unattended, no tab, lower cost. `agents sessions attach <id>` brings it back through the same origin-device recovery decision: native resume in the exact healthy origin home, or same-harness `/continue` when that home is unavailable, with the full indexed history (including whatever it did while backgrounded).
|
|
359
369
|
|
|
360
370
|
```
|
|
361
371
|
agents sessions detach a1b2c3d4 # go headless in the background, keep working
|
|
@@ -404,7 +414,7 @@ agents watchdog --nudge # actually inject "Continue." into the stalled split
|
|
|
404
414
|
agents watchdog --watch # daemon loop: a tick every --interval
|
|
405
415
|
```
|
|
406
416
|
|
|
407
|
-
`agents watchdog` detects a stalled session, resolves the *exact* terminal split it lives in (tmux, iTerm, VSCodium, or a raw pty), and injects a nudge -- `Continue.` by default, or set `--text`. It's dry by default; `--nudge` acts on a single tick
|
|
417
|
+
`agents watchdog` detects a stalled session, resolves the *exact* terminal split it lives in (tmux, iTerm, VSCodium, or a raw pty), and injects a nudge -- `Continue.` by default, or set `--text`. It's dry by default; `--nudge` acts on a single tick. `agents watchdog on|off` controls the device-local daemon pass, which runs once every three minutes. Steer a single run with `agents watchdog policy <id> off | keep | handsoff`.
|
|
408
418
|
|
|
409
419
|
A stalled session whose tail shows a hard account limit ("You've hit your weekly limit · resets …") is **rotated in place** instead of nudged: the watchdog gates on the same healthy-account selection `agents run auto` makes (zero healthy → one skip event per cooldown window, terminal untouched), injects the harness's exit sequence, relaunches `agents run auto --interactive --session-id <uuid>` in the *same* tab, then replays the old session's resume once the new TUI is live. Default on; `agents watchdog rotate off` disables it (nudging stays on).
|
|
410
420
|
|
|
@@ -608,10 +618,10 @@ Team state is observable via `agents teams list --json` / `agents teams status -
|
|
|
608
618
|
|
|
609
619
|
## Cloud
|
|
610
620
|
|
|
611
|
-
Some work shouldn't tie up your laptop. `agents cloud run` hands a task to a managed provider that clones the repo, plans, implements, tests, and opens a PR -- while your terminal stays free.
|
|
621
|
+
Some work shouldn't tie up your laptop. `agents cloud run` hands a task to a managed provider that clones the repo, plans, implements, tests, and opens a PR -- while your terminal stays free. The `host` provider dispatches the same way onto machines you own: `agents cloud run "…" --host gpu-box` (tasks track in `agents cloud ps` and `agents hosts ps` alike).
|
|
612
622
|
|
|
613
623
|
<p align="center">
|
|
614
|
-
<img src="assets/cloud.svg" alt="agents cloud run dispatches one prompt to a managed provider (Rush, Codex, Factory, or Antigravity) that
|
|
624
|
+
<img src="assets/cloud.svg" alt="agents cloud run dispatches one prompt to a managed provider (Rush, Codex, Cursor, Factory, or Antigravity) that runs while you keep working" width="100%" />
|
|
615
625
|
</p>
|
|
616
626
|
|
|
617
627
|
```bash
|
|
@@ -625,7 +635,7 @@ agents cloud message <id> "also update the changelog" # steer it mid-run
|
|
|
625
635
|
agents cloud cancel <id>
|
|
626
636
|
```
|
|
627
637
|
|
|
628
|
-
|
|
638
|
+
Five managed backends behind one interface (`agents cloud providers`):
|
|
629
639
|
|
|
630
640
|
| Provider | What runs | Notes |
|
|
631
641
|
|---|---|---|
|
|
@@ -633,6 +643,7 @@ Four managed backends behind one interface (`agents cloud providers`):
|
|
|
633
643
|
| `codex` | A pre-built Codex Cloud environment | Target it with `--env`. |
|
|
634
644
|
| `factory` | `droid exec` on a cloud VM | Computer-use; pick the box with `--computer`. |
|
|
635
645
|
| `antigravity` | Gemini managed agents | Antigravity harness in a remote sandbox. |
|
|
646
|
+
| `cursor` | Cursor Cloud Agents | v1 REST API with repo, status, SSE, cancel, and follow-up runs. |
|
|
636
647
|
|
|
637
648
|
Auto-routes each `--agent` to its native cloud, or pin the backend with `--provider`. Instead of dispatching now, register a run as an **event trigger** with `--on pull_request` (also `push`, `issue_comment`, `workflow_run`) -- it persists as a trigger-bound routine that fires on the event. `--json` on every subcommand for scripting.
|
|
638
649
|
|
package/dist/bin/agents
ADDED
|
Binary file
|
|
@@ -6,5 +6,7 @@
|
|
|
6
6
|
* history, the exact inverse of `agents sessions detach`.
|
|
7
7
|
*/
|
|
8
8
|
import type { Command } from 'commander';
|
|
9
|
+
import type { SessionMeta } from '../lib/session/types.js';
|
|
9
10
|
export declare function registerAttachCommand(program: Command): void;
|
|
10
11
|
export declare function attachAction(id: string): Promise<void>;
|
|
12
|
+
export declare function attachRecoveryArgs(session: Pick<SessionMeta, 'id'>): string[];
|
package/dist/commands/attach.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { runOnPeer } from '../lib/session/remote-list.js';
|
|
3
|
+
import { sessionRecoveryPeer } from '../lib/session/recovery.js';
|
|
4
|
+
import { resolveSessionMetadataValue, resumeSessionInPlace } from './sessions.js';
|
|
4
5
|
import { readDetachRecord, clearDetachRecord, isHeadlessAlive } from '../lib/session/detached.js';
|
|
5
6
|
export function registerAttachCommand(program) {
|
|
6
7
|
program
|
|
@@ -12,16 +13,37 @@ export function registerAttachCommand(program) {
|
|
|
12
13
|
});
|
|
13
14
|
}
|
|
14
15
|
export async function attachAction(id) {
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
16
|
+
const outcome = await resolveSessionMetadataValue(id);
|
|
17
|
+
if (outcome.kind === 'partial') {
|
|
18
|
+
console.error(chalk.red(`Could not resolve session while these devices were unavailable: ${outcome.failedPeers.join(', ')}`));
|
|
19
|
+
process.exitCode = 2;
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
if (outcome.kind === 'not-found') {
|
|
20
23
|
console.error(chalk.red(`No session matching "${id}".`));
|
|
21
24
|
console.error(chalk.gray(' See your sessions: agents sessions'));
|
|
22
25
|
process.exitCode = 1;
|
|
23
26
|
return;
|
|
24
27
|
}
|
|
28
|
+
if (outcome.kind === 'ambiguous') {
|
|
29
|
+
console.error(chalk.red(`"${id}" matches ${outcome.candidates.length} sessions. Pass the full session id.`));
|
|
30
|
+
process.exitCode = 1;
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
const meta = outcome.session;
|
|
34
|
+
// Route the WHOLE attach operation to the origin, not just its eventual
|
|
35
|
+
// resume. The detach record and headless PID are device-local; clearing them
|
|
36
|
+
// here would leave the real background continuation running beside a second
|
|
37
|
+
// process on the owning machine.
|
|
38
|
+
const peer = sessionRecoveryPeer(meta);
|
|
39
|
+
if (peer) {
|
|
40
|
+
const routed = await runOnPeer(attachRecoveryArgs(meta), peer, { tty: true });
|
|
41
|
+
if (routed === 'no-target') {
|
|
42
|
+
console.error(chalk.red(`Cannot attach ${meta.shortId}: origin device ${peer} is not a registered reachable peer.`));
|
|
43
|
+
process.exitCode = 1;
|
|
44
|
+
}
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
25
47
|
// If it's backgrounded, stop the headless continuation first so two processes
|
|
26
48
|
// don't resume the same transcript at once.
|
|
27
49
|
const rec = readDetachRecord(meta.id);
|
|
@@ -39,3 +61,6 @@ export async function attachAction(id) {
|
|
|
39
61
|
console.log(chalk.gray(`Attaching ${meta.agent} ${meta.id.slice(0, 8)} — resuming interactively…`));
|
|
40
62
|
await resumeSessionInPlace(meta);
|
|
41
63
|
}
|
|
64
|
+
export function attachRecoveryArgs(session) {
|
|
65
|
+
return ['sessions', 'attach', session.id];
|
|
66
|
+
}
|
package/dist/commands/cloud.js
CHANGED
|
@@ -25,14 +25,15 @@ export function statusColor(status) {
|
|
|
25
25
|
export function registerCloudCommands(program) {
|
|
26
26
|
const cloud = program
|
|
27
27
|
.command('cloud', { hidden: true })
|
|
28
|
-
.description('Dispatch and manage cloud agent tasks across providers (Rush, Codex, Factory, Antigravity).')
|
|
28
|
+
.description('Dispatch and manage cloud agent tasks across providers (Rush, Codex, Cursor, Factory, Antigravity, Host).')
|
|
29
29
|
.addHelpText('after', `
|
|
30
30
|
Each agent runs in its own cloud. Pass --agent and the provider is auto-selected
|
|
31
|
-
(claude→rush, codex→codex, droid→factory, antigravity→antigravity); --provider overrides.
|
|
31
|
+
(claude→rush, codex→codex, cursor→cursor, droid→factory, antigravity→antigravity); --provider overrides.
|
|
32
32
|
|
|
33
33
|
Providers:
|
|
34
34
|
rush Rush Cloud — Claude against a GitHub repo + branch → PR
|
|
35
35
|
codex Codex Cloud — runs in a pre-built Codex environment (--env)
|
|
36
|
+
cursor Cursor Cloud Agents — v1 REST API, with optional GitHub repos
|
|
36
37
|
factory Factory Droid Computer — droid exec on a cloud VM (--computer)
|
|
37
38
|
antigravity Gemini Managed Agents — Antigravity harness in a remote sandbox
|
|
38
39
|
|
|
@@ -49,6 +50,9 @@ Examples:
|
|
|
49
50
|
# Codex Cloud against a saved environment
|
|
50
51
|
agents cloud run "add pytest fixtures for the new billing module" --provider codex --env env_a1b2c3 --agent codex --timeout 30m
|
|
51
52
|
|
|
53
|
+
# Cursor Cloud Agents against a GitHub repository
|
|
54
|
+
agents cloud run "fix the flaky parser test" --agent cursor --repo acme/example
|
|
55
|
+
|
|
52
56
|
# Factory pod targeting a specific computer (Droid)
|
|
53
57
|
agents cloud run "QA the new onboarding flow end-to-end" --provider factory --computer linux-vm-1 --agent droid
|
|
54
58
|
|
|
@@ -74,9 +78,9 @@ Examples:
|
|
|
74
78
|
cloud
|
|
75
79
|
.command('run [prompt]')
|
|
76
80
|
.description('Dispatch a task to a cloud agent.')
|
|
77
|
-
.option('--provider <id>', 'Cloud backend: rush, codex, factory, antigravity, host (overrides agent auto-routing)')
|
|
78
|
-
.option('--agent <name>', 'Agent to run: claude, codex, droid, antigravity (auto-routes to its native cloud)')
|
|
79
|
-
.option('--repo <owner/repo>', 'GitHub repository. Repeatable for multi-repo dispatch (Rush Cloud
|
|
81
|
+
.option('--provider <id>', 'Cloud backend: rush, codex, cursor, factory, antigravity, host (overrides agent auto-routing)')
|
|
82
|
+
.option('--agent <name>', 'Agent to run: claude, codex, cursor, droid, antigravity (auto-routes to its native cloud)')
|
|
83
|
+
.option('--repo <owner/repo>', 'GitHub repository. Repeatable for multi-repo dispatch (Rush or Cursor Cloud).', (value, previous) => {
|
|
80
84
|
const acc = Array.isArray(previous) ? previous : [];
|
|
81
85
|
acc.push(value);
|
|
82
86
|
return acc;
|
|
@@ -47,11 +47,13 @@ export function registerDefaultsCommands(program) {
|
|
|
47
47
|
.description('Set defaults for an agent/version selector')
|
|
48
48
|
.option('--mode <mode>', "Default mode: plan, edit, auto, skip. 'full' accepted as alias for skip.")
|
|
49
49
|
.option('--model <model>', 'Default model or model alias, forwarded via --model')
|
|
50
|
+
.option('--effort <effort>', 'Default reasoning effort: low, medium, high, xhigh, max, or auto')
|
|
50
51
|
.action((selector, options) => {
|
|
51
52
|
try {
|
|
52
53
|
const entry = setRunDefault(selector, {
|
|
53
54
|
...(options.mode !== undefined ? { mode: options.mode } : {}),
|
|
54
55
|
...(options.model !== undefined ? { model: options.model } : {}),
|
|
56
|
+
...(options.effort !== undefined ? { effort: options.effort } : {}),
|
|
55
57
|
});
|
|
56
58
|
console.log(chalk.green('Set run default:'));
|
|
57
59
|
console.log(` ${formatRunDefaultEntry(entry)}`);
|