← 返回 Skills 市场
samber

Chrome Extension

作者 Samuel Berthe · GitHub ↗ · v1.0.2 · MIT-0
cross-platform ✓ 安全检测通过
252
总下载
0
收藏
1
当前安装
2
版本数
在 OpenClaw 中安装
/install chrome-extension
功能描述
Comprehensive guide for building Chrome extensions with Manifest V3. Use this skill whenever the user mentions Chrome extension, browser extension, manifest....
使用说明 (SKILL.md)

Chrome Extension Development (Manifest V3)

This skill covers everything needed to build, debug, and publish Chrome extensions with MV3. It is organized as a routing document: read this file first to understand the architecture and decision points, then load the relevant reference file for implementation details.

Reference files

Read only the reference files relevant to the current task. Each file is self-contained.

File When to read
references/manifest-v3.md Setting up or modifying manifest.json, configuring icons, versioning
references/service-worker.md Background logic, lifecycle, state persistence, alarms, events
references/content-scripts.md Injecting code into pages, isolated/main world, dynamic injection, SPA handling, orphaning
references/messaging-rpc.md Communication between any contexts, typed protocols, RPC layer, async handler patterns
references/ui-surfaces.md Popup, options page, side panel, context menus, commands, notifications, omnibox, devtools panel
references/storage.md chrome.storage (local/sync/session), quotas, reactive patterns, framework hooks
references/network-csp.md HTTP requests from content scripts, CSP bypass relay, declarativeNetRequest, offscreen docs, CORS
references/permissions.md Required/optional permissions, host permissions, activeTab, runtime request flow
references/web-accessible-resources.md Exposing extension files to web pages, security implications
references/typescript-build.md TypeScript setup, project structure, build tools comparison, bundling
references/publishing.md Chrome Web Store submission, review process, rejection reasons, updates, privacy policy
references/execution-contexts.md Communication flow diagrams, per-context capabilities/limits, choosing the right messaging method
references/debugging-mistakes.md DevTools for extensions, testing SW termination, common gotchas, error patterns

Architecture overview

A Chrome extension has up to 5 execution contexts that communicate via message passing:

┌──────────────────────────────────────────────────────────┐
│ Extension Process                                        │
│  ┌─────────────────┐  ┌───────┐  ┌─────────┐  ┌──────┐ │
│  │ Service Worker   │  │ Popup │  │ Options │  │ Side │ │
│  │ (background)     │  │       │  │  Page   │  │Panel │ │
│  │ - No DOM         │  │ Full  │  │  Full   │  │ Full │ │
│  │ - Ephemeral      │  │ DOM   │  │  DOM    │  │ DOM  │ │
│  │ - All chrome.*   │  │ All   │  │  All    │  │ All  │ │
│  │   APIs           │  │ APIs  │  │  APIs   │  │ APIs │ │
│  └────────┬─────────┘  └───┬───┘  └────┬────┘  └──┬───┘ │
│           │ chrome.runtime.sendMessage / connect   │     │
└───────────┼────────────────┼───────────┼──────────┼──────┘
            │                │           │          │
    chrome.tabs.sendMessage  │           │          │
            │                │           │          │
┌───────────┼────────────────┼───────────┼──────────┼──────┐
│ Web Page  ▼                                              │
│  ┌──────────────────┐    ┌──────────────────┐            │
│  │ Content Script    │    │ Main World Script │            │
│  │ (isolated world)  │◄──►│ (page context)    │            │
│  │ - Shared DOM      │    │ - Shared DOM      │            │
│  │ - Own JS scope    │    │ - Page JS scope   │            │
│  │ - chrome.runtime  │    │ - No chrome.* API │            │
│  │ - chrome.storage  │    │ - Full page access│            │
│  │ - Subject to CSP  │    │ - Subject to CSP  │            │
│  │   (network only)  │    │   (fully)         │            │
│  └──────────────────┘    └──────────────────┘            │
│           ▲ window.postMessage                           │
│           │ (through shared DOM)                         │
└──────────────────────────────────────────────────────────┘

