@phnx-labs/agents-cli 1.20.78 → 1.20.83

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.
Files changed (183) hide show
  1. package/CHANGELOG.md +595 -0
  2. package/README.md +26 -26
  3. package/dist/bin/agents +0 -0
  4. package/dist/commands/activity.d.ts +9 -0
  5. package/dist/commands/activity.js +153 -24
  6. package/dist/commands/apply.js +11 -4
  7. package/dist/commands/cli.js +1 -1
  8. package/dist/commands/commands.d.ts +1 -1
  9. package/dist/commands/commands.js +7 -6
  10. package/dist/commands/defaults.js +3 -11
  11. package/dist/commands/doctor.d.ts +66 -0
  12. package/dist/commands/doctor.js +596 -33
  13. package/dist/commands/events.js +1 -1
  14. package/dist/commands/exec.js +24 -5
  15. package/dist/commands/feed.d.ts +4 -0
  16. package/dist/commands/feed.js +87 -11
  17. package/dist/commands/harness.js +2 -2
  18. package/dist/commands/hooks.js +1 -1
  19. package/dist/commands/import.js +8 -4
  20. package/dist/commands/logs.js +6 -0
  21. package/dist/commands/menubar.js +12 -0
  22. package/dist/commands/models.js +1 -1
  23. package/dist/commands/packages.js +6 -6
  24. package/dist/commands/permissions.js +1 -1
  25. package/dist/commands/profiles.js +1 -1
  26. package/dist/commands/pull.d.ts +1 -1
  27. package/dist/commands/pull.js +4 -4
  28. package/dist/commands/repo.d.ts +78 -0
  29. package/dist/commands/repo.js +187 -11
  30. package/dist/commands/routines.d.ts +8 -1
  31. package/dist/commands/routines.js +241 -77
  32. package/dist/commands/rules.js +13 -12
  33. package/dist/commands/secrets.d.ts +3 -1
  34. package/dist/commands/secrets.js +100 -32
  35. package/dist/commands/sessions-inject.d.ts +7 -4
  36. package/dist/commands/sessions-inject.js +18 -18
  37. package/dist/commands/sessions-picker.js +32 -3
  38. package/dist/commands/sessions-resume.d.ts +16 -0
  39. package/dist/commands/sessions-resume.js +14 -13
  40. package/dist/commands/sessions.d.ts +115 -0
  41. package/dist/commands/sessions.js +189 -35
  42. package/dist/commands/set.d.ts +15 -0
  43. package/dist/commands/set.js +79 -0
  44. package/dist/commands/setup-fleet.d.ts +21 -0
  45. package/dist/commands/setup-fleet.js +201 -0
  46. package/dist/commands/setup-secrets.d.ts +20 -0
  47. package/dist/commands/setup-secrets.js +223 -0
  48. package/dist/commands/setup.js +17 -3
  49. package/dist/commands/skills.js +1 -1
  50. package/dist/commands/sync.js +7 -2
  51. package/dist/commands/teams-picker.js +0 -1
  52. package/dist/commands/teams.d.ts +33 -1
  53. package/dist/commands/teams.js +208 -44
  54. package/dist/commands/versions.js +10 -5
  55. package/dist/commands/view.d.ts +1 -0
  56. package/dist/commands/view.js +11 -0
  57. package/dist/index.js +52 -8
  58. package/dist/lib/acp/harnesses.js +0 -7
  59. package/dist/lib/activity.d.ts +156 -0
  60. package/dist/lib/activity.js +282 -0
  61. package/dist/lib/agents.d.ts +9 -2
  62. package/dist/lib/agents.js +72 -63
  63. package/dist/lib/browser/service.js +3 -0
  64. package/dist/lib/browser/types.d.ts +7 -0
  65. package/dist/lib/capabilities.js +6 -2
  66. package/dist/lib/crabbox/lease.js +2 -2
  67. package/dist/lib/crabbox/setup-copy.d.ts +4 -4
  68. package/dist/lib/crabbox/setup-copy.js +4 -4
  69. package/dist/lib/daemon.d.ts +18 -0
  70. package/dist/lib/daemon.js +47 -6
  71. package/dist/lib/devices/fleet.d.ts +1 -1
  72. package/dist/lib/devices/fleet.js +1 -1
  73. package/dist/lib/doctor-diff.d.ts +20 -0
  74. package/dist/lib/doctor-diff.js +6 -1
  75. package/dist/lib/drift.d.ts +31 -11
  76. package/dist/lib/drift.js +58 -7
  77. package/dist/lib/events.d.ts +8 -1
  78. package/dist/lib/events.js +10 -1
  79. package/dist/lib/exec.d.ts +7 -0
  80. package/dist/lib/exec.js +69 -11
  81. package/dist/lib/feed-post.d.ts +28 -1
  82. package/dist/lib/feed-post.js +110 -2
  83. package/dist/lib/fleet/apply.js +8 -1
  84. package/dist/lib/fleet/auth-sync.d.ts +18 -1
  85. package/dist/lib/fleet/auth-sync.js +25 -11
  86. package/dist/lib/fleet/remote-login.js +5 -0
  87. package/dist/lib/git.d.ts +14 -14
  88. package/dist/lib/git.js +41 -44
  89. package/dist/lib/hooks.d.ts +71 -0
  90. package/dist/lib/hooks.js +245 -95
  91. package/dist/lib/hosts/dispatch.d.ts +28 -1
  92. package/dist/lib/hosts/dispatch.js +33 -5
  93. package/dist/lib/hosts/option.js +2 -2
  94. package/dist/lib/hosts/passthrough.d.ts +22 -1
  95. package/dist/lib/hosts/passthrough.js +238 -13
  96. package/dist/lib/hosts/run-target.d.ts +2 -0
  97. package/dist/lib/hosts/run-target.js +1 -0
  98. package/dist/lib/hq/floor.d.ts +1 -1
  99. package/dist/lib/hq/floor.js +6 -1
  100. package/dist/lib/mcp.js +3 -71
  101. package/dist/lib/menubar/MenubarHelper.app/Contents/MacOS/MenubarHelper +0 -0
  102. package/dist/lib/menubar/install-menubar.d.ts +24 -0
  103. package/dist/lib/menubar/install-menubar.js +52 -2
  104. package/dist/lib/menubar/notify-desktop.d.ts +15 -0
  105. package/dist/lib/menubar/notify-desktop.js +41 -5
  106. package/dist/lib/merged-resources.d.ts +11 -0
  107. package/dist/{commands/resources.js → lib/merged-resources.js} +11 -19
  108. package/dist/lib/permissions.d.ts +0 -32
  109. package/dist/lib/permissions.js +4 -157
  110. package/dist/lib/picker.js +1 -1
  111. package/dist/lib/platform/process.d.ts +16 -5
  112. package/dist/lib/platform/process.js +54 -0
  113. package/dist/lib/plugins.d.ts +0 -8
  114. package/dist/lib/plugins.js +4 -110
  115. package/dist/lib/project-resources.js +4 -1
  116. package/dist/lib/refresh.d.ts +5 -3
  117. package/dist/lib/refresh.js +7 -5
  118. package/dist/lib/resources/commands.js +4 -1
  119. package/dist/lib/resources/mcp.js +0 -4
  120. package/dist/lib/resources/permissions.d.ts +1 -1
  121. package/dist/lib/resources/permissions.js +1 -5
  122. package/dist/lib/resources/rules.js +4 -1
  123. package/dist/lib/resources/skills.js +4 -1
  124. package/dist/lib/resources/subagents.js +4 -0
  125. package/dist/lib/resources/types.d.ts +1 -1
  126. package/dist/lib/routines.d.ts +33 -0
  127. package/dist/lib/routines.js +122 -0
  128. package/dist/lib/run-defaults.d.ts +1 -0
  129. package/dist/lib/run-defaults.js +9 -0
  130. package/dist/lib/runner.d.ts +0 -12
  131. package/dist/lib/runner.js +49 -10
  132. package/dist/lib/scheduler.js +16 -4
  133. package/dist/lib/secrets/Agents CLI.app/Contents/CodeResources +0 -0
  134. package/dist/lib/secrets/Agents CLI.app/Contents/MacOS/Agents CLI +0 -0
  135. package/dist/lib/secrets/agent.d.ts +16 -0
  136. package/dist/lib/secrets/agent.js +105 -3
  137. package/dist/lib/secrets/audit.d.ts +46 -0
  138. package/dist/lib/secrets/audit.js +56 -0
  139. package/dist/lib/secrets/bundles.d.ts +11 -8
  140. package/dist/lib/secrets/bundles.js +31 -23
  141. package/dist/lib/secrets/index.d.ts +2 -1
  142. package/dist/lib/secrets/index.js +8 -2
  143. package/dist/lib/secrets/remote.d.ts +75 -2
  144. package/dist/lib/secrets/remote.js +139 -5
  145. package/dist/lib/secrets/sync.js +3 -3
  146. package/dist/lib/session/active.d.ts +128 -26
  147. package/dist/lib/session/active.js +192 -53
  148. package/dist/lib/session/actor-sidecar.d.ts +23 -0
  149. package/dist/lib/session/actor-sidecar.js +101 -0
  150. package/dist/lib/session/db.d.ts +4 -1
  151. package/dist/lib/session/db.js +65 -8
  152. package/dist/lib/session/discover.d.ts +4 -0
  153. package/dist/lib/session/discover.js +13 -0
  154. package/dist/lib/session/hook-sessions.d.ts +9 -0
  155. package/dist/lib/session/hook-sessions.js +57 -8
  156. package/dist/lib/session/pid-registry.d.ts +13 -0
  157. package/dist/lib/session/render.d.ts +2 -0
  158. package/dist/lib/session/render.js +1 -1
  159. package/dist/lib/session/types.d.ts +16 -0
  160. package/dist/lib/staleness/detectors/commands.js +2 -2
  161. package/dist/lib/staleness/detectors/permissions.js +1 -45
  162. package/dist/lib/staleness/writers/commands.js +4 -5
  163. package/dist/lib/staleness/writers/hooks.js +1 -1
  164. package/dist/lib/startup/command-registry.d.ts +1 -2
  165. package/dist/lib/startup/command-registry.js +2 -4
  166. package/dist/lib/state.js +57 -1
  167. package/dist/lib/subagents-registry.js +5 -12
  168. package/dist/lib/subagents.d.ts +0 -10
  169. package/dist/lib/subagents.js +0 -12
  170. package/dist/lib/teams/agents.d.ts +0 -2
  171. package/dist/lib/teams/agents.js +10 -27
  172. package/dist/lib/teams/index.d.ts +1 -1
  173. package/dist/lib/teams/index.js +1 -1
  174. package/dist/lib/types.d.ts +17 -9
  175. package/dist/lib/usage.d.ts +28 -5
  176. package/dist/lib/usage.js +271 -8
  177. package/dist/lib/versions.js +7 -1
  178. package/dist/lib/watchdog/watchdog.d.ts +1 -1
  179. package/dist/lib/watchdog/watchdog.js +25 -13
  180. package/package.json +1 -2
  181. package/dist/commands/check.d.ts +0 -15
  182. package/dist/commands/check.js +0 -180
  183. package/dist/commands/resources.d.ts +0 -5
