Commit Graph
112 Commits
Author SHA1 Message Date
can1357 1b5148ed84 Merge PR #7368: fix(browser): guard cmux guest rejections (@roboomp) 2026-08-03 14:46:24 +02:00
can1357 ef852af986 feat(computer): implemented modular desktop backend and script workflows
- Replaced monolithic desktop native bindings and action batching with a modular cross-platform backend structure supporting Wayland, X11, macOS, and Win32.
- Updated the computer tool schema and supervisor to execute persistent JavaScript script runs with timeout clamping and asynchronous tool calling.
- Integrated accessibility (AX) tree snapshotting, node querying, and bounds-based hit testing across platform desktop layers.
- Added native clipboard bindings and updated coding-agent prompts, renderers, and tests to validate script-based computer workflows.
2026-08-02 19:46:25 +02:00
can1357 92b50faacc feat(coding-agent/lsp): implemented lsp multiplexer server and shared daemon lifecycle
- Added an LSP multiplexer server, protocol definitions, and daemon lifecycle management to route traffic across sessions.
- Introduced `lsp.shared` settings configuration and SDK session creation support for shared language servers.
- Migrated shared daemon ensure helpers into a central launch module with updated import references.
- Added comprehensive unit tests and fake LSP server fixtures covering muxing, sharing, caching, and restarts.
2026-08-02 18:15:22 +02:00
can1357 4a946e2cfc fix(coding-agent/tools): serialized tab grouping operations in the relay bridge
- Serialized group and ungroup operations to prevent duplicate tab group creation races.
- Queued and serially drained tab grouping requests in the relay bridge to prevent overlapping RPCs.
- Mirrored tab group titles to session storage and healed duplicate groups during background service worker recovery.
- Renamed run-cancellation utility to run-scope and updated corresponding module and test references.
2026-08-02 18:07:07 +02:00
roboomp c802475aa0 fix(browser): scoped cmux attribution to guest stacks
Dropped the single-active-run fallback that claimed unrelated stackless rejections in the shared main-process realm, matching the eval inline-mode invariant. Only guest-file stack frames attribute a rejection now; stackless reasons keep the fatal path. Restored the probe to an Error rejection carrying a guest stack.

Fixes #7365
2026-08-02 09:37:17 +00:00
roboomp 6113fe9727 fix(browser): handled stackless cmux rejections
Attributed unmatched rejection reasons when exactly one cmux guest run is active, covering primitive and library-created failures without guessing between concurrent runs. Updated the process probe to reject with a primitive value.

Fixes #7365
2026-08-02 09:31:21 +00:00
roboomp 8d4521db78 fix(browser): guarded cmux guest rejections
Captured browser-run-attributable promise rejections before the global fatal handler and surfaced active failures as tool errors. Retained finished run filenames so late rejections remain isolated without consuming unrelated process failures.

Fixes #7365
2026-08-02 09:20:54 +00:00
can1357 92c79d80c7 feat: introduced OMP Browser Relay extension with CDP RPC execution
- Implement the OMP Browser Relay extension with WebSocket communication and CDP RPC execution.
- Add browser relay server, daemon management, and bridge multiplexing in the coding agent.
- Introduce CLI commands and settings schema options for configuring and installing the relay.
- Add utility functions and test suites supporting environment parsing and relay lifecycle handling.
2026-08-02 05:33:07 +02:00
can1357 ad78b6a84e feat(coding-agent/tools): implemented shared browser daemon management
- Added `ensureSharedBrowser` and shared browser acquisition to manage project-shared broker-owned Chromium instances.
- Implemented concurrent duplicate daemon start prevention and single-flight `pendingOpens` deduplication.
- Updated browser handle disposal to disconnect from shared daemons rather than closing them.
- Updated browser documentation and launch specifications to support shared and local headless runs.
2026-08-01 08:30:05 +02:00
can1357 a6c6257574 chore: applied formatter and deduplicated observer stubs in task fixtures 2026-07-31 19:51:52 +02:00
can1357 63d6bd3064 Merge PR #7060: fix(browser): own headless Chromium profile dir to survive Windows EBUSY cleanup (@roboomp) 2026-07-31 19:42:43 +02:00
can1357 f46af54f9c fix(browser): preserve screenshot correctness when attached 2026-07-31 19:42:42 +02:00
can1357 ce1ec2103f Merge PR #7006: fix(tools): stop browser automation from stealing focus in an attached browser (@terrxo)
# Conflicts:
#	packages/coding-agent/src/tools/browser/tab-supervisor.ts
2026-07-31 19:42:12 +02:00
can1357 9c1facec10 test(browser): cover attached tab navigation 2026-07-31 19:41:44 +02:00
roboomp d0649f9917 fix(browser): reused shared temp removal retries
Route Chromium profile cleanup through pi-utils removeWithRetries while preserving browser-specific warn-and-leave behavior.

