Skip to content
Skill Authoring
Skill

/capturing-browser-logs

Gets runtime evidence from a web page the agent cannot run itself, using Agent Log (austegard.com/web-utilities/agent-log.html), a script that records console calls, errors, fetch/XHR traffic and the events and DOM changes of elements the user picks, as OpenTelemetry logs in the

From plugin
claude-skills
396107 skills1 agent

Claude Code

$ npx -y skills add oaustegard/claude-skills --skill capturing-browser-logs --agent claude-code

SKILL.md

capturing-browser-logs.SKILL.md
name: capturing-browser-logs
description: Gets runtime evidence from a web page the agent cannot run itself, using Agent Log (austegard.com/web-utilities/agent-log.html), a script that records console calls, errors, fetch/XHR traffic and the events and DOM changes of elements the user picks, as OpenTelemetry logs in the user's browser. Use when debugging a page, web app, browser game or bookmarklet that misbehaves on the user's device, when the user says "it doesn't work" about a page and you need to see what happened, when you want to add console.log instrumentation and read it back, when you need to see what happens on a specific button, field or element, or when the user hands you an OTLP JSON log export or a file named agent-log-*.json.
metadata:
  version: 0.2.2

Capturing browser logs

The user runs the page; you read what it did. Agent Log records the page's console output, uncaught errors, unhandled rejections, failed resource loads, CSP violations and fetch/XHR calls into the browser's IndexedDB, shows a red **Logging** badge while it records, and exports an OTLP/JSON file the user hands back to you. Nothing is uploaded.

Docs, bookmarklet and console snippet: https://austegard.com/web-utilities/agent-log.html

Applicability

Use it when the bug happens in a real browser that you do not control: the user's phone, a GPU-specific failure, a page behind their login, timing that a headless run does not reproduce. If you can run the page yourself in Playwright or a browser tool, do that instead and read the console directly. Agent Log does not see iframes, web workers or service workers, and it does not record request or response bodies.

Procedure

1. **Pick how the user turns it on.** Give them exactly one route:

  • A page whose source you can edit: add `<script src="https://austegard.com/web-utilities/agent-log.js"></script>` to its `<head>`, ship it, and ask the user to open the page with `?logging=true` (or `&logging=true` when the URL already has a query). Logging stays on in that tab across reloads until they press **Stop logging**. For a page that should always log, use `<script src="…" data-start></script>`.
  • Any other page: ask the user to drag the bookmarklet from the docs page to their bookmarks bar, open the page and click it.
  • A page with a strict Content Security Policy (GitHub, many banks and mail clients): the bookmarklet silently fails there. Ask the user to press **Copy the full script** on the docs page and paste it into the page's devtools console.
  • `raw.githubusercontent.com` cannot serve the script to a `<script>` tag (it sends `text/plain` with `nosniff`). Use the austegard.com URL, or jsDelivr: `https://cdn.jsdelivr.net/gh/oaustegard/oaustegard.github.io@main/web-utilities/agent-log.js`.

2. **Instrument with structured console calls** where the existing output will not answer your question. Pass an object: its keys become OTLP attributes you can filter on.

   console.log("bot tick", { tic, pos: { x, y }, sector, target: t?.kind, action });
   console.warn("asset retry", { url, attempt, status });
  • Start the call with a short fixed label, so `--grep` and the body find it.
  • Keep the volume low: once a second, or on change, not once per frame. The log keeps only the newest 20,000 records, so a 60 fps log fills it in under six minutes and pushes out the error you wanted.
  • Mark these calls as temporary in a comment and remove them once the bug is fixed.

3. **Watch the elements involved** when the bug is about an interaction (a button that does nothing, a field that loses its value, a counter that stops updating). Watched elements get records for clicks, typing (one per pause, with the value; password, email, phone and other personal or credential fields are `[hidden]`), changes, submits, focus, non-text keys, and changes to their attributes, text and children. Pick one of:

  • Name them yourself: tell the user to open the page with `&watch=<url-encoded selector>` (repeatable) on a page that includes the script, or to run `AgentLog.watch("#checkout", { label: "checkout button" })` in the console.
  • Let the user point: ask them to click the badge, press **Watch an element** and click the element. The click that picks is not passed to the page.

Watches persist per site until removed with × in the panel or `AgentLog.unwatch(selector)`.

4. **Ask the user to reproduce, then export.** Tell them: click the **Logging** badge, press **Download** (or **Copy** and paste the JSON), and attach the file. The export holds every page load on that site since the log was last cleared; ask them to press **Clear** before reproducing when old runs would get in the way. Tell them, in one sentence, that the log has stayed in their browser until now and that sending it to you sends it to your provider, so they should look it over and cut anything private before attaching it.

5. **Read the export with the reader below.** Save it as `read_agent_log.py` and run it with the export's path.

   python3 read_agent_log.py agent-log.json --pages          # page loads: url, start, records, errors
   python3 read_agent_log.py agent-log.json --min warn       # warnings and errors first
   python3 read_agent_log.py agent-log.json --event console --grep "bot tick" --tail 50
   python3 read_agent_log.py agent-log.json --event http --attr http.response.status_code=404
   python3 read_agent_log.py agent-log.json --event dom --attr watch.label="checkout button"   # one watched element
   python3 read_agent_log.py agent-log.json --load 2 --jsonl > load2.jsonl   # flat rows for pandas or jq

Read errors before anything else, then the records just before the first error in the same page load. Times are UTC.

6. **Verify the capture before diagnosing.** `--pages` must list the page load the user reproduced in, with a URL and a record count above one. If it does not, see the failure modes, fix the capture and ask for another

Read more
@oaustegard
Ships withclaude-skills

A collection of Claude skills distributed as a Claude Code plugin marketplace. Skills are primarily designed for the Claude.ai PaaS skill compute environment; mileage will vary if used as Claude Code Agent Skills.

396107 skills1 agent
Get the whole plugin

Stars on GitHub

Momentum

stars in total
396
Star history of oaustegard/claude-skills on GitHub, a chart by star-history.com

Other skills on claude-skills.

challenging

challenging

Cross-context adversarial review for deliverables before shipping. Use when producing blog posts, technical recommendations,…

More skills from other plugins.

gstack-openclaw-ceo-review

gstack-openclaw-ceo-re…

Use when asked to review a plan, challenge a proposal, run a CEO review, poke holes in an approach, think bigger about scope, or…

gstack2w138k
@garrytan@garrytanInstall Skill
book-to-skill

book-to-skill

Converts books and documents (PDF, EPUB, DOCX, HTML, Markdown, plain text, RTF, MOBI/AZW with Calibre) into structured agent…

@virgiliojr94@virgiliojr94Install Skill
distilly

distilly

Set up the owner profile so a personal agent knows who it works for (first-run setup, \"get to know me\"), or distill colleague,…

@titanwings@titanwingsInstall Skill

Questions about capturing-browser-logs.

Which coding agents can use capturing-browser-logs?
capturing-browser-logs installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.