Communication flows (labeled channels)

┌───────────────────────────────────────────────────────────────────────────┐
│ Extension Process                                                         │
│                                                                           │
│  ┌─────────────────┐  chrome.runtime   ┌───────┐  ┌─────────┐  ┌──────┐ │
│  │ Service Worker   │◄─.sendMessage()──│ Popup │  │ Options │  │ Side │ │
│  │ (background)     │◄─.connect()──────│       │  │  Page   │  │Panel │ │
│  │                  │                  └───────┘  └─────────┘  └──────┘ │
│  │ - No DOM         │  ┌────────────────────────────────────────────┐   │
│  │ - Ephemeral 30s  │  │ SW cannot push to these pages.             │   │
│  │ - All chrome.*   │  │ Use: ports (.connect) or storage.onChanged │   │
│  └────────┬─────────┘  └────────────────────────────────────────────┘   │
│           │                                                              │
│  chrome.storage.onChanged ◄── fires across ALL contexts simultaneously  │
│                                                                           │
└───────────┼──────────────────────────────────────────────────────────────┘
            │ chrome.tabs.sendMessage(tabId, ...) [SW must know tabId]
            │
┌───────────┼──────────────────────────────────────────────────────────────┐
│ Web Page  ▼                                                              │
│  ┌──────────────────┐  window.postMessage  ┌──────────────────┐         │
│  │ Content Script    │◄───────────────────►│ Main World Script │         │
│  │ (isolated world)  │  Custom DOM events  │ (page context)    │         │
│  │                   │                     │                   │         │
│  │ chrome.runtime ───┼── to/from SW        │ No chrome.* APIs  │         │
│  │ chrome.storage    │                     │ Full page JS      │         │
│  │ Shared DOM        │                     │ Shared DOM        │         │
│  │ Page CSP (network)│                     │ Page CSP (full)   │         │
│  └──────────────────┘                     └──────────────────┘         │
└──────────────────────────────────────────────────────────────────────────┘

For detailed flow diagrams (three-layer bridge, cross-extension, storage broadcast) and a per-context breakdown of permissions, limits, and workarounds: → Read references/execution-contexts.md

Communication methods at a glance

Method Direction Best for
chrome.runtime.sendMessage Any ext context → SW One-shot request/response (90% of cases)
chrome.tabs.sendMessage SW → content script (by tabId) Pushing data to a specific tab
chrome.runtime.connect (Port) Bidirectional Streaming, progress, SW ↔ popup
window.postMessage Between worlds on same page Page JS ↔ content script bridge
chrome.storage.onChanged Broadcast to all contexts Settings sync, no messaging needed

→ Full matrix with limits and edge cases: references/execution-contexts.md → Implementation patterns, typed protocols, RPC layer: references/messaging-rpc.md

Key architectural rules

  1. Service worker is ephemeral. It terminates after 30s of inactivity. All state must be persisted to chrome.storage. All event listeners must be registered synchronously at the top level. Never use setTimeout/setInterval for anything beyond a few seconds. → Read references/service-worker.md

  2. Content scripts run in the page's origin. Network requests from content scripts are subject to the page's CSP and CORS. To bypass, relay through the service worker. → Read references/network-csp.md

  3. Messaging is the backbone. Every cross-context interaction uses chrome.runtime messaging. The #1 bug: forgetting to return true from async message listeners. → Read references/messaging-rpc.md

  4. Permissions determine CWS review speed. Broad host_permissions trigger manual review (weeks). activeTab + optional permissions = fast automated review. → Read references/permissions.md

  5. Popup is destroyed on blur. Side panel persists. Choose based on interaction duration. → Read references/ui-surfaces.md

Decision tree: which context handles what?

"I need to run code when the user visits a page"

