Commit Graph

1080 Commits

Author SHA1 Message Date
Peter Steinberger 74052575fb fix(browser): close the created tab when opened-tab discovery is aborted (#131125)
* fix(browser): close the created tab when opened-tab discovery is aborted

* fix(browser): complete cancelled tab creation cleanup

Close newly created CDP targets on their creating socket when cancellation prevents returning the target ID. Preserve the original error even when close fails.

Capture cleanup policy and timeout before asynchronous work so runtime shutdown cannot fence compensation or mask the open error. Extend the existing cancellation tests through the real profile lifecycle.
2026-08-27 11:57:36 -07:00
Peter Steinberger 834368b7d4 fix(browser): cancel downloads after output save failures (#131048) 2026-08-27 10:28:08 -07:00
Peter Steinberger a37ad34f26 fix(browser): click the first duplicate raw accessibility ref (#130929) 2026-08-27 06:45:45 -07:00
Peter Steinberger f04a622c1f fix(browser): resolve unnamed role refs and initialize AX markers (#130881)
* fix(browser): resolve unnamed role refs and initialize AX markers

Keep explicit raw ARIA empty names distinct from omitted serializer names and share one dependency-faithful role lookup. Bind the DOM document in the marker-owning CDP session without adding a round trip.

Related: #130879. The separate snapshot membership and ordering failures remain open.

* chore(browser): shrink ref assertion safety baseline

Record the five type assertions removed by the ref-name repair. Tighten the canonical per-file allowance from seven to two; runtime and browser-test bytes are unchanged.
2026-08-27 05:22:38 -07:00
Peter Steinberger dd005e5386 fix(browser): handle concurrent first-use extension pairing (#130832)
* fix(browser): handle concurrent first-use extension pairing

* fix(browser): keep failed key reads in adoption handoff
2026-08-27 02:42:04 -07:00
Vyctor H. Brzezowski 15f24c4bfb fix(browser): keep inspection state independent of error wording (#128625)
* fix(browser): preserve action error codes

* fix(browser): retain legacy evaluation fallback

* fix(browser): preserve unknown action-code presence

* fix(browser): preserve error payload narrowing
2026-08-27 05:41:53 -03:00
juyaohuidt 343e554dd4 fix(browser): reject non-decimal --wait-ms during extension install (#130626)
* fix(browser): reject non-decimal extension install wait strings

normalizeExtensionInstallWaitMs used loose Number() on the external
--wait-ms CLI value, so inputs like 0x1000 or 1e4 coerced into valid
in-range waits instead of being rejected. Migrate the string path to
parseStrictPositiveInteger so only plain decimal integers are accepted;
keep the bound/integer checks as the canonical guard and add a
failing-before/passing-after regression.

* fix(browser): enforce decimal extension wait values

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-08-27 16:34:40 +08:00
Peter Steinberger 2a41b4e478 fix(browser): report failed nested batches (#130809) 2026-08-27 01:20:14 -07:00
Peter Steinberger ed0e4ac578 fix(browser): preserve literal names and formatter-owned snapshot refs (#130599)
* fix(browser): preserve refs for quoted control names

Decode the emitted Playwright name grammar once across snapshot consumers and keep CDP and Chrome MCP string producers consistent. Fixes #130571.

* chore(browser): document snapshot JSON string invariant

* docs: place browser snapshot note beside related fixes

* test(browser): use an event listener in snapshot fixture
2026-08-26 21:54:48 -07:00
Peter Steinberger f1bef4b3a2 fix(browser): preserve snapshot names and native refs (#130623) 2026-08-26 20:09:49 -07:00
Peter Steinberger fed350dbc4 fix(browser): hidden selectors prematurely complete waits (#130508) 2026-08-26 17:14:51 -07:00
Peter Steinberger 395e5db41b chore(deps): refresh dependencies after seven-day cooldown (#130296)
* chore(deps): refresh cooled npm and plugin dependencies

* chore(deps): refresh cooled build and workflow tooling

* chore(deps): retain formatter compatibility

* chore(deps): retain lint compatibility
2026-08-26 16:13:18 -07:00
Peter Steinberger 0e05d8205a fix(browser): accept common keyboard aliases (#130401)
* fix(browser): accept common keyboard aliases

* docs(browser): note keyboard alias repair
2026-08-26 15:12:37 -07:00
Peter Steinberger 738e67c880 fix(browser): preserve exact select option values (#130410) 2026-08-26 14:29:08 -07:00
Peter Steinberger 86233c34a9 fix(browser): response body reads outlive their timeout (#130386)
* fix(browser): bound response body reads through completion

* test(browser): use public response test types
2026-08-26 14:18:49 -07:00
shaoohh db4d42ead2 fix(browser): warn when Chrome extension version drifts after upgrades (#119641)
* fix(browser): detect Chrome extension version drift

* fix(browser): diagnose paired Chrome extension version drift

Co-authored-by: shaoohh <150606856+shaoohh@users.noreply.github.com>

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-08-26 10:42:57 -07:00
Peter Steinberger 1ff5ed7894 fix(browser): preserve snapshot deltas across browser requests (#130220) 2026-08-26 09:54:27 -07:00
Miorbnli fe6b8bf1e4 fix: prevent $-pattern injection in tilde expansion across extensions (#123004)
* fix: prevent dollar-pattern injection in tilde expansion across extensions

String.replace interprets dollar-amp/dollar-1/dollar-backtick in the
replacement string. Eight call sites across extensions and
memory-host-sdk expanded ~ using .replace(/^~/, homeVariable), which
corrupts the path when the home directory contains these sequences.

Switch each to a function replacement (() => homeVariable) so the home
path is treated literally. Same fix as the core home-dir resolver
(PR #122991) and terminal-core/display-string (#111398).

Affected: voice-call utils + doctor, browser config, migrate-claude,
migrate-hermes, memory-lancedb doctor, memory-host-sdk config-utils.

* fix: cover iMessage and 1Password tilde expansion owners

Address review: iMessage CLI path expansion and both 1Password
state-path expansions (OPENCLAW_HOME and OPENCLAW_STATE_DIR) also passed
resolved home as a string replacement. Apply the callback form so a
literal-dollar home path is preserved.

* test(voice-call): add literal-dollar tilde expansion regression

Address review rank-up: mock os.homedir to a literal-dollar path and
assert the resolved path preserves dollar-amp verbatim (fails on the
string replacement form, passes with the callback).

* test(extensions): cover literal-dollar tilde expansion at every changed owner

* test(onepassword): cover tilde OPENCLAW_HOME literal-dollar expansion
2026-08-26 07:11:11 -07:00
Peter Steinberger f1c60c7c4b fix(browser): cancel waiting profile operations promptly (#120796) 2026-08-26 06:53:56 -07:00
Piyush Bag 91888cf68b fix(browser): prove post-action target continuity before adopting a tab (#110884)
* fix(browser): bind action target continuity to operation owner

Co-authored-by: Piyush Jagadish Bag <piyushbag4@gmail.com>

* test(browser): reject unrelated existing-session target adoption

Co-authored-by: Piyush Jagadish Bag <piyushbag4@gmail.com>

* fix(browser): preserve relay ownership across detached-frame retries

Co-authored-by: Piyush Jagadish Bag <piyushbag4@gmail.com>

* test(browser): prove relay-owned recovery through real extension transport

Co-authored-by: Piyush Jagadish Bag <piyushbag4@gmail.com>

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-08-26 05:15:45 -07:00
Peter Steinberger f113f15682 fix(browser): honor canonical action execution deadlines (#130055)
* fix(browser): honor canonical action execution deadlines

* refactor(browser): keep action execution budgets owner-private
2026-08-26 03:28:31 -07:00
NianJiu 814f193ef9 fix(browser): stop agent-launched managed Chrome (#109723)
* fix(browser): safely stop cross-runtime managed Chrome

Co-authored-by: NianJiuZst <180004567+NianJiuZst@users.noreply.github.com>

* test(browser): keep shared Chrome lifecycle mocks current

Co-authored-by: NianJiuZst <180004567+NianJiuZst@users.noreply.github.com>

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
Co-authored-by: NianJiuZst <180004567+NianJiuZst@users.noreply.github.com>
2026-08-26 03:02:07 -07:00
Peter Steinberger a16722aa2d perf(browser): reuse cold status process discovery (#128692) 2026-08-26 02:53:44 -07:00
sunlit-deng 87b93b5303 fix(browser): bound batch action files (#115882)
* fix(browser): bound batch action files

* fix(browser): preserve legacy file input while bounding batches

Co-authored-by: sunlit-deng <yang.jiajun1@xydigit.com>

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-08-26 02:37:42 -07:00
FMLS ec0f112279 fix(browser): describe supported browser tool actions (#111381)
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-08-26 02:29:01 -07:00
RickLin 2e5eaae0b7 fix(browser): don't steal focus on headed screenshot captures (#105393)
* fix(browser): don't steal focus on headed screenshot captures

captureScreenshot unconditionally sent Page.bringToFront before every
capture to avoid a headless-specific stall (#100857), but on a headed
browser that activates the visible tab on every screenshot — the
highest-frequency agent operation — repeatedly stealing focus from a
watching user (#105357).

Detect headed-ness via Browser.getVersion userAgent and only skip
activation when the browser is confirmed headed. Headless browsers, and
any case where detection is unavailable, keep activating so the #100857
stall fix is never reintroduced.

Fixes #105357

* fix(browser): trust managed launch flag for screenshot tab activation

The v1 headed-detection sniffed the browser user-agent to decide whether
to activate the tab before a screenshot. A managed headless Chrome can be
launched with a custom --user-agent via extraArgs, which the sniff would
misclassify as headed and drop the activation that prevents the
background-capture stall (#100857).

For a managed browser the profile already holds the authoritative headless
launch flag, so pass it through and let it win over UA sniffing. Attached/
external sessions (headless unknown) keep the best-effort UA fallback. This
also skips the per-screenshot Browser.getVersion round-trip on the common
managed path.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix(browser): drop unreliable UA sniff; activate unless confirmed-headed

The re-review flagged a symmetric availability risk in the attached-session
fallback: an attached headless Chrome launched with a custom non-"headless"
--user-agent is misclassified by the UA sniff as headed, suppressing the
activation that prevents the #100857 background-capture stall.

Verified against real Chrome that no runtime signal survives a spoofed UA:
--headless=new with --user-agent=<normal> reports product "Chrome/…", the
spoofed userAgent, and navigator.webdriver === false — indistinguishable from
a headed browser. So the UA sniff cannot be made robust for attached sessions.

Focus-hygiene is only safe where the headless state is authoritative (managed
profiles, via the launch flag). Skip activation ONLY for a confirmed-headed
managed profile; managed headless and every attached/external session keep
activating, so the stall (a hard timeout — strictly worse than an unnecessary
activation) is never risked. This drops the UA sniff and the per-screenshot
Browser.getVersion round-trip entirely. Attached behavior matches current main
(always activate); only managed headed profiles — the primary #105357 case —
change.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix(browser): preserve focus using actual Chrome launch mode

Co-authored-by: RickLin <83101411+ObliviateRickLin@users.noreply.github.com>

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-08-26 02:23:55 -07:00
Leon-SK668 a6a3fd959b fix(browser): honor explicit inspection timeouts (#124575)
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-08-26 01:25:45 -07:00
Peter Steinberger 83fa2fc571 fix(browser): enforce download deadlines through atomic save (#129899) 2026-08-25 22:40:27 -07:00
Peter Steinberger 4b0f712644 fix(browser): preserve response-body timeout diagnostics (#129803) 2026-08-25 20:14:55 -07:00
Peter Steinberger 1f812ac4fa fix(browser): cancel pending CDP endpoint discovery (#129410) 2026-08-25 11:54:17 -07:00
Santhi Prakash 4f18aeabf3 [AI-assisted] docs(browser): teach the code-mode global call, not the removed tools.call API (#128456)
* docs(browser): teach the code-mode global call, not the removed tools.call API

The browser-automation skill's Code Mode Loop still taught the guest
`tools.call(browserTool, input)` API that #126262 removed, together with
the `.result.details`/`.result.content` envelope reads. Rewrite the loop
for the current contract: call the `browser(...)` async global directly,
receive the tool's structured details (targetId, url, newElements, stats,
blockedByDialog), and diff url/new-element counts between cells instead of
filtering snapshot text, since rendered page text is no longer
guest-visible in code mode.

* docs(browser): resolve callable from quick index and read via targeted evaluate

* docs(browser): call the search-resolved handle and carry cell state explicitly
2026-08-25 11:45:42 -07:00
Peter Steinberger 411e233525 fix(browser): surface terminal dialog handling failures (#129459) 2026-08-25 10:37:46 -07:00
Ayaan Gazali 22e12267f6 fix(browser): give a paired extension time to attach before declaring it offline (#127761)
* fix(browser): preserve live relay ownership and await authenticated attachment

Co-authored-by: Peter Steinberger <steipete@gmail.com>

* fix(browser): keep extension attachment outside serialized startup

Co-authored-by: Peter Steinberger <steipete@gmail.com>

* fix(browser): give shared relay startup lifecycle-owned cancellation

Co-authored-by: Peter Steinberger <steipete@gmail.com>

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-08-25 10:21:30 -07:00
Peter Steinberger 1699e98400 fix(browser): detect selected profile executable consistently (#129394) 2026-08-25 08:30:05 -07:00
Peter Steinberger bc4ce76db3 refactor(browser): deduplicate browser executable candidates (#129323) 2026-08-25 05:56:47 -07:00
Peter Steinberger 3506a55218 refactor(browser): unify browser mutation routes (#129303) 2026-08-25 05:28:28 -07:00
Peter Steinberger 4dc7bb7411 chore(deps): refresh dependencies after seven-day cooldown (#129187)
* chore(deps): refresh dependencies after cooldown

* fix(gateway): emit append-only Responses content events

* chore(deps): retain unverified Sherpa runtime
2026-08-25 05:00:46 -07:00
Peter Steinberger 5fde973580 refactor(browser): unify guarded page interactions (#129274) 2026-08-25 04:44:40 -07:00
Peter Steinberger f15ec26994 fix(browser): honor inherited timeouts across browser commands (#129176)
* fix(browser): honor inherited timeouts across browser commands

* test(browser): keep resize timeout regression type-safe
2026-08-25 02:14:50 -07:00
nissl24 8f243929e4 fix(browser): preserve agent identity for screenshot vision (#121941)
Fixes #121919. Preserve screenshot session ownership through the focused agent-scope SDK before media runtime resolves provider credentials.

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-08-25 01:04:55 -07:00
Peter Steinberger a30e310910 fix(browser): isolate parent and leaf CLI options (#128870) 2026-08-24 14:58:34 -07:00
Peter Steinberger 03658a99a9 fix(browser): stop cancelled downloads from publishing files (#128651)
* fix(browser): cancel in-flight downloads before atomic publication

* fix(browser): type download capture event and deferred fixtures

* fix(browser): ratchet down obsolete download capture assertions
2026-08-24 05:10:48 -07:00
Peter Steinberger 234df15a6d chore: refresh dependencies after seven-day cooldown (#128414)
* build(deps): refresh dependencies after cooldown

Apply dependency, toolchain, action, image, and exact tool updates released by the inclusive 2026-08-16 seven-day cutoff. Adapt owner boundaries for the resulting CUA, logging, Teams, Markdown, native, and test-harness contract changes while retaining versions blocked by upstream compatibility constraints.

* fix(ui): align markdown renderer env typing

* fix(deps): align postcss and mistral peer contracts

* fix(deps): repair refreshed dependency contracts

* fix(deps): retain tslog startup budget

* fix(ci): verify Android tools with SHA-256

* fix(ci): fence Android SDK cache version
2026-08-24 03:01:54 -07:00
Peter Steinberger d6679815a8 perf(browser): streamline snapshot finalization (#128036)
Amp-Thread-ID: https://ampcode.com/threads/T-01a021f5-984a-7628-a30c-491c166ff247

Co-authored-by: Amp <amp@ampcode.com>
2026-08-22 14:20:18 -07:00
Peter Steinberger c8b6ec5b33 refactor(browser): remove test route bypass (#127727) 2026-08-21 18:34:01 -07:00
Peter Steinberger 731e9e7681 perf(test): speed up browser extension state observations (#127471) 2026-08-21 13:18:11 -07:00
Dallin Romney 8dd21b0f34 fix(browser): load Playwright runtime on demand (#127049)
* fix(browser): load Playwright runtime on demand

* test(browser): use lazy Playwright accessor

* fix(worker): bind bundled Playwright runtime

* style(worker): format build regression

* style(worker): apply repository formatter
2026-08-21 10:45:18 -07:00
Dallin Romney d0091b001c fix(browser): isolate startup upload cleanup runtime (#126136)
* fix(browser): keep node-host cleanup lazy

* fix(browser): isolate upload cleanup runtime
2026-08-20 20:52:41 -07:00
施清荃 a2fe7c395d fix(browser): resolve chrome-extension bundled dir from built package layout (#126279)
The browser doctor computed BROWSER_PLUGIN_ROOT by walking one directory
up from the source file. In a source checkout the file lives in
extensions/browser/src/ and chrome-extension assets are at
extensions/browser/chrome-extension, so this worked. In a built package the
compiled artifact lives at the package root (dist/extensions/browser/) and
assets are at dist/extensions/browser/chrome-extension, so the old heuristic
looked for dist/extensions/chrome-extension and failed with ENOENT.

Resolve the package root by searching for package.json, which exists in both
layouts, and fall back to the previous heuristic only when it is absent.

Fixes the doctor report: 'Chrome extension bootstrap status could not be
inspected: ENOENT ... realpath /dist/extensions/chrome-extension'.
2026-08-20 01:50:26 -07:00
Peter Steinberger 14c02a43ab fix(mcp): stop revoked App actions after catalog waits (#126415)
* fix(mcp): revalidate app grants after catalog work

* test(mcp): track grant proof temp state

* test(browser): use canonical graceful stop budget
2026-08-19 13:35:01 -07:00