@phnx-labs/agents-cli 1.22.40 → 1.22.41
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 +22 -0
- package/README.md +5 -0
- package/dist/bin/agents +0 -0
- package/dist/bootstrap.js +0 -1
- package/dist/cli/command-registry.js +1 -2
- package/dist/commands/browser.d.ts +15 -0
- package/dist/commands/browser.js +115 -40
- package/dist/commands/feed.js +3 -11
- package/dist/commands/secrets.js +87 -97
- package/dist/commands/sessions-picker.d.ts +1 -0
- package/dist/commands/sessions-picker.js +27 -5
- package/dist/commands/sessions-share.d.ts +25 -0
- package/dist/commands/sessions-share.js +166 -0
- package/dist/commands/sessions.js +2 -0
- package/dist/commands/setup-browser.js +1 -1
- package/dist/commands/setup-preferences.js +2 -2
- package/dist/commands/webhook.js +14 -9
- package/dist/lib/browser/cdp.js +4 -0
- package/dist/lib/browser/chrome.js +12 -1
- package/dist/lib/browser/drivers/ssh.js +1 -0
- package/dist/lib/browser/profiles.d.ts +3 -3
- package/dist/lib/browser/profiles.js +7 -7
- package/dist/lib/browser/service.d.ts +24 -1
- package/dist/lib/browser/service.js +38 -14
- package/dist/lib/browser/types.d.ts +1 -1
- package/dist/lib/daemon-webhooks.d.ts +3 -1
- package/dist/lib/daemon-webhooks.js +12 -7
- package/dist/lib/device-config.js +1 -1
- package/dist/lib/menubar/MenubarHelper.app/Contents/CodeResources +0 -0
- package/dist/lib/menubar/MenubarHelper.app/Contents/MacOS/MenubarHelper +0 -0
- package/dist/lib/observe-aliases.d.ts +2 -2
- package/dist/lib/observe-aliases.js +2 -11
- package/dist/lib/project-key.js +7 -0
- package/dist/lib/runner.js +21 -6
- 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/bundles.d.ts +1 -1
- package/dist/lib/secrets/bundles.js +1 -1
- package/dist/lib/secrets/headless.d.ts +16 -0
- package/dist/lib/secrets/headless.js +21 -0
- package/dist/lib/secrets/remote.d.ts +9 -7
- package/dist/lib/secrets/remote.js +18 -9
- package/dist/lib/session/share-html.d.ts +55 -0
- package/dist/lib/session/share-html.js +319 -0
- package/dist/lib/settings-manifest.d.ts +2 -0
- package/dist/lib/settings-manifest.js +81 -3
- package/dist/lib/share/publish.d.ts +38 -0
- package/dist/lib/share/publish.js +81 -8
- package/dist/lib/startup/command-registry.d.ts +2 -1
- package/dist/lib/startup/command-registry.js +4 -2
- package/dist/lib/triggers/handlers.d.ts +37 -2
- package/dist/lib/triggers/handlers.js +56 -5
- package/dist/lib/triggers/webhook.d.ts +80 -6
- package/dist/lib/triggers/webhook.js +127 -3
- package/dist/lib/types.d.ts +1 -1
- package/dist/lib/wrap.d.ts +33 -0
- package/dist/lib/wrap.js +70 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,27 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.22.41
|
|
4
|
+
|
|
5
|
+
- **BREAKING: the top-level `agents timeline` command is removed — use `agents feed --filter updates` (RUSH-2692).** `timeline` was a pure alias of `agents feed --filter updates` (its own description said so), a second door to one stream against the CLI-surface convention of one owned noun with no duplicated surface. It is gone entirely, not deprecated: `agents timeline` now reports `unknown command`, and `timeline` is retired from distance-1 auto-correct so a stale invocation fails loudly instead of running a neighbouring command. `agents feed --filter updates` is unchanged, and the sibling observe aliases `agents inbox` and `agents roster` are unaffected. Source: `apps/cli/src/commands/feed.ts`, `apps/cli/src/lib/observe-aliases.ts`, `apps/cli/src/lib/startup/command-registry.ts`, `apps/cli/src/bootstrap.ts`.
|
|
6
|
+
|
|
7
|
+
- **Session preview leads with the title and wraps the last response to the pane (RUSH-2757).** `agents sessions preview` now opens its header with the session's title (`session.label` — an agent-generated name / `/rename` / the `--name` launch handle) instead of burying it, and the agent's last response is wrapped to the terminal width rather than running off the right edge as one long line. Wrapping measures visible width (ANSI-aware), so coloured output is not miscounted, and lines that already fit keep their rendered-markdown indentation. Source: `apps/cli/src/commands/sessions-picker.ts`, `apps/cli/src/lib/wrap.ts`.
|
|
8
|
+
|
|
9
|
+
- **`release-manifest.sh` helper digests are keyed by path relative to `--repo-root`, and `release-attestation-produce.sh` now writes the helper manifest it needs (RUSH-2766).** `hash_tree` used to bake the ABSOLUTE file path into every helper's `input-digest`, so a digest recorded in one worktree could never match the same recomputation elsewhere — `require_helpers` structurally could not pass for any release, and v1.22.40 was finished only by hand-recomputing the manifest inside a fixed-path worktree on `mac-mini` and re-uploading it to the GitHub release. Paths are now hashed relative to the repo root, so the same digest reproduces across machines and worktrees (demonstrated: identical `sha256:` for all three helpers computed from two independent checkouts). Separately, `release.sh` has always consumed `release-manifest.json` (`require` at :231, `upload_release_proof` at :976) with no producer writing it — the same consumer-without-producer gap RUSH-2749 fixed for the attestation itself. `release-attestation-produce.sh` now writes/updates it alongside `ATTEST.json`: an unchanged helper carries its prior record forward, `keychain`/`menubar` are re-recorded from the fresh signed assets this script's own Darwin block builds, and a drifted `computer-mac` digest with no prior record fails the producer closed rather than shipping a stale or missing helper record. Source: `apps/cli/scripts/release-manifest.sh`, `apps/cli/scripts/release-attestation-produce.sh`, `apps/cli/docs/release.md`.
|
|
10
|
+
|
|
11
|
+
- **BREAKING: `agents secrets` no longer prints bundle values — the plaintext export and bundle-key `get` are removed; run commands under `agents secrets exec` instead (RUSH-2774).** The `eval "$(agents secrets export <bundle> --plaintext)"` one-liner put every value of a bundle onto stdout, which inside a coding-agent session means the model's context and the synced session transcript — and agents copied it reflexively from the CLI's own help and scripts. `secrets export` is now transfer-only (`--device`, `--to-1password`, `--to-file`; anything else refuses, naming the alternatives); `secrets get <bundle> <KEY>` refuses, naming `agents secrets exec <bundle> -- printenv <KEY>`; `secrets view --reveal` refuses inside an agent session (`AGENTS_RUNTIME`/`AGENT_SESSION_ID`/`CLAUDECODE` markers) and its non-TTY `--reveal --plaintext` escape is gone; the raw-item `secrets get <item>` stays available everywhere — fleet shell hooks running inside sessions capture single ad-hoc tokens into their own variables, the accepted narrower residual. The SSH remote resolve behind `secrets exec --device` and `run --secrets <b>@<host>` still works: it rides a hidden, marker-gated transport (`AGENTS_SECRETS_REMOTE_TRANSPORT`), so a newer CLI keeps resolving from an older remote during a fleet rollout, while an older CLI against a newer remote fails loud with an upgrade hint. First-party scripts (`sandbox.sh`, both `release.sh`) now re-enter themselves under `agents secrets exec`, so values ride the child environment and never touch stdout. Migration for eval scripts: `agents secrets exec <bundle> -- <your command>`, or `VAR="$(agents secrets exec <bundle> -- printenv KEY)"` for a single value. Spec: SEC-9/SEC-9b/SEC-9c, SEC-GAP-10. Source: `apps/cli/src/commands/secrets.ts`, `apps/cli/src/lib/secrets/{headless,remote}.ts`, `apps/cli/scripts/{sandbox,release}.sh`, `apps/ext/scripts/release.sh`.
|
|
12
|
+
|
|
13
|
+
- **Fix a publish crash on any non-latin1 label, meta value, or repo name (RUSH-2784).** `fetch` encodes header values as a ByteString, so a title containing an ellipsis, a curly quote, an emoji, or CJK text threw `TypeError: Cannot convert argument to a ByteString` mid-publish — an unhandled stack trace after the body had already been read and the OG cover uploaded. Every free-text header (`x-share-label`, `x-share-repo`, `x-share-host`, `x-share-meta`, and the provenance set) now goes through `toHeaderValue()`, which transliterates common typographic punctuation to ASCII and drops the rest of the non-latin1 range. Still lossy for a title in a non-latin script, which publishes as `(unnamed)`; full Unicode needs percent-encoding plus a matching Worker decode, tracked as RUSH-2786. Source: `apps/cli/src/lib/share/publish.ts`.
|
|
14
|
+
|
|
15
|
+
- **`agents sessions share <id>` publishes a session as a link (RUSH-2784).** Sharing a session took three commands and a detour through the external artifacts-cli, so nobody ran it — every piece already existed (`sessions render` produces a redacted transcript, and the R2-backed share Worker has served artifacts for a month), but nothing wired them together. One verb now renders the session as a self-contained branded HTML page and publishes it: `agents sessions share a1b2c3d4` prints `https://share.agents-cli.sh/<you>/session-a1b2c3d4`. **Unlisted by default**, unlike `agents artifacts share` — a transcript carries file paths, command output, and error text, so it stays out of the public gallery until `--public` asks for it (the URL is still world-readable: unlisted is a capability URL, not a secret). The page is escaped rather than passed through, so a session that merely printed a `<script>` tag does not ship an executable one. Publishing inherits the existing email/credential scan and the 30d default expiry; `--reasoning fold` keeps the model's reasoning in collapsible sections, `--expire never` opts out of decay. Source: `apps/cli/src/commands/sessions-share.ts`, `apps/cli/src/lib/session/share-html.ts`, `apps/cli/src/lib/share/publish.ts`.
|
|
16
|
+
|
|
17
|
+
- **`agents browser use [name]` is the one command for choosing this machine's default browser profile (RUSH-2820).** A name writes the existing device-scoped `browser.profile` config key; a bare interactive invocation opens a picker over configured profiles and installed browsers, while a headless invocation prints the current default and usage. `--unset` and `auto` restore auto-detect. `agents browser profiles use` is an alias, and the hidden `profiles set-default` compatibility alias now points users to `browser use`. Source: `apps/cli/src/commands/browser.ts`.
|
|
18
|
+
|
|
19
|
+
- **Claude workspace trust now carries across pinned version homes (#2776).** Every pinned claude version gets an isolated home, and workspace trust (`projects[<path>].hasTrustDialogAccepted` in `.claude.json`) never carried into a new one — so the first interactive launch of each newly pinned version re-showed the workspace-trust dialog once per project, complete with the "this folder pre-approves N tool permissions" warning on repos trusted for months (headless runs skip the dialog, so the re-prompt could surface weeks after pinning and read as a trust regression). `agents add` / `agents use` now carry trust via a new `claude-trust` manifest strategy that projects ONLY the accepted trust flags out of the source `.claude.json` — the login (`oauthAccount`) and per-session stats stay per-version, same posture as the removed `.codex/auth.json` carry. A target entry's stamped-default `false` is promoted (Claude Code never persists a decline), all its other keys are preserved, the target is backed up before modification, and the write is atomic (a running Claude session rewrites this exact file). Codex was already covered: `projects.*.trust_level` rides along in `config.toml`. Source: `apps/cli/src/lib/settings-manifest.ts`.
|
|
20
|
+
|
|
21
|
+
- **Arc is a recognized browser type, and `agents browser` now refuses to drive it with a clear error instead of crashing it (#2779, #2778).** `arc` joins the Chromium-family `BrowserType` (detected at `/Applications/Arc.app`, macOS-only; `agents browser profiles seed` creates an `arc-local` profile). But Arc answers `Browser.getVersion` while exposing **zero** CDP page targets and **crashing** the moment a new tab is requested (`Target.createTarget`), so it is not actually drivable. Every tab-creating path now routes through one guard (`createPageTarget`) that throws an actionable "use Comet/Chrome/Chromium/Brave" error for an Arc profile rather than crashing the user's Arc window. The browser skill documents this and teaches showing a review doc/plan/report via `agents browser navigate --url file://<path>` (one reused tab, refreshed in place) instead of a raw `open <file>` that spawns a duplicate tab every call. Source: `apps/cli/src/lib/browser/service.ts`, `apps/cli/src/lib/browser/chrome.ts`, `apps/cli/src/lib/browser/cdp.ts`, `skills/browser/SKILL.md`.
|
|
22
|
+
|
|
23
|
+
- **Slack can now trigger an agent on your box and reply in-thread.** The signed webhook receiver (`agents webhooks serve` and the daemon `webhook-receiver`) accepts a third source, `POST /hooks/slack`: it verifies Slack's `v0` request signature with a 5-minute replay guard, answers the one-time `url_verification` handshake, and parses both slash commands (`/agents AGI: …`) and `app_mention` events. A matching `~/.agents/webhooks/*.yml` handler with `source: slack` (and optional `command`/`channel` filters) runs an agent scoped to the project named in the message — a handler may now template `project`/`cwd` from the delivery (`project: "{{slack.project}}"`), with the new `{{slack.*}}` namespace exposing `prompt`, `project`, `channel`, `thread_ts`, `user`, `text`, and `command`. The agent replies into the same thread through the existing `agents send --channel slack --to <channel> --thread <ts>` — no new outbound code. The receiver bundle gains `SLACK_SIGNING_SECRET` (and `SLACK_BOT_TOKEN` when the reply uses the Slack Web API). Setup, a ready-to-paste app manifest, and an example handler are in `docs/routines.md` and `docs/examples/slack/`. Source: `apps/cli/src/lib/triggers/webhook.ts`, `apps/cli/src/lib/triggers/handlers.ts`, `apps/cli/src/lib/daemon-webhooks.ts`, `apps/cli/src/commands/webhook.ts`.
|
|
24
|
+
|
|
3
25
|
## 1.22.40
|
|
4
26
|
|
|
5
27
|
---
|
package/README.md
CHANGED
|
@@ -285,6 +285,9 @@ agents sessions a1b2c3d4 --markdown
|
|
|
285
285
|
# Render a shareable, redacted Markdown transcript with the session preview on top
|
|
286
286
|
agents sessions render a1b2c3d4 -o session.md
|
|
287
287
|
|
|
288
|
+
# Or publish it as a link in one step (unlisted + redacted by default)
|
|
289
|
+
agents sessions share a1b2c3d4
|
|
290
|
+
|
|
288
291
|
# Just the last 3 turns, user messages only
|
|
289
292
|
agents sessions a1b2c3d4 --last 3 --include user
|
|
290
293
|
|
|
@@ -369,6 +372,8 @@ Landing on a session cold? `agents sessions <id>` prints a catch-up digest: an i
|
|
|
369
372
|
|
|
370
373
|
Sharing a session uses `agents sessions render <id> -o session.md`, not the raw harness JSONL. The document starts with that same preview, then presents user and assistant turns, fenced commands, structured tool arguments, and bounded tool output. Credential-shaped values and local home paths are redacted by default; `--no-redact` is for local-only inspection.
|
|
371
374
|
|
|
375
|
+
`agents sessions share <id>` goes one step further and publishes that document as a self-contained web page on your own share endpoint, printing the link. It is **unlisted** unless you pass `--public` — a transcript carries file paths, command output, and error text that a plan does not, so it stays out of your public gallery by default, and emails are masked on top of the render's own redaction. The slug is `session-<shortId>`, so re-sharing one session updates one URL.
|
|
376
|
+
|
|
372
377
|
### Resume anywhere — and stay resumed
|
|
373
378
|
|
|
374
379
|
Pick up any past conversation and drop it back into a terminal:
|
package/dist/bin/agents
CHANGED
|
Binary file
|
package/dist/bootstrap.js
CHANGED
|
@@ -258,7 +258,6 @@ Run and dispatch:
|
|
|
258
258
|
|
|
259
259
|
Observe (read the fleet — no store merge; aliases point at the real readers):
|
|
260
260
|
feed / inbox Needs-you inbox (open blocks waiting on you)
|
|
261
|
-
timeline Agent progress stream (= feed --filter updates)
|
|
262
261
|
sessions --active Live agents (who is running right now)
|
|
263
262
|
events Unified ops + activity event trail
|
|
264
263
|
audit Tamper-evident run-dispatch log (not events)
|
|
@@ -218,9 +218,8 @@ export const COMMAND_LOADERS = {
|
|
|
218
218
|
send: [loadSend],
|
|
219
219
|
notify: [loadSend],
|
|
220
220
|
feed: [loadFeed],
|
|
221
|
-
// Observe-umbrella
|
|
221
|
+
// Observe-umbrella alias of feed (the `timeline` alias was removed in RUSH-2692).
|
|
222
222
|
inbox: [loadFeed],
|
|
223
|
-
timeline: [loadFeed],
|
|
224
223
|
mailboxes: [loadMailboxes],
|
|
225
224
|
mailbox: [loadMailboxes],
|
|
226
225
|
serve: [loadServe],
|
|
@@ -1,3 +1,18 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
|
+
import { type BrowserProfile } from '../lib/browser/profiles.js';
|
|
3
|
+
import { listInstalledBrowsers } from '../lib/browser/chrome.js';
|
|
2
4
|
export declare function registerBrowserCommand(program: Command): void;
|
|
3
5
|
export declare function registerBrowserSubcommands(program: Command): void;
|
|
6
|
+
interface BrowserUseOptions {
|
|
7
|
+
unset?: boolean;
|
|
8
|
+
}
|
|
9
|
+
interface BrowserUseChoice {
|
|
10
|
+
name: string;
|
|
11
|
+
value: {
|
|
12
|
+
name: string;
|
|
13
|
+
installed?: ReturnType<typeof listInstalledBrowsers>[number];
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
export declare function buildBrowserUseChoices(profiles: BrowserProfile[], installed: ReturnType<typeof listInstalledBrowsers>, current?: string): BrowserUseChoice[];
|
|
17
|
+
export declare function runBrowserUse(name: string | undefined, opts: BrowserUseOptions, interactive?: boolean): Promise<boolean>;
|
|
18
|
+
export {};
|
package/dist/commands/browser.js
CHANGED
|
@@ -6,7 +6,7 @@ import { resolveActor } from '../lib/actor.js';
|
|
|
6
6
|
import { loginsForProfile, profilesLoggedInto, serviceForUrl, loginsWithAccountsForProfile, accountsForProfile, credKeysForService, AUTH_SIGNATURES, } from '../lib/browser/login-detection.js';
|
|
7
7
|
import { parseSecretRef } from '../lib/browser/secret-ref.js';
|
|
8
8
|
import { readAndResolveBundleEnv, bundleExists, readBundle, describeBundle } from '../lib/secrets/bundles.js';
|
|
9
|
-
import { findBrowserPath, getPortOccupant, isLauncherScript } from '../lib/browser/chrome.js';
|
|
9
|
+
import { findBrowserPath, getPortOccupant, isLauncherScript, listInstalledBrowsers } from '../lib/browser/chrome.js';
|
|
10
10
|
import { listProfileCacheDirs, removeProfileCache, listAllProfileSnapshots, buildProfilePrunePlan, pruneProfiles, PRUNE_REASON_TEXT, } from '../lib/browser/runtime-state.js';
|
|
11
11
|
import { DEFAULT_VIEWPORT } from '../lib/browser/devices.js';
|
|
12
12
|
import { runBrowserSessionsCommand } from './browser-sessions-picker.js';
|
|
@@ -49,7 +49,7 @@ const TASK_OPTION_DESC = 'Task name (defaults to $AGENTS_BROWSER_TASK, else the
|
|
|
49
49
|
// instead of an alphabetical dump. Everything not listed falls into a
|
|
50
50
|
// trailing "Other commands" section automatically.
|
|
51
51
|
const BROWSER_HELP_GROUPS = [
|
|
52
|
-
{ title: 'Session lifecycle', names: ['start', 'done', 'status', 'gc'] },
|
|
52
|
+
{ title: 'Session lifecycle', names: ['use', 'start', 'done', 'status', 'gc'] },
|
|
53
53
|
{ title: 'Fast action loop', names: ['stream'] },
|
|
54
54
|
{
|
|
55
55
|
title: 'Drive the page',
|
|
@@ -105,22 +105,104 @@ export function registerBrowserCommand(program) {
|
|
|
105
105
|
Most agent workflows should use the 'browser' skill instead of raw subcommands.
|
|
106
106
|
The skill wraps profile selection, snapshotting, and tunneling.
|
|
107
107
|
|
|
108
|
-
Browser support: Chromium-family only (Chrome, Comet, Chromium, Brave, Edge).
|
|
108
|
+
Browser support: Chromium-family only (Chrome, Comet, Chromium, Brave, Edge, Arc).
|
|
109
109
|
Safari and Firefox are not supported — they don't speak the Chrome DevTools
|
|
110
110
|
Protocol the way agents browser expects. On Windows, Edge is the default
|
|
111
111
|
because it's preinstalled. On macOS and Linux, Chrome is preferred when
|
|
112
112
|
installed; otherwise the first Chromium-family binary on disk wins.
|
|
113
113
|
`,
|
|
114
114
|
});
|
|
115
|
+
registerBrowserUseCommand(browser);
|
|
115
116
|
registerProfilesCommands(browser);
|
|
116
117
|
registerTaskCommands(browser);
|
|
117
118
|
registerCommandGroups(browser, BROWSER_HELP_GROUPS);
|
|
118
119
|
}
|
|
119
120
|
export function registerBrowserSubcommands(program) {
|
|
121
|
+
registerBrowserUseCommand(program);
|
|
120
122
|
registerProfilesCommands(program);
|
|
121
123
|
registerTaskCommands(program);
|
|
122
124
|
registerCommandGroups(program, BROWSER_HELP_GROUPS);
|
|
123
125
|
}
|
|
126
|
+
export function buildBrowserUseChoices(profiles, installed, current) {
|
|
127
|
+
const choices = profiles.map((profile) => ({
|
|
128
|
+
name: `${profile.name}${profile.name === current ? ' (current)' : ''}`,
|
|
129
|
+
value: { name: profile.name },
|
|
130
|
+
}));
|
|
131
|
+
const known = new Set(profiles.map((profile) => profile.name));
|
|
132
|
+
for (const browser of installed) {
|
|
133
|
+
const name = `${browser.browserType}-local`;
|
|
134
|
+
if (!known.has(name)) {
|
|
135
|
+
choices.push({ name: `${name} (installed ${browser.browserType})`, value: { name, installed: browser } });
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
return choices;
|
|
139
|
+
}
|
|
140
|
+
export async function runBrowserUse(name, opts, interactive = isInteractiveTerminal()) {
|
|
141
|
+
if (opts.unset || name === 'auto') {
|
|
142
|
+
unsetConfigValue('browser.profile');
|
|
143
|
+
console.log('Default browser profile cleared. `agents browser start` will auto-detect an installed Chromium-family browser.');
|
|
144
|
+
return true;
|
|
145
|
+
}
|
|
146
|
+
let selectedName = name;
|
|
147
|
+
if (!selectedName) {
|
|
148
|
+
const current = getConfiguredDefaultProfileName();
|
|
149
|
+
if (!interactive) {
|
|
150
|
+
console.log(current
|
|
151
|
+
? `Default browser profile (this machine): ${current}`
|
|
152
|
+
: 'Default browser profile (this machine): auto-detect');
|
|
153
|
+
console.log('Usage: agents browser use <name> (or --unset)');
|
|
154
|
+
return true;
|
|
155
|
+
}
|
|
156
|
+
const choices = buildBrowserUseChoices(await listProfiles(), listInstalledBrowsers(), current);
|
|
157
|
+
if (choices.length === 0) {
|
|
158
|
+
console.error('No configured profiles or supported installed browsers found.');
|
|
159
|
+
console.error('Create one with: agents browser profiles create <name> --browser chrome');
|
|
160
|
+
return false;
|
|
161
|
+
}
|
|
162
|
+
const { select } = await import('@inquirer/prompts');
|
|
163
|
+
const selected = await select({ message: 'Select default browser profile:', choices });
|
|
164
|
+
selectedName = selected.name;
|
|
165
|
+
if (selected.installed) {
|
|
166
|
+
const freePort = await findFreeProfilePort();
|
|
167
|
+
await createProfile({
|
|
168
|
+
name: selected.name,
|
|
169
|
+
description: `Seeded ${selected.installed.browserType} profile`,
|
|
170
|
+
browser: selected.installed.browserType,
|
|
171
|
+
binary: selected.installed.binary,
|
|
172
|
+
endpoints: [`cdp://127.0.0.1:${freePort}`],
|
|
173
|
+
viewport: { width: DEFAULT_VIEWPORT.width, height: DEFAULT_VIEWPORT.height },
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
const target = await getProfile(selectedName);
|
|
178
|
+
if (!target) {
|
|
179
|
+
console.error(`Profile "${selectedName}" not found.`);
|
|
180
|
+
const all = await listProfiles();
|
|
181
|
+
if (all.length > 0)
|
|
182
|
+
console.error(`Available profiles: ${all.map((profile) => profile.name).join(', ')}`);
|
|
183
|
+
return false;
|
|
184
|
+
}
|
|
185
|
+
setConfigValue('browser.profile', selectedName);
|
|
186
|
+
const endpoint = Object.values(getEndpointPresets(target))[0]?.target ?? '';
|
|
187
|
+
console.log(`Default browser profile (this machine) is now "${selectedName}" (${target.browser}${endpoint ? `, ${endpoint}` : ''}).`);
|
|
188
|
+
console.log('Bare `agents browser start` and `--profile default` will use it.');
|
|
189
|
+
return true;
|
|
190
|
+
}
|
|
191
|
+
function configureBrowserUseCommand(command, deprecated = false) {
|
|
192
|
+
command
|
|
193
|
+
.description('Pick the profile `agents browser start` uses when no --profile is passed. No name opens a picker on a TTY or prints the current default headlessly.')
|
|
194
|
+
.option('--unset', 'Clear the configured default (revert to auto-detecting an installed browser)')
|
|
195
|
+
.action(async (name, opts) => {
|
|
196
|
+
if (deprecated) {
|
|
197
|
+
console.warn(chalk.yellow('Deprecation: `agents browser profiles set-default` is replaced by `agents browser use`.'));
|
|
198
|
+
}
|
|
199
|
+
if (!await runBrowserUse(name, opts))
|
|
200
|
+
process.exitCode = 1;
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
function registerBrowserUseCommand(browser) {
|
|
204
|
+
configureBrowserUseCommand(browser.command('use [name]'));
|
|
205
|
+
}
|
|
124
206
|
/**
|
|
125
207
|
* Whether a profile's secrets bundle holds login creds for `service`
|
|
126
208
|
* (`<PREFIX>_USERNAME` + `<PREFIX>_PASSWORD`). Reads bundle METADATA only (key
|
|
@@ -174,43 +256,36 @@ function registerProfilesCommands(browser) {
|
|
|
174
256
|
for (const line of formatProfilesTable(scoped, configuredDefault))
|
|
175
257
|
console.log(line);
|
|
176
258
|
});
|
|
177
|
-
const browserProfileDeprecation = chalk.yellow('Deprecation: `agents browser profiles set-default` is replaced by `agents config set browser.profile <name>`.');
|
|
178
259
|
profiles
|
|
179
|
-
.command('
|
|
180
|
-
.description('
|
|
181
|
-
.
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
console.log('Default browser profile cleared. `agents browser start` will auto-detect an installed Chromium-family browser.');
|
|
187
|
-
return;
|
|
260
|
+
.command('seed')
|
|
261
|
+
.description('Create a machine-local profile for each installed browser (named <browser>-local), so you can pick or use one instead of hand-crafting each. Idempotent — existing profiles are left untouched.')
|
|
262
|
+
.action(async () => {
|
|
263
|
+
const installed = listInstalledBrowsers();
|
|
264
|
+
if (installed.length === 0) {
|
|
265
|
+
console.error('No supported browser found to seed a profile for.');
|
|
266
|
+
process.exit(1);
|
|
188
267
|
}
|
|
189
|
-
|
|
190
|
-
const
|
|
191
|
-
if (
|
|
192
|
-
console.log(
|
|
193
|
-
|
|
194
|
-
else {
|
|
195
|
-
console.log('No default browser profile set. `agents browser start` auto-detects an installed Chromium-family browser.');
|
|
196
|
-
console.log('Set one with: agents config set browser.profile <name>');
|
|
268
|
+
for (const { browserType, binary } of installed) {
|
|
269
|
+
const name = `${browserType}-local`;
|
|
270
|
+
if (await getProfile(name)) {
|
|
271
|
+
console.log(`= ${name} (already exists)`);
|
|
272
|
+
continue;
|
|
197
273
|
}
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
274
|
+
const freePort = await findFreeProfilePort();
|
|
275
|
+
await createProfile({
|
|
276
|
+
name,
|
|
277
|
+
description: `Seeded ${browserType} profile`,
|
|
278
|
+
browser: browserType,
|
|
279
|
+
binary,
|
|
280
|
+
endpoints: [`cdp://127.0.0.1:${freePort}`],
|
|
281
|
+
viewport: { width: DEFAULT_VIEWPORT.width, height: DEFAULT_VIEWPORT.height },
|
|
282
|
+
});
|
|
283
|
+
console.log(`+ ${name} (${browserType})`);
|
|
207
284
|
}
|
|
208
|
-
|
|
209
|
-
const eps = getEndpointPresets(target);
|
|
210
|
-
const epStr = Object.values(eps)[0]?.target ?? '';
|
|
211
|
-
console.log(`Default browser profile (this machine) is now "${name}" (${target.browser}${epStr ? `, ${epStr}` : ''}).`);
|
|
212
|
-
console.log('Bare `agents browser start` and `--profile default` will use it.');
|
|
285
|
+
console.log('Pick your default with: agents browser use <name>');
|
|
213
286
|
});
|
|
287
|
+
configureBrowserUseCommand(profiles.command('use [name]'));
|
|
288
|
+
configureBrowserUseCommand(profiles.command('set-default [name]', { hidden: true }), true);
|
|
214
289
|
profiles
|
|
215
290
|
.command('logins')
|
|
216
291
|
.description('Show which login-gated services each profile has a live session for, the account signed in, and whether login creds are available in the profile\'s secrets bundle (reads cookie/username presence only, never decrypts).')
|
|
@@ -239,7 +314,7 @@ function registerProfilesCommands(browser) {
|
|
|
239
314
|
}
|
|
240
315
|
}
|
|
241
316
|
});
|
|
242
|
-
const VALID_BROWSERS = ['chrome', 'comet', 'chromium', 'brave', 'edge', 'custom'];
|
|
317
|
+
const VALID_BROWSERS = ['chrome', 'comet', 'chromium', 'brave', 'edge', 'arc', 'custom'];
|
|
243
318
|
profiles
|
|
244
319
|
.command('create <name>')
|
|
245
320
|
.description('Create a new browser profile (machine-local unless --fleet)')
|
|
@@ -439,7 +514,7 @@ function registerProfilesCommands(browser) {
|
|
|
439
514
|
(removed > 0 ? ` (and ${removed} cache dir${removed === 1 ? '' : 's'})` : ''));
|
|
440
515
|
if (getConfiguredDefaultProfileName() === name) {
|
|
441
516
|
console.error(`warning: "${name}" was this machine's default browser profile; ` +
|
|
442
|
-
`\`agents browser start\` will auto-detect until you run: agents
|
|
517
|
+
`\`agents browser start\` will auto-detect until you run: agents browser use <name>`);
|
|
443
518
|
}
|
|
444
519
|
});
|
|
445
520
|
profiles
|
|
@@ -493,7 +568,7 @@ function registerProfilesCommands(browser) {
|
|
|
493
568
|
agents browser profiles prune
|
|
494
569
|
|
|
495
570
|
# Make one the machine's default for a bare \`agents browser start\`
|
|
496
|
-
agents
|
|
571
|
+
agents browser use work
|
|
497
572
|
`,
|
|
498
573
|
notes: `
|
|
499
574
|
Profiles are machine-local by default. A profile pins an OS-specific binary
|
|
@@ -748,7 +823,7 @@ function registerTaskCommands(browser) {
|
|
|
748
823
|
});
|
|
749
824
|
browser
|
|
750
825
|
.command('start')
|
|
751
|
-
.description('Start a browser task. Pass --profile <name>; omit to use your configured default (`agents
|
|
826
|
+
.description('Start a browser task. Pass --profile <name>; omit to use your configured default (`agents browser use <name>`), else auto-pick an installed Chromium-family browser. Page verbs (navigate/screenshot/…) create a task implicitly when none exists — start is for --profile/--url/--record/--title.')
|
|
752
827
|
.option('-p, --profile <name>', 'Browser profile to use (omit to use the configured default, else auto-pick an installed Chromium-family browser)')
|
|
753
828
|
.option(TASK_OPTION_FLAG, 'Task name (auto-generated short id if omitted)')
|
|
754
829
|
.option('--title <label>', 'Human label shown in `browser status` (defaults to first navigated host)')
|
|
@@ -808,7 +883,7 @@ function registerTaskCommands(browser) {
|
|
|
808
883
|
if (all.length > 0) {
|
|
809
884
|
console.error(`Available profiles: ${all.map((p) => p.name).join(', ')}`);
|
|
810
885
|
}
|
|
811
|
-
console.error(`Create one with: agents browser profiles create ${profileName} --browser <chrome|comet|chromium|brave|edge|custom>`);
|
|
886
|
+
console.error(`Create one with: agents browser profiles create ${profileName} --browser <chrome|comet|chromium|brave|edge|arc|custom>`);
|
|
812
887
|
process.exit(1);
|
|
813
888
|
}
|
|
814
889
|
// Pre-check the endpoint name too — same fail-fast rationale.
|
package/dist/commands/feed.js
CHANGED
|
@@ -312,7 +312,7 @@ export async function loadSessionMetasForFeedEnrichment(load) {
|
|
|
312
312
|
export function registerFeedCommand(program) {
|
|
313
313
|
const feed = program
|
|
314
314
|
.command('feed')
|
|
315
|
-
.description('Operator inbox + agent status posts (
|
|
315
|
+
.description('Operator inbox + agent status posts (alias: inbox = needs-you). Agent progress = --filter updates')
|
|
316
316
|
.option('--json', 'Output as JSON (each block stamped with its outcome + ask class)')
|
|
317
317
|
.option('--filter <view>', 'What to show: needs (default) · updates · all', 'needs')
|
|
318
318
|
.option('--flat', 'List one block per agent instead of grouping by outcome')
|
|
@@ -647,8 +647,8 @@ export function registerFeedCommand(program) {
|
|
|
647
647
|
registerFeedObserveAliases(program);
|
|
648
648
|
}
|
|
649
649
|
/**
|
|
650
|
-
* `inbox`
|
|
651
|
-
* for
|
|
650
|
+
* `inbox` → feed. Loaded with the feed module so the lazy COMMAND_LOADERS entry
|
|
651
|
+
* for `inbox` also gets the real `feed` command registered for re-parse.
|
|
652
652
|
*/
|
|
653
653
|
function registerFeedObserveAliases(program) {
|
|
654
654
|
const reparse = async (alias) => {
|
|
@@ -671,14 +671,6 @@ function registerFeedObserveAliases(program) {
|
|
|
671
671
|
.action(async () => {
|
|
672
672
|
await reparse('inbox');
|
|
673
673
|
});
|
|
674
|
-
program
|
|
675
|
-
.command('timeline')
|
|
676
|
-
.description('Agent progress stream (alias of `agents feed --filter updates`). What agents posted recently.')
|
|
677
|
-
.allowUnknownOption()
|
|
678
|
-
.allowExcessArguments()
|
|
679
|
-
.action(async () => {
|
|
680
|
-
await reparse('timeline');
|
|
681
|
-
});
|
|
682
674
|
}
|
|
683
675
|
/**
|
|
684
676
|
* Mirror a written post to the configured sinks (`feed.broadcast` in
|