Skills for coding agents
Teach Claude Code, Cursor, Codex and other coding agents to write correct KMPwright code with llms.txt, Markdown pages and the kmpwright skill file.
This page is about agents that write KMPwright code for you, not agents that drive a page at runtime (for those, see Build an agent). Coding agents know Playwright well and will guess Playwright-for-JavaScript signatures. Give them the KMPwright docs and they write Kotlin that compiles.
Docs in Markdown
Every docs page is available as Markdown, built from the same source as the HTML.
| URL | Content |
|---|---|
/llms.txt | Index of every page with its title, URL and description |
/llms-full.txt | Every page's Markdown in one file |
/docs/<page>.md | One page as Markdown, for example /docs/agents/commands.md |
/docs/<page> with Accept: text/markdown | The same Markdown, chosen by content negotiation |
curl https://kmpwright.vercel.app/docs/agents/snapshots.md
curl -H 'Accept: text/markdown' https://kmpwright.vercel.app/docs/agents/snapshotsOn each page, Copy Markdown (under the title) copies the page for pasting into a chat. The menu next to it can view the Markdown or open the page in ChatGPT, Claude, Cursor or Scira.
Ways to use them:
- Paste
https://kmpwright.vercel.app/llms-full.txtinto a chat, or ask the agent to fetch it, before a larger task. - Point the agent at the one page it needs (
…/docs/agents/commands.md) to save context. - Reference
llms.txtfrom your project instructions (CLAUDE.md,AGENTS.md,.cursor/rules) so the agent knows where to look.
The kmpwright skill
The repository ships a skill file at skills/kmpwright/SKILL.md. It is a short, self-contained brief: install, how to get a Page on each platform, the most-used calls, the snapshot-and-ref agent loop, the gotchas that trip agents up (main thread, suspend, timeoutMs = null, per-backend capabilities, ref lifetime), and links to these pages.
It uses the Claude skill format: a folder with a SKILL.md whose YAML frontmatter has a name and a description that tells the agent when to load it.
---
name: kmpwright
description: Write Kotlin code that automates web pages with KMPwright … Use when a project
depends on kmpwright-core or kmpwright-compose, when the user wants to automate or test an
in-app WebView from Kotlin, or when building an LLM agent that drives a WebView …
---Install for Claude Code
Claude Code loads skills from .claude/skills/<name>/SKILL.md in your project, or from ~/.claude/skills/<name>/SKILL.md for every project.
mkdir -p .claude/skills/kmpwright
curl -fsSL https://raw.githubusercontent.com/bernaferrari/kmpwright/main/skills/kmpwright/SKILL.md \
-o .claude/skills/kmpwright/SKILL.mdCommit it so everyone working on the project gets it.
Claude Code reads the description and loads the skill when a task matches, for example "add a test that fills the signup form in our WebView".
Other agents
The file is plain Markdown, so any agent can use it.
| Agent | How |
|---|---|
| Agents with skill support | Copy the kmpwright folder into the directory your agent loads skills from |
| Cursor | Save the body as a project rule under .cursor/rules/, or reference the file from an existing rule |
Codex and other AGENTS.md readers | Add a line to AGENTS.md: "For KMPwright code, read skills/kmpwright/SKILL.md and https://kmpwright.vercel.app/llms.txt" |
| Any chat | Paste the file, or its raw GitHub URL, at the start of the conversation |
Keep the copy up to date with the KMPwright version you depend on; the API is pre-1.0 and names can change between releases.
What to tell the agent
Whichever mechanism you use, these points prevent most mistakes:
- The package is
com.bernaferrari.kmpwright.core, and every page and locator method issuspend. - Names follow Playwright (
goto,goBack,getByRole,pressSequentially,waitForSelector), but options are Kotlin named arguments (click(force = true)), not JavaScript option objects. timeoutMs = nulluses the configured default (TimeoutConfig), it does not disable the timeout.- Some features depend on the backend; check
page.capabilities()(see Capabilities). - For agents that drive pages, refs such as
@e3come from the latestsnapshot()and must be refreshed after the page changes (see Snapshots and refs).