@extension.dev/mcp 4.9.0 → 5.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/CHANGELOG.md +172 -22
- package/README.md +3 -3
- package/claude/ARCHITECTURE.md +2 -2
- package/claude/CLAUDE.md +15 -15
- package/claude/README.md +8 -8
- package/claude/commands/extension-add.md +10 -10
- package/claude/commands/extension-debug.md +10 -10
- package/claude/commands/extension.md +8 -8
- package/claude/examples/add-sidebar.md +2 -2
- package/claude/examples/create-extension.md +2 -2
- package/claude/rules/cross-browser.md +1 -1
- package/claude/rules/extension-dev.md +12 -12
- package/claude/rules/mcp-tools.md +45 -45
- package/dist/module.js +1071 -353
- package/dist/src/lib/exec.d.ts +6 -1
- package/dist/src/lib/session-browser.d.ts +7 -1
- package/dist/src/lib/types.d.ts +3 -1
- package/dist/src/tools/build.d.ts +6 -0
- package/dist/src/tools/deploy.d.ts +1 -0
- package/dist/src/tools/doctor.d.ts +1 -0
- package/dist/src/tools/dom-inspect.d.ts +13 -2
- package/dist/src/tools/open.d.ts +11 -0
- package/package.json +6 -4
- package/server.json +2 -2
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"name": "extension-mcp",
|
|
11
11
|
"source": "./",
|
|
12
12
|
"description": "MCP tools for browser extension development: scaffold from 60+ templates, run the dev server with HMR, inspect the live DOM and logs, and publish store-ready builds for Chrome, Edge, and Firefox.",
|
|
13
|
-
"version": "
|
|
13
|
+
"version": "5.1.1",
|
|
14
14
|
"category": "development",
|
|
15
15
|
"author": {
|
|
16
16
|
"name": "Cezar Augusto"
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "extension-mcp",
|
|
3
3
|
"description": "MCP tools for browser extension development: scaffold from 60+ templates, run the dev server with HMR, inspect the live DOM and logs, and publish store-ready builds for Chrome, Edge, and Firefox. Ships /extension, /extension-add, /extension-debug, and /extension-publish commands.",
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "5.1.1",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Cezar Augusto",
|
|
7
7
|
"email": "boss@cezaraugusto.net",
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,155 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 5.1.1
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- `extension_deploy` warns when a Firefox or Edge submission ships without
|
|
8
|
+
the STORE.md notes the platform submits automatically (Firefox reviewer
|
|
9
|
+
and release notes, Edge certification notes). The warnings ride along in
|
|
10
|
+
the result as `warnings` and never block the submission; Chrome-only
|
|
11
|
+
submissions stay silent.
|
|
12
|
+
|
|
13
|
+
## 5.1.0
|
|
14
|
+
|
|
15
|
+
The engine closed its entire open bug range (Extension.js 61-73) in the
|
|
16
|
+
4.0.14 canary line. This release re-aligns the MCP with the fixed engine,
|
|
17
|
+
finishes the MCP-side half of those bugs, and continues the
|
|
18
|
+
report-failure-not-false-success program that 5.0.0 started. 5.0.0 was never
|
|
19
|
+
published to npm; installing 5.1.0 picks up both.
|
|
20
|
+
|
|
21
|
+
### Fixed
|
|
22
|
+
|
|
23
|
+
- **Sessions now genuinely survive the MCP process.** `detached: true` alone
|
|
24
|
+
never did it: the child held pipes to the MCP, so when the MCP exited the
|
|
25
|
+
next compile log line killed the dev server with EPIPE. Launch tools
|
|
26
|
+
(`extension_dev`/`start`/`preview`) now stream the child's output to a
|
|
27
|
+
session log file (returned as `logPath`) instead of pipes. A detached
|
|
28
|
+
session outlives the MCP and a fresh MCP process rediscovers it through
|
|
29
|
+
`ready.json` and can stop it. Pinned by a detach-contract test.
|
|
30
|
+
- **`extension_preview` no longer reports `launched` for a process that died
|
|
31
|
+
in seconds.** It health-checks the child like `dev`/`start` (the MCP half of
|
|
32
|
+
engine bug 72), and all three launch tools read the engine's new
|
|
33
|
+
`browser_exited` stamp, so a browser that dies after launch (for example a
|
|
34
|
+
rejected add-on) returns `status:"browser-exited"` instead of success.
|
|
35
|
+
- **`extension_doctor` names a dead browser.** A `browser_exited` ready
|
|
36
|
+
contract now produces a runtime-errors failure that says the browser died,
|
|
37
|
+
with the matching remedy, instead of the generic "fix the build error"
|
|
38
|
+
wording that pointed at a build that was fine.
|
|
39
|
+
- **`extension_create` verifies the scaffold.** A resolved create over a
|
|
40
|
+
partial tree (an interrupted template download) returned `nextSteps`
|
|
41
|
+
pointing at a project that could not compile. It now checks the manifest
|
|
42
|
+
exists and returns `status:"incomplete"` when it does not.
|
|
43
|
+
- **`extension_manifest_validate` is per-target honest.** `chromium:`/
|
|
44
|
+
`firefox:` prefixed keys resolve per target, `edge` joins the default
|
|
45
|
+
matrix, `manifest_version` must be 2 or 3, a `default_locale` without its
|
|
46
|
+
`_locales` catalog blocks, and a missing 128px store icon warns
|
|
47
|
+
(`extension_inspect` reports `has128Icon`).
|
|
48
|
+
- **Stale state stops being served as live.** `extension_logs` stamps
|
|
49
|
+
`stale:true` when the producing session is dead or from a different run;
|
|
50
|
+
`extension_wait` returns `runtimeErrors` alongside ready instead of a bare
|
|
51
|
+
green over a crashing worker; `extension_build` reports
|
|
52
|
+
`productionDivergence` when the production manifest lost permissions or
|
|
53
|
+
resources relative to source.
|
|
54
|
+
- **`extension_open`'s `asTab` fallback fires on the user-gesture wall**, and
|
|
55
|
+
`extension_storage` set without a `key` answers in MCP vocabulary rather
|
|
56
|
+
than CLI flags.
|
|
57
|
+
|
|
58
|
+
### Added
|
|
59
|
+
|
|
60
|
+
- **Structured bundler warnings on `extension_build`.** The engine now
|
|
61
|
+
persists its build summary to `dist/extension-js/<browser>/
|
|
62
|
+
build-summary.json` (the transport half of engine bug 73), and the tool
|
|
63
|
+
returns it as `buildWarnings` (with `buildWarningsTruncated` naming the
|
|
64
|
+
true count when the engine capped the list). Older engines simply omit the
|
|
65
|
+
field; nothing is scraped from stdout.
|
|
66
|
+
- **Popup-faithful headless rendering.** A popup rendered as a tab is now
|
|
67
|
+
sized like the real popup: the document's content size is measured over
|
|
68
|
+
CDP, clamped to Chrome's 25x25-800x600 popup bounds, and the window is
|
|
69
|
+
resized to it (reported as `renderedAsTab.popupBounds`). If the browser
|
|
70
|
+
does not verifiably honor the resize, the tool keeps saying "no popup
|
|
71
|
+
sizing" instead of implying fidelity. Note headless-new is one such
|
|
72
|
+
browser: it accepts `Browser.setWindowBounds` and changes nothing, so
|
|
73
|
+
headless sessions get the honest fallback, not a resized window. The
|
|
74
|
+
measurement also leaves `body`'s authored width alone; only the root takes
|
|
75
|
+
the temporary fit-content override, so a popup that sizes itself through
|
|
76
|
+
`body { width }` measures at its real width.
|
|
77
|
+
- **CI typechecks the tests.** `pnpm typecheck` covers `src/` and the test
|
|
78
|
+
tsconfig, wired into the CI matrix, so type drift between tools and their
|
|
79
|
+
tests cannot accumulate silently again.
|
|
80
|
+
|
|
81
|
+
### Changed
|
|
82
|
+
|
|
83
|
+
- **Tool prose caught up with the fixed engine.** `extension_eval` and
|
|
84
|
+
`extension_dom_inspect` now advertise the surface contexts
|
|
85
|
+
(`popup`/`options`/`sidebar`/`devtools`) and override pages
|
|
86
|
+
(`newtab`/`history`/`bookmarks`) the engine's relay serves, needing no tab
|
|
87
|
+
id. The "content eval is known-broken" guard is version-honest: on
|
|
88
|
+
Extension.js >= 4.0.14 a null is the expression's real result, and the note
|
|
89
|
+
says so instead of condemning a repaired path. Firefox hints name every
|
|
90
|
+
working route.
|
|
91
|
+
|
|
92
|
+
A pass focused on a single question: when something has gone wrong, does the
|
|
93
|
+
tool say so? Five tools were reporting success over a failure. All five now
|
|
94
|
+
verify before they claim anything.
|
|
95
|
+
|
|
96
|
+
### Breaking
|
|
97
|
+
|
|
98
|
+
- **`extension_build` refuses a broken build.** It runs the
|
|
99
|
+
`extension_manifest_validate` checks as a preflight and returns
|
|
100
|
+
`status:"blocked"` on build-blocking errors instead of shelling out to a build
|
|
101
|
+
it knows is broken. Pass `skipValidation: true` for the old behavior. It also
|
|
102
|
+
returns `success:false` with `status:"incomplete"` when the bundler exits 0 but
|
|
103
|
+
a declared entrypoint never reached `dist/`, because the browser refuses to
|
|
104
|
+
load that artifact. Non-blocking findings ride along as `manifestWarnings`.
|
|
105
|
+
- **Browser resolution defaults to `chrome`, not `chromium`.** A dead session
|
|
106
|
+
used to fall through to a blind default, so every call after a dev server
|
|
107
|
+
exited silently retargeted a browser the caller never ran. A dead session now
|
|
108
|
+
resolves to its own browser with `source:"stale"`.
|
|
109
|
+
- **`extension_open` renames `tab` to `target`.** The value is a CDP target id,
|
|
110
|
+
not a `chrome.tabs` id, and the old name invited callers to pass it straight
|
|
111
|
+
into tools that need a numeric tab id.
|
|
112
|
+
|
|
113
|
+
### Fixed
|
|
114
|
+
|
|
115
|
+
- **`extension_doctor` no longer reports `healthy:true` over a crashing
|
|
116
|
+
extension.** Its runtime-error check read the wrong field, so every error row
|
|
117
|
+
in `logs.ndjson` collapsed to an empty string and was skipped. It now reads the
|
|
118
|
+
engine's `messageParts` payload, with an `errorName`/`stack` fallback, and
|
|
119
|
+
collapses a throw that repeats on every event.
|
|
120
|
+
- **`extension_dev` and `extension_start` no longer report `status:"started"`
|
|
121
|
+
for a server that already exited.** Both health-check the child process and
|
|
122
|
+
return `status:"exited"` with the exit code, signal, and the child's own output
|
|
123
|
+
as evidence.
|
|
124
|
+
- **`extension_open` no longer reports success for a navigation that failed.**
|
|
125
|
+
Navigating to a `chrome-extension://` origin is cross process and swaps the
|
|
126
|
+
render frame, so the pre-navigation session reported a stale error URL on
|
|
127
|
+
success and success on failure. It now confirms against a fresh target list.
|
|
128
|
+
This affected the `url` navigation path shipped in 4.9.0, not only the new
|
|
129
|
+
surface rendering.
|
|
130
|
+
- **`extension_open` targets the right extension.** A dev session also loads
|
|
131
|
+
Extension.js's own manager extension, and taking the first extension target
|
|
132
|
+
navigated against the wrong origin. The id is now derived from the dist path
|
|
133
|
+
the session actually loaded.
|
|
134
|
+
|
|
135
|
+
### Added
|
|
136
|
+
|
|
137
|
+
- **Headless surface rendering.** `extension_open` accepts `asTab` for
|
|
138
|
+
`popup`/`options`/`sidebar`, rendering the surface document in a real tab so it
|
|
139
|
+
can be inspected where no window exists to host a popup. It is applied
|
|
140
|
+
automatically when a headless session refuses to open the surface, with a note
|
|
141
|
+
saying what was substituted.
|
|
142
|
+
- **Tab targeting by url.** `extension_eval` and `extension_dom_inspect` take a
|
|
143
|
+
`url` and otherwise default to the active tab, and `extension_dom_inspect`
|
|
144
|
+
gains `listTabs` for discovery. The engine gained this in 4.0.13; the tool
|
|
145
|
+
descriptions had been telling callers a numeric tab id was required.
|
|
146
|
+
- **Friendlier arguments.** `timeoutMs`, `lines`, `tabId`, `href` and
|
|
147
|
+
`browserName` fold onto their canonical names, `withConsole` accepts `true`,
|
|
148
|
+
and the input validator understands union types.
|
|
149
|
+
- **`extension_create` matches your package manager.** Hints and the engine
|
|
150
|
+
warning now use bun, pnpm or yarn when that is what the scaffold used, and the
|
|
151
|
+
warning reads the pin the scaffold actually wrote.
|
|
152
|
+
|
|
3
153
|
## 4.9.0
|
|
4
154
|
|
|
5
155
|
A second pass from the persona swarm, closing the gaps 4.8.0 left and the top
|
|
@@ -7,13 +157,13 @@ new blockers it surfaced.
|
|
|
7
157
|
|
|
8
158
|
- **Honest `extension_manifest_validate`.** It now scans the project source for
|
|
9
159
|
permission-gated `chrome.*`/`browser.*` calls and flags any the manifest does
|
|
10
|
-
not declare
|
|
160
|
+
not declare, an API used without its permission is `undefined` at runtime and
|
|
11
161
|
crashes the context, the exact case where validate used to report `valid:true`.
|
|
12
162
|
The headline is now honest (`valid:false` + `buildBlocking:true` on any error),
|
|
13
163
|
and it accepts singular `browser` as an alias for `browsers`.
|
|
14
164
|
- **`extension_open` can navigate a tab.** Pass a `url` (Chromium, via CDP) to
|
|
15
165
|
drive a content-script test page, a `webNavigation` target, or the popup as a
|
|
16
|
-
page (`chrome-extension://<id>/popup.html`)
|
|
166
|
+
page (`chrome-extension://<id>/popup.html`), the loop the surface-only open
|
|
17
167
|
could not do. `target` is accepted as an alias for `surface`.
|
|
18
168
|
- **`extension_stop` actually reaps the session.** It now terminates the dev CLI
|
|
19
169
|
and both browser families (gecko profile + chromium `--load-extension`, under
|
|
@@ -184,12 +334,12 @@ that removed nearly all friction a real MCP client hit.
|
|
|
184
334
|
--browser=chromium --allow-control` `` becomes `extension_dev with
|
|
185
335
|
{ browser: "chromium", allowControl: true }`, and stray
|
|
186
336
|
`--allow-control` / `--allow-eval` / `--browser=<x>` mentions become
|
|
187
|
-
their tool-argument names. Result data is never touched
|
|
337
|
+
their tool-argument names. Result data is never touched, only
|
|
188
338
|
error/hint prose. Tool descriptions now name `allowControl` /
|
|
189
339
|
`allowEval` directly, so agents no longer discover the gates by
|
|
190
340
|
fuzzing the schema.
|
|
191
341
|
- The no-channel error now names the session that IS running ("Active
|
|
192
|
-
session browser(s) for this project: chrome
|
|
342
|
+
session browser(s) for this project: chrome, pass that as `browser`"),
|
|
193
343
|
so an agent retargets instead of spawning a second, conflicting
|
|
194
344
|
session. Same for the `extension_logs` follow miss.
|
|
195
345
|
- `extension_list_extensions` / `extension_source_inspect` accept
|
|
@@ -225,7 +375,7 @@ Session lifecycle + determinism release. Tool count 27 -> 28.
|
|
|
225
375
|
- CLI spawns are deterministic: dev/start/preview and the act tools now
|
|
226
376
|
prefer the project's own `node_modules/.bin/extension`, falling back to
|
|
227
377
|
`npx extension@<pinned>` where the pin derives from the vendored
|
|
228
|
-
`extension-develop` version
|
|
378
|
+
`extension-develop` version, never a floating `latest`.
|
|
229
379
|
- Session registry keys are path-normalized, so a stop with an absolute
|
|
230
380
|
path matches a session registered with a relative one.
|
|
231
381
|
- Tests: registry suite now asserts against the exported `tools` array
|
|
@@ -300,9 +450,9 @@ this release graduates that line to stable and becomes `latest`.
|
|
|
300
450
|
@extension.dev/skill pairing.
|
|
301
451
|
- MIT license shipped; repository moved to extensiondev/mcp.
|
|
302
452
|
|
|
303
|
-
# @extension.dev/mcp
|
|
453
|
+
# @extension.dev/mcp, Changelog
|
|
304
454
|
|
|
305
|
-
## Unreleased
|
|
455
|
+
## Unreleased, agent-bridge tools
|
|
306
456
|
|
|
307
457
|
Adds the MCP client surface for the Extension.js **agent bridge** (dev-time
|
|
308
458
|
observe + act + inspect). All new tools shell out to the `extension` CLI verbs
|
|
@@ -312,32 +462,32 @@ a recent **`extension` CLI that ships the bridge verbs** (`logs`, `eval`,
|
|
|
312
462
|
|
|
313
463
|
> ⚠️ **Release order:** publish this package ONLY after the `extension` /
|
|
314
464
|
> `extension-develop` suite that ships those verbs is on npm. The published CLI
|
|
315
|
-
> at the time of writing (`3.17.0`) does NOT have them
|
|
465
|
+
> at the time of writing (`3.17.0`) does NOT have them, publishing this package
|
|
316
466
|
> before the suite would ship tools that fail with "unknown command". Bump the
|
|
317
467
|
> version + `extension-*` deps to that suite release, then publish.
|
|
318
468
|
|
|
319
469
|
New tools (22 total):
|
|
320
470
|
|
|
321
|
-
- **`extension_logs
|
|
471
|
+
- **`extension_logs`**, read/stream logs from every extension context
|
|
322
472
|
(background, content, popup/options/sidebar/devtools); filters
|
|
323
473
|
`level`/`context`/`url`/`tab`/`since`, bounded `follow` window.
|
|
324
|
-
- **`extension_eval
|
|
474
|
+
- **`extension_eval`**, evaluate an expression in a context (requires the dev
|
|
325
475
|
session started with `--allow-eval`; MV3 service worker is CSP-gated).
|
|
326
|
-
- **`extension_storage
|
|
327
|
-
- **`extension_reload
|
|
328
|
-
- **`extension_open
|
|
329
|
-
- **`extension_dom_inspect
|
|
476
|
+
- **`extension_storage`**, read/write `chrome.storage` (requires `--allow-control`).
|
|
477
|
+
- **`extension_reload`**, reload the extension or a tab (`--allow-control`).
|
|
478
|
+
- **`extension_open`**, open popup/options/sidebar (`--allow-control`).
|
|
479
|
+
- **`extension_dom_inspect`**, CDP-free DOM snapshot of content/page or an open
|
|
330
480
|
surface (popup/options/sidebar/devtools); `withConsole` merges recent logs.
|
|
331
|
-
- **`extension_publish
|
|
481
|
+
- **`extension_publish`**, publish to extension.dev and return a shareable URL
|
|
332
482
|
(auth-gated; requires `EXTENSION_DEV_TOKEN`).
|
|
333
|
-
- **`extension_source_inspect`** gains **`deepDom
|
|
483
|
+
- **`extension_source_inspect`** gains **`deepDom`**, pierce CLOSED shadow roots
|
|
334
484
|
via CDP (Chromium only).
|
|
335
485
|
|
|
336
486
|
Internal: `lib/act` (CLI shell-out helper), `lib/exec.runExtensionCli` (capture),
|
|
337
487
|
`lib/cdp.getClosedShadowRoots`. Test infra aligned to the workspace vitest
|
|
338
488
|
catalog.
|
|
339
489
|
|
|
340
|
-
## Unreleased
|
|
490
|
+
## Unreleased, login (auth tools)
|
|
341
491
|
|
|
342
492
|
Adds the missing `login` flow so `extension_publish` no longer requires the user
|
|
343
493
|
to mint and export `EXTENSION_DEV_TOKEN` by hand. Auth stays auth-AWARE: the
|
|
@@ -345,13 +495,13 @@ token lives in a local credentials file, never in the MCP process state or logs.
|
|
|
345
495
|
|
|
346
496
|
New tools (25 total):
|
|
347
497
|
|
|
348
|
-
- **`extension_login
|
|
498
|
+
- **`extension_login`**, GitHub **device-code** flow (no local server; works
|
|
349
499
|
headless). Two-phase: call with `project` (`<workspace>/<project>`) to get a
|
|
350
500
|
code + URL, call again with the returned `deviceCode` to finish. On success it
|
|
351
501
|
writes a project-scoped token to the credentials file. Never returns the token.
|
|
352
|
-
- **`extension_whoami
|
|
502
|
+
- **`extension_whoami`**, report the stored workspace/project and token expiry
|
|
353
503
|
without revealing the token.
|
|
354
|
-
- **`extension_logout
|
|
504
|
+
- **`extension_logout`**, delete the local credentials file.
|
|
355
505
|
|
|
356
506
|
Token resolution for publish is now `EXTENSION_DEV_TOKEN` env **>** the
|
|
357
507
|
credentials file (expired file tokens are ignored).
|
|
@@ -361,8 +511,8 @@ Credentials file (versioned, `0600`): `$XDG_CONFIG_HOME/extension-dev/auth.json`
|
|
|
361
511
|
|
|
362
512
|
Platform endpoints this depends on (in `apps/www.extension.dev`):
|
|
363
513
|
|
|
364
|
-
- `GET /api/cli/login/config
|
|
365
|
-
- `POST /api/cli/login/exchange
|
|
514
|
+
- `GET /api/cli/login/config`, public GitHub OAuth client id + scope.
|
|
515
|
+
- `POST /api/cli/login/exchange`, trades a GitHub **user** token for a
|
|
366
516
|
project-scoped access token after checking workspace membership. Modeled on
|
|
367
517
|
`/api/oidc/exchange`; tokens are recorded so they stay revocable.
|
|
368
518
|
|
package/README.md
CHANGED
|
@@ -41,7 +41,7 @@ Built on [Extension.js](https://extension.js.org), the open-source cross-browser
|
|
|
41
41
|
claude mcp add extension-dev npx @extension.dev/mcp
|
|
42
42
|
```
|
|
43
43
|
|
|
44
|
-
Or install it as a plugin
|
|
44
|
+
Or install it as a plugin, the MCP server plus the `/extension`, `/extension-add`, `/extension-debug`, and `/extension-publish` commands in one step:
|
|
45
45
|
|
|
46
46
|
```
|
|
47
47
|
/plugin marketplace add extensiondev/mcp
|
|
@@ -123,11 +123,11 @@ cp node_modules/@extension.dev/mcp/claude/commands/*.md ~/my-extension/.claude/c
|
|
|
123
123
|
| platform | `extension_release_promote` | Promote a build to a release channel, headless |
|
|
124
124
|
| platform | `extension_deploy` | Submit to the Chrome, Firefox, and Edge stores through extension.dev |
|
|
125
125
|
|
|
126
|
-
Browser-launching tools (`dev`, `start`, `preview`) shell out to the `extension` CLI
|
|
126
|
+
Browser-launching tools (`dev`, `start`, `preview`) shell out to the `extension` CLI, the project's own `node_modules/.bin/extension` when present, otherwise `npx extension@<pinned>` at the version this package is verified against; everything else runs in-process.
|
|
127
127
|
|
|
128
128
|
## From preview to store
|
|
129
129
|
|
|
130
|
-
The platform tools connect agents to [extension.dev](https://extension.dev): `extension_login` runs a GitHub device-code flow and stores a project-scoped token locally (never returned to the agent), `extension_publish` turns a build into a shareable preview URL, and `extension_release_promote` promotes a tested build to a release channel from CI or an agent session, no browser required. `extension_deploy` submits a built extension to the Chrome Web Store, Edge Add-ons, and Firefox AMO through extension.dev, which holds your store credentials and dispatches the release from your project's mirror CI
|
|
130
|
+
The platform tools connect agents to [extension.dev](https://extension.dev): `extension_login` runs a GitHub device-code flow and stores a project-scoped token locally (never returned to the agent), `extension_publish` turns a build into a shareable preview URL, and `extension_release_promote` promotes a tested build to a release channel from CI or an agent session, no browser required. `extension_deploy` submits a built extension to the Chrome Web Store, Edge Add-ons, and Firefox AMO through extension.dev, which holds your store credentials and dispatches the release from your project's mirror CI, it defaults to a dry run and store credentials are never tool arguments.
|
|
131
131
|
|
|
132
132
|
## The extension.dev stack
|
|
133
133
|
|
package/claude/ARCHITECTURE.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# How the pieces connect
|
|
2
2
|
|
|
3
|
-
This document explains how the three Claude integration layers
|
|
3
|
+
This document explains how the three Claude integration layers (the template, the Claude Code rules, and the MCP tools) connect through the [examples](https://github.com/extension-js/examples) repo.
|
|
4
4
|
|
|
5
5
|
## The examples repo is the backbone
|
|
6
6
|
|
|
@@ -154,7 +154,7 @@ MCP server calls extensionCreate() → same go-git-it flow as CLI
|
|
|
154
154
|
|
|
155
155
|
1. **Single source of truth.** `templates-meta.json` is generated from the actual examples. No manual sync needed. Add a template to `examples/`, run `pnpm run generate`, and all three layers pick it up.
|
|
156
156
|
|
|
157
|
-
2. **The examples repo is the knowledge base.** The MCP server doesn't hard-code extension patterns
|
|
157
|
+
2. **The examples repo is the knowledge base.** The MCP server doesn't hard-code extension patterns, it reads them from examples. This means new patterns (like `sidebar-claude`) are immediately available to Claude without updating the MCP server.
|
|
158
158
|
|
|
159
159
|
3. **Graceful degradation.** Users who don't use MCP still benefit from CLAUDE.md. Users who don't use Claude Code still benefit from the template. Each layer works independently.
|
|
160
160
|
|
package/claude/CLAUDE.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# extension.dev
|
|
1
|
+
# extension.dev, Claude Code Instructions
|
|
2
2
|
|
|
3
3
|
You are working on a browser extension project built with the [extension.dev](https://extension.dev) platform, a zero-config cross-browser extension framework.
|
|
4
4
|
|
|
@@ -23,11 +23,11 @@ The extension.dev platform ships 60+ templates in the [examples](https://github.
|
|
|
23
23
|
|
|
24
24
|
| Surface | Vanilla | React | Vue | Svelte | AI |
|
|
25
25
|
| -------------- | ------------ | ---------------- | ------------- | ---------------- | ---------------- |
|
|
26
|
-
| Content script | `content` | `content-react` | `content-vue` | `content-svelte` |
|
|
27
|
-
| Sidebar | `sidebar` | `sidebar-shadcn` |
|
|
28
|
-
| Action popup | `action` |
|
|
29
|
-
| New tab | `new` | `new-react` | `new-vue` | `new-svelte` |
|
|
30
|
-
| Full framework | `javascript` | `react` | `vue` | `svelte` |
|
|
26
|
+
| Content script | `content` | `content-react` | `content-vue` | `content-svelte` | n/a |
|
|
27
|
+
| Sidebar | `sidebar` | `sidebar-shadcn` | n/a |, | `sidebar-claude` |
|
|
28
|
+
| Action popup | `action` | n/a |, | n/a | `action-chatgpt` |
|
|
29
|
+
| New tab | `new` | `new-react` | `new-vue` | `new-svelte` | n/a |
|
|
30
|
+
| Full framework | `javascript` | `react` | `vue` | `svelte` | n/a |
|
|
31
31
|
|
|
32
32
|
**When recommending a template:**
|
|
33
33
|
|
|
@@ -56,7 +56,7 @@ A typical extension.dev project:
|
|
|
56
56
|
```
|
|
57
57
|
my-extension/
|
|
58
58
|
src/
|
|
59
|
-
manifest.json # Required
|
|
59
|
+
manifest.json # Required: the source of truth
|
|
60
60
|
background.ts # Service worker (Chromium) / background script (Firefox)
|
|
61
61
|
content/ # Content scripts
|
|
62
62
|
scripts.tsx
|
|
@@ -151,16 +151,16 @@ export default {
|
|
|
151
151
|
3. **Service workers vs background scripts.** Chromium uses `service_worker` (single file). Firefox uses `scripts` (array).
|
|
152
152
|
4. **Environment variables.** Use `EXTENSION_PUBLIC_*` prefix for variables accessible in extension code. `import.meta.env.EXTENSION_PUBLIC_BROWSER` gives the current browser.
|
|
153
153
|
5. **Asset imports.** Import images/fonts directly in your code. The build system handles bundling.
|
|
154
|
-
6. **CSS Modules.** Use `*.module.css` / `*.module.scss`. Never use the `?url` suffix for CSS module imports
|
|
154
|
+
6. **CSS Modules.** Use `*.module.css` / `*.module.scss`. Never use the `?url` suffix for CSS module imports, it breaks class name hashing.
|
|
155
155
|
|
|
156
156
|
## When creating new extensions
|
|
157
157
|
|
|
158
158
|
1. Check if an existing template matches the use case (see template catalog above)
|
|
159
159
|
2. If yes: `npx extension@latest create my-ext --template=<slug>`
|
|
160
|
-
3. If no: start from `manifest.json
|
|
160
|
+
3. If no: start from `manifest.json`, define what the extension needs
|
|
161
161
|
4. Add entry points referenced by the manifest (background, content scripts, UI pages)
|
|
162
|
-
5. Install framework deps if needed (React, Vue, etc.)
|
|
163
|
-
6. Run `npm run dev
|
|
162
|
+
5. Install framework deps if needed (React, Vue, etc.), the framework auto-detects them
|
|
163
|
+
6. Run `npm run dev`, the dev server handles the rest
|
|
164
164
|
|
|
165
165
|
**Learning from examples:** When building a feature you haven't done before, read the source of a relevant template from the examples repo. The source for any template is at:
|
|
166
166
|
|
|
@@ -234,11 +234,11 @@ npm run dev -- --logs info --log-url "example.com"
|
|
|
234
234
|
|
|
235
235
|
### Triggering events without clicking (requires `--allow-control`)
|
|
236
236
|
|
|
237
|
-
- `extension open action
|
|
238
|
-
- `extension open command --name <cmd
|
|
239
|
-
- `extension_list_extensions` (MCP tool; no CLI verb)
|
|
237
|
+
- `extension open action`, fire the toolbar action (opens its popup, or replays `chrome.action.onClicked`).
|
|
238
|
+
- `extension open command --name <cmd>`, replay a `chrome.commands.onCommand` keyboard shortcut.
|
|
239
|
+
- `extension_list_extensions` (MCP tool; no CLI verb), list extensions with a live context in the browser (Chromium, read-only).
|
|
240
240
|
|
|
241
|
-
These replay your captured listeners, so they work on Chrome and Firefox
|
|
241
|
+
These replay your captured listeners, so they work on Chrome and Firefox, but carry **no user gesture**, so `activeTab` is not granted (the result reports `gesture: false`, plus a `warning` when the manifest declares `activeTab`). If you need a genuine-gesture click (activeTab granted), use [chrome-devtools-mcp](https://github.com/ChromeDevTools/chrome-devtools-mcp)'s `trigger_extension_action` (Chromium only) alongside this server.
|
|
242
242
|
|
|
243
243
|
## Contributing templates to the examples repo
|
|
244
244
|
|
package/claude/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# extension.dev
|
|
1
|
+
# extension.dev, Claude Code Integration
|
|
2
2
|
|
|
3
3
|
Drop-in instructions, rules, and example prompts for building browser extensions with the [extension.dev](https://extension.dev) platform using Claude Code.
|
|
4
4
|
|
|
@@ -11,10 +11,10 @@ claude/
|
|
|
11
11
|
CLAUDE.md Drop-in Claude Code instructions for any extension project
|
|
12
12
|
ARCHITECTURE.md How the template, CLAUDE.md, and MCP layers connect
|
|
13
13
|
commands/
|
|
14
|
-
extension.md /extension
|
|
15
|
-
extension-add.md /extension-add
|
|
16
|
-
extension-debug.md /extension-debug
|
|
17
|
-
extension-publish.md /extension-publish
|
|
14
|
+
extension.md /extension: create, dev, build, add features, debug
|
|
15
|
+
extension-add.md /extension-add: add sidebar, popup, content script, etc.
|
|
16
|
+
extension-debug.md /extension-debug: live DOM/console inspection
|
|
17
|
+
extension-publish.md /extension-publish: store submission prep
|
|
18
18
|
rules/
|
|
19
19
|
extension-dev.md Core rules: project structure, manifest, commands
|
|
20
20
|
cross-browser.md Cross-browser manifest field mapping
|
|
@@ -61,9 +61,9 @@ Claude Code will automatically pick up the instructions and know how to:
|
|
|
61
61
|
|
|
62
62
|
The [examples repo](https://github.com/extension-js/examples) publishes `templates-meta.json` as a nightly release asset. This file is the single source of truth for:
|
|
63
63
|
|
|
64
|
-
- **CLAUDE.md
|
|
65
|
-
- **MCP tools
|
|
66
|
-
- **`extension create
|
|
64
|
+
- **CLAUDE.md**, references it so Claude knows all available templates
|
|
65
|
+
- **MCP tools**, `extension_list_templates` fetches and queries it at runtime
|
|
66
|
+
- **`extension create`**, resolves template slugs to repo URLs via the same naming convention
|
|
67
67
|
|
|
68
68
|
When a new template is added to the examples repo, all three layers pick it up automatically.
|
|
69
69
|
|
|
@@ -7,8 +7,8 @@ Add a new feature surface to the current extension project. The user said: $ARGU
|
|
|
7
7
|
|
|
8
8
|
## Parse arguments
|
|
9
9
|
|
|
10
|
-
- First argument: feature type
|
|
11
|
-
- Second argument (optional): framework
|
|
10
|
+
- First argument: feature type, one of: `sidebar`, `popup`, `content-script`, `background`, `newtab`, `options`, `devtools`
|
|
11
|
+
- Second argument (optional): framework, one of: `react`, `vue`, `svelte`, `preact`, `vanilla`. Default: detect from existing project, fall back to `react`
|
|
12
12
|
|
|
13
13
|
## Steps
|
|
14
14
|
|
|
@@ -18,7 +18,7 @@ Add a new feature surface to the current extension project. The user said: $ARGU
|
|
|
18
18
|
- Detect the framework from existing dependencies in `package.json`
|
|
19
19
|
|
|
20
20
|
2. **Get the reference pattern**
|
|
21
|
-
If MCP tool `extension_add_feature` is available, use it
|
|
21
|
+
If MCP tool `extension_add_feature` is available, use it. It returns the exact manifest additions, files to create, and reference template.
|
|
22
22
|
|
|
23
23
|
If MCP tool `extension_get_template_source` is available, read the reference template source to get real implementation patterns.
|
|
24
24
|
|
|
@@ -37,17 +37,17 @@ Add a new feature surface to the current extension project. The user said: $ARGU
|
|
|
37
37
|
|
|
38
38
|
4. **Create the files**
|
|
39
39
|
For HTML-based features (sidebar, popup, newtab, options, devtools):
|
|
40
|
-
- `src/<feature>/index.html
|
|
41
|
-
- `src/<feature>/scripts.tsx
|
|
42
|
-
- `src/<feature>/styles.css
|
|
43
|
-
- `src/<feature>/<Feature>App.tsx
|
|
40
|
+
- `src/<feature>/index.html`, HTML entry with script tag
|
|
41
|
+
- `src/<feature>/scripts.tsx`, Framework mount point (or `.ts` for vanilla)
|
|
42
|
+
- `src/<feature>/styles.css`, Stylesheet
|
|
43
|
+
- `src/<feature>/<Feature>App.tsx`, Main component (non-vanilla only)
|
|
44
44
|
|
|
45
45
|
For content scripts:
|
|
46
|
-
- `src/content/scripts.ts
|
|
47
|
-
- `src/content/styles.css
|
|
46
|
+
- `src/content/scripts.ts`, Entry point
|
|
47
|
+
- `src/content/styles.css`, Injected styles
|
|
48
48
|
|
|
49
49
|
For background:
|
|
50
|
-
- `src/background.ts
|
|
50
|
+
- `src/background.ts`, Service worker / background script
|
|
51
51
|
|
|
52
52
|
5. **Handle sidebar specifically**
|
|
53
53
|
If adding a sidebar, also create/update `src/background.ts`:
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: Debug a running extension
|
|
2
|
+
description: Debug a running extension, inspect DOM, console, content script injection
|
|
3
3
|
argument-hint: "[url] [selectors...]"
|
|
4
4
|
---
|
|
5
5
|
|
|
@@ -25,8 +25,8 @@ Debug the currently running extension dev session. The user said: $ARGUMENTS
|
|
|
25
25
|
|
|
26
26
|
3. **Exercise event handlers (when the bug is in an action / command / shortcut)**
|
|
27
27
|
If the session was started with `--allow-control`, fire the events a user would, without clicking:
|
|
28
|
-
- `extension_open` with `surface: "action"
|
|
29
|
-
- `extension_open` with `surface: "command"` and `name: "<cmd>"
|
|
28
|
+
- `extension_open` with `surface: "action"`, triggers the toolbar action (opens its popup, or replays `chrome.action.onClicked`).
|
|
29
|
+
- `extension_open` with `surface: "command"` and `name: "<cmd>"`, replays a `chrome.commands.onCommand` keyboard shortcut.
|
|
30
30
|
- Then re-inspect or read `extension_logs` to see what the handler did.
|
|
31
31
|
|
|
32
32
|
**Caveat:** replay carries no user gesture, so `activeTab` is NOT granted. If the handler depends on `activeTab` (e.g. `chrome.scripting.executeScript` on the active tab, `captureVisibleTab`), the result includes `gesture: false` and a `warning`, and behavior differs from a real click. For a genuine-gesture click (activeTab granted), use chrome-devtools-mcp's `trigger_extension_action` (Chromium only) alongside this server.
|
|
@@ -37,16 +37,16 @@ Debug the currently running extension dev session. The user said: $ARGUMENTS
|
|
|
37
37
|
Based on what you find, check for:
|
|
38
38
|
- **"It didn't load"**: Check extension root count. If 0, content scripts may not be injecting. Check manifest `content_scripts` matches patterns and the target URL.
|
|
39
39
|
- **Console errors**: Report top errors. Common ones:
|
|
40
|
-
- `Uncaught TypeError
|
|
41
|
-
- `Content Security Policy
|
|
42
|
-
- `chrome.runtime.lastError
|
|
40
|
+
- `Uncaught TypeError`, likely a missing import or wrong module format
|
|
41
|
+
- `Content Security Policy`, extension CSP blocking inline scripts
|
|
42
|
+
- `chrome.runtime.lastError`, API permission missing
|
|
43
43
|
- **Wrong page**: Check if the content script `matches` pattern in manifest covers the target URL
|
|
44
|
-
- **Shadow DOM empty**: Extension root exists but shadow content is empty
|
|
44
|
+
- **Shadow DOM empty**: Extension root exists but shadow content is empty, likely a CSS or framework mounting issue
|
|
45
45
|
|
|
46
46
|
5. **Suggest fixes** based on the diagnosis
|
|
47
47
|
|
|
48
48
|
## Examples
|
|
49
49
|
|
|
50
|
-
- `/extension-debug
|
|
51
|
-
- `/extension-debug https://example.com
|
|
52
|
-
- `/extension-debug https://example.com #my-root .sidebar
|
|
50
|
+
- `/extension-debug`, inspect the default page target
|
|
51
|
+
- `/extension-debug https://example.com`, inspect a specific URL
|
|
52
|
+
- `/extension-debug https://example.com #my-root .sidebar`, inspect URL and probe selectors
|
|
@@ -9,27 +9,27 @@ You are helping build a browser extension with the extension.dev platform. The u
|
|
|
9
9
|
|
|
10
10
|
Parse the user's intent from `$ARGUMENTS` and execute the matching action:
|
|
11
11
|
|
|
12
|
-
### "create <name>" or "new <name>"
|
|
12
|
+
### "create <name>" or "new <name>", Scaffold a new extension
|
|
13
13
|
|
|
14
14
|
1. If MCP tool `extension_list_templates` is available, use it to find the best template matching the user's description (check for surface type, framework, and keywords)
|
|
15
15
|
2. If not, check the template catalog: `curl -sL https://github.com/extension-js/examples/releases/download/nightly/templates-meta.json | jq '.templates[] | {slug, description, uiFramework, surfaces}'`
|
|
16
16
|
3. Run `npx extension@latest create <name> --template=<best-match>`
|
|
17
17
|
4. Report what was created and suggest `npm run dev`
|
|
18
18
|
|
|
19
|
-
### "dev" or "run"
|
|
19
|
+
### "dev" or "run", Start development
|
|
20
20
|
|
|
21
21
|
1. Run `npm run dev` (or `npx extension dev`) in the project root
|
|
22
22
|
2. Tell the user the browser will open with their extension loaded
|
|
23
|
-
3. Mention HMR is active
|
|
23
|
+
3. Mention HMR is active, changes will hot-reload
|
|
24
24
|
|
|
25
|
-
### "build"
|
|
25
|
+
### "build", Build for production
|
|
26
26
|
|
|
27
27
|
1. Run `npm run build` (or `npx extension build`)
|
|
28
28
|
2. After success, report the output in `dist/chrome/`
|
|
29
29
|
3. If the user mentions "firefox" or "both", also build with `--browser=firefox`
|
|
30
30
|
4. If they mention "zip" or "store", add `--zip`
|
|
31
31
|
|
|
32
|
-
### "add <feature>"
|
|
32
|
+
### "add <feature>", Add a feature surface
|
|
33
33
|
|
|
34
34
|
1. If MCP tool `extension_add_feature` is available, use it to get the manifest additions and file list
|
|
35
35
|
2. Otherwise, determine what's needed from the feature type:
|
|
@@ -40,14 +40,14 @@ Parse the user's intent from `$ARGUMENTS` and execute the matching action:
|
|
|
40
40
|
- **background**: `background.service_worker` (Chromium) + `background.scripts` (Firefox)
|
|
41
41
|
3. Create the files and update `src/manifest.json`
|
|
42
42
|
|
|
43
|
-
### "debug" or "inspect"
|
|
43
|
+
### "debug" or "inspect", Debug a running extension
|
|
44
44
|
|
|
45
45
|
1. If MCP tool `extension_source_inspect` is available, use it with `include: ["html", "console", "extension_roots"]`
|
|
46
46
|
2. If there's a URL mentioned, pass it as the target
|
|
47
47
|
3. If there are CSS selectors mentioned, pass them as `probe`
|
|
48
48
|
4. Report: injected HTML, console errors, extension root state
|
|
49
49
|
|
|
50
|
-
### "validate"
|
|
50
|
+
### "validate", Check manifest for issues
|
|
51
51
|
|
|
52
52
|
1. If MCP tool `extension_manifest_validate` is available, use it
|
|
53
53
|
2. Otherwise, read `src/manifest.json` and check:
|
|
@@ -56,7 +56,7 @@ Parse the user's intent from `$ARGUMENTS` and execute the matching action:
|
|
|
56
56
|
- Permissions: `sidePanel` present if `side_panel` is declared
|
|
57
57
|
- Background: `service_worker` (Chromium) and `scripts` (Firefox) both present
|
|
58
58
|
|
|
59
|
-
### "template <query>"
|
|
59
|
+
### "template <query>", Search for a template
|
|
60
60
|
|
|
61
61
|
1. If MCP tool `extension_list_templates` is available, use it with the query
|
|
62
62
|
2. Otherwise, search the catalog JSON
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
## How Claude should approach this
|
|
8
8
|
|
|
9
|
-
1. **Update manifest.json
|
|
9
|
+
1. **Update manifest.json**, add side panel config for both browsers:
|
|
10
10
|
|
|
11
11
|
```json
|
|
12
12
|
{
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
}
|
|
48
48
|
```
|
|
49
49
|
|
|
50
|
-
4. **Create the sidebar UI
|
|
50
|
+
4. **Create the sidebar UI**, `src/sidebar/index.html`, `src/sidebar/scripts.tsx`, `src/sidebar/styles.css`
|
|
51
51
|
|
|
52
52
|
5. **Test both browsers:**
|
|
53
53
|
```bash
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
cd page-summarizer
|
|
14
14
|
```
|
|
15
15
|
|
|
16
|
-
2. **Define the manifest
|
|
16
|
+
2. **Define the manifest**, content script for the floating button, background script for orchestration:
|
|
17
17
|
|
|
18
18
|
```json
|
|
19
19
|
{
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
}
|
|
36
36
|
```
|
|
37
37
|
|
|
38
|
-
3. **Build the content script
|
|
38
|
+
3. **Build the content script**, inject a floating button, handle click to extract `document.body.innerText`, send to background for processing.
|
|
39
39
|
|
|
40
40
|
4. **Test it:**
|
|
41
41
|
```bash
|