build-chrome-extension
Use if building or debugging a Chrome MV3 extension — manifest v3, service_worker, content_scripts.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Use if building or debugging a Chrome MV3 extension — manifest v3, service_worker, content_scripts.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Use skill if you are exhaustively testing or release-gating martool CLI commands in a source checkout or deployed Coolify container over SSH, without local Docker or provider spend.
Use if driving agent-browser for Chrome/CDP automation, @ref snapshots, tabs, or verification.
Use if testing or debugging an iOS app via agent-device CLI — simulator flows, evidence, bug triage.
Use if supervising Jean agents through MCP and Computer Use for monitoring, recovery, or closure.
Use if auditing or designing a CLI for agent/LLM use — JSON output, exit codes, non-interactive.
Use if auditing or designing an MCP server for agent-readiness — framework, security, context.
| name | build-chrome-extension |
| description | Use if building or debugging a Chrome MV3 extension — manifest v3, service_worker, content_scripts. |
Build, debug, package, and ship Chrome Manifest V3 extensions. Optimize for restart-safe service workers, isolated content scripts, least-privilege permissions, and Web Store review readiness.
Trigger when the request matches any of:
manifest.json with manifest_version: 3, service_worker, content_scripts, host_permissions, action, or side_panel fieldschrome.runtime, chrome.storage, chrome.alarms, chrome.scripting, chrome.tabs, chrome.declarativeNetRequest, chrome.sidePanel, or chrome.offscreen APIsonMessage returns, chrome.alarms vs setIntervalwebRequest → declarativeNetRequest, browser_action → action)dist/ or .output/chrome-mv3/ folder, packaging the Web Store zip, writing privacy/permission justifications, or preparing review notesDo NOT use this skill when:
browser.* namespace, web-ext tooling, Safari App Extensions)run-agent-browserpublish-npm-package| Key | Default |
|---|---|
| Manifest target | manifest_version: 3 only; never generate MV2 |
| Greenfield framework | WXT unless the repo already chose another MV3 tool |
| Persistent state | chrome.storage.local; chrome.storage.session for ephemeral restart-safe state |
| Background model | Event-driven service worker, listeners registered synchronously at top level |
| Periodic work | chrome.alarms — never setTimeout/setInterval for background scheduling |
| Network modification | chrome.declarativeNetRequest — never blocking webRequest |
| Permissions | Least privilege; prefer optional_permissions and optional_host_permissions granted via chrome.permissions.request |
| Loaded folder | Built output only: WXT .output/chrome-mv3-dev/ or .output/chrome-mv3/; Plasmo build/chrome-mv3-*; CRXJS/Vite dist/ |
| Package preflight | Run scripts/check-mv3-manifest.sh and scripts/preflight-extension.sh against the production build before zipping |
These are the failures that recur across every MV3 build. Internalize before writing code:
chrome.runtime.onMessage, onInstalled, onStartup, alarm, and tab listeners synchronously at top level. Late-registered listeners miss wake-up events.setTimeout/setInterval cannot keep a service worker alive and will not fire reliably across idle cycles. Use chrome.alarms.create with periodInMinutes >= 0.5.chrome.runtime.onMessage async handlers must return true synchronously to keep the message channel open; otherwise sendResponse throws.window.* globals are invisible. Use world: "MAIN" only for page-JS access, then bridge with postMessage plus a same-origin token.fetch requires matching host_permissions. Content-script fetch is bound by the page's origin and CORS rules — route privileged requests through the service worker via chrome.runtime.sendMessage.<script>, eval(), new Function(), and remote executable code. Bundle everything; no CDN-loaded scripts.manifest.json paths must point at built artifacts (e.g. background.js, content.js, popup.html), never src/*.ts or unbuilt source.<all_urls> or broad host permissions at install time triggers Web Store review friction. Prefer activeTab plus optional host grants.| Decision | Default | Escalate when |
|---|---|---|
| Background state | chrome.storage.session/local | Transactions, large indexes, binary blobs → IndexedDB |
| Periodic work | chrome.alarms | Real-time stream → design reconnect + queue |
| Network modification | declarativeNetRequest | Read-only observation → non-blocking webRequest |
| Page data fetch | Service worker fetch with host permissions | Page origin is sufficient → content-script fetch |
| Page JS access | world: "MAIN" bridge with payload validation | DOM-only access → stay in ISOLATED world |
| UI state persistence | chrome.storage.session | Must survive browser restart → local or sync |
| Host access | activeTab or optional host grants | Extension is non-functional without install-time host access |
| Side panel vs popup | Side panel for persistent companion UI | Quick action or short form → popup |
| Offscreen document | DOM/canvas/clipboard/audio/Worker from service worker | Popup/options/content script can own it → skip |
| Request shape | Action |
|---|---|
| "Build a Chrome extension" | Use this skill; target MV3 |
| "Build for Chrome and Firefox" | Keep Chrome MV3 here; cross-browser layer is out of scope |
| "Automate a website in a browser" | Route to run-agent-browser |
| "Write Playwright tests for an extension" | Extension launch/load notes here; broader Playwright authoring is out of scope for this pack |
| "Publish to npm" | Route to publish-npm-package |
| "Submit to Chrome Web Store" | Use this skill; read references/publishing/web-store.md |
| "Deploy via enterprise policy" | Out of scope unless a dedicated enterprise skill exists |
Ask: "Which extension surfaces exist, which Chrome APIs are required, which permissions can be deferred to runtime?"
optional_permissions/optional_host_permissions.references/frameworks/comparison.md.Ask: "Greenfield, existing framework build, or hand-written manifest?"
Chrome must load the built output folder, never src/ or unbundled TypeScript.
Ask: "Which context owns the state, which owns the DOM, which messages cross the boundary?"
Read the matching reference before writing code:
references/patterns/service-worker.mdreferences/patterns/content-scripts.mdreferences/patterns/ui-surfaces.mdreferences/apis/messaging.mdchrome.storage areas, quotas, typed wrappers, migrations → references/apis/storage.mdreferences/apis/core-apis.mdSKILL.md.Validate every cross-boundary payload: messages, storage reads, external API responses, MAIN-world bridge data.
Ask: "Can Chrome load this exact folder, and do all manifest paths exist there?"
Run from the skill directory against your build folder:
scripts/check-mv3-manifest.sh dist
scripts/preflight-extension.sh dist
Adjust the path per framework:
| Framework | Dev output | Production output |
|---|---|---|
| WXT | .output/chrome-mv3-dev/ | .output/chrome-mv3/ |
| Plasmo | build/chrome-mv3-dev/ | build/chrome-mv3-prod/ |
| CRXJS | dist/ | dist/ |
| Vanilla Vite | dist/ | dist/ |
Read scripts/check-mv3-manifest.md and scripts/preflight-extension.md before modifying either script.
Ask: "What failure only appears once Chrome loads the extension?"
chrome.* only at boundaries.chrome://extensions → "Load unpacked".chrome.permissions.request) before the host call.Read references/testing/testing-guide.md for extension-specific tests and references/testing/debugging.md for service-worker, popup, content-script, permission, and storage debugging.
Ask: "Could a reviewer state the single purpose, each permission's need, the data use, and the remote-code posture in one sentence each?"
.DS_Store, __MACOSX, framework caches.manifest.json sits at the zip root).references/publishing/web-store.md before submission.Match evidence to the task before stopping:
| Task | Evidence |
|---|---|
| New scaffold | Built-output path + check-mv3-manifest.sh result |
| Feature change | Relevant unit/integration test + manual-load note when Chrome behavior changed |
| Manifest/permission change | check-mv3-manifest.sh result + permission justification |
| Content-script change | Allowed-URL injection result + disallowed-URL injection result |
| Service-worker change | Restart-resilience note OR explicit "not exercised" caveat |
| Package/Web Store work | preflight-extension.sh result + zip path + reviewer notes |
Final reports include:
src/ in Chrome unless the framework explicitly emits loadable code there.setTimeout/setInterval to keep the service worker alive.webRequest for normal MV3 network modification.<all_urls> without a feature-level justification and a documented narrower alternative.fetch through unauthenticated content-script messages.manifest.json before claiming done.MV3 punishes the same mistakes repeatedly: lost service-worker state, late-registered listeners, timer-based scheduling, isolated-world surprises, over-broad permissions, and shipping src/ instead of built output. Apply the pinned defaults, route to references for depth, run the bundled scripts against the built folder, and produce review-ready evidence.