Agent skill
@extension.dev/skill gives a coding agent judgment for extension work: when to reach for which tool, the cross-browser rules, the silent-failure gotchas and the publish checklist. Reach for it beside the MCP server, which gives the agent hands. The package ships one skill in the open Agent Skills format, plain markdown with no login and no network, so any agent that reads the format can use it.
Quick start
npx skills add extensiondev/skillThe command installs the skill into every agent it finds on your machine. Add -g for user scope instead of project scope, or -a claude-code (or -a cursor, -a copilot) to target one agent.
Install
Every path installs the same skill. Pick the one that fits your setup.
Claude Code, through the plugin marketplace:
/plugin marketplace add extensiondev/skill
/plugin install extension-dev@extensiondevGitHub CLI:
gh skill install extensiondev/skill extension-devnpm, version locked to your dependency tree. The package declares the agents.skills field, so skills-aware installers link it into your agents on install. The manual fallback is a copy:
npm i -D @extension.dev/skill
cp -R node_modules/@extension.dev/skill/skills/extension-dev .claude/skills/Agents without skills support take one line in AGENTS.md or CLAUDE.md:
For any browser-extension work, read .agents/skills/extension-dev/SKILL.md before writing code.Your first prompt
Create a browser extension that highlights every external link on a page.
It must work on Chrome and Firefox from a single codebase, and I want proof
it actually injects: inspect the live browser, do not just tell me it works.A skill-equipped agent scaffolds from a template, writes one prefixed manifest instead of two, and verifies injection against the live browser instead of declaring victory.
How it works
SKILL.md carries the trigger metadata, a seven step workflow and the core rules. The steps name the CLI command beside the MCP tool wherever one exists, so the skill works without the server and does more with it. The workflow:
- Start from a template, or migrate an existing build.
- Treat
manifest.jsonas the source of truth. - Write cross-browser by default with
chromium:andfirefox:prefixes. - Develop with feedback, never faith, by reading logs and the live DOM.
- Build and verify per browser, then stop the session.
- Show someone the build as a link, not a file.
- Keep publish and submit apart.
The skill is @extension.dev/skill 1.2.1. SKILL.md is 339 lines and always loads when the skill triggers; the agent then reads only the reference file that matches the task. The 14 references:
| File | Title | Read when | Lines |
|---|---|---|---|
templates.md | Template Catalog | Choosing a starting point, learning a pattern from a working example | 115 |
project-structure.md | Project Structure and File Patterns | Creating or reorganizing project files, HTML/mount patterns, config | 228 |
cross-browser.md | Cross-Browser Rules | Anything touching Firefox, manifest prefixes, API namespace choices | 244 |
api-gotchas.md | Runtime API Gotchas | Service worker, permissions, tabs, messaging, or runtime API bugs | 108 |
debugging.md | Debugging: Eyes on the Live Browser | The extension misbehaves and you need eyes on the live browser | 261 |
publishing.md | Building and Publishing | Building zips, store accounts and credentials, listings, publishing | 414 |
store-md.md | STORE.md: One Store Metadata File for Every Store | Creating or updating STORE.md, store metadata, reviewer notes, rejections | 138 |
migrating.md | Migrating an Existing Extension | Bringing an existing webpack, Vite, gulp or pug extension under the engine | 73 |
surface-popup.md | Surface: toolbar popup | The extension's main surface is a toolbar popup (action) | 45 |
surface-content.md | Surface: content script | The extension changes or reads web pages (content_scripts) | 60 |
surface-sidepanel.md | Surface: side panel | The extension's main surface is a side panel or sidebar | 53 |
surface-devtools.md | Surface: DevTools panel | The extension adds a DevTools panel (devtools_page) | 50 |
surface-newtab.md | Surface: new tab page | The extension overrides the new tab page | 45 |
surface-options.md | Surface: options page | The extension has an options page (options_ui) | 42 |
The budget follows the Agent Skills guidance: the frontmatter costs about a hundred tokens at every turn, the body loads only when the skill triggers, and a reference loads only when its row above matches the task.
How the skill is checked
The package ships 7 graded tasks under evals/, each a prompt, the files it starts from, the expected outcome and the assertions a grader checks:
| Task | The prompt starts |
|---|---|
cross-browser-sidebar | Create a browser extension project called notes-panel that shows a sidebar with a simple notes textarea that persists between sessions. |
injection-debugging | I'm building a browser extension with extension.dev. |
service-worker-state | Here is my extension's background service worker and manifest (in the input directory). |
store-readiness | My Quote Keeper extension (in the input directory) is ready for users. |
migrate-entrypoints | This browser extension (in the input directory) builds with a toolchain I want to leave. |
migrate-file-conventions | This browser extension (in the input directory) builds with a toolchain I want to leave. |
share-builds-extension-dev-first | I built a cross-browser content-script extension for Chrome, Edge and Firefox and it works locally. |
In the shipped benchmark the first three tasks were run with identical prompts: the skill run passed 15 of 15 graded assertions against 10 of 15 for a no-skill baseline, and the fourth task was run later as a single sample at 5 of 5 against 4 of 5. The harness, fixtures and assertion sets ship in the package, so the numbers are reproducible.
Four test suites and a spec check keep the words true. skill-structure validates frontmatter, reference links, the progressive disclosure line budget, version sync across the plugin manifests and copy conventions. conventions-sync asserts the documented conventions against an Extension.js checkout. mcp-sync asserts the stated tool count, every extension_* name, and the CLI command and flag parity against the MCP package. templates-sync asserts every template slug the skill recommends against the nightly template catalog. skills-ref validate checks the skill against the open specification.
When Extension.js changes a documented convention, the sync test fails and names the reference file to update. The cross-browser reference carries a "verified against Extension.js x.y.z" pin that is bumped on re-verification.
npm test
npx skills-ref validate skills/extension-devThe skill in action
Asked about a content script that never shows up, with no error anywhere, a skill-equipped agent reads the debugging reference and lays out the evidence order before touching code:
My content script never shows up on example.com and there are no errors.
Where do I start?Reference
Extensions fail quietly: a content script that never injects, a panel that never opens, a permission that returns undefined with no error. An agent with tools but no judgment calls them, reads a plausible result, and moves on.
| Package | Supplies |
|---|---|
@extension.dev/mcp | The verbs: scaffold, run, inspect, act, ship |
@extension.dev/skill | The rules: what to check, in what order, and when a result is a lie |
Pair them in one line:
claude mcp add extension-dev npx @extension.dev/mcpCross-browser covers text too. For popup text that follows the browser language, start from the Action Locales template.
When it fails
- The skill never triggers: confirm it landed in
.claude/skills/extension-devor your agent's skills directory. Agents without skills support need the one line inAGENTS.mdabove. npm ilinked nothing: your installer is not skills aware. Use the manual copy above.- A sync test fails after an Extension.js release: the failure names the reference file. Update it and bump its pin.
Next
- MCP server for the tools it directs
- CLI for the command line path it documents
- Pair with Chrome DevTools MCP for the second server it knows about