pi-agent-browser-native 0.2.59 → 0.2.61
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 +23 -0
- package/README.md +1 -1
- package/dist/extensions/agent-browser/lib/input-modes/job.js +1 -23
- package/dist/extensions/agent-browser/lib/pi-tool-rendering.js +6 -9
- package/dist/extensions/agent-browser/lib/playbook.js +1 -1
- package/docs/ARCHITECTURE.md +1 -1
- package/docs/COMMAND_REFERENCE.md +15 -11
- package/docs/SUPPORT_MATRIX.md +6 -5
- package/docs/TOOL_CONTRACT.md +5 -5
- package/package.json +1 -1
- package/scripts/agent-browser-capability-baseline.mjs +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,29 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
## 0.2.61 - 2026-06-24
|
|
6
|
+
|
|
7
|
+
### Changed
|
|
8
|
+
|
|
9
|
+
- Rebaselined upstream capability metadata, command reference, support docs, playbook guidance, and real-upstream output-shape metadata for `agent-browser` `0.30.1` / vercel-labs/agent-browser@7379f7dbea76ad8dbf47f177349c4c3ce9263dcb.
|
|
10
|
+
- Removed the constrained `job.assertUrl` glob-to-`wait --fn` workaround now that upstream `wait --url` matches glob patterns such as `**/dashboard` against the full active URL.
|
|
11
|
+
|
|
12
|
+
### Validation
|
|
13
|
+
|
|
14
|
+
- Ran `npm run verify`, `npm run docs`, focused `npx tsx --test test/agent-browser.extension-input-modes.test.ts`, `npm run verify -- command-reference`, and `git diff --check`.
|
|
15
|
+
- Probed upstream `agent-browser 0.30.1` directly: `wait --url "**/dashboard"` succeeds after `pushstate /dashboard`; `find ... uncheck` and `wait <selector> --state hidden|detached` still fail, so only the URL-glob workaround was removed.
|
|
16
|
+
|
|
17
|
+
## 0.2.60 - 2026-06-24
|
|
18
|
+
|
|
19
|
+
### Changed
|
|
20
|
+
|
|
21
|
+
- Removed a dead `as never` cast and unreachable try/catch from the `agent_browser` collapsed-output "to expand" keybinding hint. `app.tools.expand` is a host-registered keybinding id (coding-agent augments pi-tui's `Keybindings` via declaration merging), so the id is resolved cast-free via `getKeybindings().getKeys(...)` with the stock `ctrl+o` fallback preserved for bare-node test contexts. No behavior change; the `pi-coding-agent` package stays type-only in the entrypoint import path so startup tax is unchanged.
|
|
22
|
+
|
|
23
|
+
### Validation
|
|
24
|
+
|
|
25
|
+
- Ran `npm run verify` (default gate: docs, typecheck, 575/575 unit, command-reference baseline + live drift), `npm run verify -- startup-profile --samples 3` (median 50.1ms, < 250ms budget), `npm run verify -- real-upstream`, `npm run verify -- lifecycle`, `npm run verify -- dogfood`, `npm run verify -- pre-pr`, and `npm run doctor` against the local checkout.
|
|
26
|
+
- Ran an independent reviewer subagent over the diff; no blockers found and the compaction-orphan audit claim was confirmed disproven against Pi 0.80.2 source.
|
|
27
|
+
|
|
5
28
|
## 0.2.59 - 2026-06-24
|
|
6
29
|
|
|
7
30
|
### Changed
|
package/README.md
CHANGED
|
@@ -347,7 +347,7 @@ Typical pitfalls:
|
|
|
347
347
|
|
|
348
348
|
For short repeatable workflows, pass a top-level `job` instead of hand-writing `batch` stdin. Keep dynamic app jobs short around navigation, click, and rerender boundaries; avoid packing a whole checkout into one job. The wrapper only supports constrained steps (`open`, `click`, `fill`, `type`, `select`, `wait`, `assertText`, `assertUrl`, `waitForDownload`, `snapshot`, and `screenshot`), compiles them to existing upstream `batch` commands, and echoes the compiled commands as `details.compiledJob` for auditability. `open` steps can include `loadState` (`domcontentloaded`, `load`, or `networkidle`) to insert a readiness wait before the next step. `click` and `fill` steps can use either CSS `selector` or semantic locator fields (`locator`, `role`/`value`, optional `name`) so a job can express flows like role/name search without brittle selectors. `type` can use `selector`, `text`, optional `delayMs` for per-character pacing, and optional `press` for a final key such as `Enter`; paced type compiles to existing `focus`, `keyboard type`, `wait`, and `press` batch rows, is capped at 200 characters per delayed step, and compacts model-visible batch text while full rows remain in `details.batchSteps`. The same compile path backs top-level `qa`, so long `qa` runs surface the same timeout evidence shape. If a long `job`, `qa`, or `batch` hits the wrapper watchdog, `details.timeoutPartialProgress` may recover per-step status (`completed`, `failed`, `pending`, or `unknown`), current page title/URL, declared artifact paths that already exist on disk, and either a `retry-timeout-step` next action for the first incomplete read-only or idempotent step or `inspect-current-page-after-timeout` when the first incomplete step may be mutating and needs state inspection before a shorter follow-up flow (see [`docs/TOOL_CONTRACT.md#details`](docs/TOOL_CONTRACT.md#details)). There is no separate catalog of reusable named browser recipes above `job`, `qa`, and raw `batch`; see [`docs/ARCHITECTURE.md#no-reusable-recipe-layer-yet`](docs/ARCHITECTURE.md#no-reusable-recipe-layer-yet) for the closed `RQ-0068` decision and when to revisit it.
|
|
349
349
|
|
|
350
|
-
**Navigation inside `job` is explicit.** A successful `click` does not prove the next page loaded; add `assertUrl` and/or `assertText` after navigation-prone clicks (forms, checkout, tabs, submit buttons) before screenshots or steps that assume the new page. `assertUrl` accepts exact URLs and `*` / `**` glob-style patterns
|
|
350
|
+
**Navigation inside `job` is explicit.** A successful `click` does not prove the next page loaded; add `assertUrl` and/or `assertText` after navigation-prone clicks (forms, checkout, tabs, submit buttons) before screenshots or steps that assume the new page. `assertUrl` accepts exact URLs and `*` / `**` glob-style patterns and now compiles directly to upstream `wait --url` for both forms.
|
|
351
351
|
|
|
352
352
|
```json
|
|
353
353
|
{
|
|
@@ -68,28 +68,6 @@ const JOB_STEP_ALLOWED_FIELDS = {
|
|
|
68
68
|
wait: new Set(["action", "milliseconds"]),
|
|
69
69
|
waitForDownload: new Set(["action", "path"]),
|
|
70
70
|
};
|
|
71
|
-
function globUrlPatternToRegexSource(pattern) {
|
|
72
|
-
let source = "^";
|
|
73
|
-
for (let index = 0; index < pattern.length; index += 1) {
|
|
74
|
-
const char = pattern.charAt(index);
|
|
75
|
-
if (char === "*") {
|
|
76
|
-
let runLength = 1;
|
|
77
|
-
while (pattern[index + runLength] === "*")
|
|
78
|
-
runLength += 1;
|
|
79
|
-
source += runLength === 1 ? "[^/]*" : ".*";
|
|
80
|
-
index += runLength - 1;
|
|
81
|
-
}
|
|
82
|
-
else {
|
|
83
|
-
source += char.replace(/[\\^$+?.()|[\]{}]/g, "\\$&");
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
return `${source}$`;
|
|
87
|
-
}
|
|
88
|
-
function compileJobAssertUrlArgs(url) {
|
|
89
|
-
if (!url.includes("*"))
|
|
90
|
-
return ["wait", "--url", url];
|
|
91
|
-
return ["wait", "--fn", `new RegExp(${JSON.stringify(globUrlPatternToRegexSource(url))}).test(location.href)`];
|
|
92
|
-
}
|
|
93
71
|
function compileJobTypeSteps(step) {
|
|
94
72
|
const text = getRequiredJobString(step, "text", "type");
|
|
95
73
|
if (text.error)
|
|
@@ -182,7 +160,7 @@ function compileAssertUrlJobStep(step) {
|
|
|
182
160
|
const result = getRequiredJobString(step, "url", "assertUrl");
|
|
183
161
|
if (result.error)
|
|
184
162
|
return { error: result.error };
|
|
185
|
-
return { args:
|
|
163
|
+
return { args: ["wait", "--url", result.value] };
|
|
186
164
|
}
|
|
187
165
|
function compilePathArtifactJobStep(step, action) {
|
|
188
166
|
const result = getRequiredJobString(step, "path", action);
|
|
@@ -73,16 +73,13 @@ function colorizeToolOutputLines(outputText, theme, isError) {
|
|
|
73
73
|
return isError ? theme.fg("error", line) : theme.fg("toolOutput", line);
|
|
74
74
|
});
|
|
75
75
|
}
|
|
76
|
+
// ponytail: "app.tools.expand" is a host-registered keybinding id (coding-agent augments pi-tui's
|
|
77
|
+
// Keybindings via declaration merging); getKeys returns [] before the host registers its ids
|
|
78
|
+
// (bare-node tests), so fall back to the stock ctrl+o. pi-tui is already a runtime import at
|
|
79
|
+
// the entrypoint, so getKeybindings() adds no startup tax.
|
|
76
80
|
function formatExpandHint(theme) {
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
if (key)
|
|
80
|
-
return `${theme.fg("dim", key)} ${theme.fg("muted", "to expand")}`;
|
|
81
|
-
}
|
|
82
|
-
catch {
|
|
83
|
-
// Fall through to the built-in default key when coding-agent keybindings are unavailable.
|
|
84
|
-
}
|
|
85
|
-
return `${theme.fg("dim", "ctrl+o")} ${theme.fg("muted", "to expand")}`;
|
|
81
|
+
const key = getKeybindings().getKeys("app.tools.expand")[0] ?? "ctrl+o";
|
|
82
|
+
return `${theme.fg("dim", key)} ${theme.fg("muted", "to expand")}`;
|
|
86
83
|
}
|
|
87
84
|
function formatVisualTruncationNotice(remainingLines, totalLines, theme, width) {
|
|
88
85
|
const notice = `${theme.fg("muted", `... (${remainingLines} more lines, ${totalLines} total, `)}${formatExpandHint(theme)}${theme.fg("muted", ")")}`;
|
|
@@ -45,7 +45,7 @@ export const SHARED_BROWSER_PLAYBOOK_GUIDELINES = [
|
|
|
45
45
|
"For Electron desktop apps, prefer top-level electron for wrapper-owned discovery, isolated launch, status, compact probe, and cleanup: list first, treat likely-sensitive annotations as hints rather than enforcement, launch with the default snapshot handoff unless handoff: \"tabs\" is the safer diagnostic starting point, use electron.probe or snapshot -i/qa.attached for current-session state, and always cleanup the returned launchId when done. electron.launch uses an isolated temporary profile; it does not reuse the app's normal signed-in profile or attach to an already-running authenticated app. For signed-in local app state, host-launch the normal app with --remote-debugging-port when appropriate, then use raw args connect <port|url>; after connect, inspect tab list, select the stable tab id such as tab t2, then run a condition wait or snapshot -i before using refs. close commands (`close`, `quit`, or `exit`) only close the browser/CDP session; leave manually launched app shutdown, profile cleanup, and explicit artifacts to the host owner.",
|
|
46
46
|
"For provider or specialized app workflows, load version-matched upstream guidance with skills get agentcore|electron|slack|dogfood|vercel-sandbox through the native tool; add --full when you need references/templates, and use skills get --all only for broad skill audits. Hosted sandbox workflows should use upstream @agent-browser/sandbox helpers outside this wrapper. Provider launches such as -p ios, --provider browserbase/kernel/browseruse/browserless/agentcore, and iOS --device are upstream-owned setup paths; use sessionMode fresh when switching providers and expect external credentials or local Appium/Xcode setup to be required.",
|
|
47
47
|
"For dialogs and frames, use dialog status/accept/dismiss and frame <selector|main> through native args; dialog commands and eval snippets that look like alert/confirm/prompt/dialog triggers are shorter-bounded than normal browser calls, and timed-out dialog-like interactions may add inspect-dialog-after-timeout, dismiss-dialog-after-timeout, or recover-fresh-session-after-dialog-timeout nextActions. When --confirm-actions produces a pending confirmation, use details.nextActions or exact confirm <id> / deny <id> calls instead of inventing ids.",
|
|
48
|
-
"If a session lands on the wrong page or tab, an interaction changes origin unexpectedly, or an open call returns blocked, blank, or otherwise unexpected results, use tab list / tab <tab-id-or-label> / snapshot -i to recover state before retrying different URLs or fallback strategies. For headed demos, put --headed on the first launch with sessionMode=fresh and verify with screenshot/tab/get-url evidence because tool success cannot prove the OS window is visible to the user. For desktop readiness, prefer real conditions first: wait --text, wait --url, wait --fn, wait --load <state>, wait --download, or qa.attached; for disappearance checks in agent-browser 0.
|
|
48
|
+
"If a session lands on the wrong page or tab, an interaction changes origin unexpectedly, or an open call returns blocked, blank, or otherwise unexpected results, use tab list / tab <tab-id-or-label> / snapshot -i to recover state before retrying different URLs or fallback strategies. For headed demos, put --headed on the first launch with sessionMode=fresh and verify with screenshot/tab/get-url evidence because tool success cannot prove the OS window is visible to the user. For desktop readiness, prefer real conditions first: wait --text, wait --url, wait --fn, wait --load <state>, wait --download, or qa.attached; for disappearance checks in agent-browser 0.30.1, use wait --fn predicates instead of stale upstream-help examples like wait <selector> --state hidden. Use electron.probe/status for wrapper-owned launch health or target mismatch. Fixed waits are a last resort: use explicit --timeout or top-level timeoutMs for legitimately slow waits, and treat a successful payload like \"waited\":\"timeout\" as elapsed time only—verify completion with an observed condition, fresh snapshot, or screenshot.",
|
|
49
49
|
"For feed, timeline, or inbox reading tasks, focus on the main timeline/list region and read the first item there rather than unrelated composer or sidebar content.",
|
|
50
50
|
"For read-only browsing tasks, prefer extracting the answer from the current snapshot, structured ref labels, or eval --stdin on the current page before navigating away. Only click into media viewers, detail routes, or new pages when the current view does not contain the needed information.",
|
|
51
51
|
"For downloads, prefer download <selector> <path> when an element click should save a file; simple loopback anchor downloads are saved to the requested path when the wrapper can resolve an HTTP(S) href. Do not rely on click alone when you need the downloaded file on disk.",
|
package/docs/ARCHITECTURE.md
CHANGED
|
@@ -177,7 +177,7 @@ That failure should include a structured recovery hint pointing to `sessionMode:
|
|
|
177
177
|
Implementation detail lives in `extensions/agent-browser/lib/launch-scoped-flags.ts` (canonical flag metadata shared with playbook/docs assertions), `extensions/agent-browser/lib/argv-descriptor.ts` and `extensions/agent-browser/lib/argv-grammar.ts` (command discovery, `VALUE_FLAGS`, `parseArgvDescriptor`) plus `extensions/agent-browser/lib/runtime.ts` (`getStartupScopedFlags`, `buildExecutionPlan`):
|
|
178
178
|
|
|
179
179
|
- **Command discovery:** Leading argv is scanned with a value-taking allowlist so known global flags and documented command flags consume their values before the upstream command word is identified. Missing-value prevalidation is intentionally limited to upstream global value flags; command-scoped flags and literal text are left to upstream parsing so values like `fill #field --password` are not rejected by wrapper heuristics before the CLI sees them. When upstream adds new global flags that take values ahead of the command, extend both the command-discovery and prevalidation allowlists; when it adds command-specific flags, extend only command discovery/redaction as needed. A smaller set of global boolean flags may be followed by an optional `true`/`false` literal; when present, that literal is consumed as the flag value before command discovery continues.
|
|
180
|
-
- **`--state` disambiguation:** Persisted browser `--state` before the command participates in launch-scoped validation and tab-correction hints. The same flag spelling after a `wait` command is excluded from startup-scoped detection so upstream help examples such as `wait @ref --state hidden` do not spuriously require `sessionMode: "fresh"` while an implicit session is active. As of upstream `agent-browser 0.
|
|
180
|
+
- **`--state` disambiguation:** Persisted browser `--state` before the command participates in launch-scoped validation and tab-correction hints. The same flag spelling after a `wait` command is excluded from startup-scoped detection so upstream help examples such as `wait @ref --state hidden` do not spuriously require `sessionMode: "fresh"` while an implicit session is active. As of upstream `agent-browser 0.30.1`, the parser still does not implement those `wait --state` examples as distinct wait modes, so agent-facing docs recommend `wait --fn` predicates for disappearance checks instead.
|
|
181
181
|
- **`--auto-connect`:** Treated as launch-scoped only when enabled (`--auto-connect` bare or `true`). `--auto-connect false` is ignored for startup-scoped blocking so disabled attach hints do not force a fresh launch.
|
|
182
182
|
|
|
183
183
|
**Sessionless inspection and local commands:** Plain-text global help and version probes (`--help`, `-h`, `--version`, `-V`) must never allocate or bind the extension-managed session. The same session-ownership rule applies to read-only upstream `skills list`, `skills get …`, and `skills path …`, local auth profile management (`auth save/list/show/delete/remove`), plus local/setup surfaces such as `profiles`, `dashboard start/stop`, `device list`, `doctor`, `install`, `upgrade`, `session list`, and targeted/all local saved-state maintenance (`state list/show`, `state clear --all`, `state clear -a`, `state clear <session-name>`, `state clean --older-than <days>`, `state rename`). Non-plain-text sessionless commands still run with `--json` for machine-readable output, but the planner does not prepend the implicit managed `--session`, so an agent can inspect local capabilities or start/stop the standalone dashboard without consuming the implicit session slot before a real `open`. Browser-backed, context-dependent, or incomplete commands such as root `session`, untargeted `state clear`, bare `state clean`, `auth login`, `state save`, and `state load` keep normal managed-session injection. Command-shape allowlisting lives in `extensions/agent-browser/lib/command-policy.ts` (`needsManagedSession`), while `extensions/agent-browser/lib/runtime.ts` (`isPlainTextInspectionArgs`, `buildExecutionPlan`) applies that decision to execution planning.
|
|
@@ -18,22 +18,26 @@ This project intentionally blocks normal `agent-browser` bash usage in most agen
|
|
|
18
18
|
|
|
19
19
|
<!-- agent-browser-capability-baseline:start upstream-baseline -->
|
|
20
20
|
<!-- Generated from scripts/agent-browser-capability-baseline.mjs. Run `npm run docs -- command-reference write` to update. Do not edit manually. -->
|
|
21
|
-
This reference is baselined to the locally installed `agent-browser 0.
|
|
21
|
+
This reference is baselined to the locally installed `agent-browser 0.30.1` command/help surface, audited against vercel-labs/agent-browser@7379f7dbea76ad8dbf47f177349c4c3ce9263dcb. Upstream `agent-browser` remains the source of truth for command semantics; this file is the local fallback for Pi agent sessions where direct binary help is blocked or discouraged.
|
|
22
22
|
|
|
23
23
|
The lightweight drift check is `npm run verify -- command-reference`. Run it whenever the installed upstream `agent-browser` version changes or this reference is edited.
|
|
24
24
|
|
|
25
25
|
Use `npm run benchmark:agent-browser` or `npm run verify -- benchmark` before and after agent-facing workflow abstractions to measure task success, tool calls, model-visible output size, stale-ref behavior, artifact success, failure-category coverage, and elapsed-time estimates.
|
|
26
26
|
<!-- agent-browser-capability-baseline:end upstream-baseline -->
|
|
27
27
|
|
|
28
|
+
### Upstream 0.30.1 rebaseline
|
|
29
|
+
|
|
30
|
+
The 0.30.1 rebaseline adds no new CLI commands. It fixes `wait --url` / `waitforurl` glob matching against the full active URL, so the wrapper removed its `job.assertUrl` `wait --fn` workaround and now delegates exact and glob patterns to upstream `wait --url`.
|
|
31
|
+
|
|
32
|
+
Runtime probes on 2026-06-24 confirm `wait --url "**/dashboard"` succeeds after a `pushstate /dashboard`. Two old caveats still stand in `agent-browser 0.30.1`: `find ... uncheck` and `wait <selector> --state hidden|detached` remain advertised by help but fail at runtime. Keep the wrapper's direct `uncheck` passthrough and `wait --fn` disappearance guidance.
|
|
33
|
+
|
|
28
34
|
### Upstream 0.29.1 rebaseline
|
|
29
35
|
|
|
30
|
-
The 0.29.1 rebaseline
|
|
36
|
+
The 0.29.1 rebaseline added no new core browser CLI commands. It captured upstream's new hosted-sandbox helper package and install behavior:
|
|
31
37
|
|
|
32
38
|
- `@agent-browser/sandbox` is the upstream helper package for Eve and Vercel Sandbox workflows. It is not bundled by this pi extension; load `skills get vercel-sandbox --full` when a task needs that hosted-sandbox guidance.
|
|
33
39
|
- Fresh Eve and Vercel Sandbox helpers install Chromium system dependencies by default; pass `installSystemDependencies: false` only when the sandbox image already has those libraries.
|
|
34
|
-
- `install --with-deps`
|
|
35
|
-
|
|
36
|
-
Runtime probes on 2026-06-21 confirm two old caveats still stand in `agent-browser 0.29.1`: `find ... uncheck` and `wait <selector> --state hidden|detached` remain advertised by help but fail at runtime, and `wait --url` glob behavior remains narrow. Keep the wrapper's direct `uncheck` passthrough, `wait --fn` disappearance guidance, and `job.assertUrl` glob workaround.
|
|
40
|
+
- `install --with-deps` exits nonzero when the package manager cannot install required browser libraries (`install --with-deps exits nonzero`).
|
|
37
41
|
|
|
38
42
|
### Upstream 0.28.0 rebaseline
|
|
39
43
|
|
|
@@ -239,7 +243,7 @@ Use `batch --bail` when later steps should stop after the first failed command.
|
|
|
239
243
|
|
|
240
244
|
For short constrained flows, use top-level `job` instead of hand-writing `batch` stdin. Supported job steps are `open`, `click`, `fill`, `type`, `select`, `wait`, `assertText`, `assertUrl`, `waitForDownload`, `snapshot`, and `screenshot`. `open` can include `loadState: "domcontentloaded" | "load" | "networkidle"` to insert a `wait --load …` row immediately after navigation before the next click/read step. `click` and `fill` accept either a stable `selector` or the same semantic locator fields as top-level `semanticAction` (`locator`, plus `role`/`name` or `value` as appropriate) and compile locator steps to upstream `find` argv. `type` focuses an optional selector, sends text through upstream keyboard typing, can insert `wait` rows via `delayMs` for human-paced input, and can append a final `press` key such as `Enter`; delayed typing is capped at 200 characters per step, and generated per-character rows are compacted in model-visible batch text while remaining available in `details.batchSteps`. `select` requires `selector` plus `value` or `values`, and compiles to upstream `select <selector> <value...>`. By default the wrapper compiles steps to upstream `batch --bail` so a failed setup/fill/assertion step stops later mutating clicks; set `failFast: false` only when you explicitly need continue-after-error diagnostics. The wrapper records `details.compiledJob.steps[]` plus `details.compiledJob.failFast`. There is still no separate first-class catalog of reusable named browser recipes above `job`, the `qa` preset, and raw `batch`; see [`ARCHITECTURE.md`](ARCHITECTURE.md#no-reusable-recipe-layer-yet) for the closed `RQ-0068` decision and revisit bar.
|
|
241
245
|
|
|
242
|
-
**Job navigation is explicit.** A `click` step (or other navigation-prone interaction) does not prove the next page loaded. The wrapper does not auto-insert `assertUrl` or `assertText` after clicks inside `job`; add those steps yourself with the exact URL, a `*` / `**` glob-style URL pattern, or on-page text you expect, especially after forms, checkout, tabs, or submit buttons, before screenshots or later steps. Exact `assertUrl` values
|
|
246
|
+
**Job navigation is explicit.** A `click` step (or other navigation-prone interaction) does not prove the next page loaded. The wrapper does not auto-insert `assertUrl` or `assertText` after clicks inside `job`; add those steps yourself with the exact URL, a `*` / `**` glob-style URL pattern, or on-page text you expect, especially after forms, checkout, tabs, or submit buttons, before screenshots or later steps. Exact and glob-style `assertUrl` values compile to `wait --url` unchanged, including query strings and literal `?`; upstream `agent-browser 0.30.1` matches `*` / `**` patterns against the full active URL. Do not put a whole dynamic checkout into one long job: split around login, sorting/cart mutations, checkout navigation, and final evidence capture so refs and app state can be rechecked between phases.
|
|
243
247
|
|
|
244
248
|
```json
|
|
245
249
|
{
|
|
@@ -365,7 +369,7 @@ Top-level `networkSourceLookup` does the same for failed browser requests. When
|
|
|
365
369
|
|
|
366
370
|
Do not omit the load state value; use `wait --load <state>` with `load`, `domcontentloaded`, or `networkidle`.
|
|
367
371
|
|
|
368
|
-
For desktop-host readiness, prefer condition waits over fixed sleeps. Use this ladder: `wait --text` /
|
|
372
|
+
For desktop-host readiness, prefer condition waits over fixed sleeps. Use this ladder: `wait --text` / `wait --url` / `wait --fn` / `wait --load <state>` / `wait --download` when a real condition exists; after raw `connect`, run `tab list` → `tab t<N>` → condition wait or `snapshot -i`; after wrapper-owned `electron.launch`, use `electron.probe` / `electron.status` for launch health or target mismatch; use `qa.attached` when expected text or selector plus diagnostics can express the check. Upstream `agent-browser 0.30.1` supports `wait --url` glob forms such as `**/dashboard` against the full active URL. Fixed waits are a last resort: use explicit `--timeout` or top-level `timeoutMs` for legitimately slow waits, and treat a successful fixed-wait payload such as `"waited":"timeout"` as elapsed time only, not proof that the desktop host finished. Verify with an observed condition, fresh snapshot, or screenshot before continuing.
|
|
369
373
|
|
|
370
374
|
Use `wait --download [path]` after an earlier action has already started a browser download, such as a dashboard export button that responds asynchronously:
|
|
371
375
|
|
|
@@ -660,7 +664,7 @@ For dense pages, the wrapper also accepts `snapshot -i --search <text>` and `sna
|
|
|
660
664
|
| `wait --download [path]` | Wait for a download started by a previous action and optionally save it to `path`; successful wrapper results include upstream-reported `savedFilePath`/`savedFile`, while `details.artifacts[].exists` is the wrapper's on-disk verification signal. |
|
|
661
665
|
| `wait --download [path] --timeout <ms>` | Set download-start timeout in milliseconds. The native Pi wrapper forwards explicit wait timeouts and extends the subprocess watchdog unless the caller supplies top-level `timeoutMs`. |
|
|
662
666
|
|
|
663
|
-
Current upstream 0.
|
|
667
|
+
Current upstream 0.30.1 still does not parse `wait <selector> --state hidden` / `wait <selector> --state detached` as distinct wait modes even though upstream help mentions those examples. Use `wait --fn "!document.querySelector('#spinner')"` or another explicit JavaScript predicate for disappearance/detach checks until upstream parser support exists.
|
|
664
668
|
|
|
665
669
|
### Diff, debug, and streaming
|
|
666
670
|
|
|
@@ -889,14 +893,14 @@ Other useful environment variables include `AGENT_BROWSER_DEFAULT_TIMEOUT`, `AGE
|
|
|
889
893
|
<!-- agent-browser-capability-baseline:start capability-token-baseline -->
|
|
890
894
|
<!-- Generated from scripts/agent-browser-capability-baseline.mjs. Run `npm run docs -- command-reference write` to update. Do not edit manually. -->
|
|
891
895
|
<details>
|
|
892
|
-
<summary>Generated verifier capability baseline for agent-browser 0.
|
|
896
|
+
<summary>Generated verifier capability baseline for agent-browser 0.30.1</summary>
|
|
893
897
|
|
|
894
898
|
This generated block is review data for maintainers. The human-authored reference sections above remain the readable command guide.
|
|
895
899
|
|
|
896
900
|
#### Source evidence
|
|
897
901
|
- repository: `vercel-labs/agent-browser`
|
|
898
|
-
- upstream HEAD: `
|
|
899
|
-
- upstream package version: `0.
|
|
902
|
+
- upstream HEAD: `7379f7dbea76ad8dbf47f177349c4c3ce9263dcb`
|
|
903
|
+
- upstream package version: `0.30.1`
|
|
900
904
|
- inspected: `agent-browser --version`
|
|
901
905
|
- inspected: `agent-browser --help`
|
|
902
906
|
- inspected: `selected agent-browser <command> --help output`
|
package/docs/SUPPORT_MATRIX.md
CHANGED
|
@@ -26,10 +26,10 @@ When upstream ships a new `agent-browser` or the inventory changes:
|
|
|
26
26
|
|
|
27
27
|
## Audit result
|
|
28
28
|
|
|
29
|
-
- Target upstream: `agent-browser 0.
|
|
29
|
+
- Target upstream: `agent-browser 0.30.1` (must match `CAPABILITY_BASELINE.targetVersion` in [`scripts/agent-browser-capability-baseline.mjs`](../scripts/agent-browser-capability-baseline.mjs)).
|
|
30
30
|
- Source of truth: `CAPABILITY_BASELINE.inventorySections` in the same file (stable `id` keys: `skills`, `core-commands`, `state-tabs-frames-dialogs`, `network-storage-artifacts-diagnostics`, `batch-auth-setup-ai`, `options-and-env`).
|
|
31
|
-
- Status: command-surface supported for the current wrapper contract after the 2026-06-
|
|
32
|
-
- High-priority support gaps: 2026-05-26 audit found sessionless local commands and command-scoped value flags needed sharper wrapper handling; runtime/tests/docs now cover those paths. The 0.28.0 rebaseline added local `mcp` and `plugin` surfaces plus plugin-backed credential login; wrapper docs/tests mark `mcp` and known `plugin` commands sessionless, with no compatibility shim for older upstream releases. The 0.29.1 rebaseline
|
|
31
|
+
- Status: command-surface supported for the current wrapper contract after the 2026-06-24 0.30.1 audit; 0.30.1 evidence covered the default local gate, command-reference sampling, runtime probes, and the removed `job.assertUrl` workaround.
|
|
32
|
+
- High-priority support gaps: 2026-05-26 audit found sessionless local commands and command-scoped value flags needed sharper wrapper handling; runtime/tests/docs now cover those paths. The 0.28.0 rebaseline added local `mcp` and `plugin` surfaces plus plugin-backed credential login; wrapper docs/tests mark `mcp` and known `plugin` commands sessionless, with no compatibility shim for older upstream releases. The 0.29.1 rebaseline added upstream `@agent-browser/sandbox` helper-package guidance and stricter `install --with-deps` failure semantics; no new wrapper runtime mode or bundled dependency was required. The 0.30.1 rebaseline fixes upstream `wait --url` glob matching, so constrained `job.assertUrl` now delegates glob and exact patterns directly to `wait --url`. Prior upstream fixes for click reliability, frame-scoped selectors/waits, form-command fixes, daemon retry improvements, and glibc-pinned release artifacts remain thin passthrough. Remaining upstream-owned caveat: current help still mentions `wait <selector> --state hidden` / `detached` and `find ... uncheck`, but runtime probes show those advertised shapes still fail, so wrapper docs keep `wait --fn` predicates and direct `uncheck` passthrough guidance.
|
|
33
33
|
- Post-`v0.2.29` review state: commits `eb55320` through `86abbfb` add browser guidance/smoke coverage plus `RQ-0086` click-probe reduction, `RQ-0087` same-snapshot form fill batching, `RQ-0088` current-ref fallback on locator misses, `RQ-0089` direct-upstream click mutation investigation, and `RQ-0090` stop-boundary/artifact-path guidance. Verification gates below were rerun on 2026-05-18 after those tasks landed. Constrained `job` (`RQ-0064`), the lightweight `qa` preset (`RQ-0065`), the experimental `sourceLookup` helper (`RQ-0066`), the experimental `networkSourceLookup` helper (`RQ-0067`), optional Exa/Brave-backed `agent_browser_web_search` with Pi-scoped package config (`RQ-0121`), and agent recovery for search/profile configuration failures (`RQ-0122`) are implemented; see [`TOOL_CONTRACT.md`](TOOL_CONTRACT.md#job), [`TOOL_CONTRACT.md`](TOOL_CONTRACT.md#qa), [`TOOL_CONTRACT.md`](TOOL_CONTRACT.md#sourcelookup), [`TOOL_CONTRACT.md`](TOOL_CONTRACT.md#networksourcelookup), and [`TOOL_CONTRACT.md`](TOOL_CONTRACT.md#optional-companion-web-search). Reusable browser recipes (`RQ-0068`) are intentionally not adopted as a runtime surface; see [`ARCHITECTURE.md`](ARCHITECTURE.md#no-reusable-recipe-layer-yet).
|
|
34
34
|
|
|
35
35
|
## Open UX/reliability follow-ups from 2026-05-29 agent feedback
|
|
@@ -45,14 +45,15 @@ Current summary:
|
|
|
45
45
|
| RQ-0101 | Upstream `agent-browser 0.27.2` rebaseline shipped. | [`docs/support-notes.md`](https://github.com/fitchmultz/pi-agent-browser-native/blob/main/docs/support-notes.md) |
|
|
46
46
|
| RQ-0128 | Upstream `agent-browser 0.27.3` install-only rebaseline shipped; no new wrapper capability adopted. | [`docs/support-notes.md`](https://github.com/fitchmultz/pi-agent-browser-native/blob/main/docs/support-notes.md) |
|
|
47
47
|
| RQ-0129 | Upstream `agent-browser 0.29.1` rebaseline shipped; sandbox helpers are documented upstream package guidance, not a wrapper runtime. | [`docs/support-notes.md`](https://github.com/fitchmultz/pi-agent-browser-native/blob/main/docs/support-notes.md) |
|
|
48
|
+
| RQ-0130 | Upstream `agent-browser 0.30.1` rebaseline shipped; `wait --url` glob support replaces the wrapper `job.assertUrl` predicate workaround. | [`docs/support-notes.md`](https://github.com/fitchmultz/pi-agent-browser-native/blob/main/docs/support-notes.md) |
|
|
48
49
|
|
|
49
50
|
## Verification evidence
|
|
50
51
|
|
|
51
|
-
Re-run the gates below before each release; this table records what the closure audit exercised. Rows marked current were rerun under `agent-browser 0.29.1` on 2026-06-21. Pi 0.79.10 compatibility was refreshed on 2026-06-22 with the targeted gates noted below.
|
|
52
|
+
Re-run the gates below before each release; this table records what the closure audit exercised. Rows marked current were rerun under `agent-browser 0.29.1` on 2026-06-21; the 0.30.1 rebaseline refreshed the default local gate plus focused runtime probes without replacing the full release-gate history. Pi 0.79.10 compatibility was refreshed on 2026-06-22 with the targeted gates noted below.
|
|
52
53
|
|
|
53
54
|
| Gate | Evidence | Status |
|
|
54
55
|
| --- | --- | --- |
|
|
55
|
-
| Default local gate | `npm run verify` checks generated playbook drift, clean-builds generated `dist/`, runs `tsc --noEmit`, unit/fake tests, generated command-reference blocks, and live command-reference sampling. | **Current for 0.
|
|
56
|
+
| Default local gate | `npm run verify` checks generated playbook drift, clean-builds generated `dist/`, runs `tsc --noEmit`, unit/fake tests, generated command-reference blocks, and live command-reference sampling. | **Current for 0.30.1:** pass on 2026-06-24 (`npm run verify`; unit/fake suite plus live command-reference sampling). **Prior release evidence for 0.29.1:** pass on 2026-06-21 inside `npm run verify -- release`; Pi 0.79.10 refresh passed on 2026-06-22 (`npm run verify`). |
|
|
56
57
|
| Pre-PR local gate | `npm run verify -- pre-pr` composes the default gate with package-content verification. Use before larger local handoffs or PR-ready claims when lifecycle/platform/live dogfood cost is not warranted. | Added 2026-06-10; orchestration is locked by `test/project-verify.test.ts` and does not change release mode. |
|
|
57
58
|
| Real upstream contract | `npm run verify -- real-upstream` runs the localhost fixture matrix against the real installed `agent-browser` matching the baseline. | **Current for 0.29.1:** pass on 2026-06-21 (`npm run verify -- real-upstream`; localhost fixture matrix and plugin list probe passed against installed `agent-browser 0.29.1`). |
|
|
58
59
|
| Packaged Pi smoke | `npm run verify -- package-pi` validates package contents, loads the packaged `agent_browser` tool without requiring optional Brave config, and executes fake-upstream `--version`. | **Current for 0.29.1:** pass on 2026-06-21 as part of `npm run verify -- release` (`verify-package.mjs --smoke-pi`; packaged `agent_browser --version` invocation passed). **Pi 0.79.10 refresh:** pass on 2026-06-22 (`npm run verify -- package-pi`). |
|
package/docs/TOOL_CONTRACT.md
CHANGED
|
@@ -159,7 +159,7 @@ The extension always plans normal browser commands with `--json` prepended in `e
|
|
|
159
159
|
- For Electron desktop apps, prefer top-level electron for wrapper-owned discovery, isolated launch, status, compact probe, and cleanup: list first, treat likely-sensitive annotations as hints rather than enforcement, launch with the default snapshot handoff unless handoff: "tabs" is the safer diagnostic starting point, use electron.probe or snapshot -i/qa.attached for current-session state, and always cleanup the returned launchId when done. electron.launch uses an isolated temporary profile; it does not reuse the app's normal signed-in profile or attach to an already-running authenticated app. For signed-in local app state, host-launch the normal app with --remote-debugging-port when appropriate, then use raw args connect <port|url>; after connect, inspect tab list, select the stable tab id such as tab t2, then run a condition wait or snapshot -i before using refs. close commands (`close`, `quit`, or `exit`) only close the browser/CDP session; leave manually launched app shutdown, profile cleanup, and explicit artifacts to the host owner.
|
|
160
160
|
- For provider or specialized app workflows, load version-matched upstream guidance with skills get agentcore|electron|slack|dogfood|vercel-sandbox through the native tool; add --full when you need references/templates, and use skills get --all only for broad skill audits. Hosted sandbox workflows should use upstream @agent-browser/sandbox helpers outside this wrapper. Provider launches such as -p ios, --provider browserbase/kernel/browseruse/browserless/agentcore, and iOS --device are upstream-owned setup paths; use sessionMode fresh when switching providers and expect external credentials or local Appium/Xcode setup to be required.
|
|
161
161
|
- For dialogs and frames, use dialog status/accept/dismiss and frame <selector|main> through native args; dialog commands and eval snippets that look like alert/confirm/prompt/dialog triggers are shorter-bounded than normal browser calls, and timed-out dialog-like interactions may add inspect-dialog-after-timeout, dismiss-dialog-after-timeout, or recover-fresh-session-after-dialog-timeout nextActions. When --confirm-actions produces a pending confirmation, use details.nextActions or exact confirm <id> / deny <id> calls instead of inventing ids.
|
|
162
|
-
- If a session lands on the wrong page or tab, an interaction changes origin unexpectedly, or an open call returns blocked, blank, or otherwise unexpected results, use tab list / tab <tab-id-or-label> / snapshot -i to recover state before retrying different URLs or fallback strategies. For headed demos, put --headed on the first launch with sessionMode=fresh and verify with screenshot/tab/get-url evidence because tool success cannot prove the OS window is visible to the user. For desktop readiness, prefer real conditions first: wait --text, wait --url, wait --fn, wait --load <state>, wait --download, or qa.attached; for disappearance checks in agent-browser 0.
|
|
162
|
+
- If a session lands on the wrong page or tab, an interaction changes origin unexpectedly, or an open call returns blocked, blank, or otherwise unexpected results, use tab list / tab <tab-id-or-label> / snapshot -i to recover state before retrying different URLs or fallback strategies. For headed demos, put --headed on the first launch with sessionMode=fresh and verify with screenshot/tab/get-url evidence because tool success cannot prove the OS window is visible to the user. For desktop readiness, prefer real conditions first: wait --text, wait --url, wait --fn, wait --load <state>, wait --download, or qa.attached; for disappearance checks in agent-browser 0.30.1, use wait --fn predicates instead of stale upstream-help examples like wait <selector> --state hidden. Use electron.probe/status for wrapper-owned launch health or target mismatch. Fixed waits are a last resort: use explicit --timeout or top-level timeoutMs for legitimately slow waits, and treat a successful payload like "waited":"timeout" as elapsed time only—verify completion with an observed condition, fresh snapshot, or screenshot.
|
|
163
163
|
- For feed, timeline, or inbox reading tasks, focus on the main timeline/list region and read the first item there rather than unrelated composer or sidebar content.
|
|
164
164
|
- For read-only browsing tasks, prefer extracting the answer from the current snapshot, structured ref labels, or eval --stdin on the current page before navigating away. Only click into media viewers, detail routes, or new pages when the current view does not contain the needed information.
|
|
165
165
|
- For downloads, prefer download <selector> <path> when an element click should save a file; simple loopback anchor downloads are saved to the requested path when the wrapper can resolve an HTTP(S) href. Do not rely on click alone when you need the downloaded file on disk.
|
|
@@ -283,12 +283,12 @@ Examples:
|
|
|
283
283
|
- `select` with `selector` plus either `value` or `values` (one or more option values; compiled as `select <selector> <value...>`)
|
|
284
284
|
- `wait` with positive integer `milliseconds`
|
|
285
285
|
- `assertText` with `text` (compiled as passive `wait --text <text>`)
|
|
286
|
-
- `assertUrl` with exact URL or `*` / `**` glob-style `url` pattern (
|
|
286
|
+
- `assertUrl` with exact URL or `*` / `**` glob-style `url` pattern (compiled as `wait --url <url-or-pattern>`)
|
|
287
287
|
- `waitForDownload` with `path` (compiled as `wait --download <path>`)
|
|
288
288
|
- `snapshot` (compiled as `snapshot -i`; useful between mutation-prone steps before reusing current refs)
|
|
289
289
|
- `screenshot` with `path`
|
|
290
290
|
|
|
291
|
-
**Navigation assertions are explicit only.** `job` never treats a successful `click` (or a `select` / submit-style interaction that may navigate) as proof that the expected next page loaded. Top-level `click` may still surface optional `details.navigationSummary` or `pageChangeSummary` hints for operators, but compiled `job` / `batch` steps do **not** auto-insert `assertUrl` or `assertText` after clicks—there is no deterministic expected URL source without caller intent. Use `open.loadState` to wait for initial page readiness after an `open`; after any later navigation-prone step (link/submit clicks, checkout or form flows, tab-sensitive UI), add an explicit `assertUrl` with the exact destination URL or `*` / `**` glob-style pattern you expect, `assertText` for on-page copy, or both, **before** screenshots or steps that assume the new page state.
|
|
291
|
+
**Navigation assertions are explicit only.** `job` never treats a successful `click` (or a `select` / submit-style interaction that may navigate) as proof that the expected next page loaded. Top-level `click` may still surface optional `details.navigationSummary` or `pageChangeSummary` hints for operators, but compiled `job` / `batch` steps do **not** auto-insert `assertUrl` or `assertText` after clicks—there is no deterministic expected URL source without caller intent. Use `open.loadState` to wait for initial page readiness after an `open`; after any later navigation-prone step (link/submit clicks, checkout or form flows, tab-sensitive UI), add an explicit `assertUrl` with the exact destination URL or `*` / `**` glob-style pattern you expect, `assertText` for on-page copy, or both, **before** screenshots or steps that assume the new page state.
|
|
292
292
|
|
|
293
293
|
Example (static landing page):
|
|
294
294
|
|
|
@@ -326,13 +326,13 @@ Compiled shape for the navigation example:
|
|
|
326
326
|
```json
|
|
327
327
|
{
|
|
328
328
|
"args": ["batch", "--bail"],
|
|
329
|
-
"stdin": "[[\"open\",\"https://shop.example/checkout\"],[\"fill\",\"#email\",\"user@example.com\"],[\"click\",\"#continue\"],[\"wait\",\"--
|
|
329
|
+
"stdin": "[[\"open\",\"https://shop.example/checkout\"],[\"fill\",\"#email\",\"user@example.com\"],[\"click\",\"#continue\"],[\"wait\",\"--url\",\"**/shipping\"],[\"wait\",\"--text\",\"Shipping address\"],[\"screenshot\",\".dogfood/shipping.png\"]]"
|
|
330
330
|
}
|
|
331
331
|
```
|
|
332
332
|
|
|
333
333
|
On app pages that expose a native dropdown, add a `select` step such as `{ "action": "select", "selector": "#flavor", "value": "chocolate" }` before the assertion that depends on it. `click` and `fill` steps may use either `selector` or semantic locator fields. A semantic locator step mirrors the top-level `semanticAction` compiler and must include `locator` plus the locator value (`role`/`value` and optional `name` for role locators); it compiles to upstream `find`, for example `{ "action": "fill", "locator": "role", "role": "searchbox", "name": "Search", "text": "agent browser" }` → `find role searchbox fill "agent browser" --name Search` and `{ "action": "click", "locator": "role", "role": "button", "name": "Search" }` → `find role button click --name Search`. Supplying both `selector` and semantic locator fields is rejected.
|
|
334
334
|
|
|
335
|
-
`assertUrl`
|
|
335
|
+
`assertUrl` compiles to upstream `wait --url <url-or-pattern>` for exact URLs and glob-style patterns, preserving query strings and literal `?` in exact URLs and delegating `*` / `**` matching to the current upstream matcher.
|
|
336
336
|
|
|
337
337
|
Use raw `args` plus `stdin` for upstream `batch` when a flow needs commands, flags, stdin forms, or failure policies outside this constrained schema. `job.failFast: false` keeps the constrained schema but removes `--bail` when collecting later diagnostic artifacts is more important than stopping on the first failure.
|
|
338
338
|
|
package/package.json
CHANGED
|
@@ -14,8 +14,8 @@ export const COMMAND_REFERENCE_BASELINE_BLOCK_IDS = Object.freeze(["upstream-bas
|
|
|
14
14
|
|
|
15
15
|
const sourceEvidence = Object.freeze({
|
|
16
16
|
repository: "vercel-labs/agent-browser",
|
|
17
|
-
upstreamHead: "
|
|
18
|
-
upstreamPackageVersion: "0.
|
|
17
|
+
upstreamHead: "7379f7dbea76ad8dbf47f177349c4c3ce9263dcb",
|
|
18
|
+
upstreamPackageVersion: "0.30.1",
|
|
19
19
|
inspectedSources: Object.freeze([
|
|
20
20
|
"agent-browser --version",
|
|
21
21
|
"agent-browser --help",
|
|
@@ -742,7 +742,7 @@ const inventorySections = Object.freeze([
|
|
|
742
742
|
]);
|
|
743
743
|
|
|
744
744
|
export const CAPABILITY_BASELINE = Object.freeze({
|
|
745
|
-
targetVersion: "0.
|
|
745
|
+
targetVersion: "0.30.1",
|
|
746
746
|
sourceEvidence,
|
|
747
747
|
helpCommands,
|
|
748
748
|
inventorySections,
|