chrome · git:20261105.d6c2fba · 2026-11-05 · sha256 cf92f359f46eb4ce
chrome git:20261105.d6c2fbaA
Immutable. This exact content never changes and is served at /api/v1/blob/cf92f359f46eb4ce.
---
name: chrome
description: Read this when you need Chrome MV3-shaped APIs — bookmarks, tabs, windows, history, downloads, or top sites — in standalone OmOWright.
---
# Chrome MV3 APIs (standalone)
`createChromeApi(connection, options?)` returns MV3-shaped namespaces backed by
CDP and the browser's own profile files — no extension required.
```js
import { createChromeApi } from "omowright";
const chrome = createChromeApi(connection, {
profilePath: "/path/to/user-data-dir", // enables bookmarks/history/topSites/downloads.search
downloadDir: "/path/to/downloads", // optional, defaults to a temp dir
});
```
**PROFILE-BACKED METHODS THROW `UnsupportedOperationError` WITHOUT `profilePath`.**
A `connectPipe` browser gets a fresh profile, so bookmarks and history are empty
there — these APIs matter when attaching to a real user browser via `connect()` or
reading a real profile directory. Profile reads are read-only and WAL-safe against a running
browser.
## tabs — CDP `Target.getTargets`
- `chrome.tabs.query({ url?: string | string[], title?, windowId? })` — `url`
takes MV3 match patterns (`*://*.example.com/*`), `title` is a substring match. **THESE THREE
ARE THE ONLY HONORED FILTERS.**
- `chrome.tabs.get(tabId)` — `tabId` is a string; throws when no tab has it.
- Returns `{ id, url, title, windowId, active, pinned, audible, discarded, groupId, index }`.
**IDS ARE CDP TARGET-ID STRINGS, NOT MV3 NUMBERS**, and the last six fields are
fixed defaults — they are not observable over CDP.
Tab lifecycle stays on `connection.newTab(url)` / `page.close()`; interaction on
`page.goto()` / `page.locator()`.
## windows — CDP `Browser.getWindowForTarget`
`get(windowId, queryOptions?)`, `getCurrent(queryOptions?)`, `getAll(queryOptions?)`.
- `queryOptions: { populate?: boolean }` — `populate: true` adds a `tabs` array.
- Returns `{ id, type, state, alwaysOnTop, incognito, tabs? }`. **THERE IS NO
`focused` FIELD**: CDP exposes no window focus state, and `document.hasFocus()`
is true in every page OmOWright attaches to (it enables focus emulation),
background agent windows included.
- `getLastFocused()` throws `UnsupportedOperationError` for the same reason. With
the extension bridge, follow `chrome.windows.onFocusChanged` instead.
- `getCurrent` returns the first window; it does not tell you where the user is
working.
## bookmarks — profile `Bookmarks` JSON, read-only
`get(idOrIdList)`, `getChildren(id)`, `getRecent(numberOfItems)`,
`getSubTree(id)`, `getTree()`, `search(query)` where `query` is a string or
`{ query?, url?, title? }`.
Nodes: `{ id, title, type: "url" | "folder", url?, dateAdded?, children? }`.
## history — profile `History` SQLite, read-only
- `search({ text, startTime?, endTime?, maxResults? })` — times are Unix ms.
Returns `[{ id, url, title, visitCount, lastVisitTime }]`, newest first.
- `getVisits({ url })` — returns `[{ id, url, visitTime, transition }]`.
## downloads — `History` SQLite + `Browser.setDownloadBehavior`
- `search({ url?, filename?, limit? })` — returns
`[{ id, url, filename, startTime, bytesReceived, totalBytes, state }]`; state is
`complete | canceled | interrupted | in_progress`. Needs `profilePath`.
- `download({ url, filename? })` — downloads through the real browser and resolves
`{ id, url, filename, state: "complete" }` with `filename` as the absolute saved
path. 30s timeout; rejects when the URL starts no download. It uses an in-page
anchor click rather than `Page.navigate`, which hangs on download navigations,
and re-asserts the download behavior on every call because tab initialization
resets it.
## topSites — profile `Top Sites` SQLite
`get()` returns `[{ url, title }]` ordered by rank, max 50.
## Write methods require the extension bridge
These throw `UnsupportedOperationError` because they would mutate the user's own
browser state: `bookmarks.create/update/move/remove/removeTree`,
`history.addUrl/deleteUrl/deleteRange`,
`downloads.pause/resume/cancel/erase`, and all of `chrome.tabGroups`.