win-dev-skills
A GitHub Copilot, Claude Code, and OpenAI Codex plugin for building native Windows apps with WinUI 3 and the Windows App SDK to cover the end-to-end inner loop: scaffold β design β build β run β test β package β ship.
Turn Your Coding Models to Be State-of-the-art Browser Agents π Blog: Webwright: A Terminal Is All You Need For Web Agents π Project Page: microsoft.github.io/Webwright Webwright gives LLM a terminal where it can launch multiple browser sessions to inspect
> /plugin marketplace add microsoft/Webwright> /plugin install webwright@webwright
What's inside
Webwright gives LLM a terminal where it can launch multiple browser sessions to inspect the page and complete a web task. It captures and inspects page screenshots/states only when needed. It enforces each web task to be completed end-to-end within a re-runnable Python script, i.e. your web agent browsing history is a single code file. No multi-agent system, no graph engine, no plugin layer, no hidden orchestration β just a terminal, a browser, and a model.
Already got your favorite agents, and wonder how to make Claude Code, Codex, Hermes, OpenClaw more capable in browser tasks? Consider adding Webwright plugin/skills!
/plugin install webwright@webwright. OpenClaw and Hermes Agent integrations shipped; the same skills/webwright/ folder now loads across Claude Code, Codex, OpenClaw, and Hermes.Most web agents today treat the browser session itself as the workspace: at each step the model receives the current page state and predicts a single next operation β a click, a type, a DOM selector, or a short tool call. Whatever the format, the agent is locked into predicting one web action at a time inside a predefined interaction loop. That harness was useful when LLMs were weaker. As models get stronger at writing and debugging code, the same harness becomes a bottleneck.
Webwright takes a different stance: separate the agent from the browser, and treat the browser as something the agent can launch, inspect, and discard while developing a program. The persistent artifact is not the browser session β it's the code and logs in the local workspace.
Most web agent frameworks bury the actual agent loop under layers of abstractions. Webwright takes the opposite stance:
httpx, pydantic, playwright, and typer.If you want a minimal, easy-to-debug starting point for browser-using agents instead of another heavyweight platform, this is it.
How they differ at the architectural level:
| Stagehand (Browserbase) | agent-browser (Vercel) | browser-use | Webwright | |
|---|---|---|---|---|
| Paradigm | Hybrid: code + NL primitives (act / extract / agent) | CLI tool that another agent (Claude Code, Codex, etc.) calls | Autonomous LLM agent loop over DOM/AX snapshots | Coding agent with a terminal; browser is just an environment it spawns |
| Action space | Playwright code, or NL β LLM-translated Playwright | Discrete subcommands (open, click @e2, snapshot, eval) | Indexed click/type actions selected by the LLM | Free-form Python (writes Playwright scripts itself) |
| What is "state"? | The browser session | The browser session (held by daemon across CLI calls) | The browser session | The local workspace β code, screenshots, logs. Browser is disposable. |
| Loop shape | Imperative; agent() does multi-step when needed | One CLI invocation per micro-step | observe β predict next action β execute β repeat | write code β execute β inspect screenshots β repair (code-as-action) |
https://github.com/user-attachments/assets/4ed94cd5-11be-4daa-b2d7-1260a803baca
State-of-the-art on two real-website benchmarks with a 100-step budget β see the blog post for full details.
webwright/
βββ pyproject.toml # package: webwright
βββ src/webwright/
β βββ run/cli.py # CLI entrypoint (`webwright`)
β βββ agents/default.py # core agent loop
β βββ environments/ # Playwright browser workspace
β βββ tools/ # image_qa, self_reflection
β βββ models/ # openai_model, anthropic_model, base
β βββ config/ # base.yaml, model_openai.yaml, model_claude.yaml
β βββ utils/
βββ assets/
β βββ task_showcase/ # tiny Flask dashboard for repeatable runs
β βββ app.py
β βββ templates/ # dashboard.html, task.html
β βββ tasks/<short_id>/ # task.json + report.json per task
βββ tests/
βββ outputs/ # run artifacts (trajectories, screenshots)
A tiny Flask app under assets/task_showcase/ consolidates
Webwright runs for repeatable odyssey tasks (deals, inventory, listings,
job boards, weather, etc.) into a single dashboard. Each task ships only two
files β task.json (metadata) and report.json (curated, structured output:
sources + result sections like tables, lists, summaries) β and the templates
render them generically, so adding a new task is just dropping a new folder
in assets/task_showcase/tasks/.
pip install flask
python assets/task_showcase/app.py # http://127.0.0.1:5005
To have Webwright produce a renderer-ready task folder at runtime, stack the Task Showcase overlay:
python -m webwright.run.cli \
-c base.yaml -c model_openai.yaml -c task_showcase.yaml \
-t "<repeatable web task>" \
--task-id my_repeatable_task \
-o outputs/default
Note:
report.jsonis only generated when-c task_showcase.yamlis included. A plainbase.yamlrun producestrajectory.jsonand debug artifacts but noreport.json.
The run writes task_showcase/tasks/<short_id>/task.json and report.json
inside the output workspace. Render those generated files without copying them
back into the repo:
python assets/task_showcase/app.py \
--tasks-dir outputs/default/<run>/task_showcase/tasks
Most agent skills are context the model reads. Ours are programs.
webwright.skill_factory distills the script every solve leaves
behind into a growing library of reusable, verified, parameterized skills β code you can run
without a model and compose into the next task instead of re-exploring the site. Plugs in with
no change to the agent loop:
recommend):
route either runs a matching skill directly (no model) or injects it into the prompt as a prior
({verdict: run|adapt|skip, skill_id, source_path}); the agent reuses the hint without ever
querying the library itself.python -m webwright.skill_factory learn outputs/ --library ./library
groups solves of the same template and distills one parameterized skill (build does solveβlearn
in one shot; update is manual-manifest mode).Verified twice before it lands: an input gate keeps a wrong solve from ever feeding a skill, and the distilled skill must replay its own answers standalone β no model β so a broken skill can't poison the library. New solves widen a skill in place, regression-replayed so old coverage can't break.
Once learned, a skill runs standalone in ~40 s with zero tokens. On WebArena (10 retrieve-type
templates, 3 self-hosted sites, gpt-5.4) reuse lifts held-out accuracy 55% β 70% (+15 pp) while
cutting steps. See src/webwright/skill_factory/README.md.
pip install -e .
playwright install chromium
Export credentials for the configured backend (for example, OPENAI_API_KEY
with model_openai.yaml or ANTHROPIC_API_KEY with model_claude.yaml). The
image_qa and self_reflection tools use the same configured model by default,
so an Anthropic run does not require an OpenAI key. Then:
python -m webwright.run.cli \
-c base.yaml -c model_openai.yaml \
-t "Search for flights from SEA to JFK on 2026-08-15 to 2026-08-20" \
--start-url https://www.google.com/flights \
--task-id demo_openai \
-o outputs/default
| Flag | Description |
|---|---|
-c | Config file(s) from src/webwright/config/ (stackable). |
-t | Task instruction. |
--start-url | Initial page. |
--task-id | Output subfolder name. |
-o | Output directory. |
Webwright ships plugin manifests for both Claude Code (.claude-plugin/plugin.json) and OpenAI Codex (.codex-plugin/plugin.json), with the shared skill at skills/webwright/ and slash commands at skills/webwright/commands/. The host agent drives the Webwright loop natively β no extra LLM API key or cost beyond your host subscription. Hosts that read PNG screenshots natively skip the image_qa / self_reflection tools.
Common runtime deps (install once after either path):
pip install -e .
playwright install chromium
Install through the bundled marketplace inside Claude Code:
# 1. Add this repo as a Claude Code plugin marketplace
/plugin marketplace add microsoft/Webwright
# 2. Install the plugin from that marketplace
/plugin install webwright@webwright
Prefer a local checkout? Point the marketplace command at the cloned repo instead:
/plugin marketplace add /absolute/path/to/Webwright
/plugin install webwright@webwright
Start a new Claude Code session after installing β plugins are loaded at session start and won't appear until you restart.
You can either ask Claude Code in plain English (the skill auto-activates from its description), or use one of the slash commands:
/webwright:run search Google Flights for flights from SEA to JFK on 2026-08-15 to 2026-08-20
/webwright:craft search a ticket on Google Flights from LAX to SFO depart June 7 return June 14
/webwright:run (or any plain prompt) produces a one-shot final_script.py for the literal task values./webwright:craft produces a reusable CLI tool: final_script.py becomes one parameterized function with a Google-style Args: docstring and an argparse wrapper whose flags default to the concrete task values, so you can rerun it later with different arguments β e.g. python final_script.py --origin JFK --destination LAX --depart-date 2026-07-01.In both modes Claude Code scaffolds a workspace with plan.md, runs instrumented Playwright scripts under final_runs/run_<id>/, and visually self-verifies each critical point against the saved screenshots.
Codex reads Claude-style marketplaces, so the same repo works as a Codex plugin marketplace. From the Codex CLI:
# 1. Add this repo as a Codex plugin marketplace
codex plugin marketplace add microsoft/Webwright
# 2. Open the plugin browser and install Webwright
codex
/plugins
Prefer a local checkout?
codex plugin marketplace add /absolute/path/to/Webwright
Then restart Codex so the new marketplace and plugin are picked up.
In a new Codex thread, either ask in plain English (the skill auto-activates from its description) or invoke the bundled skill explicitly with @webwright:
@webwright search Google Flights for flights from SEA to JFK on 2026-08-15 to 2026-08-20
Codex scaffolds a workspace with plan.md, runs instrumented Playwright scripts under final_runs/run_<id>/, and visually self-verifies each critical point against the saved screenshots.
To turn the plugin off without uninstalling, set its entry in ~/.codex/config.toml to enabled = false and restart Codex.
Install directly from a local checkout (path, archive, npm spec, git repo, or clawhub: spec all work):
openclaw plugins install /absolute/path/to/Webwright
openclaw gateway restart # reload so the plugin and skill are picked up
Verify:
openclaw plugins list | grep webwright
openclaw skills list | grep webwright # should show "β ready"
The webwright skill is now available to any OpenClaw agent surface (CLI, Telegram, etc.) β invoke it by asking the agent in natural language, or via the slash commands shipped under skills/webwright/commands/, e.g. /webwright run <task>.
To uninstall: openclaw plugins uninstall webwright.
Hermes Agent is a skills-compatible client, so the same skills/webwright/ folder loads as a Hermes skill. Symlink it into your Hermes user-skills directory:
mkdir -p ~/.hermes/skills
ln -sfn /absolute/path/to/Webwright/skills/webwright ~/.hermes/skills/webwright
No Hermes-specific manifest is needed; only SKILL.md is loaded.
Start Hermes (hermes) and ask it to drive a web task in natural language β the skill auto-activates from its description. You can also invoke it explicitly with /webwright.
Note: the named subcommands shipped under skills/webwright/commands/ (/webwright:run, /webwright:craft) are a Claude Code / Codex convention and are inert in Hermes; the skill itself still works end-to-end.
You can run the same tasks using the Webwright harness and its Codex / GitHub Copilot skill variant, and see how token usage and trajectories stack up between different harnesses. The trajectory viewer supports Codex, GitHub Copilot and Webwright harness traces.

