Windows QA Engineer
CodeAlive-AI/ai-driven-development
A skill your agent uses when testing Windows 11 desktop apps (WinForms/WPF/UWP) via UFO UIA/Win32 automation MCP.
Onboard a consumer web app to mirroir's .mirroir/ dotfile by EXPLORING the running app (chrome-devtools-mcp) — derive real selectors from the accessibility tree, exercise each surface's primary…
$ npx skills add jfarcand/mirroir-mcp --skill mirroir-onboard -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install jfarcand/mirroir-mcp mirroir-onboard --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/jfarcand/mirroir-mcp.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.claude/skills/mirroir-onboard .claude/skills/mirroir-onboard && 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 "mirroir-onboard" agent skill from https://github.com/jfarcand/mirroir-mcp/tree/main/.claude/skills/mirroir-onboard into .claude/skills/mirroir-onboard/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "mirroir-onboard", 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/jfarcand/mirroir-mcp/tree/main/.claude/skills/mirroir-onboardType 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 jfarcand/mirroir-mcp --skill mirroir-onboard -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install jfarcand/mirroir-mcp mirroir-onboard --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/jfarcand/mirroir-mcp.git skills-src && mkdir -p .agents/skills && cp -r skills-src/.claude/skills/mirroir-onboard .agents/skills/mirroir-onboard && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "mirroir-onboard" agent skill from https://github.com/jfarcand/mirroir-mcp/tree/main/.claude/skills/mirroir-onboard into .agents/skills/mirroir-onboard/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "mirroir-onboard", 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 jfarcand/mirroir-mcp --skill mirroir-onboard -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install jfarcand/mirroir-mcp mirroir-onboard --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/jfarcand/mirroir-mcp.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/.claude/skills/mirroir-onboard .cursor/skills/mirroir-onboard && 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 "mirroir-onboard" agent skill from https://github.com/jfarcand/mirroir-mcp/tree/main/.claude/skills/mirroir-onboard into .cursor/skills/mirroir-onboard/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "mirroir-onboard", 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/jfarcand/mirroir-mcp.git --path .claude/skills/mirroir-onboard--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 jfarcand/mirroir-mcp --skill mirroir-onboard -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install jfarcand/mirroir-mcp mirroir-onboard --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/jfarcand/mirroir-mcp.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/.claude/skills/mirroir-onboard .gemini/skills/mirroir-onboard && 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 "mirroir-onboard" agent skill from https://github.com/jfarcand/mirroir-mcp/tree/main/.claude/skills/mirroir-onboard into .gemini/skills/mirroir-onboard/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "mirroir-onboard", 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 jfarcand/mirroir-mcp mirroir-onboardInstalls 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 jfarcand/mirroir-mcp --skill mirroir-onboard -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/jfarcand/mirroir-mcp.git skills-src && mkdir -p .github/skills && cp -r skills-src/.claude/skills/mirroir-onboard .github/skills/mirroir-onboard && 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 "mirroir-onboard" agent skill from https://github.com/jfarcand/mirroir-mcp/tree/main/.claude/skills/mirroir-onboard into .github/skills/mirroir-onboard/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "mirroir-onboard", 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 jfarcand/mirroir-mcp --skill mirroir-onboard -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install jfarcand/mirroir-mcp mirroir-onboard --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/jfarcand/mirroir-mcp.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/.claude/skills/mirroir-onboard .opencode/skills/mirroir-onboard && 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 "mirroir-onboard" agent skill from https://github.com/jfarcand/mirroir-mcp/tree/main/.claude/skills/mirroir-onboard into .opencode/skills/mirroir-onboard/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "mirroir-onboard", 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.
mirroir-onboardOnboard a consumer web app to mirroir's .mirroir/ dotfile by EXPLORING the running app (chrome-devtools-mcp) — derive real selectors from the accessibility tree, exercise each surface's primary…
Mirroir Onboard is an agent skill from jfarcand/mirroir-mcp. Onboard a consumer web app to mirroir's .mirroir/ dotfile by EXPLORING the running app (chrome-devtools-mcp) — derive real selectors from the accessibility tree, exercise each surface's primary action, emit the .mirroir/ tree, and validate by LIVE REPLAY with a self-heal loop. Reject shallow "page renders" coverage.
Its SKILL.md is about 4.4k tokens, which your agent loads only when the skill is triggered. The skill folder holds 1 other file (for example `README.md`).
It sits in Testing & QA, covering MCP servers, Browser testing and Accessibility. It works with Model Context Protocol, Chrome DevTools, macOS and Playwright. The repository describes itself as: MCP server for controlling a real iPhone via macOS iPhone Mirroring...and any MacOs app. Screenshot, tap, swipe, type — from any MCP client. The licence is Apache-2.0.
8 steps, taken from the step headings in SKILL.md.
Read from SKILL.md and the folder at commit c652b78. It shows what the files ask for, not the result of running them.
Pre-approves these tools, so the agent can use them without asking each time:
mcp__chrome-devtools__*ReadWriteEditBashGlobGrepTaskCreateTaskUpdateTaskListFrom allowed-tools in the SKILL.md frontmatter.
Shell commands in SKILL.md call:
gitFrom the folder's file list and the shell code blocks in SKILL.md.
Links to these hosts (documentation or services it may open):
gist.github.comFrom URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Mirroir Onboard loads about 4.4k tokens when it runs. Until then it costs about 83 tokens; SKILL.md has 2,242 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.
allowed-tools: mcp__chrome-devtools__*, Read, Write, Edit, Bash, Glob, Grep, TaskCreate, TaskUpdate, TaskListAutomated 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 jfarcand/mirroir-mcp at commit c652b78, republished under its Apache-2.0 licence (© jfarcand). 2,242 words, ~4,415 tokens.
.claude/skills/mirroir-onboard/SKILL.md (or your agent's skills folder). This skill also uses 1 other file; get the full folder from GitHub.You are the web explorer. You drive a consumer's running web app the way
an agent drives an iPhone in generate_skill action=explore: navigate, read
the live accessibility tree, find each surface's primary action, derive the
exact selector that resolves it, execute it, capture the resulting state change,
and emit a replayable .mirroir/ suite. Then you prove it by live replay
and self-heal any selector that doesn't resolve.
The output is a .mirroir/ tree at the consumer root that goes green under
mirroir-run (a real boot + real Playwright replay against the real backend),
not merely one that compiles. Compile-clean is necessary but not sufficient —
selectors that pass --emit playwright still fail at replay (wrong element,
strict-mode, or never resolves). The replay is the gate.
You do not hand-author from spec files. Every selector comes from a DOM you
observed via mcp__chrome-devtools__take_snapshot. You are mechanizing the
human loop, not transcribing a test plan.
A mocked Playwright/Cypress suite (page.route(...)) verifies the frontend in
isolation — it stays green even when the backend wiring, DB seed, auth gate,
dev proxy, or LLM path is broken. mirroir's only job is to catch exactly those:
"the real stack boots and the headline journeys actually work." If your
scenarios don't exercise real primary actions against the real backend, you've
rebuilt the mocked suite slower — delete them and stop.
So: complementary, never a replacement. Run
find <root> -name '*.spec.ts' -o -name '*.cy.ts' | grep -v node_modules | wc -l
first; if non-zero, the mirroir.yaml description must say "complementary" and
name that count. Assume an existing suite exists until proven otherwise.
This is the phase that silently eats hours. A web app being "up on :PORT" does not mean a real user can log in and reach an authenticated surface. Confirm each link of the chain before exploring, because every one of these has bitten real onboarding:
Boot a genuinely fresh stack — kill stale processes first. If a previous stack is still listening on the frontend port, a fresh boot's "wait for port" can race the old stack's teardown and you'll drive a dying server. Stop all services, confirm the port is down, then boot.
Beware test-mode env flags — they often disable the real backend. Many
apps gate a dev proxy / mock layer on a flag like E2E_TEST, CI,
MOCK_API. Their own mocked suite sets it so the frontend serves canned
responses. For mirroir that is poison: with the proxy off, the login POST
(e.g. /oauth/token) 404s and every authed scenario fails. Do not set
these flags. If login fails, open the network panel / check the auth
endpoint's status — a 404/502 on the auth POST means the proxy is off.
IPv4 vs IPv6 loopback. Dev servers (Vite's default localhost) often
bind [::1] only, so http://127.0.0.1:PORT is refused while
http://localhost:PORT works. Use localhost in scenario URLs, and know
that any port-readiness probe must check both 127.0.0.1 and [::1].
The auth/onboarding gate may demand seeded state. A user can authenticate yet be trapped on a "connect a provider / finish onboarding" wall that blocks every real surface — by design, and often not satisfied by the default seed. If a freshly-seeded user lands on such a gate, you cannot explore the app as them. Find which seeded user clears the gate (read the seeder), or surface to the user that the seed needs to make one demo user fully usable. Do not fake your way past it — that's no longer a real-stack test.
Backend readiness ≠ frontend readiness. The frontend may bind its port
before the backend has finished a slow startup (migrations, a remote content
sync). With the proxy on, the app's first calls hit a not-ready backend. Give
the boot real headroom and confirm an authed API call returns 200 before
exploring.
Record the working facts as a discovery task: boot command, frontend port, the usable user credentials (and which gate they clear), and any flag you had to avoid. You will reference these throughout.
You generally do not boot the user's stack for them — it's their environment. But you must verify the chain above against the running app before exploring, and tell the user precisely which link is broken if one is.
Confirm the app is up (list_pages; navigate to the consumer URL if needed).
Then walk it like a graph.
Clear storage + cookies for the origin, navigate to /, take_snapshot.
Capture the form field selectors and a unique-on-page heading string
(avoid "Sign in" if it appears as both an <h1> and a button). → one
unauthenticated-landing scenario asserting the form is present.
For each role the seeder creates (admin, regular/demo user): fill credentials,
submit, wait for an authenticated signal, capture location and one sidebar
item unique to that role (e.g. an admin-only nav button). → one login
scenario per role asserting a real post-login element (not just "logged in").
For every top-level nav surface, find and execute its primary action — the thing a user comes to that surface to do, not the fact that it rendered:
| Surface kind | Primary action (examples) |
|---|---|
| Chat / assistant | type a message → send → wait for the real reply |
| List/store of items | open an item → assert its detail view |
| Empty-state collection | click "Create …" → assert the create modal/form |
| Feed | trigger the share/react/adapt action → assert the result |
| Admin table | Approve/Suspend/Delete a row → assert the count/row change |
A read-only surface with no action is not a deep flow — don't manufacture a shallow scenario for it (that's the anti-pattern); either find its real action or leave it to the mocked suite. One scenario per (surface × primary action); never collapse two distinct actions into one.
mirroir compiles tap:/wait_for:/assert_visible: labels to Playwright via a
helper that resolves a label as follows:
[ # . : > * → raw CSS / locator passthrough (page.locator)role= text= xpath= css= id= data-testid= → Playwright
locator-engine passthrough (page.locator('role=button[name="X"]'), etc.)[data-test="<label>"] OR getByText("<label>", {exact:true})Pick the label form from what the a11y snapshot shows, in this priority:
[name="email"],
[name="password"], [placeholder="…"]. (Password inputs are not
role=textbox; target them by [name=...]/[type="password"].)role=:
role=button[name="Create Group"], role=heading[name="Create Coaching Group"].
This is the workhorse for real apps — most use ARIA roles + accessible
names, not data-test. The role engine matches name EXACTLY (trimmed,
case-insensitive) — it is not substring. So this only works when the
accessible name equals your string.<button> whose name is category+count+title+description) → role= will
not match a fragment. Instead target the unique inner text node with the
bare-text form (Taper Builder) — the click bubbles to the card — or use
text= for a substring match.text=Pending Users (matches
"Pending Users (3)"); plain bare text is exact via getByText, so a
label with a trailing count/badge needs text=.>> nth=0 (role=button[name="Create Group"] >> nth=0) or
scope to a parent.Accessible name truth source: the chrome-devtools take_snapshot tree shows
the same accessible name Playwright's role engine uses (e.g. it renders
button "Pending 3" with the space even when textContent is "Pending3").
Trust the snapshot's name string, not el.textContent.
For each label you choose, confirm it resolves to exactly one element on the
live page before writing it (a quick take_snapshot check, or count via
evaluate_script). One label → one element at that step's moment.
The final assert_visible / wait_for of a deep flow must prove the action
happened, not that a button exists:
role=button[name="Close modal"], the modal title).role=button[name="Pending 2"]
after approving one of three), a new row, a success toast.text= substring (e.g. text=claude-opus survives a model bump from 4.7→4.8;
asserting the exact model string is brittle). Give it a real timeout.Multi-step confirmations are real flow: if "Approve" opens an inline "Approve User" confirm, both clicks belong in the scenario.
Run this audit on your drafted scenarios before writing the tree (not after). Any hit → fix that scenario now:
wait_for: <heading> and has no tap:/type: after login → shallow
"page renders". Add the primary action or drop it.take_snapshot → cold-authored. Re-walk
that surface.assert_visible on text that repeats per-card/per-row → strict-mode. Use a
unique-on-page string or >> nth=0.baselines/<flow>.ios.txt and whose scenario has no
cross_surface: step → the parity gate has no web half. Add it (Phase 5).mirroir.yaml omits "complementary" + the existing spec count → fix..mirroir/ (the consumer describing itself), but
never let consumer concepts leak into mirroir-mcp's own code/tests..mirroir/ tree<consumer-root>/.mirroir/
├── mirroir.yaml # plan; description says COMPLEMENTARY + spec count
└── apps/<sample>/
├── SAMPLE.md # session.boot (command, cwd, ports, timeout), scenarios list
├── APP.md # routes, selector style, usable test users + gate notes
├── SKILL.md # the canonical flows + why each was chosen
├── baselines/ # cross-surface oracles, shared with the iOS leg:
│ # <flow>.ios.txt (device capture, committed)
│ # <flow>.web.txt (scraped by the run, gitignored)
└── scenarios/<flow>.yaml × NSAMPLE.md boot:
cwd is resolved relative to the SAMPLE.md directory — for a sample at
.mirroir/apps/<x>/, the repo root is ../../...boot_ready_port = the frontend port; boot_ready_timeout_s generous enough
for a cold checkout (full rebuild) — minutes, not seconds.Scenario URLs use http://localhost:PORT/ (Phase 0.3). Add to consumer
.gitignore: .mirroir/.build/, .mirroir/mirroir.local.yaml,
mirroir-run-report.json, .mirroir/apps/*/baselines/*.web.txt.
baselines/ is the one directory the web leg shares with the iOS leg.
generate_skill … emit=true writes baselines/<flow>.ios.txt there:
whitespace-joined OCR text of the iPhone screen at the flow's equivalence point.
When a flow you authored has one, your scenario owes the other half — and it
produces that half itself. End the flow's own web block with a
cross_surface: step whose web capture scrapes the same screen:
# …the primary action and its state-change assertion (Phase 3)…
- cross_surface:
captures:
- surface: web
# Resolved by the same helper as Phase 2's labels: raw CSS, role=,
# text=, or a bare label.
selector: "[data-test=order-summary]"
to: "${MIRROIR_SAMPLE_DIR}/baselines/<flow>.web.txt"
response_files:
- "${MIRROIR_SAMPLE_DIR}/baselines/<flow>.web.txt"
- "${MIRROIR_SAMPLE_DIR}/baselines/<flow>.ios.txt"
min_similarity: 0.5Rules that bite:
cross_surface: alone in a file of its own has no page to scrape, so the
.web.txt is never written and that gate can only ever fail.to must be one of response_files — the runner refuses the step
otherwise, because the scrape would go unread and a stale file compared instead.min_similarity is required; there is no default. 0.5 suits iOS↔web phrasing
divergence — the iOS side carries chrome (back chevron, nav title) the web page
has no equivalent of. Raise it for high-entropy screens; be careful on
low-vocabulary ones, where a generic token set clears a low bar by coincidence.body. Whole-page text drags in nav and
footers with no iOS counterpart and drops the score for no reason.mirroir-run accept re-records the .web.txt only; the
.ios.txt closes on a device re-capture, which is the point of the gate.No .ios.txt for a flow → no cross_surface: step for it. Never hand-write one:
a baseline you typed is not a device observation, and the gate it feeds proves
nothing.
Compile-check first (fast sanity): for each scenario,
mirroir-run --emit playwright <abs-path> must write a .spec.ts carrying a
test(...) block under target/playwright/.
But compile-clean is not done — the 2 most common real failures
(role-name-not-exact, strict-mode duplicates) pass compile and only surface at
replay.
Then run the real thing from the consumer root:
# kill any stale stack first (Phase 0.1), then:
MIRROIR_PLAYWRIGHT_HOME=<dir containing node_modules/@playwright/test> mirroir-run --scenarios all(MIRROIR_PLAYWRIGHT_HOME points at where the consumer's @playwright/test
is installed — often the repo root or the frontend workspace root — so the
emitted Playwright config can resolve it.)
Self-heal loop — this is the differentiator over a static suite. For each failing scenario, read the failure:
strict mode violation: resolved to N elements → the label is ambiguous;
go back to the live DOM, pick a unique label or add >> nth=0.locator.click: Timeout … exceeded waiting on a role=button[name="X"] →
the accessible name isn't exactly X (concatenated card, or extra
badge text); re-snapshot, switch to the inner text node or text=.wait_for/assert timeout → the post-action signal was wrong; re-execute
the action live, observe what actually changes, fix the assertion.Re-drive the live app, re-derive, re-run. Repeat until the sample is green
(MIRROIR_EXIT=0, sample verdict pass). A red replay is not done.
Summarize: scenarios authored grouped by surface; the primary action each
exercises; any selector fallbacks and why; and the green replay verdict. Wait
for the user to inspect and authorize the commit. Never git add/git commit
unprompted.
mcp__mirroir__generate_skill MCP tool (CGEvent + OCR on a real iPhone). You
consume the baselines/<flow>.ios.txt it writes (Phase 5a); you never
author one.local: samples only. Promoting a flow to a shared archetype (so the
next app of the same shape — auth + sidebar + chat-console, etc. — inherits
coverage by declaring the archetype + a few selectors) is the cross-app
multiplier, but it's a separate task: runner/docs/archetype-authoring.md.role= engine passthrough and dual-stack
(127.0.0.1 + [::1]) port readiness. Older runners lack these and will
fail real-app exploration. Verify the runner is current.runner/docs/mirroir-dotfile.mdrunner/docs/archetype-authoring.md© jfarcand, 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 1 other file in .claude/skills/mirroir-onboard of jfarcand/mirroir-mcp.
Open the folder on GitHubat commit c652b78
Mirroir Onboard 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 |
|---|---|---|---|---|---|---|
| Mirroir Onboard this skilljfarcand/mirroir-mcp | 247 | — | ~4.4k | Automated safety check: Notes | Apache-2.0 | |
| Windows QA EngineerCodeAlive-AI/ai-driven-development | 159 | — | ~1.4k | Automated safety check: Pass | MIT | |
| Electron Live Testinstructa/agent-skills | 139 | — | ~1.3k | Automated safety check: Pass | None | |
| UI Visual DebuggingNangoHQ/nango | 13k | — | ~1.3k | Automated safety check: Pass | Custom licence | |
| Browser Testing With Devtoolsshashankswe2020-ux/whoop-mcp | 165 | — | ~3k | Automated safety check: Warn | MIT | |
| Igniteui Wc Figma To AppIgniteUI/igniteui-webcomponents | 170 | — | ~7.2k | Automated safety check: Pass | MIT |
CodeAlive-AI/ai-driven-development
A skill your agent uses when testing Windows 11 desktop apps (WinForms/WPF/UWP) via UFO UIA/Win32 automation MCP.
instructa/agent-skills
Live-test any Electron desktop app with native-devtools-mcp, Chrome DevTools Protocol, screenshots, OCR, and accessibility tools.
NangoHQ/nango
A skill your agent uses when modifying or visually debugging Nango frontend UI, including packages/webapp, packages/connect-ui, browser interactions, screenshots, and visual regressions.
shashankswe2020-ux/whoop-mcp
Tests in real browsers. An agent skill from shashankswe2020-ux/whoop-mcp.
IgniteUI/igniteui-webcomponents
Builds Ignite UI Web Components views from Figma designs, supporting Indigo.Design kits, third-party kits (Material 3, Fluent 2, shadcn/ui, Untitled UI, in-house), and plain frames.
holon-run/uxc
Use Chrome DevTools MCP through UXC over local stdio for page navigation, DOM/a11y snapshots, network inspection, console inspection, and performance tooling, with a live-browser autoConnect default…
jfarcand/mirroir-mcp
Work the private register (mirroir-carnet) from a session — claim an issue before touching it so peers see who holds it and which session, release or close it when done, file new issues in the one…
jfarcand/mirroir-mcp
Register a known gap in the limitation register — file the issue in the private tracker, write the LIMITATION(registren) marker, or ledger a dark-launched feature.
Onboard a consumer web app to mirroir's .mirroir/ dotfile by EXPLORING the running app (chrome-devtools-mcp) — derive real selectors from the accessibility tree, exercise each surface's primary…. Mirroir Onboard is an agent skill from jfarcand/mirroir-mcp.mirroir/ tree, and validate by LIVE REPLAY with a self-heal loop.
Mirroir Onboard fits situations like: tasks that involve MCP servers; tasks that involve Browser testing; tasks that involve Accessibility.
Run `npx skills add jfarcand/mirroir-mcp --skill mirroir-onboard -a claude-code`. Or copy the skill folder (.claude/skills/mirroir-onboard in jfarcand/mirroir-mcp) into .claude/skills/mirroir-onboard in your project. Claude Code loads it when a task matches its description.
Run `npx skills add jfarcand/mirroir-mcp --skill mirroir-onboard -a codex`. Or copy the skill folder (.claude/skills/mirroir-onboard in jfarcand/mirroir-mcp) into .agents/skills/mirroir-onboard 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 jfarcand/mirroir-mcp --skill mirroir-onboard -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/mirroir-onboard, .gemini/skills/mirroir-onboard, .github/skills/mirroir-onboard and .opencode/skills/mirroir-onboard in your project.
Going by SKILL.md and its folder, Mirroir Onboard needs the command-line tools its instructions call (git). Its frontmatter pre-approves these tools: mcp__chrome-devtools__*, Read, Write, Edit, Bash, Glob, Grep, TaskCreate, TaskUpdate, TaskList.
SKILL.md names 1 domain. As links in the text: gist.github.com. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found notes only (pre-approves every shell command (allowed-tools: bash)), nothing it rates as a warning. It is not a guarantee. Review the folder before installing.
Mirroir Onboard is published under the Apache-2.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 4.4k tokens (SKILL.md is roughly 18k 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 Mirroir Onboard: Windows QA Engineer (CodeAlive-AI/ai-driven-development, 159 stars), Electron Live Test (instructa/agent-skills, 139 stars), UI Visual Debugging (NangoHQ/nango, 13k stars) and Browser Testing With Devtools (shashankswe2020-ux/whoop-mcp, 165 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
jfarcand (a GitHub user) maintains it in jfarcand/mirroir-mcp, which has 247 GitHub stars. The repository holds 3 skills in this directory. The repository was last updated on October 5, 2026.
Source: jfarcand/mirroir-mcp on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.