{"id":51511043,"url":"https://github.com/aduermael/wb","last_synced_at":"2026-07-08T06:02:01.253Z","repository":{"id":366237502,"uuid":"1275551473","full_name":"aduermael/wb","owner":"aduermael","description":"macOS 26+ browser CLI for agents: persistent sessions, compact JSON, screenshots, clicks/forms, JS eval, and live preview in under 2 MB.","archived":false,"fork":false,"pushed_at":"2026-07-07T22:40:50.000Z","size":527,"stargazers_count":60,"open_issues_count":1,"forks_count":2,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-07-08T00:12:16.908Z","etag":null,"topics":["agent-tools","ai-agents","automation","browser","browser-automation","cli","macos","screenshot","swift","web-browser"],"latest_commit_sha":null,"homepage":"","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/aduermael.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-20T21:00:13.000Z","updated_at":"2026-07-05T14:27:55.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/aduermael/wb","commit_stats":null,"previous_names":["aduermael/wb"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/aduermael/wb","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aduermael%2Fwb","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aduermael%2Fwb/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aduermael%2Fwb/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aduermael%2Fwb/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/aduermael","download_url":"https://codeload.github.com/aduermael/wb/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aduermael%2Fwb/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35253863,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-08T02:00:06.796Z","response_time":61,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["agent-tools","ai-agents","automation","browser","browser-automation","cli","macos","screenshot","swift","web-browser"],"created_at":"2026-07-08T06:02:00.308Z","updated_at":"2026-07-08T06:02:01.245Z","avatar_url":"https://github.com/aduermael.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"# wb\n\n[![Lint](https://github.com/aduermael/wb/actions/workflows/lint.yml/badge.svg)](https://github.com/aduermael/wb/actions/workflows/lint.yml)\n[![Tests](https://github.com/aduermael/wb/actions/workflows/test.yml/badge.svg)](https://github.com/aduermael/wb/actions/workflows/test.yml)\n\n`wb` is a macOS 26+ web browser for agents, exposed as a lightweight command-line tool.\n\nIt gives scripts and coding agents a real persistent browser session without a bundled Chromium, driver server, or heavyweight app wrapper. The release binary is less than 2 MB, starts from a normal shell command, speaks compact JSON, and can still show a live native preview window when you need to see what the agent sees.\n\n`wb` is built on macOS system browser technology and is macOS-only. It does not run on Linux, Windows, or older macOS releases.\n\n## ✨ Why wb\n\n- **Small enough to vendor into agent workflows.** A single lightweight macOS binary, not a browser distribution.\n- **Made for command loops.** Create a browser once, then navigate, inspect, click, type, fill, scroll, screenshot, and evaluate JavaScript across separate CLI calls.\n- **Structured output by default.** Commands return compact JSON summaries and stable action indexes that are easy for agents to consume.\n- **Headless until you need eyes.** Use `wb show \u003cid\u003e` to attach a live preview window to the same browser session, then `wb hide \u003cid\u003e` to go back to CLI-only control.\n- **Coordinates and screenshots line up.** The screenshot viewport is the same coordinate space used by `click`, `press`, `drag`, `release`, and `scroll`.\n\n## 🚀 Install\n\nFor agent workflows when `wb` is already installed, install the embedded skill\nfolder in the current project:\n\n```bash\nwb install-skill --codex\n```\n\nUse `--claude`, `--grok`, or `--all` for other agent targets. Without target\nflags, `wb install-skill` installs the default Codex, Claude, and Grok skill\nfolders.\n\nIf you want the skill to install `wb` for agents that do not have the binary\nyet, use the standalone skill installer:\n\n```bash\ncurl -fsSL https://raw.githubusercontent.com/aduermael/wb/main/install-skill.sh | sh -s -- --codex\n```\n\nThe skill includes a bundled `install.sh` support script that makes the `wb`\ncommand available if an agent tries to use the skill before the CLI is installed.\nThat support script tries Homebrew first, then npm, then the standalone installer.\n\nTo install every default target with the standalone installer:\n\n```bash\ncurl -fsSL https://raw.githubusercontent.com/aduermael/wb/main/install-skill.sh | sh -s -- --all\n```\n\nTo install the CLI immediately while installing the skill:\n\n```bash\ncurl -fsSL https://raw.githubusercontent.com/aduermael/wb/main/install-skill.sh | sh -s -- --codex --install-cli\n```\n\nNormal `wb` commands also launch a silent project-local skill refresh in the\nbackground. That refresh only updates existing `wb` skill folders and never\ncreates missing Codex, Claude, or Grok targets. Set `WB_SKILL_AUTO_UPDATE=off`\nto disable it.\n\nTo install only the CLI, use Homebrew:\n\n```bash\nbrew install aduermael/tap/wb\n```\n\nAfter the npm package has been published, use npm:\n\n```bash\nnpm install -g @aduermael_/wb\n```\n\nThe npm package is a thin wrapper that downloads the prebuilt macOS release\nbinary. It still requires macOS 26.0 or newer, and it does not require Xcode or\na Swift toolchain.\n\nOr use the standalone installer:\n\nPrebuilt releases are macOS 26+ binaries. Installing them does not require Xcode or a Swift toolchain.\n\n```bash\ncurl -fsSL https://raw.githubusercontent.com/aduermael/wb/main/install.sh | sh\n```\n\nBy default this installs to `/usr/local/bin/wb`, which is on `PATH` for most macOS shells. If that location requires admin permissions, the script offers to use `sudo`.\n\nTo choose another location:\n\n```bash\ncurl -fsSL https://raw.githubusercontent.com/aduermael/wb/main/install.sh | env WB_INSTALL_DIR=\"$HOME/.local/bin\" sh\n```\n\nTo install a specific release:\n\n```bash\ncurl -fsSL https://raw.githubusercontent.com/aduermael/wb/main/install.sh | env WB_VERSION=0.1.0 sh\n```\n\nRelease builds check for a newer version at most once every 12 hours and print an update notice to stderr when stale. Run `wb update` to upgrade; Homebrew installs delegate to `brew update` and a no-ask `brew upgrade wb`, npm installs delegate to `npm install -g @aduermael_/wb@latest`, and standalone installs replace the current binary.\n\n## ⚡ Quick Start\n\n```bash\nwb https://example.com\n```\n\nThat creates a browser, loads the page, and prints a compact JSON summary. For a longer-lived session:\n\n```text\n$ wb https://example.com\n{\"actions\":1,\"browser\":\"a3f19c0b\",\"htmlBytes\":1256,\"jsonBytes\":468,\"progress\":1.0,\"resources\":0,\"title\":\"Example Domain\",\"url\":\"https://example.com/\"}\n\n$ wb page a3f19c0b\n{\"actions\":[{\"href\":\"https://www.iana.org/domains/example\",\"index\":1,\"kind\":\"link\",\"text\":\"More information...\"}],\"browser\":\"a3f19c0b\",\"htmlBytes\":1256,\"jsonBytes\":488,\"progress\":1.0,\"resourceCount\":0,\"text\":\"Example Domain\\n\\nThis domain is for use in illustrative examples in documents. You may use this domain in literature without prior coordination or asking for permission.\\n\\n[More information...](https://www.iana.org/domains/example)\",\"title\":\"Example Domain\",\"url\":\"https://example.com/\"}\n\n$ wb click a3f19c0b 1\n{\"actions\":1,\"browser\":\"a3f19c0b\",\"htmlBytes\":1256,\"jsonBytes\":468,\"message\":\"clicked More information...\",\"progress\":1.0,\"resources\":0,\"title\":\"Example Domain\",\"url\":\"https://example.com/\"}\n\n$ wb screenshot a3f19c0b /tmp/example.png\nsaved /tmp/example.png\n\n$ wb show a3f19c0b\n$ wb hide a3f19c0b\n```\n\n## 🧰 Requirements\n\nThe install path is intentionally light: prebuilt binaries do not require Xcode or a Swift toolchain.\n\nTo run a prebuilt release:\n\n- macOS 26.0 or newer\n- No Xcode required\n- No Swift toolchain required\n\nTo build from source:\n\n- A Mac with macOS 26.0 or newer\n- Xcode 26 or newer, with Swift 6.2 SDKs\n\n## 🛠️ Build From Source\n\n```bash\nswift build -Xswiftc -warnings-as-errors\n.build/debug/wb https://example.com\n```\n\nFor a local debug binary at `./wb`:\n\n```bash\n./build.sh\n./wb https://example.com\n```\n\n`build.sh` signs the final `./wb` binary by default using ad-hoc codesigning, so no Apple Developer ID is required. To use a specific local signing identity:\n\n```bash\nWB_CODESIGN_IDENTITY=\"wb local code signing\" ./build.sh\n```\n\nSet `WB_CODESIGN=off` to skip signing for local debugging.\n\n## 🧹 Lint\n\nFormat Swift source with the native Swift formatter:\n\n```bash\n./format.sh\n```\n\nCheck formatting and repository-specific lint rules:\n\n```bash\n./lint.sh\n```\n\n`lint.sh` first runs `swift format lint --strict`, then runs the custom SwiftPM\n`wblint` executable for rules that are specific to this repository.\n\n## ✅ Test\n\n```bash\n./test.sh\n```\n\nThe app target is macOS-only because it uses AppKit and WebKit, so the full test\nsuite runs in macOS CI. `build.sh`, `test.sh`, `lint.sh`, and release builds\ncompile Swift with warnings treated as errors.\n\n## 🤖 Agent Skill\n\nThis repo includes a standalone agent skill folder at [skill](skill). It contains the skill instructions plus an `install.sh` support script that installs `wb` through Homebrew when available, npm when available, or the standalone installer otherwise. The release binary also embeds these files and can write them with `wb install-skill`.\n\nIn this checkout, `.agents/skills/wb`, `.claude/skills/wb`, and `.grok/skills/wb` are symlinks to `skill/`, so each agent sees both files. In another project, use `wb install-skill` or `install-skill.sh` from the install section to copy the folder into the local agent skill directories.\n\n## 📦 Output\n\n`wb` keeps structured CLI JSON compact by default. JSON is emitted on one line and omits fields with default values. Error responses preserve `ok:false`. Raw `eval` results are printed as returned strings.\n\nCommands avoid returning a full page snapshot unless explicitly asked. Use `wb \u003curl\u003e` or `wb \u003cid\u003e \u003curl\u003e` for a compact summary containing the browser ID, title, URL, page/resource loading status, action count, resource count, full-document HTML byte count, and default page JSON byte count. Use `wb wait-resources \u003cid\u003e` or `wb page \u003cid\u003e --resource-timeout \u003cseconds\u003e` after navigation only when loaded resources matter. Use `wb page \u003cid\u003e` when you need visible text, the full action list, and loaded resource URLs.\n\nBrowser IDs are random 8-character lowercase hex strings. Page snapshot text is markdown-like and includes inline links where possible. Page actions are compact by default and include a 1-based `index` for `click`, `type`, `fill`, and `submit`; internal IDs, CSS selectors, and tags are omitted unless requested. Resource entries include a 1-based `index`, `type`, and resolved URL. The `resources` array is capped at 250 entries to keep output bounded, while `resourceCount` reports the total discovered resources. Use `wb page \u003cid\u003e --action-details` to include internal action IDs, or `wb page \u003cid\u003e --selectors` to include CSS selectors.\n\nNavigation errors are emitted as JSON responses with `ok:false` and a nonzero exit status. When a browser exists, the error JSON includes its browser ID so it can still be shown, reused, or closed.\n\nUse `wb page --help` to see filterable fields. Use `wb page \u003cid\u003e --fields title,url,resourceCount,resources,htmlBytes,jsonBytes` to print selected top-level fields.\n\n## ⌨️ Commands\n\n- `wb create`: create an empty browser and print its ID. Use this only when you need an ID before you know the URL; otherwise `wb \u003curl\u003e` creates and loads a new browser in one command.\n- `wb env`: print public metadata for the current `.wb` environment.\n- `wb install-skill [--codex] [--claude] [--grok] [--all]`: install the embedded agent skill.\n- `wb update`: update the CLI to the latest release.\n- `wb version`: print the CLI version.\n- `wb \u003curl\u003e [--wait-resources] [--resource-timeout \u003cseconds\u003e]`: create a browser, load the page, and print a compact summary. By default this returns after page HTML readiness. Use resource flags only when the initial response must wait for scripts, styles, images, and fetches; `--resource-timeout` implies `--wait-resources`; max 100 seconds.\n- `wb \u003cid\u003e \u003curl\u003e [--wait-resources] [--resource-timeout \u003cseconds\u003e]`: load a page in an existing browser. By default this returns after page HTML readiness. Use resource flags only when the initial response must wait for scripts, styles, images, and fetches; `--resource-timeout` implies `--wait-resources`; max 100 seconds.\n- `wb list [--quiet|-q]`: print active and saved browser summaries as compact JSON, or only browser IDs with `--quiet`/`-q`.\n- `wb remove \u003cid\u003e [\u003cid\u003e ...]`: remove active browsers and delete any saved sessions for those IDs.\n- `wb remove --all`: remove every active and saved browser.\n- `wb show \u003cid\u003e`: show a lightweight browser window for the browser.\n- `wb hide \u003cid\u003e`: hide the browser window without closing the browser.\n- `wb resize \u003cid\u003e [\u003cwidth\u003e \u003cheight\u003e]`: resize the browser window, or reset it to 800x600 when no size is provided.\n- `wb screenshot \u003cid\u003e \u003cdestination.png|destination.jpg\u003e [--resource-timeout \u003cseconds\u003e] [--capture-delay \u003cseconds\u003e]`: wait for resources, pause briefly for visual settling, then capture the current browser viewport as PNG or JPEG. `--resource-timeout` is capped at 100 seconds; `--capture-delay` defaults to 0.3 seconds and accepts 0 to disable.\n- `wb wait-resources \u003cid\u003e [--resource-timeout \u003cseconds\u003e]`: wait for the current page's resources to become quiet, then print a compact summary. Timeout is not a command failure; inspect `resourcesLoading` to see whether the page settled. The default timeout is 3 seconds.\n- `wb page \u003cid\u003e [--fields \u003clist\u003e] [--selectors|--action-details] [--resource-timeout \u003cseconds\u003e]`: refresh and print page JSON, including visible actions and loaded resource URLs. Without `--resource-timeout`, this returns immediately.\n- `wb click \u003cid\u003e \u003caction\u003e`: click an action from the latest page/action list and print a compact summary.\n- `wb click \u003cid\u003e \u003cx\u003e \u003cy\u003e`: click the current viewport coordinate without opening a window.\n- `wb press \u003cid\u003e \u003cx\u003e \u003cy\u003e`: send a page mouse-down event at a viewport coordinate.\n- `wb drag \u003cid\u003e \u003cx\u003e \u003cy\u003e`: send a page mouse-drag event to a viewport coordinate after `press`.\n- `wb release \u003cid\u003e \u003cx\u003e \u003cy\u003e`: send a page mouse-up event at a viewport coordinate.\n- `wb scroll \u003cid\u003e \u003cx\u003e \u003cy\u003e \u003cdeltaX\u003e \u003cdeltaY\u003e`: scroll at a viewport coordinate without opening a window.\n- `wb type \u003cid\u003e \u003caction\u003e \u003ctext\u003e [--backend js|native] [--rhythm flat|natural] [--speed \u003cfactor\u003e] [--delay-min \u003cseconds\u003e] [--delay-max \u003cseconds\u003e]`: focus a text input, textarea, or contenteditable element, then enter text with short randomized key delays. The default `native` backend sends AppKit key events to the browser's persistent WebView attachment, the default `natural` rhythm adds short word and punctuation pauses, and the default `--speed 2.0` types twice as fast as the base delays. Use `--speed 1.0` for the previous speed, and use `--backend js` or `--rhythm flat` only as fallbacks.\n- `wb fill \u003cid\u003e \u003caction\u003e \u003ctext\u003e`: directly set the value of an input, textarea, select, or contenteditable element and print a compact summary.\n- `wb submit \u003cid\u003e \u003caction\u003e`: submit the nearest form for an action and print a compact summary.\n- `wb eval \u003cid\u003e [--body] \u003cjavascript\u003e`: evaluate a JavaScript expression, or run a raw JavaScript function body with `--body`, and print the result.\n- `wb daemon \u003cstart|status|log|stop\u003e`: advanced browser session controls.\n\nEach command has its own help, for example `wb click --help` or `wb daemon --help`.\n\nBrowser IDs can be used across commands. If a saved browser is not currently active, `wb` resumes it automatically.\n\n## 📚 Documentation\n\nLower-level operational notes for persistence, environment isolation, coordinates, and daemon behavior live in [docs](docs).\n\n## 🤝 Contributing\n\nContributions are welcome. See [CONTRIBUTING.md](CONTRIBUTING.md) for setup, quality checks, and pull request guidance.\n\n## 📄 License\n\n`wb` is released under the [MIT License](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faduermael%2Fwb","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faduermael%2Fwb","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faduermael%2Fwb/lists"}