@robot-admin/git-standards 1.0.0 → 1.0.1

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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/cli/init.ts","../../src/utils/package-manager.ts","../../src/utils/git.ts","../../src/utils/file.ts","../../src/configs/lint-staged.ts"],"sourcesContent":["/*\r\n * @Author: ChenYu ycyplus@gmail.com\r\n * @Date: 2026-02-13\r\n * @Description: Init 命令 - 模块化初始化 Git 标准化配置(预设 + 自定义)\r\n * Copyright (c) 2026 by CHENY, All Rights Reserved.\r\n */\r\n\r\nimport { resolve } from \"node:path\";\r\nimport { unlinkSync, existsSync, rmSync } from \"node:fs\";\r\nimport chalk from \"chalk\";\r\nimport ora from \"ora\";\r\nimport { execa } from \"execa\";\r\nimport {\r\n detectPackageManager,\r\n getInstallCommand,\r\n getExecCommand,\r\n getPackageManagerName,\r\n} from \"../utils/package-manager\";\r\nimport { isGitRepository, initGitRepository } from \"../utils/git\";\r\nimport {\r\n writeFileContent,\r\n updatePackageJson,\r\n readJsonFile,\r\n} from \"../utils/file\";\r\nimport { generateLintStagedConfig } from \"../configs/lint-staged\";\r\n\r\n// ─── 品牌 & 符号系统 ──────────────────────────────────────────────\r\nconst BRAND = \"#7C3AED\";\r\nconst S = {\r\n LOGO: chalk.hex(BRAND).bold(\"[RS]\"),\r\n OK: chalk.green(\"✔\"),\r\n FAIL: chalk.red(\"✖\"),\r\n WARN: chalk.yellow(\"▲\"),\r\n STEP: chalk.hex(BRAND)(\"◆\"),\r\n ARROW: chalk.cyan(\"▸\"),\r\n DOT: chalk.gray(\"●\"),\r\n INFO: chalk.blue(\"ℹ\"),\r\n LINE: chalk.gray(\"─\".repeat(48)),\r\n};\r\n\r\n// ─── 类型定义 ──────────────────────────────────────────────────────\r\ntype PresetId = \"minimal\" | \"standard\" | \"full\" | \"custom\";\r\n\r\n/**\r\n * 功能开关集合\r\n * - commitizen / commitlint / husky 为核心功能,始终包含\r\n * - 以下为可选附加功能\r\n */\r\nexport interface FeatureSet {\r\n eslint: boolean;\r\n lintStaged: boolean;\r\n prettier: boolean;\r\n oxlint: boolean;\r\n editorconfig: boolean;\r\n}\r\n\r\nexport interface ESLintOptions {\r\n framework: \"vue\" | \"react\" | \"vanilla\";\r\n typescript: boolean;\r\n jsdoc: boolean;\r\n}\r\n\r\nexport interface InitOptions {\r\n cwd?: string;\r\n ci?: boolean;\r\n preset?: PresetId;\r\n framework?: \"vue\" | \"react\" | \"vanilla\";\r\n typescript?: boolean;\r\n oxlint?: boolean;\r\n jsdoc?: boolean;\r\n prettier?: boolean;\r\n}\r\n\r\n// ─── 预设模式定义 ──────────────────────────────────────────────────\r\nconst PRESETS: Record<\r\n Exclude<PresetId, \"custom\">,\r\n { name: string; desc: string; features: FeatureSet }\r\n> = {\r\n minimal: {\r\n name: \"极简模式\",\r\n desc: \"仅 Git 提交规范 (Commitizen + Commitlint)\",\r\n features: {\r\n eslint: false,\r\n lintStaged: false,\r\n prettier: false,\r\n oxlint: false,\r\n editorconfig: false,\r\n },\r\n },\r\n standard: {\r\n name: \"标准模式\",\r\n desc: \"提交规范 + 代码质量检查 (+ ESLint + lint-staged)\",\r\n features: {\r\n eslint: true,\r\n lintStaged: true,\r\n prettier: false,\r\n oxlint: false,\r\n editorconfig: true,\r\n },\r\n },\r\n full: {\r\n name: \"完整模式\",\r\n desc: \"全部工具链 (+ Prettier + Oxlint + EditorConfig)\",\r\n features: {\r\n eslint: true,\r\n lintStaged: true,\r\n prettier: true,\r\n oxlint: true,\r\n editorconfig: true,\r\n },\r\n },\r\n};\r\n\r\n// ─── 主函数 ──────────────────────────────────────────────────────\r\nexport async function init(options: InitOptions = {}) {\r\n const cwd = options.cwd || process.cwd();\r\n\r\n // ── Banner ──\r\n printBanner();\r\n\r\n // 1. 环境检测\r\n console.log(` ${S.STEP} ${chalk.bold(\"环境检测\")}`);\r\n console.log();\r\n\r\n if (!isGitRepository(cwd)) {\r\n const spinner = ora({\r\n text: chalk.gray(\"初始化 Git 仓库...\"),\r\n prefixText: \" \",\r\n spinner: \"dots\",\r\n }).start();\r\n await initGitRepository(cwd);\r\n spinner.succeed(chalk.white(\"Git 仓库初始化完成\"));\r\n } else {\r\n console.log(` ${S.OK} Git 仓库已就绪`);\r\n }\r\n\r\n const pm = await detectPackageManager(cwd);\r\n const pmName = getPackageManagerName(pm);\r\n console.log(` ${S.OK} 包管理器: ${chalk.cyan.bold(pmName)}`);\r\n console.log();\r\n\r\n // 2. 功能选择(交互式 or CI)\r\n let features: FeatureSet;\r\n let eslintOpts: ESLintOptions = {\r\n framework: \"vue\",\r\n typescript: true,\r\n jsdoc: false,\r\n };\r\n\r\n if (options.ci) {\r\n // ── CI 模式 ──\r\n const presetId: PresetId = options.preset || \"standard\";\r\n if (presetId === \"custom\") {\r\n features = {\r\n eslint: true,\r\n lintStaged: true,\r\n prettier: options.prettier ?? true,\r\n oxlint: options.oxlint ?? true,\r\n editorconfig: true,\r\n };\r\n } else {\r\n features = { ...PRESETS[presetId].features };\r\n }\r\n // CLI flag 覆盖\r\n if (options.prettier !== undefined) features.prettier = options.prettier;\r\n if (options.oxlint !== undefined) features.oxlint = options.oxlint;\r\n const jsdocDefault = presetId === \"full\" ? true : false;\r\n eslintOpts = {\r\n framework: options.framework || \"vue\",\r\n typescript: options.typescript ?? true,\r\n jsdoc: options.jsdoc ?? jsdocDefault,\r\n };\r\n console.log(\r\n ` ${S.INFO} ${chalk.gray(\"CI 模式\")} ${chalk.white(\r\n \"预设:\",\r\n )} ${chalk.cyan(presetId)}`,\r\n );\r\n console.log();\r\n } else {\r\n // ── 交互式模式 ──\r\n const result = await interactiveSetup(options);\r\n features = result.features;\r\n eslintOpts = result.eslintOpts;\r\n }\r\n\r\n // 3. 配置摘要 & 确认\r\n printSummary(features, eslintOpts, pmName);\r\n\r\n if (!options.ci) {\r\n const { confirm } = await import(\"@inquirer/prompts\");\r\n const proceed = await confirm({\r\n message: chalk.white(\"确认以上配置并开始安装?\"),\r\n default: true,\r\n theme: { prefix: ` ${S.ARROW}` },\r\n });\r\n if (!proceed) {\r\n console.log();\r\n console.log(` ${S.INFO} ${chalk.gray(\"重新选择配置...\")}`);\r\n console.log();\r\n const result = await interactiveSetup(options);\r\n features = result.features;\r\n eslintOpts = result.eslintOpts;\r\n printSummary(features, eslintOpts, pmName);\r\n // 递归确认后直接继续\r\n }\r\n }\r\n\r\n console.log();\r\n\r\n // 4. 执行安装流程\r\n await installDependencies(cwd, pm, features, eslintOpts);\r\n await generateConfigFiles(cwd, features, eslintOpts);\r\n await setupHusky(cwd, pm, features);\r\n await addPackageScripts(cwd, pm, features);\r\n\r\n // 5. 完成\r\n printCompletion(pm, features);\r\n}\r\n\r\n// ─── Banner ──────────────────────────────────────────────────────\r\nfunction printBanner() {\r\n console.log();\r\n console.log(S.LINE);\r\n console.log(\r\n ` ${S.LOGO} ${chalk.bold(\"Robot Standards\")} ${chalk.gray(\"v1.0.0\")}`,\r\n );\r\n console.log(` ${chalk.gray(\"零配置 · 模块化 · Git 工程化标准工具包\")}`);\r\n console.log(S.LINE);\r\n console.log();\r\n}\r\n\r\n// ─── 交互式选择 ─────────────────────────────────────────────────\r\nconst BACK_SIGNAL = Symbol(\"back\");\r\n\r\nasync function interactiveSetup(\r\n options: InitOptions,\r\n): Promise<{ features: FeatureSet; eslintOpts: ESLintOptions }> {\r\n const { select, checkbox, confirm } = await import(\"@inquirer/prompts\");\r\n\r\n // 外层循环:支持从后续步骤返回重选\r\n // eslint-disable-next-line no-constant-condition\r\n while (true) {\r\n // ── Step 1: 预设选择 ──\r\n console.log(` ${S.STEP} ${chalk.bold(\"选择模式\")}`);\r\n console.log();\r\n\r\n const presetId = await select<PresetId>({\r\n message: chalk.white(\"选择预设方案\"),\r\n choices: [\r\n {\r\n name: `极简模式 ${chalk.gray(\r\n \"── 仅提交规范 (Commitizen + Commitlint)\",\r\n )}`,\r\n value: \"minimal\" as PresetId,\r\n description: chalk.gray(\"适合只需规范提交信息的项目\"),\r\n },\r\n {\r\n name: `标准模式 ${chalk.gray(\"── 提交规范 + 代码检查 (+ ESLint)\")}`,\r\n value: \"standard\" as PresetId,\r\n description: chalk.gray(\"适合大多数项目\"),\r\n },\r\n {\r\n name: `完整模式 ${chalk.gray(\r\n \"── 全部工具链 (+ Prettier + Oxlint)\",\r\n )} ${chalk.hex(BRAND)(\"主项目(Robot_Admin)\")}`,\r\n value: \"full\" as PresetId,\r\n description: chalk.gray(\"全面代码质量管控\"),\r\n },\r\n {\r\n name: `自定义 ${chalk.gray(\"── 自由组合需要的工具链\")}`,\r\n value: \"custom\" as PresetId,\r\n description: chalk.gray(\"精确控制每个功能模块\"),\r\n },\r\n ],\r\n default: \"standard\" as PresetId,\r\n theme: { prefix: ` ${S.ARROW}` },\r\n });\r\n\r\n let features: FeatureSet;\r\n\r\n if (presetId === \"custom\") {\r\n // ── Step 2: 自定义功能选择 ──\r\n console.log();\r\n console.log(\r\n ` ${S.STEP} ${chalk.bold(\"选择功能\")} ${chalk.gray(\r\n \"(Git 提交规范默认包含)\",\r\n )}`,\r\n );\r\n console.log();\r\n\r\n type FeatureChoice =\r\n | \"eslint\"\r\n | \"lintStaged\"\r\n | \"prettier\"\r\n | \"oxlint\"\r\n | \"editorconfig\"\r\n | \"__back__\";\r\n\r\n const selected = await checkbox<FeatureChoice>({\r\n message: chalk.white(\"选择附加功能 (空格切换, 回车确认)\"),\r\n choices: [\r\n {\r\n name: `ESLint ${chalk.gray(\"代码质量检查\")}`,\r\n value: \"eslint\" as FeatureChoice,\r\n },\r\n {\r\n name: `lint-staged ${chalk.gray(\"暂存区增量检查\")}`,\r\n value: \"lintStaged\" as FeatureChoice,\r\n },\r\n {\r\n name: `Prettier ${chalk.gray(\"代码自动格式化\")}`,\r\n value: \"prettier\" as FeatureChoice,\r\n },\r\n {\r\n name: `Oxlint ${chalk.gray(\r\n \"高性能 Lint 引擎 (50x faster)\",\r\n )}`,\r\n value: \"oxlint\" as FeatureChoice,\r\n },\r\n {\r\n name: `EditorConfig ${chalk.gray(\"编辑器统一配置\")}`,\r\n value: \"editorconfig\" as FeatureChoice,\r\n },\r\n {\r\n name: chalk.yellow(\"↩ 返回上一步\"),\r\n value: \"__back__\" as FeatureChoice,\r\n },\r\n ],\r\n theme: { prefix: ` ${S.ARROW}` },\r\n });\r\n\r\n if (selected.includes(\"__back__\")) continue;\r\n\r\n features = {\r\n eslint: selected.includes(\"eslint\"),\r\n lintStaged: selected.includes(\"lintStaged\"),\r\n prettier: selected.includes(\"prettier\"),\r\n oxlint: selected.includes(\"oxlint\"),\r\n editorconfig: selected.includes(\"editorconfig\"),\r\n };\r\n\r\n // ── 依赖关系自动修正 ──\r\n if (features.oxlint && !features.eslint) {\r\n console.log(\r\n `\\n ${S.INFO} ${chalk.gray(\r\n \"Oxlint 需要 ESLint 配合,已自动启用 ESLint\",\r\n )}`,\r\n );\r\n features.eslint = true;\r\n }\r\n if (features.lintStaged && !features.eslint && !features.prettier) {\r\n console.log(\r\n `\\n ${S.INFO} ${chalk.gray(\r\n \"lint-staged 需要 ESLint 或 Prettier,已自动启用 ESLint\",\r\n )}`,\r\n );\r\n features.eslint = true;\r\n }\r\n } else {\r\n features = { ...PRESETS[presetId].features };\r\n }\r\n\r\n // ── Step 3: ESLint 子配置(仅当 ESLint 启用时显示)──\r\n let eslintOpts: ESLintOptions = {\r\n framework: \"vue\",\r\n typescript: true,\r\n jsdoc: false,\r\n };\r\n\r\n if (features.eslint) {\r\n console.log();\r\n console.log(` ${S.STEP} ${chalk.bold(\"ESLint 配置\")}`);\r\n console.log();\r\n\r\n const framework = await select({\r\n message: chalk.white(\"项目框架\"),\r\n choices: [\r\n {\r\n name: \"Vue 3\",\r\n value: \"vue\" as const,\r\n },\r\n { name: \"React\", value: \"react\" as const },\r\n { name: \"Vanilla JS / TS\", value: \"vanilla\" as const },\r\n {\r\n name: chalk.yellow(\"↩ 返回上一步\"),\r\n value: \"__back__\" as const,\r\n },\r\n ],\r\n default: options.framework || \"vue\",\r\n theme: { prefix: ` ${S.ARROW}` },\r\n });\r\n\r\n if (framework === \"__back__\") continue;\r\n\r\n const typescript = await confirm({\r\n message: chalk.white(\"使用 TypeScript\"),\r\n default: options.typescript ?? true,\r\n theme: { prefix: ` ${S.ARROW}` },\r\n });\r\n\r\n const jsdoc = await confirm({\r\n message: chalk.white(\"强制 JSDoc 注释\"),\r\n default: options.jsdoc ?? true,\r\n theme: { prefix: ` ${S.ARROW}` },\r\n });\r\n\r\n eslintOpts = { framework, typescript, jsdoc };\r\n }\r\n\r\n return { features, eslintOpts };\r\n } // end while\r\n}\r\n\r\n// ─── 配置摘要 ────────────────────────────────────────────────────\r\nfunction printSummary(\r\n features: FeatureSet,\r\n eslintOpts: ESLintOptions,\r\n pmName: string,\r\n) {\r\n console.log();\r\n console.log(` ${S.STEP} ${chalk.bold(\"配置摘要\")}`);\r\n console.log();\r\n\r\n // 核心模块(始终包含)\r\n console.log(\r\n ` ${S.OK} ${chalk.white(\"核心\")} Commitizen + Commitlint + Husky`,\r\n );\r\n\r\n if (features.eslint) {\r\n const fw =\r\n eslintOpts.framework === \"vue\"\r\n ? \"Vue 3\"\r\n : eslintOpts.framework === \"react\"\r\n ? \"React\"\r\n : \"Vanilla\";\r\n const ts = eslintOpts.typescript ? \" + TS\" : \"\";\r\n const jsdoc = eslintOpts.jsdoc ? \" + JSDoc\" : \"\";\r\n console.log(\r\n ` ${S.OK} ${chalk.white(\"检查\")} ESLint (${fw}${ts}${jsdoc})`,\r\n );\r\n }\r\n if (features.lintStaged) {\r\n console.log(` ${S.OK} ${chalk.white(\"暂存\")} lint-staged`);\r\n }\r\n if (features.oxlint) {\r\n console.log(\r\n ` ${S.OK} ${chalk.white(\"加速\")} Oxlint ${chalk.gray(\"(50x faster)\")}`,\r\n );\r\n }\r\n if (features.prettier) {\r\n console.log(` ${S.OK} ${chalk.white(\"格式\")} Prettier`);\r\n }\r\n if (features.editorconfig) {\r\n console.log(` ${S.OK} ${chalk.white(\"编辑\")} EditorConfig`);\r\n }\r\n console.log(` ${S.DOT} ${chalk.gray(\"管理\")} ${pmName}`);\r\n console.log();\r\n}\r\n\r\n// ─── 安装依赖 ────────────────────────────────────────────────────\r\nasync function installDependencies(\r\n cwd: string,\r\n pm: string,\r\n features: FeatureSet,\r\n eslintOpts: ESLintOptions,\r\n) {\r\n const spinner = ora({\r\n text: chalk.gray(\"分析依赖...\"),\r\n prefixText: \" \",\r\n spinner: \"dots\",\r\n }).start();\r\n\r\n // ── 核心依赖(始终安装) ──\r\n const deps: string[] = [\r\n \"@commitlint/cli\",\r\n \"@commitlint/config-conventional\",\r\n \"commitizen\",\r\n \"cz-customizable\",\r\n \"husky\",\r\n ];\r\n\r\n // ── ESLint ──\r\n if (features.eslint) {\r\n deps.push(\"eslint\");\r\n if (eslintOpts.framework === \"vue\") {\r\n deps.push(\"eslint-plugin-vue\", \"@vue/eslint-config-typescript\");\r\n }\r\n if (eslintOpts.typescript) {\r\n deps.push(\r\n \"@typescript-eslint/eslint-plugin\",\r\n \"@typescript-eslint/parser\",\r\n );\r\n }\r\n if (eslintOpts.jsdoc) {\r\n deps.push(\"eslint-plugin-jsdoc\");\r\n }\r\n }\r\n\r\n // ── lint-staged ──\r\n if (features.lintStaged) {\r\n deps.push(\"lint-staged\");\r\n }\r\n\r\n // ── Oxlint ──\r\n if (features.oxlint) {\r\n deps.push(\"oxlint\", \"eslint-plugin-oxlint\");\r\n }\r\n\r\n // ── Prettier ──\r\n if (features.prettier) {\r\n deps.push(\"prettier\");\r\n if (features.eslint && eslintOpts.framework === \"vue\") {\r\n deps.push(\"@vue/eslint-config-prettier\");\r\n }\r\n }\r\n\r\n spinner.text = chalk.gray(`安装 ${deps.length} 个依赖...`);\r\n\r\n try {\r\n const installCmd = getInstallCommand(pm as any);\r\n await execa(\r\n installCmd.split(\" \")[0],\r\n [...installCmd.split(\" \").slice(1), ...deps],\r\n { cwd, stdio: \"pipe\" },\r\n );\r\n spinner.succeed(\r\n chalk.white(\"依赖安装完成 \") + chalk.gray(`(${deps.length} packages)`),\r\n );\r\n } catch (error) {\r\n spinner.fail(chalk.red(\"依赖安装失败\"));\r\n throw error;\r\n }\r\n}\r\n\r\n// ─── 生成配置文件 ────────────────────────────────────────────────\r\nasync function generateConfigFiles(\r\n cwd: string,\r\n features: FeatureSet,\r\n eslintOpts: ESLintOptions,\r\n) {\r\n const spinner = ora({\r\n text: chalk.gray(\"生成配置文件...\"),\r\n prefixText: \" \",\r\n spinner: \"dots\",\r\n }).start();\r\n\r\n const generated: string[] = [];\r\n\r\n try {\r\n // ── .cz-config.js(始终生成)──\r\n const czConfig = `/*\r\n * Commitizen 自定义配置 (cz-customizable)\r\n * @generated by @robot-admin/git-standards\r\n *\r\n * 直接修改此文件即可自定义提交规范\r\n */\r\nmodule.exports = {\r\n scopes: [],\r\n allowEmptyScopes: false,\r\n allowCustomScopes: true,\r\n\r\n types: [\r\n { value: 'wip', name: 'wip: 🚧 开发中' },\r\n { value: 'feat', name: 'feat: 🎯 新功能' },\r\n { value: 'fix', name: 'fix: 🐛 Bug 修复' },\r\n { value: 'perf', name: 'perf: ⚡️ 性能优化' },\r\n { value: 'deps', name: 'deps: 📦 依赖更新' },\r\n { value: 'refactor', name: 'refactor: ♻️ 重构' },\r\n { value: 'docs', name: 'docs: 📚 文档变更' },\r\n { value: 'test', name: 'test: 🔎 测试相关' },\r\n { value: 'style', name: 'style: 💄 代码样式' },\r\n { value: 'build', name: 'build: 🧳 构建/打包' },\r\n { value: 'chore', name: 'chore: 🔧 其他杂项' },\r\n { value: 'revert', name: 'revert: 🔙 回退' },\r\n ],\r\n\r\n messages: {\r\n type: '请选择提交类型:',\r\n customScope: '请输入修改范围(必填,格式如:模块/子模块):',\r\n subject: '请简要描述提交(必填,不加句号):',\r\n body: '请输入更详细的说明(可选):\\\\n',\r\n footer: 'Footer(可选): 例如 \"Closes #123\" 或 \"Release-As: 1.3.1\"\\\\n',\r\n confirmCommit: '确认提交以上内容?(y/n/e/h)',\r\n },\r\n\r\n skipQuestions: ['body'],\r\n\r\n allowBreakingChanges: ['feat', 'fix', 'refactor'],\r\n breakingPrefix: 'BREAKING CHANGE:',\r\n\r\n subjectLimit: 88,\r\n}\r\n`;\r\n await writeFileContent(resolve(cwd, \".cz-config.js\"), czConfig);\r\n generated.push(\".cz-config.js\");\r\n\r\n // ── commitlint.config.js(始终生成)──\r\n const commitlintConfig = `/*\r\n * Commitlint 配置\r\n * @generated by @robot-admin/git-standards\r\n *\r\n * 直接修改此文件即可自定义提交校验规则\r\n */\r\nmodule.exports = {\r\n extends: ['@commitlint/config-conventional'],\r\n rules: {\r\n 'type-enum': [\r\n 2,\r\n 'always',\r\n [\r\n 'wip', 'feat', 'fix', 'docs', 'style', 'refactor',\r\n 'perf', 'test', 'chore', 'revert', 'build', 'deps',\r\n ],\r\n ],\r\n 'subject-case': [0],\r\n },\r\n}\r\n`;\r\n await writeFileContent(\r\n resolve(cwd, \"commitlint.config.js\"),\r\n commitlintConfig,\r\n );\r\n generated.push(\"commitlint.config.js\");\r\n\r\n // ── .prettierrc.js(仅当 prettier 启用)──\r\n if (features.prettier) {\r\n const prettierConfig = `/*\r\n * Prettier 配置\r\n * @generated by @robot-admin/git-standards\r\n *\r\n * 直接修改此文件即可自定义格式化规则\r\n */\r\nmodule.exports = {\r\n $schema: 'https://json.schemastore.org/prettierrc',\r\n semi: false,\r\n singleQuote: true,\r\n printWidth: 80,\r\n tabWidth: 2,\r\n quoteProps: 'as-needed',\r\n trailingComma: 'es5',\r\n bracketSpacing: true,\r\n jsxSingleQuote: true,\r\n arrowParens: 'avoid',\r\n endOfLine: 'auto',\r\n htmlWhitespaceSensitivity: 'strict',\r\n vueIndentScriptAndStyle: true,\r\n singleAttributePerLine: true,\r\n}\r\n`;\r\n await writeFileContent(resolve(cwd, \".prettierrc.js\"), prettierConfig);\r\n generated.push(\".prettierrc.js\");\r\n }\r\n\r\n // ── eslint.config.ts(仅当 eslint 启用)──\r\n if (features.eslint) {\r\n // 根据选项动态构建完整的 eslint 配置模板\r\n const hasOxlint = features.oxlint;\r\n const hasPrettier = features.prettier;\r\n const hasJsdoc = eslintOpts.jsdoc;\r\n const isVue = eslintOpts.framework === \"vue\";\r\n const isTs = eslintOpts.typescript;\r\n\r\n // ── imports ──\r\n const importLines: string[] = [];\r\n if (isVue) importLines.push(\"import pluginVue from 'eslint-plugin-vue'\");\r\n if (isVue && isTs) {\r\n importLines.push(\r\n \"import {\\n defineConfigWithVueTs,\\n vueTsConfigs,\\n} from '@vue/eslint-config-typescript'\",\r\n );\r\n }\r\n if (hasOxlint)\r\n importLines.push(\"import oxlint from 'eslint-plugin-oxlint'\");\r\n if (hasPrettier && isVue) {\r\n importLines.push(\r\n \"import skipFormatting from '@vue/eslint-config-prettier/skip-formatting'\",\r\n );\r\n }\r\n if (hasJsdoc)\r\n importLines.push(\"import jsdocPlugin from 'eslint-plugin-jsdoc'\");\r\n\r\n // ── 文件扩展名 ──\r\n const fileExts = isTs ? \"js,ts,mts,tsx,vue\" : \"js,jsx,vue\";\r\n\r\n // ── Vue 2 废弃规则 ──\r\n const vue2DeprecationRules = isVue\r\n ? `\r\n //! 主动禁止 Vue 2 写法\r\n 'vue/no-deprecated-props-default-this': 'error',\r\n 'vue/no-deprecated-events-api': 'error',\r\n 'vue/no-deprecated-filter': 'error',\r\n 'vue/no-deprecated-functional-template': 'error',\r\n`\r\n : \"\";\r\n\r\n // ── Vue 组件规则 ──\r\n const vueComponentRules = isVue\r\n ? `\r\n // Vue 规范\r\n //! PascalCase 命名规范\r\n 'vue/component-name-in-template-casing': [\r\n 'error',\r\n 'PascalCase',\r\n {\r\n registeredComponentsOnly: false,\r\n ignores: [\r\n 'router-view',\r\n 'router-link',\r\n 'transition',\r\n 'draggable',\r\n '/^icon-/i',\r\n '/^C_/',\r\n '/^c_/',\r\n 'v-md-editor',\r\n ],\r\n },\r\n ],\r\n 'vue/multi-word-component-names': [\r\n 'error',\r\n {\r\n ignores: ['index'],\r\n },\r\n ],\r\n //! 禁止在模板中注册但未使用的组件\r\n 'vue/no-unused-components': 'error',\r\n${vue2DeprecationRules}`\r\n : \"\";\r\n\r\n // ── JSDoc 块 ──\r\n const jsdocBlock = hasJsdoc\r\n ? `\r\n //MARK: 自定义规则组(优先级最高)\r\n {\r\n plugins: {\r\n jsdoc: jsdocPlugin,\r\n },\r\n rules: {\r\n //! JSDoc 注释规则\r\n 'jsdoc/require-jsdoc': [\r\n 'error',\r\n {\r\n require: {\r\n FunctionDeclaration: true,\r\n MethodDefinition: true,\r\n ClassDeclaration: true,\r\n ArrowFunctionExpression: false,\r\n FunctionExpression: true,\r\n },\r\n contexts: [\r\n 'FunctionDeclaration',\r\n 'ClassDeclaration',\r\n 'ClassProperty',\r\n 'MethodDefinition',\r\n 'FunctionExpression',\r\n ],\r\n checkConstructors: true,\r\n checkGetters: true,\r\n checkSetters: true,\r\n },\r\n ],\r\n`\r\n : `\r\n // 自定义规则组\r\n {\r\n rules: {\r\n`;\r\n\r\n // ── 文件类型覆盖 ──\r\n const fileTypeOverrides = isTs\r\n ? `\r\n //MARK: 文件类型覆盖规则\r\n\r\n //! 变量使用规则\r\n {\r\n files: ['**/*.js'],\r\n rules: {\r\n 'no-unused-vars': 'error',\r\n '@typescript-eslint/no-unused-vars': 'off',\r\n },\r\n },\r\n {\r\n files: ['**/*.{ts,mts,tsx,vue}'],\r\n rules: {\r\n 'no-unused-vars': 'off',\r\n '@typescript-eslint/no-unused-vars': 'error',\r\n },\r\n },\r\n`\r\n : \"\";\r\n\r\n // ── JSDoc 白名单 ──\r\n const jsdocWhitelist = hasJsdoc\r\n ? `\r\n //MARK: JSDoc 白名单覆盖规则\r\n {\r\n files: [\r\n 'src/router/**/*.ts',\r\n 'src/stores/**/*.ts',\r\n 'src/views/**/components/*.vue',\r\n ],\r\n rules: {\r\n 'jsdoc/require-jsdoc': 'off',\r\n '@typescript-eslint/require-jsdoc': 'off',\r\n },\r\n },\r\n`\r\n : \"\";\r\n\r\n // ── 忽略白名单 ──\r\n const ignoreAssets = `\r\n //MARK: ESLINT 白名单配置组\r\n {\r\n name: 'app/ignore-assets',\r\n ignores: [\r\n 'src/assets/images/**/*',\r\n '**/*.d.ts',\r\n '**/auto-imports.d.ts',\r\n 'src/views/**/components/*.vue',\r\n 'scripts/**/*',\r\n ],\r\n },\r\n`;\r\n\r\n // ── TS 引号和表达式规则 ──\r\n const tsRules = isTs\r\n ? `\r\n //! 关闭与 oxlint 重复的 ESLint 规则\r\n 'no-undef': 'off',\r\n\r\n //! 引号规范\r\n '@typescript-eslint/quotes': ['error', 'single'],${\r\n isVue ? \"\\n 'vue/html-quotes': ['error', 'double'],\" : \"\"\r\n }\r\n\r\n //! TypeScript 安全\r\n '@typescript-eslint/no-explicit-any': 'off',\r\n '@typescript-eslint/ban-ts-comment': [\r\n 'error',\r\n {\r\n 'ts-ignore': 'allow-with-description',\r\n },\r\n ],\r\n\r\n //! 表达式规范\r\n '@typescript-eslint/no-unused-expressions': [\r\n 'error',\r\n {\r\n allowShortCircuit: true,\r\n allowTernary: false,\r\n allowTaggedTemplates: false,\r\n enforceForJSX: true,\r\n },\r\n ],\r\n`\r\n : \"\";\r\n\r\n // ── 组装 ──\r\n const useWrapper = isVue && isTs;\r\n const wrapperStart = useWrapper\r\n ? \"export default defineConfigWithVueTs(\"\r\n : \"export default [\";\r\n const wrapperEnd = useWrapper ? \")\" : \"]\";\r\n\r\n const oxlintLine = hasOxlint\r\n ? \"\\n ...oxlint.configs['flat/recommended'], // 高性能基础校验\\n\"\r\n : \"\";\r\n const vueLine = isVue\r\n ? `\\n //! 忽略转义字符\\n {\\n rules: {\\n 'no-useless-escape': 'off',\\n },\\n },\\n\\n pluginVue.configs['flat/essential'], // Vue 专用规则`\r\n : \"\";\r\n const tsLine =\r\n isVue && isTs ? \"\\n vueTsConfigs.recommended, // TS 专用规则\" : \"\";\r\n const skipLine = hasPrettier && isVue ? \"\\n skipFormatting\" : \"\";\r\n\r\n const eslintConfig = `/*\r\n * ESLint Flat Config\r\n * @generated by @robot-admin/git-standards\r\n *\r\n * 直接修改此文件即可自定义 ESLint 规则\r\n */\r\n${importLines.join(\"\\n\")}\r\n\r\n${wrapperStart}\r\n //MARK: 基础配置组\r\n {\r\n name: 'app/files-to-lint',\r\n files: ['**/*.{${fileExts}}'],\r\n },\r\n\r\n {\r\n name: 'app/files-to-ignore',\r\n ignores: [\r\n '**/dist/**',\r\n '**/dist-ssr/**',\r\n '**/coverage/**',\r\n ],\r\n },\r\n\r\n //MARK: 核心规则组(按优先级排序)\r\n${oxlintLine}${vueLine}${tsLine}\r\n${fileTypeOverrides}\r\n${jsdocBlock}${tsRules}\r\n //! 代码复杂度\r\n 'max-depth': ['error', 4],\r\n complexity: ['warn', 10],\r\n\r\n //! 异步代码规范\r\n 'no-await-in-loop': 'error',\r\n${vueComponentRules}\r\n //MARK: 格式规范\r\n 'no-irregular-whitespace': 'error',\r\n 'no-multi-spaces': 'error',\r\n 'space-infix-ops': 'error',\r\n 'array-bracket-spacing': ['error', 'never'],\r\n 'arrow-spacing': ['error', { before: true, after: true }],\r\n 'max-params': ['warn', 6],\r\n 'no-eval': 'error',\r\n 'prefer-const': 'warn',\r\n 'no-var': 'warn',\r\n 'prefer-destructuring': [\r\n 1,\r\n { object: true, array: false },\r\n ],\r\n 'no-duplicate-imports': 'error',\r\n },\r\n },\r\n${ignoreAssets}${jsdocWhitelist}${skipLine}\r\n${wrapperEnd}\r\n`;\r\n await writeFileContent(resolve(cwd, \"eslint.config.ts\"), eslintConfig);\r\n generated.push(\"eslint.config.ts\");\r\n }\r\n\r\n // ── .editorconfig(仅当 editorconfig 启用)──\r\n if (features.editorconfig) {\r\n const editorConfig = `# EditorConfig - 编辑器统一配置\r\n# @generated by @robot-admin/git-standards\r\n# 参考: https://editorconfig.org\r\n\r\nroot = true\r\n\r\n[*]\r\ncharset = utf-8\r\nindent_style = space\r\nindent_size = 2\r\nend_of_line = lf\r\ninsert_final_newline = true\r\ntrim_trailing_whitespace = true\r\n\r\n[*.md]\r\ntrim_trailing_whitespace = false\r\n\r\n[*.{yml,yaml}]\r\nindent_size = 2\r\n\r\n[Makefile]\r\nindent_style = tab\r\n`;\r\n await writeFileContent(resolve(cwd, \".editorconfig\"), editorConfig);\r\n generated.push(\".editorconfig\");\r\n }\r\n\r\n spinner.succeed(\r\n chalk.white(\"配置文件生成完成 \") +\r\n chalk.gray(`(${generated.join(\", \")})`),\r\n );\r\n } catch (error) {\r\n spinner.fail(chalk.red(\"配置文件生成失败\"));\r\n throw error;\r\n }\r\n}\r\n\r\n// ─── Husky 设置 ──────────────────────────────────────────────────\r\nasync function setupHusky(cwd: string, pm: string, features: FeatureSet) {\r\n const spinner = ora({\r\n text: chalk.gray(\"初始化 Husky...\"),\r\n prefixText: \" \",\r\n spinner: \"dots\",\r\n }).start();\r\n\r\n try {\r\n const execCmd = getExecCommand(pm as any);\r\n await execa(execCmd, [\"husky\", \"init\"], { cwd, stdio: \"pipe\" });\r\n\r\n // ── 清理 husky v4 遗留的 _ 目录 ──\r\n const legacyDir = resolve(cwd, \".husky/_\");\r\n if (existsSync(legacyDir)) {\r\n rmSync(legacyDir, { recursive: true, force: true });\r\n }\r\n\r\n // ── commit-msg hook(始终创建)──\r\n const commitMsg = `${execCmd} --no-install commitlint --edit \"$1\"\\n`;\r\n await writeFileContent(resolve(cwd, \".husky/commit-msg\"), commitMsg);\r\n\r\n const hooks: string[] = [\"commit-msg\"];\r\n\r\n // ── pre-commit hook(根据功能动态生成)──\r\n const needsPreCommit =\r\n features.eslint || features.lintStaged || features.oxlint;\r\n\r\n if (needsPreCommit) {\r\n const cmds: string[] = [];\r\n if (features.oxlint) {\r\n cmds.push(`${execCmd} oxlint --max-warnings 0`);\r\n }\r\n if (features.lintStaged) {\r\n cmds.push(`${execCmd} lint-staged`);\r\n } else if (features.eslint) {\r\n cmds.push(`${execCmd} eslint . --fix`);\r\n }\r\n await writeFileContent(\r\n resolve(cwd, \".husky/pre-commit\"),\r\n cmds.join(\"\\n\") + \"\\n\",\r\n );\r\n hooks.push(\"pre-commit\");\r\n } else {\r\n // 极简模式:移除 husky init 创建的默认 pre-commit\r\n const defaultPreCommit = resolve(cwd, \".husky/pre-commit\");\r\n if (existsSync(defaultPreCommit)) {\r\n unlinkSync(defaultPreCommit);\r\n }\r\n }\r\n\r\n spinner.succeed(\r\n chalk.white(\"Husky 初始化完成 \") + chalk.gray(`(${hooks.join(\", \")})`),\r\n );\r\n } catch (error) {\r\n spinner.fail(chalk.red(\"Husky 初始化失败\"));\r\n throw error;\r\n }\r\n}\r\n\r\n// ─── 更新 package.json ──────────────────────────────────────────\r\nasync function addPackageScripts(\r\n cwd: string,\r\n pm: string,\r\n features: FeatureSet,\r\n) {\r\n const spinner = ora({\r\n text: chalk.gray(\"更新 package.json...\"),\r\n prefixText: \" \",\r\n spinner: \"dots\",\r\n }).start();\r\n\r\n try {\r\n const packageJsonPath = resolve(cwd, \"package.json\");\r\n const packageJson = await readJsonFile(packageJsonPath);\r\n\r\n const scripts = packageJson.scripts || {};\r\n\r\n // cz 脚本(始终添加)\r\n scripts.cz = \"git-cz\";\r\n\r\n // prepare 脚本(husky 需要)\r\n scripts.prepare = \"husky\";\r\n\r\n // lint 脚本(仅当 eslint 启用)\r\n if (features.eslint) {\r\n scripts.lint = features.oxlint\r\n ? \"oxlint . --fix -D correctness --ignore-path .gitignore && eslint . --fix\"\r\n : \"eslint . --fix\";\r\n }\r\n\r\n // format 脚本(仅当 prettier 启用)\r\n if (features.prettier) {\r\n scripts.format = \"prettier --write src/\";\r\n }\r\n\r\n // commitizen config(始终添加)\r\n const czConfig = {\r\n commitizen: { path: \"node_modules/cz-customizable\" },\r\n };\r\n\r\n const updates: Record<string, any> = { scripts, config: czConfig };\r\n\r\n // lint-staged config(仅当 lintStaged 启用)\r\n if (features.lintStaged) {\r\n updates[\"lint-staged\"] = generateLintStagedConfig({\r\n eslint: features.eslint,\r\n oxlint: features.oxlint,\r\n prettier: features.prettier,\r\n });\r\n }\r\n\r\n await updatePackageJson(updates, cwd);\r\n\r\n const parts = [\"scripts\"];\r\n if (features.lintStaged) parts.push(\"lint-staged\");\r\n spinner.succeed(\r\n chalk.white(\"package.json 更新完成 \") +\r\n chalk.gray(`(${parts.join(\" + \")})`),\r\n );\r\n } catch (error) {\r\n spinner.fail(chalk.red(\"package.json 更新失败\"));\r\n throw error;\r\n }\r\n}\r\n\r\n// ─── 完成输出 ────────────────────────────────────────────────────\r\nfunction printCompletion(pm: string, features: FeatureSet) {\r\n console.log();\r\n console.log(S.LINE);\r\n console.log(` ${S.OK} ${chalk.green.bold(\"初始化完成!\")}`);\r\n console.log(S.LINE);\r\n console.log();\r\n console.log(` ${chalk.bold(\"快速开始:\")}`);\r\n console.log();\r\n console.log(` ${S.DOT} 提交代码 ${chalk.cyan(`${pm} run cz`)}`);\r\n if (features.eslint) {\r\n console.log(` ${S.DOT} 检查代码 ${chalk.cyan(`${pm} run lint`)}`);\r\n }\r\n if (features.prettier) {\r\n console.log(` ${S.DOT} 格式化 ${chalk.cyan(`${pm} run format`)}`);\r\n }\r\n console.log();\r\n console.log(\r\n ` ${S.INFO} ${chalk.gray(\"全局安装 commitizen 后可直接使用 git cz 提交\")}`,\r\n );\r\n console.log(` ${S.DOT} ${chalk.gray(`npm install -g commitizen`)}`);\r\n console.log();\r\n console.log(\r\n ` ${S.INFO} ${chalk.gray(\"所有配置文件均支持覆盖扩展,详见 README.md\")}`,\r\n );\r\n console.log();\r\n}\r\n","/*\r\n * @Author: ChenYu ycyplus@gmail.com\r\n * @Date: 2026-02-13\r\n * @Description: 包管理器检测工具\r\n * Copyright (c) 2026 by CHENY, All Rights Reserved.\r\n */\r\n\r\nimport { existsSync } from \"node:fs\";\r\nimport { resolve } from \"node:path\";\r\n\r\nexport type PackageManager = \"npm\" | \"yarn\" | \"pnpm\" | \"bun\";\r\n\r\n/**\r\n * 检测项目使用的包管理器\r\n */\r\nexport async function detectPackageManager(\r\n cwd: string = process.cwd(),\r\n): Promise<PackageManager> {\r\n // 检测 lockfile\r\n if (\r\n existsSync(resolve(cwd, \"bun.lockb\")) ||\r\n existsSync(resolve(cwd, \"bun.lock\"))\r\n ) {\r\n return \"bun\";\r\n }\r\n if (existsSync(resolve(cwd, \"pnpm-lock.yaml\"))) {\r\n return \"pnpm\";\r\n }\r\n if (existsSync(resolve(cwd, \"yarn.lock\"))) {\r\n return \"yarn\";\r\n }\r\n if (existsSync(resolve(cwd, \"package-lock.json\"))) {\r\n return \"npm\";\r\n }\r\n\r\n // 默认返回 npm\r\n return \"npm\";\r\n}\r\n\r\n/**\r\n * 获取安装命令\r\n */\r\nexport function getInstallCommand(pm: PackageManager): string {\r\n const commands = {\r\n npm: \"npm install --save-dev\",\r\n yarn: \"yarn add --dev\",\r\n pnpm: \"pnpm add -D\",\r\n bun: \"bun add --dev\",\r\n };\r\n return commands[pm];\r\n}\r\n\r\n/**\r\n * 获取执行命令\r\n */\r\nexport function getExecCommand(pm: PackageManager): string {\r\n const commands = {\r\n npm: \"npx --no\",\r\n yarn: \"yarn\",\r\n pnpm: \"pnpm dlx\",\r\n bun: \"bunx\",\r\n };\r\n return commands[pm];\r\n}\r\n\r\n/**\r\n * 获取包管理器的显示名称\r\n */\r\nexport function getPackageManagerName(pm: PackageManager): string {\r\n const names = {\r\n npm: \"npm\",\r\n yarn: \"Yarn\",\r\n pnpm: \"pnpm\",\r\n bun: \"Bun\",\r\n };\r\n return names[pm];\r\n}\r\n","/*\r\n * @Author: ChenYu ycyplus@gmail.com\r\n * @Date: 2026-02-13\r\n * @Description: Git 工具函数\r\n * Copyright (c) 2026 by CHENY, All Rights Reserved.\r\n */\r\n\r\nimport { existsSync } from \"node:fs\";\r\nimport { resolve } from \"node:path\";\r\nimport { execa } from \"execa\";\r\n\r\n/**\r\n * 检查是否在 Git 仓库中\r\n */\r\nexport function isGitRepository(cwd: string = process.cwd()): boolean {\r\n return existsSync(resolve(cwd, \".git\"));\r\n}\r\n\r\n/**\r\n * 初始化 Git 仓库\r\n */\r\nexport async function initGitRepository(\r\n cwd: string = process.cwd(),\r\n): Promise<void> {\r\n if (!isGitRepository(cwd)) {\r\n await execa(\"git\", [\"init\"], { cwd });\r\n }\r\n}\r\n","/*\r\n * @Author: ChenYu ycyplus@gmail.com\r\n * @Date: 2026-02-13\r\n * @Description: 文件操作工具\r\n * Copyright (c) 2026 by CHENY, All Rights Reserved.\r\n */\r\n\r\nimport { existsSync } from \"node:fs\";\r\nimport { readFile, writeFile, mkdir } from \"node:fs/promises\";\r\nimport { resolve, dirname } from \"node:path\";\r\n\r\n/**\r\n * 检查文件是否存在\r\n */\r\nexport function fileExists(filePath: string): boolean {\r\n return existsSync(filePath);\r\n}\r\n\r\n/**\r\n * 读取文件内容\r\n */\r\nexport async function readFileContent(filePath: string): Promise<string> {\r\n return await readFile(filePath, \"utf-8\");\r\n}\r\n\r\n/**\r\n * 写入文件内容\r\n */\r\nexport async function writeFileContent(\r\n filePath: string,\r\n content: string,\r\n): Promise<void> {\r\n const dir = dirname(filePath);\r\n if (!existsSync(dir)) {\r\n await mkdir(dir, { recursive: true });\r\n }\r\n await writeFile(filePath, content, \"utf-8\");\r\n}\r\n\r\n/**\r\n * 读取并解析 JSON 文件\r\n */\r\nexport async function readJsonFile<T = any>(filePath: string): Promise<T> {\r\n const content = await readFileContent(filePath);\r\n return JSON.parse(content) as T;\r\n}\r\n\r\n/**\r\n * 写入 JSON 文件\r\n */\r\nexport async function writeJsonFile(\r\n filePath: string,\r\n data: any,\r\n pretty: boolean = true,\r\n): Promise<void> {\r\n const content = pretty\r\n ? JSON.stringify(data, null, 2) + \"\\n\"\r\n : JSON.stringify(data);\r\n await writeFileContent(filePath, content);\r\n}\r\n\r\n/**\r\n * 更新 package.json\r\n */\r\nexport async function updatePackageJson(\r\n updates: Record<string, any>,\r\n cwd: string = process.cwd(),\r\n): Promise<void> {\r\n const packageJsonPath = resolve(cwd, \"package.json\");\r\n const packageJson = await readJsonFile(packageJsonPath);\r\n const updated = { ...packageJson, ...updates };\r\n await writeJsonFile(packageJsonPath, updated);\r\n}\r\n","/*\r\n * @Author: ChenYu ycyplus@gmail.com\r\n * @Date: 2026-02-13\r\n * @Description: Lint-staged 配置生成器\r\n * Copyright (c) 2026 by CHENY, All Rights Reserved.\r\n */\r\n\r\nexport interface LintStagedOptions {\r\n /**\r\n * 是否启用 ESLint(默认 true)\r\n */\r\n eslint?: boolean;\r\n /**\r\n * 是否启用 Oxlint\r\n */\r\n oxlint?: boolean;\r\n /**\r\n * 是否启用 Prettier\r\n */\r\n prettier?: boolean;\r\n /**\r\n * 文件 glob 模式\r\n */\r\n filePatterns?: {\r\n code?: string;\r\n markup?: string;\r\n };\r\n}\r\n\r\n/**\r\n * 创建 Lint-staged 配置\r\n */\r\nexport function createLintStagedConfig(options: LintStagedOptions = {}) {\r\n const codePattern =\r\n options.filePatterns?.code || \"src/**/*.{js,jsx,ts,tsx,vue}\";\r\n const markupPattern = options.filePatterns?.markup || \"*.{json,md,yml,yaml}\";\r\n\r\n const codeCommands: string[] = [];\r\n\r\n // Oxlint 优先(性能最优)\r\n if (options.oxlint !== false) {\r\n codeCommands.push(\"oxlint --max-warnings 0 --deny-warnings\");\r\n }\r\n\r\n // ESLint(默认启用,可通过 eslint: false 关闭)\r\n if (options.eslint !== false) {\r\n codeCommands.push(\"eslint --fix --no-cache\");\r\n }\r\n\r\n // Prettier\r\n if (options.prettier !== false) {\r\n codeCommands.push(\"prettier --write\");\r\n }\r\n\r\n // 如果没有任何代码检查命令,不生成代码模式配置\r\n const config: Record<string, string[]> = {};\r\n\r\n if (codeCommands.length > 0) {\r\n config[codePattern] = codeCommands;\r\n }\r\n\r\n // 为标记文件添加 Prettier\r\n if (options.prettier !== false) {\r\n config[markupPattern] = [\"prettier --write\"];\r\n }\r\n\r\n return config;\r\n}\r\n\r\n/**\r\n * 生成 lint-staged 配置(用于 package.json)\r\n */\r\nexport function generateLintStagedConfig(\r\n options: LintStagedOptions = {},\r\n): Record<string, string[]> {\r\n return createLintStagedConfig(options);\r\n}\r\n"],"mappings":"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","names":["import_node_path","import_node_fs","import_execa","import_node_fs","import_node_path","import_node_fs","import_node_path","chalk","ora","chalk","ora"]}
1
+ {"version":3,"sources":["../../src/cli/init.ts","../../src/utils/package-manager.ts","../../src/utils/git.ts","../../src/utils/file.ts","../../src/configs/lint-staged.ts"],"sourcesContent":["/*\r\n * @Author: ChenYu ycyplus@gmail.com\r\n * @Date: 2026-02-13\r\n * @Description: Init 命令 - 模块化初始化 Git 标准化配置(预设 + 自定义)\r\n * Copyright (c) 2026 by CHENY, All Rights Reserved.\r\n */\r\n\r\nimport { resolve } from \"node:path\";\r\nimport { unlinkSync, existsSync } from \"node:fs\";\r\nimport chalk from \"chalk\";\r\nimport ora from \"ora\";\r\nimport { execa } from \"execa\";\r\nimport {\r\n detectPackageManager,\r\n getInstallCommand,\r\n getExecCommand,\r\n getPackageManagerName,\r\n} from \"../utils/package-manager\";\r\nimport { isGitRepository, initGitRepository } from \"../utils/git\";\r\nimport {\r\n writeFileContent,\r\n writeExecutableFile,\r\n updatePackageJson,\r\n readJsonFile,\r\n} from \"../utils/file\";\r\nimport { generateLintStagedConfig } from \"../configs/lint-staged\";\r\n\r\n// ─── 品牌 & 符号系统 ──────────────────────────────────────────────\r\nconst BRAND = \"#7C3AED\";\r\nconst S = {\r\n LOGO: chalk.hex(BRAND).bold(\"[RS]\"),\r\n OK: chalk.green(\"✔\"),\r\n FAIL: chalk.red(\"✖\"),\r\n WARN: chalk.yellow(\"▲\"),\r\n STEP: chalk.hex(BRAND)(\"◆\"),\r\n ARROW: chalk.cyan(\"▸\"),\r\n DOT: chalk.gray(\"●\"),\r\n INFO: chalk.blue(\"ℹ\"),\r\n LINE: chalk.gray(\"─\".repeat(48)),\r\n};\r\n\r\n// ─── 类型定义 ──────────────────────────────────────────────────────\r\ntype PresetId = \"minimal\" | \"standard\" | \"full\" | \"custom\";\r\n\r\n/**\r\n * 功能开关集合\r\n * - commitizen / commitlint / husky 为核心功能,始终包含\r\n * - 以下为可选附加功能\r\n */\r\nexport interface FeatureSet {\r\n eslint: boolean;\r\n lintStaged: boolean;\r\n prettier: boolean;\r\n oxlint: boolean;\r\n editorconfig: boolean;\r\n}\r\n\r\nexport interface ESLintOptions {\r\n framework: \"vue\" | \"react\" | \"vanilla\";\r\n typescript: boolean;\r\n jsdoc: boolean;\r\n}\r\n\r\nexport interface InitOptions {\r\n cwd?: string;\r\n ci?: boolean;\r\n preset?: PresetId;\r\n framework?: \"vue\" | \"react\" | \"vanilla\";\r\n typescript?: boolean;\r\n oxlint?: boolean;\r\n jsdoc?: boolean;\r\n prettier?: boolean;\r\n}\r\n\r\n// ─── 预设模式定义 ──────────────────────────────────────────────────\r\nconst PRESETS: Record<\r\n Exclude<PresetId, \"custom\">,\r\n { name: string; desc: string; features: FeatureSet }\r\n> = {\r\n minimal: {\r\n name: \"极简模式\",\r\n desc: \"仅 Git 提交规范 (Commitizen + Commitlint)\",\r\n features: {\r\n eslint: false,\r\n lintStaged: false,\r\n prettier: false,\r\n oxlint: false,\r\n editorconfig: false,\r\n },\r\n },\r\n standard: {\r\n name: \"标准模式\",\r\n desc: \"提交规范 + 代码质量检查 (+ ESLint + lint-staged)\",\r\n features: {\r\n eslint: true,\r\n lintStaged: true,\r\n prettier: false,\r\n oxlint: false,\r\n editorconfig: true,\r\n },\r\n },\r\n full: {\r\n name: \"完整模式\",\r\n desc: \"全部工具链 (+ Prettier + Oxlint + EditorConfig)\",\r\n features: {\r\n eslint: true,\r\n lintStaged: true,\r\n prettier: true,\r\n oxlint: true,\r\n editorconfig: true,\r\n },\r\n },\r\n};\r\n\r\n// ─── 主函数 ──────────────────────────────────────────────────────\r\nexport async function init(options: InitOptions = {}) {\r\n const cwd = options.cwd || process.cwd();\r\n\r\n // ── Banner ──\r\n printBanner();\r\n\r\n // 1. 环境检测\r\n console.log(` ${S.STEP} ${chalk.bold(\"环境检测\")}`);\r\n console.log();\r\n\r\n if (!isGitRepository(cwd)) {\r\n const spinner = ora({\r\n text: chalk.gray(\"初始化 Git 仓库...\"),\r\n prefixText: \" \",\r\n spinner: \"dots\",\r\n }).start();\r\n await initGitRepository(cwd);\r\n spinner.succeed(chalk.white(\"Git 仓库初始化完成\"));\r\n } else {\r\n console.log(` ${S.OK} Git 仓库已就绪`);\r\n }\r\n\r\n const pm = await detectPackageManager(cwd);\r\n const pmName = getPackageManagerName(pm);\r\n console.log(` ${S.OK} 包管理器: ${chalk.cyan.bold(pmName)}`);\r\n console.log();\r\n\r\n // 2. 功能选择(交互式 or CI)\r\n let features: FeatureSet;\r\n let eslintOpts: ESLintOptions = {\r\n framework: \"vue\",\r\n typescript: true,\r\n jsdoc: false,\r\n };\r\n\r\n if (options.ci) {\r\n // ── CI 模式 ──\r\n const presetId: PresetId = options.preset || \"standard\";\r\n if (presetId === \"custom\") {\r\n features = {\r\n eslint: true,\r\n lintStaged: true,\r\n prettier: options.prettier ?? true,\r\n oxlint: options.oxlint ?? true,\r\n editorconfig: true,\r\n };\r\n } else {\r\n features = { ...PRESETS[presetId].features };\r\n }\r\n // CLI flag 覆盖\r\n if (options.prettier !== undefined) features.prettier = options.prettier;\r\n if (options.oxlint !== undefined) features.oxlint = options.oxlint;\r\n const jsdocDefault = presetId === \"full\" ? true : false;\r\n eslintOpts = {\r\n framework: options.framework || \"vue\",\r\n typescript: options.typescript ?? true,\r\n jsdoc: options.jsdoc ?? jsdocDefault,\r\n };\r\n console.log(\r\n ` ${S.INFO} ${chalk.gray(\"CI 模式\")} ${chalk.white(\r\n \"预设:\",\r\n )} ${chalk.cyan(presetId)}`,\r\n );\r\n console.log();\r\n } else {\r\n // ── 交互式模式 ──\r\n const result = await interactiveSetup(options);\r\n features = result.features;\r\n eslintOpts = result.eslintOpts;\r\n }\r\n\r\n // 3. 配置摘要 & 确认\r\n printSummary(features, eslintOpts, pmName);\r\n\r\n if (!options.ci) {\r\n const { confirm } = await import(\"@inquirer/prompts\");\r\n const proceed = await confirm({\r\n message: chalk.white(\"确认以上配置并开始安装?\"),\r\n default: true,\r\n theme: { prefix: ` ${S.ARROW}` },\r\n });\r\n if (!proceed) {\r\n console.log();\r\n console.log(` ${S.INFO} ${chalk.gray(\"重新选择配置...\")}`);\r\n console.log();\r\n const result = await interactiveSetup(options);\r\n features = result.features;\r\n eslintOpts = result.eslintOpts;\r\n printSummary(features, eslintOpts, pmName);\r\n // 递归确认后直接继续\r\n }\r\n }\r\n\r\n console.log();\r\n\r\n // 4. 执行安装流程\r\n await installDependencies(cwd, pm, features, eslintOpts);\r\n await generateConfigFiles(cwd, features, eslintOpts);\r\n await setupHusky(cwd, pm, features);\r\n await addPackageScripts(cwd, pm, features);\r\n\r\n // 5. 完成\r\n printCompletion(pm, features);\r\n}\r\n\r\n// ─── Banner ──────────────────────────────────────────────────────\r\nfunction printBanner() {\r\n console.log();\r\n console.log(S.LINE);\r\n console.log(\r\n ` ${S.LOGO} ${chalk.bold(\"Robot Standards\")} ${chalk.gray(\"v1.0.0\")}`,\r\n );\r\n console.log(` ${chalk.gray(\"零配置 · 模块化 · Git 工程化标准工具包\")}`);\r\n console.log(S.LINE);\r\n console.log();\r\n}\r\n\r\n// ─── 交互式选择 ─────────────────────────────────────────────────\r\nconst BACK_SIGNAL = Symbol(\"back\");\r\n\r\nasync function interactiveSetup(\r\n options: InitOptions,\r\n): Promise<{ features: FeatureSet; eslintOpts: ESLintOptions }> {\r\n const { select, checkbox, confirm } = await import(\"@inquirer/prompts\");\r\n\r\n // 外层循环:支持从后续步骤返回重选\r\n // eslint-disable-next-line no-constant-condition\r\n while (true) {\r\n // ── Step 1: 预设选择 ──\r\n console.log(` ${S.STEP} ${chalk.bold(\"选择模式\")}`);\r\n console.log();\r\n\r\n const presetId = await select<PresetId>({\r\n message: chalk.white(\"选择预设方案\"),\r\n choices: [\r\n {\r\n name: `极简模式 ${chalk.gray(\r\n \"── 仅提交规范 (Commitizen + Commitlint)\",\r\n )}`,\r\n value: \"minimal\" as PresetId,\r\n description: chalk.gray(\"适合只需规范提交信息的项目\"),\r\n },\r\n {\r\n name: `标准模式 ${chalk.gray(\"── 提交规范 + 代码检查 (+ ESLint)\")}`,\r\n value: \"standard\" as PresetId,\r\n description: chalk.gray(\"适合大多数项目\"),\r\n },\r\n {\r\n name: `完整模式 ${chalk.gray(\r\n \"── 全部工具链 (+ Prettier + Oxlint)\",\r\n )} ${chalk.hex(BRAND)(\"主项目(Robot_Admin)\")}`,\r\n value: \"full\" as PresetId,\r\n description: chalk.gray(\"全面代码质量管控\"),\r\n },\r\n {\r\n name: `自定义 ${chalk.gray(\"── 自由组合需要的工具链\")}`,\r\n value: \"custom\" as PresetId,\r\n description: chalk.gray(\"精确控制每个功能模块\"),\r\n },\r\n ],\r\n default: \"standard\" as PresetId,\r\n theme: { prefix: ` ${S.ARROW}` },\r\n });\r\n\r\n let features: FeatureSet;\r\n\r\n if (presetId === \"custom\") {\r\n // ── Step 2: 自定义功能选择 ──\r\n console.log();\r\n console.log(\r\n ` ${S.STEP} ${chalk.bold(\"选择功能\")} ${chalk.gray(\r\n \"(Git 提交规范默认包含)\",\r\n )}`,\r\n );\r\n console.log();\r\n\r\n type FeatureChoice =\r\n | \"eslint\"\r\n | \"lintStaged\"\r\n | \"prettier\"\r\n | \"oxlint\"\r\n | \"editorconfig\"\r\n | \"__back__\";\r\n\r\n const selected = await checkbox<FeatureChoice>({\r\n message: chalk.white(\"选择附加功能 (空格切换, 回车确认)\"),\r\n choices: [\r\n {\r\n name: `ESLint ${chalk.gray(\"代码质量检查\")}`,\r\n value: \"eslint\" as FeatureChoice,\r\n },\r\n {\r\n name: `lint-staged ${chalk.gray(\"暂存区增量检查\")}`,\r\n value: \"lintStaged\" as FeatureChoice,\r\n },\r\n {\r\n name: `Prettier ${chalk.gray(\"代码自动格式化\")}`,\r\n value: \"prettier\" as FeatureChoice,\r\n },\r\n {\r\n name: `Oxlint ${chalk.gray(\r\n \"高性能 Lint 引擎 (50x faster)\",\r\n )}`,\r\n value: \"oxlint\" as FeatureChoice,\r\n },\r\n {\r\n name: `EditorConfig ${chalk.gray(\"编辑器统一配置\")}`,\r\n value: \"editorconfig\" as FeatureChoice,\r\n },\r\n {\r\n name: chalk.yellow(\"↩ 返回上一步\"),\r\n value: \"__back__\" as FeatureChoice,\r\n },\r\n ],\r\n theme: { prefix: ` ${S.ARROW}` },\r\n });\r\n\r\n if (selected.includes(\"__back__\")) continue;\r\n\r\n features = {\r\n eslint: selected.includes(\"eslint\"),\r\n lintStaged: selected.includes(\"lintStaged\"),\r\n prettier: selected.includes(\"prettier\"),\r\n oxlint: selected.includes(\"oxlint\"),\r\n editorconfig: selected.includes(\"editorconfig\"),\r\n };\r\n\r\n // ── 依赖关系自动修正 ──\r\n if (features.oxlint && !features.eslint) {\r\n console.log(\r\n `\\n ${S.INFO} ${chalk.gray(\r\n \"Oxlint 需要 ESLint 配合,已自动启用 ESLint\",\r\n )}`,\r\n );\r\n features.eslint = true;\r\n }\r\n if (features.lintStaged && !features.eslint && !features.prettier) {\r\n console.log(\r\n `\\n ${S.INFO} ${chalk.gray(\r\n \"lint-staged 需要 ESLint 或 Prettier,已自动启用 ESLint\",\r\n )}`,\r\n );\r\n features.eslint = true;\r\n }\r\n } else {\r\n features = { ...PRESETS[presetId].features };\r\n }\r\n\r\n // ── Step 3: ESLint 子配置(仅当 ESLint 启用时显示)──\r\n let eslintOpts: ESLintOptions = {\r\n framework: \"vue\",\r\n typescript: true,\r\n jsdoc: false,\r\n };\r\n\r\n if (features.eslint) {\r\n console.log();\r\n console.log(` ${S.STEP} ${chalk.bold(\"ESLint 配置\")}`);\r\n console.log();\r\n\r\n const framework = await select({\r\n message: chalk.white(\"项目框架\"),\r\n choices: [\r\n {\r\n name: \"Vue 3\",\r\n value: \"vue\" as const,\r\n },\r\n { name: \"React\", value: \"react\" as const },\r\n { name: \"Vanilla JS / TS\", value: \"vanilla\" as const },\r\n {\r\n name: chalk.yellow(\"↩ 返回上一步\"),\r\n value: \"__back__\" as const,\r\n },\r\n ],\r\n default: options.framework || \"vue\",\r\n theme: { prefix: ` ${S.ARROW}` },\r\n });\r\n\r\n if (framework === \"__back__\") continue;\r\n\r\n const typescript = await confirm({\r\n message: chalk.white(\"使用 TypeScript\"),\r\n default: options.typescript ?? true,\r\n theme: { prefix: ` ${S.ARROW}` },\r\n });\r\n\r\n const jsdoc = await confirm({\r\n message: chalk.white(\"强制 JSDoc 注释\"),\r\n default: options.jsdoc ?? true,\r\n theme: { prefix: ` ${S.ARROW}` },\r\n });\r\n\r\n eslintOpts = { framework, typescript, jsdoc };\r\n }\r\n\r\n return { features, eslintOpts };\r\n } // end while\r\n}\r\n\r\n// ─── 配置摘要 ────────────────────────────────────────────────────\r\nfunction printSummary(\r\n features: FeatureSet,\r\n eslintOpts: ESLintOptions,\r\n pmName: string,\r\n) {\r\n console.log();\r\n console.log(` ${S.STEP} ${chalk.bold(\"配置摘要\")}`);\r\n console.log();\r\n\r\n // 核心模块(始终包含)\r\n console.log(\r\n ` ${S.OK} ${chalk.white(\"核心\")} Commitizen + Commitlint + Husky`,\r\n );\r\n\r\n if (features.eslint) {\r\n const fw =\r\n eslintOpts.framework === \"vue\"\r\n ? \"Vue 3\"\r\n : eslintOpts.framework === \"react\"\r\n ? \"React\"\r\n : \"Vanilla\";\r\n const ts = eslintOpts.typescript ? \" + TS\" : \"\";\r\n const jsdoc = eslintOpts.jsdoc ? \" + JSDoc\" : \"\";\r\n console.log(\r\n ` ${S.OK} ${chalk.white(\"检查\")} ESLint (${fw}${ts}${jsdoc})`,\r\n );\r\n }\r\n if (features.lintStaged) {\r\n console.log(` ${S.OK} ${chalk.white(\"暂存\")} lint-staged`);\r\n }\r\n if (features.oxlint) {\r\n console.log(\r\n ` ${S.OK} ${chalk.white(\"加速\")} Oxlint ${chalk.gray(\"(50x faster)\")}`,\r\n );\r\n }\r\n if (features.prettier) {\r\n console.log(` ${S.OK} ${chalk.white(\"格式\")} Prettier`);\r\n }\r\n if (features.editorconfig) {\r\n console.log(` ${S.OK} ${chalk.white(\"编辑\")} EditorConfig`);\r\n }\r\n console.log(` ${S.DOT} ${chalk.gray(\"管理\")} ${pmName}`);\r\n console.log();\r\n}\r\n\r\n// ─── 安装依赖 ────────────────────────────────────────────────────\r\nasync function installDependencies(\r\n cwd: string,\r\n pm: string,\r\n features: FeatureSet,\r\n eslintOpts: ESLintOptions,\r\n) {\r\n const spinner = ora({\r\n text: chalk.gray(\"分析依赖...\"),\r\n prefixText: \" \",\r\n spinner: \"dots\",\r\n }).start();\r\n\r\n // ── 核心依赖(始终安装) ──\r\n const deps: string[] = [\r\n \"@commitlint/cli\",\r\n \"@commitlint/config-conventional\",\r\n \"commitizen\",\r\n \"cz-customizable\",\r\n \"husky\",\r\n ];\r\n\r\n // ── ESLint ──\r\n if (features.eslint) {\r\n deps.push(\"eslint\");\r\n if (eslintOpts.framework === \"vue\") {\r\n deps.push(\"eslint-plugin-vue\", \"@vue/eslint-config-typescript\");\r\n }\r\n if (eslintOpts.typescript) {\r\n deps.push(\r\n \"@typescript-eslint/eslint-plugin\",\r\n \"@typescript-eslint/parser\",\r\n );\r\n }\r\n if (eslintOpts.jsdoc) {\r\n deps.push(\"eslint-plugin-jsdoc\");\r\n }\r\n }\r\n\r\n // ── lint-staged ──\r\n if (features.lintStaged) {\r\n deps.push(\"lint-staged\");\r\n }\r\n\r\n // ── Oxlint ──\r\n if (features.oxlint) {\r\n deps.push(\"oxlint\", \"eslint-plugin-oxlint\");\r\n }\r\n\r\n // ── Prettier ──\r\n if (features.prettier) {\r\n deps.push(\"prettier\");\r\n if (features.eslint && eslintOpts.framework === \"vue\") {\r\n deps.push(\"@vue/eslint-config-prettier\");\r\n }\r\n }\r\n\r\n spinner.text = chalk.gray(`安装 ${deps.length} 个依赖...`);\r\n\r\n try {\r\n const installCmd = getInstallCommand(pm as any);\r\n await execa(\r\n installCmd.split(\" \")[0],\r\n [...installCmd.split(\" \").slice(1), ...deps],\r\n { cwd, stdio: \"pipe\" },\r\n );\r\n spinner.succeed(\r\n chalk.white(\"依赖安装完成 \") + chalk.gray(`(${deps.length} packages)`),\r\n );\r\n } catch (error) {\r\n spinner.fail(chalk.red(\"依赖安装失败\"));\r\n throw error;\r\n }\r\n}\r\n\r\n// ─── 生成配置文件 ────────────────────────────────────────────────\r\nasync function generateConfigFiles(\r\n cwd: string,\r\n features: FeatureSet,\r\n eslintOpts: ESLintOptions,\r\n) {\r\n const spinner = ora({\r\n text: chalk.gray(\"生成配置文件...\"),\r\n prefixText: \" \",\r\n spinner: \"dots\",\r\n }).start();\r\n\r\n const generated: string[] = [];\r\n\r\n try {\r\n // ── .cz-config.js(始终生成)──\r\n const czConfig = `/*\r\n * Commitizen 自定义配置 (cz-customizable)\r\n * @generated by @robot-admin/git-standards\r\n *\r\n * 直接修改此文件即可自定义提交规范\r\n */\r\nmodule.exports = {\r\n scopes: [],\r\n allowEmptyScopes: false,\r\n allowCustomScopes: true,\r\n\r\n types: [\r\n { value: 'wip', name: 'wip: 🚧 开发中' },\r\n { value: 'feat', name: 'feat: 🎯 新功能' },\r\n { value: 'fix', name: 'fix: 🐛 Bug 修复' },\r\n { value: 'perf', name: 'perf: ⚡️ 性能优化' },\r\n { value: 'deps', name: 'deps: 📦 依赖更新' },\r\n { value: 'refactor', name: 'refactor: ♻️ 重构' },\r\n { value: 'docs', name: 'docs: 📚 文档变更' },\r\n { value: 'test', name: 'test: 🔎 测试相关' },\r\n { value: 'style', name: 'style: 💄 代码样式' },\r\n { value: 'build', name: 'build: 🧳 构建/打包' },\r\n { value: 'chore', name: 'chore: 🔧 其他杂项' },\r\n { value: 'revert', name: 'revert: 🔙 回退' },\r\n ],\r\n\r\n messages: {\r\n type: '请选择提交类型:',\r\n customScope: '请输入修改范围(必填,格式如:模块/子模块):',\r\n subject: '请简要描述提交(必填,不加句号):',\r\n body: '请输入更详细的说明(可选):\\\\n',\r\n footer: 'Footer(可选): 例如 \"Closes #123\" 或 \"Release-As: 1.3.1\"\\\\n',\r\n confirmCommit: '确认提交以上内容?(y/n/e/h)',\r\n },\r\n\r\n skipQuestions: ['body'],\r\n\r\n allowBreakingChanges: ['feat', 'fix', 'refactor'],\r\n breakingPrefix: 'BREAKING CHANGE:',\r\n\r\n subjectLimit: 88,\r\n}\r\n`;\r\n await writeFileContent(resolve(cwd, \".cz-config.js\"), czConfig);\r\n generated.push(\".cz-config.js\");\r\n\r\n // ── commitlint.config.js(始终生成)──\r\n const commitlintConfig = `/*\r\n * Commitlint 配置\r\n * @generated by @robot-admin/git-standards\r\n *\r\n * 直接修改此文件即可自定义提交校验规则\r\n */\r\nmodule.exports = {\r\n extends: ['@commitlint/config-conventional'],\r\n rules: {\r\n 'type-enum': [\r\n 2,\r\n 'always',\r\n [\r\n 'wip', 'feat', 'fix', 'docs', 'style', 'refactor',\r\n 'perf', 'test', 'chore', 'revert', 'build', 'deps',\r\n ],\r\n ],\r\n 'subject-case': [0],\r\n },\r\n}\r\n`;\r\n await writeFileContent(\r\n resolve(cwd, \"commitlint.config.js\"),\r\n commitlintConfig,\r\n );\r\n generated.push(\"commitlint.config.js\");\r\n\r\n // ── .prettierrc.js(仅当 prettier 启用)──\r\n if (features.prettier) {\r\n const prettierConfig = `/*\r\n * Prettier 配置\r\n * @generated by @robot-admin/git-standards\r\n *\r\n * 直接修改此文件即可自定义格式化规则\r\n */\r\nmodule.exports = {\r\n $schema: 'https://json.schemastore.org/prettierrc',\r\n semi: false,\r\n singleQuote: true,\r\n printWidth: 80,\r\n tabWidth: 2,\r\n quoteProps: 'as-needed',\r\n trailingComma: 'es5',\r\n bracketSpacing: true,\r\n jsxSingleQuote: true,\r\n arrowParens: 'avoid',\r\n endOfLine: 'auto',\r\n htmlWhitespaceSensitivity: 'strict',\r\n vueIndentScriptAndStyle: true,\r\n singleAttributePerLine: true,\r\n}\r\n`;\r\n await writeFileContent(resolve(cwd, \".prettierrc.js\"), prettierConfig);\r\n generated.push(\".prettierrc.js\");\r\n }\r\n\r\n // ── eslint.config.ts(仅当 eslint 启用)──\r\n if (features.eslint) {\r\n // 根据选项动态构建完整的 eslint 配置模板\r\n const hasOxlint = features.oxlint;\r\n const hasPrettier = features.prettier;\r\n const hasJsdoc = eslintOpts.jsdoc;\r\n const isVue = eslintOpts.framework === \"vue\";\r\n const isTs = eslintOpts.typescript;\r\n\r\n // ── imports ──\r\n const importLines: string[] = [];\r\n if (isVue) importLines.push(\"import pluginVue from 'eslint-plugin-vue'\");\r\n if (isVue && isTs) {\r\n importLines.push(\r\n \"import {\\n defineConfigWithVueTs,\\n vueTsConfigs,\\n} from '@vue/eslint-config-typescript'\",\r\n );\r\n }\r\n if (hasOxlint)\r\n importLines.push(\"import oxlint from 'eslint-plugin-oxlint'\");\r\n if (hasPrettier && isVue) {\r\n importLines.push(\r\n \"import skipFormatting from '@vue/eslint-config-prettier/skip-formatting'\",\r\n );\r\n }\r\n if (hasJsdoc)\r\n importLines.push(\"import jsdocPlugin from 'eslint-plugin-jsdoc'\");\r\n\r\n // ── 文件扩展名 ──\r\n const fileExts = isTs ? \"js,ts,mts,tsx,vue\" : \"js,jsx,vue\";\r\n\r\n // ── Vue 2 废弃规则 ──\r\n const vue2DeprecationRules = isVue\r\n ? `\r\n //! 主动禁止 Vue 2 写法\r\n 'vue/no-deprecated-props-default-this': 'error',\r\n 'vue/no-deprecated-events-api': 'error',\r\n 'vue/no-deprecated-filter': 'error',\r\n 'vue/no-deprecated-functional-template': 'error',\r\n`\r\n : \"\";\r\n\r\n // ── Vue 组件规则 ──\r\n const vueComponentRules = isVue\r\n ? `\r\n // Vue 规范\r\n //! PascalCase 命名规范\r\n 'vue/component-name-in-template-casing': [\r\n 'error',\r\n 'PascalCase',\r\n {\r\n registeredComponentsOnly: false,\r\n ignores: [\r\n 'router-view',\r\n 'router-link',\r\n 'transition',\r\n 'draggable',\r\n '/^icon-/i',\r\n '/^C_/',\r\n '/^c_/',\r\n 'v-md-editor',\r\n ],\r\n },\r\n ],\r\n 'vue/multi-word-component-names': [\r\n 'error',\r\n {\r\n ignores: ['index'],\r\n },\r\n ],\r\n //! 禁止在模板中注册但未使用的组件\r\n 'vue/no-unused-components': 'error',\r\n${vue2DeprecationRules}`\r\n : \"\";\r\n\r\n // ── JSDoc 块 ──\r\n const jsdocBlock = hasJsdoc\r\n ? `\r\n //MARK: 自定义规则组(优先级最高)\r\n {\r\n plugins: {\r\n jsdoc: jsdocPlugin,\r\n },\r\n rules: {\r\n //! JSDoc 注释规则\r\n 'jsdoc/require-jsdoc': [\r\n 'error',\r\n {\r\n require: {\r\n FunctionDeclaration: true,\r\n MethodDefinition: true,\r\n ClassDeclaration: true,\r\n ArrowFunctionExpression: false,\r\n FunctionExpression: true,\r\n },\r\n contexts: [\r\n 'FunctionDeclaration',\r\n 'ClassDeclaration',\r\n 'ClassProperty',\r\n 'MethodDefinition',\r\n 'FunctionExpression',\r\n ],\r\n checkConstructors: true,\r\n checkGetters: true,\r\n checkSetters: true,\r\n },\r\n ],\r\n`\r\n : `\r\n // 自定义规则组\r\n {\r\n rules: {\r\n`;\r\n\r\n // ── 文件类型覆盖 ──\r\n const fileTypeOverrides = isTs\r\n ? `\r\n //MARK: 文件类型覆盖规则\r\n\r\n //! 变量使用规则\r\n {\r\n files: ['**/*.js'],\r\n rules: {\r\n 'no-unused-vars': 'error',\r\n '@typescript-eslint/no-unused-vars': 'off',\r\n },\r\n },\r\n {\r\n files: ['**/*.{ts,mts,tsx,vue}'],\r\n rules: {\r\n 'no-unused-vars': 'off',\r\n '@typescript-eslint/no-unused-vars': 'error',\r\n },\r\n },\r\n`\r\n : \"\";\r\n\r\n // ── JSDoc 白名单 ──\r\n const jsdocWhitelist = hasJsdoc\r\n ? `\r\n //MARK: JSDoc 白名单覆盖规则\r\n {\r\n files: [\r\n 'src/router/**/*.ts',\r\n 'src/stores/**/*.ts',\r\n 'src/views/**/components/*.vue',\r\n ],\r\n rules: {\r\n 'jsdoc/require-jsdoc': 'off',\r\n '@typescript-eslint/require-jsdoc': 'off',\r\n },\r\n },\r\n`\r\n : \"\";\r\n\r\n // ── 忽略白名单 ──\r\n const ignoreAssets = `\r\n //MARK: ESLINT 白名单配置组\r\n {\r\n name: 'app/ignore-assets',\r\n ignores: [\r\n 'src/assets/images/**/*',\r\n '**/*.d.ts',\r\n '**/auto-imports.d.ts',\r\n 'src/views/**/components/*.vue',\r\n 'scripts/**/*',\r\n ],\r\n },\r\n`;\r\n\r\n // ── TS 引号和表达式规则 ──\r\n const tsRules = isTs\r\n ? `\r\n //! 关闭与 oxlint 重复的 ESLint 规则\r\n 'no-undef': 'off',\r\n\r\n //! 引号规范\r\n '@typescript-eslint/quotes': ['error', 'single'],${\r\n isVue ? \"\\n 'vue/html-quotes': ['error', 'double'],\" : \"\"\r\n }\r\n\r\n //! TypeScript 安全\r\n '@typescript-eslint/no-explicit-any': 'off',\r\n '@typescript-eslint/ban-ts-comment': [\r\n 'error',\r\n {\r\n 'ts-ignore': 'allow-with-description',\r\n },\r\n ],\r\n\r\n //! 表达式规范\r\n '@typescript-eslint/no-unused-expressions': [\r\n 'error',\r\n {\r\n allowShortCircuit: true,\r\n allowTernary: false,\r\n allowTaggedTemplates: false,\r\n enforceForJSX: true,\r\n },\r\n ],\r\n`\r\n : \"\";\r\n\r\n // ── 组装 ──\r\n const useWrapper = isVue && isTs;\r\n const wrapperStart = useWrapper\r\n ? \"export default defineConfigWithVueTs(\"\r\n : \"export default [\";\r\n const wrapperEnd = useWrapper ? \")\" : \"]\";\r\n\r\n const oxlintLine = hasOxlint\r\n ? \"\\n ...oxlint.configs['flat/recommended'], // 高性能基础校验\\n\"\r\n : \"\";\r\n const vueLine = isVue\r\n ? `\\n //! 忽略转义字符\\n {\\n rules: {\\n 'no-useless-escape': 'off',\\n },\\n },\\n\\n pluginVue.configs['flat/essential'], // Vue 专用规则`\r\n : \"\";\r\n const tsLine =\r\n isVue && isTs ? \"\\n vueTsConfigs.recommended, // TS 专用规则\" : \"\";\r\n const skipLine = hasPrettier && isVue ? \"\\n skipFormatting\" : \"\";\r\n\r\n const eslintConfig = `/*\r\n * ESLint Flat Config\r\n * @generated by @robot-admin/git-standards\r\n *\r\n * 直接修改此文件即可自定义 ESLint 规则\r\n */\r\n${importLines.join(\"\\n\")}\r\n\r\n${wrapperStart}\r\n //MARK: 基础配置组\r\n {\r\n name: 'app/files-to-lint',\r\n files: ['**/*.{${fileExts}}'],\r\n },\r\n\r\n {\r\n name: 'app/files-to-ignore',\r\n ignores: [\r\n '**/dist/**',\r\n '**/dist-ssr/**',\r\n '**/coverage/**',\r\n ],\r\n },\r\n\r\n //MARK: 核心规则组(按优先级排序)\r\n${oxlintLine}${vueLine}${tsLine}\r\n${fileTypeOverrides}\r\n${jsdocBlock}${tsRules}\r\n //! 代码复杂度\r\n 'max-depth': ['error', 4],\r\n complexity: ['warn', 10],\r\n\r\n //! 异步代码规范\r\n 'no-await-in-loop': 'error',\r\n${vueComponentRules}\r\n //MARK: 格式规范\r\n 'no-irregular-whitespace': 'error',\r\n 'no-multi-spaces': 'error',\r\n 'space-infix-ops': 'error',\r\n 'array-bracket-spacing': ['error', 'never'],\r\n 'arrow-spacing': ['error', { before: true, after: true }],\r\n 'max-params': ['warn', 6],\r\n 'no-eval': 'error',\r\n 'prefer-const': 'warn',\r\n 'no-var': 'warn',\r\n 'prefer-destructuring': [\r\n 1,\r\n { object: true, array: false },\r\n ],\r\n 'no-duplicate-imports': 'error',\r\n },\r\n },\r\n${ignoreAssets}${jsdocWhitelist}${skipLine}\r\n${wrapperEnd}\r\n`;\r\n await writeFileContent(resolve(cwd, \"eslint.config.ts\"), eslintConfig);\r\n generated.push(\"eslint.config.ts\");\r\n }\r\n\r\n // ── .editorconfig(仅当 editorconfig 启用)──\r\n if (features.editorconfig) {\r\n const editorConfig = `# EditorConfig - 编辑器统一配置\r\n# @generated by @robot-admin/git-standards\r\n# 参考: https://editorconfig.org\r\n\r\nroot = true\r\n\r\n[*]\r\ncharset = utf-8\r\nindent_style = space\r\nindent_size = 2\r\nend_of_line = lf\r\ninsert_final_newline = true\r\ntrim_trailing_whitespace = true\r\n\r\n[*.md]\r\ntrim_trailing_whitespace = false\r\n\r\n[*.{yml,yaml}]\r\nindent_size = 2\r\n\r\n[Makefile]\r\nindent_style = tab\r\n`;\r\n await writeFileContent(resolve(cwd, \".editorconfig\"), editorConfig);\r\n generated.push(\".editorconfig\");\r\n }\r\n\r\n spinner.succeed(\r\n chalk.white(\"配置文件生成完成 \") +\r\n chalk.gray(`(${generated.join(\", \")})`),\r\n );\r\n } catch (error) {\r\n spinner.fail(chalk.red(\"配置文件生成失败\"));\r\n throw error;\r\n }\r\n}\r\n\r\n// ─── Husky 设置 ──────────────────────────────────────────────────\r\nasync function setupHusky(cwd: string, pm: string, features: FeatureSet) {\r\n const spinner = ora({\r\n text: chalk.gray(\"初始化 Husky...\"),\r\n prefixText: \" \",\r\n spinner: \"dots\",\r\n }).start();\r\n\r\n try {\r\n const execCmd = getExecCommand(pm as any);\r\n // husky init 会执行两件事:\r\n // 1. 调用 index.js default export → 创建 .husky/_/ 运行时基础设施 + 设置 core.hooksPath = .husky/_\r\n // 2. 创建 .husky/ 目录和默认 pre-commit 脚本\r\n //\r\n // .husky/_/ 是 Husky v9 的**核心运行时目录**(被 .gitignore 自动排除):\r\n // - _/h: 调度脚本,负责查找并执行 .husky/<hook-name> 用户脚本\r\n // - _/pre-commit, _/commit-msg 等: 包装脚本,Git 通过 core.hooksPath 实际调用这些\r\n // - 执行链: Git → .husky/_/<hook> → .husky/_/h → .husky/<hook>(用户脚本)\r\n //\r\n // ⚠️ 切勿删除 .husky/_/ 目录!它不是旧版遗留物,而是 hook 执行的必要基础设施。\r\n // 该目录由 prepare 脚本(husky)在每次 install 后自动重建。\r\n await execa(execCmd, [\"husky\", \"init\"], { cwd, stdio: \"pipe\" });\r\n\r\n // ── commit-msg hook(始终创建)──\r\n const commitMsg = `${execCmd} --no-install commitlint --edit \"$1\"\\n`;\r\n await writeExecutableFile(resolve(cwd, \".husky/commit-msg\"), commitMsg);\r\n\r\n const hooks: string[] = [\"commit-msg\"];\r\n\r\n // ── pre-commit hook(根据功能动态生成)──\r\n const needsPreCommit =\r\n features.eslint || features.lintStaged || features.oxlint;\r\n\r\n if (needsPreCommit) {\r\n const cmds: string[] = [];\r\n if (features.oxlint) {\r\n cmds.push(`${execCmd} oxlint --max-warnings 0`);\r\n }\r\n if (features.lintStaged) {\r\n cmds.push(`${execCmd} lint-staged`);\r\n } else if (features.eslint) {\r\n cmds.push(`${execCmd} eslint . --fix`);\r\n }\r\n await writeExecutableFile(\r\n resolve(cwd, \".husky/pre-commit\"),\r\n cmds.join(\"\\n\") + \"\\n\",\r\n );\r\n hooks.push(\"pre-commit\");\r\n } else {\r\n // 极简模式:移除 husky init 创建的默认 pre-commit\r\n const defaultPreCommit = resolve(cwd, \".husky/pre-commit\");\r\n if (existsSync(defaultPreCommit)) {\r\n unlinkSync(defaultPreCommit);\r\n }\r\n }\r\n\r\n spinner.succeed(\r\n chalk.white(\"Husky 初始化完成 \") + chalk.gray(`(${hooks.join(\", \")})`),\r\n );\r\n } catch (error) {\r\n spinner.fail(chalk.red(\"Husky 初始化失败\"));\r\n throw error;\r\n }\r\n}\r\n\r\n// ─── 更新 package.json ──────────────────────────────────────────\r\nasync function addPackageScripts(\r\n cwd: string,\r\n pm: string,\r\n features: FeatureSet,\r\n) {\r\n const spinner = ora({\r\n text: chalk.gray(\"更新 package.json...\"),\r\n prefixText: \" \",\r\n spinner: \"dots\",\r\n }).start();\r\n\r\n try {\r\n const packageJsonPath = resolve(cwd, \"package.json\");\r\n const packageJson = await readJsonFile(packageJsonPath);\r\n\r\n const scripts = packageJson.scripts || {};\r\n\r\n // cz 脚本(始终添加)\r\n scripts.cz = \"git-cz\";\r\n\r\n // prepare 脚本(husky 需要)\r\n scripts.prepare = \"husky\";\r\n\r\n // lint 脚本(仅当 eslint 启用)\r\n if (features.eslint) {\r\n scripts.lint = features.oxlint\r\n ? \"oxlint . --fix -D correctness --ignore-path .gitignore && eslint . --fix\"\r\n : \"eslint . --fix\";\r\n }\r\n\r\n // format 脚本(仅当 prettier 启用)\r\n if (features.prettier) {\r\n scripts.format = \"prettier --write src/\";\r\n }\r\n\r\n // commitizen config(始终添加)\r\n const czConfig = {\r\n commitizen: { path: \"node_modules/cz-customizable\" },\r\n };\r\n\r\n const updates: Record<string, any> = { scripts, config: czConfig };\r\n\r\n // lint-staged config(仅当 lintStaged 启用)\r\n if (features.lintStaged) {\r\n updates[\"lint-staged\"] = generateLintStagedConfig({\r\n eslint: features.eslint,\r\n oxlint: features.oxlint,\r\n prettier: features.prettier,\r\n });\r\n }\r\n\r\n await updatePackageJson(updates, cwd);\r\n\r\n const parts = [\"scripts\"];\r\n if (features.lintStaged) parts.push(\"lint-staged\");\r\n spinner.succeed(\r\n chalk.white(\"package.json 更新完成 \") +\r\n chalk.gray(`(${parts.join(\" + \")})`),\r\n );\r\n } catch (error) {\r\n spinner.fail(chalk.red(\"package.json 更新失败\"));\r\n throw error;\r\n }\r\n}\r\n\r\n// ─── 完成输出 ────────────────────────────────────────────────────\r\nfunction printCompletion(pm: string, features: FeatureSet) {\r\n console.log();\r\n console.log(S.LINE);\r\n console.log(` ${S.OK} ${chalk.green.bold(\"初始化完成!\")}`);\r\n console.log(S.LINE);\r\n console.log();\r\n console.log(` ${chalk.bold(\"快速开始:\")}`);\r\n console.log();\r\n console.log(` ${S.DOT} 提交代码 ${chalk.cyan(`${pm} run cz`)}`);\r\n if (features.eslint) {\r\n console.log(` ${S.DOT} 检查代码 ${chalk.cyan(`${pm} run lint`)}`);\r\n }\r\n if (features.prettier) {\r\n console.log(` ${S.DOT} 格式化 ${chalk.cyan(`${pm} run format`)}`);\r\n }\r\n console.log();\r\n console.log(\r\n ` ${S.INFO} ${chalk.gray(\"全局安装 commitizen 后可直接使用 git cz 提交\")}`,\r\n );\r\n console.log(` ${S.DOT} ${chalk.gray(`npm install -g commitizen`)}`);\r\n console.log();\r\n console.log(\r\n ` ${S.INFO} ${chalk.gray(\"所有配置文件均支持覆盖扩展,详见 README.md\")}`,\r\n );\r\n console.log();\r\n}\r\n","/*\r\n * @Author: ChenYu ycyplus@gmail.com\r\n * @Date: 2026-02-13\r\n * @Description: 包管理器检测工具\r\n * Copyright (c) 2026 by CHENY, All Rights Reserved.\r\n */\r\n\r\nimport { existsSync } from \"node:fs\";\r\nimport { resolve } from \"node:path\";\r\n\r\nexport type PackageManager = \"npm\" | \"yarn\" | \"pnpm\" | \"bun\";\r\n\r\n/**\r\n * 检测项目使用的包管理器\r\n */\r\nexport async function detectPackageManager(\r\n cwd: string = process.cwd(),\r\n): Promise<PackageManager> {\r\n // 检测 lockfile\r\n if (\r\n existsSync(resolve(cwd, \"bun.lockb\")) ||\r\n existsSync(resolve(cwd, \"bun.lock\"))\r\n ) {\r\n return \"bun\";\r\n }\r\n if (existsSync(resolve(cwd, \"pnpm-lock.yaml\"))) {\r\n return \"pnpm\";\r\n }\r\n if (existsSync(resolve(cwd, \"yarn.lock\"))) {\r\n return \"yarn\";\r\n }\r\n if (existsSync(resolve(cwd, \"package-lock.json\"))) {\r\n return \"npm\";\r\n }\r\n\r\n // 默认返回 npm\r\n return \"npm\";\r\n}\r\n\r\n/**\r\n * 获取安装命令\r\n */\r\nexport function getInstallCommand(pm: PackageManager): string {\r\n const commands = {\r\n npm: \"npm install --save-dev\",\r\n yarn: \"yarn add --dev\",\r\n pnpm: \"pnpm add -D\",\r\n bun: \"bun add --dev\",\r\n };\r\n return commands[pm];\r\n}\r\n\r\n/**\r\n * 获取执行命令\r\n */\r\nexport function getExecCommand(pm: PackageManager): string {\r\n const commands = {\r\n npm: \"npx --no\",\r\n yarn: \"yarn\",\r\n pnpm: \"pnpm dlx\",\r\n bun: \"bunx\",\r\n };\r\n return commands[pm];\r\n}\r\n\r\n/**\r\n * 获取包管理器的显示名称\r\n */\r\nexport function getPackageManagerName(pm: PackageManager): string {\r\n const names = {\r\n npm: \"npm\",\r\n yarn: \"Yarn\",\r\n pnpm: \"pnpm\",\r\n bun: \"Bun\",\r\n };\r\n return names[pm];\r\n}\r\n","/*\r\n * @Author: ChenYu ycyplus@gmail.com\r\n * @Date: 2026-02-13\r\n * @Description: Git 工具函数\r\n * Copyright (c) 2026 by CHENY, All Rights Reserved.\r\n */\r\n\r\nimport { existsSync } from \"node:fs\";\r\nimport { resolve } from \"node:path\";\r\nimport { execa } from \"execa\";\r\n\r\n/**\r\n * 检查是否在 Git 仓库中\r\n */\r\nexport function isGitRepository(cwd: string = process.cwd()): boolean {\r\n return existsSync(resolve(cwd, \".git\"));\r\n}\r\n\r\n/**\r\n * 初始化 Git 仓库\r\n */\r\nexport async function initGitRepository(\r\n cwd: string = process.cwd(),\r\n): Promise<void> {\r\n if (!isGitRepository(cwd)) {\r\n await execa(\"git\", [\"init\"], { cwd });\r\n }\r\n}\r\n","/*\r\n * @Author: ChenYu ycyplus@gmail.com\r\n * @Date: 2026-02-13\r\n * @Description: 文件操作工具\r\n * Copyright (c) 2026 by CHENY, All Rights Reserved.\r\n */\r\n\r\nimport { existsSync, chmodSync } from \"node:fs\";\r\nimport { readFile, writeFile, mkdir } from \"node:fs/promises\";\r\nimport { resolve, dirname } from \"node:path\";\r\n\r\n/**\r\n * 检查文件是否存在\r\n */\r\nexport function fileExists(filePath: string): boolean {\r\n return existsSync(filePath);\r\n}\r\n\r\n/**\r\n * 读取文件内容\r\n */\r\nexport async function readFileContent(filePath: string): Promise<string> {\r\n return await readFile(filePath, \"utf-8\");\r\n}\r\n\r\n/**\r\n * 写入文件内容\r\n */\r\nexport async function writeFileContent(\r\n filePath: string,\r\n content: string,\r\n): Promise<void> {\r\n const dir = dirname(filePath);\r\n if (!existsSync(dir)) {\r\n await mkdir(dir, { recursive: true });\r\n }\r\n await writeFile(filePath, content, \"utf-8\");\r\n}\r\n\r\n/**\r\n * 写入可执行文件(自动设置 chmod 755 执行权限)\r\n * 用于 Husky Hook 等需要执行权限的文件\r\n */\r\nexport async function writeExecutableFile(\r\n filePath: string,\r\n content: string,\r\n): Promise<void> {\r\n await writeFileContent(filePath, content);\r\n try {\r\n chmodSync(filePath, 0o755);\r\n } catch {\r\n // Windows 环境下 chmod 可能不生效,忽略错误\r\n }\r\n}\r\n\r\n/**\r\n * 读取并解析 JSON 文件\r\n */\r\nexport async function readJsonFile<T = any>(filePath: string): Promise<T> {\r\n const content = await readFileContent(filePath);\r\n return JSON.parse(content) as T;\r\n}\r\n\r\n/**\r\n * 写入 JSON 文件\r\n */\r\nexport async function writeJsonFile(\r\n filePath: string,\r\n data: any,\r\n pretty: boolean = true,\r\n): Promise<void> {\r\n const content = pretty\r\n ? JSON.stringify(data, null, 2) + \"\\n\"\r\n : JSON.stringify(data);\r\n await writeFileContent(filePath, content);\r\n}\r\n\r\n/**\r\n * 更新 package.json\r\n */\r\nexport async function updatePackageJson(\r\n updates: Record<string, any>,\r\n cwd: string = process.cwd(),\r\n): Promise<void> {\r\n const packageJsonPath = resolve(cwd, \"package.json\");\r\n const packageJson = await readJsonFile(packageJsonPath);\r\n const updated = { ...packageJson, ...updates };\r\n await writeJsonFile(packageJsonPath, updated);\r\n}\r\n","/*\r\n * @Author: ChenYu ycyplus@gmail.com\r\n * @Date: 2026-02-13\r\n * @Description: Lint-staged 配置生成器\r\n * Copyright (c) 2026 by CHENY, All Rights Reserved.\r\n */\r\n\r\nexport interface LintStagedOptions {\r\n /**\r\n * 是否启用 ESLint(默认 true)\r\n */\r\n eslint?: boolean;\r\n /**\r\n * 是否启用 Oxlint\r\n */\r\n oxlint?: boolean;\r\n /**\r\n * 是否启用 Prettier\r\n */\r\n prettier?: boolean;\r\n /**\r\n * 文件 glob 模式\r\n */\r\n filePatterns?: {\r\n code?: string;\r\n markup?: string;\r\n };\r\n}\r\n\r\n/**\r\n * 创建 Lint-staged 配置\r\n */\r\nexport function createLintStagedConfig(options: LintStagedOptions = {}) {\r\n const codePattern =\r\n options.filePatterns?.code || \"src/**/*.{js,jsx,ts,tsx,vue}\";\r\n const markupPattern = options.filePatterns?.markup || \"*.{json,md,yml,yaml}\";\r\n\r\n const codeCommands: string[] = [];\r\n\r\n // Oxlint 优先(性能最优)\r\n if (options.oxlint !== false) {\r\n codeCommands.push(\"oxlint --max-warnings 0 --deny-warnings\");\r\n }\r\n\r\n // ESLint(默认启用,可通过 eslint: false 关闭)\r\n if (options.eslint !== false) {\r\n codeCommands.push(\"eslint --fix --no-cache\");\r\n }\r\n\r\n // Prettier\r\n if (options.prettier !== false) {\r\n codeCommands.push(\"prettier --write\");\r\n }\r\n\r\n // 如果没有任何代码检查命令,不生成代码模式配置\r\n const config: Record<string, string[]> = {};\r\n\r\n if (codeCommands.length > 0) {\r\n config[codePattern] = codeCommands;\r\n }\r\n\r\n // 为标记文件添加 Prettier\r\n if (options.prettier !== false) {\r\n config[markupPattern] = [\"prettier --write\"];\r\n }\r\n\r\n return config;\r\n}\r\n\r\n/**\r\n * 生成 lint-staged 配置(用于 package.json)\r\n */\r\nexport function generateLintStagedConfig(\r\n options: LintStagedOptions = {},\r\n): Record<string, string[]> {\r\n return createLintStagedConfig(options);\r\n}\r\n"],"mappings":"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","names":["import_node_path","import_node_fs","import_execa","import_node_fs","import_node_path","import_node_fs","import_node_path","chalk","ora","chalk","ora"]}
package/dist/cli/init.js CHANGED
@@ -1,6 +1,6 @@
1
1
  // src/cli/init.ts