cd assets/compare_trajectory/
python3 -m http.server
Open the webpage in your browser and upload the Webwright raw_responses.jsonl and attach trajectory.json to view. Then on the other side you can upload your Codex or GitHub Copilot trace.
ls ~/.codex/sessions/2026/MONTH/DAY/SESSION_ID.jsonl
/export file session
-> session.md is the uploadable trace
| Tokens | Webwright Harness (Local Browser Mode) | Codex Webwright Skill |
|---|---|---|
| Input | 420,433 | 3,271,143 |
| Output | 3,593 | 20,040 |
| Reasoning | 0 | 4,410 |
| Cached | 217,216 | 3,081,3440 |
| Total | 424,026 | 3,291,183 |
Individual runs and results may vary.
If you use Webwright in your research or build on it, please cite this repository:
@misc{webwright2026,
title = {Webwright: A terminal is all you need for web agents},
author = {Lu, Yadong and Xu, Lingrui and Huang, Chao and Awadallah, Ahmed},
year = {2026},
howpublished = {\url{https://github.com/microsoft/Webwright}},
note = {GitHub repository}
}
.claude-plugin/
marketplace.json
plugin.json
.codex-plugin/
plugin.json
.github/
workflows/
skills-tests.yml
.gitignore
assets/
compare_trajectory/
app.js
index.html
styles.css
demo.mp4
odysseys_eval_step100.png
om2w_autoeval_step100.png
skill_factory_demo.mp4
skill_factory_interfaces.png
skill_factory_interfaces.svg
skill_factory_pipeline.png
skill_factory_pipeline.svg
task_showcase/
app.py
README.md
tasks/
austin_apartments/
report.json
task.json
driving_weather/
report.json
task.json
nz_au_legal_jobs/
report.json
task.json
ophelia_pittsburgh/
report.json
task.json
pokemon_tcg/
report.json
task.json
slickdeals/
report.json
task.json
templates/
dashboard.html
task.html
trajectory-compare.png
webwright_logo.svg
CODE_OF_CONDUCT.md
docs/
skill_factory/
manual.md
reference.md
LICENSE
pyproject.toml
README.md
SECURITY.md
skills/
webwright/
commands/
craft.md
run.md
reference/
cli_tool_mode.md
playwright_patterns.md
workflow.md
SKILL.md
src/
webwright/
__init__.py
agents/
__init__.py
default.py
config/
__init__.py
base.yaml
crafted_cli.yaml
local_browser.yaml
model_claude.yaml
model_openai.yaml
model_openrouter.yaml
persistent_browser.yaml
task_showcase.yaml
environments/
__init__.py
local_browser.py
local_workspace.py
exceptions.py
models/
__init__.py
anthropic_model.py
base.py
openai_model.py
openrouter_model.py
run/
__init__.py
cli.py
doctor.py
run_command.sh
skill_factory/
__init__.py
__main__.py
build.py
decide.py
entry_shim.py
examples/
batch.example.json
flights.skill.yaml
learned_library/
what_is_the_earliest_nonstop_flight_from_2c8dab1/
meta.json
replays.json
skill.py
model_gateway.example.yaml
README.md
solve_with_library.sh
tasks.example.json
trajectories/
lax_ord/
agent_response.json
final_script.py
task.json
README.md
sea_jfk/
agent_response.json
final_script.py
task.json
sfo_bos/
agent_response.json
final_script.py
task.json
execute.py
fill.py
gate.py
init.py
learn.py
library.py
llm.py
prompt.py
README.md
retrieve.py
route.py
update.py
tools/
__init__.py
_model_config.py
image_qa.py
persistent_local_browser.py
self_reflection.py
skill_use.py
utils/
__init__.py
logging.py
runtime.py
serialize.py
SUPPORT.md
tests/
conftest.py
skill_factory/
test_build_init.py
test_entry_shim.py
test_evolve.py
test_execute.py
test_fill.py
test_gate.py
test_learn.py
test_learned_example.py
test_library.py
test_llm_env.py
test_recommend.py
test_retrieve_decide.py
test_route.py
unit/
test_doctor.py
test_tool_model_routing.pyA GitHub Copilot, Claude Code, and OpenAI Codex plugin for building native Windows apps with WinUI 3 and the Windows App SDK to cover the end-to-end inner loop: scaffold β design β build β run β test β package β ship.
Official agent skills/plugins for Power Platform development by Microsoft.
Train agent skills like you train neural networks β with epochs, (mini-)batchsize, learning rates, and validation gates β but without touching model weights.
FAQ
webwright is a Claude Code plugin with 1 hand-picked skill for automation work, indexed on Flowy. Install it with the command on its page. It includes webwright. Its skills do not fire on their own yet. Request auto-invocation to have Flowy route them as you prompt. Free and open source.