what-antibot

3周前发布 8 0 0 0

browserbase/skills#what-antibot

Skill 安装

多 Agent 安装
npx skills add https://github.com/browserbase/skills --skill what-antibot

使用 npx skills 快速安装,支持将 Skill 添加到多个兼容的 AI Agent。

Skill 调研报告

browserbase/skills#what-antibot

Skill 更新日志

版本列表
无版本号
[codex] Add source-integrated WebMCP skill (#155) * [codex] Add source-integrated WebMCP skill * fix: address review comments (autofix loop #1) Addresses feedback from Cursor Bugbot and Socket Security * feat: add adversarial verification step and default local runs to headed Step 5 proves a tool is discoverable and that its executor ran, not that it did what it claimed. Add step 6: probe schema closure, required fields, types and constraints, error honesty, annotation honesty, clean rejection, and consequential gating against the live page, then verify the effect in the application rather than trusting the return value. Also: - Default --local validation to headed so the browser is visible; add --headless for CI and unattended runs. - Record that document.modelContext is the live accessor while navigator.modelContext is undefined, so the fallback is load-bearing. - Record that registerTool is idempotent by name with no unregister handle, which is what makes remount and hot reload safe. - Require handlers to read results back from application state instead of echoing the request, including polling asynchronous stores until they settle. * fix: run the scanner when invoked through a symlinked skill path The self-invocation guard compared path.resolve(process.argv[1]) against fileURLToPath(import.meta.url). path.resolve normalizes . and .. but does not resolve symlinks, so when the skill is installed as a link the two paths never match, main() never runs, and the scanner prints nothing and exits 0. That is the default install shape for a Claude Code user, whose skill directory is a symlink to the real one, and step 1 points them at exactly that path. Resolve symlinks on both sides before comparing. Also tell the skill to report what each step found as it goes, rather than saving everything for the final report. * docs: validate against localhost rather than 127.0.0.1 Dev servers commonly bind localhost only, so validating against http://127.0.0.1:PORT discovers zero tools while http://localhost:PORT works. The examples recommended the address that fails, and the symptom is indistinguishable from tools never registering. Point the examples at localhost and say what zero discovered tools usually means.
无版本号
[codex] Add Optimize Agent Prompt skill (#146) * Add Agent API Autobrowse skill * Rename skill to optimize agent prompt * Fix optimize prompt run artifact handling
无版本号
Add `browse upload` to browser skill docs (#62) Document the new `browse upload ` command for uploading files to elements. Works with CSS selectors, XPath, and ref-based selectors from snapshot. Supports single and multiple files, local and remote Browserbase sessions. Co-authored-by: Claude Opus 4.6 (1M context)
无版本号
Add `browse get markdown` to browser skill docs (#61) Document the new `browse get markdown [selector]` command that converts page HTML to clean markdown. Defaults to body content, supports optional selector for specific elements. Co-authored-by: Claude Opus 4.6 (1M context)
无版本号
Resolve CDP tailing docs conflicts (#60)
无版本号
chore: remove deprecated browserbase-cli skill (#142) The browserbase-cli skill describes the deprecated `bb` CLI (@browserbasehq/cli), which has 0 tracked installs. The canonical Browserbase CLI is now `browse`. Remove it from the marketplace catalog so it no longer ships in the plugin marketplace. - Delete skills/browserbase-cli/ (SKILL.md, REFERENCE.md, LICENSE.txt) - Remove the browserbase-cli plugin entry from .claude-plugin/marketplace.json - Remove the browserbase-cli row from the README skills table Note: the stale `@browserbasehq/browse-cli` install string called out in the task is already absent on main (fixed in #111); skills/browser/SKILL.md already uses `npm install -g browse`. No install-command change was needed. Co-authored-by: Claude Opus 4.8 (1M context)
无版本号
harden(autobrowse): restrict trace artifacts to owner-only permissions (#139) Autobrowse trace artifacts (trace.json, messages.json, summary.md, and screenshots) can contain cookies, auth headers, bearer tokens, passwords from form POSTs, private URLs, and screenshots of authenticated pages. Previously these were written with fs.writeFileSync / fs.mkdirSync using default permissions, which inherit the process umask (typically 0644 files / 0755 dirs). On a shared host -- CI runners, shared dev boxes, or multi-tenant containers -- that leaves the trace tree readable by other local users and processes. This restricts trace artifacts to the owner: - run dir + screenshots/ created with mode 0700; the run dir is also chmod'd explicitly since mkdirSync's mode only applies to dirs it creates (a pre-existing parent could otherwise stay traversable). - trace.json / messages.json / summary.md written with mode 0600. - lockDownTrace() sweeps the run dir at the end to cover files written by subprocesses (screenshots from the browse CLI, .o11y artifacts) whose creation mode we don't control. Symlinks (the `latest` link) are skipped. 0700/0600 are unaffected by the process umask, so the result is consistent regardless of host configuration. The owner -- the same user the self-improvement loop runs as -- retains full read/write, so the loop is unaffected; only cross-user access is removed. Co-authored-by: Claude Opus 4.8 (1M context)
无版本号
Add browser-use-to-stagehand skill: migrate browser-use to Stagehand on Browserbase (#130) * Add bu-to-bb skill: migrate browser-use to Stagehand on Browserbase Converts browser-use (Python) automation to Stagehand v3 (TypeScript) on Browserbase, choosing the right level of determinism per step rather than a one-to-one agentic copy. - SKILL.md: detect the browser-use variant, decompose the task across the determinism spectrum, emit Stagehand v3 + a migration summary - references/: full API mapping, determinism decision framework, and an optional trace-assisted path (pairs with the browser-trace skill) - GUIDE.md: human migration guide (philosophy, feature mapping, determinism) - PROMPT.md: tool-agnostic docs prompt (works in any AI assistant) - EXAMPLES.md: before/after pairs - README.md (skill): index; root README.md: add to the skills table Targets Stagehand v3 (verified against live docs); validated by running the skill on fresh scripts a clean agent had never seen. Co-Authored-By: Claude Opus 4.8 * Remove Playwright references; full browser-use → Stagehand conversion Express determinism purely through Stagehand primitives — cached observe()→act() plus selfHeal/cacheDir/serverCache — instead of falling back to Playwright selectors. Drops all "Playwright" references and page.locator()/page.fill() calls across SKILL.md, GUIDE.md, PROMPT.md, README.md, and the determinism / trace-assisted references. page.goto/page.url stay (Stagehand's own page methods). Co-Authored-By: Claude Opus 4.8 * Address review (PR #130): add LICENSE.txt, fold docs into references/ Per @shrey150's standards pass: - add LICENSE.txt (MIT, verbatim from skills/browser) - move GUIDE.md -> references/guide.md and PROMPT.md -> references/prompt.md, both linked from SKILL.md so the content isn't stranded - drop the skill-local README.md - fix relative links in references/guide.md and EXAMPLES.md Skill dir now follows the convention: SKILL.md + EXAMPLES.md + references/ + LICENSE.txt. Co-Authored-By: Claude Opus 4.8 * Fix runtime API bugs + add doc-resilience (validated via live eval) Validated by converting 9 real browser-use examples through the skill and running the generated Stagehand on live Browserbase. Fixes 3 runtime failures that typecheck clean but broke at runtime: - Page settling: networkidle -> domcontentloaded. networkidle never fires on Google/analytics/SPA pages and throws a 15s timeout (broke 2 of 9 cases). - Agent output schema: agent().execute({ output }) throws ExperimentalNotConfiguredError unless experimental:true, and output must be a zod object (not a top-level array). Document both, and recommend the agent-then-extract pattern to stay on the managed API path (broke 1 case). - setViewportSize takes positional (width, height), not Playwright's { width, height } object (would not compile). - Variant table: ChatBrowserUse is browser-use's hosted-model class and appears in stable 0.13.x code -- it is NOT a Rust-beta tell. Only a literal browser_use.beta import is. Prevents variant mis-detection. - Add an "iterate an extracted list / resolve relative URLs" pattern (new URL(href, page.url())) to avoid "Cannot navigate to invalid URL". Doc-resilience (keep the API tables, demote them): add a version-provenance header, state that the live docs supersede this snapshot on any conflict, and make "verify signatures against the installed package" an explicit workflow step -- so the skill fails safe as Stagehand / browser-use drift. Validated against @browserbasehq/stagehand 3.6.0 / browser-use 0.13.1. Eval: 9/9 compile; live Browserbase 3 PASS/3 PARTIAL/3 FAIL -> 6 PASS/2 PARTIAL/0 FAIL. Co-Authored-By: Claude Opus 4.8 (1M context) * Rename skill bu-to-bb -> browser-use-to-stagehand Cryptic abbreviation -> descriptive, discoverable name: - "bu-to-bb" was opaque, and "bb" collided with the (now-deprecated) bb CLI. - "bu" is also a loaded token in browser-use land -- it's the prefix for their hosted models (bu-2-0, bu-30b), not the library -- so "bu-to-*" misreads. - The name is loaded into the system prompt as discovery metadata, so a name carrying "browser-use" + "stagehand" aids triggering, not just human scanning. - Matches the repo's descriptive naming convention (competitor-analysis, browser-trace, cookie-sync). Renames the directory, frontmatter name, SKILL.md heading, README row, and all internal /bu-to-bb references. Validator passes (node scripts/validate-skills.mjs). Co-Authored-By: Claude Opus 4.8 (1M context) * Add agent-tools + MCP mappings; real-world coverage (validated via tier-2 eval) Patches the holes a tier-2 eval found by converting real-world browser-use code (custom agent-tools, MCP client/server, and BU embedded in real app code: LangManus, BLAST) through the skill and type-checking against installed 3.6.0. Correctness: - Agent custom `tools` require `experimental: true` (same gate as agent `output` and MCP `integrations`) -- the prior tools example omitted it and would throw ExperimentalNotConfiguredError at runtime. Consolidated callout added. - `ai` must be pinned to v5: Stagehand 3.6.x types `tools` as the v5 ToolSet (schema field `inputSchema`); the v4 `tool()` helper emits `parameters` and fails to type-check. Template now pins `^5.0.0` and documents the plain-object `{ description, inputSchema, execute }` alternative. New mappings: - §3.7 MCP: browser-use MCPClient (stdio + remote) -> Stagehand `agent({ integrations })` via `connectToMCPServer(...)` / URL string, with the experimental requirement and the tool_filter/prefix + server-direction gaps. - §3.8 Real-world patterns: embedded/wrapped code (convert the browser-use surface, keep app glue), sync-over-async -> async, long-lived stateful executors -> stateless `messages`, vision intent -> `mode: hybrid/cua`, legacy `result.final_result` attribute form. - Custom-action gaps: injected special params (browser_session etc.) -> closures, `domains=` -> in-tool host check, `terminates_sequence` -> no equivalent. SKILL.md: added a "when NOT to migrate" scope gate (MCP-server / non-Agent / embedded) so the workflow doesn't assume every input is a convertible script. Tier-2: 5/5 handled correctly (4 convert+compile clean; MCP-server correctly flagged out-of-scope without fabricating). Validated against stagehand 3.6.0 / browser-use 0.13.1. Co-Authored-By: Claude Opus 4.8 (1M context) * Note Stagehand 3.6.0 stdio-MCP runtime bug in §3.7 Live e2e smoke of the converted MCP-client script surfaced a Stagehand bug: passing a Client instance (local/stdio server via connectToMCPServer) into agent({ integrations }) throws "Converting circular structure to JSON" before the agent runs -- agent() does JSON.stringify(options.integrations) (v3.ts:1992) and the Client object is circular. Reproduced with two different MCP servers (filesystem, everything). URL-string integrations are unaffected. The skill's mapping is correct (it connects to the server); this is a framework bug, so §3.7 now flags it and recommends remote/URL MCP until fixed upstream. Co-Authored-By: Claude Opus 4.8 (1M context) * Address Bugbot: experimental flag in prompt/determinism, complete login example - prompt.md + determinism.md recommended agent().execute({ output }) (and prompt.md the agent `tools` path) without the experimental:true requirement that api-mapping already documents -> would throw ExperimentalNotConfiguredError. Added the experimental gate (output/tools/integrations) + prefer agent-then-extract, and pinned ai@^5 for the tools row. - EXAMPLES.md login: the browser-use task is "log in then open the dashboard" but the Stagehand after-script stopped at the allow-list check. Added the dashboard step so the migration completes the same task. Co-Authored-By: Claude Opus 4.8 (1M context) * Address Bugbot: align prompt.md determinism levels with canonical scale prompt.md numbered the spectrum 1=Navigation..5=Autonomous, inverted vs determinism.md/guide.md/workflow (1=Autonomous..5=Navigation), so "Level N" citations could contradict across docs. Flipped prompt.md's table + the "decomposition (levels 2-5)" rule + the example's page.goto (L5) cite to match the canonical scale. Co-Authored-By: Claude Opus 4.8 (1M context) * Address Bugbot: §3.5 saveUrl tool reads URL from page, not the model The agent-tool example took `url` from the model via inputSchema, but the original browser-use action reads the current URL from browser_session. That let the model pass a guessed URL and contradicted the section's own "close over page/stagehand in execute" guidance. The tool now takes no model args and reads page.url() directly. Co-Authored-By: Claude Opus 4.8 (1M context) * Address Bugbot: enforce allow-list after every navigation in login example The host check ran once after sign-in, but the added dashboard step navigated past it — and browser-use's allowed_domains enforces across the whole run. Extracted the check into assertAllowedHost() and call it after each navigation, with a comment that even this is best-effort (real continuous enforcement = Browserbase proxy domain rules, api-mapping §5). Co-Authored-By: Claude Opus 4.8 (1M context) --------- Co-authored-by: Chris Browder Co-authored-by: Claude Opus 4.8 Co-authored-by: Shrey Pandya
无版本号
Competitor analysis skill (#76) * feat: add competitor-analysis skill * fix(competitor-analysis): harden merge_partials against subagent format drift * feat(competitor-analysis): add mandatory Step 4.5 — confirm enrichment set with user The gate has known blind spots that silently drop real competitors: - JS-heavy homepages (Tavily, Firecrawl) — bb fetch returns near-empty hero text, keyword matcher has nothing to match on - Cloudflare challenge pages (Perplexity) — title becomes "Just a moment...", no category signal - Semantic variants — "search foundation" (Jina AI), "retrieval backbone", etc. don't lexically match a list centered on "search API" - Apex-vs-product domain confusion — brave.com (browser) vs api-dashboard.search.brave.com (actual API) Auto-promoting the PASS list to enrichment is the wrong default because enrichment is expensive (5 competitors × 5 lane-subagents = 25 subagents, ~10-15 min wall time, ~300 bb calls). Running that on a partly wrong set wastes all of it. Insert a mandatory Step 4.5 between Gate and Deep Enrichment: 1. Main agent groups /tmp/competitor_gated.jsonl into three buckets — PASS, UNKNOWN (fetch failed — surfaced separately, these are the silent misses), and rejected-brand-matches (top ~10 REJECTs whose title contains a seed token or shows up in Wave C "X vs Y" graph). 2. AskUserQuestion with a checkbox list + free-text "add more" field. 3. Write the confirmed set to /tmp/competitor_enrichment_set.txt — this is the input for Step 5, not /tmp/competitor_passed.txt. Surfaced while testing the skill on Exa (exa.ai): the gate passed 22/101 candidates but silently rejected Tavily, Jina AI, Firecrawl, and Perplexity — all real direct competitors. Step 4.5 catches them. SKILL.md pipeline overview is now 8 steps (was 7). Step 5 input path is updated. workflow.md gets a User-confirm phase section with the three buckets and the list of known gate blind spots. * fix(competitor-analysis): normalize mention-bullet format during merge Lane subagents don't consistently emit the canonical Mentions bullet format specified in workflow.md — they drift into variants per lane: - Discussion lane: `- **HN** — [Title](url) — snippet` - News lane: `- **2025-08-06** — [News] Outlet — "title" — url` - Technical lane: `- **[Benchmark]** ...` (canonical) compile_report.mjs' parseMentions only matches the canonical `- **[SourceType]** Title | Snippet (source: URL, YYYY-MM-DD)` shape, so non-canonical variants silently dropped from the mentions feed. On the Exa end-to-end test, merge reported 404 total mentions across 5 competitors but the rendered feed showed 0. Rather than fight prompt drift across 25 subagents, normalize at merge time. New normalizeMentionBullet() rewrites the three observed variants into canonical form before dedup, so downstream (CSV, per-competitor pages, mentions.html feed) stays clean. After fix on the Exa run: 294 mentions render, 81% with dates, distribution: 42 LinkedIn / 34 HN / 25 Blog / 24 YouTube / 20 Reddit / 12 Comparison / 11 DevTo / 8 News / 4 Substack. * refactor(competitor-analysis): drop pricing screenshot — hero only Pricing-page screenshots were adding ~300KB per competitor (Browsaur's was 580KB) and doubling the per-run browse-CLI cost, but the per-tier text already lives in the frontmatter (pricing_tiers, pricing_model) and renders in the Pricing section of the per-competitor page. The visual didn't add signal over the structured data — it was redundant. Homepage hero stays. That one is worth keeping: the tagline, visual brand identity, and positioning screenshot-vs-text diff surface things the fields can't (logo treatment, animation cues, hero copy voice). Changes: - capture_screenshots.mjs: drop pricingCandidates() + pricing capture loop, simplify result shape to {slug, hero, errors}, halve per-competitor wall time (~10-20s vs ~15-20s, no pricing fallback chain). - compile_report.mjs: remove 2-column .shots grid + .shot-pricing CSS, render single .shot-hero card per page. - SKILL.md Step 6 + references/workflow.md: doc sync. Also clarify that `browse` is a separate package from `bb` (@browserbasehq/browse-cli vs @browserbasehq/cli) — came up as a user question during test runs. Existing runs re-rendered without pricing shots; ~1.5MB of PNGs removed from the two test output dirs on Desktop. * feat(competitor-analysis): render matrix from curated matrix.json taxonomy The old matrix view was broken on real runs. Subagents write key_features and integrations as prose (comma-separated or full sentences), not as pipe-separated atomic labels the matrix expected. Pipe-splitting gave one unique blob per competitor, so the matrix trivially rendered a diagonal — zero actual comparison across competitors. Fix is to synthesize a shared taxonomy after enrichment and render the matrix from that. New flow: - After merge, the main agent reads all per-competitor .md files, distills a canonical list of 12-20 atomic features and 10-20 integrations that apply across the category, and writes {OUTPUT_DIR}/matrix.json with a per-competitor yes/no mapping. - compile_report.mjs auto-detects matrix.json and renders the Features + Integrations axes from it. Falls back to the old pipe-split behavior when matrix.json is missing. Verified on the Exa test: before fix, Features axis was 5 one-off blobs with a diagonal of ●s. After: 19 atomic feature rows × 5 competitors with 36 ● cells showing real overlap (Web Search API, MCP server, Free tier, Structured JSON are universal; only Jina has Reranker+Embeddings; only Tavily has Site crawler; SerpAPI alone has CAPTCHA solving and hourly throughput SLA; etc.). SKILL.md Step 5 gets a new "Synthesize the comparison matrix" substep with the matrix.json schema and the rule "do not skip — without this the matrix view is trivially diagonal". * fix(competitor-analysis): realign matrix column headers Rotated competitor-name headers were misaligned with their data columns and the rightmost labels (Tavily, You.com in the Exa test) got cut off. Root cause: `transform-origin: left top` combined with a fixed `width: 160px` on the label made each label's horizontal extent run ~131px to the right of the column, so labels visually floated several columns to the right of their target and the last N labels overflowed off-screen. Fix: anchor the rotated label to the BOTTOM-RIGHT of its column cell (position:absolute right:4px bottom:8px, transform-origin:right bottom) and steepen rotation from -35° to -55° so horizontal extent is reduced. Drop the fixed width — label is now only as wide as its text, which shrinks short names (Jina AI, Serper) and tightens layout. Cell width 44→52px and header height 130→150px give rotated labels room to live inside the cell rather than overflowing. Result on the Exa run: all 5 competitor names visible, each label's bottom-right sits at the top-right of its column, leaning up-left toward the column — the shingled "hanging label" pattern. * fix(competitor-analysis): horizontal matrix column headers Rotated/diagonal competitor names (35° then 55°) kept producing awkward alignment: the rotation anchor vs the column's visual center never quite matched, and long names (You.com, LlamaIndex) overflowed off the right. Simpler fix: just make the headers horizontal. With 5 competitors × 110px each = 550px, plus the 240px feature column, the table is 790px wide — fits inside the 1200px container without scrolling. For >10 competitors the .mx-scroll wrapper already provides horizontal scroll. Drops the .mx-comp-h-inner rotation wrapper, bumps cell width from 52→110px and data font from 0.9→0.95rem for readability. Feature column grows 220→240px to fit longer taxonomy labels like "Hourly throughput SLA". * feat(competitor-analysis): add "Where you're winning / losing" on overview The overview page showed a list of competitors but no explicit view of the user's own strategic position. Hard to answer at a glance: what do I uniquely have, what are the table-stakes features I'm missing? Extend matrix.json with a `userCompany` entry (same shape as each competitor — features + integrations yes/no flags), and compute two buckets on the overview page: - Winning: features the user has where 0–1 competitors also have them. Ordered by rarity (unique features first). - Losing: features the user lacks where 3+ competitors have them. Ordered by gap size (most common features first). Each item shows who else has it ("only you" / "Tavily, SerpAPI" / "4 competitors"), so users can assess the strategic weight at a glance. Rendered as two cards (green-bordered "win", brand-red-bordered "loss") between the summary stats and the results table on index.html. Cards gracefully degrade to nothing if matrix.json lacks userCompany — a skill run that skipped Step 5b's matrix synthesis gets an overview without the strategic summary rather than an error. On the Exa test: 4 wins (Site crawler · Embeddings · 3+ SDK languages · CrewAI integration) and 3 losses (Image/visual search · Dedicated news endpoint · Hourly throughput SLA). Clear strategic picture in one screen. SKILL.md Step 5b "Synthesize the comparison matrix" now documents userCompany as a required field with the explicit note that without it the strategic summary doesn't render. * docs(competitor-analysis): require userCompany in matrix.json schema Missed in the strategic-summary commit (652a9a4) — the SKILL.md block that defines the matrix.json schema was on an older revision of the file that didn't get re-staged. Re-add the userCompany field and flag it as required, with the explicit note that skipping it means the "Where you're winning / losing" cards don't render. * feat(competitor-analysis): mandate fact-check subagent for matrix.json Step 5b (matrix synthesis) produces LLM inference from heterogeneous subagent prose. On the Browserbase run 2026-04-23 that inference confidently marked SOC 2 as a Browserbase moat — except Hyperbrowser, Kernel, AND Anchor Browser all have SOC 2 Type II (verified via their own trust portals and compliance blog posts). Shipping that to a GTM team would have made the whole report un-trustable. Add Step 5c: a mandatory fact-check subagent that runs after the taxonomy synthesis and before compile. For every true/false cell in matrix.json, it: - If true: finds a concrete source URL (docs, trust portal, changelog, GitHub license) or flips to false. - If false: runs one targeted bb search to guard against misses. - Outputs a verified matrix.json with a per-cell `sources` field plus a matrix_fact_check.md delta log of every flip. The "Where you're winning / losing" cards are strategic claims. Without verification they hallucinate moats. The SKILL now labels this step MANDATORY with the Browserbase-SOC 2 example as proof of what skipping it costs. * feat(competitor-analysis): prose summaries for win/loss cards Bulleted lists of winning/losing features read like a spreadsheet, not the analyst-briefing the overview page is supposed to be. Extend matrix.json's userCompany with optional winningSummary / losingSummary prose fields (2-4 sentences each) and render them as paragraphs when present. Falls back to the existing bulleted list when absent so a partial run still shows the boolean comparison. SKILL.md flags these as strongly preferred and tells the main agent to write them AFTER the fact-check step so the prose is grounded in verified cells — otherwise the paragraph will state fluent but false moats. Updated the Exa example in the schema block to include the two summary fields. On the Browserbase run: two paragraphs replace the previous 12 bullets. Winning reads as enterprise moats (SLA, Stagehand, EU/APAC, Selenium, OpenAI Agents + n8n integrations). Losing reads as transparency + openness gaps — concrete competitor names cited (Anchor's Halluminate win, Steel's leaderboard, Browsaur MIT + Kernel + Steel AGPL). * fix(competitor-analysis): mandate user-company research parity with competitors Step 1 was doing light self-research on the user's company while Step 5 did deep 5-lane enrichment on every competitor. That asymmetry meant the userCompany row in matrix.json was filled from the main agent's memory rather than from verified partials, and the strategic summary printed fabricated moats about the user's OWN product. Concrete examples from the Browserbase run 2026-04-23, caught only when the user pushed back: - Claimed a "published uptime SLA" — no numeric SLA exists on browserbase.com, only a status page. - Marked open-source as false — Stagehand is MIT-licensed at github.com/browserbase/stagehand, plus Browserbase ships 10+ other OSS repos (sdk-node, sdk-python, create-browser-app, Arena, open-operator, mcp-server-browserbase, etc). The correct framing is "OSS at the SDK layer, cloud-only at the infra layer" — a split the skill wasn't capturing. Systemic fix: - Step 1 now mandates the same 5-lane partial enrichment on the user's company that Step 5 runs on competitors. Partials go to partials/{user-slug}.{lane}.md. merge_partials.mjs consolidates to {OUTPUT_DIR}/{user-slug}.md. - Step 5b (matrix synthesis) now explicitly reads {user-slug}.md as the source for userCompany flags. Every flag must be traceable to a Research Findings bullet with a cited URL — the rule applies identically to the user's company and every competitor. - Added the Browserbase-SLA + Browserbase-Stagehand errors to SKILL.md as the cautionary tale for why this parity matters. * feat(competitor-analysis): battle card lane (6th synthesis subagent) Adds sales-enablement output grounded in the fact-checked matrix. Closes the single biggest gap surfaced by the v0.2 framework research: the skill was a Competitor Profiling Matrix but not a Battle Card tool — Klue/Crayon's most-requested artifact had no equivalent in our pipe. Design: synthesis-only lane (no new bb calls), runs AFTER Step 5c fact-check so battle cards are grounded in verified cells, not fresh inference. Eliminates the failure mode where the skill's sales output would contradict the matrix it publishes. Changes: - scripts/merge_partials.mjs: add 'battle' to LANES; union the `## Battle Card` section into the merged {slug}.md between the Comparison and Mentions sections. - scripts/compile_report.mjs: parse the Battle Card section from c.sections, render as a brand-accented `.research.battle` card on the per-competitor HTML page (left border in brand orange, uppercase small-caps subheadings for Landmines / Objection Handlers / Talk Tracks). - references/battle-card.md (new): format spec — three sections, citation rules, adversarial self-check checklist. - references/battle-card-subagent.md (new): standalone prompt template with placeholder list. Main agent substitutes per competitor and launches one subagent per competitor in parallel. - references/example-research.md: add a worked Battle Card section to the Rival Co example. - SKILL.md: new Step 5d (Battle synthesis) with explicit dependency on Step 5c fact-check; Pipeline Overview updated to mention the 6th lane in deep/deeper modes. Scope deliberately tight — this is Phase E of the approved v0.2 plan (/Users/jay/.claude/plans/you-can-figure-out-jaunty-pelican.md). Phases A/B/C/D/F/G deferred. Existing Browserbase + Exa compile runs verified unchanged (no battle partials → battle card card omitted). * fix(competitor-analysis): accept battle-lane format drift at merge time First end-to-end run of the battle lane on Browserbase data: 4 of 5 subagents emitted their Battle Card content with format drift that parseSections() couldn't resolve — some led with `# Battle Card: X vs Y` (h1, not h2 and so invisible to the `## `-only section splitter), some skipped the wrapper heading entirely and led with `## 1. Landmines`. Only 1 of 5 battle cards made it into the merged {slug}.md. Same root cause as the earlier mention-bullet-format fix (commit 953f078): subagents will drift from any prompt-level format spec. Treat the entire battle partial body as the Battle Card content regardless of heading style. Strip any leading `# Battle Card …` h1 or `## Battle Card` h2 wrapper so we don't double-wrap, then emit the rest under our canonical `## Battle Card` heading in the merged file. After the fix: 5 of 5 battle cards rendered in per-competitor HTML on the Browserbase run, each with 5-6 cited landmines, 5 objection handlers with source links, and 2-3 talk tracks. Content quality spot-checked on Anchor (counters the Halluminate stealth benchmark loss with the Advanced Stealth update link) and Steel (flags US-only regions + self-benchmark bias). * fix(competitor-analysis): harden merge + capture scripts on fresh run Second end-to-end run on Browserbase (2026-04-24-1955) exposed two small-but-real bugs not caught on the 2026-04-23 run: 1) merge_partials.mjs — the Battle Card heading-stripper's regex required the first line to be exactly `## Battle Card\s*\n` or `# Battle Card[^\n]*\n`, so an h2-with-suffix line like `## Battle Card — Hyperbrowser` slipped through. The merged hyperbrowser.md got a duplicate `## Battle Card` heading and the HTML rendered the section twice. Generalize to strip any leading heading line (h1-h3) mentioning "Battle Card" with any suffix. One regex handles all observed drift patterns from the 5 subagents. 2) capture_screenshots.mjs — the --help template literal contained unescaped backticks around `website`, breaking the enclosing `\`...\`` literal and yielding a SyntaxError at load time. Never caught before because prior runs skipped --help. Replaced the inner backticks with double quotes. Verified on the fresh Browserbase run: all 5 battle cards merge with exactly one `## Battle Card` header each; 5/5 hero screenshots captured (anchor / browserbase / hyperbrowser / kernel / steel). * fix(competitor-analysis): tighten overview table — exclude user, truncate cells Three concrete bugs on the refreshed Browserbase run: 1) The user's own company leaked into the competitor table as the first row with '—' pricing. Filter it out by matching competitor_name AND slug (case-insensitive) against matrix.json userCompany.name (falling back to --user-company). Also rebuild metaLine + {{TOTAL}} + mentions-header count off the filtered list so "N competitors" is accurate. 2) Overview table cells rendered full 650-char pricing_tiers strings when subagents drifted into prose instead of pipe-separated tiers. Add truncate() helper (~140-160ch with word-boundary ellipsis) on tagline, pricing, and strategic_diff cells. 3) featurePills dropped all pills when key_features had no pipes — because splitPipes returned a single giant blob. Fall back to splitting on semicolons/commas, and cap each pill to 40 chars with a word-boundary ellipsis. Prevents wall-of-text pills. Also lifted the curatedMatrix load above the first use site to avoid a temporal dead zone (the filter needs userCompany.name; the matrix was previously loaded farther down for the renderer functions). After fix: 5-row table instead of 6, pricing/tagline/diff cells fit the intended max-widths, feature pills show as short capsules. * fix(competitor-analysis): mentions feed — alias frontmatter + normalize pills Two bugs on the fresh Browserbase run that both traced to subagent format drift: 1) Browsaur missing entirely from mentions feed chips Root cause: browsaur.marketing.md wrote `competitor: Browsaur` instead of canonical `competitor_name: Browsaur`. merge_partials' CANONICAL_FIELDS whitelist dropped the field silently, leaving Browsaur's merged .md with an empty competitor_name. The overview table still rendered (by slug) but the mentions feed keys on competitor name for the chip label — blank chips filtered out. Fix: FIELD_ALIASES map in merge_partials — `competitor` and `name` and `company` all map to `competitor_name`; `homepage` and `url` to `website`; `price_tiers` and `pricing` to `pricing_tiers`. canonicalValue(fm, key) walks the alias table when the canonical key is absent. Silent fallback: subagents can drift on field names without us losing data. 2) Unstyled mention pills with invented source types Subagents emitted `[VendorBlog]`, `[HackerNews]`, `[GitHubIssue]`, `[CompetitorBlog]` — none matching the CSS classes. Rendered as unstyled spans. Fix: normalizeSourceType() in parseMentions. Canonical set (Benchmark/Comparison/News/Reddit/HN/LinkedIn/YouTube/Review/ Podcast/X/DevTo/Hashnode/Substack/Blog) stays. Aliases map HackerNews→HN, Twitter→X, VendorBlog/CompetitorBlog/GitHubIssue/ Medium/Docs→Blog. Unknown types keyword-scan for a canonical token; else fall back to Blog. Guarantees every pill gets styled. Also filter competitorRows (not deduped) when building allMentions, so the user's own company doesn't leak into the feed even if it has mentions. Fallback chip label is c.slug if competitor_name is blank. After fix on the Browserbase run: 5 competitor chips (Anchor 21, Browsaur 12, Hyperbrowser 22, Kernel 28, Steel 23), all source pills mapped to canonical palette. * perf(competitor-analysis): fix 25-min Step 5 wall-clock + skill-creator nits A real 10-competitor run on Browserbase clocked 40 minutes and never reached fact-check or screenshots before interrupt. Trace attribution: Step 5 enrichment alone burned 25 minutes by self-throttling to 10 agents per message (5 sequential rounds of 10), when the Agent tool happily runs 50+ in parallel. Wall clock collapses to the slowest single agent (~5 min) once we stop batching. Three classes of fix in this commit: 1. Parallelism guidance — workflow.md + SKILL.md - Drop the "up to ~6 per message" cap. Replaced with the explicit rule: launch ALL subagents needed for a phase in ONE Agent message. For 10 × 5 lanes = 50 parallel agents in one message. - Document the measured cost: splitting cost 20 minutes vs unsplit on the Apr 2026 Browserbase run. - Update Step 5 + Wave Management + the lane-fan-out section to match. No remaining contradictions in the docs. 2. Discovery is parallel Bash, not subagents Discovery is 6-12 `bb search` calls. Wrapping each wave in an Agent subagent costs more in cold-start + tool-reasoning overhead than the work itself (~1-2 min wasted). New "Discovery — parallel Bash, not subagents" section in workflow.md gives the exact 3-Bash-call recipe (Wave A/B/C). SKILL.md Step 3 points at it. 3. Skill-creator audit nits (rules from the skill-creator skill) - Add Tables of Contents to all 4 reference docs >100 lines (workflow.md, research-patterns.md, example-research.md, battle-card-subagent.md). battle-card.md is 91 lines so skipped per the rule. - Bump version "0.1.0" → "0.2.0". The skill picked up battle cards (df62374), fact-check (8502f71), prose summaries (9fd482f), user-company parity (845422d), matrix taxonomy (c74d229), Step 4.5 user-confirm (ae58982), and 7 more fixes since 0.1.0 — well past a minor bump. - Kept `allowed-tools` frontmatter field. Not in skill-creator's spec but harness-consumed in some Claude Code setups; harmless if ignored, useful if respected. Estimated next-run impact: 40 min → ~12-15 min through compile, dominated by per-subagent ceiling (3-5 min) + matrix synthesis (4 min) + fact-check (5-10 min if you want it). * perf(competitor-analysis): spot-check fact-check by default, 25-call budget The Apr 25 Browserbase run got stuck at 111+ bb tool calls in fact-check before user interrupt. Root cause: the previous Step 5c mandated verifying EVERY cell of matrix.json — for a 7-company × 33-axis matrix that's 231 cells. Most of those cells are universal table-stakes (Playwright, Puppeteer, CDP, Python SDK) where any cloud browser has them; verifying all of those is redundant work that blocks the pipeline from reaching battle cards / screenshots / compile. The original problem fact-check was solving (the SOC 2 hallucination on the Apr 23 run) was about a HANDFUL of high-stakes cells: the ones that drive the "Where you're winning" summary, plus compliance + license + pricing. Rest doesn't need verification. Switch the default to spot-check with a hard 25-call budget. Priority order is explicit and ranked: 1. Every cell that appears in userCompany.winningSummary/losingSummary 2. Compliance cells (SOC 2, HIPAA, ISO 27001) across all competitors 3. Open-source license cells (Steel was wrong as AGPL — actually Apache 2.0) 4. Pricing tiers + funding numbers cited in summaries Explicit skip list: - Universal cells (Playwright, Puppeteer, CDP, Python SDK, etc.) - `false` cells with no claim - Integration cells unless cited in summaries The subagent counts its own bb calls and STOPS at 25 — partial fact-check beats blocking the pipeline. Full-sweep mode (~80 calls, verifies every non-universal cell) is opt-in for board-deck-level deliverables. Estimated impact on next run: fact-check phase 15+ min → 3-5 min, no more pipeline stalls before battle cards. The summary stays trustworthy because we verify the cells that actually feed it. * perf(competitor-analysis): hard-cap research lane tool calls + halve discovery results User reported research phase still takes ~25min before fact-check even after prior parallelism fixes. Trace showed 2 lanes hitting 29-30 bb calls each against an 8-call advisory budget, dragging the 30-agent fan-out from 5→12min. - references/workflow.md: replace soft "BUDGETS (respect strictly)" with HARD CAP + per-call self-counter ("# bb call N/8") and explicit "stop and write what you have" instruction. Cite Apr 25 incident. - references/workflow.md: drop discovery searches from 25→12 results per query. Gate already filters most noise; 25 just inflated the candidate list and downstream gate calls. - profiles/example.json: drop redundant template (browserbase.json is the reference profile). * fix(competitor-analysis): four Cursor Bugbot findings 1. matrix.html leaked user company as a column with all-false features. Move competitorRows definition above aggregates and replace `deduped` with `competitorRows` in matrix headers/cells, axis counts, pricing table, strategic-summary inner loop, per-competitor page generation, and CSV. Now a single filter applies consistently across all views. 2. report-template.html referenced undefined --high / --low CSS vars on strategic win/loss card border-lefts (and the loss badge text color), so the colored borders silently didn't render. Define both in :root (high=#5a8a1a green, low=#F03603 brand) so they match the existing palette tokens. 3. gate_candidates.mjs used spawnSync inside async gateOne, blocking the event loop and reducing the documented --concurrency 6 to N=1 in practice. Switch to promisified execFile so the worker pool actually parallelizes. 4. extract_vs_names.mjs used bidirectional startsWith for domain resolution, which mapped "steel" -> steelhead.com and "browse" -> browserbase.com. Restrict prefix matches to known branding suffixes (browser/ai/io/app/ labs/etc.), break ties by shortest suffix, and exclude seeds from the host map so the user's own domain can't shadow shorter extracted names. 5. capture_screenshots.mjs (also flagged): the underlying `browse` CLI shares a single session, so true async parallelism would race on the same tab. Clamp --concurrency to 1 with a stderr note rather than silently corrupting output. * bugbot fixes * fix: bugbot complaints * small fix * fix(competitor-analysis): address PR review — remove PII, neutral example industry, browse CLI migration - Remove PII: replace literal /Users/jay desktop path in battle-card-subagent with a generic "absolute path to the output directory" description. - Reframe all worked examples from Browserbase's own competitive set (Hyperbrowser, Stagehand, Anchor, Kernel, Steel, Browserless) to a neutral AI-search-API industry (Exa/Tavily/SerpAPI/Serper, fictional Rival Co). Kept legitimate Browserbase branding/attribution and the Search API tool references. - Migrate bb -> unified browse CLI: bb search -> browse cloud search, bb fetch -> browse cloud fetch (--format raw where HTML is needed since the new default is markdown), bb browse -> browse open --remote + browse get markdown, package npm install -g browse, permission Bash(browse:*). - Screenshots: drop programmatic `browse env`; select mode per-command via --remote/--local and document it in SKILL.md Step 6. Use an isolated named session (and stop it on exit) so capture never collides with the user's existing browse session. Update screenshot flags to the unified surface (--path, --animations disabled). Verified end-to-end against the live browse CLI: gate (Exa PASS / Tavily REJECT), discovery dedup + vs-name extraction, and screenshot capture (valid PNG written). Co-Authored-By: Claude Opus 4.8 (1M context) * fix(competitor-analysis): address review + skills CI compliance - Add LICENSE.txt (MIT, Browserbase, Inc.) and a README table row; trim the SKILL.md description to <=1024 chars so validate-skills passes - Remove stray skill-creator symlink (leaked local ../.agents path, broken for everyone else) - SKILL.md: re-run merge_partials after the Step 5d battle-card lane so the cards actually land in the consolidated files / report; resolve the winning/losing summary write-order contradiction (draft in 5b, finalize after 5c fact-check) - capture_screenshots.mjs: bail on a failed `browse open` (the reused session was saving the previous competitor's page under the new slug); pass mode flags to `browse stop` so remote Browserbase sessions actually tear down - merge_partials.mjs: map a bare `pricing` key to pricing_model, not pricing_tiers (prose/model strings were corrupting the structured tiers) Co-Authored-By: Claude Opus 4.8 (1M context) * fix(competitor-analysis): address second-pass Bugbot findings - md_utils.mjs: tolerate CRLF in parseFrontmatter/parseBody/parseSections (the `---` anchors assumed LF, so CRLF files were skipped or read bodyless) - compile_report.mjs: normalize the user-company exclusion (strip trailing corporate suffix + punctuation) so legal/DBA drift ("Exa, Inc." vs slug `exa`) still filters out the user's own file; still exact normalized-equality, so a real competitor is only dropped if its normalized name equals the user's - SKILL.md: Step 0 note that re-runs must start from a clean $OUTPUT_DIR, since compile_report ingests every {slug}.md and merge_partials never deletes slugs dropped from a new enrichment set (stale competitors would leak into the report) Co-Authored-By: Claude Opus 4.8 (1M context) * fix(competitor-analysis): harden gate concurrency + discovery dedup - gate_candidates.mjs: floor --concurrency at 1, so `--concurrency 0` or a non-numeric value can't spawn zero workers and silently exit having gated nothing (discovery would look empty with no error) - list_urls.mjs: when deduping by hostname, prefer the shallowest path (site root) over a deep link — the first search hit for a domain is often a blog/doc/comparison path, and gating + enrichment want the homepage Co-Authored-By: Claude Opus 4.8 (1M context) * fix(competitor-analysis): floor screenshot concurrency at 1 `--concurrency 0` spawned zero workers (no screenshots captured, script still exited successfully) and a non-numeric value threw on Array(NaN). Normalize to at least 1 before the existing >1 clamp. Same bug class as the gate_candidates concurrency fix. Co-Authored-By: Claude Opus 4.8 (1M context) * fix(competitor-analysis): hide strategic badge count when prose is shown The "Where X is winning/losing" card badge always showed the boolean-heuristic count (allWins/allLosses length), even when the card body rendered analyst prose from matrix.json — the count can be 0 or unrelated to the prose, misstating the card. Only render the badge when the boolean list is what's actually shown. Co-Authored-By: Claude Opus 4.8 (1M context) * fix(competitor-analysis): correct screenshot open-guard + stop teardown Live e2e against browse v0.8.5 showed my two earlier capture_screenshots fixes didn't hold: - Failed-open guard: `browse open` exits 0 even on nav failure (it lands on chrome-error://chromewebdata/), so the exit-status check never fired and a junk error-page PNG was still saved. Now parse the open result's `url` and bail on chrome-error:// / about:blank / empty. Verified: a .invalid URL is now skipped (no PNG) while a good URL still captures. - Teardown: `browse stop --remote` is rejected ("Nonexistent flag: --remote") in v0.8.5 — my flag-passing change broke teardown and leaked the session. Reverted to `browse stop -s `, which does stop a remote session. Co-Authored-By: Claude Opus 4.8 (1M context) --------- Co-authored-by: Claude Opus 4.8 (1M context) Co-authored-by: Shrey Pandya
无版本号
Add webmcp gen skill (#133) * wip * wip * Conform webmcp-gen frontmatter to house skill standards - allowed-tools: space-separated list (matches ui-test style) - compatibility: include install commands (pnpm install, npm install -g browse) Co-Authored-By: Claude Fable 5 * fix(webmcp-gen): make validate.mjs fail on empty tools and empty errorText Address Cursor Bugbot review on validate.mjs: - Empty manifest tools array no longer reports "passed" (vacuous every() + 0===0 length check); now pushes an explicit error and requires >0 tools. - A tool returning { success: false } with an empty errorText is now stored as an error and fails validation (|| fallback instead of ?? on ""). Co-Authored-By: Claude Opus 4.8 (1M context) * fix(webmcp-gen): reject path-traversal in scaffold slug segments Address Cursor Bugbot: parseSlug accepted a ".." segment (e.g. "../task"), and artifactDirFor resolves with path.resolve, so scaffold could write outside the artifacts/ tree. Now each slug segment must match ^[A-Za-z0-9][A-Za-z0-9._-]*$, rejecting ".." and leading-dot segments. Co-Authored-By: Claude Opus 4.8 (1M context) * fix(webmcp-gen): guard validate.mjs against non-array manifest tools Address Cursor Bugbot: a manifest with missing/null `tools` made `manifest.tools.length` throw after the try/finally, crashing before eval.json/eval-report.md were written. Now validate early-returns a written "failed" report when `tools` is not an array. Co-Authored-By: Claude Opus 4.8 (1M context) * fix(webmcp-gen): cap scaffolded tool name to 80 chars, widen validate tool-list timeout Address Cursor Bugbot: - scaffold.mjs toolNameFor now slices to compile.mjs's 1-80 char limit so a long slug can't scaffold a manifest that then fails compile. - validate.mjs listWebMCPTools timeout 1000ms -> 5000ms so slow page loads don't false-report tools as unregistered (example uses the default wait). Co-Authored-By: Claude Opus 4.8 (1M context) * feat(webmcp-gen): emit stagehand-example as .ts run via tsx Match the create-browser-app / browserbase/templates convention (TS examples run with tsx). The generator now writes stagehand-example.ts (no shebang); package.json adds tsx/typescript/@types/node devDeps; SKILL.md documents `npx tsx stagehand-example.ts` and points to `npx create-browser-app` for turning the demo into a standalone project. Co-Authored-By: Claude Opus 4.8 (1M context) --------- Co-authored-by: Sean McGuire Co-authored-by: Claude Fable 5
无版本号
[STG-2253] ci: validate skills against agent-skills standards (#134) * ci: validate skills against agent-skills standards Adds scripts/validate-skills.mjs (zero-dependency Node 20+ validator), a GitHub Actions workflow that runs it on PRs and pushes to main, and CONTRIBUTING.md documenting the skill standards it enforces. Co-Authored-By: Claude Fable 5 * ci: bump checkout/setup-node to v5 (Node 20 action runtime deprecated) Co-Authored-By: Claude Fable 5 * ci: disable setup-node pnpm auto-cache in validate workflow setup-node@v5 defaults package-manager-cache to true, reads the packageManager (pnpm) field from package.json, and tries to prime a pnpm cache. pnpm isn't installed in the job, so it fails with "Unable to locate executable file: pnpm" before the validator runs. validate-skills.mjs uses only Node built-ins (no deps to install), so disable the auto-cache rather than adding a pnpm setup step. Co-Authored-By: Claude Opus 4.8 (1M context) --------- Co-authored-by: Claude Fable 5
无版本号
[STG-2254] chore: bring merged skills up to agent-skills standards (#135) * chore: bring merged skills up to agent-skills standards - Add MIT LICENSE.txt to browser-to-api, company-research, event-prospecting - Normalize autobrowse LICENSE year to 2026 and license frontmatter to MIT - Add license/compatibility/allowed-tools frontmatter where missing (agent-experience, cookie-sync, fetch, functions, safe-browser, search) - README: drop stale site-debugger/bb-usage rows, add agent-experience, autobrowse, browser-to-api, company-research, event-prospecting rows - Remove banned .env.example from autobrowse (update README setup snippet) Co-Authored-By: Claude Fable 5 * fix: drop BROWSERBASE_PROJECT_ID from autobrowse setup line Addresses review feedback from shrey150 --------- Co-authored-by: Claude Fable 5
无版本号
feat(autobrowse): scripts/codegen.mjs — multi-framework runnable-script generator (#125) * feat(autobrowse): scripts/codegen.mjs — multi-framework runnable-script generator Migrates the script-generation apparatus from browse.sh's sandbox prompt into autobrowse itself, so any caller (browse.sh, a developer using autobrowse standalone, future apps) can convert a converged trace into a runnable script with one CLI invocation. What this PR adds: scripts/codegen.mjs orchestrator (~340 lines) codegen/prompts/playwright.md framework-specific system prompt codegen/prompts/stagehand.md framework-specific system prompt codegen/scaffolds/{fw}/package.json pinned deps, self-contained codegen/scaffolds/{fw}/tsconfig.json standard ESM/strict codegen/runners/{fw}.mjs spawn npx tsx + parse JSON result references/playwright-cdp-bridge.md canonical CDP-attach patterns (moved from browse.sh) Pipeline per framework (see scripts/codegen.mjs header): 1. Build context from task.md + unified-events.jsonl + descriptors.ndjson + strategy.md + the framework's prompt template + the cdp-bridge doc. 2. Cache key over sha256(framework + prompt-version + task + trace + descriptors). Hit short-circuits with $0 cost. 3. Single Anthropic completion → emit . to the output dir. 4. Drop scaffold files (package.json, tsconfig) per framework. 5. If --verify: invoke the framework's runner against a fresh BB session. On failure, feed the error back into a rewrite call up to --max-retries times. 6. Emit one JSON line per framework on stdout. Non-zero exit if any selected framework failed. CLI surface: --task required --workspace default ./autobrowse --run default: newest passing run-NNN --frameworks default: playwright; builtins: playwright,stagehand --verify | --no-verify default: --verify --max-retries N default 2 --cache-dir / --out / --force / --dry-run / --cache-only / --model --prompt-template custom template for --frameworks=custom No new top-level deps (uses the @anthropic-ai/sdk that evaluate.mjs already imports). Smoke-tested with --help, --dry-run, --cache-only error paths. Companion change in browse.sh (separate PR): collapse the §4b `for target in playwright stagehand` bash loop and §5 SCRIPT_FLAGS construction into a single `codegen.mjs --frameworks $SKILL_FRAMEWORKS` call; delete prompts/playwright-cdp-bridge.md and src/lib/agent-runtime/ script-references.ts (the doc + bundling logic both live in autobrowse now); drop the playwright/stagehand/tsx/zod install block and the playwright-best-practices-skill clone from src/lib/dispatch.ts. Co-Authored-By: Claude Opus 4.7 (1M context) * fix(codegen): framework-tagged filenames in --out mode Without this, --out with multiple frameworks selected would have both writing to /.ts and overwriting each other. Fix: - Default (no --out): per-framework subdir, file named after the task (e.g. tasks/acme/playwright/acme.ts) — feels like a standalone project. - --out : flat, framework-named files (/playwright.ts + /stagehand.ts) — for callers like browse.sh that flatten everything into one upload-staging dir. Runners updated to take --script instead of --task (the basename is what codegen.mjs decides per the rule above). No interface change to codegen.mjs's CLI — same flags, same JSON output. Co-Authored-By: Claude Opus 4.7 (1M context) * fix(codegen): teach playwright prompt to use APIRequestContext for HTTP/RPC workflows Empirically across 13 non-browser-method skills tested, the agent's emit behavior is inconsistent: CLI (7/7) skipped codegen entirely — correct (CLI setup guides don't wrap into a script). MCP (5) 2 emitted, 3 skipped. Of the 2 that emitted: - packrift: used @playwright/test + APIRequestContext to drive the MCP JSON-RPC server (no browser). Genuinely valuable conformance test. - hiveround: emitted chromium.connectOverCDP + DOM scrape, ignoring the MCP method label entirely. fetch (8) 6 emitted; all 6 used the browser path even when fetch + cheerio could have done the job in 30 lines vs ~400. api (2) chess.com used Playwright-as-fetch (goto + JSON.parse(body) via residential proxy — correct for Cloudflare bypass). sfgov used a similar pattern. Both kept the browser session because they needed the proxy. The packrift case proves the agent CAN write API-RPC scripts via APIRequestContext — it just doesn't always pick that path. Refine playwright.md with an explicit "approach selection" section at the top that branches between API path and browser path based on: - recommended_method in task.md - whether the trace shows real DOM interaction vs HTTP-only calls - whether the data lives in client-rendered DOM vs HTTP response body API path uses `import { request, type APIRequestContext } from "playwright"` (playwright already in the scaffold; @playwright/test is NOT required — plain throw + Zod handles assertions/validation). Browser path is unchanged. Bump PROMPT_TEMPLATE_VERSION to "2" so the cache key invalidates and existing cached outputs don't shadow the refined prompt. stagehand.md untouched in this commit — Stagehand fundamentally needs a browser, so for HTTP-only workflows the right answer is "don't emit a Stagehand script at all", which needs a separate codegen.mjs change (allow runners to signal "not applicable"). Follow-up. Co-Authored-By: Claude Opus 4.7 (1M context) * Revert "fix(codegen): teach playwright prompt to use APIRequestContext for HTTP/RPC workflows" This reverts commit aac0acc1733f5a2a7cc7b0104a6cf2e1c7474b88. * fix(codegen): address 6 PR #125 review threads Six findings from cursor + shubh24 on the codegen PR: 1. (HIGH / blocker) Rewrite verify uses wrong script name `verify(framework, outDir, TASK)` on the rewrite path passes the bare task slug; `verify()` then resolves it as a missing file basename (TASK lacks the .ts extension that scriptBasename carries). This silently disabled the verify→rewrite loop. Fix: pass scriptBasename on both the initial and retry call sites, matching the variable used to write the file at L375. 2. (MEDIUM) Cache hit allowed one extra rewrite On cache hit, `attempts` stayed at 0 through the first failed verify, so the loop condition `attempts < MAX_RETRIES + 1` allowed MAX_RETRIES+1 rewrites for cached runs vs MAX_RETRIES for uncached. --max-retries was therefore inconsistent. Initialize attempts to 1 on both paths so the bound matches. Update the result-object's `cached` flag accordingly: was `!!cached && attempts === 0` (now never true with the new init), now `!!cached && cost === 0` — same semantic ("no LLM call was made for this output"), now expressed via cost which is the load-bearing signal anyway. 3. (MEDIUM) Forced --run path unchecked `pickRun` returned any --run value without checking that `traces//` exists. Codegen would then proceed with empty trace/events/descriptors while logs reported the forced run id as if it were a real input. Add an fs.existsSync gate on FORCED_RUN and a distinct error message when the named dir is missing. 4. (LOW) `ranner_missing` typo Producer (L301) and consumer (L385) shared the misspelling, so the break-on-missing-runner path worked, but it was fragile — fix one without the other and the retry loop would silently stop stopping. Renamed both to `runner_missing`. 5. (DRY) Stagehand runner was 95% identical to Playwright runner Factored the shared spawn-tsx-and-parse-JSON logic into codegen/runners/lib/tsx-runner.mjs (runTsxTarget({label, extraEnv, installEnv, preflight})). The per-framework runners now hold only their genuine differences: - playwright.mjs: PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1 for install+run - stagehand.mjs: ANTHROPIC_API_KEY preflight check Net: ~120 lines collapsed to ~25 each + ~110 in the shared lib. 6. (REGRESSION fix) Scaffold versions had no env override browse.sh's old dispatch.ts used resolveVersion('PLAYWRIGHT_VERSION', …) / 'STAGEHAND_VERSION' / 'TSX_VERSION' / 'ZOD_VERSION' so a deployment could canary a new framework version without a code change. Moving the pins into autobrowse's scaffold/package.json as literals dropped that. Restore the knob: codegen.mjs now reads {PLAYWRIGHT,STAGEHAND,TSX,ZOD,DOTENV}_VERSION env vars (with a semver guard) and interpolates them into the scaffold via the existing template-interpolation pass. Defaults match the previous literals. Bump PROMPT_TEMPLATE_VERSION to "2" so any cached outputs from the buggy verify-loop path get re-emitted. Co-Authored-By: Claude Opus 4.7 (1M context) * fix(codegen): make scaffold `npm start` use generated script name When --out is set, emitted scripts are named .ts but scaffolded package.json hardcoded `tsx {{TASK}}.ts`, so standalone `npm start` in the out dir targeted a nonexistent file. Thread {{SCRIPT}} through dropScaffold and update both scaffolds to `tsx {{SCRIPT}}`. Co-Authored-By: Claude Opus 4.7 (1M context) * fix(codegen): merge package.json deps across frameworks in shared --out dir When --out is set and multiple frameworks share one outDir (browse.sh passes --frameworks playwright,stagehand --out ), framework #1 wrote package.json with its deps and verify ran npm install. Framework #2's dropScaffold hit `if exists(dst) continue` and silently skipped its package.json, so @browserbasehq/stagehand was never declared or installed. The runner's `skip install if node_modules exists` gate then skipped re-install, and verify died at `Cannot find package '@browserbasehq/stagehand'` before any browser work — burning all MAX_RETRIES on an unfixable error. Fix: - dropScaffold: when package.json already exists, deep-merge the scaffold's dependencies/devDependencies in instead of skipping. - tsx-runner: replace `!exists(node_modules)` gate with a sha256 stamp of package.json written under node_modules/.codegen-pkg-hash, so framework #2's merged deps trigger a re-install. Co-Authored-By: Claude Opus 4.7 (1M context) * fix(codegen): correct Stagehand prompt for the v3 API The Stagehand codegen prompt described the old connectOverCDP/attach pattern, so generated scripts failed verify against @browserbasehq/stagehand 3.4.0: - passed the Anthropic key as the top-level `apiKey` (which is the Browserbase key in v3), so session lookup 404'd with "Session not found" - bare `modelName: "claude-opus-4-5"` — v3 wants `model: { modelName: "anthropic/", apiKey }` (provider-prefixed) - `stagehand.page` / `page.extract()` — v3 uses `stagehand.context.pages()[0]` and `stagehand.extract(instruction, schema)` on the instance - REQUEST_RELEASE teardown — v3 owns the session, so use `stagehand.close()` Rewrite the prompt to teach the v3 own-session pattern. BROWSERBASE_API_KEY alone is sufficient (the project is inferred from the key; no projectId). Verified end-to-end: `codegen --frameworks playwright,stagehand --out --verify` now passes both frameworks on the first attempt against live Browserbase sessions (google-news task). Co-Authored-By: Claude Opus 4.8 (1M context) * fix(codegen): --cache-only must also short-circuit the rewrite loop Previously --cache-only only blocked generation on a cache miss; a cached script that failed verify would still enter the rewrite loop and call the Anthropic API, contradicting the documented "no LLM call" CI semantics. Bail out of the rewrite loop when CACHE_ONLY is set. Co-Authored-By: Claude Opus 4.7 (1M context) * fix(codegen): raise verify() timeout above runner worst case verify() spawned the runner with a 5min cap, but tsx-runner internally allows up to 3min for npm install + 5min for the tsx run (8min worst case). The parent could SIGTERM a healthy runner mid-script, leaving verify with no {passed:boolean} JSON line — codegen then treated the script as broken and burned a retry. Bump verify's cap to 10min so the parent always exceeds the child's bounded internals. Co-Authored-By: Claude Opus 4.7 (1M context) * fix(codegen): always set PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD on install In shared --out mode, framework #2 (e.g. stagehand) inherits playwright in its merged package.json via dropScaffold, so stagehand's install would trigger playwright's postinstall and try to fetch ~hundreds of MB of chromium — almost always blowing the 3min install budget and failing verify on a healthy script. Set PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1 unconditionally in the install env (we always connectOverCDP, never need local browsers). Per-runner installEnv still wins via the spread order. Co-Authored-By: Claude Opus 4.7 (1M context) --------- Co-authored-by: Claude Opus 4.7 (1M context) Co-authored-by: shubh24
无版本号
autobrowse: add opt-in --browser-trace integration (#121) * autobrowse: add opt-in --browser-trace integration Wire the sibling browser-trace skill into the autobrowse loop behind a default-off --browser-trace flag. When set, each iteration pre-creates a Browserbase --keep-alive session, attaches bb-capture as a passive CDP observer, and runs evaluate.mjs with --connect-url so every inner browse call is rewritten to attach via --cdp $connectUrl --session autobrowse-main. browse stop is suppressed under trace mode so the named daemon survives the iteration. The --cdp attach mode is the key: --remote routes Network.*/Console.* events only to the driving client, so the trace observer sees nothing useful. --cdp gives the observer the full per-page firehose, matching the canonical pattern documented in browser-trace's SKILL.md. Default path is unchanged; --browser-trace implies --env remote. Co-Authored-By: Claude Opus 4.7 (1M context) * autobrowse: preflight browser-trace + teach cross-trace hypothesis - Add a fail-fast preflight in the traced-path block: if ${CLAUDE_SKILL_DIR}/../browser-trace/scripts/bb-capture.mjs is missing, bail with an install hint pointing at github.com/browserbase/skills. Prevents the harness from blowing up halfway through with "no such file or directory" on bb-capture.mjs. - Make explicit in "Read the trace" + "Form one hypothesis" that under --browser-trace there are now TWO complementary traces: trace.json (what the agent did, per turn) and cdp/summary.json (what the browser did, per page). Document the cross-reference pattern: find the failing page in cdp/summary.json, then jump back to trace.json for the turn whose command produced it. Hypotheses should cite both — "the click went through but /api/checkout returned 403" beats "the click failed." Co-Authored-By: Claude Opus 4.7 (1M context) * autobrowse: thread --browser-trace through multi-task sub-agents Closes the gap flagged in PR #121 review: /autobrowse --tasks a,b --browser-trace would silently fall back to the untraced path inside each spawned sub-agent because the sub-agent prompt template said only "Use --env " without mentioning --browser-trace. The sub-agent prompt now explicitly requires the traced-path loop block (pre-create session, bb-capture, --connect-url to evaluate.mjs, stop+ bisect, release) when the parent invocation passed --browser-trace. Co-Authored-By: Claude Opus 4.7 (1M context) * autobrowse: unified event log as primary --browser-trace artifact Per design feedback (Derek): the two-trace cross-reference UX from the prior commits puts friction on the outer agent. Replace it with a single time-ordered NDJSON stream that joins the agent's turn log (trace.json) and the browser-trace CDP firehose (cdp/raw.ndjson) into one source-tagged file the outer agent reads first each iteration. New: skills/autobrowse/scripts/unify-trace.mjs - Joins trace.json + cdp/raw.ndjson by wall-clock timestamp - Reuses bisect-cdp.mjs's monotonic→wall-clock conversion logic (anchor on first monotonic CDP timestamp + manifest.started_at) - Filters out noisy/redundant CDP methods (dataReceived, ExtraInfo, frame Started/Stopped Loading, executionContextCreated, ...) so the unified log stays scannable - Inline summary fields per browser-event family (url+status+mime for Network.*, level+text for Console.*, name for Page.lifecycle, etc.); full payloads remain in the cdp/ drill-down files - Annotates each browser row with page_id, derived by walking top-level Page.frameNavigated events in the same order bisect-cdp uses SKILL.md changes: - Traced-path block now invokes unify-trace.mjs after bisect-cdp - "Read the trace" section rewritten: unified-events.jsonl is the primary path; structured files (cdp/summary.json, trace.json, cdp/network/failed.jsonl, etc.) are documented as agent-consumable drill-downs for queries the stream doesn't naturally answer - "Form one hypothesis" updated: hypothesis must cite a specific line/timestamp in unified-events.jsonl or name the drill-down file Verified end-to-end on news.ycombinator.com → first story's article: 6 turns, $0.31, 126-event unified log (113 browser + 13 agent), strictly time-ordered, no leaked sessions. No changes to evaluate.mjs or browser-trace. Default path (no --browser-trace) is unchanged — no unify step runs. Co-Authored-By: Claude Opus 4.7 (1M context) * autobrowse: unique daemon name per session + MAX_TURNS env override Two small fixes surfaced by v3.1 verification: 1. Static bug: --browser-trace hardcoded the local browse-daemon name as "autobrowse-main". Two parallel evaluate.mjs invocations (SKILL.md Step-3 multi-task sub-agents) would collide on that socket. Derive a per-process daemon name from a sha1 hash of the connectUrl (autobrowse-) so each Browserbase session gets its own local daemon. Deterministic, no deps beyond node:crypto. 2. QOL: MAX_TURNS is now overridable via the MAX_TURNS env var (default 30). Useful for testing failure-first recovery without patching source. No effect on default invocations. Verification (v3.1, /tmp/autobrowse-eval-v2): - Part 1: joiner's page_id walk matches bisect-cdp exactly (no drift). - Part 2: SKIP_METHODS audit — Network.dataReceived + *ExtraInfo etc. are filtered correctly; ExtraInfo headers remain accessible via drill-down (cdp/raw.ndjson, query.mjs). Known limitation: header-based hypotheses need drill-down today. - Part 3: parallel-daemon contention fixed (this commit). Unit-level verified: different connectUrls → different daemon names. - Part 4: failure-first single-arm on httpbin-form-incomplete - iter 1 (MAX_TURNS=15, --browser-trace): max_turns failure at $0.38; agent burned 4 turns on verification checks (turns 11-14) before submit clicked at turn 15. POST went through (200 OK in unified log) but agent ran out of turns before reading response. - Manual outer-agent step: read unified-events.jsonl, cited specific events (POST line + 4 verification turns), wrote evidence-grounded strategy.md update telling iter 2 to skip the verification loop. - iter 2: 12 turns, $0.27, status=completed, echoed_custname matches. - Net: unified-log evidence drove a real recovery on a failure-first task. ~$0.65 total v3.1 spend. Co-Authored-By: Claude Opus 4.7 (1M context) * autobrowse: export O11Y_RUN_ID so browse CLI can emit descriptors Pair to the descriptor-capture change landing in the browse CLI: every page-driving browse call (click/fill/select/goto/wait/etc.) now side-channels a rich node descriptor to $O11Y_ROOT/$O11Y_RUN_ID/cdp/descriptors.ndjson when both env vars are set. The CLI was already gated on O11Y_ROOT — adding O11Y_RUN_ID lets it know which run subdirectory to write into without inferring from the most-recently-modified dir. Two lines change in the traced-path loop block: - export O11Y_RUN_ID="$RUN_ID" alongside O11Y_ROOT - documentation note on what descriptors.ndjson is and that the outer agent should skip it when reading the trace (it feeds downstream codegen, not hypothesis formation) No effect when --browser-trace is unset or when the CLI doesn't yet have the descriptor-capture utility — the new env var is harmless. Co-Authored-By: Claude Opus 4.7 (1M context) --------- Co-authored-by: Claude Opus 4.7 (1M context) Co-authored-by: ziruihao
无版本号
Rename skill: audit-agent-experience → agent-experience (#120) * Rename skill: audit-agent-experience -> agent-experience Rename the skill folder and scrub all slug references in SKILL.md (name field, report output path) and the HTML report template (header label, footer link). * Point report footer link to browserbase/skills repo Address review: footer linked to github.com/jay/... — repoint to the skill's location in browserbase/skills. Co-Authored-By: Claude Opus 4.8 (1M context) --------- Co-authored-by: Claude Opus 4.8 (1M context)
无版本号
Audit Agent Experience Skill (#79) * Add audit-agent-experience skill — multi-agent evaluation of agent DX Spawns parallel Claude subagents against a target docs/SDK/SKILL.md from a one-sentence prompt, captures structured traces, and renders a graded HTML report scoring Setup Friction, Speed, Efficiency, Error Recovery, and Doc Quality. Includes narrative cross-agent review to surface convergent hallucinations and silent workarounds the JSON self-report misses. Co-Authored-By: Claude Opus 4.7 (1M context) * fix: updated license.txt * bugbot fixes * bugbot fixes * bugbot fixes * bugbot fixes * fix: address review comments on audit-agent-experience SKILL.md - Set author to GH username jay-sahnan - Remove BROWSERBASE_PROJECT_ID from orchestrator-retained credentials example Co-Authored-By: Claude Opus 4.8 (1M context) --------- Co-authored-by: Claude Opus 4.7 (1M context)
无版本号
Update skills to use verified Browserbase sessions (#106)
无版本号
docs: rename bb/browse-cli references to unified browse CLI (#111) * docs: rename bb/browse-cli references to unified browse CLI The `@browserbasehq/cli` (bb) and `@browserbasehq/browse-cli` packages were merged into a single `browse` package (`npm install -g browse`). Update all skill docs, scripts, and examples to use the new command surface: - `bb fetch|search|sessions|projects|contexts|extensions` → `browse cloud ...` - `bb functions ...` → `browse functions ...` - `bb templates ...` → `browse templates ...` - `bb skills install` → `browse skills install` - `bb browse ` → top-level `browse ` (open, get, click, …) - `pnpm bb dev|publish` → `browse functions dev|publish` - `# bb call N/TOTAL` enforcement comments → `# browse call N/TOTAL` - `bbFetch`/`bbBrowseMarkdown` helpers in extract_page.mjs renamed and reworked to call the new `browse cloud fetch` / `browse get markdown` surface. - bb-capture.mjs / bb-finalize.mjs shell out to `browse cloud sessions ...` SDK variable names (`const bb = new Browserbase()`) and the `x-bb-api-key` HTTP header are untouched. Co-Authored-By: Claude Opus 4.7 (1M context) * fix: align browse command examples with 0.6 * docs: note deprecated context upload refresh * docs: clarify cdp flag usage in trace example * docs: rely on cdp daemon persistence in trace example * docs(browser-trace): drop redundant target flags on follow-up commands The browse daemon caches the target after the first command, so commands that follow `browse open --cdp 9222` (or `--remote --session "$SID"`) don't need to repeat the target flag. Addresses PR #111 review comments about `--cdp` repetition in EXAMPLES.md. Co-Authored-By: Claude Opus 4.7 (1M context) * docs: clarify cdp daemon behavior * fix(extract_page): drop redundant --local --headless on `browse get` The browse daemon caches the target after `browse open --local --headless`, so the follow-up `browse get markdown` call shouldn't repeat the mode flags. Matches the convention from skills/browser/SKILL.md ("put --local, --remote, --auto-connect, or --cdp on the first browser command") and the same fix Shrey applied to browser-trace in 5468e0e. Addresses the Cursor Bugbot finding on PR #111. Co-Authored-By: Claude Opus 4.7 (1M context) * docs: align browse lifecycle examples * docs: remove stale fill flag reference * docs: tighten browse skill migration wording * docs: clarify browse stop mode switching * docs: verify browse command caveats --------- Co-authored-by: Claude Opus 4.7 (1M context) Co-authored-by: Shrey Pandya
无版本号
Add browser-reverse skill — OpenAPI 3.1 from browser-trace captures (#88) * Add browser-reverse skill — discover OpenAPI 3.1 from browser-trace captures Consumes a browser-trace run (.o11y//), pairs CDP request/response events, templatizes paths, infers JSON schemas from samples, and emits an OpenAPI 3.1 document with a coverage report and confidence metadata. Pipeline: load → filter → normalize → infer → emit. Each stage is a discrete script writing to intermediate/ for debuggability. Optional --bodies flag joins a `browse network on` capture by CDP requestId so response bodies feed into schema inference. E2E tested against Hacker News, jsonplaceholder, derekmeegan.com, browserbase.com, browser-use.com, reddit.com. Co-Authored-By: Claude Opus 4.7 (1M context) * Address PR #88 review: rename to browser-to-api, drop lift doc, fix bugs Renaming and doc cleanup (per shrey150): - Rename skill from `browser-reverse` to `browser-to-api`. Updates SKILL.md frontmatter + heading, package.json, REFERENCE.md heading, the OpenAPI doc's `info.description`, and the report.md heading. - Fix the stale `discover-api-spec` reference in SKILL.md's composition diagram (left over from an earlier rename). - Drop `BODY-CAPTURE-LIFT.md` from the PR; it's a separate proposal. - Remove the `exec.sendFile()` reference in SKILL.md (browserbase-internal, not a generic skill primitive). - REFERENCE.md restructured to lead with the script/CLI/file-format reference rather than an architecture intro. Pipeline diagram dropped. Bug fixes (per Cursor Bugbot): - `filter.mjs`: rework precedence so `--include` actually rescues URLs that would be hit by a default exclude, matching the documented contract. User `--exclude` still wins. Added a unit-style test path. - `infer.mjs`: skip response-body samples whose CDP status is null. Previously they were keyed under `"0"` but `emit.mjs` only iterates `ep.statusCodes` (which excludes nulls), silently discarding the body. - `load.mjs`: fix the comment in `urlQuery()` — code is first-value-wins, not last-value-wins. Co-Authored-By: Claude Opus 4.7 (1M context) * Add Swagger UI preview for browser-to-api * Noise classification, GraphQL decomposition, and client SDK generation normalize.mjs: - Auto-classify endpoints as api/noise/page and drop non-API traffic (tracking, analytics, bot defense, session plumbing, HTML page renders) - Detect multiplexed endpoints (GraphQL operationName, JSON-RPC method, query param dispatch) and decompose into separate logical operations - Typically drops 60-80% of captured traffic as noise emit.mjs: - Generate client.mjs — zero-dependency ES module wrapping each discovered operation as an async function with JSDoc param types - For GraphQL/APQ endpoints, embeds persisted query hashes and wires up the full request shape so callers just pass variables - Extract required headers from trace (CSRF tokens, custom headers) and include them in client defaults - Task-oriented report.md with quick-start import, curl examples, variables tables, and response samples per operation On OpenTable trace: 27 raw endpoints → 9 named operations, zero noise. Generated client with autocomplete(), restaurantsAvailability(), etc. Co-Authored-By: Claude Opus 4.6 (1M context) * Add self-contained HTML report replacing Swagger UI Generates index.html with: - Summary stats (operations, endpoint, protocol, sample count) - Expandable cards per operation with variables table, client usage, request body, and response example - Full generated client.mjs embedded at the bottom The Swagger UI was a poor fit — 10 identical green POST bars for a single GraphQL endpoint with bracket-syntax paths that aren't even valid OpenAPI. The HTML report shows what actually matters. Co-Authored-By: Claude Opus 4.6 (1M context) * Replace Swagger UI with self-contained HTML report emit.mjs already generates index.html as the primary visual output — update SKILL.md to match and remove the dead open-swagger-ui.mjs script. Co-Authored-By: Claude Opus 4.6 (1M context) --------- Co-authored-by: Claude Opus 4.7 (1M context) Co-authored-by: Shrey Pandya
无版本号
Remove what-antibot skill (#104) Co-authored-by: Claude Opus 4.7 (1M context)
无版本号
chore: clean up what-antibot skill (#99)
无版本号
add skill to check sites for antibots (#98) * add skill to check sites for antibots * fix jank footer * remove jawn * whatantibot instead + url parsing and remove html * fix no csv
无版本号
feat: add safe browser skill (#89)
无版本号
Add browser-trace skill (#83) * Add browser-observability skill Capture the full CDP firehose plus periodic screenshots and DOM dumps alongside any browser automation (browse, Stagehand, Playwright, Puppeteer — anything that speaks CDP), then bisect the stream into per-page searchable buckets keyed by top-level navigations. The skill is purely observational: it adds a second CDP client that enables read-only domains (Network, Console, Runtime, Log, Page) and never sends action commands, so it can attach to an in-flight automation without disrupting it. Layout produced under .o11y//: manifest.json, index.jsonl cdp/raw.ndjson full firehose, NDJSON cdp/summary.json {sessionId, duration, totalEvents, pages[]} cdp//... session-wide buckets cdp/pages// per-page slices, indexed by Page.frameNavigated summary.json, raw.jsonl, network/, console/, page/, ... screenshots/.png, dom/.html browserbase/ added by bb-finalize.sh on remote runs Scripts (pure bash + jq, no Python/Node deps beyond the existing browse CLI): start-capture.sh / stop-capture.sh / snapshot-loop.sh bisect-cdp.sh — splits raw.ndjson into session-wide and per-page buckets, writes the structured summary.json query.sh — drill-down helper: list, page [bucket], errors, hosts, host , timeline, summary bb-capture.sh / bb-finalize.sh — Browserbase wrappers; bb-capture handles --keep-alive + connectUrl resolution + manifest stamping with the session id, region, and live debugger URL; bb-finalize writes browserbase/{session.json, logs.json, downloads.zip} and optionally releases the session The CDP firehose is sourced via `browse cdp `, which streams DevTools-protocol events as NDJSON. That command requires @browserbasehq/browse-cli alpha or a release that includes browserbase/stagehand#1905; lifecycle events specifically require browserbase/stagehand#2056. Co-Authored-By: Claude Opus 4.7 (1M context) * Convert browser-observability scripts from bash to .mjs Mirrors the cookie-sync skill's pattern: each script becomes a Node ESM module, with a shared scripts/lib.mjs for common helpers and a minimal package.json (no dependencies — pure Node stdlib, so no `npm install` step is needed). scripts/lib.mjs shared helpers, BUCKETS table, isTopNav scripts/start-capture.mjs spawn detached `browse cdp` + sampler scripts/snapshot-loop.mjs screenshot+DOM+url poll loop (internal) scripts/stop-capture.mjs SIGTERM+grace+SIGKILL, sweep .partials scripts/bisect-cdp.mjs page-aware bisect + structured summary.json scripts/query.mjs drill-down: list/page/errors/hosts/host/timeline scripts/bb-capture.mjs Browserbase wrapper (--new or attach by id) scripts/bb-finalize.mjs pull session.json/logs.json/downloads.zip Output layout, per-page bisection logic, summary.json shape, and the query.mjs subcommands are identical to the bash versions. SKILL.md, REFERENCE.md, and EXAMPLES.md updated to invoke `node scripts/foo.mjs` instead of `bash scripts/foo.sh`. Dogfooded end-to-end against a Browserbase session and against the saved /Users/d/Desktop/browserbase/o11y-demo-1 run — page bisection, durations, error attribution, host counts all match the bash output. Co-Authored-By: Claude Opus 4.7 (1M context) * Rename browser-observability → browser-trace Shorter, more action-oriented name that reads cleanly as a slash command and pairs naturally with the autobrowse skill (which can use the trace output as the structured "what just happened" data for its loop). Renames: - skills/browser-observability/ → skills/browser-trace/ - SKILL.md frontmatter `name`, doc H1s, package.json name - marketplace.json plugin entry (name, skills path, description, keywords) - README.md skills table row - "observer" → "tracer" throughout the prose for consistency with the new name No behaviour change — all script interfaces, output layout, summary.json shape, and query.mjs subcommands are unchanged. Co-Authored-By: Claude Opus 4.7 (1M context) * Address Cursor Bugbot review on browser-trace Fix three issues flagged on PR #83: - query.mjs cmdTimeline: was printing every navigation followed by every lifecycle event, so all `[NAV …]` lines bunched before any `[init]`/`[load]` lines. Now reads cdp/raw.ndjson directly and emits top-level frameNavigated and lifecycle events in actual stream order. - query.mjs cmdHost: was using `url.startsWith('https://' + hostname)`, which would match `https://api.example.com.evil.tld/...` when the user asked for `api.example.com`. Switched to exact `new URL(url).hostname` comparison via a small `hostMatches` helper. - query.mjs: removed the unused `emitJsonl` helper (defined but never called — same class of dead-code issue Bugbot raised against the bash version's `cat_bucket_across`). Bugbot also flagged the bash bb-capture.sh's `| grep ... || true` that silently swallowed start-capture failures. The .mjs version already handles this correctly via `if (start.status !== 0) process.exit(...)`, so no change needed there. Co-Authored-By: Claude Opus 4.7 (1M context) * Fix Console domain bucket + align hosts/host port handling Two more issues from Cursor Bugbot on PR #83: 1. Console errors and warnings were being silently dropped from the per-page summary. computePageSummary classified each event by `method.split('.')[0]`, which puts Runtime.consoleAPICalled events into a `Runtime` bucket — but errors/warnings from those events were being recorded under the key `Console`. The output loop iterates `counts.entries()` and looks up errors/warnings by that domain key, so the Console errors/warnings never made it into the rollup. Added a `domainFor(method)` helper that returns 'Console' for `Runtime.consoleAPICalled` and the standard `method.split('.')[0]` otherwise. Now matches the schema documented in SKILL.md. 2. cmdHosts grouped by `URL.host` (port included) but cmdHost compared against `URL.hostname` (port stripped), so `hosts` output couldn't be piped into `host` when a port was present. Switched `hostMatches` to `URL.host` for consistency. Impostor protection (rejecting `example.com.evil.tld` for `example.com` queries) is preserved by the exact-equality check. Verified against /Users/d/Desktop/browserbase/o11y-demo-1: every page now shows Console + Runtime as distinct domain blocks; page 4 (httpbin/418) correctly attributes the 418 status to a Log error. Co-Authored-By: Claude Opus 4.7 (1M context) --------- Co-authored-by: Claude Opus 4.7 (1M context)
无版本号
feat: event-prospecting skill (#80) * feat: event-prospecting skill v0.1 Pre-event prospecting skill that wraps company-research's ICP backend. Takes a conference / event speakers URL, extracts the people, filters their companies against the user's ICP, then deep-researches only the speakers at ICP-fit companies. Outputs a person-first HTML report with 3-bullet "why reach out" rationale, all public links surfaced, and a one-click DM opener / "research deeper" clipboard hook per card. Validated end-to-end on Stripe Sessions 2026: 4 browse commands extract 240 speakers / 99 companies in ~6s via the Next.js __NEXT_DATA__ shortcut. Reuses extract_page.mjs + list_urls.mjs verbatim from company-research, extends compile_report.mjs with person-card + people/companies views, and copies the Plan→Research→Synthesize pattern (skills must be self-contained per skill-creator). * addressed bug bot comments * fix: bugbot comments * fix: more bug bot comments * fix: bugbot comment * more bug bot fixes * more bug bot fixes
无版本号
Add company-research skill — deep ICP research with HTML report (#75) * Add company-research skill — deep ICP research with HTML report Co-Authored-By: Claude Opus 4.7 (1M context) * removed profiles * reduce hallucinations * bugbot fix --------- Co-authored-by: Claude Opus 4.7 (1M context)
无版本号
docs(autobrowse): replace slusa-payment with amazon-add-to-cart in examples (#74) Co-authored-by: Claude Opus 4.7 (1M context)
无版本号
feat: autobrowse skill — self-improving browser automation (#71) * feat: add autobrowse skill — self-improving browser automation Auto-research loop for building reliable browser navigation skills. Inner agent browses the site, outer agent reads the trace and improves strategy.md. Repeat until it passes consistently. - SKILL.md: /autobrowse skill (single + parallel task modes via sub-agents) - scripts/evaluate.ts: inner agent harness (Anthropic API + browse CLI) - references/: example-task.md and example-skill.md templates - README, EXAMPLES, REFERENCE docs Co-Authored-By: Claude Sonnet 4.6 (1M context) * docs: replace example-skill.md with real graduated SF 311 skill 17 iterations, 3/3 consecutive passes, remote env. Shows real site-specific gotchas: named Browserbase sessions, ESRI map location, Verint form patterns, XPath vs ref tradeoffs. Co-Authored-By: Claude Sonnet 4.6 (1M context) * feat: sync SKILL.md with latest improvements - structured skill.md graduation template (not just copying strategy.md) - graduate at max iterations too, not just on pass rate - persistent session reports in reports/ with per-iteration cost table - richer sub-agent prompt with key learnings output - cost column in multi-task report table Co-Authored-By: Claude Sonnet 4.6 (1M context) * docs: sync example-skill.md with latest sf-311 skill - remove --session flags (skills must be portable, not session-coupled) - add Known Failure Point section (turn budget exhaustion pattern) - correct wait syntax docs (browse wait load / browse wait timeout N) - 22 iterations, updated gotchas order Co-Authored-By: Claude Sonnet 4.6 (1M context) * fix: address all 5 bugbot findings - [high] block shell metacharacters (;|&|`$()) to prevent injection bypass - [medium] fix npm evaluate script path: evaluate.ts → scripts/evaluate.ts - [low] fix tsconfig include: *.ts → scripts/**/*.ts - [low] lastAssistantText += (accumulate, not overwrite) - [low] remove unused deps: @browserbasehq/stagehand, zod Co-Authored-By: Claude Sonnet 4.6 (1M context) * fix autobrowse bugbot findings * fix autobrowse pricing and symlink handling * feat: add demo-video skill — Remotion launch video learnings Captures full pipeline from storytelling to render: - IDEA ENGINE narrative structure - Remotion gotchas (extrapolateLeft, staticFile, durationInFrames) - Browserbase brand colors and typography - UI mocking patterns with real reference video analysis - Audio production (background, SFX, ffmpeg generation) - Content authenticity (real failures vs invented ones) - Render quality settings (CRF 8 for Twitter masters) Co-Authored-By: Claude Sonnet 4.6 (1M context) * Revert "feat: add demo-video skill — Remotion launch video learnings" This reverts commit 07e7794e3252aec4ee9ce1ac16de81e2e373c2f6. * refactor(autobrowse): convert evaluate.ts to .mjs, follow agentskills.io conventions - Converted scripts/evaluate.ts → scripts/evaluate.mjs (plain ESM JavaScript) - Removed tsx, typescript, @types/node devDependencies - Removed tsconfig.json (no longer needed) - Added --help flag with full usage documentation - Moved diagnostics to stderr, structured JSON result to stdout - Added license field to SKILL.md frontmatter - Updated all references from tsx/evaluate.ts to node/evaluate.mjs Co-Authored-By: Claude Opus 4.6 (1M context) * feat(autobrowse): graduate skills to ~/.claude/skills/ instead of git Graduated skills now install as Claude Code slash commands at ~/.claude/skills//SKILL.md instead of committing a local skill.md file. Removed all git commit references from the loop — the working directory (tasks/, traces/, strategy.md) doesn't need to be a git repo. Co-Authored-By: Claude Opus 4.6 (1M context) * fix(autobrowse): correct ref format, add workspace flag, fail-fast on missing key Three fixes surfaced while running the google-flights task from an empty strategy baseline: 1. Ref format: the inner agent was told to click by @ref (e.g. @0-5), but browse snapshot emits refs as [X-Y] (e.g. [0-5], [2-147]). The agent hallucinated @-refs which the CLI silently accepted as no-ops, burning 30 turns without useful interaction. Updated both the TOOLS description and the system prompt to document [X-Y] format with examples, and added a "never invent refs" rule. 2. Ref counter: the live stderr log and summary writer counted @ chars in snapshot output, which always returned 0 for real snapshots. Switched to /\[\d+-\d+\]/g so outer agents can see the real ref count. 3. Workspace + key UX: added --workspace flag (default ./autobrowse) so tasks/, traces/, and reports/ land in CWD instead of under ~/.claude/skills/autobrowse/. This avoids the permission friction of writing inside Claude's home dir during training. Added ensureApiKey() that fails fast with a clear setup message when ANTHROPIC_API_KEY is missing — no more outer-agent key-hunting paths. SKILL.md updated to document natural-language invocation (URL drops and free-form goals, not just --task ), the new CWD-based workspace flow, and the new ref format / wait semantics. Verified on google-flights: empty-strategy baseline now sees 1157 real refs and drives the form correctly (previously 0 refs, total blindness). With a 9-line strategy, completes in 5 turns / \$0.16. Co-Authored-By: Claude Opus 4.7 (1M context) * fix(autobrowse): address bugbot findings on evaluate.mjs and SKILL.md - Guard lastAssistantText overwrite: only update when the turn produced text, so a final tool_use-only response doesn't wipe prior output (bugbot 3061376570). - Drop redundant reasoningText; the two variables held identical values (bugbot 3061376573). - Reorder tool-result branches: check error before isSnapshot/isScreenshot in both live log and summary writer, so a failed snapshot reports as error, not as "0 refs" (bugbot 3061606988). - Track completion via explicit flag set on end_turn / no-tool-use, not via `turn < MAX_TURNS`: a clean finish on turn 30 was misreported as max_turns (bugbot 3065604864). - Replace personal home path with generic placeholder in the sub-agent prompt template (bugbot 3118916022). Co-Authored-By: Claude Opus 4.7 (1M context) * fix(autobrowse): align wait guidance with browse cli * fix(autobrowse): mark truncated runs incomplete --------- Co-authored-by: Claude Sonnet 4.6 (1M context) Co-authored-by: Shrey Pandya
无版本号
Update CLI command reference for bb v0.5.4 (#72) - Add `sessions create` convenience flags (proxies, stealth, captchas, region, viewport, etc.) that replace manual --body JSON - Add new `templates` command (list, clone) for scaffolding starter projects - Update SKILL.md to include templates in command selection and workflows Co-authored-by: Claude Opus 4.6 (1M context)
无版本号
Add 5 new skills to README (#67)

暂无评论

none
暂无评论...