Fixes #7058
2026-07-30 05:22:14 +00:00
roboomp 7ab3d2ecb6 fix(browser): cleaned headless profile after failed launch
Remove the OMP-owned Chromium user-data directory when executable resolution or puppeteer launch fails before a browser handle exists.

Fixes #7058
2026-07-30 05:19:18 +00:00
roboomp afd6f8eed4 fix(browser): own headless chromium profile dir to survive windows ebusy cleanup
launchHeadlessBrowser let puppeteer-core create and delete a temporary
Chrome profile via an unretried rm() from an eager process-exit hook. On
Windows, when an orphaned browser tree still held the profile lock, that
rm threw EBUSY and rejected the eager promise with no handler attached,
crashing OMP with an unhandled rejection during cleanup.

OMP now passes an explicit --user-data-dir, which makes puppeteer treat
the profile as non-temporary (ChromeLauncher.cleanUserDataDir becomes a
no-op), and removes the directory itself on dispose with lock-tolerant
retry, warning and leaving it in place if it stays busy rather than
crashing.

Fixes #7058
2026-07-30 05:09:26 +00:00
Nik Divjak b8b0d342da fix(tools): stop browser automation from stealing focus in an attached browser
Attaching over app.cdp_url points automation at a browser the user is driving,
so two behaviors that are correct for a browser we own are wrong there.

pickElectronTarget enumerated CDP targets and took the first usable one, which
is not necessarily the tab in front of the user, and #captureScreenshot always
called page.bringToFront(), which switches the user's visible tab and pulls
window focus on every screenshot.

Connected browsers now prefer a tab that reports document.visibilityState
"visible" and skip the pre-capture activation, accepting the compositor stall
risk that activation avoids. Headless and spawned browsers are unchanged.
2026-07-29 11:26:13 +02:00
Nik Divjak da1d393c39 fix(tools): navigate to the requested url when opening an attached browser tab
buildInitPayload dropped opts.url, opts.waitUntil and opts.timeoutMs on the
attach branch, so `browser open` with a url against app.cdp_url or app.path
adopted the existing target without navigating and reported its current url as
the result. Reusing the same tab name afterwards did navigate, because the reuse
path issues tab.goto, so the same call behaved differently on first open.

