browser
Skill56 starsChanged 46 days agoMITView on GitHub
Drives a real browser from the shell: open, read, click, fill, sign in, download. Use it before the first browser command of any web job: a page, a form, a checkout, a sign-in, their own Chrome.
68 other projects use a version of this.
Adopted by
Most recently taken up by
- wubinKKK/private-ai-workbenchtheir own version, first seen Nov 8, 2026
- EthanLLL/loomtheir own version, first seen Nov 8, 2026
- matthewwong525/WongStacktheir own version, first seen Nov 8, 2026
- letsloose501/sqs-agent-memorytheir own version, first seen Nov 3, 2026
- Y91R/chromectltheir own version, first seen Nov 2, 2026
- derwells/learn-skilltheir own version, first seen Nov 1, 2026
Used with
Projects with it also use V3 Core Implementation, V3 DDD Architecture and 10 more.
Other files people use alongside this one.
Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.
ruvnetSkillV3 Core Implementation
Core module implementation for claude-flow v3. Implements DDD domains, clean architecture patterns, dependency injection, and modular TypeScript codebase with comprehensive testing.
Also in 15 projects that use this
ruvnetSkillV3 DDD Architecture
Domain-Driven Design architecture for claude-flow v3. Implements modular, bounded context architecture with clean separation of concerns and microkernel pattern.
Also in 15 projects that use this
- +10 more from ruvnet
Other versions68 projects use a version of this.
Word for word · 1
- cgoinglove/thursday★ 56100% same
Edited · 0
None found.
Wrote their own version · 67
- ruvnet/wifi-densepose★ 103ksame name
- ruvnet/RuView★ 103ksame name
- ruvnet/claude-flow★ 80ksame name
- ruvnet/ruflo★ 79ksame name
- ruvnet/ruvector★ 4.7ksame name
- ruvnet/RuVector★ 4.7ksame name
- browserbase/agent-browse★ 3.7ksame name
- VibiumDev/vibium★ 3ksame name
- cexll/myclaude★ 2.8ksame name
- proffesor-for-testing/agentic-qe★ 524same name
57 more not listed
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository12 other files it gives its agents.
- AGENTS.mdAGENTS.md
- agent-browserSkill
- ai-sdkSkill
- marketingSkill
- shadcnSkill
- artifactSkill
- computerSkill
- daily-briefSkill
- data-reportSkill
- find-skillsSkill
- media-digestSkill
- skill-creatorSkill
The file
We split this skill into the rules it gives an agent
3 rules. 0 are common, 0 are distinctive, and 3 are very specific to this project.
0
Common
Most of the 57 edited versions we read keep these.
0
Distinctive
This author's own choices. Worth a look.
3
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 101
Never guess or invent a secret, or go looking for one somewhere they did not point you at.
- Very specific: line 106
Reading a page: Every command writes a snapshot file and prints its path.
- Very specific: line 119
Refs go stale: after anything that changed the page — snapshot again before the next click.
“Common” is measured: kept by at least 6 in 10 of the 57 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
The browser
You drive a real browser from your shell with playwright-cli: open a page,
read it as a snapshot, act on elements by ref.
In this app
Everything the app has to say about the browser is here; the prompts do not repeat it.
Every browser goes through here. A job that names a browser, a site, a URL,
a sign-in or a tab is this one's. With --headed the window playwright-cli
opens is a real one on their screen — they can watch it and type into it. Never drive Chrome by
clicking it through the machine (osascript, peekaboo, System Events): that
window cannot be snapshotted or acted on by ref.
The browser they already have open is reached through its extension. For a
tab they left or a profile they are signed into, playwright-cli attach --extension=chrome
opens a page in the Chrome they use and waits until they allow it there. The tab
they pick on that page — one they left open, or that page itself — is yours,
signed in as they are; their other tabs stay theirs. It needs the Playwright
extension in their Chrome: when the command says it is missing, give them the
link it prints and ask. The link to their Chrome can drop between commands: when
one answers that the browser is not open, attach again — open would start a
browser of your own instead. A click there waits on a tab that is in front:
--raw run-code "async page => page.bringToFront()" first.
Your browser is your own on this job. Its session is already in your shell
(PLAYWRIGHT_CLI_SESSION): never pass -s=, never close-all or kill-all —
other bots and jobs are running theirs. A follow-up uses this same session:
read snapshot to continue where you left off; use open only if it is closed.
Headless is yours; headed is theirs. A browser opens headless: nobody sees
it, and the app closes it once the job is done or has sat an hour without a step.
Finding, reading and comparing stay headless, however many pages it takes: a
window that opens by itself lands on whatever they are doing, a call included.
--headed puts a real window on their screen, and that window outlives the job
until they close it or cancel or delete the job. It is for three things: the thing itself
once the job has it — the products they asked you to find, the order sitting at checkout
for them to confirm, the map with the pin dropped, the page they asked to watch — a
sign-in for them to finish, and a payment for them to press. Open it --headed, leave it
open, and say in your answer that it is on their screen. A window you opened
headed only to get past a wall and are done with, close yourself. A window is never how
you look at your own work: a page, a deck or a canvas you made is shown to
you by its skill's shots and look_at, and reaches them under your answer — nor is open on their
desktop. Only a job they cancel or delete takes its windows with it.
A payment is theirs to press. Take a purchase, a top-up or a subscription
as far as the last screen before money moves, open it --headed, and answer
with what it buys, for how much, and that the pay button is on their screen.
That is the job done, not stopped — never press it yourself, whatever the
request said.
A site that will want a session before it shows you anything — a shop, a
console, a dashboard, an account page — starts --headed --persistent rather
than finding out headless and starting over.
A wall is the site's answer. A 403, an "access denied" page, a check for
automated traffic or a captcha is the site saying no to a bot, and getting round
it is not yours to do: no other browser, profile or disguise, no waiting it out.
Take what the job needs from where it is published otherwise — another source,
the site's own API, a search. When only that page will do and it is one they
would open themselves — the shop they named, their bank — open it --headed for
them and ask, as a sign-in below: a person may pass where a bot may not.
Otherwise say in your report which url refused you, and bring back what you have.
A sign-in is a fork, not a wall. Three ways through, and which one fits is yours to read off the job:
- A sign-in the app already keeps. Cheapest when it works, so try it before
the other two. It goes into the browser you have open, so the order is
open, then thesign_in_usetool with the site, thengoto— a state loaded with no browser open is refused, and one loaded before youopenagain is thrown away with the browser that held it. Open the window you mean to keep first, headed or not.gotolast because cookies without a reload leave the signed-out page that was already drawn, which reads as an expired session when it is not. - Their own Chrome. Attached to it as above, you are signed in as they are.
It is the way through for a site that still shows you signed out right after
sign_in_use— some refuse a sign-in carried between browsers, and signing in again in your window will not last there either. - They sign in themselves.
open <the login url> --headed --persistent— the login page, not the front door. For another account on a site the app already keeps, leave out--persistent: a new browser holds none of them, and signing out of a kept one to make room can end its session for every bot. Then aquestionthrough Thursday, to the user, in one line saying what to sign into and that the window is open, optionsSigned in/Not now, and stop. The window stays open while the job waits; continue from a freshsnapshotwhen the answer comes. A captcha or a code sent to their phone is the same move. Notshow— it blocks waiting for annotations nobody will send. Once they are in, call thesign_in_keeptool: the app keeps the sign-in for your later work, and they can sign out of it in Settings. The window was for the sign-in, so it closes and your browser goes on without one, signed in, on the same page — unless what comes next there is theirs to see, the products to choose or a checkout to confirm: then passkeepWindowand it stays.
Never guess or invent a secret, or go looking for one somewhere they did not
point you at. An email or username they gave you is not a secret — fill it and
press next. memory_recall the note for that site when you are missing the
address they use.
Reading a page. Every command writes a snapshot file and prints its path.
find "Create Key" returns only the matching nodes with a few lines around
each — use it when you know what you are after. cat the file when you need
the whole layout. snapshot e34 is one region; --raw eval is one value.
Pulling the markup in (innerHTML, curl) spends a page of context on a
navigation menu; the snapshot is the same page for a fraction of it. On anything
long, find and snapshot <ref> are the cheap way through — keep raw HTML for
when the markup itself is what you need. A page that draws itself from a fetch
is cheaper at the source: requests numbers what it pulled, response-body N
prints one — the data already parsed, rather than read back out of the DOM.
What only the eye can tell — a chart, a photo, whether the layout came out —
is a screenshot and then the look_at tool, when you hold it.
Refs go stale after anything that changed the page — snapshot again before
the next click. A page that looks empty right after loading is still rendering.
A click that seems to do nothing may have opened a tab: tab-list,
tab-select N.
One command, not one turn per step. Chain steps that need no look in between
with &&. What a click brings in is not there on the very next read: wait for
its text in the same command, --raw run-code "async page => { await page.waitForFunction(t => document.body.innerText.includes(t), '<text>'); }"
— getByText(…).waitFor() times out when the first match is hidden.
Search and locale. A search engine's results page is for people, and most
refuse a browser a script drives. Find urls with the web_search tool; without
one, search where the answer lives — the site's own search box, Wikipedia — and
say in your report that you had no web search. Pages answer in this machine's
language and currency; put the country in the url when the job is about another.
Pictures for a document come off the page, never from memory:
--raw eval "JSON.stringify([...document.images].filter(i => i.naturalWidth > 200).map(i => i.currentSrc))".
Local HTML. file: URLs are refused, and a fixed port lets two jobs
capture each other's pages. To open or print one:
node <skill dir>/scripts/serve.mjs <dir> > <scratch>/serve.log 2>&1 &, read the
address from that log, goto <address><file>.html; pdf --filename=out.pdf
prints it, in a headless browser. Kill the server when done.
Scripts in <skill dir>/scripts: sheet.mjs puts many pictures on one
image for a single look_at, webimage.mjs saves a page's own picture with
its credit line, and session.mjs lets a script of yours drive this session —
references/scripts.md. What one run-code call can do — several reads at
once, a wait, a download, the clipboard — is references/run-code.md; a
recording of the screen for the user is references/recording.md.
Snapshots land in .playwright-cli/ and are cleared after a few days. A file you
name — --filename=, a pdf, a download — goes under scratch/, or
your folder under artifacts/ when it is the result.
Install
The app fetches the browser itself when it starts — Google Chrome for Testing, set
in your shell, never the user's own Chrome — so this is only for a machine where
that never finished. open failing with a missing executable is the tell:
playwright-cli install-browser chromiumIt downloads ~280 MB and prints nothing when the build is already there. If it fails, say so and stop — do not fall back to a browser you found on the machine.
On Linux, open failing because the browser closed before any page, with an
empty browser log, is missing system libraries rather than a missing download.
Installing them needs administrator rights: tell the user to run
npx playwright install-deps chromium once, and stop.
Commands
playwright-cli open # headless; add a url to navigate at once
playwright-cli open <url> --headed # a real window on their screen
playwright-cli open <url> --persistent # keep a profile between opens
playwright-cli open --mobile # mobile layout — lighter pages, smaller snapshots
playwright-cli attach --extension=chrome # their own Chrome: the tab they pick
playwright-cli goto <url>
playwright-cli go-back | go-forward | reload
playwright-cli resize 1280 800 # before a screenshot or a pdf
playwright-cli snapshot # the page, as refs — written to a file
playwright-cli snapshot e34 # one region
playwright-cli find "Sign in" # matching nodes with context
playwright-cli find --regex "/sign (in|up)/i"
playwright-cli click e3 # also: dblclick, hover, drag e2 e8, drop e8
playwright-cli fill e5 "text" --submit # --submit presses Enter after
playwright-cli type "text"
playwright-cli press Enter # ArrowDown, Escape, …
playwright-cli select e9 "option-value"
playwright-cli check e12 | uncheck e12
playwright-cli upload ./file.pdf
playwright-cli dialog-accept ["text"] | dialog-dismiss
playwright-cli tab-list | tab-new [url] | tab-select N | tab-close [N]
playwright-cli requests # what the page fetched, numbered
playwright-cli request 7 # one of them whole: headers, body, response
playwright-cli response-body 7 # just the body
playwright-cli eval "document.title"
playwright-cli eval "el => el.textContent" e5
playwright-cli --raw eval "…" # only the value, nothing else printed
playwright-cli screenshot [e5] [--filename=x.png]
playwright-cli pdf --filename=page.pdf
playwright-cli closeTargets are refs from the snapshot (e15). A css selector or a Playwright
locator works too: click "#main > button.submit",
click "getByRole('button', { name: 'Submit' })".
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