→ Content script. Static (manifest) for known URL patterns, dynamic (chrome.scripting) for user-triggered injection. Default to isolated world unless you need page JS access. → Read references/content-scripts.md

"I need to make an HTTP request to my API"

  • From popup/options/side panel: direct fetch() works (extension origin, no CSP issues)
  • From content script on a page with restrictive CSP: relay through service worker
  • From service worker: direct fetch() works (requires host_permissions for the target domain) → Read references/network-csp.md

"I need to store user settings"

  • Settings that sync across devices: chrome.storage.sync (100KB limit)
  • Large data or caches: chrome.storage.local (10MB, or unlimited with permission)
  • Ephemeral state surviving SW restarts: chrome.storage.session → Read references/storage.md

"I need to modify HTTP headers or block requests"

→ declarativeNetRequest (NOT webRequest, which lost blocking in MV3) → Read references/network-csp.md

"I need the page's JavaScript to talk to my extension"

→ Three-layer bridge: page (window.postMessage) → content script → service worker → Read references/messaging-rpc.md

"I need to understand what each context can and cannot do"

→ Read references/execution-contexts.md — per-context cards listing chrome.* access, DOM, network, storage, lifetime, hard limits, and practical workarounds.

"I need periodic background tasks"

→ chrome.alarms (minimum 30s interval). NOT setTimeout. → Read references/service-worker.md

"I need DOM APIs in the background" (DOMParser, Canvas, Audio)

→ Offscreen document. One per extension, only chrome.runtime available. → Read references/network-csp.md

"I need to authenticate with OAuth"

→ chrome.identity.launchWebAuthFlow() or chrome.identity.getAuthToken() (Google only) → Read references/service-worker.md (identity section)

Workflow: new extension from scratch

  1. Define the manifest with minimum permissions. Start with activeTab + scripting. → Read references/manifest-v3.md

  2. Set up TypeScript and build tooling (or use CRXJS for Vite-based dev). → Read references/typescript-build.md

  3. Implement the service worker with all event listeners at the top level. → Read references/service-worker.md

  4. Add content scripts if you need page interaction. → Read references/content-scripts.md

  5. Build UI surfaces (popup, options, side panel) as needed. → Read references/ui-surfaces.md

  6. Wire up messaging between all contexts. → Read references/messaging-rpc.md

  7. Test with DevTools, specifically test service worker termination. → Read references/debugging-mistakes.md

  8. Publish to Chrome Web Store. → Read references/publishing.md

Workflow: adding a feature to an existing extension

  1. Identify which context the feature belongs to (see decision tree above).
  2. Read the relevant reference file(s) for that context.
  3. Check if new permissions are needed. Prefer optional_permissions for new capabilities. → Read references/permissions.md
  4. Update the manifest if adding new content scripts, UI surfaces, or permissions.
  5. Handle extension updates gracefully (content script orphaning). → Read references/content-scripts.md (orphaning section)

Minimal manifest.json template

{
  "manifest_version": 3,
  "name": "My Extension",
  "version": "1.0.0",
  "description": "What it does in one sentence",
  "permissions": ["storage", "activeTab", "scripting"],
  "action": {
    "default_popup": "popup.html",
    "default_icon": {
      "16": "icons/icon16.png",
      "48": "icons/icon48.png",
      "128": "icons/icon128.png"
    }
  },
  "background": {
    "service_worker": "background.js",
    "type": "module"
  },
  "icons": {
    "16": "icons/icon16.png",
    "48": "icons/icon48.png",
    "128": "icons/icon128.png"
  }
}

→ For the full manifest reference with all fields: references/manifest-v3.md

Code patterns quick reference

Async message handler (the safe pattern)

