From magic-powers
Design and configure Manifest V3 browser extensions — service workers, permissions, declarative rules, and migration from MV2.
npx claudepluginhub kienbui1995/magic-powers --plugin magic-powersThis skill uses the workspace's default tool permissions.
- Starting a new browser extension project
Generates design tokens/docs from CSS/Tailwind/styled-components codebases, audits visual consistency across 10 dimensions, detects AI slop in UI.
Records polished WebM UI demo videos of web apps using Playwright with cursor overlay, natural pacing, and three-phase scripting. Activates for demo, walkthrough, screen recording, or tutorial requests.
Delivers idiomatic Kotlin patterns for null safety, immutability, sealed classes, coroutines, Flows, extensions, DSL builders, and Gradle DSL. Use when writing, reviewing, refactoring, or designing Kotlin code.
Required fields:
{
"manifest_version": 3,
"name": "My Extension",
"version": "1.0.0",
"description": "...",
"permissions": [],
"host_permissions": [],
"background": {
"service_worker": "background.js",
"type": "module"
},
"action": {
"default_popup": "popup.html",
"default_icon": "icons/icon48.png"
},
"icons": { "16": "icons/icon16.png", "48": "icons/icon48.png", "128": "icons/icon128.png" },
"content_scripts": [],
"web_accessible_resources": []
}
permissions = extension APIs (storage, tabs, contextMenus, alarms, notifications)host_permissions = website access (*://*.example.com/* or <all_urls>)optional_permissions for features users might not need<all_urls>, webNavigation, history, bookmarksKey differences from MV2 background pages:
chrome.storage (not global variables) to persist datachrome.alarms API// ✅ Correct — top-level listener
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
// handle message
return true; // keep channel open for async response
});
// ❌ Wrong — listener inside async callback
chrome.tabs.query({}, (tabs) => {
chrome.runtime.onMessage.addListener(...); // never registered reliably
});
declarativeNetRequest for URL blocking/redirecting{
"declarative_net_request": {
"rule_resources": [{ "id": "ruleset_1", "enabled": true, "path": "rules.json" }]
}
}
eval()web_accessible_resources for resources injected into pagesmanifest_version: 3 (not 2)?chrome.storage not in-memory state?host_permissions scoped as narrowly as possible?<all_urls>), persistent state in service workerchrome.storage.session or chrome.storage.local, not global varsreturn true in onMessage listener is required to keep the message channel open for async responsesweb_accessible_resources must explicitly list files injected into pages