Thread the navigation fields through the attach arm of WorkerInitPayload and
goto after the page is adopted and the dialog policy is installed, mirroring the
headless arm.
2026-07-29 11:20:52 +02:00
can1357 e7009452b4 feat(coding-agent/tools): simplified browser screenshot persistence and return paths
- Remove the per-call `save` option from `tab.screenshot()` to simplify usage.
- Update `tab.screenshot()` to return the saved file path as a promise string.
- Configure screenshot persistence to use daemon path or custom `browser.screenshotDir`.
- Add comprehensive tests verifying temp path return and custom directory saving.
2026-07-28 06:40:31 +02:00
can1357 ff49b986d5 feat(coding-agent/tools): introduced language-specific code formatters for display rendering
- Added language-specific code formatters for JavaScript, Julia, Python, and Ruby to improve display rendering.
- Integrated display formatting into browser run and eval render tools while preserving verbatim execution.
- Added comprehensive test suites verifying formatting stability, lexical safety, and streaming behavior.
2026-07-24 16:26:03 +02:00
can1357 1e1d2e91ea style: applied biome formatting 2026-07-24 02:27:35 +02:00
can1357 3d64910bb0 feat(coding-agent/live): added realtime voice interaction with Codex Live sessions (experimental)
- Added `src/live/` subsystem with WebRTC transport, protocol parser, session controller, and headless Chromium audio injection.
- Added `LiveVisualizer` component with phase states, transcript display, and animated waveform rendering.
- Added `/live` slash command and `LiveCommandController` to toggle live voice sessions.
- Suppressed local TTS via `vocalizer.suspend()` during live mode to prevent audio conflicts.
- Added live-instructions and agent-final-message prompts for agent messaging context.
- Added `protocol.test.ts` covering event parsing, chunking, and context message construction.
2026-07-24 02:20:43 +02:00
roboomp d4b1fd5107 fix(browser): bound open timeout and lease browser across tab acquisition
The browser tool's open action only passed the requested timeout to acquireTab; acquireBrowser ran under the caller signal alone, so CDP discovery/connect could run through its own fixed 5s/30s waits past the requested deadline. A freshly-created browser also sat in the registry at refCount 0 during worker/surface acquisition: the worker-abort branch released it only on tempHold (never on the fresh refCount-0 case), orphaning the handle, and two different-name opens sharing one refCount-0 browser let a single failure dispose it out from under the survivor.

Compose one open deadline from the caller signal and params.timeout and thread it through both acquireBrowser and acquireTab; caller cancellation stays ToolAbortError, the requested timeout becomes a timeout ToolError. Hold one explicit registry lease across tab acquisition, released exactly once on the mutually-exclusive success/rollback paths, and make the worker-abort browser release mirror the error paths' refCount-0 check.

Fixes #6365
2026-07-23 19:02:38 +00:00
can1357 4617d71ba7 fix(browser): keep raw AbortSignal identity through run facade
Native combinators (AbortSignal.any, fetch) brand-check internal slots
that a Proxy cannot forward; return signals unwrapped from
bindBrowserRunFacade so tab.signal composes with native cancellation.
2026-07-18 21:04:16 +02:00
can1357 707932e786 Merge PR #5588: fix(browser): observe raw promises before target close (@serverinspector)
# Conflicts:
#	packages/coding-agent/src/tools/browser/tab-worker.ts
#	packages/coding-agent/test/tools/browser-tab-evaluate.test.ts
2026-07-18 21:04:16 +02:00
can1357 31f7aa6d58 Merge PR #5778: fix(browser): reject non-string tab selectors with a named error (@roboomp)
# Conflicts:
#	packages/coding-agent/src/prompts/tools/browser.md
#	packages/coding-agent/src/tools/browser/aria/aria-snapshot.ts
2026-07-18 20:13:44 +02:00
can1357 22b2a1d8f0 Merge PR #5789: fix(browser): support authenticated cmux TCP relays (@roboomp) 2026-07-18 20:12:47 +02:00
can1357 6c8b0f4a2f Merge PR #5906: fix(browser): bound scroll renderer acknowledgement wait (@roboomp) 2026-07-18 19:57:44 +02:00
can1357 b95a25820f Merge PR #6005: fix(browser): isolate request interception per run (@roboomp) 2026-07-18 19:42:36 +02:00
roboomp e0358b77a0 fix(browser): unregister fired once request handlers
- Removed the once wrapper from Puppeteer's request emitter on first fire so it cannot leak into later runs.
- Added regression coverage asserting a fired once handler leaves zero residual request listeners.

