web-extension 0.0.0-stage → 2.0.0

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.
Files changed (53) hide show
  1. package/AI.md +270 -0
  2. package/DEVELOPER.md +122 -0
  3. package/LICENSE +21 -0
  4. package/README.md +140 -2
  5. package/dist/index.js +2125 -0
  6. package/dist/index.js.map +1 -0
  7. package/package.json +54 -4
  8. package/templates/base/_gitignore +6 -0
  9. package/templates/base/public/icons/128.png +0 -0
  10. package/templates/base/public/icons/16.png +0 -0
  11. package/templates/base/public/icons/48.png +0 -0
  12. package/templates/features/background/js/src/background/index.js +6 -0
  13. package/templates/features/background/ts/src/background/index.ts +6 -0
  14. package/templates/features/content/content-only/js/src/content/index.js +32 -0
  15. package/templates/features/content/content-only/ts/src/content/index.ts +32 -0
  16. package/templates/features/content/full/js/src/content/index.js +6 -0
  17. package/templates/features/content/full/ts/src/content/index.ts +6 -0
  18. package/templates/features/content/style.css +16 -0
  19. package/templates/features/devtools/js/src/devtools/devtools.html +9 -0
  20. package/templates/features/devtools/js/src/devtools/devtools.js +11 -0
  21. package/templates/features/devtools/js/src/devtools/panel.html +18 -0
  22. package/templates/features/devtools/ts/src/devtools/devtools.html +9 -0
  23. package/templates/features/devtools/ts/src/devtools/devtools.ts +11 -0
  24. package/templates/features/devtools/ts/src/devtools/panel.html +18 -0
  25. package/templates/features/dnr/rules.json +18 -0
  26. package/templates/features/extras/storage/js/src/lib/storage.js +31 -0
  27. package/templates/features/extras/storage/ts/src/lib/storage.ts +15 -0
  28. package/templates/features/newtab/js/src/newtab/index.html +17 -0
  29. package/templates/features/newtab/js/src/newtab/main.js +8 -0
  30. package/templates/features/newtab/js/src/newtab/style.css +30 -0
  31. package/templates/features/newtab/ts/src/newtab/index.html +17 -0
  32. package/templates/features/newtab/ts/src/newtab/main.ts +8 -0
  33. package/templates/features/newtab/ts/src/newtab/style.css +30 -0
  34. package/templates/features/options/js/src/options/index.html +21 -0
  35. package/templates/features/options/js/src/options/main.js +11 -0
  36. package/templates/features/options/js/src/options/style.css +37 -0
  37. package/templates/features/options/ts/src/options/index.html +21 -0
  38. package/templates/features/options/ts/src/options/main.ts +11 -0
  39. package/templates/features/options/ts/src/options/style.css +37 -0
  40. package/templates/features/popup/js/src/popup/index.html +18 -0
  41. package/templates/features/popup/js/src/popup/main.js +9 -0
  42. package/templates/features/popup/js/src/popup/style.css +39 -0
  43. package/templates/features/popup/ts/src/popup/index.html +18 -0
  44. package/templates/features/popup/ts/src/popup/main.ts +9 -0
  45. package/templates/features/popup/ts/src/popup/style.css +39 -0
  46. package/templates/features/sidepanel/js/src/sidepanel/index.html +17 -0
  47. package/templates/features/sidepanel/js/src/sidepanel/main.js +7 -0
  48. package/templates/features/sidepanel/js/src/sidepanel/style.css +25 -0
  49. package/templates/features/sidepanel/ts/src/sidepanel/index.html +17 -0
  50. package/templates/features/sidepanel/ts/src/sidepanel/main.ts +7 -0
  51. package/templates/features/sidepanel/ts/src/sidepanel/style.css +25 -0
  52. package/templates/js/src/lib/browser.js +9 -0
  53. package/templates/ts/src/lib/browser.ts +9 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/utils/validate.ts","../src/cli/args.ts","../src/cli/prompts.ts","../src/utils/pm.ts","../src/utils/exec.ts","../src/generate/index.ts","../src/generate/targets.ts","../src/generate/manifest.ts","../src/generate/pkgjson.ts","../src/generate/tsconfig.ts","../src/generate/copy.ts"],"sourcesContent":["#!/usr/bin/env node\nimport * as p from '@clack/prompts';\nimport pico from 'picocolors';\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { parseCliArgs, printHelp, validateFlagCombinations } from './cli/args.js';\nimport { runPrompts } from './cli/prompts.js';\nimport { generateProject } from './generate/index.js';\nimport { getInstallCommand, getRunCommand } from './utils/pm.js';\nimport { isCommandAvailable, runCommand } from './utils/exec.js';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\nfunction getCliVersion(): string {\n try {\n const pkgPath = path.resolve(__dirname, '../package.json');\n if (fs.existsSync(pkgPath)) {\n const data = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));\n return data.version || '2.0.0';\n }\n } catch {\n }\n return '2.0.0';\n}\n\nasync function main(): Promise<void> {\n const rawArgs = process.argv.slice(2);\n let parsedArgs;\n\n try {\n parsedArgs = parseCliArgs(rawArgs);\n } catch (err: any) {\n console.error(pico.red(`Error: ${err.message}`));\n process.exit(1);\n }\n\n if (parsedArgs.help) {\n printHelp();\n process.exit(0);\n }\n\n if (parsedArgs.version) {\n console.log(`web-extension v${getCliVersion()}`);\n process.exit(0);\n }\n\n try {\n validateFlagCombinations(parsedArgs);\n } catch (err: any) {\n console.error(pico.red(`Configuration Error: ${err.message}`));\n process.exit(1);\n }\n\n p.intro(pico.bold(pico.cyan('web-extension scaffold')));\n\n for (const warning of parsedArgs.warnings) {\n p.log.warn(warning);\n }\n\n let ctx;\n try {\n ctx = await runPrompts(parsedArgs);\n } catch (err: any) {\n console.error(pico.red(`Error: ${err.message}`));\n process.exit(1);\n }\n\n if (ctx.ifExists === 'overwrite' && fs.existsSync(ctx.targetDir)) {\n const entries = fs.readdirSync(ctx.targetDir);\n for (const entry of entries) {\n fs.rmSync(path.join(ctx.targetDir, entry), { recursive: true, force: true });\n }\n }\n\n const s = p.spinner();\n s.start('Generating project files...');\n try {\n generateProject(ctx);\n s.stop('Project files created successfully.');\n } catch (err: any) {\n s.stop('Failed to generate project files.');\n console.error(pico.red(err.message));\n process.exit(1);\n }\n\n if (ctx.git) {\n s.start('Initializing git repository...');\n const gitRes = await runCommand('git', ['init'], ctx.targetDir);\n if (gitRes.success) {\n s.stop('Git repository initialized.');\n } else {\n s.stop('Skipped git initialization.');\n p.log.warn(`Git init failed: ${gitRes.error}`);\n }\n }\n\n if (ctx.install) {\n const pmAvailable = await isCommandAvailable(ctx.pm);\n if (!pmAvailable) {\n p.log.warn(\n `Package manager \"${ctx.pm}\" is not found in PATH. Skipping dependency installation.`,\n );\n p.log.info(`Please run \"${getInstallCommand(ctx.pm)}\" manually.`);\n } else {\n s.start(`Installing dependencies with ${ctx.pm}...`);\n const installCmd = ctx.pm === 'yarn' ? [] : ['install'];\n const installRes = await runCommand(ctx.pm, installCmd, ctx.targetDir);\n if (installRes.success) {\n s.stop('Dependencies installed successfully.');\n } else {\n s.stop('Failed to install dependencies.');\n p.log.warn(`Installation failed: ${installRes.error}`);\n p.log.info(`You can try running \"${getInstallCommand(ctx.pm)}\" manually.`);\n }\n }\n }\n\n const relPath = path.relative(process.cwd(), ctx.targetDir);\n const cdInstruction = relPath && relPath !== '.' ? `cd ${relPath}\\n ` : '';\n const firstBrowser = ctx.browsers[0];\n const devCommand = getRunCommand(ctx.pm, `dev:${firstBrowser}`);\n\n p.outro(\n pico.green(\n `Done! To get started:\\n\\n ${pico.bold(\n `${cdInstruction}${devCommand}`,\n )}\\n`,\n ),\n );\n}\n\nmain().catch((err) => {\n console.error(pico.red(`Fatal Error: ${err.message}`));\n process.exit(1);\n});\n\n","import path from 'node:path';\n\n/**\n * Validates npm package name.\n * Rules:\n * - non-empty\n * - lowercase\n * - no spaces\n * - only URL-friendly characters (lowercase letters, numbers, hyphens, dots, underscores, @, /)\n * - cannot start with dot or underscore\n */\nexport function validatePackageName(name: string): true | string {\n if (!name || name.trim().length === 0) {\n return 'Project name cannot be empty.';\n }\n const trimmed = name.trim();\n if (trimmed !== trimmed.toLowerCase()) {\n return 'Project name must be lowercase.';\n }\n if (/\\s/.test(trimmed)) {\n return 'Project name cannot contain spaces.';\n }\n if (trimmed.startsWith('.') || trimmed.startsWith('_')) {\n return 'Project name cannot start with a dot or underscore.';\n }\n if (!/^(?:@[a-z0-9-*~][a-z0-9-*._~]*\\/)?[a-z0-9-~][a-z0-9-._~]*$/.test(trimmed)) {\n return 'Project name contains invalid characters for an npm package.';\n }\n if (encodeURIComponent(trimmed) !== trimmed && !trimmed.startsWith('@')) {\n return 'Project name must be URL-safe.';\n }\n return true;\n}\n\n/**\n * Derives valid package name from path or string.\n */\nexport function getPackageName(input: string): string {\n const base = path.basename(path.resolve(input));\n return base.toLowerCase().replace(/[^a-z0-9-_]/g, '-').replace(/^-+|-+$/g, '') || 'my-extension';\n}\n\n/**\n * Validates match patterns for Chrome/Firefox/Safari content scripts.\n * Must start with http://, https://, *://, file://, or be <all_urls>\n */\nexport function validateMatchPattern(pattern: string): true | string {\n const p = pattern.trim();\n if (!p) {\n return 'Match pattern cannot be empty.';\n }\n if (p === '<all_urls>') {\n return true;\n }\n const validSchemes = ['http://', 'https://', '*://', 'file://'];\n const hasValidScheme = validSchemes.some((scheme) => p.startsWith(scheme));\n if (!hasValidScheme) {\n return `Invalid match pattern \"${p}\". Must start with http://, https://, *://, file://, or be <all_urls>`;\n }\n return true;\n}\n\nexport function parseAndValidateMatches(input: string | string[]): { valid: true; matches: string[] } | { valid: false; error: string } {\n const list = Array.isArray(input)\n ? input\n : input.split(',').map((s) => s.trim()).filter(Boolean);\n\n if (list.length === 0) {\n return { valid: false, error: 'At least one match pattern is required.' };\n }\n\n for (const item of list) {\n const res = validateMatchPattern(item);\n if (res !== true) {\n return { valid: false, error: res };\n }\n }\n\n return { valid: true, matches: list };\n}\n\nexport function toSlug(str: string): string {\n return str\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '') || 'extension';\n}\n\n","import type {\n BrowserKey,\n ContentScriptRunAt,\n ContentScriptWorld,\n ExtraKey,\n FeatureKey,\n IfExistsAction,\n Language,\n ManifestVersion,\n PackageManager,\n ProjectType,\n} from './context.js';\nimport { parseAndValidateMatches } from '../utils/validate.js';\n\nexport interface ParsedArgs {\n subcommand?: string;\n dir?: string;\n name?: string;\n ifExists?: IfExistsAction;\n lang?: Language;\n type?: ProjectType;\n browser?: BrowserKey[];\n firefoxMv?: ManifestVersion;\n safariMv?: ManifestVersion;\n features?: FeatureKey[];\n matches?: string[];\n runAt?: ContentScriptRunAt;\n world?: ContentScriptWorld;\n css?: boolean;\n extras?: ExtraKey[];\n pm?: PackageManager;\n install?: boolean;\n git?: boolean;\n yes?: boolean;\n help?: boolean;\n version?: boolean;\n rawFlags: Record<string, any>;\n warnings: string[];\n}\n\nconst VALID_BROWSERS = ['chrome', 'firefox', 'safari', 'chromium'];\nconst VALID_LANGS = ['ts', 'js', 'typescript', 'javascript'];\nconst VALID_TYPES = ['full', 'content-only'];\nconst VALID_MVS = ['2', '3'];\nconst VALID_FEATURES: FeatureKey[] = [\n 'background',\n 'content',\n 'popup',\n 'options',\n 'sidepanel',\n 'dnr',\n 'devtools',\n 'newtab',\n];\nconst VALID_EXTRAS: ExtraKey[] = [\n 'contextmenu',\n 'commands',\n 'omnibox',\n 'storage',\n];\nconst VALID_RUN_AT: ContentScriptRunAt[] = [\n 'document_start',\n 'document_end',\n 'document_idle',\n];\nconst VALID_WORLD: ContentScriptWorld[] = ['ISOLATED', 'MAIN'];\nconst VALID_IF_EXISTS: IfExistsAction[] = ['cancel', 'overwrite', 'merge'];\nconst VALID_PM: PackageManager[] = ['npm', 'pnpm', 'yarn', 'bun'];\n\nexport function parseCliArgs(argv: string[]): ParsedArgs {\n const result: ParsedArgs = {\n rawFlags: {},\n warnings: [],\n };\n\n const positionals: string[] = [];\n const browserList: BrowserKey[] = [];\n\n let i = 0;\n while (i < argv.length) {\n const arg = argv[i];\n\n if (arg === '--help' || arg === '-h') {\n result.help = true;\n i++;\n } else if (arg === '--version' || arg === '-v') {\n result.version = true;\n i++;\n } else if (arg === '--yes' || arg === '-y') {\n result.yes = true;\n i++;\n } else if (arg === '--overwrite') {\n result.ifExists = 'overwrite';\n result.rawFlags['ifExists'] = 'overwrite';\n i++;\n } else if (arg === '--css') {\n result.css = true;\n result.rawFlags['css'] = true;\n i++;\n } else if (arg === '--no-css') {\n result.css = false;\n result.rawFlags['css'] = false;\n i++;\n } else if (arg === '--install') {\n result.install = true;\n result.rawFlags['install'] = true;\n i++;\n } else if (arg === '--no-install') {\n result.install = false;\n result.rawFlags['install'] = false;\n i++;\n } else if (arg === '--git') {\n result.git = true;\n result.rawFlags['git'] = true;\n i++;\n } else if (arg === '--no-git') {\n result.git = false;\n result.rawFlags['git'] = false;\n i++;\n } else if (arg.startsWith('--')) {\n const eqIdx = arg.indexOf('=');\n let flag = arg.slice(2);\n let val: string | undefined;\n\n if (eqIdx !== -1) {\n flag = arg.slice(2, eqIdx);\n val = arg.slice(eqIdx + 1);\n } else if (i + 1 < argv.length && !argv[i + 1].startsWith('-')) {\n val = argv[++i];\n }\n\n if (val === undefined) {\n throw new Error(`Flag --${flag} requires a value.`);\n }\n\n switch (flag) {\n case 'name':\n result.name = val;\n result.rawFlags['name'] = val;\n break;\n case 'if-exists':\n if (!VALID_IF_EXISTS.includes(val as IfExistsAction)) {\n throw new Error(\n `Invalid value \"${val}\" for --if-exists. Expected one of: ${VALID_IF_EXISTS.join(', ')}`,\n );\n }\n result.ifExists = val as IfExistsAction;\n result.rawFlags['ifExists'] = val;\n break;\n case 'lang':\n if (!VALID_LANGS.includes(val.toLowerCase())) {\n throw new Error(\n `Invalid value \"${val}\" for --lang. Expected one of: ts, js`,\n );\n }\n result.lang = (val.toLowerCase() === 'javascript' || val.toLowerCase() === 'js') ? 'js' : 'ts';\n result.rawFlags['lang'] = result.lang;\n break;\n case 'type':\n if (!VALID_TYPES.includes(val.toLowerCase())) {\n throw new Error(\n `Invalid value \"${val}\" for --type. Expected one of: ${VALID_TYPES.join(', ')}`,\n );\n }\n result.type = val.toLowerCase() as ProjectType;\n result.rawFlags['type'] = result.type;\n break;\n case 'browser':\n case 'browsers': {\n const parts = val.split(',').map((s) => s.trim().toLowerCase());\n for (const b of parts) {\n if (!VALID_BROWSERS.includes(b)) {\n throw new Error(\n `Invalid value \"${b}\" for --browser. Expected one of: chrome, firefox, safari`,\n );\n }\n const mapped: BrowserKey = b === 'chromium' ? 'chrome' : (b as BrowserKey);\n if (!browserList.includes(mapped)) {\n browserList.push(mapped);\n }\n }\n result.browser = browserList;\n result.rawFlags['browser'] = browserList;\n break;\n }\n case 'firefox-mv':\n if (!VALID_MVS.includes(val)) {\n throw new Error(\n `Invalid value \"${val}\" for --firefox-mv. Expected 2 or 3.`,\n );\n }\n result.firefoxMv = parseInt(val, 10) as ManifestVersion;\n result.rawFlags['firefoxMv'] = result.firefoxMv;\n break;\n case 'safari-mv':\n if (!VALID_MVS.includes(val)) {\n throw new Error(\n `Invalid value \"${val}\" for --safari-mv. Expected 2 or 3.`,\n );\n }\n result.safariMv = parseInt(val, 10) as ManifestVersion;\n result.rawFlags['safariMv'] = result.safariMv;\n break;\n case 'features': {\n if (val.trim().toLowerCase() === 'none') {\n result.features = [];\n } else {\n const list = val.split(',').map((s) => s.trim().toLowerCase() as FeatureKey);\n for (const f of list) {\n if (!VALID_FEATURES.includes(f)) {\n throw new Error(\n `Invalid feature \"${f}\". Expected one of: ${VALID_FEATURES.join(', ')} (or none)`,\n );\n }\n }\n result.features = Array.from(new Set(list));\n }\n result.rawFlags['features'] = result.features;\n break;\n }\n case 'matches': {\n const matchRes = parseAndValidateMatches(val);\n if (!matchRes.valid) {\n throw new Error(matchRes.error);\n }\n result.matches = matchRes.matches;\n result.rawFlags['matches'] = result.matches;\n break;\n }\n case 'run-at':\n if (!VALID_RUN_AT.includes(val as ContentScriptRunAt)) {\n throw new Error(\n `Invalid value \"${val}\" for --run-at. Expected one of: ${VALID_RUN_AT.join(', ')}`,\n );\n }\n result.runAt = val as ContentScriptRunAt;\n result.rawFlags['runAt'] = result.runAt;\n break;\n case 'world':\n if (!VALID_WORLD.includes(val.toUpperCase() as ContentScriptWorld)) {\n throw new Error(\n `Invalid value \"${val}\" for --world. Expected ISOLATED or MAIN`,\n );\n }\n result.world = val.toUpperCase() as ContentScriptWorld;\n result.rawFlags['world'] = result.world;\n break;\n case 'extras': {\n if (val.trim().toLowerCase() === 'none') {\n result.extras = [];\n } else {\n const list = val.split(',').map((s) => s.trim().toLowerCase() as ExtraKey);\n for (const e of list) {\n if (!VALID_EXTRAS.includes(e)) {\n throw new Error(\n `Invalid extra \"${e}\". Expected one of: ${VALID_EXTRAS.join(', ')} (or none)`,\n );\n }\n }\n result.extras = Array.from(new Set(list));\n }\n result.rawFlags['extras'] = result.extras;\n break;\n }\n case 'pm':\n if (!VALID_PM.includes(val.toLowerCase() as PackageManager)) {\n throw new Error(\n `Invalid value \"${val}\" for --pm. Expected one of: ${VALID_PM.join(', ')}`,\n );\n }\n result.pm = val.toLowerCase() as PackageManager;\n result.rawFlags['pm'] = result.pm;\n break;\n default:\n throw new Error(`Unknown option --${flag}. Run with --help to see valid options.`);\n }\n i++;\n } else {\n positionals.push(arg);\n i++;\n }\n }\n\n if (positionals.length > 0) {\n if (positionals[0] === 'init') {\n result.subcommand = 'init';\n if (positionals.length > 1) {\n result.dir = positionals[1];\n }\n } else {\n result.subcommand = 'init';\n result.dir = positionals[0];\n }\n } else {\n result.subcommand = 'init';\n }\n\n return result;\n}\n\nexport function validateFlagCombinations(args: ParsedArgs): void {\n if (args.help || args.version) {\n return;\n }\n\n const isContentOnly = args.type === 'content-only';\n\n if (isContentOnly && (args.features !== undefined || args.extras !== undefined)) {\n throw new Error(\n 'Cannot specify --features or --extras when --type is content-only.',\n );\n }\n\n const browsers = args.browser || ['chrome'];\n const hasOnlySafari = browsers.length === 1 && browsers[0] === 'safari';\n\n if (args.features?.includes('sidepanel') && hasOnlySafari) {\n throw new Error('Side panel feature is not supported when targeting only Safari.');\n }\n\n const hasFirefoxMv2 = browsers.includes('firefox') && args.firefoxMv === 2;\n const hasSafariMv2 = browsers.includes('safari') && args.safariMv === 2;\n const anyMv2 = hasFirefoxMv2 || hasSafariMv2;\n\n if (args.features?.includes('dnr') && anyMv2) {\n throw new Error(\n 'DeclarativeNetRequest (DNR) is not supported with Manifest V2 targets.',\n );\n }\n\n const hasBackground = !isContentOnly && (args.features === undefined || args.features.includes('background'));\n if (args.extras?.some((e) => ['contextmenu', 'commands', 'omnibox'].includes(e))) {\n if (!hasBackground) {\n throw new Error(\n 'Extras contextmenu, commands, and omnibox require background feature.',\n );\n }\n }\n\n if (args.world === 'MAIN' && anyMv2) {\n throw new Error('Content script world MAIN is only supported in Manifest V3.');\n }\n\n if (args.firefoxMv !== undefined && !browsers.includes('firefox')) {\n args.warnings.push('--firefox-mv specified without Firefox target.');\n }\n if (args.safariMv !== undefined && !browsers.includes('safari')) {\n args.warnings.push('--safari-mv specified without Safari target.');\n }\n if (!isContentOnly && args.features !== undefined && !args.features.includes('content')) {\n if (args.matches !== undefined || args.runAt !== undefined || args.world !== undefined || args.css !== undefined) {\n args.warnings.push('Content script options specified but content feature was not selected.');\n }\n }\n}\n\nexport function printHelp(): void {\n console.log(`\nweb-extension [init] [dir] [options]\n\nOptions:\n [dir] Target directory (defaults to current or prompt)\n --name <string> Project name (defaults to basename of dir or \"my-extension\")\n --if-exists <action> Action if directory exists: cancel, overwrite, merge (default: cancel)\n --overwrite Shorthand for --if-exists overwrite\n --lang <ts|js> Project language: ts (TypeScript) or js (JavaScript) (default: ts)\n --type <type> Project type: full or content-only (default: full)\n --browser <browsers> Target browsers: chrome, firefox, safari (default: chrome)\n --firefox-mv <2|3> Manifest version for Firefox (default: 3)\n --safari-mv <2|3> Manifest version for Safari (default: 3)\n --features <list> Comma-separated features: background,content,popup,options,sidepanel,dnr,devtools,newtab (or \"none\")\n --matches <patterns> Content script match patterns (default: https://*/*)\n --run-at <timing> Content script run timing: document_start, document_end, document_idle (default: document_idle)\n --world <world> Execution world: ISOLATED or MAIN (default: ISOLATED)\n --css / --no-css Generate CSS for content script (default: --css)\n --extras <list> Extras: contextmenu,commands,omnibox,storage (or \"none\")\n --pm <pm> Package manager override: npm, pnpm, yarn, bun\n --install / --no-install Install dependencies automatically (default: --install)\n --git / --no-git Initialize git repository (default: --git)\n --yes, -y Use defaults for all unanswered questions\n --help, -h Show this help message\n --version, -v Show version number\n`);\n}\n\n","import * as p from '@clack/prompts';\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport type { ParsedArgs } from './args.js';\nimport type {\n BrowserKey,\n ContentScriptRunAt,\n ContentScriptWorld,\n Context,\n ExtraKey,\n FeatureKey,\n IfExistsAction,\n Language,\n ManifestVersion,\n PackageManager,\n ProjectType,\n} from './context.js';\nimport {\n getPackageName,\n parseAndValidateMatches,\n validatePackageName,\n} from '../utils/validate.js';\nimport {\n detectPackageManager,\n formatPmSource,\n} from '../utils/pm.js';\nimport { isInsideGitRepo } from '../utils/exec.js';\n\nexport async function runPrompts(args: ParsedArgs): Promise<Context> {\n const isTTY = Boolean(process.stdin.isTTY && process.stdout.isTTY);\n const useDefaults = Boolean(args.yes);\n\n function handleCancel<T>(value: T | symbol): T {\n if (p.isCancel(value)) {\n p.cancel('Operation cancelled.');\n process.exit(0);\n }\n return value as T;\n }\n\n let projectName = args.name;\n let targetDir = args.dir;\n\n if (!projectName && !targetDir) {\n if (!isTTY && !useDefaults) {\n throw new Error('Missing project name or target directory. Provide [dir] or --name.');\n }\n if (useDefaults) {\n projectName = 'my-extension';\n targetDir = 'my-extension';\n } else {\n const nameInput = handleCancel(\n await p.text({\n message: 'Project name:',\n placeholder: 'my-extension',\n defaultValue: 'my-extension',\n validate(val) {\n const trimmed = val ? val.trim() : '';\n if (!trimmed) return 'Project name cannot be empty.';\n const check = validatePackageName(trimmed);\n return check === true ? undefined : check;\n },\n }),\n );\n projectName = (nameInput as string).trim();\n targetDir = projectName;\n }\n } else if (!projectName && targetDir) {\n projectName = getPackageName(targetDir);\n } else if (projectName && !targetDir) {\n targetDir = projectName;\n }\n\n const resolvedTargetDir = path.resolve(targetDir!);\n\n let ifExists: IfExistsAction = args.ifExists || 'cancel';\n const dirExists = fs.existsSync(resolvedTargetDir);\n const dirHasFiles = dirExists && fs.readdirSync(resolvedTargetDir).length > 0;\n\n if (dirHasFiles && !args.ifExists) {\n if (!isTTY && !useDefaults) {\n throw new Error(\n `Target directory \"${targetDir}\" is not empty. Specify --if-exists or --overwrite.`,\n );\n }\n if (useDefaults) {\n throw new Error(\n `Target directory \"${targetDir}\" is not empty and default action is cancel.`,\n );\n }\n ifExists = handleCancel(\n await p.select({\n message: `Target directory \"${targetDir}\" is not empty. How to proceed?`,\n options: [\n { value: 'cancel', label: 'Cancel', hint: 'Exit without modifying files' },\n { value: 'overwrite', label: 'Overwrite', hint: 'Delete existing files and proceed' },\n { value: 'merge', label: 'Merge', hint: 'Keep existing files and add extension files' },\n ],\n initialValue: 'cancel',\n }),\n ) as IfExistsAction;\n\n if (ifExists === 'cancel') {\n p.cancel('Operation cancelled.');\n process.exit(0);\n }\n }\n\n let language: Language = args.lang || (useDefaults ? 'ts' : (undefined as any));\n if (!language) {\n if (!isTTY) throw new Error('Missing --lang flag in non-interactive environment.');\n language = handleCancel(\n await p.select({\n message: 'Select language:',\n options: [\n { value: 'ts', label: 'TypeScript', hint: 'Recommended' },\n { value: 'js', label: 'JavaScript' },\n ],\n initialValue: 'ts',\n }),\n ) as Language;\n }\n\n let projectType: ProjectType = args.type || (useDefaults ? 'full' : (undefined as any));\n if (!projectType) {\n if (!isTTY) throw new Error('Missing --type flag in non-interactive environment.');\n projectType = handleCancel(\n await p.select({\n message: 'Select project type:',\n options: [\n { value: 'full', label: 'Full extension', hint: 'Background, popup, options, content scripts, etc.' },\n { value: 'content-only', label: 'Content script only', hint: 'DOM injector/script with no extension UI' },\n ],\n initialValue: 'full',\n }),\n ) as ProjectType;\n }\n\n let browsers: BrowserKey[] = args.browser?.length\n ? args.browser\n : (useDefaults ? ['chrome'] : (undefined as any));\n\n if (!browsers) {\n if (!isTTY) throw new Error('Missing --browser flag in non-interactive environment.');\n browsers = handleCancel(\n await p.multiselect({\n message: 'Select target browsers:',\n options: [\n { value: 'chrome', label: 'Chromium (Chrome, Edge, Brave, Opera)', hint: 'default' },\n { value: 'firefox', label: 'Firefox' },\n { value: 'safari', label: 'Safari' },\n ],\n initialValues: ['chrome'],\n required: true,\n }),\n ) as BrowserKey[];\n }\n\n let firefoxMv: ManifestVersion | undefined = args.firefoxMv;\n if (browsers.includes('firefox') && firefoxMv === undefined) {\n if (useDefaults) {\n firefoxMv = 3;\n } else if (!isTTY) {\n throw new Error('Missing --firefox-mv flag in non-interactive environment.');\n } else {\n firefoxMv = handleCancel(\n await p.select({\n message: 'Manifest version for Firefox:',\n options: [\n { value: 3, label: 'MV3', hint: 'Recommended modern standard' },\n { value: 2, label: 'MV2', hint: 'Legacy background page' },\n ],\n initialValue: 3,\n }),\n ) as ManifestVersion;\n }\n }\n\n let safariMv: ManifestVersion | undefined = args.safariMv;\n if (browsers.includes('safari') && safariMv === undefined) {\n if (useDefaults) {\n safariMv = 3;\n } else if (!isTTY) {\n throw new Error('Missing --safari-mv flag in non-interactive environment.');\n } else {\n safariMv = handleCancel(\n await p.select({\n message: 'Manifest version for Safari:',\n options: [\n { value: 3, label: 'MV3', hint: 'Recommended modern standard' },\n { value: 2, label: 'MV2', hint: 'Legacy extension converter target' },\n ],\n initialValue: 3,\n }),\n ) as ManifestVersion;\n }\n }\n\n const anyMv2 =\n (browsers.includes('firefox') && firefoxMv === 2) ||\n (browsers.includes('safari') && safariMv === 2);\n const onlySafari = browsers.length === 1 && browsers[0] === 'safari';\n\n let features: FeatureKey[] = [];\n if (projectType === 'full') {\n if (args.features !== undefined) {\n features = args.features;\n } else if (useDefaults) {\n features = ['background', 'content'];\n } else if (!isTTY) {\n throw new Error('Missing --features flag in non-interactive environment.');\n } else {\n const featureOptions: { value: FeatureKey; label: string; hint?: string }[] = [\n { value: 'background', label: 'Background', hint: 'Service worker or background script' },\n { value: 'content', label: 'Content script', hint: 'Inject scripts and styles into webpages' },\n { value: 'popup', label: 'Popup', hint: 'Toolbar action popup HTML dialog' },\n { value: 'options', label: 'Options page', hint: 'Extension settings interface' },\n ];\n\n if (!onlySafari) {\n featureOptions.push({\n value: 'sidepanel',\n label: 'Side panel',\n hint: browsers.includes('safari') ? 'Not supported on Safari' : undefined,\n });\n }\n\n if (!anyMv2) {\n featureOptions.push({\n value: 'dnr',\n label: 'declarativeNetRequest rules',\n hint: 'Declarative network request blocking/redirect rules',\n });\n }\n\n featureOptions.push({ value: 'devtools', label: 'DevTools page', hint: 'Custom developer tools tab' });\n featureOptions.push({ value: 'newtab', label: 'New tab override', hint: 'Override default new tab page' });\n\n features = handleCancel(\n await p.multiselect({\n message: 'Select extension features:',\n options: featureOptions,\n initialValues: ['background', 'content'],\n required: false,\n }),\n ) as FeatureKey[];\n }\n }\n\n const hasContentScript = projectType === 'content-only' || features.includes('content');\n let contentScriptOptions: Context['contentScript'] = undefined;\n\n if (hasContentScript) {\n let matches: string[] = args.matches || [];\n if (matches.length === 0) {\n if (useDefaults) {\n matches = ['https://*/*'];\n } else if (!isTTY) {\n throw new Error('Missing --matches flag in non-interactive environment.');\n } else {\n const matchesInput = handleCancel(\n await p.text({\n message: 'Content script URL match patterns (comma-separated):',\n placeholder: 'https://*/*',\n defaultValue: 'https://*/*',\n validate(val) {\n const res = parseAndValidateMatches(val || '');\n return res.valid ? undefined : res.error;\n },\n }),\n );\n const parsed = parseAndValidateMatches(matchesInput as string);\n if (parsed.valid) {\n matches = parsed.matches;\n } else {\n matches = ['https://*/*'];\n }\n }\n }\n\n let runAt: ContentScriptRunAt = args.runAt || 'document_idle';\n if (!args.runAt) {\n if (useDefaults) {\n runAt = 'document_idle';\n } else if (!isTTY) {\n throw new Error('Missing --run-at flag in non-interactive environment.');\n } else {\n runAt = handleCancel(\n await p.select({\n message: 'Content script run timing:',\n options: [\n { value: 'document_idle', label: 'document_idle', hint: 'Default, after page finishes loading' },\n { value: 'document_start', label: 'document_start', hint: 'Before any DOM is created' },\n { value: 'document_end', label: 'document_end', hint: 'Immediately after DOM is parsed' },\n ],\n initialValue: 'document_idle',\n }),\n ) as ContentScriptRunAt;\n }\n }\n\n let world: ContentScriptWorld = args.world || 'ISOLATED';\n if (!anyMv2 && args.world === undefined) {\n if (useDefaults) {\n world = 'ISOLATED';\n } else if (!isTTY) {\n world = 'ISOLATED';\n } else {\n world = handleCancel(\n await p.select({\n message: 'Content script execution world:',\n options: [\n { value: 'ISOLATED', label: 'ISOLATED', hint: 'Default, isolated JS execution space' },\n { value: 'MAIN', label: 'MAIN', hint: 'Share DOM and JS context with page scripts' },\n ],\n initialValue: 'ISOLATED',\n }),\n ) as ContentScriptWorld;\n }\n }\n\n let css: boolean = args.css ?? true;\n if (args.css === undefined) {\n if (useDefaults) {\n css = true;\n } else if (!isTTY) {\n css = true;\n } else {\n css = handleCancel(\n await p.confirm({\n message: 'Create CSS style file for content script?',\n initialValue: true,\n }),\n ) as boolean;\n }\n }\n\n contentScriptOptions = {\n matches,\n runAt,\n world,\n css,\n };\n }\n\n let extras: ExtraKey[] = [];\n if (projectType === 'full') {\n if (args.extras !== undefined) {\n extras = args.extras;\n } else if (useDefaults) {\n extras = [];\n } else if (!isTTY) {\n extras = [];\n } else {\n const extraOptions: { value: ExtraKey; label: string; hint?: string }[] = [];\n const hasBackground = features.includes('background');\n\n if (hasBackground) {\n extraOptions.push({\n value: 'contextmenu',\n label: 'Context menu sample',\n hint: 'contextMenus permission + listener',\n });\n extraOptions.push({\n value: 'commands',\n label: 'Keyboard shortcut sample',\n hint: 'commands manifest entry + listener',\n });\n extraOptions.push({\n value: 'omnibox',\n label: 'Omnibox address bar keyword sample',\n hint: 'omnibox keyword + handler',\n });\n }\n\n extraOptions.push({\n value: 'storage',\n label: 'Storage helper library',\n hint: 'Type-safe local storage wrapper in src/lib/storage',\n });\n\n if (extraOptions.length > 0) {\n extras = handleCancel(\n await p.multiselect({\n message: 'Select optional extra samples:',\n options: extraOptions,\n initialValues: [],\n required: false,\n }),\n ) as ExtraKey[];\n }\n }\n }\n\n const detectedPm = detectPackageManager({\n flag: args.pm,\n targetDir: resolvedTargetDir,\n });\n\n let chosenPm: PackageManager = detectedPm.name;\n if (!args.pm && !detectedPm.confident && isTTY && !useDefaults) {\n chosenPm = handleCancel(\n await p.select({\n message: 'Select package manager to use:',\n options: [\n { value: 'npm', label: 'npm' },\n { value: 'pnpm', label: 'pnpm' },\n { value: 'yarn', label: 'yarn' },\n { value: 'bun', label: 'bun' },\n ],\n initialValue: detectedPm.name,\n }),\n ) as PackageManager;\n } else {\n p.log.info(`Using ${chosenPm} (detected from ${formatPmSource(detectedPm.source)})`);\n }\n\n let install: boolean = args.install ?? true;\n if (args.install === undefined) {\n if (useDefaults || !isTTY) {\n install = true;\n } else {\n install = handleCancel(\n await p.confirm({\n message: 'Install dependencies now?',\n initialValue: true,\n }),\n ) as boolean;\n }\n }\n\n let git: boolean = args.git ?? true;\n const alreadyInGit = isInsideGitRepo(resolvedTargetDir);\n if (args.git === undefined) {\n if (alreadyInGit) {\n git = false;\n } else if (useDefaults || !isTTY) {\n git = true;\n } else {\n git = handleCancel(\n await p.confirm({\n message: 'Initialize a new git repository?',\n initialValue: true,\n }),\n ) as boolean;\n }\n } else if (git && alreadyInGit) {\n p.log.warn('Target directory is already inside a git repository; skipping git init.');\n git = false;\n }\n\n return {\n projectName: projectName || 'my-extension',\n targetDir: resolvedTargetDir,\n ifExists,\n language,\n projectType,\n browsers,\n firefoxMv,\n safariMv,\n features,\n contentScript: contentScriptOptions,\n extras,\n pm: chosenPm,\n install,\n git,\n isInteractive: isTTY && !useDefaults,\n };\n}\n","import fs from 'node:fs';\nimport path from 'node:path';\n\nexport type PackageManager = 'npm' | 'pnpm' | 'yarn' | 'bun';\n\nexport type PmSource =\n | 'flag'\n | 'user-agent'\n | 'package-json'\n | 'lockfile'\n | 'global-path'\n | 'runtime'\n | 'prompt'\n | 'default';\n\nexport interface PmResult {\n name: PackageManager;\n source: PmSource;\n confident: boolean;\n}\n\nexport interface DetectPmInput {\n flag?: string;\n env?: Record<string, string | undefined>;\n argv1?: string;\n cwd?: string;\n targetDir?: string;\n versions?: Record<string, string | undefined>;\n fsModule?: {\n existsSync: (p: string) => boolean;\n readFileSync: (p: string, encoding: 'utf-8') => string;\n realpathSync: (p: string) => string;\n };\n}\n\nexport function detectPackageManager(input: DetectPmInput = {}): PmResult {\n const fsImpl = input.fsModule ?? {\n existsSync: fs.existsSync,\n readFileSync: (p: string) => fs.readFileSync(p, 'utf-8'),\n realpathSync: fs.realpathSync,\n };\n\n const env = input.env ?? process.env;\n const argv1 = input.argv1 ?? process.argv[1];\n const versions = input.versions ?? (process.versions as Record<string, string | undefined>);\n\n if (input.flag) {\n const f = input.flag.trim().toLowerCase();\n if (f === 'npm' || f === 'pnpm' || f === 'yarn' || f === 'bun') {\n return { name: f as PackageManager, source: 'flag', confident: true };\n }\n }\n\n const userAgent = env.npm_config_user_agent;\n if (userAgent) {\n const ua = userAgent.trim().toLowerCase();\n if (ua.startsWith('bun/')) {\n return { name: 'bun', source: 'user-agent', confident: true };\n }\n if (ua.startsWith('pnpm/')) {\n return { name: 'pnpm', source: 'user-agent', confident: true };\n }\n if (ua.startsWith('yarn/')) {\n return { name: 'yarn', source: 'user-agent', confident: true };\n }\n if (ua.startsWith('npm/')) {\n return { name: 'npm', source: 'user-agent', confident: true };\n }\n }\n\n const startDir = path.resolve(input.targetDir || input.cwd || process.cwd());\n\n let curDir = startDir;\n while (true) {\n const pkgPath = path.join(curDir, 'package.json');\n if (fsImpl.existsSync(pkgPath)) {\n try {\n const raw = fsImpl.readFileSync(pkgPath, 'utf-8');\n const parsed = JSON.parse(raw);\n if (typeof parsed.packageManager === 'string') {\n const pmField = parsed.packageManager.toLowerCase();\n if (pmField.startsWith('bun@') || pmField === 'bun') {\n return { name: 'bun', source: 'package-json', confident: true };\n }\n if (pmField.startsWith('pnpm@') || pmField === 'pnpm') {\n return { name: 'pnpm', source: 'package-json', confident: true };\n }\n if (pmField.startsWith('yarn@') || pmField === 'yarn') {\n return { name: 'yarn', source: 'package-json', confident: true };\n }\n if (pmField.startsWith('npm@') || pmField === 'npm') {\n return { name: 'npm', source: 'package-json', confident: true };\n }\n }\n } catch {\n }\n }\n const parent = path.dirname(curDir);\n if (parent === curDir) break;\n curDir = parent;\n }\n\n curDir = startDir;\n while (true) {\n const found: PackageManager[] = [];\n if (fsImpl.existsSync(path.join(curDir, 'bun.lock')) || fsImpl.existsSync(path.join(curDir, 'bun.lockb'))) {\n found.push('bun');\n }\n if (fsImpl.existsSync(path.join(curDir, 'pnpm-lock.yaml'))) {\n found.push('pnpm');\n }\n if (fsImpl.existsSync(path.join(curDir, 'yarn.lock'))) {\n found.push('yarn');\n }\n if (fsImpl.existsSync(path.join(curDir, 'package-lock.json')) || fsImpl.existsSync(path.join(curDir, 'npm-shrinkwrap.json'))) {\n found.push('npm');\n }\n\n if (found.length === 1) {\n return { name: found[0], source: 'lockfile', confident: true };\n }\n if (found.length > 1) {\n const priority: PackageManager[] = ['bun', 'pnpm', 'yarn', 'npm'];\n const chosen = priority.find((p) => found.includes(p))!;\n return { name: chosen, source: 'lockfile', confident: false };\n }\n\n if (fsImpl.existsSync(path.join(curDir, '.git'))) {\n break;\n }\n const parent = path.dirname(curDir);\n if (parent === curDir) break;\n curDir = parent;\n }\n\n if (argv1) {\n try {\n const real = fsImpl.existsSync(argv1) ? fsImpl.realpathSync(argv1) : argv1;\n const normalized = real.replace(/\\\\/g, '/').toLowerCase();\n\n if (normalized.includes('/.bun/') || normalized.includes('/bun/bin/')) {\n return { name: 'bun', source: 'global-path', confident: false };\n }\n if (normalized.includes('/pnpm/global/') || normalized.includes('/appdata/local/pnpm')) {\n return { name: 'pnpm', source: 'global-path', confident: false };\n }\n if (\n normalized.includes('/yarn/global/') ||\n normalized.includes('/.config/yarn/global/') ||\n normalized.includes('/appdata/local/yarn')\n ) {\n return { name: 'yarn', source: 'global-path', confident: false };\n }\n } catch {\n }\n }\n\n if (versions && versions.bun) {\n return { name: 'bun', source: 'runtime', confident: false };\n }\n\n return { name: 'npm', source: 'default', confident: false };\n}\n\nexport function formatPmSource(source: PmSource): string {\n switch (source) {\n case 'flag':\n return 'command line flag';\n case 'user-agent':\n return 'user agent';\n case 'package-json':\n return 'package.json packageManager field';\n case 'lockfile':\n return 'lockfile';\n case 'global-path':\n return 'global installation directory';\n case 'runtime':\n return 'runtime environment';\n case 'prompt':\n return 'user selection';\n case 'default':\n return 'default fallback';\n }\n}\n\nexport function getInstallCommand(pm: PackageManager): string {\n switch (pm) {\n case 'npm':\n return 'npm install';\n case 'pnpm':\n return 'pnpm install';\n case 'yarn':\n return 'yarn';\n case 'bun':\n return 'bun install';\n }\n}\n\nexport function getRunCommand(pm: PackageManager, script: string): string {\n switch (pm) {\n case 'npm':\n return `npm run ${script}`;\n case 'pnpm':\n return `pnpm ${script}`;\n case 'yarn':\n return `yarn ${script}`;\n case 'bun':\n return `bun run ${script}`;\n }\n}\n\n","import { spawn } from 'node:child_process';\nimport fs from 'node:fs';\nimport path from 'node:path';\n\nexport function isCommandAvailable(command: string): Promise<boolean> {\n return new Promise((resolve) => {\n const isWindows = process.platform === 'win32';\n const child = spawn(command, ['--version'], {\n shell: isWindows,\n stdio: 'ignore',\n });\n child.on('error', () => resolve(false));\n child.on('close', (code) => resolve(code === 0));\n });\n}\n\nexport function isInsideGitRepo(dir: string): boolean {\n let cur = path.resolve(dir);\n while (true) {\n if (fs.existsSync(path.join(cur, '.git'))) {\n return true;\n }\n const parent = path.dirname(cur);\n if (parent === cur) break;\n cur = parent;\n }\n return false;\n}\n\nexport function runCommand(command: string, args: string[], cwd: string): Promise<{ success: boolean; error?: string }> {\n return new Promise((resolve) => {\n const isWindows = process.platform === 'win32';\n const child = spawn(command, args, {\n cwd,\n shell: isWindows,\n stdio: 'inherit',\n });\n child.on('error', (err) => resolve({ success: false, error: err.message }));\n child.on('close', (code) => {\n if (code === 0) {\n resolve({ success: true });\n } else {\n resolve({ success: false, error: `Exited with code ${code}` });\n }\n });\n });\n}\n\n","import fs from 'node:fs';\nimport path from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport type { Context } from '../cli/context.js';\nimport { resolveTargets, type TargetConfig } from './targets.js';\nimport { buildManifest } from './manifest.js';\nimport { buildPackageJson } from './pkgjson.js';\nimport { buildConfigs } from './tsconfig.js';\nimport { copyDirectory } from './copy.js';\nimport { toSlug } from '../utils/validate.js';\nimport { getInstallCommand, getRunCommand } from '../utils/pm.js';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\n/**\n * Locates the templates directory regardless of whether running from src/ or dist/.\n */\nexport function getTemplatesDir(): string {\n const candidate1 = path.resolve(__dirname, '../../templates');\n if (fs.existsSync(candidate1)) {\n return candidate1;\n }\n const candidate2 = path.resolve(__dirname, '../templates');\n if (fs.existsSync(candidate2)) {\n return candidate2;\n }\n return path.resolve(process.cwd(), 'templates');\n}\n\nexport function buildProjectReadme(ctx: Context, targets: TargetConfig[]): string {\n const pm = ctx.pm;\n const devCmd = getRunCommand(pm, 'dev');\n const buildCmd = getRunCommand(pm, 'build');\n const firstTarget = targets[0];\n\n let loadInstructions = '';\n for (const t of targets) {\n if (t.browser === 'chrome') {\n loadInstructions += `\n### Chromium (Chrome, Edge, Brave, Opera)\n1. Open \\`chrome://extensions\\` (or equivalent in your browser)\n2. Enable **Developer mode** toggle in the top-right corner\n3. Click **Load unpacked** and select the \\`${t.outDir}\\` directory\n`;\n } else if (t.browser === 'firefox') {\n loadInstructions += `\n### Firefox\n1. Open \\`about:debugging#/runtime/this-firefox\\`\n2. Click **Load Temporary Add-on...**\n3. Select the \\`manifest.json\\` file inside \\`${t.outDir}\\`\n*(Alternatively, run \\`${getRunCommand(pm, 'run:firefox')}\\`)*\n`;\n } else if (t.browser === 'safari') {\n loadInstructions += `\n### Safari\nSafari requires converting the built extension with Xcode:\n\\`\\`\\`bash\nxcrun safari-web-extension-converter ${t.outDir}\n\\`\\`\\`\nThen open and run the generated Xcode project.\n`;\n }\n }\n\n const scriptList = Object.entries(buildPackageJson(ctx, targets).scripts)\n .map(([name, cmd]) => `- \\`${getRunCommand(pm, name)}\\`: \\`${cmd}\\``)\n .join('\\n');\n\n return `# ${ctx.projectName}\n\n${ctx.projectName} browser extension built with Vite and CRXJS.\n\n## Getting Started\n\n### Development\n\\`\\`\\`bash\n${devCmd}\n\\`\\`\\`\n\n### Production Build\n\\`\\`\\`bash\n${buildCmd}\n\\`\\`\\`\n\n## Available Scripts\n${scriptList}\n\n## Loading the Extension in Your Browser\n${loadInstructions}\n\n## Before Publishing\n- Update the extension name, description, and icons in \\`public/icons/\\`.\n${targets.some((t) => t.browser === 'firefox') ? '- Customize the Firefox Gecko ID in `manifest.config` (default is placeholder `@example.com`).\\n' : ''}${ctx.features.includes('dnr') ? '- Review the default rules in `public/rules/rules.json` and narrow `host_permissions` in the manifest.\\n' : ''}\n`;\n}\n\nexport function generateProject(ctx: Context): { targetDir: string; targets: TargetConfig[] } {\n const targetDir = path.resolve(ctx.targetDir);\n const templatesDir = getTemplatesDir();\n const slug = toSlug(ctx.projectName);\n const targets = resolveTargets(ctx.browsers, ctx.firefoxMv, ctx.safariMv);\n const hasMv2 = targets.some((t) => t.mv === 2);\n const ext = ctx.language === 'ts' ? 'ts' : 'js';\n\n const replacements: Record<string, string> = {\n name: ctx.projectName,\n description: `${ctx.projectName} browser extension`,\n slug,\n pm: ctx.pm,\n };\n\n fs.mkdirSync(targetDir, { recursive: true });\n\n const baseDir = path.join(templatesDir, 'base');\n copyDirectory(baseDir, targetDir, replacements);\n\n const langDir = path.join(templatesDir, ctx.language);\n copyDirectory(langDir, targetDir, replacements);\n\n if (ctx.projectType === 'content-only') {\n const contentDir = path.join(templatesDir, 'features', 'content', 'content-only', ctx.language);\n copyDirectory(contentDir, targetDir, replacements);\n if (ctx.contentScript?.css) {\n const styleSrc = path.join(templatesDir, 'features', 'content', 'style.css');\n const styleDest = path.join(targetDir, 'src', 'content', 'style.css');\n fs.mkdirSync(path.dirname(styleDest), { recursive: true });\n fs.copyFileSync(styleSrc, styleDest);\n }\n } else {\n if (ctx.features.includes('background')) {\n const bgDir = path.join(templatesDir, 'features', 'background', ctx.language);\n copyDirectory(bgDir, targetDir, replacements);\n\n const bgFile = path.join(targetDir, 'src', 'background', `index.${ext}`);\n let bgContent = fs.readFileSync(bgFile, 'utf-8');\n\n if (ctx.extras.includes('contextmenu')) {\n bgContent += `\\napi.contextMenus?.create?.({\n id: '${slug}-menu',\n title: '${ctx.projectName} Action',\n contexts: ['all'],\n});\n\napi.contextMenus?.onClicked?.addListener((info, tab) => {\n console.log('Context menu clicked:', info.menuItemId, 'tab:', tab?.id);\n});\\n`;\n }\n\n if (ctx.extras.includes('commands')) {\n bgContent += `\\napi.commands?.onCommand?.addListener((command) => {\n console.log('Command received:', command);\n});\\n`;\n }\n\n if (ctx.extras.includes('omnibox')) {\n bgContent += `\\napi.omnibox?.onInputEntered?.addListener((text, disposition) => {\n console.log('Omnibox search:', text, 'disposition:', disposition);\n});\\n`;\n }\n\n fs.writeFileSync(bgFile, bgContent, 'utf-8');\n }\n\n if (ctx.features.includes('content')) {\n const contentDir = path.join(templatesDir, 'features', 'content', 'full', ctx.language);\n copyDirectory(contentDir, targetDir, replacements);\n if (ctx.contentScript?.css) {\n const styleSrc = path.join(templatesDir, 'features', 'content', 'style.css');\n const styleDest = path.join(targetDir, 'src', 'content', 'style.css');\n fs.mkdirSync(path.dirname(styleDest), { recursive: true });\n fs.copyFileSync(styleSrc, styleDest);\n }\n }\n\n if (ctx.features.includes('popup')) {\n const popupDir = path.join(templatesDir, 'features', 'popup', ctx.language);\n copyDirectory(popupDir, targetDir, replacements);\n }\n\n if (ctx.features.includes('options')) {\n const optionsDir = path.join(templatesDir, 'features', 'options', ctx.language);\n copyDirectory(optionsDir, targetDir, replacements);\n }\n\n if (ctx.features.includes('sidepanel')) {\n const sidepanelDir = path.join(templatesDir, 'features', 'sidepanel', ctx.language);\n copyDirectory(sidepanelDir, targetDir, replacements);\n }\n\n if (ctx.features.includes('devtools')) {\n const devtoolsDir = path.join(templatesDir, 'features', 'devtools', ctx.language);\n copyDirectory(devtoolsDir, targetDir, replacements);\n }\n\n if (ctx.features.includes('newtab')) {\n const newtabDir = path.join(templatesDir, 'features', 'newtab', ctx.language);\n copyDirectory(newtabDir, targetDir, replacements);\n }\n\n if (ctx.features.includes('dnr')) {\n const dnrSrc = path.join(templatesDir, 'features', 'dnr', 'rules.json');\n const dnrDest = path.join(targetDir, 'public', 'rules', 'rules.json');\n fs.mkdirSync(path.dirname(dnrDest), { recursive: true });\n fs.copyFileSync(dnrSrc, dnrDest);\n }\n\n if (ctx.extras.includes('storage')) {\n const storageDir = path.join(templatesDir, 'features', 'extras', 'storage', ctx.language);\n copyDirectory(storageDir, targetDir, replacements);\n }\n }\n\n const targetsConfigContent = `export interface TargetConfig {\n id: string;\n browser: 'chrome' | 'firefox' | 'safari';\n mv: 2 | 3;\n outDir: string;\n}\n\nexport const targets: TargetConfig[] = ${JSON.stringify(targets, null, 2)};\n\nexport function getTarget(mode: string): TargetConfig {\n const found = targets.find((t) => t.id === mode);\n return found || targets[0];\n}\n`;\n fs.writeFileSync(\n path.join(targetDir, `targets.config.${ext}`),\n ctx.language === 'ts'\n ? targetsConfigContent\n : targetsConfigContent.replace(/export interface TargetConfig \\{[\\s\\S]*?\\}\\n\\n/, '').replace(/: TargetConfig\\[\\]/g, '').replace(/: string/g, '').replace(/: TargetConfig/g, ''),\n 'utf-8',\n );\n\n const manifestMap: Record<string, any> = {};\n for (const t of targets) {\n manifestMap[t.id] = buildManifest(ctx, t);\n }\n\n const manifestConfigContent = ctx.language === 'ts'\n ? `import type { TargetConfig } from './targets.config';\n\nconst manifests: Record<string, any> = ${JSON.stringify(manifestMap, null, 2)};\n\nexport function buildManifest(target: TargetConfig): any {\n return manifests[target.id] || manifests['${targets[0].id}'];\n}\n`\n : `const manifests = ${JSON.stringify(manifestMap, null, 2)};\n\nexport function buildManifest(target) {\n return manifests[target.id] || manifests['${targets[0].id}'];\n}\n`;\n fs.writeFileSync(path.join(targetDir, `manifest.config.${ext}`), manifestConfigContent, 'utf-8');\n\n if (hasMv2) {\n const mv2Dir = path.join(targetDir, 'build');\n fs.mkdirSync(mv2Dir, { recursive: true });\n\n const mv2Content = ctx.language === 'ts'\n ? `import type { Plugin } from 'vite';\nimport { build as viteBuild } from 'vite';\nimport fs from 'node:fs';\nimport path from 'node:path';\n\nexport function buildMv2Plugin(options: { target: any; manifest: any }): Plugin {\n const { manifest } = options;\n let config: any;\n\n return {\n name: 'web-extension:mv2-builder',\n configResolved(resolvedConfig) {\n config = resolvedConfig;\n },\n async writeBundle() {\n const outDir = config.build.outDir;\n const root = config.root || process.cwd();\n const mv2Manifest = JSON.parse(JSON.stringify(manifest));\n\n if (manifest.background?.scripts?.length) {\n const outScripts: string[] = [];\n for (let i = 0; i < manifest.background.scripts.length; i++) {\n const entryPath = path.resolve(root, manifest.background.scripts[i]);\n const outName = 'background.js';\n await viteBuild({\n configFile: false,\n root,\n build: {\n lib: {\n entry: entryPath,\n formats: ['iife'],\n name: 'ExtensionBackground',\n fileName: () => outName,\n },\n outDir,\n emptyOutDir: false,\n sourcemap: config.build.sourcemap,\n },\n });\n outScripts.push(outName);\n }\n mv2Manifest.background.scripts = outScripts;\n }\n\n if (manifest.content_scripts?.length) {\n for (let sIdx = 0; sIdx < manifest.content_scripts.length; sIdx++) {\n const cs = manifest.content_scripts[sIdx];\n if (cs.js?.length) {\n const outJs: string[] = [];\n for (let jIdx = 0; jIdx < cs.js.length; jIdx++) {\n const entryPath = path.resolve(root, cs.js[jIdx]);\n const outName = \\`content-\\${sIdx}-\\${jIdx}.js\\`;\n await viteBuild({\n configFile: false,\n root,\n build: {\n lib: {\n entry: entryPath,\n formats: ['iife'],\n name: \\`ExtensionContent_\\${sIdx}_\\${jIdx}\\`,\n fileName: () => outName,\n },\n outDir,\n emptyOutDir: false,\n sourcemap: config.build.sourcemap,\n },\n });\n outJs.push(outName);\n }\n mv2Manifest.content_scripts[sIdx].js = outJs;\n }\n\n if (cs.css?.length) {\n const outCss: string[] = [];\n for (let cIdx = 0; cIdx < cs.css.length; cIdx++) {\n const srcCss = path.resolve(root, cs.css[cIdx]);\n const outCssName = \\`content-\\${sIdx}-\\${cIdx}.css\\`;\n if (fs.existsSync(srcCss)) {\n fs.copyFileSync(srcCss, path.join(outDir, outCssName));\n outCss.push(outCssName);\n }\n }\n mv2Manifest.content_scripts[sIdx].css = outCss;\n }\n }\n }\n\n const iconsDir = path.resolve(root, 'public', 'icons');\n if (fs.existsSync(iconsDir)) {\n const outIcons = path.join(outDir, 'icons');\n fs.mkdirSync(outIcons, { recursive: true });\n for (const icon of fs.readdirSync(iconsDir)) {\n fs.copyFileSync(path.join(iconsDir, icon), path.join(outIcons, icon));\n }\n }\n\n fs.writeFileSync(\n path.join(outDir, 'manifest.json'),\n JSON.stringify(mv2Manifest, null, 2),\n );\n },\n };\n}\n`\n : `import { build as viteBuild } from 'vite';\nimport fs from 'node:fs';\nimport path from 'node:path';\n\nexport function buildMv2Plugin(options) {\n const { manifest } = options;\n let config;\n\n return {\n name: 'web-extension:mv2-builder',\n configResolved(resolvedConfig) {\n config = resolvedConfig;\n },\n async writeBundle() {\n const outDir = config.build.outDir;\n const root = config.root || process.cwd();\n const mv2Manifest = JSON.parse(JSON.stringify(manifest));\n\n if (manifest.background?.scripts?.length) {\n const outScripts = [];\n for (let i = 0; i < manifest.background.scripts.length; i++) {\n const entryPath = path.resolve(root, manifest.background.scripts[i]);\n const outName = 'background.js';\n await viteBuild({\n configFile: false,\n root,\n build: {\n lib: {\n entry: entryPath,\n formats: ['iife'],\n name: 'ExtensionBackground',\n fileName: () => outName,\n },\n outDir,\n emptyOutDir: false,\n sourcemap: config.build.sourcemap,\n },\n });\n outScripts.push(outName);\n }\n mv2Manifest.background.scripts = outScripts;\n }\n\n if (manifest.content_scripts?.length) {\n for (let sIdx = 0; sIdx < manifest.content_scripts.length; sIdx++) {\n const cs = manifest.content_scripts[sIdx];\n if (cs.js?.length) {\n const outJs = [];\n for (let jIdx = 0; jIdx < cs.js.length; jIdx++) {\n const entryPath = path.resolve(root, cs.js[jIdx]);\n const outName = \\`content-\\${sIdx}-\\${jIdx}.js\\`;\n await viteBuild({\n configFile: false,\n root,\n build: {\n lib: {\n entry: entryPath,\n formats: ['iife'],\n name: \\`ExtensionContent_\\${sIdx}_\\${jIdx}\\`,\n fileName: () => outName,\n },\n outDir,\n emptyOutDir: false,\n sourcemap: config.build.sourcemap,\n },\n });\n outJs.push(outName);\n }\n mv2Manifest.content_scripts[sIdx].js = outJs;\n }\n\n if (cs.css?.length) {\n const outCss = [];\n for (let cIdx = 0; cIdx < cs.css.length; cIdx++) {\n const srcCss = path.resolve(root, cs.css[cIdx]);\n const outCssName = \\`content-\\${sIdx}-\\${cIdx}.css\\`;\n if (fs.existsSync(srcCss)) {\n fs.copyFileSync(srcCss, path.join(outDir, outCssName));\n outCss.push(outCssName);\n }\n }\n mv2Manifest.content_scripts[sIdx].css = outCss;\n }\n }\n }\n\n const iconsDir = path.resolve(root, 'public', 'icons');\n if (fs.existsSync(iconsDir)) {\n const outIcons = path.join(outDir, 'icons');\n fs.mkdirSync(outIcons, { recursive: true });\n for (const icon of fs.readdirSync(iconsDir)) {\n fs.copyFileSync(path.join(iconsDir, icon), path.join(outIcons, icon));\n }\n }\n\n fs.writeFileSync(\n path.join(outDir, 'manifest.json'),\n JSON.stringify(mv2Manifest, null, 2),\n );\n },\n };\n}\n`;\n fs.writeFileSync(path.join(mv2Dir, `mv2.${ext}`), mv2Content, 'utf-8');\n }\n\n const hasMv3 = targets.some((t) => t.mv === 3);\n let pluginsExpression = '';\n if (hasMv3 && hasMv2) {\n pluginsExpression = `isMv3\n ? [\n crx({\n manifest,\n browser: target.browser === 'firefox' ? 'firefox' : 'chrome',\n }),\n ]\n : [buildMv2Plugin({ target, manifest })]`;\n } else if (hasMv3) {\n pluginsExpression = `[\n crx({\n manifest,\n browser: target.browser === 'firefox' ? 'firefox' : 'chrome',\n }),\n ]`;\n } else {\n pluginsExpression = `[buildMv2Plugin({ target, manifest })]`;\n }\n\n const viteConfigContent = `import { defineConfig } from 'vite';\n${hasMv3 ? \"import { crx } from '@crxjs/vite-plugin';\" : ''}\nimport { getTarget } from './targets.config';\nimport { buildManifest } from './manifest.config';\n${hasMv2 ? \"import { buildMv2Plugin } from './build/mv2';\" : ''}\n\nfunction getHtmlInputs(manifest${ctx.language === 'ts' ? ': any' : ''}) {\n const inputs${ctx.language === 'ts' ? ': Record<string, string>' : ''} = {};\n if (manifest.action?.default_popup || manifest.browser_action?.default_popup) {\n inputs.popup = manifest.action?.default_popup || manifest.browser_action?.default_popup;\n }\n if (manifest.options_ui?.page) {\n inputs.options = manifest.options_ui.page;\n }\n if (manifest.side_panel?.default_path || manifest.sidebar_action?.default_panel) {\n inputs.sidepanel = manifest.side_panel?.default_path || manifest.sidebar_action?.default_panel;\n }\n if (manifest.devtools_page) {\n inputs.devtools = manifest.devtools_page;\n }\n if (manifest.chrome_url_overrides?.newtab) {\n inputs.newtab = manifest.chrome_url_overrides.newtab;\n }\n return inputs;\n}\n\nexport default defineConfig(({ mode }) => {\n const target = getTarget(mode);\n const manifest = buildManifest(target);\n const isMv3 = target.mv === 3;\n\n const htmlInputs = !isMv3 ? getHtmlInputs(manifest) : {};\n const hasInputs = Object.keys(htmlInputs).length > 0;\n\n return {\n build: {\n outDir: \\`dist/\\${target.id}\\`,\n emptyOutDir: true,\n ...(!isMv3\n ? {\n rollupOptions: hasInputs\n ? { input: htmlInputs }\n : undefined,\n ...(hasInputs\n ? {}\n : {\n lib: {\n entry: manifest.content_scripts?.[0]?.js?.[0] || 'src/content/index.${ext}',\n formats: ['iife'],\n name: 'ExtensionContent',\n fileName: () => 'content-0-0.js',\n },\n }),\n }\n : {}),\n },\n plugins: ${pluginsExpression},\n };\n});\n`;\n fs.writeFileSync(path.join(targetDir, `vite.config.${ext}`), viteConfigContent, 'utf-8');\n\n const pkgJson = buildPackageJson(ctx, targets);\n fs.writeFileSync(path.join(targetDir, 'package.json'), JSON.stringify(pkgJson, null, 2), 'utf-8');\n\n const configs = buildConfigs(ctx, targets);\n for (const [relPath, content] of Object.entries(configs)) {\n const fullPath = path.join(targetDir, relPath);\n fs.mkdirSync(path.dirname(fullPath), { recursive: true });\n fs.writeFileSync(fullPath, content, 'utf-8');\n }\n\n const readmeContent = buildProjectReadme(ctx, targets);\n fs.writeFileSync(path.join(targetDir, 'README.md'), readmeContent, 'utf-8');\n\n return { targetDir, targets };\n}\n\n","import type { BrowserKey, ManifestVersion } from '../cli/context.js';\n\nexport interface TargetConfig {\n id: string;\n browser: BrowserKey;\n mv: ManifestVersion;\n outDir: string;\n}\n\nexport interface BrowserCapability {\n supportsBackgroundServiceWorker: boolean;\n supportsBackgroundScripts: boolean;\n popupKey: 'action' | 'browser_action';\n supportsSidePanel: boolean;\n sidePanelType?: 'side_panel' | 'sidebar_action';\n supportsDnr: boolean;\n supportsDevtools: boolean;\n supportsNewtab: boolean;\n supportsWorldMain: boolean;\n}\n\nexport const CAPABILITY_MATRIX: Record<string, BrowserCapability> = {\n 'chrome-mv3': {\n supportsBackgroundServiceWorker: true,\n supportsBackgroundScripts: false,\n popupKey: 'action',\n supportsSidePanel: true,\n sidePanelType: 'side_panel',\n supportsDnr: true,\n supportsDevtools: true,\n supportsNewtab: true,\n supportsWorldMain: true,\n },\n 'firefox-mv3': {\n supportsBackgroundServiceWorker: false,\n supportsBackgroundScripts: true,\n popupKey: 'action',\n supportsSidePanel: true,\n sidePanelType: 'sidebar_action',\n supportsDnr: true,\n supportsDevtools: true,\n supportsNewtab: true,\n supportsWorldMain: true,\n },\n 'firefox-mv2': {\n supportsBackgroundServiceWorker: false,\n supportsBackgroundScripts: true,\n popupKey: 'browser_action',\n supportsSidePanel: true,\n sidePanelType: 'sidebar_action',\n supportsDnr: false,\n supportsDevtools: true,\n supportsNewtab: true,\n supportsWorldMain: false,\n },\n 'safari-mv3': {\n supportsBackgroundServiceWorker: true,\n supportsBackgroundScripts: false,\n popupKey: 'action',\n supportsSidePanel: false,\n supportsDnr: true,\n supportsDevtools: false,\n supportsNewtab: false,\n supportsWorldMain: true,\n },\n 'safari-mv2': {\n supportsBackgroundServiceWorker: false,\n supportsBackgroundScripts: true,\n popupKey: 'browser_action',\n supportsSidePanel: false,\n supportsDnr: false,\n supportsDevtools: false,\n supportsNewtab: false,\n supportsWorldMain: false,\n },\n};\n\nexport function resolveTargets(\n browsers: BrowserKey[],\n firefoxMv: ManifestVersion = 3,\n safariMv: ManifestVersion = 3,\n): TargetConfig[] {\n const targets: TargetConfig[] = [];\n\n for (const b of browsers) {\n if (b === 'chrome') {\n targets.push({\n id: 'chrome-mv3',\n browser: 'chrome',\n mv: 3,\n outDir: 'dist/chrome-mv3',\n });\n } else if (b === 'firefox') {\n const mv = firefoxMv || 3;\n targets.push({\n id: `firefox-mv${mv}`,\n browser: 'firefox',\n mv,\n outDir: `dist/firefox-mv${mv}`,\n });\n } else if (b === 'safari') {\n const mv = safariMv || 3;\n targets.push({\n id: `safari-mv${mv}`,\n browser: 'safari',\n mv,\n outDir: `dist/safari-mv${mv}`,\n });\n }\n }\n\n return targets;\n}\n\n","import type { Context } from '../cli/context.js';\nimport { CAPABILITY_MATRIX, type TargetConfig } from './targets.js';\nimport { toSlug } from '../utils/validate.js';\n\nexport function buildManifest(ctx: Context, target: TargetConfig): Record<string, any> {\n const cap = CAPABILITY_MATRIX[target.id] || {\n supportsBackgroundServiceWorker: true,\n supportsBackgroundScripts: false,\n popupKey: 'action',\n supportsSidePanel: false,\n supportsDnr: target.mv === 3,\n supportsDevtools: false,\n supportsNewtab: false,\n supportsWorldMain: target.mv === 3,\n };\n\n const ext = ctx.language === 'ts' ? 'ts' : 'js';\n const slug = toSlug(ctx.projectName);\n\n const manifest: Record<string, any> = {\n manifest_version: target.mv,\n name: ctx.projectName,\n version: '0.0.1',\n description: `${ctx.projectName} browser extension`,\n icons: {\n '16': 'icons/16.png',\n '48': 'icons/48.png',\n '128': 'icons/128.png',\n },\n };\n\n if (ctx.projectType === 'content-only') {\n const matches = ctx.contentScript?.matches?.length\n ? ctx.contentScript.matches\n : ['https://*/*'];\n\n const contentEntry: Record<string, any> = {\n matches,\n js: [`src/content/index.${ext}`],\n run_at: ctx.contentScript?.runAt || 'document_idle',\n };\n\n if (ctx.contentScript?.css) {\n contentEntry.css = ['src/content/style.css'];\n }\n\n if (target.mv === 3 && cap.supportsWorldMain) {\n contentEntry.world = ctx.contentScript?.world || 'ISOLATED';\n }\n\n manifest.content_scripts = [contentEntry];\n\n if (target.browser === 'firefox') {\n manifest.browser_specific_settings = {\n gecko: {\n id: `${slug}@example.com`,\n strict_min_version: target.mv === 3 ? '109.0' : '58.0',\n },\n };\n }\n\n return manifest;\n }\n\n const permissions: string[] = [];\n\n if (ctx.features.includes('background')) {\n if (target.mv === 3) {\n if (cap.supportsBackgroundScripts) {\n manifest.background = {\n scripts: [`src/background/index.${ext}`],\n };\n } else {\n manifest.background = {\n service_worker: `src/background/index.${ext}`,\n type: 'module',\n };\n }\n } else {\n manifest.background = {\n scripts: [`src/background/index.${ext}`],\n persistent: false,\n };\n }\n }\n\n if (ctx.features.includes('popup')) {\n if (cap.popupKey === 'action') {\n manifest.action = {\n default_popup: 'src/popup/index.html',\n };\n } else {\n manifest.browser_action = {\n default_popup: 'src/popup/index.html',\n };\n }\n }\n\n if (ctx.features.includes('options')) {\n if (target.mv === 3) {\n manifest.options_ui = {\n page: 'src/options/index.html',\n open_in_tab: true,\n };\n } else {\n manifest.options_ui = {\n page: 'src/options/index.html',\n chrome_style: true,\n };\n }\n }\n\n if (ctx.features.includes('sidepanel') && cap.supportsSidePanel) {\n if (cap.sidePanelType === 'side_panel') {\n manifest.side_panel = {\n default_path: 'src/sidepanel/index.html',\n };\n permissions.push('sidePanel');\n } else if (cap.sidePanelType === 'sidebar_action') {\n manifest.sidebar_action = {\n default_panel: 'src/sidepanel/index.html',\n };\n }\n }\n\n if (ctx.features.includes('devtools') && cap.supportsDevtools) {\n manifest.devtools_page = 'src/devtools/devtools.html';\n }\n\n if (ctx.features.includes('newtab') && cap.supportsNewtab) {\n manifest.chrome_url_overrides = {\n newtab: 'src/newtab/index.html',\n };\n }\n\n if (ctx.features.includes('content')) {\n const matches = ctx.contentScript?.matches?.length\n ? ctx.contentScript.matches\n : ['https://*/*'];\n\n const contentEntry: Record<string, any> = {\n matches,\n js: [`src/content/index.${ext}`],\n run_at: ctx.contentScript?.runAt || 'document_idle',\n };\n\n if (ctx.contentScript?.css) {\n contentEntry.css = ['src/content/style.css'];\n }\n\n if (target.mv === 3 && cap.supportsWorldMain) {\n contentEntry.world = ctx.contentScript?.world || 'ISOLATED';\n }\n\n manifest.content_scripts = [contentEntry];\n }\n\n if (ctx.features.includes('dnr') && cap.supportsDnr && target.mv === 3) {\n manifest.declarative_net_request = {\n rule_resources: [\n {\n id: 'ruleset_1',\n enabled: true,\n path: 'rules/rules.json',\n },\n ],\n };\n permissions.push('declarativeNetRequest');\n manifest.host_permissions = ['<all_urls>'];\n }\n\n if (ctx.extras.includes('storage')) {\n permissions.push('storage');\n }\n\n if (ctx.features.includes('background')) {\n if (ctx.extras.includes('contextmenu')) {\n permissions.push('contextMenus');\n }\n\n if (ctx.extras.includes('commands')) {\n manifest.commands = {\n _execute_action: {\n suggested_key: {\n default: 'Ctrl+Shift+Y',\n mac: 'Command+Shift+Y',\n },\n description: 'Toggle extension action',\n },\n };\n }\n\n if (ctx.extras.includes('omnibox')) {\n manifest.omnibox = {\n keyword: slug.slice(0, 10),\n };\n }\n }\n\n if (permissions.length > 0) {\n manifest.permissions = permissions;\n }\n\n if (target.browser === 'firefox') {\n manifest.browser_specific_settings = {\n gecko: {\n id: `${slug}@example.com`,\n strict_min_version: target.mv === 3 ? '109.0' : '58.0',\n },\n };\n }\n\n return manifest;\n}\n\n","import type { Context } from '../cli/context.js';\nimport type { TargetConfig } from './targets.js';\n\nexport function buildPackageJson(ctx: Context, targets: TargetConfig[]): Record<string, any> {\n const scripts: Record<string, string> = {};\n\n for (const t of targets) {\n if (t.mv === 2 || t.browser === 'firefox') {\n scripts[`dev:${t.browser}`] = `vite build --watch --mode ${t.id}`;\n } else {\n scripts[`dev:${t.browser}`] = `vite --mode ${t.id}`;\n }\n scripts[`build:${t.browser}`] = `vite build --mode ${t.id}`;\n\n if (t.browser === 'firefox') {\n scripts['run:firefox'] = `web-ext run --source-dir dist/${t.id}`;\n }\n }\n\n const first = targets[0];\n scripts['dev'] = `npm run dev:${first.browser}`;\n scripts['build'] = `npm run build:${first.browser}`;\n\n if (targets.length > 1) {\n scripts['build:all'] = targets.map((t) => `npm run build:${t.browser}`).join(' && ');\n }\n\n scripts['typecheck'] = ctx.language === 'ts' ? 'tsc -b' : 'tsc -p jsconfig.json --noEmit';\n\n const devDependencies: Record<string, string> = {\n vite: '^8.3.6',\n typescript: '^5.8.2',\n };\n\n const hasMv3 = targets.some((t) => t.mv === 3);\n if (hasMv3) {\n devDependencies['@crxjs/vite-plugin'] = '^3.0.0';\n }\n\n const hasChrome = targets.some((t) => t.browser === 'chrome');\n const hasFirefox = targets.some((t) => t.browser === 'firefox');\n const hasSafari = targets.some((t) => t.browser === 'safari');\n\n if (hasChrome || (hasSafari && !hasFirefox)) {\n devDependencies['@types/chrome'] = '^0.3.7';\n }\n if (hasFirefox) {\n devDependencies['@types/firefox-webext-browser'] = '^143.0.1';\n devDependencies['web-ext'] = '^10.8.0';\n }\n\n return {\n name: ctx.projectName,\n version: '0.0.1',\n description: `${ctx.projectName} browser extension`,\n type: 'module',\n scripts,\n devDependencies,\n };\n}\n\n","import type { Context } from '../cli/context.js';\nimport type { TargetConfig } from './targets.js';\n\nexport function buildConfigs(\n ctx: Context,\n targets: TargetConfig[],\n): Record<string, string> {\n const files: Record<string, string> = {};\n\n const types: string[] = [];\n const hasChrome = targets.some((t) => t.browser === 'chrome');\n const hasFirefox = targets.some((t) => t.browser === 'firefox');\n const hasSafari = targets.some((t) => t.browser === 'safari');\n\n if (hasChrome || (hasSafari && !hasFirefox)) {\n types.push('chrome');\n }\n if (hasFirefox) {\n types.push('firefox-webext-browser');\n }\n\n const hasBackground =\n ctx.projectType === 'full' && ctx.features.includes('background');\n\n if (ctx.language === 'ts') {\n const references = [{ path: './tsconfig.app.json' }];\n if (hasBackground) {\n references.push({ path: './tsconfig.background.json' });\n }\n references.push({ path: './tsconfig.node.json' });\n\n files['tsconfig.json'] = JSON.stringify(\n {\n files: [],\n references,\n },\n null,\n 2,\n );\n\n const appConfig: Record<string, any> = {\n compilerOptions: {\n target: 'ES2022',\n lib: ['ES2022', 'DOM', 'DOM.Iterable'],\n module: 'ESNext',\n moduleResolution: 'bundler',\n strict: true,\n noEmit: true,\n isolatedModules: true,\n skipLibCheck: true,\n types,\n },\n include: ['src/**/*'],\n };\n\n if (hasBackground) {\n appConfig.exclude = ['src/background/**/*'];\n }\n\n files['tsconfig.app.json'] = JSON.stringify(appConfig, null, 2);\n\n if (hasBackground) {\n const bgLib = ['ES2022', 'WebWorker'];\n if (hasFirefox) {\n bgLib.push('DOM');\n }\n\n files['tsconfig.background.json'] = JSON.stringify(\n {\n compilerOptions: {\n target: 'ES2022',\n lib: bgLib,\n module: 'ESNext',\n moduleResolution: 'bundler',\n strict: true,\n noEmit: true,\n isolatedModules: true,\n skipLibCheck: true,\n types,\n },\n include: ['src/background/**/*', 'src/lib/**/*'],\n },\n null,\n 2,\n );\n }\n\n files['tsconfig.node.json'] = JSON.stringify(\n {\n compilerOptions: {\n target: 'ES2022',\n lib: ['ES2022'],\n module: 'ESNext',\n moduleResolution: 'bundler',\n strict: true,\n noEmit: true,\n isolatedModules: true,\n skipLibCheck: true,\n },\n include: [\n 'vite.config.ts',\n 'manifest.config.ts',\n 'targets.config.ts',\n 'build/**/*',\n ],\n },\n null,\n 2,\n );\n } else {\n files['jsconfig.json'] = JSON.stringify(\n {\n compilerOptions: {\n target: 'ES2022',\n lib: ['ES2022', 'DOM', 'DOM.Iterable'],\n module: 'ESNext',\n moduleResolution: 'bundler',\n checkJs: true,\n noEmit: true,\n types,\n },\n include: [\n 'src/**/*',\n 'vite.config.js',\n 'manifest.config.js',\n 'targets.config.js',\n 'build/**/*',\n ],\n },\n null,\n 2,\n );\n }\n\n const hasMv3 = targets.some((t) => t.mv === 3);\n const envDtsLines = ['/// <reference types=\"vite/client\" />'];\n if (hasMv3) {\n envDtsLines.push('/// <reference types=\"@crxjs/vite-plugin/client\" />');\n }\n files['src/env.d.ts'] = envDtsLines.join('\\n') + '\\n';\n\n return files;\n}\n\n","import fs from 'node:fs';\nimport path from 'node:path';\n\nconst BINARY_EXTENSIONS = new Set(['.png', '.jpg', '.jpeg', '.gif', '.ico', '.webp', '.woff', '.woff2', '.ttf']);\n\nexport function copyDirectory(\n sourceDir: string,\n targetDir: string,\n replacements: Record<string, string> = {},\n): void {\n if (!fs.existsSync(sourceDir)) {\n return;\n }\n\n const entries = fs.readdirSync(sourceDir, { withFileTypes: true });\n\n for (const entry of entries) {\n const srcPath = path.join(sourceDir, entry.name);\n const targetName = entry.name === '_gitignore' ? '.gitignore' : entry.name;\n const destPath = path.join(targetDir, targetName);\n\n if (entry.isDirectory()) {\n fs.mkdirSync(destPath, { recursive: true });\n copyDirectory(srcPath, destPath, replacements);\n } else if (entry.isFile()) {\n fs.mkdirSync(path.dirname(destPath), { recursive: true });\n\n const ext = path.extname(entry.name).toLowerCase();\n if (BINARY_EXTENSIONS.has(ext)) {\n fs.copyFileSync(srcPath, destPath);\n } else {\n let content = fs.readFileSync(srcPath, 'utf-8');\n for (const [key, val] of Object.entries(replacements)) {\n const placeholder = new RegExp(`\\\\{\\\\{${key}\\\\}\\\\}`, 'g');\n content = content.replace(placeholder, val);\n }\n fs.writeFileSync(destPath, content, 'utf-8');\n }\n }\n }\n}\n\n"],"mappings":"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","names":["p","fs","path","fileURLToPath","p","fs","path","path","p","fs","path","path","fs","fs","path","fs","path","path","fs","__filename","fileURLToPath","__dirname","path","fs"]}