// Wrap async handlers to avoid the return-true trap
function asyncHandler(
  fn: (msg: any, sender: chrome.runtime.MessageSender) => Promise\x3Cany>,
) {
  return (
    message: any,
    sender: chrome.runtime.MessageSender,
    sendResponse: (r: any) => void,
  ) => {
    fn(message, sender)
      .then(sendResponse)
      .catch((e) => sendResponse({ __error: true, message: e.message }));
    return true; // literal true, not Promise\x3Ctrue>
  };
}

chrome.runtime.onMessage.addListener(
  asyncHandler(async (msg, sender) => {
    if (msg.type === "FETCH") {
      const res = await fetch(msg.url);
      return { ok: res.ok, data: await res.text() };
    }
  }),
);

CSP bypass relay (content script → service worker → API)

// content-script.ts
async function apiCall(endpoint: string, options?: RequestInit) {
  return chrome.runtime.sendMessage({ type: "API_RELAY", endpoint, options });
}

// background.ts
const ALLOWED_ENDPOINTS = ["https://api.example.com"];
chrome.runtime.onMessage.addListener(
  asyncHandler(async (msg) => {
    if (msg.type !== "API_RELAY") return;
    if (!ALLOWED_ENDPOINTS.some((e) => msg.endpoint.startsWith(e))) {
      throw new Error("Blocked endpoint");
    }
    const res = await fetch(msg.endpoint, msg.options);
    return { ok: res.ok, status: res.status, data: await res.text() };
  }),
);

Persist state across SW restarts

// Use chrome.storage.session for ephemeral state
chrome.storage.session.setAccessLevel({
  accessLevel: "TRUSTED_AND_UNTRUSTED_CONTEXTS",
});

async function getState\x3CT>(key: string, fallback: T): Promise\x3CT> {
  const result = await chrome.storage.session.get(key);
  return result[key] ?? fallback;
}
async function setState\x3CT>(key: string, value: T): Promise\x3Cvoid> {
  await chrome.storage.session.set({ [key]: value });
}

Orphaned content script detection

function isExtensionContextValid(): boolean {
  try {
    return !!chrome.runtime?.id;
  } catch {
    return false;
  }
}

// Before any chrome.runtime call
if (!isExtensionContextValid()) {
  showRefreshBanner();
  return;
}