2
2
  import { resolve as resolve4 } from "path";
3
- import { unlinkSync, existsSync as existsSync4, rmSync } from "fs";
3
+ import { unlinkSync, existsSync as existsSync4 } from "fs";
4
4
  import chalk from "chalk";
5
5
  import ora from "ora";
6
6
  import { execa as execa2 } from "execa";
@@ -65,7 +65,7 @@ async function initGitRepository(cwd = process.cwd()) {
65
65
  }
66
66
 
67
67
  // src/utils/file.ts
68
- import { existsSync as existsSync3 } from "fs";
68
+ import { existsSync as existsSync3, chmodSync } from "fs";
69
69
  import { readFile, writeFile, mkdir } from "fs/promises";
70
70
  import { resolve as resolve3, dirname } from "path";
71
71
  async function readFileContent(filePath) {
@@ -78,6 +78,13 @@ async function writeFileContent(filePath, content) {
78
78
  }
79
79
  await writeFile(filePath, content, "utf-8");
80
80
  }
81
+ async function writeExecutableFile(filePath, content) {
82
+ await writeFileContent(filePath, content);
83
+ try {
84
+ chmodSync(filePath, 493);
85
+ } catch {
86
+ }
87
+ }
81
88
  async function readJsonFile(filePath) {
82
89
  const content = await readFileContent(filePath);
83
90
  return JSON.parse(content);
@@ -887,13 +894,9 @@ async function setupHusky(cwd, pm, features) {
887
894
  try {
888
895
  const execCmd = getExecCommand(pm);
889
896
  await execa2(execCmd, ["husky", "init"], { cwd, stdio: "pipe" });
890
- const legacyDir = resolve4(cwd, ".husky/_");
891
- if (existsSync4(legacyDir)) {
892
- rmSync(legacyDir, { recursive: true, force: true });
893
- }
894
897
  const commitMsg = `${execCmd} --no-install commitlint --edit "$1"
895
898
  `;
896
- await writeFileContent(resolve4(cwd, ".husky/commit-msg"), commitMsg);
899
+ await writeExecutableFile(resolve4(cwd, ".husky/commit-msg"), commitMsg);
897
900
  const hooks = ["commit-msg"];
898
901
  const needsPreCommit = features.eslint || features.lintStaged || features.oxlint;
899
902
  if (needsPreCommit) {
@@ -906,7 +909,7 @@ async function setupHusky(cwd, pm, features) {
906
909
  } else if (features.eslint) {
907
910
  cmds.push(`${execCmd} eslint . --fix`);
908
911
  }
909
- await writeFileContent(
912
+ await writeExecutableFile(
910
913
  resolve4(cwd, ".husky/pre-commit"),
911
914
  cmds.join("\n") + "\n"
912
915
  );