Push browser tab and download lifecycle events plus manager-owned background tabs. Read this when an agent needs lifecycle notifications or a temporary tab without polling.
日本語の概要は準備中です。原文の説明を表示しています。
Interact with challenge widgets in an authorized automation flow using checkbox clicks, slider drags, text OCR, and image-grid input. Verify completion with an application-specific condition.
インストールする前に、エージェントに与えられる指示の中身を確認できます。
createCaptcha(page, { ocr? }) provides input and OCR helpers, not a general
CAPTCHA solver. click and drag return a compact snapshot tree string after
settling. readText returns text or null. A snapshot, token, or disappearing
widget alone does not prove that the application accepted the challenge.
This is rung 4 of the ladder in presets/visual-browse/SKILL.md. Pin the viewport
before measuring coordinates (Emulation.setDeviceMetricsOverride and
refreshViewportSize), and measure again after scrolling, resizing, or reflow.
import { createCaptcha } from "omowright";
const captcha = createCaptcha(page);
click(bounds) clicks the center, not the left-center. Measure the actual
checkbox bounds, or provide an explicit point within a measured widget rectangle.
All bounds and points use absolute top-level viewport CSS pixels. Coordinates
can target a visible control inside a frame without switching frames, but a
cross-origin iframe's outer bounds do not locate its checkbox. Account for frame
geometry; an opaque or missing frame in a snapshot is not evidence of no challenge.
For an application-owned widget with a DOM-accessible checkbox:
const bounds = await page.evaluate(`(() => {
const el = document.querySelector("#captcha-checkbox");
if (!el) throw new Error("Checkbox not found");
const r = el.getBoundingClientRect();
return { x: r.x, y: r.y, width: r.width, height: r.height };
})()`);
await captcha.click(bounds, {
point: { x: bounds.x + bounds.width / 2, y: bounds.y + bounds.height / 2 },
approachSteps: 12,
settleMs: 0,
});
const result = await captcha.waitFor({
// Replace with your application's authoritative acceptance condition.
until: page => page.evaluate(
`document.querySelector("#application-status")?.dataset.accepted === "true"`
),
timeoutMs: 10000,
pollMs: 100,
});
if (result.outcome !== "matched") {
throw new Error(`Acceptance not confirmed: ${result.outcome}`);
}
// Capture visual evidence separately; waitFor never returns a tree or image.
const image = await page.screenshot({ type: "png" });
point is optional; omit it to retain center targeting. approachSteps is an
optional positive integer for intermediate pointer movement before clicking.
Omitting it retains the direct click. Interpolation is not a human-likeness or
acceptance guarantee. Bounds must have finite coordinates and positive finite
dimensions; the point must be inside [x, x + width) and [y, y + height).
Invalid geometry is rejected before input, not clamped or coerced.
captcha.waitFor({ until, timeoutMs = 10000, pollMs = 100, signal } = {})
returns exactly { outcome: "matched" | "timed_out" | "cancelled", elapsedMs }.
It never clicks, takes a snapshot, or infers server acceptance. You can check an
already-accepted application without sending input.
until is required and called as until(page, { signal: operationSignal });
one-argument predicates also work. Only literal true matches, not a truthy
string or object. The first check runs immediately; subsequent checks are serial,
after pollMs, bounded by one monotonic deadline. Predicate errors before
termination propagate unchanged. timeoutMs must be finite in [0, 2147483647];
pollMs must be finite in (0, 2147483647]. A supplied signal must be
AbortSignal-compatible. Invalid arguments throw TypeError or RangeError without
running the predicate; values are not coerced.
At completion boundaries, cancellation takes priority over the deadline, and
the deadline over a match. A pre-aborted signal runs no predicate and returns
cancelled; a zero timeout runs no predicate and returns timed_out unless
already aborted. Async predicates and delays are bounded by abort/deadline,
without overlapping checks. The owned operation signal is aborted on every
terminal exit; owned timers and external abort listeners are cleaned up.
A non-cooperative predicate can remain pending after return; late rejection does
not change the result or become an unhandled rejection. Cancellation cannot
retract dispatched input or requests, or interrupt blocking synchronous code.
const tree = await captcha.drag({ x: 150, y: 300 }, { x: 450, y: 300 }, { steps: 40 });
Endpoints must be finite viewport points. steps is a positive integer (default
20); it controls intermediate movement, not whether the application accepts the
result. Mouse release is attempted even if movement fails.
const text = await captcha.readText({ x: 100, y: 200, width: 200, height: 60 });
if (text !== null) await page.locator("input[name=captcha]").fill(text);
The built-in macOSVisionOcr uses macOS Vision via Swift. Elsewhere, inject an
OCR function: createCaptcha(page, { ocr: async (pngBuffer) => "recognized text" }).
readText(bounds?) screenshots a cropped region, or the whole viewport when
bounds are absent, and returns OCR text or null, never a snapshot tree.
Recognizing text is not proof of submission or acceptance.
page.annotatedScreenshot() overlays numbered boxes on interactive elements.
Use the image to identify targets and createCua(page) for coordinate input;
verify the application's result separately after submission.
click and drag accept finite supported timer milliseconds as settleMs
(default 3000, including 0 to disable the settling delay). They still take a
snapshot with settleMs: 0; that delay is not a completion check or an overall
timeout. If targeting fails, re-measure geometry. If input lands but acceptance
does not follow, inspect the application state rather than assuming extra steps,
a longer delay, or a different engine will solve it. See
CAPTCHA quality and comparison for the limits.
まだレビューはありません。使ってみた感想をお寄せください。
概要と使いどころ
Push browser tab and download lifecycle events plus manager-owned background tabs. Read this when an agent needs lifecycle notifications or a temporary tab without polling.
日本語の概要は準備中です。原文の説明を表示しています。
Read this when you need Chrome MV3-shaped APIs — bookmarks, tabs, windows, history, downloads, or top sites — in standalone OmOWright.
日本語の概要は準備中です。原文の説明を表示しています。
Use when a user-driven CloakBrowser profile needs MV3 Chrome writes/events through the native messaging bridge.
日本語の概要は準備中です。原文の説明を表示しています。
Read the network instead of the DOM. Snoop JSON API responses, wait for a request instead of sleeping, collect items while scrolling, record a QA flight trace (jsonl, HAR, screenshots), and intercept requests with routes.
日本語の概要は準備中です。原文の説明を表示しています。
The default code-driven browser path for interactive browsing work: drives any browser from code with token-efficient a11y snapshots (57% smaller via compactSnapshot), ref-based clicks, coordinate control (CUA), viewport pinning, CAPTCHA solving (reCAPTCHA, Turnstile, hCaptcha, slider, OCR), Chrome MV3 APIs (tabs/bookmarks/history/downloads/topSites), network snoop (read API JSON instead of DOM), flight-recorder trace (jsonl + HAR + screenshots), OOPIF-aware snapshots, dialog policy, human handoff for login/OTP, device emulation, request routes, stealth via CloakBrowser as the default owned engine with zero exposed CDP ports, and an attached engine that drives the user's own signed-in browser through BrowserSkill (connectBrowserSkill, bskSnapshot, one-click onboarding via bskOnboard). MUST USE for interactive browser work: scraping, blocked/WAF/JS-rendered pages, logins, the user's logged-in sites and open tabs, extension popups, form filling, screenshots, web QA, CAPTCHAs. The ulw-research browsing lane runs on ultimate-browsing, not this skill.
日本語の概要は準備中です。原文の説明を表示しています。
Coordinate-level browser control for UI that snapshots, refs, and locators cannot target - canvas apps, extension popups, OS-drawn dialogs, custom drag surfaces. Read this when a DOM-targeted action fails twice, when the next decision depends on rendered pixels, or when CUA clicks land on the wrong element.
日本語の概要は準備中です。原文の説明を表示しています。