package/package.json CHANGED
@@ -1,6 +1,56 @@
1
1
  {
2
2
  "name": "web-extension",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "2.0.0",
4
+ "description": "Scaffold cross-browser extensions with Vite and CRXJS",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "bin": {
8
+ "web-extension": "dist/index.js"
9
+ },
10
+ "files": [
11
+ "dist",
12
+ "templates",
13
+ "AI.md",
14
+ "DEVELOPER.md"
15
+ ],
16
+ "repository": {
17
+ "type": "git",
18
+ "url": "git+https://github.com/TiwPhiraphan/web-extension.git"
19
+ },
20
+ "bugs": {
21
+ "url": "https://github.com/TiwPhiraphan/web-extension/issues"
22
+ },
23
+ "homepage": "https://github.com/TiwPhiraphan/web-extension#readme",
24
+ "engines": {
25
+ "node": ">=20"
26
+ },
27
+ "scripts": {
28
+ "build": "tsup",
29
+ "dev": "tsup --watch",
30
+ "test": "vitest run",
31
+ "test:smoke": "bun test-smoke.mjs",
32
+ "typecheck": "tsc --noEmit"
33
+ },
34
+ "keywords": [
35
+ "chrome-extension",
36
+ "firefox-addon",
37
+ "safari-extension",
38
+ "webextension",
39
+ "crxjs",
40
+ "vite",
41
+ "scaffold",
42
+ "cli"
43
+ ],
44
+ "author": "TiwPhiraphan",
45
+ "license": "MIT",
46
+ "dependencies": {
47
+ "@clack/prompts": "^1.8.1",
48
+ "picocolors": "^1.1.1"
49
+ },
50
+ "devDependencies": {
51
+ "@types/node": "^22.13.9",
52
+ "tsup": "^9.0.0",
53
+ "typescript": "^5.8.2",
54
+ "vitest": "^5.1.0"
55
+ }
56
+ }
@@ -0,0 +1,6 @@
1
+ node_modules/
2
+ dist/
3
+ .DS_Store
4
+ *.local
5
+ *.log
6
+
@@ -0,0 +1,6 @@
1
+ import { api } from '../lib/browser.js';
2
+
3
+ api.runtime.onInstalled.addListener((details) => {
4
+ console.log('{{name}} extension installed or updated:', details.reason);
5
+ });
6
+
@@ -0,0 +1,6 @@
1
+ import { api } from '../lib/browser';
2
+
3
+ api.runtime.onInstalled.addListener((details) => {
4
+ console.log('{{name}} extension installed or updated:', details.reason);
5
+ });
6
+
@@ -0,0 +1,32 @@
1
+ console.log('{{name}} content script (DOM injector) initialized on', window.location.href);
2
+
3
+ function initDomHacks() {
4
+ const badge = document.createElement('div');
5
+ badge.className = 'we-injected-badge';
6
+ badge.textContent = '{{name}} Active';
7
+ document.body.appendChild(badge);
8
+
9
+ const observer = new MutationObserver((mutations) => {
10
+ for (const mutation of mutations) {
11
+ if (mutation.addedNodes.length > 0) {
12
+ }
13
+ }
14
+ });
15
+
16
+ observer.observe(document.body, { childList: true, subtree: true });
17
+
18
+ window.addEventListener(
19
+ 'pagehide',
20
+ () => {
21
+ observer.disconnect();
22
+ },
23
+ { once: true }
24
+ );
25
+ }
26
+
27
+ if (document.readyState === 'loading') {
28
+ document.addEventListener('DOMContentLoaded', initDomHacks);
29
+ } else {
30
+ initDomHacks();
31
+ }
32
+
@@ -0,0 +1,32 @@
1
+ console.log('{{name}} content script (DOM injector) initialized on', window.location.href);
2
+
3
+ function initDomHacks() {
4
+ const badge = document.createElement('div');
5
+ badge.className = 'we-injected-badge';
6
+ badge.textContent = '{{name}} Active';
7
+ document.body.appendChild(badge);
8
+
9
+ const observer = new MutationObserver((mutations) => {
10
+ for (const mutation of mutations) {
11
+ if (mutation.addedNodes.length > 0) {
12
+ }
13
+ }
14
+ });
15
+
16
+ observer.observe(document.body, { childList: true, subtree: true });
17
+
18
+ window.addEventListener(
19
+ 'pagehide',
20
+ () => {
21
+ observer.disconnect();
22
+ },
23
+ { once: true }
24
+ );
25
+ }
26
+
27
+ if (document.readyState === 'loading') {
28
+ document.addEventListener('DOMContentLoaded', initDomHacks);
29
+ } else {
30
+ initDomHacks();
31
+ }
32
+
@@ -0,0 +1,6 @@
1
+ import { api } from '../lib/browser.js';
2
+
3
+ console.log('{{name}} content script loaded on', window.location.href);
4
+
5
+ api.runtime?.sendMessage?.({ type: 'CONTENT_LOADED', url: window.location.href }).catch(() => {});
6
+
@@ -0,0 +1,6 @@
1
+ import { api } from '../lib/browser';
2
+
3
+ console.log('{{name}} content script loaded on', window.location.href);
4
+
5
+ api.runtime?.sendMessage?.({ type: 'CONTENT_LOADED', url: window.location.href }).catch(() => {});
6
+
@@ -0,0 +1,16 @@
1
+ .we-injected-badge {
2
+ position: fixed;
3
+ bottom: 16px;
4
+ right: 16px;
5
+ z-index: 999999;
6
+ background-color: #3b82f6;
7
+ color: #ffffff;
8
+ padding: 6px 12px;
9
+ font-family: system-ui, -apple-system, sans-serif;
10
+ font-size: 12px;
11
+ font-weight: 500;
12
+ border-radius: 6px;
13
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
14
+ pointer-events: none;
15
+ }
16
+
@@ -0,0 +1,9 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <script type="module" src="./devtools.js"></script>
6
+ </head>
7
+ <body></body>
8
+ </html>
9
+
@@ -0,0 +1,11 @@
1
+ import { api } from '../lib/browser.js';
2
+
3
+ api.devtools?.panels?.create(
4
+ '{{name}}',
5
+ 'icons/16.png',
6
+ 'src/devtools/panel.html',
7
+ () => {
8
+ console.log('DevTools panel created');
9
+ }
10
+ );
11
+
@@ -0,0 +1,18 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <title>{{name}} DevTools Panel</title>
6
+ <style>
7
+ body {
8
+ margin: 16px;
9
+ font-family: system-ui, sans-serif;
10
+ }
11
+ </style>
12
+ </head>
13
+ <body>
14
+ <h2>{{name}} DevTools Panel</h2>
15
+ <p>Custom DevTools panel is running.</p>
16
+ </body>
17
+ </html>
18
+
@@ -0,0 +1,9 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <script type="module" src="./devtools.ts"></script>
6
+ </head>
7
+ <body></body>
8
+ </html>
9
+
@@ -0,0 +1,11 @@
1
+ import { api } from '../lib/browser';
2
+
3
+ api.devtools?.panels?.create(
4
+ '{{name}}',
5
+ 'icons/16.png',
6
+ 'src/devtools/panel.html',
7
+ () => {
8
+ console.log('DevTools panel created');
9
+ }
10
+ );
11
+
@@ -0,0 +1,18 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <title>{{name}} DevTools Panel</title>
6
+ <style>
7
+ body {
8
+ margin: 16px;
9
+ font-family: system-ui, sans-serif;
10
+ }
11
+ </style>
12
+ </head>
13
+ <body>
14
+ <h2>{{name}} DevTools Panel</h2>
15
+ <p>Custom DevTools panel is running.</p>
16
+ </body>
17
+ </html>
18
+
@@ -0,0 +1,18 @@
1
+ [
2
+ {
3
+ "id": 1,
4
+ "priority": 1,
5
+ "action": {
6
+ "type": "block"
7
+ },
8
+ "condition": {
9
+ "urlFilter": "*://example.invalid/*",
10
+ "resourceTypes": [
11
+ "main_frame",
12
+ "sub_frame",
13
+ "xmlhttprequest"
14
+ ]
15
+ }
16
+ }
17
+ ]
18
+
@@ -0,0 +1,31 @@
1
+ import { api } from './browser.js';
2
+
3
+ /**
4
+ * @template T
5
+ * @param {string} key
6
+ * @param {T} [defaultValue]
7
+ * @returns {Promise<T | undefined>}
8
+ */
9
+ export async function getStorage(key, defaultValue) {
10
+ const result = await api.storage.local.get(key);
11
+ return result[key] ?? defaultValue;
12
+ }
13
+
14
+ /**
15
+ * @template T
16
+ * @param {string} key
17
+ * @param {T} value
18
+ * @returns {Promise<void>}
19
+ */
20
+ export async function setStorage(key, value) {
21
+ await api.storage.local.set({ [key]: value });
22
+ }
23
+
24
+ /**
25
+ * @param {string} key
26
+ * @returns {Promise<void>}
27
+ */
28
+ export async function removeStorage(key) {
29
+ await api.storage.local.remove(key);
30
+ }
31
+