@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.
- package/CHANGELOG.md +595 -0
- package/README.md +26 -26
- package/dist/bin/agents +0 -0
- package/dist/commands/activity.d.ts +9 -0
- package/dist/commands/activity.js +153 -24
- package/dist/commands/apply.js +11 -4
- package/dist/commands/cli.js +1 -1
- package/dist/commands/commands.d.ts +1 -1
- package/dist/commands/commands.js +7 -6
- package/dist/commands/defaults.js +3 -11
- package/dist/commands/doctor.d.ts +66 -0
- package/dist/commands/doctor.js +596 -33
- package/dist/commands/events.js +1 -1
- package/dist/commands/exec.js +24 -5
- package/dist/commands/feed.d.ts +4 -0
- package/dist/commands/feed.js +87 -11
- package/dist/commands/harness.js +2 -2
- package/dist/commands/hooks.js +1 -1
- package/dist/commands/import.js +8 -4
- package/dist/commands/logs.js +6 -0
- package/dist/commands/menubar.js +12 -0
- package/dist/commands/models.js +1 -1
- package/dist/commands/packages.js +6 -6
- package/dist/commands/permissions.js +1 -1
- package/dist/commands/profiles.js +1 -1
- package/dist/commands/pull.d.ts +1 -1
- package/dist/commands/pull.js +4 -4
- package/dist/commands/repo.d.ts +78 -0
- package/dist/commands/repo.js +187 -11
- package/dist/commands/routines.d.ts +8 -1
- package/dist/commands/routines.js +241 -77
- package/dist/commands/rules.js +13 -12
- package/dist/commands/secrets.d.ts +3 -1
- package/dist/commands/secrets.js +100 -32
- package/dist/commands/sessions-inject.d.ts +7 -4
- package/dist/commands/sessions-inject.js +18 -18
- package/dist/commands/sessions-picker.js +32 -3
- package/dist/commands/sessions-resume.d.ts +16 -0
- package/dist/commands/sessions-resume.js +14 -13
- package/dist/commands/sessions.d.ts +115 -0
- package/dist/commands/sessions.js +189 -35
- package/dist/commands/set.d.ts +15 -0
- package/dist/commands/set.js +79 -0
- package/dist/commands/setup-fleet.d.ts +21 -0
- package/dist/commands/setup-fleet.js +201 -0
- package/dist/commands/setup-secrets.d.ts +20 -0
- package/dist/commands/setup-secrets.js +223 -0
- package/dist/commands/setup.js +17 -3
- package/dist/commands/skills.js +1 -1
- package/dist/commands/sync.js +7 -2
- package/dist/commands/teams-picker.js +0 -1
- package/dist/commands/teams.d.ts +33 -1
- package/dist/commands/teams.js +208 -44
- package/dist/commands/versions.js +10 -5
- package/dist/commands/view.d.ts +1 -0
- package/dist/commands/view.js +11 -0
- package/dist/index.js +52 -8
- package/dist/lib/acp/harnesses.js +0 -7
- package/dist/lib/activity.d.ts +156 -0
- package/dist/lib/activity.js +282 -0
- package/dist/lib/agents.d.ts +9 -2
- package/dist/lib/agents.js +72 -63
- package/dist/lib/browser/service.js +3 -0
- package/dist/lib/browser/types.d.ts +7 -0
- package/dist/lib/capabilities.js +6 -2
- package/dist/lib/crabbox/lease.js +2 -2
- package/dist/lib/crabbox/setup-copy.d.ts +4 -4
- package/dist/lib/crabbox/setup-copy.js +4 -4
- package/dist/lib/daemon.d.ts +18 -0
- package/dist/lib/daemon.js +47 -6
- package/dist/lib/devices/fleet.d.ts +1 -1
- package/dist/lib/devices/fleet.js +1 -1
- package/dist/lib/doctor-diff.d.ts +20 -0
- package/dist/lib/doctor-diff.js +6 -1
- package/dist/lib/drift.d.ts +31 -11
- package/dist/lib/drift.js +58 -7
- package/dist/lib/events.d.ts +8 -1
- package/dist/lib/events.js +10 -1
- package/dist/lib/exec.d.ts +7 -0
- package/dist/lib/exec.js +69 -11
- package/dist/lib/feed-post.d.ts +28 -1
- package/dist/lib/feed-post.js +110 -2
- package/dist/lib/fleet/apply.js +8 -1
- package/dist/lib/fleet/auth-sync.d.ts +18 -1
- package/dist/lib/fleet/auth-sync.js +25 -11
- package/dist/lib/fleet/remote-login.js +5 -0
- package/dist/lib/git.d.ts +14 -14
- package/dist/lib/git.js +41 -44
- package/dist/lib/hooks.d.ts +71 -0
- package/dist/lib/hooks.js +245 -95
- package/dist/lib/hosts/dispatch.d.ts +28 -1
- package/dist/lib/hosts/dispatch.js +33 -5
- package/dist/lib/hosts/option.js +2 -2
- package/dist/lib/hosts/passthrough.d.ts +22 -1
- package/dist/lib/hosts/passthrough.js +238 -13
- package/dist/lib/hosts/run-target.d.ts +2 -0
- package/dist/lib/hosts/run-target.js +1 -0
- package/dist/lib/hq/floor.d.ts +1 -1
- package/dist/lib/hq/floor.js +6 -1
- package/dist/lib/mcp.js +3 -71
- package/dist/lib/menubar/MenubarHelper.app/Contents/MacOS/MenubarHelper +0 -0
- package/dist/lib/menubar/install-menubar.d.ts +24 -0
- package/dist/lib/menubar/install-menubar.js +52 -2
- package/dist/lib/menubar/notify-desktop.d.ts +15 -0
- package/dist/lib/menubar/notify-desktop.js +41 -5
- package/dist/lib/merged-resources.d.ts +11 -0
- package/dist/{commands/resources.js → lib/merged-resources.js} +11 -19
- package/dist/lib/permissions.d.ts +0 -32
- package/dist/lib/permissions.js +4 -157
- package/dist/lib/picker.js +1 -1
- package/dist/lib/platform/process.d.ts +16 -5
- package/dist/lib/platform/process.js +54 -0
- package/dist/lib/plugins.d.ts +0 -8
- package/dist/lib/plugins.js +4 -110
- package/dist/lib/project-resources.js +4 -1
- package/dist/lib/refresh.d.ts +5 -3
- package/dist/lib/refresh.js +7 -5
- package/dist/lib/resources/commands.js +4 -1
- package/dist/lib/resources/mcp.js +0 -4
- package/dist/lib/resources/permissions.d.ts +1 -1
- package/dist/lib/resources/permissions.js +1 -5
- package/dist/lib/resources/rules.js +4 -1
- package/dist/lib/resources/skills.js +4 -1
- package/dist/lib/resources/subagents.js +4 -0
- package/dist/lib/resources/types.d.ts +1 -1
- package/dist/lib/routines.d.ts +33 -0
- package/dist/lib/routines.js +122 -0
- package/dist/lib/run-defaults.d.ts +1 -0
- package/dist/lib/run-defaults.js +9 -0
- package/dist/lib/runner.d.ts +0 -12
- package/dist/lib/runner.js +49 -10
- package/dist/lib/scheduler.js +16 -4
- package/dist/lib/secrets/Agents CLI.app/Contents/CodeResources +0 -0
- package/dist/lib/secrets/Agents CLI.app/Contents/MacOS/Agents CLI +0 -0
- package/dist/lib/secrets/agent.d.ts +16 -0
- package/dist/lib/secrets/agent.js +105 -3
- package/dist/lib/secrets/audit.d.ts +46 -0
- package/dist/lib/secrets/audit.js +56 -0
- package/dist/lib/secrets/bundles.d.ts +11 -8
- package/dist/lib/secrets/bundles.js +31 -23
- package/dist/lib/secrets/index.d.ts +2 -1
- package/dist/lib/secrets/index.js +8 -2
- package/dist/lib/secrets/remote.d.ts +75 -2
- package/dist/lib/secrets/remote.js +139 -5
- package/dist/lib/secrets/sync.js +3 -3
- package/dist/lib/session/active.d.ts +128 -26
- package/dist/lib/session/active.js +192 -53
- package/dist/lib/session/actor-sidecar.d.ts +23 -0
- package/dist/lib/session/actor-sidecar.js +101 -0
- package/dist/lib/session/db.d.ts +4 -1
- package/dist/lib/session/db.js +65 -8
- package/dist/lib/session/discover.d.ts +4 -0
- package/dist/lib/session/discover.js +13 -0
- package/dist/lib/session/hook-sessions.d.ts +9 -0
- package/dist/lib/session/hook-sessions.js +57 -8
- package/dist/lib/session/pid-registry.d.ts +13 -0
- package/dist/lib/session/render.d.ts +2 -0
- package/dist/lib/session/render.js +1 -1
- package/dist/lib/session/types.d.ts +16 -0
- package/dist/lib/staleness/detectors/commands.js +2 -2
- package/dist/lib/staleness/detectors/permissions.js +1 -45
- package/dist/lib/staleness/writers/commands.js +4 -5
- package/dist/lib/staleness/writers/hooks.js +1 -1
- package/dist/lib/startup/command-registry.d.ts +1 -2
- package/dist/lib/startup/command-registry.js +2 -4
- package/dist/lib/state.js +57 -1
- package/dist/lib/subagents-registry.js +5 -12
- package/dist/lib/subagents.d.ts +0 -10
- package/dist/lib/subagents.js +0 -12
- package/dist/lib/teams/agents.d.ts +0 -2
- package/dist/lib/teams/agents.js +10 -27
- package/dist/lib/teams/index.d.ts +1 -1
- package/dist/lib/teams/index.js +1 -1
- package/dist/lib/types.d.ts +17 -9
- package/dist/lib/usage.d.ts +28 -5
- package/dist/lib/usage.js +271 -8
- package/dist/lib/versions.js +7 -1
- package/dist/lib/watchdog/watchdog.d.ts +1 -1
- package/dist/lib/watchdog/watchdog.js +25 -13
- package/package.json +1 -2
- package/dist/commands/check.d.ts +0 -15
- package/dist/commands/check.js +0 -180
- 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` / `
|
|
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,
|
|
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 ->
|
|
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, `
|
|
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/
|
|
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
|
|
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,
|
|
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,
|
|
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,
|
|
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
|
|
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`
|
|
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,
|
|
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,
|
|
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
|
|
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
|
|
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
|
-
>
|
|
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,
|
|
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` / `
|
|
1164
|
+
### Why use `agents` instead of `claude` / `codex` / `antigravity` directly?
|
|
1165
1165
|
|
|
1166
|
-
Claude Code, Codex CLI,
|
|
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,
|
|
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, `
|
|
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,
|
|
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
|
|
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
|
-
|
|
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 =
|
|
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
|
-
|
|
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(
|
|
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 (
|
|
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
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
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
|
}
|
package/dist/commands/apply.js
CHANGED
|
@@ -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:
|
|
108
|
-
//
|
|
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 (
|
|
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
|
}
|
package/dist/commands/cli.js
CHANGED
|
@@ -52,7 +52,7 @@ Examples:
|
|
|
52
52
|
agents cli check
|
|
53
53
|
|
|
54
54
|
When to use:
|
|
55
|
-
- After 'agents
|
|
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
|
|
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,
|
|
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
|
|
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,
|
|
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,
|
|
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(
|
|
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,
|
|
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(` ${
|
|
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(` ${
|
|
57
|
+
console.log(` ${formatRunDefaultEntry(entry)}`);
|
|
66
58
|
}
|
|
67
59
|
catch (err) {
|
|
68
60
|
console.error(chalk.red(err.message));
|