Skip to content

feat: list, inspect, and navigate tabs in a dedicated browser - #163

Merged
iamnbutler merged 3 commits into
mainfrom
codex/browser-pages
Oct 6, 2026
Merged

iamnbutler merged 3 commits into
mainfrom
codex/browser-pages

Conversation

@iamnbutler

@iamnbutler iamnbutler commented Oct 6, 2026 •

Copy link
Copy Markdown
Contributor

First browser slice for #50; it doesn't close #50. Three tools list, navigate, and inspect tabs in a dedicated development browser on the execution host, over direct Chrome DevTools Protocol on loopback.

  • Wiring. A runtime-neutral Browser capability (packages/channel/src/browser.ts) is injected at Channel.open by the local worker, the workspace Link/serve, and the hosted object. Pi stores the results; there is no new store.

  • Dedicated browser only. apps/host/src/browser.ts reads DevToolsActivePort only from $ACE_HOME/browser and checks the port and browser path. It never reaches personal browsers or other debugging sessions, and it doesn't launch the browser. Refusals include a macOS or Linux launch command.

  • Exact targets. A target is the browser instance ID plus Chrome's target ID. Every call refuses a replaced browser or a closed or non-page tab before dispatch. Tabs are never chosen by URL, title, or position, and prerender targets are not listed.

  • browser_inspect returns:

    • the main frame's accessibility tree, capped at 32 KB of UTF-8 with 400-byte fields;
    • an unresized viewport JPEG of at most 4096 px per side and 900 KB;
    • the loader ID before and after, so the result says whether the document changed.

    A screenshot, deadline, or 16 MB per-command failure keeps the other evidence. Results stay under 2 MB.

  • browser_navigate (http/https only) runs sequentially and is unsafe to replay. Chrome's answer comes back as started, same_document, download (keeping the error text), or failed, never as readiness. An uncertain dispatch or answer is unknown, and dispatch may have happened.

Validation

bun types and bun run ci pass. CI passed on 0ee3f53. The runtime checks exercised the same host behavior before the final wording and launch-hint edits (8ff9cd2, 8f227e1, and the Linux hint), not every check on the exact final head. Detailed logs are kept privately.

  • Real Chrome for Testing 153 and Chrome 154, each with its own temporary profile:
    • Same-title tabs stayed distinct.
    • Closed, replaced, and stale targets were refused.
    • Normal, hash, failed, and download navigation returned the expected statuses.
    • Cancelling before dispatch was refused. Cancelling after dispatch was unknown, and the navigation still happened.
    • A wide accessibility tree was bounded as expected. An oversized tree failed only its own command and kept the screenshot.
    • A zoomed, scrolled viewport capture was checked.
  • Real Anthropic model in a native channel:
    • Tabs, navigate, and inspect worked on the rendered Ace app shell. It showed the disconnected-host banner; this was not an authenticated workflow.
    • The screenshot was stored in history.
    • After I killed the worker mid-navigation, the reopened worker reported it interrupted and did not repeat it.
    • Tool results and usage stayed identical through a fresh worker reopen.
  • Compiled Ace Helper: the worker reopened without replay. Fresh tools completed once the key was passed into that disposable worker's environment. Its first run stalled before admission, likely on the Keychain lookup.
  • Workspace forwarding: real Link/serve over a WebSocket. While disconnected, navigation was refused and inspection failed. After reconnecting, the same browser identity worked. A drop during navigation was unknown.

Limits

  • I did not run a deployed or wrangler dev hosted object.
  • Still open in Inspect and debug browser pages from an Ace channel #50: DOM input and element references, console and network inspection, uploads, viewport and mobile emulation, managed browser launch, iframe content, Browser Preview, and reproducing, fixing, and verifying a real defect end to end.
  • Cleanup is done: the owned processes are stopped, and the temporary profiles, host data, project, and helper are deleted. One smoke download had landed outside the profile, at /Users/natebutler/Downloads/x.bin. A direct-path check confirmed it was 4 bytes containing data, and I removed it.

Built in Ace

Implementation, validation, commits, and this PR were done by the native Ace channel browser-pages, using Ace's lane, shell, file, and model tools. External Codex did read-only architecture research coordination and review, and passed notes into the channel, because Ace lacks external-harness support (#9). No code or validation ran outside Ace.

@iamnbutler
iamnbutler merged commit 8ae23e4 into main Oct 6, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Inspect and debug browser pages from an Ace channel

1 participant