20 KiB
name, description, tools, triggers, role
| name | description | tools | triggers | role | |||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| browser-debug | Use ONLY when an agent must interact with a live browser to debug, verify, or iterate on Web UI work in packages/app. Triggers on UI bugs, visual regressions, layout/positioning issues, keyboard-focus problems, console-error reports, and any "open the page and check X" task. Uses the built-in unified browser tool surface (browser_open, browser_snapshot, browser_take_screenshot, browser_console_messages, browser_evaluate, browser_close) — contract shared/browser-tool-surface-v1 ([org-internal #4972]); the playwright MCP server is retired ([org-internal #4977]). Use ONLY for interactive browser work; for writing Playwright *test files* use the existing e2e/ suites under packages/app, not this skill. |
|
|
Producer |
Core 中立版(Increment 6a 改写,原 deferHard verbatimDir)。机制、结构与 frontmatter 保持;实例术语(工具名、路径、工单号)按
core/adapters/TERMINOLOGY.md绑定到具体实例。
Browser Debug
Interactive browser automation for Web UI work in packages/app. This skill
teaches the recipe for driving the unified browser tool surface — when to
reach for it, which tool for which job, and how to capture evidence a reviewer
can trust. The former playwright MCP server is retired ([org-internal #4977], Epic [org-internal #4972]
N-05); the tools below are built-in and mount into the session tool face
when this skill activates (default-off the LLM face for weight economy,
[org-internal #5131]) — a user-configured tools_exclude vetoes the mounts.
When this skill applies
Reach for browser-debug when a task requires observing the live
application, not just reasoning about code:
- Reproducing a UI bug (focus lost, dropdown won't close, scroll jumps).
- Verifying a visual change actually landed (computed style, layout box, dark-mode token).
- Capturing console errors or failed network requests during a user flow.
- Recording a screenshot / trace as evidence for a review or DoD entry.
- Exercising a keyboard / screen-reader flow end-to-end.
Do not reach for it when:
- You are writing Playwright test files — those live in
packages/app/e2e/...and run viacd packages/app && bun run test:e2e(variant suites:test:e2e:perf,test:e2e:a11y,test:e2e:smoke,test:e2e:visual). This skill is for ad-hoc, agent-driven sessions, not for adding tests. - The question can be answered by reading code or running a unit test. Browser time is expensive; spend it only when the live DOM is the oracle.
Preconditions
- Unified browser tools are built-in and skill-mounted.
browser_open,browser_snapshot,browser_console_messages,browser_take_screenshot,browser_evaluate, andbrowser_closeare registered for every session (no MCP server needed) but default-off the LLM face — activating this skill mounts them onto the session tool face ([org-internal #5131]); a user tools_exclude vetoes the mounts config needed (the playwright MCP is retired, [org-internal #4977]). If the tools are not visible, the session runs a pre-[org-internal #4972] build — update. - Dev server is running. The app under test must be reachable. For
packages/app, runbash script/dev-fresh.sh --fullfor the dev server (Windows workstations:bash script/dev-fresh-windows.sh— dev-fresh.sh's stop path depends on setsid/ss, silently ineffective under Git Bash; see local-workstation-quirks.md §5); frontend is athttp://localhost:4444and backend athttp://localhost:4096(see AGENTS.md Dev services section). - Chromium is installed. The headless backend drives an isolated
Chromium; if a tool reports a missing browser, run
bunx playwright install chromiumonce in any shell.
Tool selection recipe
The unified surface exposes focused read/navigation tools. Pick by what you need to observe, not by familiarity. Cost discipline applies: the snapshot answers structure/state questions, the screenshot only visual ones — take both in one cycle only when a visual verdict is itself the deliverable:
| Need | Tool | Why |
|---|---|---|
| Open a URL | browser_open |
Always the first call (opens the user-visible browser pane / isolated browser). Pass surface: "headless" when the intent is headless — the user's pane is never touched (no confirmation bar, no pane binding) and later browser_* tools operate on the isolated headless copy; if already bound to the pane, browser_pane_release first. |
| See the page structure (roles, names) | browser_snapshot |
Returns the accessibility tree — stable across CSS refactors. Prefer this over browser_take_screenshot when asserting "does element X exist / is it labelled Y?". |
| See the page visually | browser_take_screenshot |
For layout, spacing, color, overflow. Attach the PNG to your report. Vision-model guard (#screenshot-guard): the PNG is pixels, not text — a session model without vision CANNOT read it. If YOU cannot see images, you must delegate reading via Task(role: "Tool") per the image-interpret skill (returns a structured text spec); never attempt to interpret the PNG yourself. Pixel questions → image-interpret; DOM/state questions → browser_evaluate. |
| Read console errors / warnings | browser_console_messages |
Filter by level (error, warn). The first stop for any "page is blank" bug. |
| Assert computed style / DOM state | browser_evaluate |
Last resort. Snapshots cover 90%; reach for evaluate only when you need getComputedStyle, scroll positions, or arbitrary JS state. |
| Close the session | browser_close |
Tear down when done; see the session cleanup section. |
Pane-first recipe (prefer over headless)
Default to the user-visible browser pane unless the task explicitly needs
an isolated headless Chromium (surface: "headless"). Pane agents now match
or exceed Playwright for the hard cases:
| Need | Pane tool / pattern | Notes |
|---|---|---|
| Open / bind pane | browser_open (default surface) |
Never touch the user's pane from a headless-only intent — pass surface: "headless" or browser_pane_release first. |
| Structure + refs | browser_snapshot |
Open shadow is pierced; closed shadow is CDP-merged (closedShadow:true, no e<n>). Cross-origin iframes expose f{seq}/e{n} synthetic refs — prefer those over attr ids when acting into child frames. Closed hosts inside stitched OOPIF subtrees carry closedShadow:true (CDP merge after stitch). |
| Act (click/type/…) | browser_click / browser_type / browser_act_batch |
Locators (role= / text= / …) walk open shadow; after a JS miss, pane CDP pierces closed shadow for locate/wait/scroll (nested closed-in-open + same-origin iframe contentDocument + cross-origin OOPIF via Target.attachToTarget, including nested OOPIF-in-OOPIF host-offset chains; DOM.focus for type). css= stays light-DOM. Cross-origin click/type route through CDP trusted events. |
| Native dialogs | browser_handle_dialog before the act |
Prefer mode: "arm" (or act_batch.dialog_prearm) so the pane parks the answer before the click that opens confirm/prompt — avoids the 1.5s auto-dismiss / widget-cancel race. Bind with messageIncludes when the page can raise multiple dialogs. Call mode: "disarm" if the trigger was cancelled. |
| Highlight / locator | browser_highlight, browser_generate_locator |
Dual-leg: both pane and headless. Use highlight to confirm the ref before a write. |
| Failure recovery | re-snapshot + path candidates | Act/locator failures may return pathCandidates (frame/shadow path hints). Heal scores framePath so sibling iframes do not auto-heal across frames. |
Headless remains the right tool for parallel CI-style isolation and when the
user must not see the session. For interactive debug of packages/app, stay
on the pane.
Standard recipe — reproduce a UI bug
Follow these steps in order. Do not skip the snapshot step: the ref it
returns is the stable handle every subsequent tool needs.
browser_openthe page where the bug lives.browser_console_messages— record any errors before touching anything. Many "interaction bugs" are actually load-time errors.browser_snapshot— locate the target element; capture its accessible name.- If the reproduction needs interaction beyond reading, use
browser_evaluatesparingly to probe state — the unified surface is read-focused; drive deep flows via the e2e suites when needed. - Re-read
browser_console_messages— capture the delta introduced by the interaction / page state. browser_take_screenshot(or a secondbrowser_snapshot) to freeze the broken state.- Report: URL, the observation sequence, console delta, screenshot, and the
suspected component path in
packages/app/src/....
Standard recipe — verify a UI fix
browser_openthe affected page.browser_snapshot— confirm the fixed element is present with the expected accessible name.browser_take_screenshot— only when the fix is visual (layout, styling, rendering); full page and element-cropped if the fix is local. For non-visual fixes (logic, state, wiring) the snapshot plus console delta is the evidence — skip the screenshot.- If the fix touched layout,
browser_evaluateagetBoundingClientRect()orgetComputedStyle()on the key node and paste the value into your report. Numbers beat adjectives. - If the fix touched interaction, replay the original bug reproduction steps and assert the previous failure no longer fires.
Standard recipe — capture evidence for verify / DoD
When a verify work item has an E2E or UI DoD entry:
- Run the recipe above for each DoD line.
- Save each screenshot as
.playwright-mcp/dod-{item-id}-{state}.png— the worktree's gitignored output dir. See "Screenshot output paths" below. - In the verification report, cite the file names and tell the reviewer
where to look: open the worktree as an octopus project → session side
panel "Screenshots" tab (or the standalone screenshots page). Verify
with
GET /screenshots?directory={worktree}before citing. A screenshot the reviewer can open beats a paragraph of "I checked it". - When the DoD row will cite the evidence as a
BROWSER:{pack-ref}reference (UI-touching PRs,verifyskill Phase 2.7 / contractbrowser-evidence-4486/shared/evidence-ref-v1), promote the captures into an evidence pack first — feed COPIES throughwriteEvidencePack(packages/octopus/src/browser/evidence-pack.ts, the single mandatory sanitize boundary; the.playwright-mcp/layer keeps its current semantics, additive not replaced) and cite the pack directory. Evidence ladder: raw capture →.playwright-mcp/working layer (gitignored) → sanitized Tier-1 pack →BROWSER:reference the verifier validates mechanically.
Rationalizations to refuse
| Excuse | Reality |
|---|---|
| "The unit test already covers it." | Unit tests assert component logic, not what Chromium actually renders. Visual and focus bugs live in the gap. |
| "I can tell from the JSX that it's aligned." | Computed layout depends on parent containers, fonts, and viewport. Screenshot the real page. |
| "Browser automation is overkill for a small change." | A browser_open + browser_snapshot read is ~2 seconds — cheap. The cost is in not looking; add the screenshot only where the question is visual. |
| "I'll just run the whole e2e suite." | The suite answers "did anything break?" — it does not answer "does this specific change look right?". |
| "Snapshot is enough, skip the screenshot." | Depends on the claim. For a visual change it is backwards — accessibility trees hide overflow, clipping, and z-index bugs, so take the screenshot too. For a non-visual claim (presence, label, state) the snapshot alone IS the observation; don't pad it with pixels. |
Boundaries
- Read-only by default. This skill never writes files under
packages/app/src/— it observes. Edits flow throughimplement(bugfix/refactor/port mode). - One page at a time. Close tabs (
browser_close) between scenarios so state doesn't leak. - Evidence lives in the worktree's
.playwright-mcp/dir. Any screenshot or trace you reference in a PR comment, verification report, or DoD entry must be copied into the workflow worktree's.playwright-mcp/directory (gitignored) — never left in/tmp/,playwright-report/, or any machine-local path the reviewer cannot reach through octopus. Cite file names + the worktree project path; the reviewer opens the octopus screenshots UI (session panel tab or screenshots page) to view them.
Session cleanup (mandatory)
The unified surface's isolated backend is a real Chrome with a /tmp
user-data-dir. It stays alive as long as its parent octopus backend runs.
When a browser-debug session ends without an explicit browser_close, OR the
octopus session times out mid-task, the Chrome is orphaned and accumulates
across sessions — burning CPU and leaving dead profile dirs (issue [org-internal #1315]); in
headed mode the orphan is a visible stray window.
Iron rule: every browser-debug session MUST close its browser before ending.
- Always close when done. The last action of any browser-debug task is
browser_close. Treat it like areturn— if you opened a browser, you close it. Do not rely on session teardown to do it for you; it doesn't. - Close on error too. If the task aborts (bug not reproduced, tool error,
user redirect), still call
browser_closebefore moving on. An abandoned debugging session is the most common orphan source. - If a browser was already orphaned (you spot a stale Chrome in
ps, or a/tmp/playwright_chromiumdev_profile-*dir with no live session), do not leave it.bash script/dev-fresh.sh --full(Windows workstations:dev-fresh-windows.sh, same stop-path caveat as Preconditions §2) reaps orphan dev sessions and init-adopted browsers before restarting; run it to clean up. For a targeted clean without restarting the dev server, kill the Chrome by its profile:pkill -f 'playwright_chromiumdev_profile'(and anyagent-browserharness reparented to init).
Why this matters: a single forgotten browser_close leaves a Chrome
subtree (8+ processes) running indefinitely. Over days this is hundreds of
orphaned processes and wasted CPU. Only an explicit browser_close (or
process reaping) releases it.
Screenshot output paths
Screenshots from browser_take_screenshot land in .playwright-mcp/ in the
process cwd (the worktree root), gitignored. An explicit filename can
resolve against the cwd and drop the PNG into the repo root, where the
/*.png gitignore backstop hides it from git status and nothing ever
cleans it up.
Iron rule: 截图文件名必须写进 .playwright-mcp/。 Every filename
passed to browser_take_screenshot (or any tool that writes a file) MUST
resolve into .playwright-mcp/ — write it as .playwright-mcp/<name>.png,
or use an absolute path under /tmp/octopus/. NEVER a bare relative name
like 2202-after-models.png: it leaks a root-level PNG that gitignore masks
but nobody deletes (the 2026-08 repo-root buildup — 40+ orphan PNGs — came
from exactly this).
Two valid destinations for screenshots, by purpose:
| Purpose | Destination | Why |
|---|---|---|
| Ad-hoc / throwaway (debug a layout, confirm a fix landed, never cited in any report) | .playwright-mcp/<name>.png, or omit filename to auto-save into the same dir |
Survives across the session, auto-evicted at 100 MB, never pollutes the repo. |
| Evidence cited in a PR / report / DoD entry | .playwright-mcp/<name>.png — the cwd is the worktree root, so no copy step is needed |
Zero repo bloat (gitignored, never committed); viewable by the reviewer through octopus's own screenshots UI (session panel "Screenshots" tab / standalone screenshots page, served by GET /screenshots?directory={worktree}); lifecycle bounded to the worktree = the review window. |
Evidence publishing ladder (verified 2026-08-14 on this Gitea version):
- Copy into the workflow worktree's
.playwright-mcp/— primary path. Cite file names + worktree project path; reviewer views via the octopus screenshots UI. Verify reachability withGET /screenshots?directory={worktree}before citing. Never commit evidence binaries to git — screenshots accumulate per PR and git history is unreclaimable (measured ~80KB/PR today, unbounded growth). Do not put routine debug screenshots on the wiki either — base64-in-page bloats the wiki git repo equivalently; the wiki evidence namespace is reserved for the durable verify-stage evidence channel (rung 3). - Issue attachments API (
POST /api/v1/repos/{o}/{r}/issues/{n}/assets) — alternative when the reviewer cannot reach the worktree through the octopus UI. The endpoint exists but has returned 500 on this instance; verify before relying on it. - Publish to the wiki evidence namespace
{slug}/verify/evidence/{name}via git direct-push tooctopus.wiki.git(_shared/gitea-write-patterns.mdtop-of-file, [org-internal #6180]) — last resort only, when no other channel works AND the evidence must outlive the worktree (this is the same durable channelverifymandates for DoD evidence entries — see.octopus/skills/verify/SKILL.mdReferences). Keep it small: ≤5 images per PR, each ≤200KB (compress/downscale, prefer element crops over full-page).
Iron rule: never cite a machine-local path (/tmp/..., ~, project
root) as evidence in a Tier-2 output (PR comment, issue comment,
verification report). The reviewer must be able to open the evidence
through octopus (.playwright-mcp/ + screenshots UI) or a repo/wiki URL
(worktree files, or the {slug}/verify/evidence/{name} wiki pages). A
citation they cannot reach is a fabricated citation.
Never write screenshots to the project root. The .gitignore rejects
/*.png, /.playwright-mcp/, and /playwright-report/ only as a backstop —
an ignored file is still an orphan on disk. The .playwright-mcp/ filename
prefix is the real fix; rely on that, not on the backstop.
References
.octopus/skills/image-interpret/SKILL.md— REQUIRED when the session model has no vision:browser_take_screenshotwrites a PNG the driving model cannot read. Delegate reading viaTask(role: "Tool")(structured text spec back); never self-interpret pixel content. Pixel questions (layout, color, spacing) → image-interpret; DOM/state questions (form values, validation) →browser_evaluate..octopus/skills/frontend/SKILL.md— where UI changes are planned; invoke this skill during Phase 3 / Phase 4 to verify each state visually..octopus/skills/implement/SKILL.md— Frontend Mode; pair withbrowser-debugwhen the work item touches rendering..octopus/skills/implement/SKILL.md(Mode: bugfix) — Phase 1 reproduction; use this skill to capture the failing state before isolating root cause..octopus/skills/verify/SKILL.md— Phase 2 / DoD matrix; use this skill to generate screenshot evidence for UI-tagged DoD entries.packages/app/e2e/— permanent Playwright test suites; this skill is the ad-hoc complement, not a replacement.rules/dev-serveron the wiki — how to run the dev server for TUI work; consultpackages/app/README.mdfor the web equivalent.