Fixes #6004
2026-07-18 16:31:10 +00:00
roboomp fe2fdf6564 fix(browser): isolated request interception per run
- Removed run-scoped Puppeteer request handlers and disabled interception on every browser.run exit path.
- Recycled workers when bounded interception cleanup cannot restore the tab, with raw CDP recovery for held requests.
- Added live Chromium coverage for held requests, normal traffic restoration, and thrown setup calls.

Fixes #6004
2026-07-18 16:22:40 +00:00
can1357 1a6fc09611 feat(tools): added bare ARIA ref support in browser actions, fixed select() double-count
- Added bare `eN`/`@eN` regex to `parseAriaRefSelector` so agents can copy refs straight from snapshot output.
- Applied ref resolution to `press`, `screenshot`, `drag`, `select`, and `uploadFile` action handlers.
- Fixed `#select` to assign the full option set first then read back, avoiding double-counting when unselecting mid-loop.
2026-07-18 17:51:54 +02:00
roboomp 4e216a3b98 fix(browser): canceled settled scroll timers
- Replaced the losing Bun.sleep with an unrefed timeout cleared in a finally block.
- Added regression coverage that verifies prompt wheel acknowledgements leave no timer behind.

Fixes #5905
2026-07-17 20:10:01 +00:00
roboomp b8ef46a0c8 fix(browser): bounded scroll acknowledgement wait
- Released tab.scroll after two seconds when a queued wheel event waits on a busy renderer acknowledgement.
- Preserved immediate dispatch failures and added regression coverage for both outcomes.

Fixes #5905
2026-07-17 20:02:53 +00:00
roboomp 940f19d8c4 fix(browser): supported authenticated cmux tcp relays
Dialed loopback CMUX_SOCKET_PATH endpoints over TCP and completed the cmux relay HMAC challenge before sending JSON-RPC requests.

Loaded relay credentials from the session environment or the per-port cmux auth file while preserving Unix socket behavior.

Fixes #5788
2026-07-17 03:42:01 +00:00
roboomp 7715132e71 fix(browser): guard cmux selector funnel against non-string selectors
CmuxTab.#selectorSpec bypassed the puppeteer-backend guards and called
normalized.startsWith(...) directly, so tab.click(await tab.ref("e5")) on a
cmux surface still threw the opaque TypeError instead of the named ToolError.
Apply assertSelectorString at the cmux funnel too.

Fixes #5776
2026-07-17 02:14:58 +00:00
roboomp 9f836712e8 fix(browser): rejected non-string tab selectors with a named error
tab.click/type/fill/waitFor*/scrollIntoView route their selector through
parseAriaRefSelector (.trim) and normalizeSelector (.startsWith) before any
validation, so passing the ElementHandle from tab.id(n)/tab.ref(...) (or an
un-awaited Promise of one) crashed with the opaque minified
"A.trim is not a function" instead of an actionable error.

- Added assertSelectorString guard at both selector funnels; throws a ToolError
  naming the recovery ((await tab.id(n)).click() or a string selector) and
  distinguishing ElementHandle / Promise / primitive.
- Corrected browser.md: handles are called directly, not fed to tab.click.
- Regression tests in both selector suites.

Fixes #5776
2026-07-17 02:10:55 +00:00
can1357 7363684cb6 merged PR #5453: fix(browser): bound tab teardown waits
# Conflicts:
#	packages/coding-agent/src/tools/browser/registry.ts
#	packages/coding-agent/src/tools/browser/tab-supervisor.ts
2026-07-16 03:43:17 +02:00
serverinspector d52084f536 fix(browser): observe raw promises before target close 2026-07-15 14:35:44 +00:00
can1357 6f8a3ab94a Merge PR #5458: fix(browser): bound headless browser close to unblock tab cleanup (@roboomp) 2026-07-14 22:58:47 +02:00
roboomp 33e87d5930 fix(browser): bound headless browser close to unblock tab cleanup
disposeBrowserHandle awaited Puppeteer's browser.close() for the headless
kind with no timeout. browser.close() resolves only once Chromium fully
exits, so a wedged process (a Windows failure mode) left releaseTab stuck
in the "Closing tab" phase forever.