package/README.md CHANGED
@@ -94,7 +94,7 @@ agents:
94
94
  codex: "0.116.0"
95
95
  ```
96
96
 
97
- Think `requirements.txt` for CLI coding agents, on steroids. A shim reads `agents.yaml` from the project root and routes `claude` / `codex` / `gemini` / `grok` (and others) to the right version automatically. Each version gets its own isolated home -- switching backs up config and re-syncs resources.
97
+ Think `requirements.txt` for CLI coding agents, on steroids. A shim reads `agents.yaml` from the project root and routes `claude` / `codex` / `antigravity` / `grok` (and others) to the right version automatically. Each version gets its own isolated home -- switching backs up config and re-syncs resources.
98
98
 
99
99
  ```bash
100
100
  agents add claude@2.0.65 # Install a specific version
@@ -111,7 +111,7 @@ agents view # See everything installed
111
111
  # Set up the Notion MCP server once.
112
112
  agents install mcp:com.notion/mcp
113
113
 
114
- # It's now registered with Claude Code, Codex, Gemini CLI, and Cursor.
114
+ # It's now registered with Claude Code, Codex, Antigravity, and Cursor.
115
115
  agents mcp list
116
116
  ```
117
117
 
@@ -120,25 +120,25 @@ Skills, slash commands, rules, hooks, and permissions work the same way -- insta
120
120
  ```bash
121
121
  agents skills add gh:yourteam/python-expert # Knowledge pack -> all agents
122
122
  agents commands add gh:yourteam/commands # Slash commands -> all agents
123
- agents rules add gh:team/rules # AGENTS.md -> CLAUDE.md, GEMINI.md, .cursorrules
123
+ agents rules add gh:team/rules # AGENTS.md -> per-agent instruction files
124
124
  agents permissions add ./perms # Permissions -> auto-converted per agent
125
125
  ```
126
126
 
127
- Write one `AGENTS.md`. It becomes `CLAUDE.md` for Claude Code, `GEMINI.md` for Gemini CLI, `.cursorrules` for Cursor.
127
+ Write one `AGENTS.md`. It becomes `CLAUDE.md` for Claude Code, `AGENTS.md` for Antigravity, and `.cursorrules` for Cursor.
128
128
 
129
129
  ---
130
130
 
131
131
  ## Run any agent
132
132
 
133
133
  <p align="center">
134
- <img src="assets/run-agent.svg" alt="agents run: one command runs any harness (claude/codex/gemini) against the project-pinned version, with an automatic rate-limit fallback chain." width="100%" />
134
+ <img src="assets/run-agent.svg" alt="agents run: one command runs any harness (claude/codex/antigravity) against the project-pinned version, with an automatic rate-limit fallback chain." width="100%" />
135
135
  </p>
136
136
 
137
137
 
138
138
  ```bash
