@phnx-labs/agents-cli 1.22.46 → 1.22.47
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 +279 -0
- package/LICENSE +102 -182
- package/README.md +31 -18
- package/dist/cli/command-registry.d.ts +1 -1
- package/dist/cli/command-registry.js +4 -2
- package/dist/commands/accounts.js +56 -12
- package/dist/commands/auth.js +7 -5
- package/dist/commands/browser-sessions-picker.js +9 -7
- package/dist/commands/browser.js +266 -15
- package/dist/commands/config.js +26 -4
- package/dist/commands/cost.d.ts +1 -1
- package/dist/commands/detach.d.ts +13 -0
- package/dist/commands/detach.js +11 -8
- package/dist/commands/exec.js +55 -38
- package/dist/commands/feed-watch.d.ts +2 -0
- package/dist/commands/feed-watch.js +28 -0
- package/dist/commands/feed.js +27 -0
- package/dist/commands/feedback.js +3 -19
- package/dist/commands/insights.d.ts +1 -1
- package/dist/commands/insights.js +2 -2
- package/dist/commands/lease.js +3 -3
- package/dist/commands/routines.js +1 -1
- package/dist/commands/sessions-picker-factory.d.ts +2 -1
- package/dist/commands/sessions-picker-factory.js +1 -1
- package/dist/commands/sessions-stop.d.ts +24 -0
- package/dist/commands/sessions-stop.js +66 -0
- package/dist/commands/sessions-trace.d.ts +82 -0
- package/dist/commands/sessions-trace.js +387 -0
- package/dist/commands/sessions.js +4 -0
- package/dist/commands/ssh.d.ts +15 -0
- package/dist/commands/ssh.js +194 -16
- package/dist/commands/teams.js +34 -2
- package/dist/commands/view.d.ts +2 -0
- package/dist/commands/view.js +18 -31
- package/dist/commands/watchdog.js +9 -14
- package/dist/lib/account-capabilities.d.ts +4 -0
- package/dist/lib/account-capabilities.js +13 -9
- package/dist/lib/account-registry.d.ts +2 -0
- package/dist/lib/account-registry.js +30 -2
- package/dist/lib/accounting/rotate.d.ts +9 -0
- package/dist/lib/accounting/rotate.js +12 -2
- package/dist/lib/accounting/usage.d.ts +70 -3
- package/dist/lib/accounting/usage.js +235 -63
- package/dist/lib/agent-modes.js +29 -1
- package/dist/lib/agent-spec/agents.d.ts +4 -3
- package/dist/lib/agent-spec/agents.js +14 -6
- package/dist/lib/analytics/mix-commands.d.ts +1 -1
- package/dist/lib/analytics/mix-commands.js +2 -2
- package/dist/lib/auth-health.d.ts +13 -3
- package/dist/lib/auth-health.js +50 -8
- package/dist/lib/browser/devices.d.ts +19 -0
- package/dist/lib/browser/devices.js +23 -0
- package/dist/lib/browser/ipc.d.ts +1 -1
- package/dist/lib/browser/ipc.js +33 -7
- package/dist/lib/browser/profiles.d.ts +106 -1
- package/dist/lib/browser/profiles.js +300 -17
- package/dist/lib/browser/remote-control.d.ts +26 -2
- package/dist/lib/browser/remote-control.js +33 -3
- package/dist/lib/browser/runtime-state.d.ts +9 -0
- package/dist/lib/browser/runtime-state.js +24 -8
- package/dist/lib/browser/service.d.ts +37 -0
- package/dist/lib/browser/service.js +78 -20
- package/dist/lib/browser/sessions-list.d.ts +1 -3
- package/dist/lib/browser/sessions-list.js +3 -16
- package/dist/lib/browser/types.d.ts +12 -1
- package/dist/lib/codex-policy.d.ts +11 -1
- package/dist/lib/codex-policy.js +20 -5
- package/dist/lib/config-keys.d.ts +4 -3
- package/dist/lib/config-keys.js +17 -7
- package/dist/lib/daemon/runner.js +15 -2
- package/dist/lib/daemon-ticks.js +2 -2
- package/dist/lib/device-config.d.ts +25 -8
- package/dist/lib/device-config.js +90 -17
- package/dist/lib/devices/config-migration.d.ts +7 -0
- package/dist/lib/devices/config-migration.js +67 -3
- package/dist/lib/devices/health.d.ts +27 -2
- package/dist/lib/devices/health.js +39 -9
- package/dist/lib/devices/interactive-host.d.ts +15 -0
- package/dist/lib/devices/interactive-host.js +53 -0
- package/dist/lib/devices/registry.d.ts +61 -4
- package/dist/lib/devices/registry.js +94 -38
- package/dist/lib/devices/stats-cache.d.ts +6 -0
- package/dist/lib/devices/stats-cache.js +10 -2
- package/dist/lib/exec.d.ts +5 -3
- package/dist/lib/exec.js +32 -16
- package/dist/lib/feed/answer.d.ts +29 -0
- package/dist/lib/feed/answer.js +145 -0
- package/dist/lib/feed/attention.d.ts +83 -0
- package/dist/lib/feed/attention.js +0 -0
- package/dist/lib/feed/feed.d.ts +109 -0
- package/dist/lib/feed/feed.js +154 -3
- package/dist/lib/feed/pr-status.d.ts +14 -0
- package/dist/lib/feed/pr-status.js +47 -0
- package/dist/lib/feed/watch.d.ts +59 -0
- package/dist/lib/feed/watch.js +180 -0
- package/dist/lib/fleet/capture.js +6 -0
- package/dist/lib/fleet/remote-login.js +8 -3
- package/dist/lib/fleet/types.d.ts +17 -0
- package/dist/lib/harness/adapter.d.ts +11 -0
- package/dist/lib/harness/adapters/claude.js +38 -24
- package/dist/lib/harness/adapters/codex.js +2 -4
- package/dist/lib/hooks/cache.js +8 -0
- package/dist/lib/hooks/match.d.ts +3 -0
- package/dist/lib/hooks/match.js +25 -0
- package/dist/lib/hosts/passthrough.js +16 -0
- package/dist/lib/hosts/registry.js +7 -0
- package/dist/lib/menubar/MenubarHelper.app/Contents/CodeResources +0 -0
- package/dist/lib/menubar/MenubarHelper.app/Contents/MacOS/MenubarHelper +0 -0
- package/dist/lib/menubar/install-menubar.d.ts +13 -0
- package/dist/lib/menubar/install-menubar.js +26 -2
- package/dist/lib/open-url.d.ts +60 -2
- package/dist/lib/open-url.js +167 -12
- package/dist/lib/refresh-coordinator.d.ts +1 -1
- package/dist/lib/refresh-coordinator.js +1 -1
- package/dist/lib/secrets/Agents CLI.app/Contents/CodeResources +0 -0
- package/dist/lib/secrets/Agents CLI.app/Contents/Info.plist +2 -0
- package/dist/lib/secrets/Agents CLI.app/Contents/MacOS/Agents CLI +0 -0
- package/dist/lib/secrets/Agents CLI.app/Contents/Resources/AppIcon.icns +0 -0
- package/dist/lib/secrets/Agents CLI.app/Contents/_CodeSignature/CodeResources +13 -1
- package/dist/lib/session/active.d.ts +67 -0
- package/dist/lib/session/active.js +69 -1
- package/dist/lib/session/db.js +4 -2
- package/dist/lib/session/discover.d.ts +2 -0
- package/dist/lib/session/discover.js +12 -6
- package/dist/lib/session/prompt.d.ts +35 -0
- package/dist/lib/session/prompt.js +56 -0
- package/dist/lib/session/remote/watch.d.ts +1 -1
- package/dist/lib/session/remote/watch.js +6 -1
- package/dist/lib/session/render.js +7 -3
- package/dist/lib/session/session-cache.js +5 -1
- package/dist/lib/session/trajectory-compare.d.ts +47 -0
- package/dist/lib/session/trajectory-compare.js +116 -0
- package/dist/lib/session/trajectory-html.d.ts +15 -0
- package/dist/lib/session/trajectory-html.js +750 -0
- package/dist/lib/session/trajectory-lineage.d.ts +92 -0
- package/dist/lib/session/trajectory-lineage.js +195 -0
- package/dist/lib/session/trajectory-text.d.ts +37 -0
- package/dist/lib/session/trajectory-text.js +277 -0
- package/dist/lib/session/trajectory.d.ts +102 -0
- package/dist/lib/session/trajectory.js +335 -0
- package/dist/lib/startup/command-registry.d.ts +3 -1
- package/dist/lib/startup/command-registry.js +5 -2
- package/dist/lib/state.d.ts +1 -1
- package/dist/lib/state.js +4 -2
- package/dist/lib/teams/agents.js +9 -0
- package/dist/lib/terminal/inject.d.ts +19 -0
- package/dist/lib/terminal/inject.js +19 -9
- package/dist/lib/tmux/session.d.ts +46 -13
- package/dist/lib/tmux/session.js +173 -27
- package/dist/lib/types.d.ts +16 -0
- package/dist/lib/usage-backoff.d.ts +2 -1
- package/dist/lib/usage-backoff.js +60 -19
- package/dist/lib/usage-refresh.d.ts +17 -3
- package/dist/lib/usage-refresh.js +57 -11
- package/dist/lib/watchdog/log.d.ts +1 -1
- package/dist/lib/watchdog/log.js +1 -1
- package/dist/lib/watchdog/runner.d.ts +36 -45
- package/dist/lib/watchdog/runner.js +150 -119
- package/dist/lib/watchdog/service.d.ts +0 -1
- package/dist/lib/watchdog/service.js +0 -1
- package/dist/lib/watchdog/watchdog-agent.d.ts +38 -0
- package/dist/lib/watchdog/watchdog-agent.js +59 -0
- package/dist/lib/watchdog/watchdog.d.ts +11 -2
- package/dist/lib/watchdog/watchdog.js +37 -104
- package/package.json +2 -2
- package/dist/commands/usage.d.ts +0 -27
- package/dist/commands/usage.js +0 -96
package/README.md
CHANGED
|
@@ -54,7 +54,7 @@ agents setup status # readiness for browser, computer, fleet,
|
|
|
54
54
|
agents run claude "explain this repo" # run any agent on your existing subscription
|
|
55
55
|
```
|
|
56
56
|
|
|
57
|
-
`agents setup` is interactive and idempotent -- safe to re-run on any machine. Once core setup exists, it opens a status-aware menu for browser, computer, secrets, fleet, share, watchdog, and device preferences; each choice delegates to the same wizard available under `agents setup <capability>`. In CI or another non-TTY, bare setup prints the checklist without prompting. The `agi-cli.sh` one-liner installs this same canonical `@phnx-labs/agents-cli` package. Prefer bun? `bun install -g @phnx-labs/agents-cli` works too.
|
|
57
|
+
Everything here — and every other command in this README — is free and needs no account; the optional `agents auth login` exists only for [team spaces](#sign-in). `agents setup` is interactive and idempotent -- safe to re-run on any machine. Once core setup exists, it opens a status-aware menu for browser, computer, secrets, fleet, share, watchdog, and device preferences; each choice delegates to the same wizard available under `agents setup <capability>`. In CI or another non-TTY, bare setup prints the checklist without prompting. The `agi-cli.sh` one-liner installs this same canonical `@phnx-labs/agents-cli` package. Prefer bun? `bun install -g @phnx-labs/agents-cli` works too.
|
|
58
58
|
|
|
59
59
|
Full path -- installing harnesses, logging in, smoke-testing `agents teams`, and setting up your own fleet: [`apps/cli/docs/QUICKSTART.md`](apps/cli/docs/QUICKSTART.md).
|
|
60
60
|
|
|
@@ -224,8 +224,8 @@ Supports plan (read-only), edit, auto, and skip modes, effort levels, JSON outpu
|
|
|
224
224
|
Treat `skip` as a last-resort escape hatch. In direct-exec runs (without `--acp`),
|
|
225
225
|
agi-cli forwards the harness's native no-prompt flag; it does not add another
|
|
226
226
|
safety layer. Prefer `auto` where it adds a safer automatic policy (smart classifier
|
|
227
|
-
on Claude/Copilot,
|
|
228
|
-
everywhere else. For headless Kimi, `edit`, `auto`, and `skip` all use the same
|
|
227
|
+
on Claude/Copilot, never-prompt over a sandbox on Codex, native high-auto mode on
|
|
228
|
+
Droid, or interactive Kimi), or `edit` everywhere else. For headless Kimi, `edit`, `auto`, and `skip` all use the same
|
|
229
229
|
already-auto-approved `-p` behavior, so prefer `edit` rather than signaling a blanket
|
|
230
230
|
bypass. Harnesses without a native bypass flag reject direct-exec `skip`.
|
|
231
231
|
|
|
@@ -247,11 +247,13 @@ permission requests at the ACP protocol layer: it selects `allow_always` when of
|
|
|
247
247
|
otherwise the first permission option offered by the server. The same last-resort
|
|
248
248
|
warning applies.
|
|
249
249
|
|
|
250
|
-
Codex has
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
250
|
+
Codex has three managed permission profiles rather than a smart classifier. `edit`
|
|
251
|
+
and `auto` share one sandbox — the workspace, `~/.agents`, and regenerable toolchain
|
|
252
|
+
caches are writable, and network access is enabled — and differ only in approvals:
|
|
253
|
+
`edit` requests them on demand, while `auto` never prompts, so a sandbox-denied
|
|
254
|
+
command fails and the agent works around it instead of stopping on a dialog nobody
|
|
255
|
+
is watching. When `--mode` is omitted for Codex, `edit` is used. An explicit
|
|
256
|
+
`--mode plan` keeps the filesystem read-only while leaving network access on.
|
|
255
257
|
`agents run codex --mode skip` is different:
|
|
256
258
|
it bypasses approvals **and** removes the sandbox. `full` remains an alias for `skip`,
|
|
257
259
|
but new scripts should use the explicit `skip` name.
|
|
@@ -295,6 +297,11 @@ agents sessions render a1b2c3d4 -o session.md
|
|
|
295
297
|
# Or publish it as a link in one step (unlisted + redacted by default)
|
|
296
298
|
agents sessions share a1b2c3d4
|
|
297
299
|
|
|
300
|
+
# Visualize a session as a trajectory -- tool-call waterfall, timing, stalls, errors
|
|
301
|
+
agents trace a1b2c3d4 # opens the HTML (a person at a terminal)
|
|
302
|
+
agents trace a1b2c3d4 --text --errors-only # compact text an agent reads in-context
|
|
303
|
+
agents sessions trace a1b2c3d4 --json # the versioned sessions-trace envelope
|
|
304
|
+
|
|
298
305
|
# Just the last 3 turns, user messages only
|
|
299
306
|
agents sessions a1b2c3d4 --last 3 --include user
|
|
300
307
|
|
|
@@ -434,6 +441,8 @@ agents feed --flat # one row per agent (legacy)
|
|
|
434
441
|
agents feed --device mac-mini # scope the view to one or more hosts
|
|
435
442
|
agents feed --local # skip the SSH fan-out
|
|
436
443
|
agents feed --json # blocks stamped with their outcome key
|
|
444
|
+
agents feed watch --json # versioned agents + attention + activity NDJSON
|
|
445
|
+
agents feed answer <key> --choice 0 # first answer wins; route over the recorded reply rail
|
|
437
446
|
agents feed post --title "Halfway done" "CI green, watching merge" # title + body
|
|
438
447
|
```
|
|
439
448
|
|
|
@@ -600,7 +609,7 @@ agents hosts check gpu-box # reachable? which agi-cli version?
|
|
|
600
609
|
|
|
601
610
|
# Run there instead of locally
|
|
602
611
|
agents run claude --device gpu-box "profile this build" # headless: follows live by default
|
|
603
|
-
agents run claude --device gpu-box # no prompt → interactive TTY over SSH
|
|
612
|
+
agents run claude --device gpu-box # no prompt → direct interactive TTY over SSH
|
|
604
613
|
agents accounts sync work --device gpu-box # portable provider account only; native OAuth stays local
|
|
605
614
|
agents run claude --device auto "…" # affinity-pick host from 14d usage (harness stays claude)
|
|
606
615
|
agents run claude --device auto "…" # same — auto is a host value, not a harness name
|
|
@@ -638,10 +647,12 @@ agents devices sync # ingest `tailscale status`
|
|
|
638
647
|
agents devices ignore ipad # sync the dismissal via agents.yaml fleet.discovery
|
|
639
648
|
agents repo push user # carry device decisions to the other machines
|
|
640
649
|
agents repo pull user # pull and reconcile them into this machine's registry
|
|
641
|
-
agents devices list #
|
|
650
|
+
agents devices list # spec (cores/RAM/disk) + load/mem/disk + headroom + role + description
|
|
642
651
|
agents devices list --live # force a live probe of every device (alias of --refresh)
|
|
643
|
-
agents devices list --full # add per-device
|
|
652
|
+
agents devices list --full # add per-device free/total RAM detail
|
|
644
653
|
agents devices list --no-stats # instant: names/addresses only, skip the probe
|
|
654
|
+
agents devices describe mac-mini "signing + notarize box" # one-line purpose, synced + shown in the list
|
|
655
|
+
agents devices ignored # dismissed nodes — when, and which machine dismissed them
|
|
645
656
|
agents devices config zion interactive.host zion # the device agents show YOU artifacts on (★ in the list)
|
|
646
657
|
agents devices config mac-mini agents.max-concurrent 4 # per-device settings (tracked devices/<name>/agents.yaml)
|
|
647
658
|
agents devices config mac-mini scheduler.enabled off # bare `devices config <name>` opens a settings menu (TTY)
|
|
@@ -814,7 +825,7 @@ tools:
|
|
|
814
825
|
---
|
|
815
826
|
```
|
|
816
827
|
|
|
817
|
-
Workflows that need to write — post PR comments, edit files, send Slack — should run with `--mode edit`, or `--mode auto` on Claude Code
|
|
828
|
+
Workflows that need to write — post PR comments, edit files, send Slack — should run with `--mode edit`, or `--mode auto` on Claude Code, GitHub Copilot, and Codex. Reserve `--mode skip` (legacy alias: `full`) for last-resort bypasses. `agents run` defaults to `--mode plan` for other harnesses; Codex defaults to its safe writable profile. An explicit Codex `--mode plan` is read-only with network access.
|
|
818
829
|
|
|
819
830
|
Resolution is project > user > system: a `<repo>/.agents/workflows/<name>/` overrides a same-named workflow in `~/.agents/workflows/`. Commit project workflows with your repo so teammates get the same pipeline.
|
|
820
831
|
|
|
@@ -898,7 +909,7 @@ agents setup mine remove jack --purge
|
|
|
898
909
|
|
|
899
910
|
Under the hood, `init` drops a pure pass-through shim in `~/.agents/.cache/shims/<name>` (already on `PATH`) that sets `AGENTS_BRAND` and forwards every argument to the same binary — nothing is copied or forked. The brand's config lives in `~/.agents/agents.yaml` (`brands.<name>`), so it rides `agents repo push/pull` across your fleet. Disabling a command hides it **only** under that brand; plain `agents` / `ag` keep every command. Curated skills/plugins/MCP ride a per-brand [resource profile](apps/cli/docs/profiles.md). Full reference: [Make it yours](apps/cli/docs/mine.md).
|
|
900
911
|
|
|
901
|
-
>
|
|
912
|
+
> Branded builds are free for personal and commercial use alike. New versions ship under FSL-1.1-Apache-2.0: every user and company may use, modify, and redistribute; only offering agents-cli itself as a competing commercial product or service is barred, and each version automatically becomes Apache-2.0 two years after release.
|
|
902
913
|
|
|
903
914
|
---
|
|
904
915
|
|
|
@@ -1005,7 +1016,7 @@ agents browser profiles create cloud \
|
|
|
1005
1016
|
|
|
1006
1017
|
## Sign in
|
|
1007
1018
|
|
|
1008
|
-
`agents auth` signs this machine in to **Phoenix ID
|
|
1019
|
+
Signing in is **optional**. Every local feature — `agents run`, sessions, teams, fleet dispatch, secrets, browser, computer — works with no account. The one thing an account unlocks is **team spaces**, the hosted surface under `agents auth space`. `agents auth` signs this machine in to **Phoenix ID**, the Phoenix Labs account layer behind team spaces. Sign-in is Google-only and runs a device-code flow: the CLI shows a code, your browser confirms it, and the CLI picks the session up.
|
|
1009
1020
|
|
|
1010
1021
|
```bash
|
|
1011
1022
|
agents auth login # shows a code, opens a Phoenix-branded page
|
|
@@ -1314,7 +1325,7 @@ Two repos with the same shape, different roles:
|
|
|
1314
1325
|
|
|
1315
1326
|
See [docs/concepts.md](apps/cli/docs/concepts.md) for the full mental model: DotAgents repos, resource kinds, and how resolution works end-to-end.
|
|
1316
1327
|
|
|
1317
|
-
Other useful commands: `agents doctor` checks CLI availability and resource sync drift, `agents
|
|
1328
|
+
Other useful commands: `agents doctor` checks CLI availability and resource sync drift, `agents view` shows per-account quota/rate-limit data for installed agents, `agents config budget` shows cross-vendor spend caps and current spend-to-cap (and enforces pre-flight estimates + a hard-cap kill-switch on every run — see [docs/observability.md](apps/cli/docs/observability.md#budget-guardrails-agents-budget)), `agents import` adopts an existing unmanaged install, `agents trash` lists and restores soft-deleted version directories, and `agents subagents` installs reusable subagent definitions for parent-agent workflows.
|
|
1318
1329
|
|
|
1319
1330
|
---
|
|
1320
1331
|
|
|
@@ -1499,7 +1510,7 @@ Claude Code, Codex CLI, Antigravity, Grok Build, and others each have their own
|
|
|
1499
1510
|
|
|
1500
1511
|
### Is it free?
|
|
1501
1512
|
|
|
1502
|
-
Yes. This developer tool is entirely free because we believe developers should have the best tools — fast and robust — so they can create the best products for their users.
|
|
1513
|
+
Yes — every feature, with no account and no signup. `agents run`, sessions, teams, fleet dispatch, secrets, browser, and computer automation all work the moment you install. The optional `agents auth login` exists only to unlock hosted team spaces (`agents auth space`); there are no paid tiers. This developer tool is entirely free because we believe developers should have the best tools — fast and robust — so they can create the best products for their users.
|
|
1503
1514
|
|
|
1504
1515
|
### Is this like `nvm` / `mise` / `asdf` for AI agents?
|
|
1505
1516
|
|
|
@@ -1533,7 +1544,9 @@ macOS and Linux. Windows via WSL works but isn't first-class yet.
|
|
|
1533
1544
|
|
|
1534
1545
|
**macOS-only features:** Keychain-based secrets (`agents secrets`, `agents accounts add`) require macOS. Default iCloud sync for bundles requires macOS + iCloud Keychain enabled; use `--no-icloud-sync` for device-local bundles. On Linux, use environment variables or `.env` files for API keys. Native Linux credential store support is planned.
|
|
1535
1546
|
|
|
1536
|
-
Interactive
|
|
1547
|
+
Interactive runs spawn directly by default. Enable `tmux.enabled` on a device to
|
|
1548
|
+
give each run an addressable pane for `agents message`, injection, and `agents
|
|
1549
|
+
focus`; tmux-backed runs require tmux 3.2 or newer.
|
|
1537
1550
|
|
|
1538
1551
|
### Do I need Node.js?
|
|
1539
1552
|
|
|
@@ -1592,4 +1605,4 @@ Commands in [`apps/cli/src/commands/`](apps/cli/src/commands/), libraries in [`a
|
|
|
1592
1605
|
|
|
1593
1606
|
## License
|
|
1594
1607
|
|
|
1595
|
-
Apache-2.0 -- see [LICENSE](./LICENSE).
|
|
1608
|
+
FSL-1.1-Apache-2.0 -- see [LICENSE](./LICENSE). Free for every user and company to use, modify, and redistribute; the only barred use is offering agents-cli itself as a competing commercial product or service. Each version automatically becomes Apache-2.0 two years after its release.
|
|
@@ -63,8 +63,8 @@ export declare const loadMenubar: ModuleLoader;
|
|
|
63
63
|
export declare const loadSync: ModuleLoader;
|
|
64
64
|
export declare const loadRefreshRules: ModuleLoader;
|
|
65
65
|
export declare const loadFactory: ModuleLoader;
|
|
66
|
-
export declare const loadUsage: ModuleLoader;
|
|
67
66
|
export declare const loadInsights: ModuleLoader;
|
|
67
|
+
export declare const loadTrace: ModuleLoader;
|
|
68
68
|
export declare const loadPerf: ModuleLoader;
|
|
69
69
|
export declare const loadPty: ModuleLoader;
|
|
70
70
|
export declare const loadTmux: ModuleLoader;
|
|
@@ -65,8 +65,8 @@ export const loadMenubar = async () => (await import('../commands/menubar.js')).
|
|
|
65
65
|
export const loadSync = async () => (await import('../commands/sync.js')).registerSyncCommand;
|
|
66
66
|
export const loadRefreshRules = async () => (await import('../commands/refresh-rules.js')).registerRefreshRulesCommand;
|
|
67
67
|
export const loadFactory = async () => (await import('../commands/factory.js')).registerFactoryCommands;
|
|
68
|
-
export const loadUsage = async () => (await import('../commands/usage.js')).registerUsageCommand;
|
|
69
68
|
export const loadInsights = async () => (await import('../commands/insights.js')).registerInsightsCommand;
|
|
69
|
+
export const loadTrace = async () => (await import('../commands/sessions-trace.js')).registerTraceCommand;
|
|
70
70
|
export const loadPerf = async () => (await import('../commands/perf.js')).registerPerfCommand;
|
|
71
71
|
export const loadPty = async () => (await import('../commands/pty.js')).registerPtyCommands;
|
|
72
72
|
export const loadTmux = async () => (await import('../commands/tmux.js')).registerTmuxCommands;
|
|
@@ -172,8 +172,10 @@ export const COMMAND_LOADERS = {
|
|
|
172
172
|
sync: [loadSync],
|
|
173
173
|
'refresh-rules': [loadRefreshRules],
|
|
174
174
|
factory: [loadFactory],
|
|
175
|
-
usage: [loadUsage],
|
|
176
175
|
insights: [loadInsights],
|
|
176
|
+
// `agents trace` is a top-level alias of `agents sessions trace` (precedent:
|
|
177
|
+
// `agents insights` aliases `agents sessions insights`). One implementation.
|
|
178
|
+
trace: [loadTrace],
|
|
177
179
|
perf: [loadPerf],
|
|
178
180
|
pty: [loadPty],
|
|
179
181
|
tmux: [loadTmux],
|
|
@@ -3,7 +3,7 @@ import { password } from '@inquirer/prompts';
|
|
|
3
3
|
import { setHelpSections } from '../lib/help.js';
|
|
4
4
|
import { readMeta, updateMeta } from '../lib/state.js';
|
|
5
5
|
import { ALL_AGENT_IDS, getAccountInfo, resolveAgentName } from '../lib/agents.js';
|
|
6
|
-
import { getVersionHomePath, listInstalledVersions } from '../lib/installations/versions.js';
|
|
6
|
+
import { getGlobalDefault, getVersionHomePath, listInstalledVersions } from '../lib/installations/versions.js';
|
|
7
7
|
import { assertNativeAccountNameable, nativeAccountCapability, nativeIdentityKey } from '../lib/account-capabilities.js';
|
|
8
8
|
import { collectRunCandidates } from '../lib/accounting/rotate.js';
|
|
9
9
|
import { isInteractiveTerminal } from './utils.js';
|
|
@@ -16,7 +16,10 @@ import { runDevicesAccounts } from './ssh.js';
|
|
|
16
16
|
import { discoverNativeAccounts } from '../lib/account-catalog.js';
|
|
17
17
|
import { readAndResolveBundleEnv } from '../lib/secrets/bundles.js';
|
|
18
18
|
import { getAccountProvider, listAccountProviders } from '../lib/account-provider-registry.js';
|
|
19
|
-
import { accountBindings, addAccount, addNativeAccount, bindAccount, findAccount, findUnifiedAccount, inspectAccount, listNativeAccounts, readAccountRegistry, removeAccount, renameAccount, setAccountSecret, unbindAccount } from '../lib/account-registry.js';
|
|
19
|
+
import { accountBindings, addAccount, addNativeAccount, bindAccount, findAccount, findUnifiedAccount, inspectAccount, labelNativeAccount, listNativeAccounts, readAccountRegistry, removeAccount, renameAccount, setAccountSecret, unbindAccount } from '../lib/account-registry.js';
|
|
20
|
+
function cleanCommandError(command, err) {
|
|
21
|
+
command.error(err instanceof Error ? err.message : String(err), { exitCode: 1, code: 'accounts.error' });
|
|
22
|
+
}
|
|
20
23
|
function parseInstallation(raw) {
|
|
21
24
|
const at = raw.lastIndexOf('@');
|
|
22
25
|
if (at < 1 || at === raw.length - 1)
|
|
@@ -273,12 +276,43 @@ export function registerAccountsCommand(program) {
|
|
|
273
276
|
});
|
|
274
277
|
accounts.command('name <source> <name>')
|
|
275
278
|
.description('Name a signed-in native installation without copying its OAuth credentials')
|
|
276
|
-
.action(async (source, name) => {
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
279
|
+
.action(async (source, name, _o, command) => {
|
|
280
|
+
try {
|
|
281
|
+
const identity = await nativeIdentityFromSource(source);
|
|
282
|
+
const account = addNativeAccount(name, identity.agent, identity.identityKey, identity.identityLabel, identity.scope);
|
|
283
|
+
console.log(chalk.green(`Named ${source} as ${account.name}.`));
|
|
284
|
+
if (account.scope === 'device')
|
|
285
|
+
console.log(chalk.gray(`${identity.agent} authentication is device-scoped; attach '${account.name}' to '${identity.agent}', not an individual version.`));
|
|
286
|
+
}
|
|
287
|
+
catch (err) {
|
|
288
|
+
cleanCommandError(command, err);
|
|
289
|
+
}
|
|
290
|
+
});
|
|
291
|
+
accounts.command('label <harness> [label]')
|
|
292
|
+
.description('Label a native login independently of its installed harness version')
|
|
293
|
+
.option('--account <email-or-id>', 'Native identity to label when the harness has multiple logins')
|
|
294
|
+
.action(async (harness, label, o, command) => {
|
|
295
|
+
try {
|
|
296
|
+
const agent = parseHarness(harness);
|
|
297
|
+
assertNativeAccountNameable(agent);
|
|
298
|
+
const candidates = (await collectRunCandidates(agent)).filter(candidate => candidate.signedIn);
|
|
299
|
+
const needle = o.account?.toLowerCase();
|
|
300
|
+
const selected = needle
|
|
301
|
+
? candidates.find(candidate => candidate.email?.toLowerCase() === needle || candidate.accountKey?.toLowerCase() === needle)
|
|
302
|
+
: candidates.find(candidate => candidate.version === getGlobalDefault(agent)) ?? (candidates.length === 1 ? candidates[0] : undefined);
|
|
303
|
+
if (!selected)
|
|
304
|
+
throw new Error(needle
|
|
305
|
+
? `Unknown ${agent} account '${o.account}'.`
|
|
306
|
+
: `Multiple ${agent} accounts are connected; pass --account <email|id>.`);
|
|
307
|
+
const identityKey = selected.accountKey ?? selected.email?.toLowerCase();
|
|
308
|
+
if (!identityKey)
|
|
309
|
+
throw new Error(`${agent} account '${selected.version}' has no stable identity.`);
|
|
310
|
+
const account = labelNativeAccount(agent, identityKey, selected.email ?? undefined, label, nativeAccountCapability(agent).scope);
|
|
311
|
+
console.log(chalk.green(`Labeled ${agent} account ${selected.email ?? identityKey} as '${account.name}'.`));
|
|
312
|
+
}
|
|
313
|
+
catch (err) {
|
|
314
|
+
cleanCommandError(command, err);
|
|
315
|
+
}
|
|
282
316
|
});
|
|
283
317
|
accounts.command('attach <account> <target>')
|
|
284
318
|
.description('Attach a named account to a native installation or custom harness')
|
|
@@ -329,15 +363,25 @@ export function registerAccountsCommand(program) {
|
|
|
329
363
|
accounts.command('remove <name>').description('Remove an account and its device-local credential').action((name) => removeAccount(name));
|
|
330
364
|
accounts.command('set-default <agent> <name>')
|
|
331
365
|
.description('Use this account for a harness when --account is omitted')
|
|
332
|
-
.action((agentRaw, name) => {
|
|
333
|
-
|
|
334
|
-
|
|
366
|
+
.action((agentRaw, name, _o, command) => {
|
|
367
|
+
try {
|
|
368
|
+
const { agent, account } = setDefaultAccount(agentRaw, name);
|
|
369
|
+
console.log(chalk.green(`${agent} now uses account '${account.name}' unless --account overrides it.`));
|
|
370
|
+
}
|
|
371
|
+
catch (err) {
|
|
372
|
+
cleanCommandError(command, err);
|
|
373
|
+
}
|
|
335
374
|
});
|
|
336
375
|
const switchCmd = accounts.command('switch <harness> [account]')
|
|
337
376
|
.description('Pick the default account for a harness')
|
|
338
377
|
.option('--json', 'Machine-readable account list or the resulting default')
|
|
339
378
|
.action(async (harness, account, o, command) => {
|
|
340
|
-
|
|
379
|
+
try {
|
|
380
|
+
await runAccountsSwitch(harness, account, { json: !!(o.json || command.optsWithGlobals().json) });
|
|
381
|
+
}
|
|
382
|
+
catch (err) {
|
|
383
|
+
cleanCommandError(command, err);
|
|
384
|
+
}
|
|
341
385
|
});
|
|
342
386
|
accounts.command('clear-default <agent>')
|
|
343
387
|
.description('Return a harness to native login or balanced account selection')
|
package/dist/commands/auth.js
CHANGED
|
@@ -3,9 +3,10 @@ import { PhoenixApiError, clearSession, createSpace, createSpaceInvite, fetchWho
|
|
|
3
3
|
import { setHelpSections } from '../lib/help.js';
|
|
4
4
|
import { runOrDie } from '../lib/format.js';
|
|
5
5
|
/**
|
|
6
|
-
* `agents auth` — sign in to Phoenix ID, the account layer behind
|
|
7
|
-
*
|
|
8
|
-
*
|
|
6
|
+
* `agents auth` — sign in to Phoenix ID, the account layer behind team spaces.
|
|
7
|
+
* Signing in is optional: every local feature works with no account. Everything
|
|
8
|
+
* here goes through `lib/identity`; this file builds no URLs and reads no
|
|
9
|
+
* credential files of its own.
|
|
9
10
|
*/
|
|
10
11
|
function sleep(ms) {
|
|
11
12
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
@@ -90,14 +91,15 @@ async function requireSpace(ref) {
|
|
|
90
91
|
export function registerAuthCommand(program) {
|
|
91
92
|
const auth = program
|
|
92
93
|
.command('auth')
|
|
93
|
-
.description('Sign in to Phoenix ID — the account layer behind spaces
|
|
94
|
+
.description('Sign in to Phoenix ID — the account layer behind team spaces');
|
|
94
95
|
setHelpSections(auth, {
|
|
95
96
|
examples: `agents auth login # device-code sign-in via your browser
|
|
96
97
|
agents auth whoami # who this machine is signed in as
|
|
97
98
|
agents auth space create "Design Team" # start a space
|
|
98
99
|
agents auth space invite ada@example.com # add a teammate
|
|
99
100
|
agents auth logout # clear this machine only`,
|
|
100
|
-
notes: `
|
|
101
|
+
notes: `Signing in is optional — every local feature works with no account; team spaces are what it unlocks.
|
|
102
|
+
Sign-in is Google-only and opens a Phoenix-branded page; the CLI never sees a password.
|
|
101
103
|
The session lives in this machine's agents state dir, so logging out here signs out nothing else.
|
|
102
104
|
Point at a different backend with PHOENIX_ID_BASE (defaults to the production service).`,
|
|
103
105
|
});
|
|
@@ -10,12 +10,13 @@
|
|
|
10
10
|
* second renderer. Interactive routing and the browse loop live in
|
|
11
11
|
* `sessions-picker-factory.ts` (shared with the computer twin).
|
|
12
12
|
*/
|
|
13
|
+
import { showFile } from '../lib/open-url.js';
|
|
13
14
|
import chalk from 'chalk';
|
|
14
15
|
import { itemPicker } from '../lib/picker.js';
|
|
15
16
|
import { isPromptCancelled } from './utils.js';
|
|
16
17
|
import { buildPreview } from './sessions-picker.js';
|
|
17
18
|
import { createSessionsPickerCommand } from './sessions-picker-factory.js';
|
|
18
|
-
import { runBrowserSessions, buildBrowserSessionRows, matchesBrowserSessionRow,
|
|
19
|
+
import { runBrowserSessions, buildBrowserSessionRows, matchesBrowserSessionRow, formatBytes, } from '../lib/browser/sessions-list.js';
|
|
19
20
|
import { formatRelativeTime } from '../lib/session/relative-time.js';
|
|
20
21
|
const KIND_LABEL = {
|
|
21
22
|
screenshot: 'shots',
|
|
@@ -89,11 +90,12 @@ function formatArtifactLabel(a) {
|
|
|
89
90
|
const age = formatRelativeTime(new Date(a.mtimeMs).toISOString());
|
|
90
91
|
return `${age.padEnd(11)} ${a.name.padEnd(34)} ${formatBytes(a.bytes).padStart(8)}`;
|
|
91
92
|
}
|
|
92
|
-
/** Open one artifact
|
|
93
|
-
*
|
|
94
|
-
|
|
93
|
+
/** Open one artifact, printing its path (matches the non-interactive `--open`
|
|
94
|
+
* behavior) and any open failure. Routes through the same viewer seam as
|
|
95
|
+
* `--open`, so the interactive and non-interactive halves cannot diverge. */
|
|
96
|
+
async function openAndReport(a) {
|
|
95
97
|
console.log(a.path);
|
|
96
|
-
if (
|
|
98
|
+
if ((await showFile(a.path)).via === 'none')
|
|
97
99
|
console.error(`Could not open ${a.path}`);
|
|
98
100
|
}
|
|
99
101
|
/** Second-level picker over one row's captures, newest first. Enter opens the
|
|
@@ -136,12 +138,12 @@ const browserSessionsPicker = createSessionsPickerCommand({
|
|
|
136
138
|
return;
|
|
137
139
|
}
|
|
138
140
|
if (row.artifacts.length === 1) {
|
|
139
|
-
openAndReport(row.artifacts[0]);
|
|
141
|
+
await openAndReport(row.artifacts[0]);
|
|
140
142
|
return;
|
|
141
143
|
}
|
|
142
144
|
const artifact = await pickArtifact(row);
|
|
143
145
|
if (artifact)
|
|
144
|
-
openAndReport(artifact);
|
|
146
|
+
await openAndReport(artifact);
|
|
145
147
|
},
|
|
146
148
|
});
|
|
147
149
|
/** True when the interactive picker should open instead of the printed table:
|