ultimate-browsing skill
Renders, drives, and screenshots web pages: JS-rendered sources, clicks and forms, persistent logins, WAF-blocked hosts (platform-native readers, stealth Chrome), and the browsing lane of a research run, with screenshots as provenance. Not for plain search or unblocked static fetch.
Is the ultimate-browsing skill safe?
A critical finding: do not install it without reading the flagged line. We read 57 files in the folder on 2026-09-28.
- critical
engine/tests/fixtures/search_interstitial.html:7Decodes hidden content and executes it: the real instructions are not readable in the file.
'*/var yt=153,T=function(y,x,Y,E,t,Z,W,f,n,p,V){(y&125)==y&&(p=(Y|7)- -1+(~Y^7),n=d5,t=[-82,48,-20,-47,74,-64,t,-71,-52,80],W=Nu[E.l](E.Du),W[E.l]=function(P){f=(p+=6+7*Y,p&=7,P)},W.concat=function... - medium
engine/tests/fixtures/search_interstitial.html:7A long encoded blob (base64 or escaped hex) that cannot be read as it stands.
'*/var yt=153,T=function(y,x,Y,E,t,Z,W,f,n,p,V){(y&125)==y&&(p=(Y|7)- -1+(~Y^7),n=d5,t=[-82,48,-20,-47,74,-64,t,-71,-52,80],W=Nu[E.l](E.Du),W[E.l]=function(P){f=(p+=6+7*Y,p&=7,P)},W.concat=function...
Install the ultimate-browsing skill
A skill is a folder. Copy it into your agent's skills folder and the agent loads it when the task matches its description. Read the findings above first.
git clone --depth 1 https://github.com/code-yeongyu/oh-my-openagent.git /tmp/oh-my-openagent mkdir -p ~/.claude/skills cp -r /tmp/oh-my-openagent/packages/shared-skills/skills/ultimate-browsing ~/.claude/skills/ultimate-browsing
In the Claude apps, zip the folder and upload it from the Skills settings. The folder on GitHub
The instructions your agent would load
SKILL.md as published, without the frontmatter. Read it on GitHub
Ultimate Browsing
Web access for everything a plain fetch cannot finish: a page that renders in JS, a click or a form, a screenshot, a login that must persist across pages, or a host that blocks generic fetchers (WAF / 403 / Cloudflare). Start at the cheapest tier that can do the job and climb only when it cannot:
Tier 1 — insane-search (headless extraction + WAF bypass) -> Tier 1.5 — agent-reach (platform-native APIs, esp. Chinese platforms) -> Tier 2 — a real browser through omowright from js eval: 2a the owned engine (a browser your code launches, CloakBrowser for stealth), 2b the attached engine (the user's own signed-in browser).
PHASE 0 — ROUTE FIRST (MANDATORY)
User request
|
+- extract text/data from a URL --------------------- TIER 1 insane-search
+- URL blocked / 403 / Cloudflare / WAF ------------- TIER 1 insane-search
+- YouTube/Vimeo/TikTok subtitles or metadata ------- TIER 1 insane-search (yt-dlp)
+- read an article / blog / Reddit / HN / arXiv ----- TIER 1 insane-search
|
+- Chinese platform (xhs/douyin/weibo/bilibili/v2ex/wechat) TIER 1.5 agent-reach
+- podcast transcript / stock forum ----------------- TIER 1.5 agent-reach
+- Twitter feed / LinkedIn profile / GitHub via CLI - TIER 1.5 agent-reach
|
+- Tier 1/1.5 returned empty or partial ------------- TIER 2 2a owned engine -> 2b attached engine
+- click / fill form / scroll / interact ------------ TIER 2 2a owned engine -> 2b attached engine
+- screenshot / render / play video ----------------- TIER 2 2a owned engine -> 2b attached engine
+- login session across pages / the user's account --- TIER 2 2b attached engine (their browser)
+- test web app / QA / dogfood ---------------------- TIER 2 2a owned engine -> 2b attached engine
|
+- simple search query ------------------------------ NOT this skill (use web-search)Read the matching reference before acting: references/insane-search/README.md, references/agent-reach/README.md, or references/chrome-stealth.md.
Tier 1 — insane-search (headless extraction)
When: content extraction, blocked-URL bypass, media metadata — no browser UI needed. Why first: ~10x faster than a browser, no process spin-up; handles most "fetch this blocked page" requests via curlcffi TLS impersonation, yt-dlp (1858 sites), official public APIs, mobile URL transforms, Phase-2.5 surrogate archives (Wayback / archive.today snapshots, provenance-tagged — see references/insane-search/cache-archive.md), a key-gated Jina Reader (JINAAPIKEY), and a Playwright real-Chrome fallback. The engine lives inside this skill at engine/ and is invoked as a module. Surrogate results are dated COPIES: a result whose provenance is snapshot must be reported with its snapshottimestamp, never presented as the live page.
# Core command — auto-detects WAF, runs the full fetch grid (run from the skill dir):
python3 -m engine "https://example.com/blocked-page"
# add --selector "<CSS>" for positive-proof validation, --device auto|desktop|mobile,
# --trace to inspect every attempt, --json for machine-readable output.
# YouTube subtitles / metadata (no browser):
yt-dlp --write-sub --write-auto-sub --sub-lang "en,ko" --skip-download -o "/tmp/%(id)s" "<URL>"
# Reddit / HN / Bluesky / arXiv etc. use official public endpoints — see the Phase 0 index in
# references/insane-search/README.md (Twitter syndication, Reddit .json, HN Firebase, ...).The full engine harness (rules R1-R7, the Phase 0 official-API index, the no-site-name rule, and the references/insane-search/*.md deep-dives for TLS, Playwright routing, Naver, media, etc.) is in references/insane-search/README.md. Read it before tuning the engine or adding a WAF profile.
Escalate to Tier 1.5 or Tier 2 when
- The target is a Chinese / social platform with a native reader -> Tier 1.5.
- insane-search returns empty/partial, or the page needs JS interaction, a screenshot, a persistent login, or media playback -> Tier 2.
Tier 1.5 — agent-reach (platform-native readers)
When: the target is a platform with a first-class API/CLI that beats generic fetching — especially Chinese platforms that stealth browsers still cannot reach cleanly. Several channels are zero-config (Douyin, V2EX, Reddit, RSS, YouTube); others need a one-time auth you supply via environment variables if you have access (JINAAPIKEY for Jina Reader — anonymous access is dead, see references/insane-search/jina.md; TWITTER_* for X; a transcription key for podcasts).
mcporter call 'douyin.parse_douyin_video_info(url: "<URL>")' # douyin, zero-config
curl -s "https://r.jina.ai/https://weibo.com/<uid>/<pid>" # weibo via Jina
yt-dlp --dump-json "<bilibili-url>" # Bilibili (overseas: add --cookies-from-browser)
curl -s "https://www.v2ex.com/api/topics/hot.json" # V2EX public APIRouting table, per-platform auth (set TWITTER_* env vars, gh auth login, a transcription key — only if you have access), rate-limit notes, and known version quirks are in references/agent-reach/README.md.
Tier 2 — a real browser (real interaction)
When: real interaction is needed (clicks, forms, screenshots, video, persistent login), or Tier 1/1.5 failed.
Both tiers are omowright, staged inside the browser skill and loaded from js eval:
const { loadOmowright } = await import("<browser-skill-root>/scripts/omowright.mjs")
const { omowright } = await loadOmowright()Tier 2a — owned engine (default)
A browser your code launches with a task-owned profile. connectPipe opens no listening port; connectCloakProfile launches CloakBrowser with a pinned fingerprint seed and is the path for WAF, Cloudflare and bot-scored pages.
const browser = await omowright.connectPipe({ browserPath, browserArgs: ["--headless", `--user-data-dir=${profile}`], storageRoot: profile })
try {
const page = await browser.newTab(url)
const tree = omowright.compactSnapshot(await page.snapshot()) // the read; refs come from it
const snoop = omowright.createNetworkSnoop(page) // read the API JSON instead of the DOM when there is one
await page.locator("e3").click()
await Bun.write(pngPath, await page.screenshot())
} finally {
await browser.close() // then rm -rf the profile
}The rest of the surface (CUA coordinates, captcha solving, routes, traces, frames, human handoff) is in the browser skill's references/owned-engine/. A stealth binary is not proof of access: inspect the rendered result and report challenges that remain.
Tier 2b — attached engine (logged-in pages)
When the page needs the user's account, drive the browser they are already signed into instead of cloning their profile: connectBrowserSkill() → session.navigate → bskSnapshot(session) / session.observe() → session.click → session.stop(). NEVER launch against or clear cookies/cache/site data from the user's live profile, and never fall back to the owned engine for an authenticated criterion: if no extension is connected, run the browser skill's onboarding script and relay its one human step. The full loop is the browser skill.
Cookie login (cross-platform)
scripts/extract_cookies.py reads cookies from a local Chromium-family or Firefox-family browser and optionally injects them into the running CDP session. It resolves browser profile paths and decrypts cookie values per-OS (macOS Keychain, Linux libsecret, Windows DPAPI):
# Extract cookies to a file:
mkdir -p ~/.local/state/omo-cookies
python3 scripts/extract_cookies.py --browser chrome --domain youtube.com --output ~/.local/state/omo-cookies/youtube.cookies.json
# Extract and inject into the running CDP session:
python3 scripts/extract_cookies.py --browser chrome --domain youtube.com --inject --cdp 9242Cookie export files are written with owner-only 0600 permissions. Do not place live auth cookies in shared temp directories or commit them to a repo. Cookie injection sends values to CDP over stdin rather than argv. Cookies apply on next navigation — reload after injecting. Google services use fingerprint-bound tokens that may not transfer across browser profiles. Limits in references/chrome-stealth.md.
Reference docs
Environment variables
# agent-reach auth: set the channel-specific env vars from each tool's docs only if you have access
# insane-search needs no env vars — it auto-installs deps on first runAnti-patterns
- Do NOT launch Chrome stealth for plain text extraction — use Tier 1.
- Use stealth plugins only in an explicitly installed script environment, not injected into WebView.
- Close every WebView/browser context when done and remove only task-owned profile clones.
- Do NOT inject cookies without reloading the page.
- Do NOT hardcode site domains/selectors into engine/ or wafprofiles.yaml — runtime hints only (see the no-site-name rule in the insane-search reference).
More skills from code-yeongyu/oh-my-openagent
- Aast-grepSearches and rewrites code by AST shape across 25 languages. Use when the target is a syntax pattern (every call/class/import shaped like X, a codemod, a YAML rule) rather than literal text; for plain strings, comments, or filenames, use rg.
- AbrowserDrives a real browser through the omowright library from the js eval kernel: sites the user is already signed into, forms and clicks, JS-rendered pages, screenshots, web QA, extension popups, a human handoff for login, CAPTCHA or OTP, and a browser you own for scraping, bot-scored targets, network capture and QA traces. Use for any interactive browser task; not for a plain search or an unblocked static fetch.
- Acodex-qaQA the omo Codex Light edition (lazycodex / packages/omo-codex) itself, in strict isolation so ONLY our plugin is exercised, never the user's real ~/.codex. The first-party method drives the real `codex app-server` against an isolated CODEX_HOME plus a LOCAL mock model (no real API call), and proves a plugin hook fired by asserting hook/started + hook/completed notifications. Also: isolated install verification, per-component hook probes, a tmux TUI smoke, and runtime log observation (RUST_LOG / logs SQLite / /debug-config). Ships tested helper scripts each with a --self-test. Use whenever someone changes anything under packages/omo-codex or wants to QA, smoke-test, verify, or debug the Codex plugin, its hooks/components, the installer/config.toml, the app-server flow, or the Codex TUI. Triggers: codex qa, qa codex, codex-qa, test codex plugin, verify codex hook, codex app-server, lazycodex qa, isolated CODEX_HOME, prove codex hook fired, codex tui test.
- Acoding-agent-sessionsFinds, reads, and reconstructs coding-agent sessions across Codex, Claude, OpenCode, OMO/Senpi, and other local agent logs. Use when asked to find or search past sessions, transcripts, or subagent runs, or to recover what an earlier session did.
- Acomment-checkerUse when Codex needs to understand or respond to automatic comment-checker feedback emitted after an edit-like PostToolUse hook.
- Adag-libraryStores a DAG definition once and re-runs it by name, instead of pasting the definition into every run. Use when the user wants to save a DAG, run a saved one, or schedule the same multi-agent graph repeatedly.
- Ddata-scientistProcesses and analyzes data with resident-kernel engines (DuckDB, Polars) and one-shot tools. Use for CSV/parquet/JSON analysis, group-by/join/aggregation, time series, distributions, cleaning, or plotting a dataset.
- AdebuggingRuns a hypothesis-driven debugging loop across any language or binary, escalating to orthogonal oracle angles and locking the fix with a failing test. Use for crashes, silent failures, hangs, wrong responses, memory leaks, async misbehavior, or reverse engineering.
- Adev-browserBrowser automation with persistent page state. Use when users ask to navigate websites, fill forms, take screenshots, extract web data, test web apps, or automate browser workflows. Trigger phrases include "go to [url]", "click on", "fill out the form", "take a screenshot", "scrape", "automate", "test the website", "log into", or any browser interaction request.
- CfrontendBuilds, styles, and polishes web UI and UX. Use for any frontend, page, component, styling, layout, animation, or visual-quality task, or when asked to make an interface look or feel a certain way.
- AfrontendBuilds, styles, and polishes web UI and UX. Use for any frontend, page, component, styling, layout, animation, or visual-quality task, or when asked to make an interface look or feel a certain way.
- Aget-unpublished-changesCompare HEAD with the latest published npm versions and list all unpublished changes by release layer. Triggers: unpublished changes, changelog, what changed, whats new.