Playwright E2E Tests
onyx-dot-app/onyx
Write and maintain Playwright end-to-end tests for the Onyx application.
Installs Reticle's dev-only SDK in a running web app and verifies user-facing changes by driving a real flow, returning a verdict with the file and line to fix.
$ npx skills add reticlehq/reticle --skill reticle -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install reticlehq/reticle reticle --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/reticlehq/reticle.git skills-src && mkdir -p .claude/skills && cp -r skills-src/plugin .claude/skills/reticle && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "reticle" agent skill from https://github.com/reticlehq/reticle/tree/main/plugin into .claude/skills/reticle/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "reticle", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/reticlehq/reticle/tree/main/pluginType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add reticlehq/reticle --skill reticle -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install reticlehq/reticle reticle --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/reticlehq/reticle.git skills-src && mkdir -p .agents/skills && cp -r skills-src/plugin .agents/skills/reticle && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "reticle" agent skill from https://github.com/reticlehq/reticle/tree/main/plugin into .agents/skills/reticle/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "reticle", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add reticlehq/reticle --skill reticle -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install reticlehq/reticle reticle --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/reticlehq/reticle.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/plugin .cursor/skills/reticle && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "reticle" agent skill from https://github.com/reticlehq/reticle/tree/main/plugin into .cursor/skills/reticle/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "reticle", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/reticlehq/reticle.git --path plugin--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add reticlehq/reticle --skill reticle -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install reticlehq/reticle reticle --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/reticlehq/reticle.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/plugin .gemini/skills/reticle && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "reticle" agent skill from https://github.com/reticlehq/reticle/tree/main/plugin into .gemini/skills/reticle/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "reticle", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install reticlehq/reticle reticleInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add reticlehq/reticle --skill reticle -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/reticlehq/reticle.git skills-src && mkdir -p .github/skills && cp -r skills-src/plugin .github/skills/reticle && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "reticle" agent skill from https://github.com/reticlehq/reticle/tree/main/plugin into .github/skills/reticle/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "reticle", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add reticlehq/reticle --skill reticle -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install reticlehq/reticle reticle --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/reticlehq/reticle.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/plugin .opencode/skills/reticle && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "reticle" agent skill from https://github.com/reticlehq/reticle/tree/main/plugin into .opencode/skills/reticle/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "reticle", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
reticleInstalls Reticle's dev-only SDK in a running web app and verifies user-facing changes by driving a real flow, returning a verdict with the file and line to fix.
Reticle embeds a dev-only SDK inside the running web app and exposes it to the agent as reticle_* MCP tools, so the agent can look, act, observe and assert against the real DOM, network, routing, console and framework state instead of relying on screenshots. The plugin has already registered the MCP server, so no client restart is needed.
The skill first checks for a .reticle.json file. If it is missing, the project is onboarded with npx @reticlehq/server@latest init, which detects the framework and package manager, wires the build config, installs the SDK, registers the MCP server, starts the dev server, opens the app and waits for a session to connect; it exits non-zero if nothing connects. Either way the work is finished only when a verdict exists from reticle_act_and_wait, reticle_assert, or reticle_act with a step that declares an expectation.
The first run is a separate reticle_verify call with the explore action and a persona. It drives the app with a model inside the daemon and records the flow, so later checks replay it with no model involved. The agent asks you only when a step needs a decision, such as no recognizable dev script in package.json or a host prompt to approve a command, which it must never bypass.
2 steps, taken from the first numbered list in SKILL.md.
Read from SKILL.md and the folder at commit 178e5c0. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
Ships script files (JavaScript), which the agent can run.
Shell commands in SKILL.md call:
curlnpxFrom the folder's file list and the shell code blocks in SKILL.md.
Hosts in commands or code, which the agent is likely to contact:
docs.reticle.shFrom URLs in SKILL.md, links to its own repository left out.
Names these keys or tokens, usually read from environment variables:
RETICLE_LICENSE_KEYFrom names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Reticle Runtime Verification loads about 2.8k tokens when it runs. Until then it costs about 109 tokens; SKILL.md has 1,546 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check noted patterns worth knowing about, such as sudo or a known installer.
one: it writes `RETICLE_LICENSE_KEY` to `.env` and keeps `.env` out of git.CLE_LICENSE_KEY=<key>` to the project's `.env` (create it if absent). The CLI loads a project-local `.env` on every invo2. Make sure `.env` is in `.gitignore`. A license key in git is a leaked credential, so check before you write and add tAutomated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from reticlehq/reticle at commit 178e5c0, republished under its Apache-2.0 licence (© reticlehq). 1,546 words, ~2,829 tokens.
.claude/skills/reticle/SKILL.md (or your agent's skills folder). This skill also uses 4 other files; get the full folder from GitHub.Reticle embeds a dev-only SDK in the running app and exposes it to you as reticle_* MCP tools. You look, act, observe, and assert against the real app. No screenshots.
The plugin already registered the MCP server, so this file runs with no client restart. Finish the setup steps; ask the user only when a step needs their decision. Running init, fixing wiring it could not, starting the dev server and opening the browser are setup steps, not decisions.
The repo already answers which framework, package manager and port, so work those out rather than asking. Say what you did in one line.
Two places always need the user:
package.json. Say so; do not invent one.init writing a pre-approval rule for the reticle server is not that: it is a scoped, announced config change the human asked for by running the command, and it covers only Reticle's own tools.cat .reticle.json 2>/dev/null || echo NOT_FOUNDNOT_FOUND → ONBOARD, then VERIFY.Either way you are finished only when a verdict exists: from reticle_act_and_wait, reticle_assert, or reticle_act { steps } where a step declares expect. Config files are not an install, and a listed session is not a result.
One command wires the project. A second one proves a flow.
npx @reticlehq/server@latest initIt detects the framework and package manager, wires the build config, installs the SDK, registers the MCP server, starts the dev server, opens the app, and waits for a session to connect from inside it. That connection IS the proof onboarding worked: the SDK is in the page and the tools have something to talk to. It exits non-zero if nothing connected, and prints exactly what is left to do.
Then prove a flow. That is the FIRST RUN, and it is a separate call:
reticle_act_and_wait { ref, action, until }Drive the journey that matters and put the verdict on its LAST step: until names the end state before the action fires. What you drive is saved as a flow, so later runs replay it with no model. On a linked project (reticle connect; every plan, Free included, has monthly Harness credits), reticle_verify { action: "explore", persona: "<who does what>" } has the Reticle Harness drive the whole journey for you instead. Before driving anything, replay what is already saved: reticle_verify { action: "flows" } costs no model at all.
The command reads the repository. It cannot read the request, and these live only there.
| flag | what only you know |
|---|---|
persona: "<what>" (on the FIRST RUN, not on init) | which journey proves the thing the user asked for. Code can list the buttons; it cannot know checkout matters and the theme toggle does not. |
--env KEY=VALUE | what the app needs to reach a usable state: the key from .env.example, the mock backend, the variable that skips an auth wall. Repeatable. |
--app <dir> | which app in a monorepo. It can list the servable ones; only the request says which is being worked on. |
Add --license <key> if the user gave you one: it writes RETICLE_LICENSE_KEY to .env and keeps .env out of git.
Framework, package manager, port, editor and MCP client are answerable from the repo you are sitting in, so work them out rather than asking.
A non-zero exit is a to-do list, not a failed install. The command names the cause and prints the REMAINING steps from wherever it stopped; it will not tell you to redo a phase that already worked. Do those and re-run, which is safe.
It is not finished until a verdict exists. Writing files is not an install, and neither is a connected session.
Do not choose this path. It is not the thorough version of the one above; it is what you fall back to when the command physically could not do the work. Use it only when init exited without ever printing starting: or ▸ WATCH (an older CLI that stops after writing files), or when it stopped in the same place twice after you did what it asked. A ⚠ in the report is not a reason: re-run the command, which is idempotent and names what is still outstanding.
curl https://docs.reticle.sh/install-manual.md # register the MCP, wire the SDK, prove it
curl https://docs.reticle.sh/troubleshooting.md # nothing connected, click did nothing, verdict unknownVerdicts come from reticle_act_and_wait, reticle_assert, and reticle_act { steps } when a step declares expect. Everything else (a bare act, look, navigate, observe) moves or reads the app and proves nothing, however many tools it used.
verified: "unknown" is not a pass. It means Reticle drove the app and could not tell what happened, so report it as unknown. verified: "no-fault" is not a pass either: the page settled and no channel complained, but nothing was declared to prove. Never weaken a check to make it pass. That converts a real signal into a false one, which is the failure this product exists to prevent.
Stop at the first row that fits.
| The question | The call | Calls |
|---|---|---|
| "Did my edit break anything?" | reticle_verify({ action: "change", files: ["src/App.tsx"] }) | 1 |
| "Does this known journey still work?" | reticle_run({ tool: "reticle_flow_replay", args: { flowName: "login" } }) | 1 |
| "Does this new behaviour work?" | reticle_act { steps: [...] } to the last page, then reticle_act_and_wait on the step that ENDS the journey | 2 |
| No MCP reachable at all | npx @reticlehq/server verify <url> in the shell | 1, no MCP |
reticle_flow_replay is not on the advertised tool list. It is reached through reticle_run exactly as written, which is the supported call shape and why you have to be told it exists. reticle_verify {action:"change"} answers unknown when no saved flow covers the files you changed: nothing ran, so nothing was proved. That is the honest answer and the signal to record one, never a pass.
Four calls for a login, not fourteen. Every call is a full model turn, and in a client that approves each one it is also a click.
reticle_look({ action: "page", mode: "interactive" }) once, for the whole flow. Elements are addressable by role and name, so you do not need to add data-testid anywhere.reticle_act { steps: [...] } for the setup: every fill and every intermediate click in ONE call.reticle_act_and_wait({ ref, action, until }) for the step that ENDS the journey (the confirmation, the saved record, the last page), not the first click that looks like success. until names that end state before the action fires, which is the difference between a check and a rationalisation. Pass durable: true when the change should survive a reload. A step on the way with a consequence of its own (a save, a submit) gets its own expect in steps, so a journey that breaks at step three fails at step three.reticle_look({ action: "state" }) once at the end. If it comes back empty or hasCapabilities is false, the capabilities file init generated registered nothing, which is what its ℹ AGENT: finish the capabilities file line was telling you. Finish it yourself before you drive: open src/reticle-dev.*, register the app's store if it has one, and list the testids the flow you picked actually touches. That is a setup step rather than a decision: a few lines in a file init already wrote for you. Never report a clean install over an empty state read.Assert what the app did, not what it shows. A UI that renders the value it just sent, rather than the value the server returned, passes every DOM-level check ever written:
until: { kind: "allOf", predicates: [
{ kind: "net", method: "POST", urlContains: "/api/refund", status: 200, bodyContains: "\"refunded\":1187.01" },
{ kind: "element", query: { testid: "receipt" } },
{ kind: "console", level: "error", absent: true },
]}Then report what you drove, what it produced, and the file:line for anything broken.
Enterprise features are unlocked by a signed key, verified locally with Ed25519 and no network call. If the user hands you one, at any point:
RETICLE_LICENSE_KEY=<key> to the project's .env (create it if absent). The CLI loads a project-local .env on every invocation, so nothing else has to change..env is in .gitignore. A license key in git is a leaked credential, so check before you write and add the line if it is missing.npx @reticlehq/server license prints active, eval, missing or expired.Never echo the key back in your reply, and never put it in a commit, a comment, or a feedback report. Details: curl https://docs.reticle.sh/enterprise.md.
Reticle is built for agents. You are its user, and your experience is the only signal that decides what gets built or fixed, and it disappears when your context does. The moment Reticle breaks, lies, cannot see something you needed, costs too many calls, or gives you trouble during setup:
reticle_session { action: "feedback" } { kind, text }kind is one of bug, gap, ambiguity, feature_request, improvement. One call, then carry on. If the tools are unreachable, file the same report from the shell:
npx @reticlehq/server feedback --agent --kind <bug|gap|ambiguity|feature_request|improvement> "what happened"Nothing is too minor. Report defects in Reticle; a bug you find in the app under test is Reticle working, and belongs in your answer to the user. Never put app source, secrets, or user data in a report.
Fetch the one page that answers the question rather than re-reading this file. Appending .md to any docs URL returns its source with no site chrome.
curl https://docs.reticle.sh/llms.txt # every page title and URL; read this first
curl https://docs.reticle.sh/frameworks.md # per-framework SDK wiring
curl https://docs.reticle.sh/troubleshooting.md # nothing connected, click did nothing, verdict unknown
curl https://docs.reticle.sh/agent-cheatsheet.md # the verify loop on one screen
curl https://docs.reticle.sh/predicates.md # every `until` predicate© reticlehq, Apache-2.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
SKILL.md and 4 other files in plugin of reticlehq/reticle.
Open the folder on GitHubat commit 178e5c0
Reticle Runtime Verification next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Reticle Runtime Verification this skillreticlehq/reticle | 1.2k | — | ~2.8k | Automated safety check: Notes | Apache-2.0 | |
| Playwright E2E Testsonyx-dot-app/onyx | 32k | 1 repos | ~2.8k | Automated safety check: Notes | Custom licence | |
| Diff-Driven Smoke TestsSkyvern-AI/skyvern | 23k | — | ~5.2k | Automated safety check: Pass | AGPL-3.0 | |
| E2E VerificationChorus-AIDLC/Chorus | 1.2k | — | ~1.5k | Automated safety check: Notes | AGPL-3.0 | |
| Playwright Testingchongdashu/vibejam-starter-pack | 149 | — | ~2.2k | Automated safety check: Pass | None | |
| Frontend Playwright E2Eansible/ansible-ui | 113 | — | ~2.5k | Automated safety check: Notes | Apache-2.0 |
onyx-dot-app/onyx
Write and maintain Playwright end-to-end tests for the Onyx application.
Skyvern-AI/skyvern
Reads your git diff, writes a handful of happy-path browser smoke tests, runs them with Skyvern or Chrome DevTools MCP and posts screenshot evidence to the PR.
Chorus-AIDLC/Chorus
A skill your agent uses when manually verifying a Chorus frontend change in a real browser — finding local login credentials, driving the running dev server with the Playwright MCP, logging in…
chongdashu/vibejam-starter-pack
Plan, implement, and debug frontend tests: unit/integration/E2E/visual/a11y.
ansible/ansible-ui
Write, run, and debug Playwright E2E / integration / live tests.
langbot-app/LangBot
Tests LangBot's WebUI and core flows through an automated browser and backend logs, with a routing table to reference guides per feature area.
reticlehq/reticle
Applies red-green TDD to behavior unit tests cannot reach, by stating the expected outcome against the running app with Reticle before writing the feature.
reticlehq/reticle
Sweeps a running web app by clicking every reachable control, then reports dead buttons, console errors, failed requests and mismatches between API data and the screen.
reticlehq/reticle
Finds why a running web app misbehaves when the console is empty and the code looks fine, by reading the click, request, store and console together.
reticlehq/reticle
Drives and verifies Electron or Tauri desktop apps through Reticle, which sees the renderer and the IPC calls that a browser-based testing tool cannot observe.
reticlehq/reticle
Finds out why a passing test suite sits on top of a broken app by comparing what the running app does with what the tests claim, using Reticle.
reticlehq/reticle
Picks up bugs a person flagged by pointing at elements in the running app, each mark carrying the element, their note and the source file and line, then fixes and verifies them.
Works with
Categories
Installs Reticle's dev-only SDK in a running web app and verifies user-facing changes by driving a real flow, returning a verdict with the file and line to fix. Reticle embeds a dev-only SDK inside the running web app and exposes it to the agent as reticle_* MCP tools, so the agent can look, act, observe and assert against the real DOM, network, routing, console and framework state instead of relying on screenshots. The plugin has already registered the MCP server, so no client restart is needed.
Reticle Runtime Verification fits situations like: installing and setting up Reticle in a web project; proving a user-facing change works before calling it done; investigating a UI that is broken even though the tests pass; checking DOM, network, routing and console state of a running app without screenshots.
Run `npx skills add reticlehq/reticle --skill reticle -a claude-code`. Or copy the skill folder (plugin in reticlehq/reticle) into .claude/skills/reticle in your project. Claude Code loads it when a task matches its description.
Run `npx skills add reticlehq/reticle --skill reticle -a codex`. Or copy the skill folder (plugin in reticlehq/reticle) into .agents/skills/reticle in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add reticlehq/reticle --skill reticle -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/reticle, .gemini/skills/reticle, .github/skills/reticle and .opencode/skills/reticle in your project.
Going by SKILL.md and its folder, Reticle Runtime Verification needs JavaScript for the scripts in its folder, the command-line tools its instructions call (curl and npx) and credentials named RETICLE_LICENSE_KEY. Our summary lists: A web app with a recognizable dev script in package.json; npx, to run the Reticle server init command; The Reticle plugin with its MCP server registered.
SKILL.md names 1 domain. In commands or code: docs.reticle.sh; the agent is likely to contact it when it follows the instructions. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found notes only (mentions a .env file), nothing it rates as a warning. It is not a guarantee. Review the folder before installing.
Reticle Runtime Verification is published under the Apache-2.0 licence (declared in SKILL.md). It allows redistribution, so the full SKILL.md is shown on this page.
About 2.8k tokens (SKILL.md is roughly 11k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
Skills that share tags, products or a category with Reticle Runtime Verification: Playwright E2E Tests (onyx-dot-app/onyx, 32k stars), Diff-Driven Smoke Tests (Skyvern-AI/skyvern, 23k stars), E2E Verification (Chorus-AIDLC/Chorus, 1.2k stars) and Playwright Testing (chongdashu/vibejam-starter-pack, 149 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
reticlehq (a GitHub organization) maintains it in reticlehq/reticle, which has 1,199 GitHub stars. The repository holds 19 skills in this directory. The repository was last updated on October 9, 2026.
Source: reticlehq/reticle on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.