libretto-readonly
SkillWeb & browsingRead-only Libretto workflow for diagnosing live browser state without clicks, typing, navigation, or mutation requests.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the libretto-readonly skill
What this skill tells your AI
The instructions your AI receives, as published by saffron-health/libretto in .agents/skills/libretto-readonly/SKILL.md and read by ahel’s review.
How Libretto Read-Only Works
- Use this skill when the browser session must stay strictly read-only.
- Libretto stores read-only vs write-access on the session itself.
- The primary inspection tools are
snapshotandreadonly-exec. readonly-execreuses Libretto's normal execution pipeline, but it only exposes read-only helpers and denies mutating Playwright methods.- Only a user can change the session mode for an existing session. Never change a session's mode on your own — the user must change it themselves manually.
Working Rules
- Announce which session you are using and what page you are inspecting.
- Do not use
exec,run, or any direct Playwright action that could change browser or application state. - Do not click, type, submit forms, navigate, upload files, dispatch DOM events, or send non-GET requests.
- Prefer
snapshotfirst when the visible page state is unclear. - Use
readonly-execfor focused inspection: titles, HTML, locator text, counts, visibility checks, and GET requests. - Keep snippets small and purpose-built. Do not run multiple
readonly-execcommands at the same time. - Close disposable sessions before your final response once inspection is complete. Open browsers keep consuming local or hosted resources.
- End with diagnosis and handoff guidance, not an attempted in-browser repair.
Commands
connect
- Use
connectto attach to an existing CDP endpoint for a preserved browser session. - Use
--read-onlywhen creating the Libretto session handle for a preserved browser session. - Libretto read-only mode is enforced through Libretto commands; direct CDP clients that skip Libretto are outside this boundary.
libretto connect http://127.0.0.1:9222 --read-only --session failed-job-debug
pages
- Use
pageswhen a popup, new tab, or second page exists. - If
readonly-execorsnapshotcomplains about multiple pages, list ids first and then pass--page.
libretto pages --session failed-job-debug
snapshot
- Use
snapshotas the first high-level observation tool. - Run
snapshot <ref>to inspect a subtree from the latest full snapshot.
readonly-exec
- Use
readonly-execfor narrow inspection code only. - Denied operations fail with
ReadonlyExecDenied: ....
Helpers
page— a read-only PlaywrightPageproxy. Standard Playwright read methods work normally (url(),title(),content(),frames(),getByRole(),locator(),textContent(),isVisible(),count(),scrollIntoViewIfNeeded(), etc.).frames()returns read-onlyFrameproxies, including fromchildFrames()andparentFrame(). Anything that mutates a page or frame (click,fill,goto,evaluate,keyboard,mouse) is blocked.state— the current Libretto session state object.get(url, options?)— HTTP client restricted to GET and HEAD requests. Replacesfetch, which is blocked in readonly mode. Any request with a body or a non-GET/HEAD method throwsReadonlyExecDenied.scrollBy(deltaX, deltaY)— scroll the viewport by pixel offset. Use this to inspect content below the fold without targeting a specific element.
Standard JS globals console, URL, Buffer, setTimeout, and setInterval are also available.
Examples
libretto readonly-exec "return page.url()" --session failed-job-debug
libretto readonly-exec "return await page.getByRole('heading').first().textContent()" --session failed-job-debug
libretto readonly-exec "return await page.frames()[1]?.getByRole('heading').textContent()" --session failed-job-debug
# HTTP GET inspection
echo "const r = await get('https://api.example.com/status'); return await r.json()" \
| libretto readonly-exec - --session failed-job-debug
# Scroll down to inspect below-the-fold content
libretto readonly-exec "await scrollBy(0, 500)" --session failed-job-debug
close
- Use
closewhen the inspection session is no longer needed, unless the user explicitly asks to keep the browser open.
libretto close --session failed-job-debug
Signals
- GitHub stars
- 889
- Forks
- 69
- Last commit
- Aug 2026
Advanced
- Catalog kind
- skill
- Gateway key
libretto-readonly- Source
- github.com/saffron-health/libretto