Forge playbook for browser extensions (Chrome/Edge MV3). Use for chrome extension, manifest v3, service worker, content script, permissions, CSP, Web Store, store policy.
Scanned 9/6/2026
Install to Claude Code
npx -y skills add ForgeyClap/claude-forge --skill forge-extension --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Forge Extension?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/forgeyclap-forge-extension)More formats (shields.io, HTML) on the badges page.
---
name: forge-extension
description: Forge playbook for browser extensions (Chrome/Edge MV3). Use for chrome extension, manifest v3, service worker, content script, permissions, CSP, Web Store, store policy.
---
# Forge playbook — Browser extension (Chrome MV3)
`build-boss` leads; `security-boss` co-owns the permission + messaging + CSP surface (this is a security-heavy domain and a real Codex/security trigger). Popup/options UI defers to `forge-website` (real content, responsive, a11y); anything that calls a backend defers to `forge-integration`. Scope is **Chrome/Edge Manifest V3** unless the owner asks for Firefox/Safari (those are separate ports). The honesty rule: an extension that "loads unpacked" must have its core flow actually exercised, and every permission requested must be one the code genuinely uses.
## Hard rules (non-negotiable)
- **Least-privilege permissions.** Request only the `permissions` + `host_permissions` the code actually uses; prefer `activeTab` and `optional_permissions` over a blanket `<all_urls>`. Each permission is justifiable in one sentence. Over-broad scope is both a Web Store rejection risk and a user-trust failure.
- **No remotely-hosted code (MV3 policy).** All executable JS ships inside the package — **no** `eval`, `new Function` on remote strings, or `<script src>` from a CDN. Remote code is a hard Chrome Web Store rejection.
- **Safe content-script + messaging.** Content scripts run in the page's hostile context: validate every `chrome.runtime.onMessage` payload **and check `sender`**; never trust or `eval` `window.postMessage` data from the page; keep `externally_connectable` narrow. `web_accessible_resources` scoped to specific matches, never `<all_urls>`.
- **Strict CSP kept strict.** MV3's default extension CSP (`script-src 'self'`) is not weakened — no `'unsafe-eval'`, no `'unsafe-inline'`, no remote script sources. Sandboxed pages only if genuinely required, narrowly.
- **Termination-resilient service worker.** The MV3 background is an **event-driven service worker**, not a persistent page: listeners registered at top level, no reliance on in-memory global state surviving, durable state persisted to `chrome.storage`.
- **No secrets in the package; store-policy compliance.** No API secret baked into the extension (it's extractable); real secrets sit behind a backend, OAuth via `chrome.identity` with minimal scopes. Single clear purpose, accurate description, privacy disclosure if user data is handled, no obfuscated code.
## Team (conditional by stack/level)
Lead: `build-boss`. Security: **`security-boss`** (permission surface, CSP, message validation, no-remote-code — the defining risk of this domain). Support: `typescript-reviewer` (background/content/messaging code), `test-boss` (load the unpacked extension in Playwright/Puppeteer for E2E), `ui-boss` (popup/options UI via `forge-website`). Backend calls: `forge-integration` team.
## Skills / commands / MCP
Chrome Extension **MV3** docs via Context7 (manifest v3, service-worker lifecycle, messaging + storage + identity APIs — get the current API, MV2 patterns are dead). `forge-website` for the popup/options page UI; `forge-integration` if it talks to an API; `systematic-debugging` for service-worker lifecycle bugs (the "why did my listener not fire after idle" class). `browser` skill / Playwright to load the unpacked build and drive the core flow. No special MCP required. Reuse a bundler (esbuild / Vite / webpack) with an MV3/CRX plugin — don't hand-assemble the package.
## Fan-out & flow
L2 a single-purpose extension (popup + one content script); L3 a service worker + multiple content scripts + options page + messaging + a backend.
**Serial:** manifest + permission model → service worker + messaging contract → content scripts → popup/options UI → CSP + security review → load-unpacked E2E → production zip.
**Parallel:** content script ∥ popup/options UI ∥ background logic build in parallel **once** the message contract is fixed (the message schema is the seam).
## Domain gates
- Manifest requests only permissions/`host_permissions` the code uses; `activeTab`/optional preferred over `<all_urls>` (each justified).
- No remotely-hosted code — no `eval`/`new Function`/remote `<script>`; all JS bundled.
- Runtime + content-script messages validate `sender` + payload; page-supplied data is never `eval`'d; `externally_connectable` and `web_accessible_resources` scoped to specific matches.
- Default MV3 CSP kept strict (`script-src 'self'`, no `unsafe-eval`/`unsafe-inline`).
- Service worker is event-driven and termination-resilient — listeners at top level, durable state in `chrome.storage`, no global-state reliance.
- No secrets in the package; OAuth via `chrome.identity` with minimal scopes.
- Extension **loads unpacked and the core flow works** (evidence: load + a screenshot/log), and a production zip is produced.
## Ship-readiness (unique)
Manifest permissions minimal and each justified; no remote code / `eval`; messaging validates sender + payload; MV3 CSP strict; service worker termination-resilient (state in `chrome.storage`); no secrets in the package; extension **loaded unpacked with the core flow exercised** (real output attached) and a production zip built. Store-listing prerequisites — single-purpose description, privacy policy if user data, per-permission justifications, screenshots — are noted as **owner action** (submission itself needs a developer account and is owner-gated). Firefox/Safari ports are out of scope unless requested. Advisory checklist; running `security-boss` / `codex-reviewer` on the permission + messaging surface is strongly recommended here — not a blocker, but say so if it was not run.
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!