What NOT to do

  • Do NOT use eval(), new Function(), or load remote scripts. MV3 forbids it.
  • Do NOT use setTimeout/setInterval for anything > 5s in service workers.
  • Do NOT register event listeners inside callbacks or async functions.
  • Do NOT use \x3Call_urls> host permission unless absolutely necessary.
  • Do NOT rely on DevTools keeping the service worker alive during testing.
  • Do NOT forget return true in async message listeners.
  • Do NOT use localStorage or sessionStorage in service workers (they don't exist there).
  • Do NOT assume content scripts survive extension updates.
  • Do NOT use webRequest blocking (removed in MV3). Use declarativeNetRequest.
  • Do NOT use chrome.extension.getBackgroundPage() (removed in MV3).
安全使用建议
This is a thorough, internally consistent MV3 extension developer guide — suitable if you want help building or debugging extensions. Before using examples verbatim, be aware the references describe powerful, potentially dangerous techniques (CSP-relay patterns, removing/modifying CSP via declarativeNetRequest, dynamic rules, relaying Authorization headers, persistent dynamic content script registration). Those are legitimate for some extension use-cases but increase attack surface and may violate Chrome Web Store policies if misused. Recommendations: (1) review and restrict any allowlists (ALLOWED_ORIGINS) before enabling relays; (2) avoid removing CSP headers broadly — scope any declarativeNetRequest modifications narrowly and document intent; (3) use optional_host_permissions and least-privilege host patterns; (4) treat the code samples as starting points to be audited, tested, and hardened; (5) don't copy secrets into content scripts or page-injected code. If you need higher assurance, request a review of any produced manifest or service-worker code before publishing.
功能分析
Type: OpenClaw Skill Name: chrome-extension Version: 1.0.2 The `chrome-extension` skill bundle is a comprehensive educational resource for building Chrome extensions using Manifest V3. It provides detailed reference files (`references/*.md`) and architectural guidance in `SKILL.md`. The code snippets demonstrate standard patterns for messaging, storage, and UI development. No malicious intent, data exfiltration, or harmful prompt injections were identified; the bundle is purely technical documentation designed to assist developers.
能力标签
cryptorequires-oauth-token
能力评估
Purpose & Capability
Name/description (Chrome extension MV3 guide) align with the contents: many detailed reference files about manifest, service worker, content scripts, messaging, CSP/relays, publishing, etc. Declared required binaries (git, node, npm) make sense for a coding agent creating or building extensions.
Instruction Scope
SKILL.md is a routing/guide document and the referenced files contain step-by-step patterns. Several references explicitly cover techniques with strong security implications: relay patterns to bypass page CSP (service-worker relay), use of declarativeNetRequest to remove/modify response headers (including CSP), dynamic registration of persistent content scripts, and examples passing Authorization headers via relay. Those techniques are legitimate for extension development but are powerful and must be used with strict allowlists and review; the skill documents them directly rather than restricting or warning strongly.
Install Mechanism
Instruction-only (no install spec, no downloads, no code files that execute on the host). Low-risk from installation perspective — nothing is written or fetched at install time.
Credentials
No environment variables, no credentials, no config paths requested. Allowed tools (git, npm) are reasonable for developing/building extensions. There are no unrelated credentials or secrets requested.
Persistence & Privilege
always:false and user-invocable:true (normal). The skill does not request to modify other skills or system-wide settings. It documents extension behaviors that affect browser-wide state (declarativeNetRequest rules, host_permissions) — which is expected for extension development — but it does not itself request persistent platform privileges.
如何使用
  1. 确保已安装 OpenClaw(本地或 Docker 部署)
  2. 在对话框中输入安装命令:/install chrome-extension
  3. 安装完成后,直接呼叫该 Skill 的名称或使用 /chrome-extension 触发
  4. 根据 Skill 的参数说明提供必要输入,即可获得结构化输出
版本历史
v1.0.2
Version 1.0.2 - Updated metadata version to 1.0.2. - Added AskUserQuestion to allowed tools. - Minor formatting fixes in the reference table and documentation. - No functional or structural changes to the skill’s content or routing logic.
v1.0.0
- Initial release of the "chrome-extension" skill. - Provides a comprehensive guide for building Chrome extensions with Manifest V3. - Includes coverage of all Chrome extension APIs, injection, messaging, CSP bypass, and publishing. - Organized reference files for quick access to implementation details per feature (manifest, service worker, UI surfaces, messaging, storage, permissions, etc.). - Contains architectural overviews and communication flow diagrams for extension contexts. - Designed for both new and existing extension projects, with compatibility for Claude Code or similar coding agents.
元数据
Slug chrome-extension
版本 1.0.2
许可证 MIT-0
累计安装 1
当前安装数 1
历史版本数 2
常见问题

Chrome Extension 是什么?

Comprehensive guide for building Chrome extensions with Manifest V3. Use this skill whenever the user mentions Chrome extension, browser extension, manifest.... 它是一个面向 Claude Code / OpenClaw 的 AI Agent Skill 插件,目前累计下载 252 次。

如何安装 Chrome Extension?

在 OpenClaw 或 Claude Code 对话框中运行命令「/install chrome-extension」即可一键安装,无需额外配置。

Chrome Extension 是免费的吗?

是的,Chrome Extension 完全免费,采用 MIT-0 许可证,可自由下载、安装和使用。

Chrome Extension 支持哪些平台?

Chrome Extension 跨平台运行,可在任意部署了 OpenClaw / Claude Code 的环境中使用(cross-platform)。

谁开发了 Chrome Extension?

由 Samuel Berthe(@samber)开发并维护,当前版本 v1.0.2。

💬 留言讨论