Cap the close at 5s and force-kill the Chromium process tree on timeout so
the tool call always releases.

Fixes #5260
2026-07-14 17:48:18 +00:00
roboomp 7b399b32a2 fix(browser): bounded tab teardown waits
- Applied close deadlines to cmux surfaces, orphan targets, and browser handles.
- Surfaced the backend, tab name, and pending cleanup resource on timeout.
- Forced stuck headless browser processes down after Browser.close timed out.

Fixes #5259
2026-07-14 17:37:01 +00:00
can1357 3047c27c33 fix(test): skip real-browser tab.evaluate test when chromium cannot exec
- Exported ensureChromiumExecutable so the test can probe launchability.
- CI runner holds the downloaded Chrome but lacks libnspr4 & co., so the
  binary fails at dynamic-link time; probe --version and skipIf instead
  of failing the release run.
2026-07-14 02:12:21 +02:00
can1357 8c8afaf477 fix(browser): made tab evaluation use the main world 2026-07-13 00:05:43 +02:00
can1357 0d07da529a feat(coding-agent-tools): implemented browser execution safety controls
- Implemented cell budget clamping for timeouts to prevent stalled browser operations from exceeding execution limits.
- Added `recover` capabilities for tab workers to clear blocking dialogs and safely terminate hung navigations.
- Introduced `//!world=main` support for `tab.evaluate` via Puppeteer patch to allow execution in main execution contexts.
- Improved failure attribution for tab terminations by tracking dialogs, stalled operations, and specific termination reasons.
2026-07-13 00:05:43 +02:00
can1357 bd7d395222 feat(coding-agent/tools): added predicate polling support to wait()
- Enhanced `wait()` in browser tools to accept a predicate function in addition to milliseconds.
- Implemented automatic polling with configurable timeout and interval, resolving with the first truthy value.
- Throws a descriptive `ToolError` on timeout instead of waiting for the full execution deadline.
- Added comprehensive unit tests to verify polling behavior, cancellation, and error handling.
2026-07-13 00:05:42 +02:00
can1357 9ebc239280 feat(coding-agent/tools): added fail-fast watchdog for browser selector ops
- Implement a zero-match watchdog for browser selector operations that aborts after ~2s if no elements are found, preventing actions from unnecessarily consuming the full deadline.
- Lower the default interactive action operation ceiling from 15s to 8s.
- Update `waitFor` and `waitForSelector` to conditionally opt out of the fast-fail mechanism when explicit timeouts or hidden-state expectations are provided.
2026-07-11 07:33:20 +02:00
can1357 a9cdaf427a feat(coding-agent/tools): standardized browser tool execution flow
- Introduced `RunOutput` class to standardize buffering and sequencing of stream text, displays, and screenshots.
- Standardized element interaction via `ActionableHandle` and `fillViaHandle` to improve focus, clear, and typing reliability.
- Updated browser tool method signatures to return consistent actionable handles and integrated diagnostic hints for selector timeouts.
- Consolidated utility functions for safer serialization and cross-boundary value passing into the new output module.
2026-07-11 07:33:19 +02:00
can1357 d993b13c80 fix(coding-agent): strengthened browser interaction reliability and error transparency
- Implemented a try/catch envelope for browser evaluations to surface detailed page-side JS exceptions and detect unsupported Promise returns.
- Added transparent error reporting for cmux browser surface limitations regarding screenshot clipping and full-page captures.
- Forced tab activation before screenshot capture to prevent stale or sibling-tab image data in shared-endpoint environments.
2026-07-11 05:47:54 +02:00