139
139
  agents run claude "Find all auth vulnerabilities in src/"
140
140
  agents run codex "Fix the issues Claude found"
141
- agents run gemini "Write tests for the fixed code"
141
+ agents run antigravity "Write tests for the fixed code"
142
142
  ```
143
143
 
144
144
  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`.
@@ -147,7 +147,7 @@ Each resolves to the project-pinned version with skills, MCP servers, and permis
147
147
 
148
148
  ```bash
149
149
  # Claude Code hits a rate limit -> Codex picks up automatically. Same project, same config.
150
- agents run claude "refactor auth module" --mode edit --fallback codex,gemini
150
+ agents run claude "refactor auth module" --mode edit --fallback codex,antigravity
151
151
  ```
152
152
 
153
153
  ### Multiple accounts? Spread the load.
@@ -165,7 +165,7 @@ agents run codex@ "review this branch"
165
165
 
166
166
  A trailing `@` opens an account picker before either an interactive or prompt-based run. Each installed version shows its account identity, exact version, login state, plan, and every available session, weekly, or monthly limit. Logged-out, rate-limited, and out-of-credit accounts remain visible with the reason they cannot be selected; signed-in accounts whose provider does not expose quota data stay selectable and say `limits unavailable`. The choice pins only that run and does not change your default version.
167
167
 
168
- Account selection is available for Claude, Codex, Gemini, Grok, Antigravity, Kimi, Droid, and OpenCode. It requires a terminal and cannot be combined with `--resume`, `--strategy`/`--balanced`, `--lease`, or `--host`/`--device`; profiles and workflows must use their concrete host agent instead.
168
+ Account selection is available for Claude, Codex, Antigravity, Grok, Kimi, Droid, and OpenCode. It requires a terminal and cannot be combined with `--resume`, `--strategy`/`--balanced`, `--lease`, or `--host`/`--device`; profiles and workflows must use their concrete host agent instead.
169
169
 
170
170
  ### Chain agents
171
171
 
@@ -218,21 +218,21 @@ agents run claude "review this diff" --acp --json
218
218
 
219
219
  `--acp` routes through the [Agent Client Protocol](https://github.com/zed-industries/agent-client-protocol) so you get a unified event stream -- `agent_message_chunk`, `tool_call`, `plan_update`, `stop_reason` -- instead of writing a parser per CLI. File writes and shell commands flow through agents-cli, which means `--mode plan` becomes a real sandbox: the write RPC is denied, not just unused.
220
220
 
221
- ACP adapters are documented for claude, codex, gemini, cursor, opencode, openclaw, and grok. Other harnesses keep running on the direct-exec path.
221
+ ACP adapters are documented for claude, codex, cursor, opencode, openclaw, and grok. Other harnesses keep running on the direct-exec path.
222
222
 
223
223
  ---
224
224
 
225
225
  ## Sessions across agents
226
226
 
227
227
  <p align="center">
228
- <img src="assets/sessions.svg" alt="agents sessions: search transcripts across Claude, Codex, Gemini, and OpenCode at once, plus a live --active panel showing each running session's state (working / waiting / idle)." width="100%" />
228
+ <img src="assets/sessions.svg" alt="agents sessions: search transcripts across Claude, Codex, legacy Gemini, and OpenCode at once, plus a live --active panel showing each running session's state (working / waiting / idle)." width="100%" />
229
229
  </p>
230
230
 
231
231
 
232
232
  When you run multiple agents, conversations scatter across tools. Session search brings them together.
233
233
 
234
234
  ```bash
235
- # Where was that auth conversation? Search Claude Code, Codex, Gemini CLI, OpenCode at once.
235
+ # Where was that auth conversation? Search Claude Code, Codex, legacy Gemini, OpenCode at once.
236
236
  agents sessions "auth middleware"
237
237
 
238
238
  # Filter by agent, project, or time window
@@ -306,7 +306,7 @@ agents sessions detach a1b2c3d4 # go headless in the background, keep workin
306
306
  agents sessions attach a1b2c3d4 # resume it interactively, right here
307
307
  ```
308
308
 
309
- Both are agent-agnostic -- they route through the same `agents run --resume` path (native resume for Claude/Codex, `/continue` replay for the rest). `agents sessions --active` marks each session's `presence` -- `attached` (you're watching it), `background` (running headless), or `parked` (its background run finished) -- so the menu bar and Factory show where every agent is. In the Factory extension, **Agents: Detach** (`Cmd/Ctrl+K B`) and **Agents: Attach** (`Cmd/Ctrl+K A`) do the same over the focused terminal.
309
+ Both are agent-agnostic -- they route through the same `agents run --resume` path (native resume for Claude/Codex, `/continue` replay for the rest). `agents sessions --active` shows each session's **owner** (the human who launched it, resolved from the tailnet identity, or `-` for an unresolved local run) and its `presence` -- `attached` (you're watching it), `background` (running headless), or `parked` (its background run finished) -- so the menu bar and Factory show who is running what, and where. In the Factory extension, **Agents: Detach** (`Cmd/Ctrl+K B`) and **Agents: Attach** (`Cmd/Ctrl+K A`) do the same over the focused terminal.
310
310
 
311
311
  ---
312
312
 
@@ -366,7 +366,7 @@ One machine is set up the way you like it. Make every other machine match -- sam
366
366
  fleet:
367
367
  devices: all # every online registered device (minus this one)
368
368
  defaults:
369
- agents: [claude@latest, codex@latest, gemini@latest]
369
+ agents: [claude@latest, codex@latest, antigravity@latest]
370
370
  sync: [user] # config scopes to reconcile
371
371
  login: sync # propagate logins where the token is portable
372
372
  ```
@@ -379,7 +379,7 @@ agents apply --only agents,config # limit dimensions (agents, config, login)
379
379
  agents apply --no-login # skip login propagation
380
380
  ```
381
381
 
382
- `agents apply` (`ag apply`) probes every target over the existing SSH transport, then reconciles it to the profile: installs missing agents, upgrades `agents-cli`, syncs the named config scopes, and **propagates logins** so a host signed in once seeds the fleet -- turning "6 hosts x 8 harnesses = 48 OAuth flows" into one. Portable credential files (claude, codex, gemini, grok, kimi, opencode, droid, antigravity) stream to each target over encrypted SSH stdin, never shell-interpolated, and land at `0600`. **Honest boundary:** macOS keychain-bound tokens (claude, antigravity on a Mac target) can't be extracted -- those surface as a one-time manual login, never faked. `--plan` / `--dry-run` shows the full matrix without touching anything.
382
+ `agents apply` (`ag apply`) probes every target over the existing SSH transport, then reconciles it to the profile: installs missing agents, upgrades `agents-cli`, syncs the named config scopes, and **propagates logins** so a host signed in once seeds the fleet -- turning "6 hosts x 8 harnesses = 48 OAuth flows" into one. Portable credential files (claude, codex, grok, kimi, opencode, droid, antigravity) stream to each target over encrypted SSH stdin, never shell-interpolated, and land at `0600`. **Honest boundary:** macOS keychain-bound tokens (claude, antigravity on a Mac target) can't be extracted -- those surface as a one-time manual login, never faked. `--plan` / `--dry-run` shows the full matrix without touching anything.
383
383
 
