Skip to content
cccskills
FreePublished on GitHub

captcha

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.

The English summary is being prepared. Showing the original description.

See how to install

Files included (1)

  • SKILL.md6.0 KB

SKILL.md (original)

Review the instructions the agent will receive before you install.

Captcha

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);

Checkbox widgets

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.

Completion is separate from input

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.

Slider and puzzle drags

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.

Text and number captchas

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.

Image-grid challenges and diagnosis

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.

Reviews

No reviews yet. Tell others what you thought.

Comments

No login needed. Share how it worked for you, ask a question, or note where it did not run.

No comments yet. Be the first to write one.

Comments are published right away. Do not include personal information such as email addresses or phone numbers. Up to 2 URLs.

0 / 1,000 characters

This form is protected by reCAPTCHA, and the Google Privacy Policy and Terms of Service apply.

More skills from this repository

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.

The English summary is being prepared. Showing the original description.

code-yeongyu/omowright5Updated Oct 20, 2026

chrome

Free

Read this when you need Chrome MV3-shaped APIs — bookmarks, tabs, windows, history, downloads, or top sites — in standalone OmOWright.

The English summary is being prepared. Showing the original description.

code-yeongyu/omowright5Updated Oct 20, 2026

Use when a user-driven CloakBrowser profile needs MV3 Chrome writes/events through the native messaging bridge.

The English summary is being prepared. Showing the original description.

code-yeongyu/omowright5Updated Oct 20, 2026

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 English summary is being prepared. Showing the original description.

code-yeongyu/omowright5Updated Oct 20, 2026

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.

The English summary is being prepared. Showing the original description.

code-yeongyu/omowright5Updated Oct 20, 2026

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.

The English summary is being prepared. Showing the original description.

code-yeongyu/omowright5Updated Oct 20, 2026

See all skills by code-yeongyu

Report a problem with this skill