@addfox/cli 0.1.1-beta.2

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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sources":["../src/pipeline/frameworkPlugins.ts","../src/pipeline/Pipeline.ts","../src/cli/args.ts","../src/utils/buildStats.ts","../src/utils/prefixStream.ts","../src/utils/zipDist.ts","../src/utils/version.ts","../src/commands/test.ts","../src/cli.ts"],"sourcesContent":["/**\r\n * Central list of framework Rsbuild plugins. Add or remove plugins here only.\r\n */\r\n\r\nimport type { RsbuildConfig } from \"@rsbuild/core\";\r\nimport type { PipelineContext } from \"@addfox/core\";\r\nimport { entryPlugin } from \"@addfox/rsbuild-plugin-extension-entry\";\r\nimport { extensionPlugin } from \"@addfox/rsbuild-plugin-extension-manifest\";\r\nimport { monitorPlugin } from \"@addfox/rsbuild-plugin-extension-monitor\";\r\nimport { getVueRsbuildPlugins } from \"@addfox/rsbuild-plugin-vue\";\r\n\r\ntype LoosePlugin = RsbuildConfig[\"plugins\"] extends (infer P)[] ? P : never;\r\n\r\nfunction expandUserPlugins(\r\n userPlugins: RsbuildConfig[\"plugins\"] | undefined,\r\n appRoot: string\r\n): LoosePlugin[] {\r\n const out: LoosePlugin[] = [];\r\n const list = userPlugins ?? [];\r\n const arr = Array.isArray(list) ? list : [list];\r\n for (const p of arr) {\r\n const name = (p as { name?: string } | null)?.name;\r\n if (name === \"rsbuild-plugin-vue\") {\r\n const vuePlugins = getVueRsbuildPlugins(appRoot);\r\n if (Array.isArray(vuePlugins)) out.push(...(vuePlugins as LoosePlugin[]));\r\n }\r\n out.push(p as LoosePlugin);\r\n }\r\n return out;\r\n}\r\n\r\n/**\r\n * Build the framework plugin array for base Rsbuild config.\r\n * Modifying the pipeline plugin set = edit this function only.\r\n */\r\nexport function buildFrameworkPluginList(ctx: PipelineContext): LoosePlugin[] {\r\n const useEntry = (ctx.config as { entry?: Record<string, unknown> | false }).entry !== false;\r\n const expanded = expandUserPlugins(ctx.config.plugins, ctx.root);\r\n const useMonitor = ctx.isDev && ctx.config.debug === true;\r\n\r\n const list: LoosePlugin[] = [];\r\n if (useEntry) {\r\n list.push(entryPlugin(ctx.config, ctx.entries, ctx.distPath, { browser: ctx.browser }) as LoosePlugin);\r\n }\r\n list.push(...expanded);\r\n if (useMonitor) {\r\n list.push(monitorPlugin(ctx.config, ctx.entries, ctx.browser) as LoosePlugin);\r\n }\r\n list.push(extensionPlugin(ctx.config, ctx.entries, ctx.browser, ctx.distPath) as LoosePlugin);\r\n return list;\r\n}\r\n","import { existsSync, readFileSync } from \"fs\";\r\nimport { resolve } from 'path';\r\nimport type { RsbuildConfig, RsbuildPlugin, RsbuildPluginAPI } from '@rsbuild/core';\r\nimport { mergeRsbuildConfig } from '@rsbuild/core';\r\nimport { HookManager } from '@addfox/common';\r\nimport type { PipelineContext, AddfoxResolvedConfig, EntryInfo, LaunchTarget } from '@addfox/core';\r\nimport { warn } from \"@addfox/common\";\r\nimport { AddfoxError, ADDFOX_ERROR_CODES } from \"@addfox/common\";\r\nimport {\r\n resolveAddfoxConfig,\r\n getManifestRecordForTarget,\r\n HMR_WS_PORT,\r\n toReloadManagerEntries,\r\n getBrowserOutputDir,\r\n} from \"@addfox/core\";\r\nimport { Pipeline as CorePipeline } from '@addfox/core/pipeline';\r\nimport { hmrPlugin, type HmrPluginOptions } from '@addfox/rsbuild-plugin-extension-hmr';\r\nimport { getMissingPackages, getAddCommand, detectFromLockfile } from '@addfox/pkg-manager';\r\nimport { buildFrameworkPluginList } from './frameworkPlugins.js';\r\n\r\ntype LoosePlugin = RsbuildConfig['plugins'] extends (infer P)[] ? P : never;\r\ntype RuntimeEnvConfig = {\r\n define: Record<string, string>;\r\n processEnvBase: Record<string, string>;\r\n backgroundPrivateEnv: Record<string, string>;\r\n};\r\n\r\nexport interface PipelineOptions {\r\n root: string;\r\n command: 'dev' | 'build';\r\n browser: 'chromium' | 'firefox';\r\n launch: LaunchTarget;\r\n cache: boolean;\r\n report: boolean | Record<string, unknown>;\r\n /** When true, enable error monitor in dev; CLI --debug overrides config.debug */\r\n debug?: boolean;\r\n /** When false, do not auto-open browser. */\r\n open?: boolean;\r\n /** Pre-loaded config to avoid double loading */\r\n config?: AddfoxResolvedConfig;\r\n baseEntries?: EntryInfo[];\r\n entries?: EntryInfo[];\r\n}\r\n\r\n/**\r\n * CLI-specific pipeline implementation\r\n */\r\nexport class Pipeline {\r\n private hookManager: HookManager<Record<string, PipelineContext>>;\r\n private corePipeline: CorePipeline;\r\n private options: PipelineOptions;\r\n\r\n constructor(options: PipelineOptions) {\r\n this.options = options;\r\n this.hookManager = new HookManager<Record<string, PipelineContext>>();\r\n this.corePipeline = new CorePipeline(this.hookManager);\r\n this.registerDefaultHooks();\r\n }\r\n\r\n /**\r\n * Get the hook manager for registering additional hooks\r\n */\r\n get hooks(): HookManager<Record<string, PipelineContext>> {\r\n return this.hookManager;\r\n }\r\n\r\n /**\r\n * Execute the build process\r\n */\r\n async run(): Promise<PipelineContext> {\r\n return this.corePipeline.execute(this.options.root, []);\r\n }\r\n\r\n /**\r\n * Register default build hooks\r\n */\r\n private registerDefaultHooks(): void {\r\n // Load stage: load config and entries (use pre-loaded if available)\r\n this.hookManager.register('load', 'after', async (ctx) => {\r\n if (this.options.config) {\r\n ctx.config = this.options.config;\r\n ctx.baseEntries = this.options.baseEntries ?? [];\r\n ctx.entries = this.options.entries ?? [];\r\n } else {\r\n const result = resolveAddfoxConfig(ctx.root);\r\n ctx.config = result.config;\r\n ctx.baseEntries = result.baseEntries;\r\n ctx.entries = result.entries;\r\n }\r\n });\r\n\r\n // Resolve stage: build context from options (CLI overrides config)\r\n this.hookManager.register('resolve', 'after', async (ctx) => {\r\n ctx.command = this.options.command;\r\n ctx.browser = this.options.browser;\r\n ctx.cache = this.options.cache;\r\n ctx.report = this.options.report;\r\n ctx.isDev = this.options.command === 'dev';\r\n // Use browser-specific output subdirectory: .addfox/extension/extension-chromium or extension-firefox\r\n const browserSubDir = getBrowserOutputDir(ctx.browser);\r\n ctx.distPath = resolve(ctx.root, ctx.config.outputRoot, ctx.config.outDir, browserSubDir);\r\n\r\n if (this.options.debug !== undefined) {\r\n ctx.config = { ...ctx.config, debug: this.options.debug };\r\n }\r\n\r\n // Warn about deprecated MV2 for Chromium\r\n if (ctx.browser === 'chromium') {\r\n const record = getManifestRecordForTarget(ctx.config.manifest, ctx.browser);\r\n if (record?.manifest_version === 2) {\r\n warn('Warning: MV2 has been deprecated for Chrome. Please use MV3.');\r\n }\r\n }\r\n });\r\n\r\n // Build stage: build Rsbuild config\r\n this.hookManager.register('build', 'after', async (ctx) => {\r\n ctx.rsbuild = await this.buildRsbuildConfig(ctx);\r\n });\r\n }\r\n\r\n private async buildRsbuildConfig(ctx: PipelineContext): Promise<RsbuildConfig> {\r\n const base = this.buildBaseRsbuildConfig(ctx);\r\n const userConfig = await this.resolveUserRsbuildConfig(base, ctx.config);\r\n \r\n let merged = mergeRsbuildConfig(base, userConfig);\r\n \r\n if (ctx.isDev) {\r\n const hmrOverrides = this.buildHmrOverrides(ctx);\r\n if (hmrOverrides) {\r\n merged = mergeRsbuildConfig(merged, hmrOverrides);\r\n }\r\n }\r\n \r\n if (ctx.report) {\r\n merged = await this.mergeRsdoctorPlugin(merged, ctx.root, ctx.config.outputRoot, ctx.report);\r\n }\r\n \r\n return merged;\r\n }\r\n\r\n private buildBaseRsbuildConfig(ctx: PipelineContext): RsbuildConfig {\r\n const runtimeEnvConfig = buildRuntimeEnvConfig(ctx.config, ctx.browser, ctx.root, ctx.isDev);\r\n const plugins = buildFrameworkPluginList(ctx);\r\n const scopedProcessEnvPlugin = createScopedProcessEnvPlugin(\r\n runtimeEnvConfig.processEnvBase,\r\n runtimeEnvConfig.backgroundPrivateEnv\r\n );\r\n if (scopedProcessEnvPlugin) plugins.push(scopedProcessEnvPlugin as LoosePlugin);\r\n\r\n return {\r\n root: ctx.root,\r\n plugins,\r\n source: {\r\n define: runtimeEnvConfig.define,\r\n },\r\n output: {\r\n legalComments: 'none',\r\n sourceMap: ctx.isDev ? { js: 'inline-source-map' } : false,\r\n },\r\n };\r\n }\r\n\r\n private async resolveUserRsbuildConfig(\r\n base: RsbuildConfig,\r\n config: AddfoxResolvedConfig\r\n ): Promise<RsbuildConfig> {\r\n const user = config.rsbuild;\r\n if (typeof user === 'function') {\r\n return user(base, { merge: mergeRsbuildConfig });\r\n }\r\n return (user && typeof user === 'object') ? user : {};\r\n }\r\n\r\n private buildHmrOverrides(ctx: PipelineContext): RsbuildConfig | undefined {\r\n const hotReload = ctx.config.hotReload;\r\n const hotReloadEnabled = hotReload !== false;\r\n const hotReloadOpts = typeof hotReload === 'object' && hotReload !== null ? hotReload : undefined;\r\n const isConfigRestart = process.env.ADDFOX_CONFIG_RESTART === '1';\r\n const reloadManagerEntries = toReloadManagerEntries(ctx.entries, ctx.root);\r\n\r\n // User-defined browser paths from addfox.config (optional overrides)\r\n const browserPathConfig = ctx.config.browserPath ?? {};\r\n\r\n const hmrOpts: HmrPluginOptions = {\r\n distPath: ctx.distPath,\r\n autoOpen: !isConfigRestart && (this.options.open !== false),\r\n browser: this.options.launch,\r\n debug: ctx.config.debug,\r\n root: ctx.root,\r\n outputRoot: ctx.config.outputRoot,\r\n chromePath: browserPathConfig.chrome,\r\n chromiumPath: browserPathConfig.chromium,\r\n edgePath: browserPathConfig.edge,\r\n bravePath: browserPathConfig.brave,\r\n vivaldiPath: browserPathConfig.vivaldi,\r\n operaPath: browserPathConfig.opera,\r\n santaPath: browserPathConfig.santa,\r\n arcPath: browserPathConfig.arc,\r\n yandexPath: browserPathConfig.yandex,\r\n browserosPath: browserPathConfig.browseros,\r\n customPath: browserPathConfig.custom,\r\n firefoxPath: browserPathConfig.firefox,\r\n cache: ctx.cache,\r\n wsPort: hotReloadOpts?.port ?? HMR_WS_PORT,\r\n enableReload: hotReloadEnabled,\r\n autoRefreshContentPage: hotReloadEnabled ? (hotReloadOpts?.autoRefreshContentPage ?? true) : false,\r\n reloadManagerEntries,\r\n };\r\n\r\n const useRsbuildClientHmr = ctx.browser !== 'firefox' && hotReloadEnabled;\r\n const devConfig = useRsbuildClientHmr\r\n ? {\r\n hmr: true,\r\n client: { protocol: 'ws' as const, host: '127.0.0.1', port: '<port>', path: '/rsbuild-hmr' },\r\n liveReload: true,\r\n writeToDisk: true,\r\n }\r\n : {\r\n hmr: false,\r\n liveReload: false,\r\n writeToDisk: true,\r\n };\r\n\r\n return {\r\n dev: devConfig,\r\n server: { printUrls: false, cors: { origin: '*' } },\r\n plugins: [hmrPlugin(hmrOpts) as LoosePlugin],\r\n };\r\n }\r\n\r\n private async mergeRsdoctorPlugin(\r\n config: RsbuildConfig,\r\n root: string,\r\n outputRoot: string,\r\n reportOption: true | Record<string, unknown>\r\n ): Promise<RsbuildConfig> {\r\n const missing = getMissingPackages(root, ['@rsdoctor/rspack-plugin']);\r\n if (missing.length > 0) {\r\n const pm = detectFromLockfile(root);\r\n const cmd = getAddCommand(pm, missing.join(' '), true);\r\n throw new AddfoxError({\r\n code: ADDFOX_ERROR_CODES.RSDOCTOR_NOT_INSTALLED,\r\n message: \"Rsdoctor plugin not installed\",\r\n details: \"report (-r/--report or config.report) requires @rsdoctor/rspack-plugin\",\r\n hint: `Install with: ${cmd}`,\r\n });\r\n }\r\n\r\n const reportDir = resolve(root, outputRoot, 'report');\r\n const { RsdoctorRspackPlugin } = await import('@rsdoctor/rspack-plugin');\r\n const tools = config.tools as { rspack?: { plugins?: unknown[] } } | undefined;\r\n const existing = tools?.rspack?.plugins ?? [];\r\n \r\n const pluginOptions = reportOption === true\r\n ? { output: { reportDir }, mode: 'brief' as const }\r\n : { ...(reportOption as Record<string, unknown>), output: { ...(reportOption as { output?: Record<string, unknown> }).output, reportDir } };\r\n\r\n const rsdoctorPlugin = new RsdoctorRspackPlugin(pluginOptions);\r\n\r\n return mergeRsbuildConfig(config, {\r\n tools: { rspack: { plugins: [...existing, rsdoctorPlugin] } },\r\n } as RsbuildConfig);\r\n }\r\n}\r\n\r\nfunction getManifestVersionValue(config: AddfoxResolvedConfig, browser: 'chromium' | 'firefox'): string {\r\n const manifestRecord = getManifestRecordForTarget(config.manifest, browser);\r\n const mv = manifestRecord?.manifest_version;\r\n if (typeof mv === \"number\" || typeof mv === \"string\") return String(mv);\r\n return \"\";\r\n}\r\n\r\nexport function buildRuntimeEnvDefine(\r\n config: AddfoxResolvedConfig,\r\n browser: 'chromium' | 'firefox',\r\n root: string,\r\n isDev: boolean\r\n): Record<string, string> {\r\n return buildRuntimeEnvConfig(config, browser, root, isDev).define;\r\n}\r\n\r\nfunction buildRuntimeEnvConfig(\r\n config: AddfoxResolvedConfig,\r\n browser: 'chromium' | 'firefox',\r\n root: string,\r\n isDev: boolean\r\n): RuntimeEnvConfig {\r\n const mode = isDev ? \"development\" : \"production\";\r\n const fileEnv = loadDotEnvByMode(root, mode);\r\n const mergedEnv = { ...fileEnv, ...process.env };\r\n const envPrefixes = getLoadEnvPrefixes(config);\r\n const publicEnv = pickPublicEnvVars(mergedEnv, envPrefixes);\r\n const backgroundPrivateEnv = pickBackgroundPrivateEnvVars(mergedEnv, envPrefixes);\r\n const manifestVersion = getManifestVersionValue(config, browser);\r\n const importMetaEnv = {\r\n ...publicEnv,\r\n MODE: mode,\r\n DEV: isDev,\r\n PROD: !isDev,\r\n BROWSER: browser,\r\n MANIFEST_VERSION: manifestVersion,\r\n };\r\n const processEnvForBundle = {\r\n NODE_ENV: mode,\r\n BROWSER: browser,\r\n MANIFEST_VERSION: manifestVersion,\r\n ...publicEnv,\r\n };\r\n\r\n return {\r\n define: {\r\n \"process.env\": \"globalThis.__ADDFOX_PROCESS_ENV__\",\r\n \"import.meta.env\": JSON.stringify(importMetaEnv),\r\n \"import.meta.env.BROWSER\": JSON.stringify(browser),\r\n \"import.meta.env.MANIFEST_VERSION\": JSON.stringify(manifestVersion),\r\n },\r\n processEnvBase: processEnvForBundle,\r\n backgroundPrivateEnv,\r\n };\r\n}\r\n\r\nexport function getLoadEnvPrefixes(config: AddfoxResolvedConfig): string[] {\r\n return config.envPrefix ?? [\"ADDFOX_PUBLIC_\"];\r\n}\r\n\r\nfunction pickPublicEnvVars(\r\n env: Record<string, string | undefined>,\r\n prefixes: string[]\r\n): Record<string, string> {\r\n const result: Record<string, string> = {};\r\n for (const [key, value] of Object.entries(env)) {\r\n if (typeof value !== \"string\") continue;\r\n if (!prefixes.some((prefix) => key.startsWith(prefix))) continue;\r\n result[key] = value;\r\n }\r\n return result;\r\n}\r\n\r\nfunction pickBackgroundPrivateEnvVars(\r\n env: Record<string, string | undefined>,\r\n publicPrefixes: string[]\r\n): Record<string, string> {\r\n const result: Record<string, string> = {};\r\n for (const [key, value] of Object.entries(env)) {\r\n if (typeof value !== \"string\") continue;\r\n if (!key.startsWith(\"ADDFOX_\")) continue;\r\n if (publicPrefixes.some((prefix) => key.startsWith(prefix))) continue;\r\n result[key] = value;\r\n }\r\n return result;\r\n}\r\n\r\nfunction createScopedProcessEnvPlugin(\r\n processEnvBase: Record<string, string>,\r\n privateEnv: Record<string, string>\r\n): RsbuildPlugin | undefined {\r\n if (Object.keys(processEnvBase).length === 0) return undefined;\r\n\r\n return {\r\n name: \"addfox-scoped-process-env\",\r\n setup(api: RsbuildPluginAPI) {\r\n api.modifyRsbuildConfig((config) => {\r\n const source = config.source ?? {};\r\n const entry = source.entry as Record<string, string | { import: string | string[]; html?: boolean }> | undefined;\r\n if (!entry) return;\r\n\r\n const nextEntry = { ...entry };\r\n const scopedEnvByEntry = buildScopedEnvByEntry(\r\n Object.keys(entry),\r\n processEnvBase,\r\n privateEnv\r\n );\r\n for (const [entryName, entryValue] of Object.entries(entry)) {\r\n const scopedEnv = scopedEnvByEntry[entryName] ?? processEnvBase;\r\n const snippet = buildScopedProcessEnvSnippet(scopedEnv);\r\n const prepend = `data:text/javascript,${encodeURIComponent(snippet)}`;\r\n nextEntry[entryName] = prependDataModule(entryValue, prepend);\r\n }\r\n\r\n config.source = { ...source, entry: nextEntry };\r\n });\r\n },\r\n };\r\n}\r\n\r\nexport function buildScopedEnvByEntry(\r\n entryNames: string[],\r\n processEnvBase: Record<string, string>,\r\n privateEnv: Record<string, string>\r\n): Record<string, Record<string, string>> {\r\n const result: Record<string, Record<string, string>> = {};\r\n for (const entryName of entryNames) {\r\n result[entryName] = entryName === \"background\"\r\n ? { ...processEnvBase, ...privateEnv }\r\n : { ...processEnvBase };\r\n }\r\n return result;\r\n}\r\n\r\nfunction buildScopedProcessEnvSnippet(processEnv: Record<string, string>): string {\r\n const envJson = JSON.stringify(processEnv);\r\n return `\r\nconst addfoxScopedEnv = ${envJson};\r\nif (!globalThis.__ADDFOX_PROCESS_ENV__) {\r\n globalThis.__ADDFOX_PROCESS_ENV__ = {};\r\n}\r\nObject.assign(globalThis.__ADDFOX_PROCESS_ENV__, addfoxScopedEnv);\r\n`;\r\n}\r\n\r\nfunction prependDataModule(\r\n entryValue: string | { import: string | string[]; html?: boolean },\r\n prependModule: string\r\n): { import: string | string[]; html?: boolean } {\r\n if (typeof entryValue === \"string\") {\r\n return { import: [prependModule, entryValue] };\r\n }\r\n if (Array.isArray(entryValue.import)) {\r\n return { ...entryValue, import: [prependModule, ...entryValue.import] };\r\n }\r\n return { ...entryValue, import: [prependModule, entryValue.import] };\r\n}\r\n\r\nfunction loadDotEnvByMode(root: string, mode: \"development\" | \"production\"): Record<string, string> {\r\n const result: Record<string, string> = {};\r\n const files = [\".env\", \".env.local\", `.env.${mode}`, `.env.${mode}.local`];\r\n\r\n for (const file of files) {\r\n const path = resolve(root, file);\r\n if (!existsSync(path)) continue;\r\n const parsed = parseDotEnv(readFileSync(path, \"utf-8\"));\r\n Object.assign(result, parsed);\r\n }\r\n\r\n return result;\r\n}\r\n\r\nfunction parseDotEnv(content: string): Record<string, string> {\r\n const result: Record<string, string> = {};\r\n const lines = content.split(/\\r?\\n/);\r\n\r\n for (const line of lines) {\r\n const trimmed = line.trim();\r\n if (!trimmed || trimmed.startsWith(\"#\")) continue;\r\n const eq = trimmed.indexOf(\"=\");\r\n if (eq <= 0) continue;\r\n\r\n const key = trimmed.slice(0, eq).trim();\r\n const rawValue = trimmed.slice(eq + 1).trim();\r\n result[key] = stripQuotes(rawValue);\r\n }\r\n\r\n return result;\r\n}\r\n\r\nfunction stripQuotes(value: string): string {\r\n if (value.length < 2) return value;\r\n const quote = value[0];\r\n if ((quote !== '\"' && quote !== \"'\") || value[value.length - 1] !== quote) return value;\r\n return value.slice(1, -1);\r\n}\r\n\r\n/**\r\n * Run pipeline with given options\r\n */\r\nexport async function runPipeline(\r\n options: PipelineOptions\r\n): Promise<PipelineContext> {\r\n const pipeline = new Pipeline(options);\r\n return pipeline.run();\r\n}\r\n","import {\n CLI_COMMANDS,\n type BrowserTarget,\n type CliCommand,\n type LaunchTarget,\n} from \"@addfox/core\";\nimport { AddfoxError, ADDFOX_ERROR_CODES } from \"@addfox/common\";\n\nconst BROWSER_FLAGS = [\"-b\", \"--browser\"];\nconst REPORT_FLAGS = [\"-r\", \"--report\"];\n\n/** Maps any browser input to its manifest target (chromium/firefox) */\nconst BROWSER_TO_TARGET: Record<string, BrowserTarget> = {\n chromium: \"chromium\",\n chrome: \"chromium\",\n edge: \"chromium\",\n brave: \"chromium\",\n vivaldi: \"chromium\",\n opera: \"chromium\",\n santa: \"chromium\",\n arc: \"chromium\",\n yandex: \"chromium\",\n browseros: \"chromium\",\n custom: \"chromium\",\n firefox: \"firefox\",\n};\n\n/** Valid launch targets (browser names that can be launched) */\nconst VALID_LAUNCH_TARGETS = new Set([\n \"chrome\", \"chromium\", \"edge\", \"brave\", \"vivaldi\", \"opera\",\n \"santa\", \"arc\", \"yandex\", \"browseros\", \"custom\", \"firefox\",\n]);\n\nexport interface CliParseResult {\n command: CliCommand;\n /** Browser target for manifest (chromium/firefox) */\n browser?: BrowserTarget;\n /** Specific browser to launch (chrome/chromium/edge/brave/firefox/...) */\n launch?: LaunchTarget;\n unknownBrowser?: string;\n cache?: boolean;\n /** When true, same as debug: true in addfox.config (e.g. enable monitor in dev). From --debug. */\n debug?: boolean;\n /** When true, enable Rsdoctor build report (RSDOCTOR=true). From -r/--report. */\n report?: boolean;\n /** When false, do not auto-open browser. From --no-open. */\n open?: boolean;\n}\n\n/** CLI parser: parses command, -b/--browser; throws AddfoxError on invalid input. */\nexport class CliParser {\n parse(argv: string[]): CliParseResult {\n const cmdRaw = argv[0] ?? \"dev\";\n const command = CLI_COMMANDS.includes(cmdRaw as CliCommand) ? (cmdRaw as CliCommand) : null;\n if (command === null) {\n throw new AddfoxError({\n code: ADDFOX_ERROR_CODES.UNKNOWN_COMMAND,\n message: \"Unknown command\",\n details: `Command: \"${cmdRaw}\"`,\n hint: \"Supported: addfox dev | addfox build | addfox test [-b chrome|...]; custom requires browser.custom in config\",\n });\n }\n const { browser, launch, unknown: unknownBrowser } = this.getBrowserFromArgv(argv);\n const cache = this.getCacheFromArgv(argv);\n const debug = this.getDebugFromArgv(argv);\n const report = this.getReportFromArgv(argv);\n const open = this.getOpenFromArgv(argv);\n return { command, browser, launch, unknownBrowser, cache, debug, report, open };\n }\n\n private getBrowserFromArgv(argv: string[]): { browser?: BrowserTarget; launch?: LaunchTarget; unknown?: string } {\n for (let i = 0; i < argv.length; i++) {\n const arg = argv[i];\n if (BROWSER_FLAGS.includes(arg)) {\n const value = argv[i + 1];\n if (value && !value.startsWith(\"-\")) {\n const normalized = value.trim().toLowerCase();\n const browser = BROWSER_TO_TARGET[normalized];\n if (browser) {\n // launch is the specific browser (chrome/edge/brave...), browser is the target (chromium/firefox)\n const launch = (VALID_LAUNCH_TARGETS.has(normalized) ? normalized : undefined) as LaunchTarget | undefined;\n return { browser, launch };\n }\n return { unknown: value };\n }\n }\n if (arg.startsWith(\"-b=\") || arg.startsWith(\"--browser=\")) {\n const normalized = (arg.split(\"=\")[1] ?? \"\").trim().toLowerCase();\n const browser = BROWSER_TO_TARGET[normalized];\n if (browser) {\n const launch = (VALID_LAUNCH_TARGETS.has(normalized) ? normalized : undefined) as LaunchTarget | undefined;\n return { browser, launch };\n }\n return { unknown: normalized };\n }\n }\n return {};\n }\n\n private getCacheFromArgv(argv: string[]): boolean | undefined {\n let cache: boolean | undefined;\n for (const arg of argv) {\n if (arg === \"-c\" || arg === \"--cache\") cache = true;\n if (arg === \"--no-cache\") cache = false;\n }\n return cache;\n }\n\n private getDebugFromArgv(argv: string[]): true | undefined {\n return argv.some((arg) => arg === \"--debug\") ? true : undefined;\n }\n\n private getReportFromArgv(argv: string[]): true | undefined {\n return argv.some((arg) => REPORT_FLAGS.includes(arg)) ? true : undefined;\n }\n\n private getOpenFromArgv(argv: string[]): boolean {\n return !argv.some((arg) => arg === \"--no-open\");\n }\n\n assertSupportedBrowser(value: string): asserts value is BrowserTarget {\n const b = BROWSER_TO_TARGET[value.trim().toLowerCase()];\n if (b) return;\n throw new AddfoxError({\n code: ADDFOX_ERROR_CODES.INVALID_BROWSER,\n message: \"Unsupported browser argument\",\n details: `Current value: \"${value}\"`,\n hint:\n \"Use -b chrome/chromium/edge/brave/vivaldi/opera/santa/arc/yandex/browseros/custom/firefox or --browser=...; use custom only with browser.custom in config\",\n });\n }\n}\n\nconst defaultParser: CliParser = new CliParser();\n\nexport function parseCliArgs(argv: string[]): CliParseResult {\n return defaultParser.parse(argv);\n}\n\nexport function assertSupportedBrowser(value: string): asserts value is BrowserTarget {\n defaultParser.assertSupportedBrowser(value);\n}\n","import { resolve } from \"path\";\r\nimport { existsSync, statSync, readdirSync } from \"fs\";\r\n\r\n/** Recursively compute directory size in bytes. */\r\nexport function getDistSizeSync(dirPath: string): number {\r\n if (!existsSync(dirPath)) return -1;\r\n const stat = statSync(dirPath);\r\n if (!stat.isDirectory()) return stat.size;\r\n let total = 0;\r\n for (const name of readdirSync(dirPath)) {\r\n const s = statSync(resolve(dirPath, name));\r\n total += s.isDirectory() ? getDistSizeSync(resolve(dirPath, name)) : s.size;\r\n }\r\n return total;\r\n}\r\n\r\nexport function formatBytes(bytes: number): string {\r\n if (bytes < 1024) return bytes + \" B\";\r\n if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(2) + \" KB\";\r\n return (bytes / (1024 * 1024)).toFixed(2) + \" MB\";\r\n}\r\n\r\n/** Whether the Rsbuild config has JS source map enabled (any format). */\r\nexport function isSourceMapEnabled(\r\n rsbuildConfig: { output?: { sourceMap?: unknown } }\r\n): boolean {\r\n const sm = rsbuildConfig?.output?.sourceMap;\r\n if (sm === true) return true;\r\n if (sm && typeof sm === \"object\" && typeof (sm as { js?: string }).js === \"string\") {\r\n return true;\r\n }\r\n return false;\r\n}\r\n\r\n/** Get total size of build output from Rsbuild build result (stats.assets). */\r\nexport function getBuildOutputSize(result: unknown): number | null {\r\n const stats = (\r\n result as {\r\n stats?: {\r\n toJson?: (opts: unknown) => { assets?: Array<{ size?: number }> };\r\n };\r\n }\r\n )?.stats;\r\n if (!stats?.toJson) return null;\r\n try {\r\n const json = stats.toJson({ all: false, assets: true });\r\n const assets = json?.assets;\r\n if (!Array.isArray(assets)) return null;\r\n let total = 0;\r\n for (const a of assets) {\r\n if (a && typeof a.size === \"number\") total += a.size;\r\n }\r\n return total > 0 ? total : null;\r\n } catch {\r\n return null;\r\n }\r\n}\r\n","import { getWebExtStdoutOriginDepth } from \"@addfox/common\";\n\n/** ANSI: orange (256 color 208), then reset. Exported for tests. */\nexport const ADDFOX_PREFIX = \"\\x1b[38;5;208m[Addfox]\\x1b[0m \";\n/** Light purple [Rsbuild] for rsbuild-origin lines (256 color 141) */\nconst RSBUILD_PREFIX = \"\\x1b[38;5;141m[Rsbuild]\\x1b[0m \";\n/** Cyan [Web-ext] for web-ext-origin lines (256 color 45) */\nconst WEBEXT_PREFIX = \"\\x1b[38;5;45m[Web-ext]\\x1b[0m \";\n\nlet rawStdoutWrite: NodeJS.WriteStream[\"write\"] | null = null;\nlet rawStderrWrite: NodeJS.WriteStream[\"write\"] | null = null;\n\n/** \"addfox\" | \"rsbuild\" — which prefix to use for wrapped stdout/stderr (non-logger output). */\nlet outputPrefix: \"addfox\" | \"rsbuild\" = \"addfox\";\n\n/**\n * Use [Rsbuild] prefix for subsequent stdout/stderr lines (e.g. before createRsbuild / startDevServer).\n * Call setOutputPrefixAddfox() after build() to restore [Addfox] for non-rsbuild output.\n */\nexport function setOutputPrefixRsbuild(): void {\n outputPrefix = \"rsbuild\";\n}\n\n/**\n * Use [Addfox] prefix for subsequent stdout/stderr lines. Call after rsbuild.build() when only addfox will write.\n */\nexport function setOutputPrefixAddfox(): void {\n outputPrefix = \"addfox\";\n}\n\n/** Return raw stream writes (before wrap) for the shared logger so output has a single prefix. */\nexport function getRawWrites(): {\n stdout: NodeJS.WriteStream[\"write\"];\n stderr: NodeJS.WriteStream[\"write\"];\n} {\n return {\n stdout: rawStdoutWrite ?? process.stdout.write.bind(process.stdout),\n stderr: rawStderrWrite ?? process.stderr.write.bind(process.stderr),\n };\n}\n\ntype Encoding = BufferEncoding | ((err?: Error) => void);\ntype WriteCallback = (err?: Error) => void;\n\nfunction isEncoding(x: Encoding | undefined): x is BufferEncoding {\n return typeof x === \"string\";\n}\n\n/** Exported for tests. */\nexport function createPrefixedWrite(\n stream: NodeJS.WriteStream,\n getPrefix: (line: string) => string\n): NodeJS.WriteStream[\"write\"] {\n const originalWrite = stream.write.bind(stream);\n let buffer = \"\";\n\n function flushIncomplete() {\n if (buffer.length > 0) {\n originalWrite(getPrefix(buffer) + buffer);\n buffer = \"\";\n }\n }\n\n const write: NodeJS.WriteStream[\"write\"] = function (\n chunk: string | Buffer | Uint8Array,\n encodingOrCallback?: Encoding,\n callback?: WriteCallback\n ): boolean {\n const encoding: BufferEncoding | undefined = isEncoding(encodingOrCallback)\n ? encodingOrCallback\n : undefined;\n const cb = typeof encodingOrCallback === \"function\" ? encodingOrCallback : callback;\n const str = typeof chunk === \"string\" ? chunk : chunk.toString(encoding ?? \"utf8\");\n buffer += str;\n const lines = buffer.split(\"\\n\");\n buffer = lines.pop() ?? \"\";\n for (const line of lines) {\n originalWrite(getPrefix(line) + line + \"\\n\", encoding as BufferEncoding);\n }\n if (typeof cb === \"function\") cb();\n return true;\n };\n\n (write as { flush?: () => void }).flush = flushIncomplete;\n return write;\n}\n\n/**\n * Wraps process.stdout and process.stderr so each line is prefixed with colored \"[Addfox]\" or \"[Rsbuild]\".\n * Call before running rsbuild dev/build. Use setOutputPrefixRsbuild() before rsbuild, setOutputPrefixAddfox() after build.\n */\nexport function wrapAddfoxOutput(): void {\n rawStdoutWrite = process.stdout.write.bind(process.stdout);\n rawStderrWrite = process.stderr.write.bind(process.stderr);\n\n const getPrefix = (_line: string): string => {\n if (outputPrefix === \"rsbuild\" && getWebExtStdoutOriginDepth() > 0) {\n return WEBEXT_PREFIX;\n }\n return outputPrefix === \"rsbuild\" ? RSBUILD_PREFIX : ADDFOX_PREFIX;\n };\n const stdoutWrite = createPrefixedWrite(process.stdout, getPrefix);\n const stderrWrite = createPrefixedWrite(process.stderr, getPrefix);\n\n (process.stdout as NodeJS.WriteStream & { write: NodeJS.WriteStream[\"write\"] }).write = stdoutWrite;\n (process.stderr as NodeJS.WriteStream & { write: NodeJS.WriteStream[\"write\"] }).write = stderrWrite;\n\n const flush = () => {\n const fOut = (stdoutWrite as { flush?: () => void }).flush;\n const fErr = (stderrWrite as { flush?: () => void }).flush;\n if (fOut) fOut();\n if (fErr) fErr();\n };\n\n process.once(\"exit\", flush);\n}\n","import { createWriteStream, mkdirSync, existsSync } from \"fs\";\r\nimport { resolve } from \"path\";\r\nimport archiver from \"archiver\";\r\nimport type { AddfoxErrorCode } from \"@addfox/common\";\r\nimport { AddfoxError } from \"@addfox/common\";\r\nimport { ADDFOX_OUTPUT_ROOT, type BrowserTarget, getBrowserOutputDir } from \"@addfox/core\";\r\n\r\n/** Error codes for zip operations; match core ADDFOX_ERROR_CODES */\r\nconst ZIP_OUTPUT_CODE = \"ADDFOX_ZIP_OUTPUT\" as AddfoxErrorCode;\r\nconst ZIP_ARCHIVE_CODE = \"ADDFOX_ZIP_ARCHIVE\" as AddfoxErrorCode;\r\n\r\n/** Default zlib level for zip compression */\r\nconst ZIP_LEVEL = 9;\r\n\r\n/** Optional for tests: inject stream/archiver to trigger error paths */\r\nexport type ZipDistDeps = {\r\n createWriteStream?: typeof createWriteStream;\r\n archiver?: typeof archiver;\r\n mkdirSync?: typeof mkdirSync;\r\n existsSync?: typeof existsSync;\r\n};\r\n\r\n/**\r\n * Packs the built output directory into a zip file.\r\n * Output: root/.addfox/<outDir>/<outDir>-<browser>.zip (browser-specific zip inside .addfox/<outDir>).\r\n * Zip contents are the files inside distPath (no extra top-level folder).\r\n */\r\nexport function zipDist(\r\n distPath: string,\r\n root: string,\r\n outDir: string,\r\n browser?: BrowserTarget,\r\n deps?: ZipDistDeps\r\n): Promise<string> {\r\n const createStream = deps?.createWriteStream ?? createWriteStream;\r\n const archiverFn = deps?.archiver ?? archiver;\r\n const mkdir = deps?.mkdirSync ?? mkdirSync;\r\n const exists = deps?.existsSync ?? existsSync;\r\n const outputRoot = ADDFOX_OUTPUT_ROOT;\r\n // Zip file goes to .addfox/<outDir>/<outDir>-<browser>.zip\r\n const zipDir = resolve(root, outputRoot, outDir);\r\n if (!exists(zipDir)) mkdir(zipDir, { recursive: true });\r\n const browserSuffix = browser ? `-${browser}` : \"\";\r\n const zipPath = resolve(zipDir, `${outDir}${browserSuffix}.zip`);\r\n const output = createStream(zipPath);\r\n const archive = archiverFn(\"zip\", { zlib: { level: ZIP_LEVEL } });\r\n\r\n return new Promise((resolvePromise, reject) => {\r\n output.on(\"error\", (err) =>\r\n reject(\r\n new AddfoxError({\r\n message: \"Zip output stream failed\",\r\n code: ZIP_OUTPUT_CODE,\r\n details: err instanceof Error ? err.message : String(err),\r\n cause: err,\r\n })\r\n )\r\n );\r\n output.on(\"close\", () => resolvePromise(zipPath));\r\n\r\n archive.on(\"error\", (err: unknown) =>\r\n reject(\r\n new AddfoxError({\r\n message: \"Zip archive failed\",\r\n code: ZIP_ARCHIVE_CODE,\r\n details: err instanceof Error ? err.message : String(err),\r\n cause: err,\r\n })\r\n )\r\n );\r\n archive.pipe(output);\r\n archive.directory(distPath, false);\r\n archive.finalize();\r\n });\r\n}\r\n","import { resolve, dirname } from \"path\";\r\nimport { existsSync, readFileSync } from \"fs\";\r\nimport { fileURLToPath } from \"url\";\r\nimport { createRequire } from \"module\";\r\n\r\nconst require = createRequire(import.meta.url);\r\n\r\nfunction readPackageVersion(pkgPath: string): string {\r\n try {\r\n const pkg = JSON.parse(readFileSync(pkgPath, \"utf-8\")) as { version?: string };\r\n return pkg.version ?? \"?\";\r\n } catch {\r\n return \"?\";\r\n }\r\n}\r\n\r\n/** Get addfox CLI package version. */\r\nexport function getVersion(): string {\r\n try {\r\n const pkgPath = resolve(\r\n dirname(fileURLToPath(import.meta.url)),\r\n \"..\",\r\n \"package.json\"\r\n );\r\n return readPackageVersion(pkgPath) || \"0.0.0\";\r\n } catch {\r\n return \"0.0.0\";\r\n }\r\n}\r\n\r\n/** Get @rsbuild/core version from project or monorepo. */\r\nexport function getRsbuildVersion(projectRoot: string): string {\r\n const cliDir = dirname(fileURLToPath(import.meta.url));\r\n const candidates = [\r\n () => {\r\n const p = resolve(projectRoot, \"node_modules\", \"@rsbuild\", \"core\", \"package.json\");\r\n return existsSync(p) ? p : null;\r\n },\r\n () => {\r\n try {\r\n return require.resolve(\"@rsbuild/core/package.json\", { paths: [projectRoot] });\r\n } catch {\r\n return null;\r\n }\r\n },\r\n () => {\r\n try {\r\n return require.resolve(\"@rsbuild/core/package.json\", {\r\n paths: [resolve(cliDir, \"..\"), resolve(cliDir, \"..\", \"..\")],\r\n });\r\n } catch {\r\n return null;\r\n }\r\n },\r\n ];\r\n for (const getPath of candidates) {\r\n const pkgPath = getPath();\r\n if (!pkgPath) continue;\r\n return readPackageVersion(pkgPath);\r\n }\r\n return \"?\";\r\n}\r\n","import { resolve, dirname } from \"path\";\r\nimport { existsSync, readFileSync } from \"fs\";\r\nimport { spawnSync } from \"child_process\";\r\nimport { createRequire } from \"module\";\r\nimport { exitWithError, AddfoxError, ADDFOX_ERROR_CODES } from \"@addfox/common\";\r\nimport { getResolvedRstestConfigFilePath } from \"@addfox/core\";\r\nimport {\r\n detectFromLockfile,\r\n getAddCommand,\r\n getMissingPackages,\r\n} from \"@addfox/pkg-manager\";\r\n\r\nconst require = createRequire(import.meta.url);\r\n\r\nfunction hasRstestConfigFile(projectRoot: string): boolean {\r\n return getResolvedRstestConfigFilePath(projectRoot) !== null;\r\n}\r\n\r\n/** Detect browser.enabled from rstest config via regex (avoids loading .ts). */\r\nfunction isRstestBrowserEnabled(projectRoot: string): boolean {\r\n const configPath = getResolvedRstestConfigFilePath(projectRoot);\r\n if (!configPath) return false;\r\n try {\r\n const content = readFileSync(configPath, \"utf-8\");\r\n return (\r\n /browser\\s*:\\s*\\{[^}]*enabled\\s*:\\s*true/.test(content) ||\r\n /browser\\.enabled\\s*===?\\s*true/.test(content)\r\n );\r\n } catch {\r\n return false;\r\n }\r\n}\r\n\r\nfunction getRequiredTestPackages(projectRoot: string): string[] {\r\n const required: string[] = [\"@rstest/core\"];\r\n if (isRstestBrowserEnabled(projectRoot)) {\r\n required.push(\"@rstest/browser\", \"playwright\");\r\n }\r\n return required;\r\n}\r\n\r\nfunction getRstestBinPath(projectRoot: string): string {\r\n const binDir = resolve(projectRoot, \"node_modules\", \".bin\");\r\n const name = process.platform === \"win32\" ? \"rstest.cmd\" : \"rstest\";\r\n const p = resolve(binDir, name);\r\n if (existsSync(p)) return p;\r\n const fallback = resolve(binDir, \"rstest\");\r\n if (existsSync(fallback)) return fallback;\r\n try {\r\n const corePkgPath = require.resolve(\"@rstest/core/package.json\", {\r\n paths: [projectRoot],\r\n });\r\n const coreDir = dirname(corePkgPath);\r\n const binInCore = resolve(coreDir, \"bin\", \"rstest.js\");\r\n if (existsSync(binInCore)) return binInCore;\r\n } catch {\r\n /* fall through to exitWithError */\r\n }\r\n exitWithError(\r\n new Error(\r\n \"rstest binary not found in node_modules/.bin after installing @rstest/core\"\r\n )\r\n );\r\n}\r\n\r\nfunction runRstest(projectRoot: string, restArgs: string[]): number {\r\n const rstestBin = getRstestBinPath(projectRoot);\r\n const result = spawnSync(rstestBin, restArgs, {\r\n cwd: projectRoot,\r\n stdio: \"inherit\",\r\n shell: process.platform === \"win32\",\r\n });\r\n return result.status ?? 0;\r\n}\r\n\r\n/**\r\n * Run addfox test: ensure rstest config exists, install missing deps, forward to rstest.\r\n */\r\nexport async function runTest(projectRoot: string, argv: string[]): Promise<void> {\r\n if (!hasRstestConfigFile(projectRoot)) {\r\n const files = \"rstest.config.cts, rstest.config.mts, rstest.config.cjs, rstest.config.js, rstest.config.ts, rstest.config.mjs\";\r\n throw new AddfoxError({\r\n code: ADDFOX_ERROR_CODES.RSTEST_CONFIG_NOT_FOUND,\r\n message: \"Rstest config file not found\",\r\n details: `No rstest.config.* found under ${projectRoot}`,\r\n hint: `Create one of: ${files}`,\r\n });\r\n }\r\n\r\n const required = getRequiredTestPackages(projectRoot);\r\n const missing = getMissingPackages(projectRoot, required);\r\n if (missing.length > 0) {\r\n const pm = detectFromLockfile(projectRoot);\r\n const installCmd = getAddCommand(pm, missing.join(\" \"), true);\r\n exitWithError(\r\n new Error(\r\n `Missing test dependencies: ${missing.join(\", \")}. Please run:\\n ${installCmd}`\r\n )\r\n );\r\n }\r\n\r\n const restArgs = argv.slice(1);\r\n const code = runRstest(projectRoot, restArgs);\r\n process.exit(code);\r\n}\r\n","#!/usr/bin/env node\nimport { resolve } from \"path\";\nimport { existsSync, watch } from \"fs\";\nimport { runPipeline, type PipelineOptions } from \"./pipeline/index.ts\";\nimport { getLoadEnvPrefixes } from \"./pipeline/Pipeline.ts\";\nimport { parseCliArgs } from \"./cli/index.ts\";\nimport {\n wrapAddfoxOutput,\n getRawWrites,\n setOutputPrefixRsbuild,\n setOutputPrefixAddfox,\n zipDist,\n getVersion,\n getRsbuildVersion,\n getDistSizeSync,\n formatBytes,\n isSourceMapEnabled,\n getBuildOutputSize,\n} from \"./utils/index.ts\";\nimport { runTest } from \"./commands/index.ts\";\nimport {\n log,\n logDone,\n logDoneTimed,\n logDoneWithValue,\n setAddfoxLoggerRawWrites,\n error,\n formatError,\n exitWithError,\n AddfoxError,\n ADDFOX_ERROR_CODES,\n} from \"@addfox/common\";\nimport {\n CONFIG_FILES,\n getResolvedConfigFilePath,\n clearConfigCache,\n resolveAddfoxConfig,\n} from \"@addfox/core\";\nimport type { PipelineContext, AddfoxResolvedConfig, BrowserTarget, LaunchTarget } from \"@addfox/core\";\nimport { launchBrowserOnly } from \"@addfox/rsbuild-plugin-extension-hmr\";\n\nconst root = process.cwd();\n\n/** ANSI light purple for Rsbuild branding (256 color 141). */\nconst PURPLE = \"\\x1b[38;5;141m\";\nconst RESET = \"\\x1b[0m\";\n\nfunction hasConfigFile(): boolean {\n return CONFIG_FILES.some((file) => existsSync(resolve(root, file)));\n}\n\nfunction printHelp(): void {\n const version = getVersion();\n console.log(`\n addfox v${version}\n\n Build tool for browser extensions\n\n Usage:\n addfox <command> [options]\n\n Commands:\n dev Start development server with HMR\n build Build for production\n test Run tests with rstest (unit + optional E2E); forwards args to rstest\n\n Options:\n -b, --browser <browser> Target/launch browser (chromium | firefox | chrome | edge | brave | ...)\n -c, --cache Cache browser profile between launches\n --no-cache Disable browser profile cache for current run\n -r, --report Enable Rsdoctor build report (opens analysis after build)\n --no-open Do not auto-open browser (dev/build)\n --debug Enable debug mode\n --help Show this help message\n --version Show version number\n`);\n}\n\n// ─── Resolve options from CLI args and config ───\n\ninterface ResolvedCliOptions {\n /** Manifest/build target: chromium vs firefox (from -b/--browser, normalized by parser). */\n browser: BrowserTarget;\n /** Which executable to launch in dev (chrome/edge/brave/firefox/...); distinct from browser. */\n launch: LaunchTarget;\n cache: boolean;\n report: boolean | Record<string, unknown>;\n debug: boolean;\n /** When false, do not auto-open browser. */\n open: boolean;\n}\n\nfunction resolveOptions(argv: string[], config: AddfoxResolvedConfig): ResolvedCliOptions {\n const parsed = parseCliArgs(argv);\n // Parser maps -b/--browser into both: browser = chromium|firefox, launch = chrome|edge|firefox|...\n // (e.g. -b edge => browser=chromium, launch=edge). No overlap: browser for manifest, launch for dev open.\n\n const browser = parsed.browser ?? \"chromium\";\n const launch = parsed.launch ?? (browser === \"firefox\" ? \"firefox\" : \"chrome\");\n\n // CLI overrides config: --debug takes precedence over config.debug\n const debug = parsed.debug ?? config.debug ?? false;\n\n return {\n browser,\n launch,\n cache: parsed.cache ?? config.cache ?? true,\n report: parsed.report ?? false,\n debug,\n open: parsed.open ?? true,\n };\n}\n\n// ─── Shared Rsbuild instance creation ───\n\nasync function createRsbuildInstance(ctx: PipelineContext) {\n setOutputPrefixRsbuild();\n const { createRsbuild } = await import(\"@rsbuild/core\");\n const rsbuild = await createRsbuild({\n rsbuildConfig: ctx.rsbuild,\n cwd: ctx.root,\n loadEnv: {\n cwd: ctx.root,\n prefixes: getLoadEnvPrefixes(ctx.config),\n },\n });\n return rsbuild;\n}\n\n/** Log extension size info to terminal. */\nfunction logExtensionSize(distDir: string, rsbuildConfig: { output?: { sourceMap?: unknown } }): void {\n const size = getDistSizeSync(distDir);\n if (size < 0) return;\n const sizeStr = formatBytes(size);\n const suffix = isSourceMapEnabled(rsbuildConfig) ? \" (with inline-source-map)\" : \"\";\n logDoneWithValue(\"Extension size:\", sizeStr + suffix);\n}\n\n// ─── addfox.config file watcher ───\n\nconst ADDFOX_CONFIG_DEBOUNCE_MS = 300;\n\n/**\n * Watch addfox.config file; on change, run onRestart (e.g. close dev server and re-run dev in-process).\n * Returns the watcher so caller can close it before restarting.\n */\nfunction watchAddfoxConfig(\n configPath: string,\n onRestart: () => void | Promise<void>\n): { close: () => void } {\n let timer: ReturnType<typeof setTimeout> | null = null;\n const run = (): void => {\n if (timer) clearTimeout(timer);\n timer = setTimeout(() => {\n timer = null;\n Promise.resolve(onRestart()).catch((e) => {\n error(formatError(e));\n exitWithError(e);\n });\n }, ADDFOX_CONFIG_DEBOUNCE_MS);\n };\n try {\n const watcher = watch(configPath, { persistent: true }, (eventType, filename) => {\n if (filename && (eventType === \"change\" || eventType === \"rename\")) run();\n });\n return { close() { try { watcher.close(); } catch { /* ignore */ } } };\n } catch {\n return { close() {} };\n }\n}\n\n// ─── Dev / Build commands ───\n\n/** Dev mode: auto-restart dev server on addfox.config change. */\nasync function runDev(root: string, argv: string[]): Promise<void> {\n // Load config first to get defaults\n const { config, baseEntries, entries } = resolveAddfoxConfig(root);\n \n const resolved = resolveOptions(argv, config);\n const options: PipelineOptions = {\n root,\n command: 'dev',\n ...resolved,\n config,\n baseEntries,\n entries,\n };\n const rsbuildReadyStart = performance.now();\n const ctx = await runPipeline(options);\n process.env.NODE_ENV = ctx.isDev ? \"development\" : \"production\";\n const rsbuild = await createRsbuildInstance(ctx);\n logDoneTimed(\"Rsbuild ready\", Math.round(performance.now() - rsbuildReadyStart));\n\n const configPath = getResolvedConfigFilePath(ctx.root);\n let devServerRef: Awaited<ReturnType<typeof rsbuild.startDevServer>> | null = null;\n let watcherRef: { close: () => void } | null = null;\n\n const onAddfoxConfigChange = async (): Promise<void> => {\n if (watcherRef) { watcherRef.close(); watcherRef = null; }\n if (devServerRef?.server?.close) await devServerRef.server.close();\n if (configPath) clearConfigCache(configPath);\n process.env.ADDFOX_CONFIG_RESTART = \"1\";\n try {\n await runDev(root, argv);\n } finally {\n delete process.env.ADDFOX_CONFIG_RESTART;\n }\n };\n\n if (configPath) watcherRef = watchAddfoxConfig(configPath, onAddfoxConfigChange);\n const devServerStart = performance.now();\n devServerRef = await rsbuild.startDevServer({ getPortSilently: true });\n const urls = devServerRef?.urls ?? [];\n const mainUrl = urls[0] ?? `http://localhost:${devServerRef?.port ?? \"?\"}`;\n logDoneTimed(\"Dev server \" + mainUrl, Math.round(performance.now() - devServerStart));\n\n const devDistDir = (rsbuild.context as { distPath?: string } | undefined)?.distPath ?? ctx.distPath;\n setTimeout(() => logExtensionSize(devDistDir, ctx.rsbuild), 2500);\n}\n\n/** Build mode: compile + optional zip + auto browser launch. */\nasync function runBuild(root: string, argv: string[]): Promise<void> {\n // Load config first to get defaults\n const { config, baseEntries, entries } = resolveAddfoxConfig(root);\n \n const resolved = resolveOptions(argv, config);\n const options: PipelineOptions = {\n root,\n command: 'build',\n ...resolved,\n config,\n baseEntries,\n entries,\n };\n const rsbuildReadyStart = performance.now();\n const ctx = await runPipeline(options);\n const rsbuild = await createRsbuildInstance(ctx);\n logDoneTimed(\"Rsbuild ready\", Math.round(performance.now() - rsbuildReadyStart));\n\n const buildStart = performance.now();\n const buildResult = await rsbuild.build();\n logDoneTimed(\"Rsbuild build\", Math.round(performance.now() - buildStart));\n setOutputPrefixAddfox();\n\n if (ctx.config.zip !== false) {\n const zipPath = await zipDist(ctx.distPath, ctx.root, ctx.config.outDir, ctx.browser);\n logDone(\"Zipped output to\", zipPath);\n }\n\n const distDir = (rsbuild.context as { distPath?: string } | undefined)?.distPath || ctx.distPath;\n const distSize = getBuildOutputSize(buildResult) ?? getDistSizeSync(distDir);\n if (distSize >= 0) logDoneWithValue(\"Extension size:\", formatBytes(distSize));\n\n // Auto launch browser with loaded extension (unless --no-open)\n if (resolved.open) {\n const browserPathConfig = ctx.config.browserPath ?? {};\n await launchBrowserOnly({\n distPath: distDir,\n browser: resolved.launch,\n cache: resolved.cache,\n chromePath: browserPathConfig.chrome,\n chromiumPath: browserPathConfig.chromium,\n edgePath: browserPathConfig.edge,\n bravePath: browserPathConfig.brave,\n vivaldiPath: browserPathConfig.vivaldi,\n operaPath: browserPathConfig.opera,\n santaPath: browserPathConfig.santa,\n arcPath: browserPathConfig.arc,\n yandexPath: browserPathConfig.yandex,\n browserosPath: browserPathConfig.browseros,\n customPath: browserPathConfig.custom,\n firefoxPath: browserPathConfig.firefox,\n });\n }\n}\n\nasync function main(): Promise<void> {\n const argv = process.argv.slice(2);\n\n if (argv.includes(\"--help\") || argv.includes(\"-h\")) {\n printHelp();\n return;\n }\n\n if (argv.includes(\"--version\") || argv.includes(\"-v\")) {\n console.log(getVersion());\n return;\n }\n\n wrapAddfoxOutput();\n setAddfoxLoggerRawWrites(getRawWrites());\n log(\"Addfox \" + getVersion() + \" with \" + PURPLE + \"Rsbuild \" + getRsbuildVersion(root) + RESET);\n\n const command = argv[0];\n if (command === \"test\") {\n await runTest(root, argv);\n return;\n }\n\n if (!hasConfigFile()) {\n throw new AddfoxError({\n code: ADDFOX_ERROR_CODES.CONFIG_NOT_FOUND,\n message: \"Addfox config file not found\",\n details: `No addfox.config.ts, addfox.config.js or addfox.config.mjs found under ${root}`,\n hint: \"Run the command from project root or create addfox.config.ts / addfox.config.js\",\n });\n }\n\n // Command is determined by runDev/runBuild internally; set env before running\n process.env.NODE_ENV = command === \"dev\" ? \"development\" : \"production\";\n\n if (command === \"dev\") {\n await runDev(root, argv);\n } else {\n await runBuild(root, argv);\n }\n}\n\nmain().catch((e) => {\n error(formatError(e));\n exitWithError(e);\n});\n"],"names":["expandUserPlugins","userPlugins","appRoot","out","list","arr","Array","p","name","vuePlugins","getVueRsbuildPlugins","buildFrameworkPluginList","ctx","useEntry","expanded","useMonitor","entryPlugin","monitorPlugin","extensionPlugin","Pipeline","options","HookManager","CorePipeline","result","resolveAddfoxConfig","browserSubDir","getBrowserOutputDir","resolve","undefined","record","getManifestRecordForTarget","warn","base","userConfig","merged","mergeRsbuildConfig","hmrOverrides","runtimeEnvConfig","buildRuntimeEnvConfig","plugins","scopedProcessEnvPlugin","createScopedProcessEnvPlugin","config","user","hotReload","hotReloadEnabled","hotReloadOpts","isConfigRestart","process","reloadManagerEntries","toReloadManagerEntries","browserPathConfig","hmrOpts","HMR_WS_PORT","useRsbuildClientHmr","devConfig","hmrPlugin","root","outputRoot","reportOption","missing","getMissingPackages","pm","detectFromLockfile","cmd","getAddCommand","AddfoxError","ADDFOX_ERROR_CODES","reportDir","RsdoctorRspackPlugin","tools","existing","pluginOptions","rsdoctorPlugin","getManifestVersionValue","browser","manifestRecord","mv","String","isDev","mode","fileEnv","loadDotEnvByMode","mergedEnv","envPrefixes","getLoadEnvPrefixes","publicEnv","pickPublicEnvVars","backgroundPrivateEnv","pickBackgroundPrivateEnvVars","manifestVersion","importMetaEnv","processEnvForBundle","JSON","env","prefixes","key","value","Object","prefix","publicPrefixes","processEnvBase","privateEnv","api","source","entry","nextEntry","scopedEnvByEntry","buildScopedEnvByEntry","entryName","entryValue","scopedEnv","snippet","buildScopedProcessEnvSnippet","prepend","encodeURIComponent","prependDataModule","entryNames","processEnv","envJson","prependModule","files","file","path","existsSync","parsed","parseDotEnv","readFileSync","content","lines","line","trimmed","eq","rawValue","stripQuotes","quote","runPipeline","pipeline","BROWSER_FLAGS","REPORT_FLAGS","BROWSER_TO_TARGET","VALID_LAUNCH_TARGETS","Set","CliParser","argv","cmdRaw","command","CLI_COMMANDS","launch","unknownBrowser","cache","debug","report","open","i","arg","normalized","b","defaultParser","parseCliArgs","getDistSizeSync","dirPath","stat","statSync","total","readdirSync","s","formatBytes","bytes","isSourceMapEnabled","rsbuildConfig","sm","getBuildOutputSize","stats","json","assets","a","ADDFOX_PREFIX","RSBUILD_PREFIX","WEBEXT_PREFIX","rawStdoutWrite","rawStderrWrite","outputPrefix","setOutputPrefixRsbuild","setOutputPrefixAddfox","getRawWrites","isEncoding","x","createPrefixedWrite","stream","getPrefix","originalWrite","buffer","flushIncomplete","write","chunk","encodingOrCallback","callback","encoding","cb","str","wrapAddfoxOutput","_line","getWebExtStdoutOriginDepth","stdoutWrite","stderrWrite","flush","fOut","fErr","ZIP_OUTPUT_CODE","ZIP_ARCHIVE_CODE","ZIP_LEVEL","zipDist","distPath","outDir","deps","createStream","createWriteStream","archiverFn","archiver","mkdir","mkdirSync","exists","ADDFOX_OUTPUT_ROOT","zipDir","browserSuffix","zipPath","output","archive","Promise","resolvePromise","reject","err","Error","require","createRequire","readPackageVersion","pkgPath","pkg","getVersion","dirname","fileURLToPath","getRsbuildVersion","projectRoot","cliDir","candidates","getPath","hasRstestConfigFile","getResolvedRstestConfigFilePath","isRstestBrowserEnabled","configPath","getRequiredTestPackages","required","getRstestBinPath","binDir","fallback","corePkgPath","coreDir","binInCore","exitWithError","runRstest","restArgs","rstestBin","spawnSync","runTest","installCmd","code","PURPLE","RESET","hasConfigFile","CONFIG_FILES","printHelp","version","console","resolveOptions","createRsbuildInstance","createRsbuild","rsbuild","logExtensionSize","distDir","size","sizeStr","suffix","logDoneWithValue","ADDFOX_CONFIG_DEBOUNCE_MS","watchAddfoxConfig","onRestart","timer","run","clearTimeout","setTimeout","e","error","formatError","watcher","watch","eventType","filename","runDev","baseEntries","entries","resolved","rsbuildReadyStart","performance","logDoneTimed","Math","getResolvedConfigFilePath","devServerRef","watcherRef","onAddfoxConfigChange","clearConfigCache","devServerStart","urls","mainUrl","devDistDir","runBuild","buildStart","buildResult","logDone","distSize","launchBrowserOnly","main","setAddfoxLoggerRawWrites","log"],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * CLI commands
3
+ */
4
+ export { runTest } from "./test.ts";
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/commands/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Run addfox test: ensure rstest config exists, install missing deps, forward to rstest.
3
+ */
4
+ export declare function runTest(projectRoot: string, argv: string[]): Promise<void>;
5
+ //# sourceMappingURL=test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test.d.ts","sourceRoot":"","sources":["../../src/commands/test.ts"],"names":[],"mappings":"AA2EA;;GAEG;AACH,wBAAsB,OAAO,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CA0BhF"}
@@ -0,0 +1,52 @@
1
+ import { HookManager } from '@addfox/common';
2
+ import type { PipelineContext, AddfoxResolvedConfig, EntryInfo, LaunchTarget } from '@addfox/core';
3
+ export interface PipelineOptions {
4
+ root: string;
5
+ command: 'dev' | 'build';
6
+ browser: 'chromium' | 'firefox';
7
+ launch: LaunchTarget;
8
+ cache: boolean;
9
+ report: boolean | Record<string, unknown>;
10
+ /** When true, enable error monitor in dev; CLI --debug overrides config.debug */
11
+ debug?: boolean;
12
+ /** When false, do not auto-open browser. */
13
+ open?: boolean;
14
+ /** Pre-loaded config to avoid double loading */
15
+ config?: AddfoxResolvedConfig;
16
+ baseEntries?: EntryInfo[];
17
+ entries?: EntryInfo[];
18
+ }
19
+ /**
20
+ * CLI-specific pipeline implementation
21
+ */
22
+ export declare class Pipeline {
23
+ private hookManager;
24
+ private corePipeline;
25
+ private options;
26
+ constructor(options: PipelineOptions);
27
+ /**
28
+ * Get the hook manager for registering additional hooks
29
+ */
30
+ get hooks(): HookManager<Record<string, PipelineContext>>;
31
+ /**
32
+ * Execute the build process
33
+ */
34
+ run(): Promise<PipelineContext>;
35
+ /**
36
+ * Register default build hooks
37
+ */
38
+ private registerDefaultHooks;
39
+ private buildRsbuildConfig;
40
+ private buildBaseRsbuildConfig;
41
+ private resolveUserRsbuildConfig;
42
+ private buildHmrOverrides;
43
+ private mergeRsdoctorPlugin;
44
+ }
45
+ export declare function buildRuntimeEnvDefine(config: AddfoxResolvedConfig, browser: 'chromium' | 'firefox', root: string, isDev: boolean): Record<string, string>;
46
+ export declare function getLoadEnvPrefixes(config: AddfoxResolvedConfig): string[];
47
+ export declare function buildScopedEnvByEntry(entryNames: string[], processEnvBase: Record<string, string>, privateEnv: Record<string, string>): Record<string, Record<string, string>>;
48
+ /**
49
+ * Run pipeline with given options
50
+ */
51
+ export declare function runPipeline(options: PipelineOptions): Promise<PipelineContext>;
52
+ //# sourceMappingURL=Pipeline.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Pipeline.d.ts","sourceRoot":"","sources":["../../src/pipeline/Pipeline.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,KAAK,EAAE,eAAe,EAAE,oBAAoB,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAsBnG,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,KAAK,GAAG,OAAO,CAAC;IACzB,OAAO,EAAE,UAAU,GAAG,SAAS,CAAC;IAChC,MAAM,EAAE,YAAY,CAAC;IACrB,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC1C,iFAAiF;IACjF,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,4CAA4C;IAC5C,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,gDAAgD;IAChD,MAAM,CAAC,EAAE,oBAAoB,CAAC;IAC9B,WAAW,CAAC,EAAE,SAAS,EAAE,CAAC;IAC1B,OAAO,CAAC,EAAE,SAAS,EAAE,CAAC;CACvB;AAED;;GAEG;AACH,qBAAa,QAAQ;IACnB,OAAO,CAAC,WAAW,CAA+C;IAClE,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,OAAO,CAAkB;gBAErB,OAAO,EAAE,eAAe;IAOpC;;OAEG;IACH,IAAI,KAAK,IAAI,WAAW,CAAC,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC,CAExD;IAED;;OAEG;IACG,GAAG,IAAI,OAAO,CAAC,eAAe,CAAC;IAIrC;;OAEG;IACH,OAAO,CAAC,oBAAoB;YA6Cd,kBAAkB;IAoBhC,OAAO,CAAC,sBAAsB;YAsBhB,wBAAwB;IAWtC,OAAO,CAAC,iBAAiB;YAyDX,mBAAmB;CAiClC;AASD,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,oBAAoB,EAC5B,OAAO,EAAE,UAAU,GAAG,SAAS,EAC/B,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,OAAO,GACb,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAExB;AA0CD,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,oBAAoB,GAAG,MAAM,EAAE,CAEzE;AA8DD,wBAAgB,qBAAqB,CACnC,UAAU,EAAE,MAAM,EAAE,EACpB,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EACtC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GACjC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAQxC;AAiED;;GAEG;AACH,wBAAsB,WAAW,CAC/B,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,eAAe,CAAC,CAG1B"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Central list of framework Rsbuild plugins. Add or remove plugins here only.
3
+ */
4
+ import type { RsbuildConfig } from "@rsbuild/core";
5
+ import type { PipelineContext } from "@addfox/core";
6
+ type LoosePlugin = RsbuildConfig["plugins"] extends (infer P)[] ? P : never;
7
+ /**
8
+ * Build the framework plugin array for base Rsbuild config.
9
+ * Modifying the pipeline plugin set = edit this function only.
10
+ */
11
+ export declare function buildFrameworkPluginList(ctx: PipelineContext): LoosePlugin[];
12
+ export {};
13
+ //# sourceMappingURL=frameworkPlugins.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frameworkPlugins.d.ts","sourceRoot":"","sources":["../../src/pipeline/frameworkPlugins.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAMpD,KAAK,WAAW,GAAG,aAAa,CAAC,SAAS,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,KAAK,CAAC;AAoB5E;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,eAAe,GAAG,WAAW,EAAE,CAe5E"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Addfox CLI pipeline
3
+ */
4
+ export { Pipeline, runPipeline } from './Pipeline.ts';
5
+ export type { PipelineOptions } from './Pipeline.ts';
6
+ export type { PipelineContext, PipelineStage } from '@addfox/core/pipeline';
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/pipeline/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACtD,YAAY,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAGrD,YAAY,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC"}
@@ -0,0 +1,12 @@
1
+ /** Recursively compute directory size in bytes. */
2
+ export declare function getDistSizeSync(dirPath: string): number;
3
+ export declare function formatBytes(bytes: number): string;
4
+ /** Whether the Rsbuild config has JS source map enabled (any format). */
5
+ export declare function isSourceMapEnabled(rsbuildConfig: {
6
+ output?: {
7
+ sourceMap?: unknown;
8
+ };
9
+ }): boolean;
10
+ /** Get total size of build output from Rsbuild build result (stats.assets). */
11
+ export declare function getBuildOutputSize(result: unknown): number | null;
12
+ //# sourceMappingURL=buildStats.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"buildStats.d.ts","sourceRoot":"","sources":["../../src/utils/buildStats.ts"],"names":[],"mappings":"AAGA,mDAAmD;AACnD,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAUvD;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAIjD;AAED,yEAAyE;AACzE,wBAAgB,kBAAkB,CAChC,aAAa,EAAE;IAAE,MAAM,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,OAAO,CAAA;KAAE,CAAA;CAAE,GAClD,OAAO,CAOT;AAED,+EAA+E;AAC/E,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAqBjE"}
@@ -0,0 +1,24 @@
1
+ import type { AddfoxResolvedConfig } from "@addfox/core";
2
+ import type { PackageManager } from "@addfox/pkg-manager";
3
+ export type { PackageManager };
4
+ /** Exported for tests. */
5
+ export declare function readProjectPackageJson(root: string): {
6
+ dependencies?: Record<string, string>;
7
+ devDependencies?: Record<string, string>;
8
+ } | null;
9
+ /** Exported for tests. Runs package manager install. */
10
+ export declare function runInstall(root: string, pm: PackageManager, packages: string[], dev: boolean): boolean;
11
+ export type RunInstallFn = (root: string, pm: PackageManager, packages: string[], dev: boolean) => boolean;
12
+ export interface EnsureDependenciesOptions {
13
+ silent?: boolean;
14
+ runInstall?: RunInstallFn;
15
+ }
16
+ /**
17
+ * Check that extension dev and plugin deps are installed; install via current package manager if missing.
18
+ * Set ADDFOX_SKIP_DEPS=1 to skip (e.g. CI or user-managed deps).
19
+ * Tests can pass runInstall to avoid real spawn.
20
+ */
21
+ export declare function ensureDependencies(root: string, config: AddfoxResolvedConfig, options?: EnsureDependenciesOptions): Promise<{
22
+ installed: string[];
23
+ }>;
24
+ //# sourceMappingURL=ensureDeps.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ensureDeps.d.ts","sourceRoot":"","sources":["../../src/utils/ensureDeps.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAGzD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE1D,YAAY,EAAE,cAAc,EAAE,CAAC;AAU/B,0BAA0B;AAC1B,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAAC,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,GAAG,IAAI,CAS/I;AAoCD,wDAAwD;AACxD,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,OAAO,GAAG,OAAO,CAmBtG;AAED,MAAM,MAAM,YAAY,GAAG,CACzB,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,cAAc,EAClB,QAAQ,EAAE,MAAM,EAAE,EAClB,GAAG,EAAE,OAAO,KACT,OAAO,CAAC;AAEb,MAAM,WAAW,yBAAyB;IACxC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,UAAU,CAAC,EAAE,YAAY,CAAC;CAC3B;AAED;;;;GAIG;AACH,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,oBAAoB,EAC5B,OAAO,CAAC,EAAE,yBAAyB,GAClC,OAAO,CAAC;IAAE,SAAS,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CAgBlC"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * CLI utilities
3
+ */
4
+ export { getDistSizeSync, getBuildOutputSize, formatBytes, isSourceMapEnabled, } from "./buildStats.ts";
5
+ export { ensureDependencies, readProjectPackageJson, runInstall, } from "./ensureDeps.ts";
6
+ export type { PackageManager, RunInstallFn, EnsureDependenciesOptions, } from "./ensureDeps.ts";
7
+ export { wrapAddfoxOutput, setOutputPrefixRsbuild, setOutputPrefixAddfox, getRawWrites, createPrefixedWrite, ADDFOX_PREFIX, } from "./prefixStream.ts";
8
+ export { zipDist } from "./zipDist.ts";
9
+ export type { ZipDistDeps } from "./zipDist.ts";
10
+ export { getVersion, getRsbuildVersion, } from "./version.ts";
11
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACL,eAAe,EACf,kBAAkB,EAClB,WAAW,EACX,kBAAkB,GACnB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EACL,kBAAkB,EAClB,sBAAsB,EACtB,UAAU,GACX,MAAM,iBAAiB,CAAC;AAEzB,YAAY,EACV,cAAc,EACd,YAAY,EACZ,yBAAyB,GAC1B,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EACL,gBAAgB,EAChB,sBAAsB,EACtB,qBAAqB,EACrB,YAAY,EACZ,mBAAmB,EACnB,aAAa,GACd,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,YAAY,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEhD,OAAO,EACL,UAAU,EACV,iBAAiB,GAClB,MAAM,cAAc,CAAC"}
@@ -0,0 +1,24 @@
1
+ /** ANSI: orange (256 color 208), then reset. Exported for tests. */
2
+ export declare const ADDFOX_PREFIX = "\u001B[38;5;208m[Addfox]\u001B[0m ";
3
+ /**
4
+ * Use [Rsbuild] prefix for subsequent stdout/stderr lines (e.g. before createRsbuild / startDevServer).
5
+ * Call setOutputPrefixAddfox() after build() to restore [Addfox] for non-rsbuild output.
6
+ */
7
+ export declare function setOutputPrefixRsbuild(): void;
8
+ /**
9
+ * Use [Addfox] prefix for subsequent stdout/stderr lines. Call after rsbuild.build() when only addfox will write.
10
+ */
11
+ export declare function setOutputPrefixAddfox(): void;
12
+ /** Return raw stream writes (before wrap) for the shared logger so output has a single prefix. */
13
+ export declare function getRawWrites(): {
14
+ stdout: NodeJS.WriteStream["write"];
15
+ stderr: NodeJS.WriteStream["write"];
16
+ };
17
+ /** Exported for tests. */
18
+ export declare function createPrefixedWrite(stream: NodeJS.WriteStream, getPrefix: (line: string) => string): NodeJS.WriteStream["write"];
19
+ /**
20
+ * Wraps process.stdout and process.stderr so each line is prefixed with colored "[Addfox]" or "[Rsbuild]".
21
+ * Call before running rsbuild dev/build. Use setOutputPrefixRsbuild() before rsbuild, setOutputPrefixAddfox() after build.
22
+ */
23
+ export declare function wrapAddfoxOutput(): void;
24
+ //# sourceMappingURL=prefixStream.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prefixStream.d.ts","sourceRoot":"","sources":["../../src/utils/prefixStream.ts"],"names":[],"mappings":"AAEA,oEAAoE;AACpE,eAAO,MAAM,aAAa,uCAAmC,CAAC;AAY9D;;;GAGG;AACH,wBAAgB,sBAAsB,IAAI,IAAI,CAE7C;AAED;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,IAAI,CAE5C;AAED,kGAAkG;AAClG,wBAAgB,YAAY,IAAI;IAC9B,MAAM,EAAE,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;IACpC,MAAM,EAAE,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;CACrC,CAKA;AASD,0BAA0B;AAC1B,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,MAAM,CAAC,WAAW,EAC1B,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAClC,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,CAiC7B;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,IAAI,IAAI,CAwBvC"}
@@ -0,0 +1,5 @@
1
+ /** Get addfox CLI package version. */
2
+ export declare function getVersion(): string;
3
+ /** Get @rsbuild/core version from project or monorepo. */
4
+ export declare function getRsbuildVersion(projectRoot: string): string;
5
+ //# sourceMappingURL=version.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../../src/utils/version.ts"],"names":[],"mappings":"AAgBA,sCAAsC;AACtC,wBAAgB,UAAU,IAAI,MAAM,CAWnC;AAED,0DAA0D;AAC1D,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CA8B7D"}
@@ -0,0 +1,17 @@
1
+ import { createWriteStream, mkdirSync, existsSync } from "fs";
2
+ import archiver from "archiver";
3
+ import { type BrowserTarget } from "@addfox/core";
4
+ /** Optional for tests: inject stream/archiver to trigger error paths */
5
+ export type ZipDistDeps = {
6
+ createWriteStream?: typeof createWriteStream;
7
+ archiver?: typeof archiver;
8
+ mkdirSync?: typeof mkdirSync;
9
+ existsSync?: typeof existsSync;
10
+ };
11
+ /**
12
+ * Packs the built output directory into a zip file.
13
+ * Output: root/.addfox/<outDir>/<outDir>-<browser>.zip (browser-specific zip inside .addfox/<outDir>).
14
+ * Zip contents are the files inside distPath (no extra top-level folder).
15
+ */
16
+ export declare function zipDist(distPath: string, root: string, outDir: string, browser?: BrowserTarget, deps?: ZipDistDeps): Promise<string>;
17
+ //# sourceMappingURL=zipDist.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"zipDist.d.ts","sourceRoot":"","sources":["../../src/utils/zipDist.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAE9D,OAAO,QAAQ,MAAM,UAAU,CAAC;AAGhC,OAAO,EAAsB,KAAK,aAAa,EAAuB,MAAM,cAAc,CAAC;AAS3F,wEAAwE;AACxE,MAAM,MAAM,WAAW,GAAG;IACxB,iBAAiB,CAAC,EAAE,OAAO,iBAAiB,CAAC;IAC7C,QAAQ,CAAC,EAAE,OAAO,QAAQ,CAAC;IAC3B,SAAS,CAAC,EAAE,OAAO,SAAS,CAAC;IAC7B,UAAU,CAAC,EAAE,OAAO,UAAU,CAAC;CAChC,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,OAAO,CACrB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,aAAa,EACvB,IAAI,CAAC,EAAE,WAAW,GACjB,OAAO,CAAC,MAAM,CAAC,CAyCjB"}
package/package.json ADDED
@@ -0,0 +1,41 @@
1
+ {
2
+ "name": "@addfox/cli",
3
+ "version": "0.1.1-beta.2",
4
+ "description": "addfox CLI: addfox dev / build, parses argv and drives Rsbuild",
5
+ "type": "module",
6
+ "bin": {
7
+ "addfox": "./dist/cli.js"
8
+ },
9
+ "files": [
10
+ "dist"
11
+ ],
12
+ "dependencies": {
13
+ "@rsbuild/core": "^1.7.3",
14
+ "archiver": "^7.0.0",
15
+ "@addfox/common": "0.1.1-beta.2",
16
+ "@addfox/rsbuild-plugin-extension-entry": "0.1.1-beta.2",
17
+ "@addfox/rsbuild-plugin-extension-manifest": "0.1.1-beta.2",
18
+ "@addfox/pkg-manager": "0.1.1-beta.2",
19
+ "@addfox/core": "0.1.1-beta.2",
20
+ "@addfox/rsbuild-plugin-extension-hmr": "0.1.1-beta.2",
21
+ "@addfox/rsbuild-plugin-vue": "0.1.1-beta.2",
22
+ "@addfox/rsbuild-plugin-extension-monitor": "0.1.1-beta.2"
23
+ },
24
+ "devDependencies": {
25
+ "@rslib/core": "^0.20.0",
26
+ "@rstest/core": "^0.9.2",
27
+ "@rstest/coverage-istanbul": "^0.3.0",
28
+ "@types/archiver": "^6.0.0",
29
+ "@types/node": "^20.0.0",
30
+ "typescript": "^5.0.0"
31
+ },
32
+ "peerDependencies": {
33
+ "@rsbuild/core": ">=1.0.0"
34
+ },
35
+ "scripts": {
36
+ "build": "rslib build",
37
+ "dev": "rslib build --watch",
38
+ "test": "rstest run",
39
+ "test:coverage": "rstest run --coverage"
40
+ }
41
+ }