384
384
  See [docs/fleet.md](apps/cli/docs/fleet.md) for the manifest schema and reconcile semantics.
385
385
 
@@ -445,6 +445,9 @@ agents run claude --host gpu-box # no prompt → interac
445
445
  agents run claude --host gpu-box --copy-creds "fix auth" # copy local runtime creds + Claude token, shred after
446
446
  agents run claude --device auto "…" # affinity-pick host from 14d usage (harness stays claude)
447
447
  agents run claude --host auto "…" # same — auto is a host value, not a harness name
448
+ agents view kimi --device all # fan out across every registered device (grouped-by-OS roster)
449
+ agents output --device all # per-device burn vs shipped output across the fleet
450
+ agents view --device all --json # machine-readable fleet inventory
448
451
  agents hosts ps # list dispatched runs + terminal status
449
452
  agents hosts stop <id> # terminate a hung/detached run (alias: kill)
450
453
  agents logs --host gpu-box # pick a dispatched run — concise summary by default
@@ -459,7 +462,7 @@ agents fleet status # online/offline rollup + NEEDS ATTENTIO
459
462
  agents fleet status --verbose # full per-device auth/CLI/sync/version grid
460
463
  agents fleet status --live # force a live resource probe (alias of --refresh)
461
464
  agents fleet status --json --strict # scriptable fleet health gate
462
- agents check --devices # CI drift gate across every registered device
465
+ agents doctor --check --devices # CI drift gate across every registered device
463
466
 
464
467
  # Your Tailscale fleet, auto-discovered
465
468
  agents devices sync # ingest `tailscale status`
@@ -986,7 +989,7 @@ Two repos with the same shape, different roles:
986
989
 
987
990
  **Version pinning:** `agents.yaml` at project root pins which agent version to use (like `.nvmrc` for Node).
988
991
 
989
- **Resource resolution:** When syncing resources (commands, skills, rules, hooks, MCP, permissions), the order is **project > user > system**. A `.agents/` directory at project root wins, then `~/.agents/`, then `~/.agents-system/`. Same-named resources higher in the chain override lower ones; everything else unions in. Run `agents resources --merged` to see the effective skills, commands, MCP servers, hooks, rules, plugins, workflows, and subagents, with each row tagged by its winning layer.
992
+ **Resource resolution:** When syncing resources (commands, skills, rules, hooks, MCP, permissions), the order is **project > user > system**. A `.agents/` directory at project root wins, then `~/.agents/`, then `~/.agents-system/`. Same-named resources higher in the chain override lower ones; everything else unions in. Run `agents view --merged` to see the effective skills, commands, MCP servers, hooks, rules, plugins, workflows, and subagents, with each row tagged by its winning layer.
990
993
 
991
994
  See [docs/00-concepts.md](apps/cli/docs/00-concepts.md) for the full mental model: DotAgents repos, resource kinds, and how resolution works end-to-end.
992
995
 
@@ -1069,7 +1072,7 @@ Every agent run, version install, browser launch, and secrets access is logged t
1069
1072
 
1070
1073
  ### Session search
1071
1074
 
1072
- Conversations with Claude, Codex, Gemini, and other agents scatter across their native storage. Session search indexes them locally so you can find any conversation:
1075
+ Conversations with Claude, Codex, legacy Gemini, and other agents scatter across their native storage. Session search indexes them locally so you can find any conversation:
1073
1076
 
1074
1077
  ```bash
1075
1078
  agents sessions "auth middleware" # Full-text search across all agents
@@ -1104,13 +1107,12 @@ By default, secrets sync via iCloud Keychain to your other Macs. With `--no-iclo
1104
1107
 
1105
1108
  Which DotAgents resources each agent CLI can load. Source of truth: [src/lib/agents.ts](apps/cli/src/lib/agents.ts) (`capabilities`); gates use `supports(agent, cap, version)` from [src/lib/capabilities.ts](apps/cli/src/lib/capabilities.ts). Full matrix also in [docs/00-concepts.md](apps/cli/docs/00-concepts.md).
1106
1109
 
1107
- > **† Gemini CLI is deprecated.** Google retired it for free, Pro, and Ultra tiers on **June 18, 2026** (announced at Google I/O 2026); the `gemini` command no longer serves requests on those tiers. agents-cli still manages existing installs, but warns on `agents add gemini` and `agents teams add … gemini`. New setups should use **Antigravity CLI** (`antigravity`), Google's official successor — see [the transition notice](https://developers.googleblog.com/an-important-update-transitioning-gemini-cli-to-antigravity-cli/).
1110
+ > **Gemini CLI is hard-deprecated.** Google retired it for free, Pro, and Ultra tiers on **June 18, 2026** (announced at Google I/O 2026); the `gemini` command no longer serves requests on those tiers. agents-cli keeps the legacy `gemini` id only so old sessions/config can still be read. `agents add gemini`, `agents import gemini`, and `agents sync gemini` fail and point to **Antigravity CLI** (`antigravity`), Google's official successor — see [the transition notice](https://developers.googleblog.com/an-important-update-transitioning-gemini-cli-to-antigravity-cli/).
1108
1111
 
1109
1112
  | Agent | Versions | Hooks | MCP | Permissions | Skills | Commands | Plugins | Subagents | Rules | Workflows |
1110
1113
  |-------|----------|-------|-----|-------------|--------|----------|---------|-----------|-------|-----------|
1111
1114
  | Claude Code | yes | yes | yes | yes | yes | yes | yes | yes | `CLAUDE.md` | yes |
1112
1115
  | Codex CLI | yes | >= 0.116.0 | yes | no | yes | < 0.117.0 · skills ($name, >= 0.117) | >= 0.128.0 | no | `AGENTS.md` | no |
1113
- | Gemini CLI † | yes | >= 0.26.0 | yes | no | yes | yes (.toml) | no | no | `GEMINI.md` | no |
1114
1116
  | Antigravity | yes | yes | yes | yes | yes | yes | yes | no | `AGENTS.md` | no |
1115
1117
  | Grok Build | yes | yes | yes | yes | yes | skills ($name) | yes | no | `AGENTS.md` | no |
1116
1118
  | OpenClaw | yes | yes | yes | no | yes | gateway | yes | yes | `workspace/AGENTS.md` | no |
@@ -1133,7 +1135,6 @@ Which DotAgents resources each agent CLI can load. Source of truth: [src/lib/age
1133
1135
  |-------|----------|-------|---------------|
1134
1136
  | Claude Code | yes | yes | yes |
1135
1137
  | Codex CLI | yes | yes | yes |
1136
- | Gemini CLI † | yes | yes | yes |
1137
1138
  | Cursor | -- | yes | -- |
1138
1139
  | OpenCode | -- | yes | -- |
1139
1140
  | Grok Build | -- | yes | yes |
@@ -1150,20 +1151,19 @@ Which DotAgents resources each agent CLI can load. Source of truth: [src/lib/age
1150
1151
  | Subagents | Kiro | >= 1.23.0 |
1151
1152
  | Skills | Droid | >= 0.26.0 |
1152
1153
  | Permissions | Droid | >= 0.57.5 |
1153
- | Hooks | Gemini | >= 0.26.0 |
1154
1154
  | Permissions | Kiro | >= 2.8.0 |
1155
1155
  | File-based commands | Codex | < 0.117.0 (0.117+ uses command-as-skill) |
1156
1156
  | Plugins | Codex | >= 0.128.0 |
1157
1157
 
1158
1158
  Codex `0.117.0+` no longer reads `.codex/prompts/`; agents-cli converts slash commands into skills so they stay invocable as `$name`. OpenCode's plugin-based hook system is on the roadmap; hooks stay `no` until a writer ships.
1159
1159
 
1160
- Slash commands can declare per-agent/version targeting in frontmatter (`agents:`, `since:`, `until:`). Gating applies when syncing from `~/.agents/commands/` (user/system) into version homes — project `.agents/commands/` files are read in place and are not filtered by `agents:`. This repo ships `.agents/commands/version.md` as `/version` for Claude, Codex, Gemini, Cursor, OpenCode, Copilot, and Grok; Antigravity excluded until verified.
1160
+ Slash commands can declare per-agent/version targeting in frontmatter (`agents:`, `since:`, `until:`). Gating applies when syncing from `~/.agents/commands/` (user/system) into version homes — project `.agents/commands/` files are read in place and are not filtered by `agents:`. This repo ships `.agents/commands/version.md` as `/version` for Claude, Codex, Cursor, OpenCode, Copilot, and Grok; Antigravity excluded until verified.
1161
1161
 
1162
1162
  ## FAQ
1163
1163
 
1164
- ### Why use `agents` instead of `claude` / `codex` / `gemini` directly?
1164
+ ### Why use `agents` instead of `claude` / `codex` / `antigravity` directly?
1165
1165
 
1166
- Claude Code, Codex CLI, Gemini CLI, Grok Build, and others each have their own config format, MCP setup, version management, and skill system. If you use more than one, you maintain N copies of everything. `agents` gives you one interface, one config source, and one place to pin versions -- plus features the individual CLIs don't ship: cross-agent pipelines, shared teams, unified session search, and project-pinned versions like `.nvmrc`.
1166
+ Claude Code, Codex CLI, Antigravity, Grok Build, and others each have their own config format, MCP setup, version management, and skill system. If you use more than one, you maintain N copies of everything. `agents` gives you one interface, one config source, and one place to pin versions -- plus features the individual CLIs don't ship: cross-agent pipelines, shared teams, unified session search, and project-pinned versions like `.nvmrc`.
1167
1167
 
1168
1168
  ### Is it free?
1169
1169
 
@@ -1181,9 +1181,9 @@ Same approach as nvm, pyenv, and rbenv — battle-tested by millions of develope
1181
1181
 
1182
1182
  Add a `.agents/` directory at your project root with your skills, hooks, rules, and commands. Resources merge automatically: project > user (`~/.agents/`) > system (`~/.agents-system/`). Commit it with your repo and teammates get the same agent environment.
1183
1183
 
1184
- ### Do I need to write separate rules for each agent (CLAUDE.md, GEMINI.md, etc.)?
1184
+ ### Do I need to write separate rules for each agent (CLAUDE.md, .cursorrules, etc.)?
1185
1185
 
1186
- No. Write one `AGENTS.md` — it's the canonical source. We automatically sync it to each agent's expected location (`CLAUDE.md` for Claude Code, `GEMINI.md` for Gemini CLI, `.cursorrules` for Cursor). Same content, zero duplication.
1186
+ No. Write one `AGENTS.md` — it's the canonical source. We automatically sync it to each agent's expected location (`CLAUDE.md` for Claude Code, `AGENTS.md` for Antigravity, `.cursorrules` for Cursor). Same content, zero duplication.
1187
1187
 
1188
1188
  ### Do agents use API keys or subscriptions?
1189
1189
 
package/dist/bin/agents CHANGED
Binary file
@@ -7,6 +7,15 @@
7
7
  * hook time by 11-activity-log.py, so this reader never re-parses transcripts --
8
8
  * it tails the logs and collapses routine work to counts, surfacing milestones
9
9
  * individually and newest-first.
10
+ *
11
+ * Fleet-wide by opt-in: `--devices-all` (or `--host <box>`) fans the same
12
+ * `activity --json` payload out across the fleet the way `agents feed` does,
13
+ * merges every peer's stream host-tagged, and joins each item to live sessions
14
+ * (project / ticket / execution host) so `--group-by project` shows, per
15
+ * project, what each agent did, where, and for which ticket -- progress at a
16
+ * glance. Local-only stays the default.
10
17
  */
11
18
  import type { Command } from 'commander';
19
+ /** Recursion guard: a peer answering a fan-out never re-fans-out itself. */
20
+ export declare const ACTIVITY_NO_FANOUT_ENV = "AGENTS_ACTIVITY_LOCAL";
12
21
  export declare function registerActivityCommand(program: Command): void;
@@ -1,5 +1,12 @@
1
1
  import chalk from 'chalk';
2
- import { collapseActivity, ensureActivityLogHook, formatActivityLine, readRecentActivity, styleForEvent, tierForEvent, } from '../lib/activity.js';
2
+ import { collapseActivity, enrichActivityEvents, ensureActivityLogHook, filterActivityEvents, formatActivityGroupHeader, formatEnrichedActivityLine, formatProgressUpdate, groupActivity, mergeActivityEvents, parseActivityPayload, projectFromCwd, readRecentActivity, styleForEvent, tierForEvent, } from '../lib/activity.js';
3
+ import { gatherRemoteAgentsJson } from '../lib/remote-agents-json.js';
4
+ import { machineId, normalizeHost } from '../lib/machine-id.js';
5
+ import { shouldIncludeLocalFeed, remoteFeedHostsToDial } from './feed.js';
6
+ import { getActiveSessions } from '../lib/session/active.js';
7
+ /** Recursion guard: a peer answering a fan-out never re-fans-out itself. */
8
+ export const ACTIVITY_NO_FANOUT_ENV = 'AGENTS_ACTIVITY_LOCAL';
9
+ const GROUP_BY_VALUES = ['project', 'device', 'agent'];
3
10
  /** Wire the activity-log hooks into each hooks-capable version's settings. */
4
11
  async function installActivityHooks() {
5
12
  const warnings = [];
@@ -20,49 +27,171 @@ async function installActivityHooks() {
20
27
  }
21
28
  return warnings;
22
29
  }
30
+ /** Session facts (project / ticket / execution host) keyed for the read-time join. */
31
+ function activityHintsFromSessions(sessions) {
32
+ return sessions.map((s) => ({
33
+ sessionId: s.sessionId,
34
+ ticket: s.ticket?.id,
35
+ // Where the process actually lives — the SSH-resolved provenance host, else
36
+ // the cross-machine `machine` id. Normalized to match the event `host` form.
37
+ executionHost: s.provenance?.host ? normalizeHost(s.provenance.host) : s.machine,
38
+ project: projectFromCwd(s.cwd),
39
+ }));
40
+ }
41
+ /**
42
+ * Render one enriched event. Deliberate progress posts (`status.posted`) use the
43
+ * rich multi-line {@link formatProgressUpdate} (joining the ticket the event's
44
+ * session carries); every other milestone keeps the compact enriched line.
45
+ */
46
+ function renderEnrichedEntry(ev, opts = {}) {
47
+ if (ev.event === 'status.posted') {
48
+ const body = formatProgressUpdate(ev, { joined: { ticketId: ev.ticket } });
49
+ return opts.indent ? body.split('\n').map((l) => `${opts.indent}${l}`).join('\n') : body;
50
+ }
51
+ return formatEnrichedActivityLine(ev, opts);
52
+ }
53
+ /** Print one flat, newest-first stream (the default view). */
54
+ function renderFlat(events, opts) {
55
+ const { milestones, counts, subagentCount } = collapseActivity(events);
56
+ process.stdout.write(chalk.bold('\n recent activity\n'));
57
+ const shown = opts.all ? events : milestones;
58
+ for (const ev of shown) {
59
+ process.stdout.write(`${renderEnrichedEntry(ev, { showHost: true, showProject: true })}\n`);
60
+ }
61
+ if (!opts.all) {
62
+ const parts = Object.entries(counts)
63
+ .sort((a, b) => b[1] - a[1])
64
+ .map(([event, n]) => `${styleForEvent(event).label} ×${n}`);
65
+ if (parts.length > 0)
66
+ process.stdout.write(chalk.gray(`\n · ${parts.join(' ')}\n`));
67
+ }
68
+ if (subagentCount > 0) {
69
+ process.stdout.write(chalk.magenta(`\n ⑂ ${subagentCount} sub-agent${subagentCount === 1 ? '' : 's'} spawned\n`));
70
+ }
71
+ process.stdout.write('\n');
72
+ }
73
+ /** Print the bucketed view (`--group-by project|device|agent`). */
74
+ function renderGrouped(events, by, opts) {
75
+ const groups = groupActivity(events, by);
76
+ // The grouping dimension is redundant on each line -- drop it from the tags.
77
+ const showHost = by !== 'device';
78
+ const showProject = by !== 'project';
79
+ process.stdout.write(chalk.bold(`\n activity by ${by}\n`));
80
+ for (const group of groups) {
81
+ process.stdout.write(`\n ${chalk.bold(formatActivityGroupHeader(group))}\n`);
82
+ const { milestones, counts, subagentCount } = collapseActivity(group.events);
83
+ const shown = opts.all ? group.events : milestones;
84
+ for (const ev of shown) {
85
+ process.stdout.write(`${renderEnrichedEntry(ev, { showHost, showProject, indent: ' ' })}\n`);
86
+ }
87
+ if (!opts.all) {
88
+ const parts = Object.entries(counts)
89
+ .sort((a, b) => b[1] - a[1])
90
+ .map(([event, n]) => `${styleForEvent(event).label} ×${n}`);
91
+ if (parts.length > 0)
92
+ process.stdout.write(chalk.gray(` · ${parts.join(' ')}\n`));
93
+ }
94
+ if (subagentCount > 0) {
95
+ process.stdout.write(chalk.magenta(` ⑂ ${subagentCount} sub-agent${subagentCount === 1 ? '' : 's'} spawned\n`));
96
+ }
97
+ }
98
+ process.stdout.write('\n');
99
+ }
23
100
  export function registerActivityCommand(program) {
24
101
  program
25
102
  .command('activity')
26
103
  .description('Recent agent activity -- plans, PRs, worktrees, sub-agents (newest first)')
27
- .option('--json', 'Emit the raw event list as JSON')
104
+ .option('--json', 'Emit the (enriched) event list as JSON')
28
105
  .option('--all', 'Include routine activity (file edits) inline, not collapsed')
29
106
  .option('--milestones', 'Only milestone events (plans, PRs, worktrees, sub-agents)')
30
107
  .option('-n, --limit <n>', 'Cap the number of events shown', (v) => parseInt(v, 10), 40)
31
108
  .option('--since <minutes>', 'Only events within the last N minutes', (v) => parseInt(v, 10))
109
+ .option('--local', 'Only this machine -- skip the cross-machine SSH fan-out')
110
+ .option('-H, --host <target...>', 'Scope to remote machine(s) over SSH; repeatable')
111
+ .option('--device <target...>', 'Alias for --host; repeatable')
112
+ .option('--devices-all', 'Fan out to every reachable device on the fleet')
113
+ .option('--hosts-all', 'Alias for --devices-all')
114
+ .option('--group-by <field>', 'Bucket the stream by project | device | agent')
115
+ .option('--filter <text>', 'Narrow to items matching a project / device / agent / event / ticket')
116
+ .addHelpText('after', `
117
+ Examples:
118
+ agents activity # this machine, newest first
119
+ agents activity --devices-all --group-by project # per project across the fleet
120
+ agents activity --host yosemite-s1 # one box over SSH
121
+ agents activity --devices-all --filter RUSH-2100 # one ticket, fleet-wide
122
+ agents activity --milestones # only plans / PRs / worktrees / sub-agents
123
+
124
+ Each item is enriched by JOINING to live sessions (project, execution host,
125
+ Linear ticket) -- never by re-parsing transcripts. --devices-all runs the same
126
+ 'activity --json' on each peer and merges the streams host-tagged.
127
+ `)
32
128
  .action(async (opts) => {
33
- const warnings = await installActivityHooks();
129
+ if (opts.device?.length)
130
+ opts.host = [...(opts.host ?? []), ...opts.device];
131
+ const groupBy = opts.groupBy;
132
+ if (groupBy && !GROUP_BY_VALUES.includes(groupBy)) {
133
+ process.stderr.write(chalk.red(`--group-by must be one of: ${GROUP_BY_VALUES.join(', ')}\n`));
134
+ process.exitCode = 1;
135
+ return;
136
+ }
137
+ const self = machineId();
138
+ const forceLocal = opts.local === true || process.env[ACTIVITY_NO_FANOUT_ENV] === '1';
139
+ const explicitHosts = opts.host;
140
+ const wantAll = Boolean(opts.devicesAll || opts.hostsAll);
141
+ const wantRemote = !forceLocal && (wantAll || (explicitHosts != null && explicitHosts.length > 0));
142
+ // Local events are included unless an explicit --host list excludes this box.
143
+ let includeLocal = true;
144
+ if (wantRemote && explicitHosts && explicitHosts.length > 0) {
145
+ includeLocal = shouldIncludeLocalFeed(explicitHosts, self);
146
+ }
147
+ const warnings = includeLocal ? await installActivityHooks() : [];
34
148
  const sinceMs = typeof opts.since === 'number' && opts.since > 0
35
149
  ? Date.now() - opts.since * 60_000
36
150
  : undefined;
37
- let events = readRecentActivity({ sinceMs, limit: opts.limit });
151
+ let events = includeLocal
152
+ ? readRecentActivity({ sinceMs, limit: opts.limit })
153
+ : [];
154
+ if (wantRemote) {
155
+ // Explicit hosts drop self (it's the local read); --devices-all dials
156
+ // every online peer (hosts undefined).
157
+ const remoteHosts = explicitHosts?.length ? remoteFeedHostsToDial(explicitHosts, self) : undefined;
158
+ if (!explicitHosts?.length || (remoteHosts && remoteHosts.length > 0)) {
159
+ const remoteArgs = ['activity', '--json', '-n', String(opts.limit)];
160
+ if (typeof opts.since === 'number' && opts.since > 0)
161
+ remoteArgs.push('--since', String(opts.since));
162
+ const remote = await gatherRemoteAgentsJson({
163
+ args: remoteArgs,
164
+ noFanoutEnv: ACTIVITY_NO_FANOUT_ENV,
165
+ hosts: remoteHosts,
166
+ parse: parseActivityPayload,
167
+ });
168
+ events = mergeActivityEvents(events, remote.items);
169
+ }
170
+ }
171
+ // Enrich by joining to live LOCAL sessions (ticket/project/execution host).
172
+ // Remote events arrive already enriched by their own peer, so the join only
173
+ // fills local ones; the pure fallbacks (cwd->project, host->device) cover
174
+ // everything either way. Skip the ps/lsof scan when there's nothing to show.
175
+ const sessions = includeLocal && events.length > 0 ? await getActiveSessions() : [];
176
+ let enriched = enrichActivityEvents(events, activityHintsFromSessions(sessions));
38
177
  if (opts.milestones)
39
- events = events.filter((e) => tierForEvent(e.event) === 'milestone');
178
+ enriched = enriched.filter((e) => tierForEvent(e.event) === 'milestone');
179
+ if (opts.filter)
180
+ enriched = filterActivityEvents(enriched, opts.filter);
181
+ enriched = enriched.slice(0, opts.limit);
40
182
  if (opts.json) {
41
- process.stdout.write(`${JSON.stringify(events, null, 2)}\n`);
183
+ process.stdout.write(`${JSON.stringify(enriched, null, 2)}\n`);
42
184
  return;
43
185
  }
44
186
  for (const w of warnings)
45
187
  process.stderr.write(chalk.yellow(` ! ${w}\n`));
46
- if (events.length === 0) {
188
+ if (enriched.length === 0) {
47
189
  process.stdout.write(chalk.gray('No recent agent activity. Events appear here as agents create plans, open PRs, and spawn sub-agents.\n'));
48
190
  return;
49
191
  }
50
- const { milestones, counts, subagentCount } = collapseActivity(events);
51
- process.stdout.write(chalk.bold('\n recent activity\n'));
52
- const shown = opts.all ? events : milestones;
53
- for (const ev of shown)
54
- process.stdout.write(`${formatActivityLine(ev, { showHost: true })}\n`);
55
- if (!opts.all) {
56
- const parts = Object.entries(counts)
57
- .sort((a, b) => b[1] - a[1])
58
- .map(([event, n]) => `${styleForEvent(event).label} ×${n}`);
59
- if (parts.length > 0) {
60
- process.stdout.write(chalk.gray(`\n · ${parts.join(' ')}\n`));
61
- }
62
- }
63
- if (subagentCount > 0) {
64
- process.stdout.write(chalk.magenta(`\n ⑂ ${subagentCount} sub-agent${subagentCount === 1 ? '' : 's'} spawned\n`));
65
- }
66
- process.stdout.write('\n');
192
+ if (groupBy)
193
+ renderGrouped(enriched, groupBy, opts);
194
+ else
195
+ renderFlat(enriched, opts);
67
196
  });
68
197
  }
@@ -17,7 +17,7 @@ import { machineId } from '../lib/session/sync/config.js';
17
17
  import { loadDevices, isControlDevice } from '../lib/devices/registry.js';
18
18
  import { ensureDevicesRegistered } from '../lib/devices/sync.js';
19
19
  import { readFleetFile, resolveDesired } from '../lib/fleet/manifest.js';
20
- import { snapshotAuth, materializeAuth, parseAuthBundle, KEYCHAIN_BOUND_ON_MAC } from '../lib/fleet/auth-sync.js';
20
+ import { snapshotAuth, materializeAuth, parseAuthBundle, KEYCHAIN_BOUND_ON_MAC, isCredentialSafeToPropagate } from '../lib/fleet/auth-sync.js';
21
21
  import { agentIdOf, diffFleet, probeDevice, runFleetApply, pool, sourceHome, expandAllSpecs, rosterNeedsVersions, } from '../lib/fleet/apply.js';
22
22
  import { listInstalledVersions } from '../lib/versions.js';
23
23
  /** Version of the running agents-cli — the fleet target version. */
@@ -104,19 +104,26 @@ function renderPlan(plan) {
104
104
  }
105
105
  console.log();
106
106
  console.log(chalk.gray(` ${plan.actions.length} action(s) across ${rows.filter((r) => r.probe.reachable).length} reachable device(s)`));
107
- // Distinguish *why* a login can't be propagated: a macOS keychain-bound token
108
- // vs. the source simply not being signed in to that agent (no portable file).
107
+ // Distinguish *why* a login can't be propagated: macOS keychain-bound,
108
+ // single-use rotating refresh token (never copied), or the source simply not
109
+ // being signed in to that agent (no portable file).
109
110
  const bound = [];
111
+ const rotating = [];
110
112
  const noToken = [];
111
113
  for (const r of rows) {
112
114
  for (const a of r.loginBlocked) {
113
115
  const tag = `${a}@${r.device}`;
114
- if (r.probe.platform === 'macos' && KEYCHAIN_BOUND_ON_MAC.has(a))
116
+ if (!isCredentialSafeToPropagate(a))
117
+ rotating.push(tag);
118
+ else if (r.probe.platform === 'macos' && KEYCHAIN_BOUND_ON_MAC.has(a))
115
119
  bound.push(tag);
116
120
  else
117
121
  noToken.push(tag);
118
122
  }
119
123
  }
124
+ if (rotating.length > 0) {
125
+ console.log(chalk.yellow(` manual login needed (single-use rotating refresh token): ${rotating.join(', ')}`));
126
+ }
120
127
  if (bound.length > 0) {
121
128
  console.log(chalk.yellow(` manual login needed (macOS keychain-bound): ${bound.join(', ')}`));
122
129
  }
@@ -52,7 +52,7 @@ Examples:
52
52
  agents cli check
53
53
 
54
54
  When to use:
55
- - After 'agents repo refresh' on a new machine, to materialize host binaries
55
+ - After 'agents sync' on a new machine, to materialize host binaries
56
56
  - In a team setup: commit cli/ entries so teammates get the same toolchain
57
57
  `);
58
58
  cliCmd
@@ -4,7 +4,7 @@
4
4
  * Implements `agents commands` -- list, add, remove, sync, prune, and view
5
5
  * markdown files that agents invoke mid-session as slash commands. Central
6
6
  * storage lives in ~/.agents/commands/ and commands are synced to individual
7
- * version homes (with TOML conversion for Gemini).
7
+ * version homes.
8
8
  */
9
9
  import type { Command } from 'commander';
10
10
  /** Register the `agents commands` command tree (list, add, remove, sync, prune, view). */
@@ -4,7 +4,8 @@ import * as fs from 'fs';
4
4
  import * as os from 'os';
5
5
  import * as path from 'path';
6
6
  import { checkbox } from '@inquirer/prompts';
7
- import { AGENTS, ALL_AGENT_IDS, resolveAgentName, formatAgentError, agentLabel, } from '../lib/agents.js';
7
+ import { AGENTS, resolveAgentName, formatAgentError, agentLabel, } from '../lib/agents.js';
8
+ import { capableAgents } from '../lib/capabilities.js';
8
9
  import { cloneRepo } from '../lib/git.js';
9
10
  import { discoverCommands, resolveCommandSource, installCommandCentrally, listCentralCommands, listInstalledCommandsWithScope, getCommandInfo, diffVersionCommands, iterCommandsCapableVersions, removeCommandFromVersion, } from '../lib/commands.js';
10
11
  import { getCommandsDir } from '../lib/state.js';
@@ -80,7 +81,7 @@ When to use:
80
81
  commandsCmd
81
82
  .command('add [source]')
82
83
  .description('Install commands from a source (GitHub, local) or pick from central storage')
83
- .option('-a, --agents <list>', 'Targets: claude, codex@0.116.0, or gemini@default')
84
+ .option('-a, --agents <list>', 'Targets: claude, codex@0.116.0, or cursor@default')
84
85
  .option('--names <list>', 'Command names from ~/.agents/commands/ (comma-separated)')
85
86
  .option('-y, --yes', 'Skip all prompts')
86
87
  .addHelpText('after', `
@@ -92,7 +93,7 @@ Examples:
92
93
  agents commands add --names README,debug --agents codex@0.116.0
93
94
 
94
95
  # Pull commands from GitHub and sync to all installed agents
95
- agents commands add gh:user/repo --agents claude,codex,gemini
96
+ agents commands add gh:user/repo --agents claude,codex,cursor
96
97
 
97
98
  # Add a local command directory
98
99
  agents commands add ~/my-commands --agents claude@default
@@ -216,7 +217,7 @@ Examples:
216
217
  let selectedAgents;
217
218
  let versionSelections;
218
219
  if (options.agents) {
219
- const result = await resolveAgentTargetsAutoInstalling(options.agents, ALL_AGENT_IDS, { yes: options.yes });
220
+ const result = await resolveAgentTargetsAutoInstalling(options.agents, capableAgents('commands'), { yes: options.yes });
220
221
  if (!result) {
221
222
  console.log(chalk.gray('Cancelled.'));
222
223
  return;
@@ -225,7 +226,7 @@ Examples:
225
226
  versionSelections = result.versionSelections;
226
227
  }
227
228
  else {
228
- const result = await promptAgentVersionSelection(ALL_AGENT_IDS, {
229
+ const result = await promptAgentVersionSelection(capableAgents('commands'), {
229
230
  skipPrompts: options.yes,
230
231
  });
231
232
  selectedAgents = result.selectedAgents;
@@ -345,7 +346,7 @@ Examples:
345
346
  // agent@x.y.z, agent@all, literal all) works here too.
346
347
  let availableTargets = cmdInfo.targets;
347
348
  if (options?.agents) {
348
- const requestedTargets = resolveInstalledAgentTargets(options.agents, ALL_AGENT_IDS);
349
+ const requestedTargets = resolveInstalledAgentTargets(options.agents, capableAgents('commands'));
349
350
  const requested = new Set();
350
351
  for (const aid of requestedTargets.directAgents) {
351
352
  for (const ver of listInstalledVersions(aid)) {
@@ -5,16 +5,8 @@
5
5
  */
6
6
  import chalk from 'chalk';
7
7
  import { setHelpSections } from '../lib/help.js';
8
- import { listRunDefaults, setRunDefault, unsetRunDefault, } from '../lib/run-defaults.js';
8
+ import { formatRunDefaultEntry, listRunDefaults, setRunDefault, unsetRunDefault, } from '../lib/run-defaults.js';
9
9
  import { getProjectRoot, setProjectRoot } from '../lib/project-root.js';
10
- function formatRunDefault(entry) {
11
- const parts = [];
12
- if (entry.defaults.mode)
13
- parts.push(`mode ${chalk.white(entry.defaults.mode)}`);
14
- if (entry.defaults.model)
15
- parts.push(`model ${chalk.white(entry.defaults.model)}`);
16
- return `${chalk.cyan(entry.selector.padEnd(22))} ${parts.join(' ')}`;
17
- }
18
10
  export function registerDefaultsCommands(program) {
19
11
  const defaults = program
20
12
  .command('defaults')
@@ -47,7 +39,7 @@ export function registerDefaultsCommands(program) {
47
39
  }
48
40
  console.log(chalk.bold('Run Defaults\n'));
49
41
  for (const entry of entries) {
50
- console.log(` ${formatRunDefault(entry)}`);
42
+ console.log(` ${formatRunDefaultEntry(entry)}`);
51
43
  }
52
44
  });
53
45
  run
@@ -62,7 +54,7 @@ export function registerDefaultsCommands(program) {
62
54
  ...(options.model !== undefined ? { model: options.model } : {}),
63
55
  });
64
56
  console.log(chalk.green('Set run default:'));
65
- console.log(` ${formatRunDefault(entry)}`);
57
+ console.log(` ${formatRunDefaultEntry(entry)}`);
66
58
  }
67
59
  catch (err) {
68
60
  console.error(chalk.red(err.message));