create-einja-app 0.2.2 → 0.2.4
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.
- package/dist/cli.js +1 -1
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -487,7 +487,7 @@ async function execPostSetup(config, targetPath, options) {
|
|
|
487
487
|
if (config.setupEinjaCli) {
|
|
488
488
|
const einjaSpinner = ora("@einja/dev-cli \u3092\u521D\u671F\u5316\u4E2D...").start();
|
|
489
489
|
try {
|
|
490
|
-
await execa("npx", ["@einja/dev-cli", "init", "--force"], { cwd: targetPath });
|
|
490
|
+
await execa("npx", ["@einja/dev-cli", "init", "--force", "--no-backup"], { cwd: targetPath });
|
|
491
491
|
einjaSpinner.succeed("@einja/dev-cli \u3092\u521D\u671F\u5316\u3057\u307E\u3057\u305F");
|
|
492
492
|
} catch (error2) {
|
|
493
493
|
einjaSpinner.fail("@einja/dev-cli \u306E\u521D\u671F\u5316\u306B\u5931\u6557\u3057\u307E\u3057\u305F");
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli.ts","../src/commands/create.ts","../src/prompts/project.ts","../src/generators/template.ts","../src/utils/fs.ts","../src/utils/logger.ts","../src/generators/post-setup.ts","../src/commands/setup.ts","../src/prompts/setup.ts","../src/generators/tools/direnv.ts","../src/generators/tools/dotenvx.ts","../src/utils/package-json.ts","../src/generators/tools/volta.ts","../src/generators/tools/biome.ts","../src/generators/tools/husky.ts","../src/commands/add.ts","../src/prompts/add.ts","../src/generators/partials/packages.ts","../src/utils/merger.ts","../src/generators/partials/apps.ts","../src/generators/partials/config.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport { readFileSync } from \"node:fs\";\nimport { fileURLToPath } from \"node:url\";\nimport { dirname, join } from \"node:path\";\nimport { createCommand } from \"./commands/create.js\";\nimport { setupCommand } from \"./commands/setup.js\";\nimport { addCommand } from \"./commands/add.js\";\n\n// package.jsonからバージョン情報を読み込み\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\nconst packageJsonPath = join(__dirname, \"../package.json\");\nconst packageJson = JSON.parse(readFileSync(packageJsonPath, \"utf-8\"));\n\nconst program = new Command();\n\nprogram\n .name(\"create-einja-app\")\n .description(\"CLI tool to create new projects with Einja Management Template\")\n .version(packageJson.version);\n\n// createコマンド\nprogram\n .argument(\"[project-name]\", \"Project name\")\n .option(\"--skip-git\", \"Skip git initialization\")\n .option(\"--skip-install\", \"Skip package installation\")\n .option(\"-y, --yes\", \"Skip interactive prompts\")\n .action(\n async (\n projectName: string | undefined,\n options: {\n skipGit?: boolean;\n skipInstall?: boolean;\n yes?: boolean;\n }\n ) => {\n await createCommand(projectName, options);\n }\n );\n\n// setupコマンド\nprogram\n .command(\"setup\")\n .description(\"Setup tools for existing project\")\n .action(async () => {\n await setupCommand();\n });\n\n// addコマンド\nprogram\n .command(\"add\")\n .description(\"Add einja components to existing monorepo\")\n .option(\"-y, --yes\", \"Skip prompts and use defaults (select all)\")\n .option(\"--all\", \"Select all components (same as -y)\")\n .option(\"--dry-run\", \"Preview changes without making them\")\n .action(\n async (options: { yes?: boolean; all?: boolean; dryRun?: boolean }) => {\n await addCommand({\n skipPrompts: options.yes || options.all || false,\n dryRun: options.dryRun || false,\n });\n }\n );\n\nprogram.parse();\n","import { existsSync, readdirSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport ora from \"ora\";\nimport { promptProjectConfig, type ProjectConfig } from \"../prompts/project.js\";\nimport { generateTemplate } from \"../generators/template.js\";\nimport { execPostSetup } from \"../generators/post-setup.js\";\nimport * as logger from \"../utils/logger.js\";\n\n/**\n * ディレクトリが空かどうかを確認\n * @param dirPath - ディレクトリパス\n * @returns 空の場合true、存在しないかファイルがある場合false\n */\nfunction isDirectoryEmpty(dirPath: string): boolean {\n if (!existsSync(dirPath)) {\n return true;\n }\n const files = readdirSync(dirPath);\n // .git, .DS_Store などの隠しファイルは無視(空のGitリポジトリは空とみなす)\n const significantFiles = files.filter(\n (f) => !f.startsWith(\".\")\n );\n return significantFiles.length === 0;\n}\n\n/**\n * CreateOptions型\n * createコマンドのオプション\n */\ninterface CreateOptions {\n skipGit?: boolean;\n skipInstall?: boolean;\n yes?: boolean;\n}\n\n/**\n * プロジェクト名のバリデーション\n * @param projectName - プロジェクト名\n * @returns エラーメッセージ(問題なければundefined)\n */\nfunction validateProjectName(projectName: string): string | undefined {\n const regex = /^[a-zA-Z][a-zA-Z0-9_-]{0,49}$/;\n if (!regex.test(projectName)) {\n return \"プロジェクト名は英字で始まり、英数字・ハイフン・アンダースコアのみ使用できます(1〜50文字)\";\n }\n return undefined;\n}\n\n/**\n * プロジェクトディレクトリの存在確認\n * @param targetPath - ターゲットパス\n * @returns 存在する場合true\n */\nfunction checkProjectExists(targetPath: string): boolean {\n return existsSync(targetPath);\n}\n\n\n/**\n * createコマンドの実装\n * @param projectName - プロジェクト名(オプション)\n * @param options - コマンドオプション\n */\nexport async function createCommand(\n projectName: string | undefined,\n options: CreateOptions\n): Promise<void> {\n try {\n // プロンプトで設定収集\n let config: ProjectConfig;\n\n if (options.yes && projectName) {\n // --yes オプション: デフォルト値を使用\n const error = validateProjectName(projectName);\n if (error) {\n logger.error(error);\n process.exit(1);\n }\n\n config = {\n projectName,\n packageScope: \"@repo\",\n template: \"default\",\n authMethod: \"default\",\n tools: {\n direnv: true,\n dotenvx: true,\n volta: true,\n biome: true,\n husky: true,\n },\n setupEinjaCli: true,\n worktreeConfig: undefined,\n useCurrentDir: false,\n };\n\n logger.info(`プロジェクト名: ${config.projectName}`);\n logger.info(`テンプレート: ${config.template}`);\n logger.info(`認証方式: ${config.authMethod}`);\n } else {\n // 対話式プロンプト\n config = await promptProjectConfig(projectName);\n }\n\n // ターゲットパスの解決\n const targetPath = config.useCurrentDir\n ? process.cwd()\n : resolve(process.cwd(), config.projectName);\n\n // ディレクトリの確認\n if (config.useCurrentDir) {\n // カレントディレクトリに展開する場合、空かどうか確認\n if (!isDirectoryEmpty(targetPath)) {\n logger.error(\"現在のディレクトリにファイルが存在します\");\n logger.info(\"空のディレクトリで実行するか、サブディレクトリを作成してください\");\n process.exit(1);\n }\n } else {\n // サブディレクトリを作成する場合、存在確認\n if (checkProjectExists(targetPath)) {\n logger.error(`ディレクトリ '${config.projectName}' は既に存在します`);\n logger.info(\"別の名前を指定するか、既存ディレクトリを削除してください\");\n process.exit(1);\n }\n }\n\n // テンプレート展開\n const spinner = ora(\"プロジェクトを作成中...\").start();\n\n try {\n await generateTemplate(config, targetPath);\n spinner.succeed(\"プロジェクトを作成しました\");\n } catch (error) {\n spinner.fail(\"プロジェクトの作成に失敗しました\");\n throw error;\n }\n\n // 生成後セットアップ実行\n await execPostSetup(config, targetPath, {\n skipGit: options.skipGit,\n skipInstall: options.skipInstall,\n });\n } catch (error) {\n logger.error(\"エラーが発生しました:\");\n if (error instanceof Error) {\n logger.error(error.message);\n } else {\n logger.error(String(error));\n }\n process.exit(1);\n }\n}\n","import inquirer from \"inquirer\";\nimport type { ProjectConfig, WorktreeConfig, App } from \"../types/index.js\";\n\nexport type { ProjectConfig, WorktreeConfig, App };\n\n/**\n * プロジェクト作成用プロンプトを実行\n * @param defaultProjectName - デフォルトのプロジェクト名\n * @returns ProjectConfig - プロジェクト設定\n */\nexport async function promptProjectConfig(\n defaultProjectName?: string\n): Promise<ProjectConfig> {\n const answers = await inquirer.prompt([\n {\n type: \"input\",\n name: \"projectName\",\n message: \"プロジェクト名:\",\n default: defaultProjectName || \"my-project\",\n validate: (input: string): boolean | string => {\n // 英数字・ハイフン・アンダースコアのみ許可、先頭は英字、1〜50文字\n const regex = /^[a-zA-Z][a-zA-Z0-9_-]{0,49}$/;\n if (!regex.test(input)) {\n return \"プロジェクト名は英字で始まり、英数字・ハイフン・アンダースコアのみ使用できます(1〜50文字)\";\n }\n return true;\n },\n },\n {\n type: \"confirm\",\n name: \"useCurrentDir\",\n message: \"今いるディレクトリに直接作成しますか?(Noならサブディレクトリを作成)\",\n default: false,\n },\n {\n type: \"input\",\n name: \"packageScope\",\n message: \"パッケージスコープ:\",\n default: \"@repo\",\n validate: (input: string): boolean | string => {\n // @で始まり、英数字・ハイフン・アンダースコアのみ許可\n const regex = /^@[a-zA-Z][a-zA-Z0-9_-]{0,49}$/;\n if (!regex.test(input)) {\n return \"パッケージスコープは@で始まり、英数字・ハイフン・アンダースコアのみ使用できます\";\n }\n return true;\n },\n },\n {\n type: \"list\",\n name: \"authMethod\",\n message: \"認証機能:\",\n choices: [\n { name: \"NextAuth.js を使用\", value: \"default\" },\n { name: \"なし(認証ファイルを除外)\", value: \"none\" },\n ],\n default: \"default\",\n },\n {\n type: \"confirm\",\n name: \"setupEinjaCli\",\n message: \"@einja/dev-cli を自動セットアップしますか?\",\n default: true,\n },\n {\n type: \"confirm\",\n name: \"customizeWorktree\",\n message: \"Worktree設定をカスタマイズしますか?\",\n default: false,\n },\n ]);\n\n // ツールは全て有効(固定)\n const tools = {\n direnv: true,\n dotenvx: true,\n volta: true,\n biome: true,\n husky: true,\n };\n\n let worktreeConfig: WorktreeConfig | undefined;\n\n // Worktree設定カスタマイズ\n if (answers.customizeWorktree) {\n const worktreeAnswers = await inquirer.prompt([\n {\n type: \"input\",\n name: \"postgresPort\",\n message: \"PostgreSQLポート番号:\",\n default: \"25432\",\n validate: (input: string): boolean | string => {\n const port = Number.parseInt(input, 10);\n if (Number.isNaN(port) || port < 1024 || port > 65535) {\n return \"ポート番号は1024〜65535の範囲で指定してください\";\n }\n return true;\n },\n },\n {\n type: \"input\",\n name: \"containerName\",\n message: \"Dockerコンテナ名:\",\n default: `${answers.projectName}-postgres`,\n },\n {\n type: \"input\",\n name: \"appId\",\n message: \"アプリケーションID:\",\n default: \"web\",\n },\n {\n type: \"input\",\n name: \"portRangeStart\",\n message: \"アプリポート範囲開始:\",\n default: \"3000\",\n validate: (input: string): boolean | string => {\n const port = Number.parseInt(input, 10);\n if (Number.isNaN(port) || port < 1024 || port > 65535) {\n return \"ポート番号は1024〜65535の範囲で指定してください\";\n }\n return true;\n },\n },\n {\n type: \"input\",\n name: \"rangeSize\",\n message: \"ポート範囲サイズ:\",\n default: \"1000\",\n validate: (input: string): boolean | string => {\n const size = Number.parseInt(input, 10);\n if (Number.isNaN(size) || size < 1 || size > 10000) {\n return \"範囲サイズは1〜10000の範囲で指定してください\";\n }\n return true;\n },\n },\n ]);\n\n worktreeConfig = {\n postgres: {\n port: Number.parseInt(worktreeAnswers.postgresPort, 10),\n containerName: worktreeAnswers.containerName,\n },\n apps: [\n {\n id: worktreeAnswers.appId,\n portRangeStart: Number.parseInt(worktreeAnswers.portRangeStart, 10),\n rangeSize: Number.parseInt(worktreeAnswers.rangeSize, 10),\n },\n ],\n };\n }\n\n return {\n projectName: answers.projectName,\n packageScope: answers.packageScope,\n template: \"default\" as const,\n authMethod: answers.authMethod,\n tools,\n setupEinjaCli: answers.setupEinjaCli,\n worktreeConfig,\n useCurrentDir: answers.useCurrentDir,\n };\n}\n","import fsExtra from \"fs-extra\";\nconst { copySync, readFileSync, writeFileSync, existsSync, removeSync } = fsExtra;\nimport { glob } from \"glob\";\nimport { dirname, join, relative } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport type { ProjectConfig } from \"../prompts/project.js\";\nimport { ensureDir } from \"../utils/fs.js\";\nimport * as logger from \"../utils/logger.js\";\n\n/**\n * TemplateVariables型\n * テンプレート変数(プレースホルダー置換用)\n */\nexport interface TemplateVariables {\n projectName: string;\n packageName: string;\n description: string;\n}\n\n/**\n * テンプレートディレクトリのパスを取得\n * @param templateName - テンプレート名\n * @returns テンプレートディレクトリパス\n */\nfunction getTemplatePath(templateName: string): string {\n const __filename = fileURLToPath(import.meta.url);\n const __dirname = dirname(__filename);\n\n // バンドル後(dist/cli.js)とソース実行(src/generators/template.ts)の両方に対応\n // dist/cli.js -> ../templates/ (1階層上)\n // src/generators/template.ts -> ../../templates/ (2階層上)\n const distPath = join(__dirname, \"../templates\", templateName);\n const srcPath = join(__dirname, \"../../templates\", templateName);\n\n if (existsSync(distPath)) {\n return distPath;\n }\n if (existsSync(srcPath)) {\n return srcPath;\n }\n\n // どちらも存在しない場合はdistPathを返す(エラーメッセージ用)\n return distPath;\n}\n\n/**\n * 認証方式に応じた除外パターンを取得\n * @param authMethod - 認証方式\n * @returns 除外パターン配列\n */\nfunction getAuthExcludePatterns(authMethod: string): string[] {\n if (authMethod === \"none\") {\n return [\n \"**/api/auth/**\",\n \"**/packages/auth/**\",\n \"**/signin/**\",\n \"**/signup/**\",\n ];\n }\n return [];\n}\n\n/**\n * ファイル内容のプレースホルダー変数を置換\n * @param content - ファイル内容\n * @param variables - 置換する変数\n * @returns 置換後の内容\n */\nfunction replacePlaceholders(\n content: string,\n variables: TemplateVariables\n): string {\n let result = content;\n\n // {{projectName}} の置換\n result = result.replaceAll(\"{{projectName}}\", variables.projectName);\n\n // {{packageName}}/ の置換(長いパターンを先に置換)\n result = result.replaceAll(\"{{packageName}}/\", `${variables.packageName}/`);\n\n // {{packageName}} の置換\n result = result.replaceAll(\"{{packageName}}\", variables.packageName);\n\n // {{description}} の置換\n result = result.replaceAll(\"{{description}}\", variables.description);\n\n // @repo/ の置換(パッケージスコープ)\n result = result.replaceAll(\"@repo/\", `${variables.packageName}/`);\n\n return result;\n}\n\n/**\n * ファイルの変数置換処理\n * @param filePath - ファイルパス\n * @param variables - 置換する変数\n */\nfunction processFileVariables(\n filePath: string,\n variables: TemplateVariables\n): void {\n // バイナリファイルは処理しない\n const binaryExtensions = [\".png\", \".jpg\", \".jpeg\", \".gif\", \".ico\", \".woff\", \".woff2\", \".ttf\", \".eot\"];\n if (binaryExtensions.some((ext) => filePath.endsWith(ext))) {\n return;\n }\n\n try {\n const content = readFileSync(filePath, \"utf-8\");\n const replaced = replacePlaceholders(content, variables);\n\n if (content !== replaced) {\n writeFileSync(filePath, replaced, \"utf-8\");\n }\n } catch (error) {\n // 読み込みに失敗した場合はスキップ(バイナリファイル等)\n logger.warn(`変数置換をスキップ: ${filePath}`);\n }\n}\n\n/**\n * .templateファイルのリネーム処理\n * @param targetPath - ターゲットディレクトリパス\n */\nfunction renameTemplateFiles(targetPath: string): void {\n const templateFiles = glob.sync(\"**/*.template\", {\n cwd: targetPath,\n absolute: true,\n dot: true,\n });\n\n for (const file of templateFiles) {\n const newPath = file.replace(/\\.template$/, \"\");\n copySync(file, newPath);\n removeSync(file);\n }\n}\n\n/**\n * gitignoreファイルをリネーム処理(gitignore → .gitignore)\n * @param targetPath - ターゲットディレクトリパス\n */\nfunction renameSpecialFiles(targetPath: string): void {\n const gitignoreFiles = glob.sync(\"**/gitignore\", {\n cwd: targetPath,\n absolute: true,\n dot: true,\n });\n\n for (const file of gitignoreFiles) {\n const dir = dirname(file);\n const newPath = join(dir, \".gitignore\");\n\n if (existsSync(file)) {\n copySync(file, newPath);\n removeSync(file);\n }\n }\n}\n\n/**\n * 認証方式に応じたファイル除外処理\n * @param targetPath - ターゲットディレクトリパス\n * @param authMethod - 認証方式\n */\nfunction excludeAuthFiles(targetPath: string, authMethod: string): void {\n const excludePatterns = getAuthExcludePatterns(authMethod);\n\n if (excludePatterns.length === 0) {\n return;\n }\n\n logger.info(\"認証方式に応じたファイルを除外中...\");\n\n for (const pattern of excludePatterns) {\n const files = glob.sync(pattern, {\n cwd: targetPath,\n absolute: true,\n dot: true,\n });\n\n for (const file of files) {\n removeSync(file);\n }\n }\n}\n\n/**\n * テンプレートを展開\n * @param config - プロジェクト設定\n * @param targetPath - ターゲットディレクトリパス\n */\nexport async function generateTemplate(\n config: ProjectConfig,\n targetPath: string\n): Promise<void> {\n const templatePath = getTemplatePath(config.template);\n\n // テンプレートディレクトリの存在確認\n if (!existsSync(templatePath)) {\n throw new Error(`テンプレートが見つかりません: ${config.template}`);\n }\n\n logger.info(\"テンプレートをコピー中...\");\n\n // ターゲットディレクトリの作成\n await ensureDir(targetPath);\n\n // テンプレートファイルをコピー\n copySync(templatePath, targetPath, {\n filter: (src: string): boolean => {\n const relativePath = relative(templatePath, src);\n\n // 除外パターン(ディレクトリ名やファイル名として完全一致するもの)\n // 注意: .env.*ファイルはテンプレートに含め、pnpm env:updateで再設定する\n const excludePatterns = [\n \"node_modules\",\n \".git\",\n \".next\",\n \".turbo\",\n \"out\",\n \"dist\",\n \"logs\",\n \".env\", // フェイルセーフ(暗号化キーファイル)\n \".DS_Store\",\n \"Thumbs.db\",\n \"coverage\",\n ];\n\n // ファイル拡張子パターン(*.log など)\n const excludeExtensions = [\".log\"];\n\n // パスセグメントに分割(/ または \\ で分割)\n const pathSegments = relativePath.split(/[/\\\\]/);\n\n // パスセグメント単位で完全一致チェック\n // これにより \"out\" は \"out/\" ディレクトリにマッチするが\n // \"logout-button.tsx\" にはマッチしない\n const matchesExcludePattern = excludePatterns.some((pattern) =>\n pathSegments.includes(pattern)\n );\n\n // 拡張子チェック\n const matchesExtension = excludeExtensions.some((ext) =>\n relativePath.endsWith(ext)\n );\n\n return !matchesExcludePattern && !matchesExtension;\n },\n });\n\n // 認証方式に応じたファイル除外\n excludeAuthFiles(targetPath, config.authMethod);\n\n // .templateファイルのリネーム\n renameTemplateFiles(targetPath);\n\n // gitignore → .gitignore リネーム\n renameSpecialFiles(targetPath);\n\n // 変数置換\n logger.info(\"プレースホルダー変数を置換中...\");\n\n const variables: TemplateVariables = {\n projectName: config.projectName,\n packageName: config.packageScope,\n description: `${config.projectName} - Einja Management Template`,\n };\n\n const allFiles = glob.sync(\"**/*\", {\n cwd: targetPath,\n absolute: true,\n nodir: true,\n dot: true,\n });\n\n for (const file of allFiles) {\n processFileVariables(file, variables);\n }\n\n logger.success(\"テンプレート展開完了\");\n}\n","import { existsSync, readFileSync, writeFileSync, appendFileSync, mkdirSync } from \"node:fs\";\nimport { join, dirname } from \"node:path\";\nimport type { ConflictStrategy } from \"../types/index.js\";\n\n/**\n * 競合戦略に基づいてファイルを書き込む\n */\nexport function writeWithStrategy(\n filePath: string,\n content: string,\n strategy: ConflictStrategy\n): boolean {\n const exists = existsSync(filePath);\n\n if (!exists) {\n ensureDir(dirname(filePath));\n writeFileSync(filePath, content, \"utf-8\");\n return true;\n }\n\n switch (strategy) {\n case \"overwrite\": {\n writeFileSync(filePath, content, \"utf-8\");\n return true;\n }\n\n case \"merge\": {\n const existingContent = readFileSync(filePath, \"utf-8\");\n const mergedContent = mergeContent(existingContent, content);\n writeFileSync(filePath, mergedContent, \"utf-8\");\n return true;\n }\n\n case \"skip\": {\n return false;\n }\n\n default: {\n const _exhaustiveCheck: never = strategy;\n throw new Error(`Unknown strategy: ${_exhaustiveCheck}`);\n }\n }\n}\n\n/**\n * 既存コンテンツと新規コンテンツをマージする\n */\nfunction mergeContent(existing: string, newContent: string): string {\n if (existing.includes(newContent)) {\n return existing;\n }\n return `${existing}\\n${newContent}`;\n}\n\n/**\n * ディレクトリが存在しない場合は作成する\n */\nexport function ensureDir(dirPath: string): void {\n if (!existsSync(dirPath)) {\n mkdirSync(dirPath, { recursive: true });\n }\n}\n\n/**\n * .gitignoreに行を追加する\n */\nexport function appendToGitignore(targetDir: string, line: string): void {\n const gitignorePath = join(targetDir, \".gitignore\");\n\n if (!existsSync(gitignorePath)) {\n writeFileSync(gitignorePath, `${line}\\n`, \"utf-8\");\n return;\n }\n\n const content = readFileSync(gitignorePath, \"utf-8\");\n if (content.includes(line)) {\n return;\n }\n\n appendFileSync(gitignorePath, `\\n${line}\\n`, \"utf-8\");\n}\n\n/**\n * ファイルが存在するか確認する\n */\nexport function fileExists(filePath: string): boolean {\n return existsSync(filePath);\n}\n","import chalk from \"chalk\";\n\n/**\n * 情報メッセージを出力\n * @param message - メッセージ\n */\nexport function info(message: string): void {\n console.log(chalk.blue(\"ℹ\"), message);\n}\n\n/**\n * 成功メッセージを出力(緑色)\n * @param message - メッセージ\n */\nexport function success(message: string): void {\n console.log(chalk.green(\"✔\"), message);\n}\n\n/**\n * 警告メッセージを出力(黄色)\n * @param message - メッセージ\n */\nexport function warn(message: string): void {\n console.log(chalk.yellow(\"⚠\"), message);\n}\n\n/**\n * エラーメッセージを出力(赤色)\n * @param message - メッセージ\n */\nexport function error(message: string): void {\n console.error(chalk.red(\"✖\"), message);\n}\n","import { execa, execaSync } from \"execa\";\nimport chalk from \"chalk\";\nimport inquirer from \"inquirer\";\nimport ora from \"ora\";\nimport type { ProjectConfig } from \"../types/index.js\";\nimport * as logger from \"../utils/logger.js\";\n\n/**\n * PostSetupOptions型\n * 生成後セットアップのオプション\n */\nexport interface PostSetupOptions {\n skipGit?: boolean;\n skipInstall?: boolean;\n}\n\n/**\n * direnvコマンドが利用可能かチェック\n * @returns direnvコマンドが利用可能な場合true\n */\nfunction isDirenvAvailable(): boolean {\n try {\n execaSync(\"which\", [\"direnv\"]);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * direnv allowの確認プロンプトを表示し、実行する\n * @param targetPath - プロジェクトディレクトリ\n */\nasync function promptAndExecuteDirenvAllow(targetPath: string): Promise<void> {\n try {\n const { shouldAllow } = await inquirer.prompt([\n {\n type: \"confirm\",\n name: \"shouldAllow\",\n message: \"direnv allow を実行しますか?(環境変数を有効化します)\",\n default: true,\n },\n ]);\n\n if (shouldAllow) {\n try {\n await execa(\"direnv\", [\"allow\"], { cwd: targetPath });\n logger.success(\"direnv allow を実行しました\");\n } catch (error) {\n logger.warn(\"direnv allow の実行に失敗しました\");\n logger.info(\"後で手動で 'direnv allow' を実行してください\");\n }\n } else {\n logger.info(\"direnv allow をスキップしました\");\n logger.info(\"後で手動で 'direnv allow' を実行してください\");\n }\n } catch (error) {\n logger.info(\"direnv allow をスキップしました\");\n }\n}\n\n/**\n * 完了メッセージを表示\n * @param config - プロジェクト設定\n */\nfunction printCompletionMessage(config: ProjectConfig): void {\n console.log();\n logger.success(\"プロジェクトの作成が完了しました!\");\n console.log();\n console.log(chalk.bold(\"次のステップ:\"));\n console.log();\n console.log(chalk.cyan(` cd ${config.projectName}`));\n console.log(chalk.cyan(\" pnpm env:update # 環境変数を設定\"));\n console.log(chalk.cyan(\" docker-compose up -d postgres\"));\n console.log(chalk.cyan(\" pnpm dev\"));\n console.log();\n console.log(chalk.gray(\"開発サーバー: ターミナルに表示されるURLを確認\"));\n console.log();\n console.log(\n chalk.yellow(\"⚠ 重要: \") +\n chalk.gray(\"pnpm env:update で環境変数を自分のプロジェクト用に再設定してください\")\n );\n console.log();\n console.log(chalk.gray(\"詳細は README.md をご確認ください。\"));\n console.log();\n}\n\n/**\n * 生成後セットアップを実行\n * @param config - プロジェクト設定\n * @param targetPath - プロジェクトディレクトリ\n * @param options - セットアップオプション\n */\nexport async function execPostSetup(\n config: ProjectConfig,\n targetPath: string,\n options: PostSetupOptions\n): Promise<void> {\n const { skipGit, skipInstall } = options;\n\n // Git初期化\n if (!skipGit) {\n const gitSpinner = ora(\"Gitリポジトリを初期化中...\").start();\n try {\n await execa(\"git\", [\"init\"], { cwd: targetPath });\n await execa(\"git\", [\"add\", \".\"], { cwd: targetPath });\n await execa(\"git\", [\"commit\", \"-m\", \"Initial commit\"], { cwd: targetPath });\n gitSpinner.succeed(\"Gitリポジトリを初期化しました\");\n } catch (error) {\n gitSpinner.fail(\"Gitリポジトリの初期化に失敗しました\");\n logger.warn(\"後で手動で 'git init' を実行してください\");\n }\n }\n\n // 依存関係インストール\n if (!skipInstall) {\n const installSpinner = ora(\"依存関係をインストール中...\").start();\n try {\n await execa(\"pnpm\", [\"install\"], { cwd: targetPath });\n installSpinner.succeed(\"依存関係をインストールしました\");\n\n // Prismaクライアント生成\n const prismaSpinner = ora(\"Prismaクライアントを生成中...\").start();\n try {\n await execa(\"pnpm\", [\"db:generate\"], { cwd: targetPath });\n prismaSpinner.succeed(\"Prismaクライアントを生成しました\");\n } catch (error) {\n prismaSpinner.fail(\"Prismaクライアントの生成に失敗しました\");\n logger.warn(\"後で手動で 'pnpm db:generate' を実行してください\");\n }\n } catch (error) {\n installSpinner.fail(\"依存関係のインストールに失敗しました\");\n logger.warn(\"後で手動で 'pnpm install' を実行してください\");\n }\n }\n\n // direnv allow(direnvが有効で、コマンドが利用可能な場合)\n if (config.tools.direnv && isDirenvAvailable()) {\n await promptAndExecuteDirenvAllow(targetPath);\n }\n\n // @einja/dev-cli init\n if (config.setupEinjaCli) {\n const einjaSpinner = ora(\"@einja/dev-cli を初期化中...\").start();\n try {\n await execa(\"npx\", [\"@einja/dev-cli\", \"init\", \"--force\"], { cwd: targetPath });\n einjaSpinner.succeed(\"@einja/dev-cli を初期化しました\");\n } catch (error) {\n einjaSpinner.fail(\"@einja/dev-cli の初期化に失敗しました\");\n logger.warn(\"後で手動で 'npx @einja/dev-cli init' を実行してください\");\n }\n }\n\n // 完了メッセージ表示\n printCompletionMessage(config);\n}\n","import { existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport ora from \"ora\";\nimport { promptSetupConfig } from \"../prompts/setup.js\";\nimport {\n setupDirenv,\n setupDotenvx,\n setupVolta,\n setupBiome,\n setupHusky,\n promptDirenvAllow,\n} from \"../generators/tools/index.js\";\nimport type { ToolSetupOptions } from \"../types/index.js\";\nimport * as logger from \"../utils/logger.js\";\n\n/**\n * setupコマンド - 既存プロジェクトへのツール追加\n *\n * US-002: 既存プロジェクトへの環境ツール追加\n * AC-002-1: `npx create-einja-app --setup` で対話式プロンプトが表示される\n * AC-002-2: 既存の設定ファイルがある場合、マージ・上書き・スキップを選択できる\n * AC-002-3: 選択したツールのみがセットアップされる\n * AC-002-4: 既存ファイルを破壊せずにツールが追加される(マージモード時)\n */\nexport async function setupCommand(): Promise<void> {\n const targetDir = process.cwd();\n\n // 1. プロジェクトディレクトリ確認(package.json存在確認)\n const packageJsonPath = join(targetDir, \"package.json\");\n if (!existsSync(packageJsonPath)) {\n logger.error(\"エラー: package.jsonが見つかりません\");\n logger.info(\"このコマンドは既存のプロジェクトディレクトリで実行してください\");\n process.exit(1);\n }\n\n logger.info(\"既存プロジェクトへのツール追加を開始します\");\n logger.info(\"\");\n\n // 2. プロンプトで設定収集\n const config = await promptSetupConfig();\n\n logger.info(\"\");\n logger.info(\"セットアップを開始します...\");\n logger.info(\"\");\n\n const options: ToolSetupOptions = {\n targetDir,\n conflictStrategy: config.conflictStrategy,\n };\n\n // 3. 選択されたツールのセットアップ\n let setupCount = 0;\n\n if (config.tools.direnv) {\n const spin = ora(\"direnv をセットアップしています...\").start();\n try {\n setupDirenv(options);\n spin.succeed(\"direnv セットアップ完了\");\n setupCount++;\n } catch (error) {\n spin.fail(\"direnv セットアップ失敗\");\n logger.error(\n error instanceof Error ? error.message : \"予期しないエラーが発生しました\"\n );\n }\n }\n\n if (config.tools.dotenvx) {\n const spin = ora(\"dotenvx をセットアップしています...\").start();\n try {\n setupDotenvx(options);\n spin.succeed(\"dotenvx セットアップ完了\");\n setupCount++;\n } catch (error) {\n spin.fail(\"dotenvx セットアップ失敗\");\n logger.error(\n error instanceof Error ? error.message : \"予期しないエラーが発生しました\"\n );\n }\n }\n\n if (config.tools.volta) {\n const spin = ora(\"Volta をセットアップしています...\").start();\n try {\n setupVolta(options);\n spin.succeed(\"Volta セットアップ完了\");\n setupCount++;\n } catch (error) {\n spin.fail(\"Volta セットアップ失敗\");\n logger.error(\n error instanceof Error ? error.message : \"予期しないエラーが発生しました\"\n );\n }\n }\n\n if (config.tools.biome) {\n const spin = ora(\"Biome をセットアップしています...\").start();\n try {\n setupBiome(options);\n spin.succeed(\"Biome セットアップ完了\");\n setupCount++;\n } catch (error) {\n spin.fail(\"Biome セットアップ失敗\");\n logger.error(\n error instanceof Error ? error.message : \"予期しないエラーが発生しました\"\n );\n }\n }\n\n if (config.tools.husky) {\n const spin = ora(\"Husky をセットアップしています...\").start();\n try {\n setupHusky(options);\n spin.succeed(\"Husky セットアップ完了\");\n setupCount++;\n } catch (error) {\n spin.fail(\"Husky セットアップ失敗\");\n logger.error(\n error instanceof Error ? error.message : \"予期しないエラーが発生しました\"\n );\n }\n }\n\n logger.info(\"\");\n\n // 4. direnv allowの確認プロンプト(direnvがセットアップされた場合のみ)\n if (config.tools.direnv) {\n await promptDirenvAllow(targetDir);\n logger.info(\"\");\n }\n\n // 5. 完了メッセージ\n logger.success(`✅ セットアップが完了しました!(${setupCount}個のツール)`);\n logger.info(\"\");\n logger.info(\"次のステップ:\");\n\n if (config.tools.direnv) {\n logger.info(\" 1. .envrc を編集して環境変数を設定\");\n logger.info(\" 2. direnv allow を実行(まだの場合)\");\n }\n\n if (config.tools.dotenvx) {\n logger.info(\" - .env.example をコピーして .env を作成\");\n logger.info(\" - 必要に応じて pnpm env:encrypt で暗号化\");\n }\n\n if (config.tools.biome) {\n logger.info(\" - pnpm lint でコードをチェック\");\n logger.info(\" - pnpm format:fix でフォーマット\");\n }\n\n if (config.tools.husky) {\n logger.info(\" - pnpm install でHuskyフックをインストール\");\n }\n\n logger.info(\"\");\n logger.success(\"開発を開始できます!\");\n}\n","import inquirer from \"inquirer\";\n\n/**\n * SetupConfig型\n * 既存プロジェクトへのツール追加設定\n */\nexport interface SetupConfig {\n tools: {\n direnv: boolean;\n dotenvx: boolean;\n volta: boolean;\n biome: boolean;\n husky: boolean;\n };\n conflictStrategy: \"merge\" | \"overwrite\" | \"skip\";\n}\n\n/**\n * セットアップ用プロンプトを実行\n * @returns SetupConfig - セットアップ設定\n */\nexport async function promptSetupConfig(): Promise<SetupConfig> {\n const answers = await inquirer.prompt([\n {\n type: \"checkbox\",\n name: \"tools\",\n message: \"セットアップするツールを選択(複数選択可):\",\n choices: [\n {\n name: \"direnv(ディレクトリごとの環境変数管理)\",\n value: \"direnv\",\n checked: true,\n },\n {\n name: \"dotenvx(.env暗号化)\",\n value: \"dotenvx\",\n checked: true,\n },\n {\n name: \"Volta(Node.jsバージョン管理)\",\n value: \"volta\",\n checked: true,\n },\n {\n name: \"Biome(Linter / Formatter)\",\n value: \"biome\",\n checked: false,\n },\n {\n name: \"Husky + lint-staged(Git hooks)\",\n value: \"husky\",\n checked: false,\n },\n ],\n },\n {\n type: \"list\",\n name: \"conflictStrategy\",\n message: \"既存ファイルがある場合の動作:\",\n choices: [\n {\n name: \"マージ(既存設定を保持しつつ追加)\",\n value: \"merge\",\n },\n {\n name: \"上書き\",\n value: \"overwrite\",\n },\n {\n name: \"スキップ\",\n value: \"skip\",\n },\n ],\n default: \"merge\",\n },\n ]);\n\n // ツール選択を boolean フラグに変換\n const toolsArray = answers.tools as string[];\n const tools = {\n direnv: toolsArray.includes(\"direnv\"),\n dotenvx: toolsArray.includes(\"dotenvx\"),\n volta: toolsArray.includes(\"volta\"),\n biome: toolsArray.includes(\"biome\"),\n husky: toolsArray.includes(\"husky\"),\n };\n\n return {\n tools,\n conflictStrategy: answers.conflictStrategy,\n };\n}\n","import { join } from \"node:path\";\nimport { execSync } from \"node:child_process\";\nimport inquirer from \"inquirer\";\nimport type { ToolSetupOptions } from \"../../types/index.js\";\nimport { writeWithStrategy, appendToGitignore } from \"../../utils/fs.js\";\nimport * as logger from \"../../utils/logger.js\";\n\nconst ENVRC_CONTENT = `# direnv configuration\n# Load .env if it exists\ndotenv_if_exists\n\n# Allow local overrides\ndotenv_if_exists .env.local\n`;\n\nconst ENVRC_EXAMPLE_CONTENT = `# Example direnv configuration\n# Copy this file to .envrc and run 'direnv allow'\n\n# Load environment variables from .env\ndotenv_if_exists\n\n# Load local overrides\ndotenv_if_exists .env.local\n`;\n\n/**\n * direnvのセットアップを実行する\n *\n * AC-003-1: .envrc ファイルが生成される\n * AC-003-2: .envrc.example ファイルが生成される\n * AC-003-3: .gitignore に .envrc が追加される\n */\nexport function setupDirenv(options: ToolSetupOptions): void {\n const { targetDir, conflictStrategy } = options;\n\n const envrcPath = join(targetDir, \".envrc\");\n const envrcExamplePath = join(targetDir, \".envrc.example\");\n\n writeWithStrategy(envrcPath, ENVRC_CONTENT, conflictStrategy);\n\n writeWithStrategy(envrcExamplePath, ENVRC_EXAMPLE_CONTENT, conflictStrategy);\n\n appendToGitignore(targetDir, \".envrc\");\n}\n\n/**\n * direnv allowの確認プロンプトを表示し、実行する\n *\n * AC-003-4: 確認後 `direnv allow` が実行される\n *\n * @param targetDir - ターゲットディレクトリ\n */\nexport async function promptDirenvAllow(targetDir: string): Promise<void> {\n try {\n const { shouldAllow } = await inquirer.prompt([\n {\n type: \"confirm\",\n name: \"shouldAllow\",\n message: \"direnv allow を実行しますか?(環境変数を有効化します)\",\n default: true,\n },\n ]);\n\n if (shouldAllow) {\n try {\n execSync(\"direnv allow\", { cwd: targetDir, stdio: \"inherit\" });\n logger.success(\"direnv allow を実行しました\");\n } catch (error) {\n logger.warn(\"direnv allow の実行に失敗しました\");\n logger.info(\"後で手動で 'direnv allow' を実行してください\");\n }\n } else {\n logger.info(\"direnv allow をスキップしました\");\n logger.info(\"後で手動で 'direnv allow' を実行してください\");\n }\n } catch (error) {\n // プロンプトがキャンセルされた場合など\n logger.info(\"direnv allow をスキップしました\");\n }\n}\n","import { join } from \"node:path\";\nimport type { ToolSetupOptions } from \"../../types/index.js\";\nimport { writeWithStrategy } from \"../../utils/fs.js\";\nimport { addDependencies, addScripts } from \"../../utils/package-json.js\";\n\nconst ENV_EXAMPLE_CONTENT = `# Environment variables template\n# Copy this file to .env and fill in the values\n\n# Database\nDATABASE_URL=\"postgresql://user:password@localhost:25432/dbname\"\n\n# NextAuth\nNEXTAUTH_URL=\"http://localhost:3000\"\nNEXTAUTH_SECRET=\"your-secret-here\"\n\n# OAuth (if using)\n# GOOGLE_CLIENT_ID=\"\"\n# GOOGLE_CLIENT_SECRET=\"\"\n# GITHUB_CLIENT_ID=\"\"\n# GITHUB_CLIENT_SECRET=\"\"\n`;\n\n/**\n * dotenvxのセットアップを実行する\n *\n * AC-004-1: package.jsonに依存関係が追加される\n * AC-004-2: npm scriptsにdotenvxコマンドが追加される\n * AC-004-3: .env.example が生成される\n */\nexport function setupDotenvx(options: ToolSetupOptions): void {\n const { targetDir, conflictStrategy } = options;\n\n addDependencies(targetDir, {\n \"@dotenvx/dotenvx\": \"^1.29.0\",\n });\n\n addScripts(targetDir, {\n \"env:encrypt\": \"dotenvx encrypt\",\n \"env:decrypt\": \"dotenvx decrypt\",\n });\n\n const envExamplePath = join(targetDir, \".env.example\");\n writeWithStrategy(envExamplePath, ENV_EXAMPLE_CONTENT, conflictStrategy);\n}\n","import { readFileSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { fileExists } from \"./fs.js\";\n\ntype PackageJson = {\n name?: string;\n version?: string;\n scripts?: Record<string, string>;\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n volta?: {\n node?: string;\n pnpm?: string;\n };\n \"lint-staged\"?: Record<string, string | string[]>;\n [key: string]: unknown;\n};\n\n/**\n * package.jsonを読み込む\n */\nexport function readPackageJson(targetDir: string): PackageJson {\n const packageJsonPath = join(targetDir, \"package.json\");\n\n if (!fileExists(packageJsonPath)) {\n return {};\n }\n\n const content = readFileSync(packageJsonPath, \"utf-8\");\n return JSON.parse(content) as PackageJson;\n}\n\n/**\n * package.jsonに書き込む\n */\nexport function writePackageJson(targetDir: string, data: PackageJson): void {\n const packageJsonPath = join(targetDir, \"package.json\");\n const content = JSON.stringify(data, null, 2);\n writeFileSync(packageJsonPath, `${content}\\n`, \"utf-8\");\n}\n\n/**\n * package.jsonにスクリプトを追加する\n */\nexport function addScripts(\n targetDir: string,\n scripts: Record<string, string>\n): void {\n const pkg = readPackageJson(targetDir);\n pkg.scripts = { ...pkg.scripts, ...scripts };\n writePackageJson(targetDir, pkg);\n}\n\n/**\n * package.jsonに依存関係を追加する\n */\nexport function addDependencies(\n targetDir: string,\n dependencies: Record<string, string>,\n dev = false\n): void {\n const pkg = readPackageJson(targetDir);\n\n if (dev) {\n pkg.devDependencies = { ...pkg.devDependencies, ...dependencies };\n } else {\n pkg.dependencies = { ...pkg.dependencies, ...dependencies };\n }\n\n writePackageJson(targetDir, pkg);\n}\n\n/**\n * package.jsonにVoltaフィールドを追加する\n */\nexport function addVoltaField(\n targetDir: string,\n nodeVersion: string,\n pnpmVersion: string\n): void {\n const pkg = readPackageJson(targetDir);\n pkg.volta = {\n node: nodeVersion,\n pnpm: pnpmVersion,\n };\n writePackageJson(targetDir, pkg);\n}\n\n/**\n * package.jsonにlint-staged設定を追加する\n */\nexport function addLintStaged(\n targetDir: string,\n config: Record<string, string | string[]>\n): void {\n const pkg = readPackageJson(targetDir);\n pkg[\"lint-staged\"] = { ...pkg[\"lint-staged\"], ...config };\n writePackageJson(targetDir, pkg);\n}\n","import { join } from \"node:path\";\nimport type { ToolSetupOptions } from \"../../types/index.js\";\nimport { writeWithStrategy } from \"../../utils/fs.js\";\nimport { addVoltaField } from \"../../utils/package-json.js\";\n\nconst NODE_VERSION = \"22.16.0\";\nconst PNPM_VERSION = \"9.15.0\";\n\nconst NODE_VERSION_CONTENT = `${NODE_VERSION}\n`;\n\n/**\n * Voltaのセットアップを実行する\n *\n * AC-005-1: package.jsonにvoltaフィールドが追加される\n * AC-005-2: .node-version ファイルが生成される\n */\nexport function setupVolta(options: ToolSetupOptions): void {\n const { targetDir, conflictStrategy } = options;\n\n addVoltaField(targetDir, NODE_VERSION, PNPM_VERSION);\n\n const nodeVersionPath = join(targetDir, \".node-version\");\n writeWithStrategy(nodeVersionPath, NODE_VERSION_CONTENT, conflictStrategy);\n}\n","import { join } from \"node:path\";\nimport type { ToolSetupOptions } from \"../../types/index.js\";\nimport { writeWithStrategy, ensureDir } from \"../../utils/fs.js\";\nimport { addDependencies, addScripts } from \"../../utils/package-json.js\";\n\nconst BIOME_CONFIG = `{\n \"$schema\": \"https://biomejs.dev/schemas/1.9.4/schema.json\",\n \"vcs\": {\n \"enabled\": true,\n \"clientKind\": \"git\",\n \"useIgnoreFile\": true\n },\n \"files\": {\n \"ignoreUnknown\": false,\n \"ignore\": [\"node_modules\", \"dist\", \".next\", \"out\", \"build\", \"coverage\"]\n },\n \"formatter\": {\n \"enabled\": true,\n \"indentStyle\": \"space\",\n \"indentWidth\": 2,\n \"lineEnding\": \"lf\",\n \"lineWidth\": 100\n },\n \"organizeImports\": {\n \"enabled\": true\n },\n \"linter\": {\n \"enabled\": true,\n \"rules\": {\n \"recommended\": true\n }\n },\n \"javascript\": {\n \"formatter\": {\n \"quoteStyle\": \"double\",\n \"trailingCommas\": \"es5\",\n \"semicolons\": \"always\",\n \"arrowParentheses\": \"always\"\n }\n }\n}\n`;\n\nconst VSCODE_SETTINGS = `{\n \"editor.defaultFormatter\": \"biomejs.biome\",\n \"editor.formatOnSave\": true,\n \"editor.codeActionsOnSave\": {\n \"quickfix.biome\": \"explicit\",\n \"source.organizeImports.biome\": \"explicit\"\n },\n \"[javascript]\": {\n \"editor.defaultFormatter\": \"biomejs.biome\"\n },\n \"[typescript]\": {\n \"editor.defaultFormatter\": \"biomejs.biome\"\n },\n \"[json]\": {\n \"editor.defaultFormatter\": \"biomejs.biome\"\n }\n}\n`;\n\n/**\n * Biomeのセットアップを実行する(--setupモードのみ)\n *\n * AC-006-1: biome.json が生成される\n * AC-006-2: package.jsonにlint/formatスクリプトが追加される\n * AC-006-3: VSCode設定が追加される\n */\nexport function setupBiome(options: ToolSetupOptions): void {\n const { targetDir, conflictStrategy } = options;\n\n const biomeConfigPath = join(targetDir, \"biome.json\");\n writeWithStrategy(biomeConfigPath, BIOME_CONFIG, conflictStrategy);\n\n addDependencies(\n targetDir,\n {\n \"@biomejs/biome\": \"^1.9.4\",\n },\n true\n );\n\n addScripts(targetDir, {\n lint: \"biome lint .\",\n \"lint:fix\": \"biome lint --write .\",\n format: \"biome format .\",\n \"format:fix\": \"biome format --write .\",\n });\n\n const vscodeDir = join(targetDir, \".vscode\");\n ensureDir(vscodeDir);\n\n const vscodeSettingsPath = join(vscodeDir, \"settings.json\");\n writeWithStrategy(vscodeSettingsPath, VSCODE_SETTINGS, conflictStrategy);\n}\n","import { join } from \"node:path\";\nimport { writeFileSync } from \"node:fs\";\nimport type { ToolSetupOptions } from \"../../types/index.js\";\nimport { ensureDir } from \"../../utils/fs.js\";\nimport { addDependencies, addScripts, addLintStaged } from \"../../utils/package-json.js\";\n\nconst PRE_COMMIT_HOOK = `#!/usr/bin/env sh\n. \"$(dirname -- \"$0\")/_/husky.sh\"\n\npnpm lint-staged\n`;\n\n/**\n * Husky + lint-stagedのセットアップを実行する(--setupモードのみ)\n *\n * AC-007-1: .husky/ ディレクトリが生成される\n * AC-007-2: pre-commitフックが設定される\n * AC-007-3: lint-staged設定が追加される\n */\nexport function setupHusky(options: ToolSetupOptions): void {\n const { targetDir } = options;\n\n addDependencies(\n targetDir,\n {\n husky: \"^9.1.7\",\n \"lint-staged\": \"^15.2.11\",\n },\n true\n );\n\n addScripts(targetDir, {\n prepare: \"husky\",\n });\n\n addLintStaged(targetDir, {\n \"*.{js,jsx,ts,tsx}\": [\"biome format --write\", \"biome lint --write\"],\n \"*.{json,md,yml,yaml}\": [\"biome format --write\"],\n });\n\n const huskyDir = join(targetDir, \".husky\");\n ensureDir(huskyDir);\n\n const preCommitPath = join(huskyDir, \"pre-commit\");\n writeFileSync(preCommitPath, PRE_COMMIT_HOOK, { mode: 0o755 });\n}\n","import { existsSync } from \"node:fs\";\nimport { readFile } from \"node:fs/promises\";\nimport { dirname, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport ora from \"ora\";\nimport {\n promptAddConfig,\n getDefaultAddConfig,\n} from \"../prompts/add.js\";\nimport type { AddConfig, AddOptions, SyncMetadata } from \"../types/index.js\";\nimport { addPackages } from \"../generators/partials/packages.js\";\nimport { addApps } from \"../generators/partials/apps.js\";\nimport { addConfigFiles } from \"../generators/partials/config.js\";\nimport {\n loadSyncMetadata,\n saveSyncMetadata,\n} from \"../utils/merger.js\";\nimport * as logger from \"../utils/logger.js\";\n\n/**\n * AddCommandOptions型\n * addコマンドのオプション\n */\nexport interface AddCommandOptions {\n skipPrompts: boolean;\n dryRun: boolean;\n}\n\n/**\n * テンプレートディレクトリのパスを取得\n * @param templateName - テンプレート名\n * @returns テンプレートディレクトリパス\n */\nfunction getTemplatePath(templateName: string): string {\n const __filename = fileURLToPath(import.meta.url);\n const __dirname = dirname(__filename);\n\n // バンドル後(dist/cli.js)とソース実行(src/commands/add.ts)の両方に対応\n // dist/cli.js -> ../templates/ (1階層上)\n // src/commands/add.ts -> ../../templates/ (2階層上)\n const distPath = join(__dirname, \"../templates\", templateName);\n const srcPath = join(__dirname, \"../../templates\", templateName);\n\n if (existsSync(distPath)) {\n return distPath;\n }\n if (existsSync(srcPath)) {\n return srcPath;\n }\n\n // どちらも存在しない場合はdistPathを返す(エラーメッセージ用)\n return distPath;\n}\n\n/**\n * テンプレートから.einja-sync.jsonを読み込む\n * @param templateDir - テンプレートディレクトリパス\n * @returns SyncMetadata または null(ファイルが存在しない場合)\n */\nasync function loadTemplateSyncMetadata(\n templateDir: string\n): Promise<SyncMetadata | null> {\n const syncFilePath = join(templateDir, \".einja-sync.json\");\n try {\n const content = await readFile(syncFilePath, \"utf-8\");\n return JSON.parse(content) as SyncMetadata;\n } catch {\n return null;\n }\n}\n\n/**\n * テンプレートと既存のSyncMetadataをマージ\n * @param template - テンプレートのSyncMetadata\n * @param existing - 既存のSyncMetadata\n * @returns マージされたSyncMetadata\n */\nfunction mergeSyncMetadata(\n template: SyncMetadata | null,\n existing: SyncMetadata | null\n): SyncMetadata {\n const now = new Date().toISOString();\n\n // テンプレートのjsonPathsを優先的に使用\n const jsonPaths =\n template?.jsonPaths ?? existing?.jsonPaths ?? { managed: {}, seed: {} };\n\n return {\n version: template?.version ?? existing?.version ?? \"1.0.0\",\n lastSync: now,\n templateVersion: template?.templateVersion ?? \"1.0.0\",\n files: { ...(existing?.files ?? {}), ...(template?.files ?? {}) },\n jsonPaths,\n };\n}\n\n/**\n * addコマンドの実装\n * @param options - コマンドオプション\n */\nexport async function addCommand(options: AddCommandOptions): Promise<void> {\n try {\n // Given: カレントディレクトリをターゲットとする\n const targetDir = process.cwd();\n\n // Given: プロンプトまたはデフォルト設定を取得\n let config: AddConfig;\n\n if (options.skipPrompts) {\n // When: skipPromptsが有効な場合、デフォルト設定を使用\n config = getDefaultAddConfig();\n logger.info(\"デフォルト設定を使用します(すべてのコンポーネントを選択)\");\n } else {\n // When: 対話式プロンプトを実行\n config = await promptAddConfig(options.dryRun);\n }\n\n // Given: dry-runモードかどうかを設定に反映\n config.dryRun = options.dryRun;\n\n // When: dry-runモードの場合、プレビューを表示\n if (config.dryRun) {\n logger.warn(\"dry-runモード: 実際のファイル操作は行いません\");\n logger.info(\"\\n--- 追加予定のコンポーネント ---\");\n\n if (config.components.packages) {\n logger.info(\n `- packages/: ${config.packageComponents.join(\", \")}`\n );\n }\n\n if (config.components.apps) {\n logger.info(`- apps/: ${config.appComponents.join(\", \")}`);\n }\n\n if (config.components.config) {\n logger.info(\"- 直下設定ファイル: turbo.json, pnpm-workspace.yaml 等\");\n }\n\n logger.info(\"---\\n\");\n }\n\n // Given: テンプレートディレクトリのパスを取得\n const templateDir = getTemplatePath(\"default\");\n\n // Given: テンプレートディレクトリの存在確認\n if (!existsSync(templateDir)) {\n throw new Error(\"テンプレートが見つかりません: default\");\n }\n\n // Given: テンプレートのSyncMetadataを読み込む\n const templateMetadata = await loadTemplateSyncMetadata(templateDir);\n\n // Given: 既存のSyncMetadataを読み込む\n const existingMetadata = await loadSyncMetadata(targetDir);\n\n // When: テンプレートと既存のメタデータをマージ\n const syncMetadata = mergeSyncMetadata(templateMetadata, existingMetadata);\n\n // Given: AddOptionsを構築\n const addOptions: AddOptions = {\n targetDir,\n templateDir,\n config,\n };\n\n let totalAdded = 0;\n let totalMerged = 0;\n let totalSkipped = 0;\n\n // When: packages を追加\n if (config.components.packages && config.packageComponents.length > 0) {\n const spinner = ora(\"パッケージを追加中...\").start();\n\n try {\n const result = await addPackages(\n addOptions,\n config.packageComponents,\n syncMetadata\n );\n\n totalAdded += result.added.length;\n totalMerged += result.merged.length;\n totalSkipped += result.skipped.length;\n\n spinner.succeed(\n `パッケージを追加しました(追加: ${result.added.length}, マージ: ${result.merged.length}, スキップ: ${result.skipped.length})`\n );\n } catch (error) {\n spinner.fail(\"パッケージの追加に失敗しました\");\n throw error;\n }\n }\n\n // When: apps を追加\n if (config.components.apps && config.appComponents.length > 0) {\n const spinner = ora(\"アプリを追加中...\").start();\n\n try {\n const result = await addApps(\n addOptions,\n config.appComponents,\n syncMetadata\n );\n\n totalAdded += result.added.length;\n totalMerged += result.merged.length;\n totalSkipped += result.skipped.length;\n\n spinner.succeed(\n `アプリを追加しました(追加: ${result.added.length}, マージ: ${result.merged.length}, スキップ: ${result.skipped.length})`\n );\n } catch (error) {\n spinner.fail(\"アプリの追加に失敗しました\");\n throw error;\n }\n }\n\n // When: config を追加\n if (config.components.config) {\n const spinner = ora(\"設定ファイルを追加中...\").start();\n\n try {\n const result = await addConfigFiles(addOptions, syncMetadata);\n\n totalAdded += result.added.length;\n totalMerged += result.merged.length;\n totalSkipped += result.skipped.length;\n\n spinner.succeed(\n `設定ファイルを追加しました(追加: ${result.added.length}, マージ: ${result.merged.length}, スキップ: ${result.skipped.length})`\n );\n } catch (error) {\n spinner.fail(\"設定ファイルの追加に失敗しました\");\n throw error;\n }\n }\n\n // When: SyncMetadataを更新して保存\n if (!config.dryRun) {\n syncMetadata.lastSync = new Date().toISOString();\n await saveSyncMetadata(targetDir, syncMetadata);\n }\n\n // Then: 結果サマリーを表示\n logger.success(\"\\n✓ 追加完了!\\n\");\n\n if (config.dryRun) {\n logger.info(\"(dry-runモードのため、実際の変更は行われていません)\\n\");\n }\n\n logger.info(`追加されたファイル: ${totalAdded}個`);\n logger.info(`マージされたファイル: ${totalMerged}個`);\n logger.info(`スキップされたファイル: ${totalSkipped}個\\n`);\n\n // When: @einja/cliがインストールされていない場合、案内メッセージを表示\n const packageJsonPath = join(targetDir, \"package.json\");\n if (existsSync(packageJsonPath)) {\n const packageJson = await import(packageJsonPath, {\n assert: { type: \"json\" },\n });\n\n const hasEinjaCli =\n packageJson.default?.devDependencies?.[\"@einja/dev-cli\"] ||\n packageJson.default?.dependencies?.[\"@einja/dev-cli\"];\n\n if (!hasEinjaCli) {\n logger.info(\"次のステップ:\");\n logger.info(\"1. pnpm install\");\n logger.info(\"2. pnpm dev:setup\");\n logger.info(\"\\n推奨:\");\n logger.info(\" einja開発支援CLI (@einja/dev-cli) のインストール:\");\n logger.info(\" pnpm add -D @einja/dev-cli\\n\");\n } else {\n logger.info(\"次のステップ:\");\n logger.info(\"1. pnpm install\");\n logger.info(\"2. pnpm dev:setup\\n\");\n }\n } else {\n logger.info(\"次のステップ:\");\n logger.info(\"1. pnpm install\");\n logger.info(\"2. pnpm dev:setup\\n\");\n }\n } catch (error) {\n logger.error(\"エラーが発生しました:\");\n if (error instanceof Error) {\n logger.error(error.message);\n } else {\n logger.error(String(error));\n }\n process.exit(1);\n }\n}\n","import inquirer from \"inquirer\";\nimport type {\n AddConfig,\n PackageComponent,\n AppComponent,\n} from \"../types/index.js\";\n\n/**\n * デフォルトの追加設定を取得\n * skipPrompts=true 時に使用\n */\nexport function getDefaultAddConfig(): AddConfig {\n return {\n components: {\n packages: true,\n apps: true,\n config: true,\n },\n packageComponents: [\"front-core\", \"server-core\", \"config\", \"ui\"],\n appComponents: [\"web\"],\n dryRun: false,\n };\n}\n\n/**\n * 追加用プロンプトを実行\n * @param dryRun - dry-runモードかどうか\n * @returns AddConfig - 追加設定\n */\nexport async function promptAddConfig(dryRun: boolean): Promise<AddConfig> {\n // ステージ1: コンポーネント種別選択\n const componentAnswers = await inquirer.prompt([\n {\n type: \"checkbox\",\n name: \"components\",\n message: \"追加するコンポーネントを選択(Spaceで選択、Enterで確定):\",\n choices: [\n {\n name: \"packages/ - 共通パッケージ(front-core, server-core, config, ui)\",\n value: \"packages\",\n checked: true,\n },\n {\n name: \"apps/ - アプリテンプレート\",\n value: \"apps\",\n checked: true,\n },\n {\n name: \"直下設定ファイル - turbo.json, pnpm-workspace.yaml 等\",\n value: \"config\",\n checked: true,\n },\n ],\n },\n ]);\n\n const selectedComponents = componentAnswers.components as string[];\n const hasPackages = selectedComponents.includes(\"packages\");\n const hasApps = selectedComponents.includes(\"apps\");\n const hasConfig = selectedComponents.includes(\"config\");\n\n // ステージ2: packages詳細選択\n let packageComponents: PackageComponent[] = [];\n if (hasPackages) {\n const packageAnswers = await inquirer.prompt([\n {\n type: \"checkbox\",\n name: \"packages\",\n message: \"追加するパッケージを選択:\",\n choices: [\n {\n name: \"front-core - フロントエンド共通層(認証設定、hooks、utils)\",\n value: \"front-core\",\n checked: true,\n },\n {\n name: \"server-core - バックエンド共通層(Prisma、ドメインロジック)\",\n value: \"server-core\",\n checked: true,\n },\n {\n name: \"config - 共通設定(Biome, TypeScript, Panda CSS)\",\n value: \"config\",\n checked: true,\n },\n {\n name: \"ui - 共通UIコンポーネント(shadcn/ui)\",\n value: \"ui\",\n checked: true,\n },\n ],\n validate: (input: string[]): boolean | string => {\n if (input.length === 0) {\n return \"少なくとも1つのパッケージを選択してください\";\n }\n return true;\n },\n },\n ]);\n packageComponents = packageAnswers.packages as PackageComponent[];\n }\n\n // ステージ3: apps詳細選択\n let appComponents: AppComponent[] = [];\n if (hasApps) {\n const appAnswers = await inquirer.prompt([\n {\n type: \"checkbox\",\n name: \"apps\",\n message: \"追加するアプリを選択:\",\n choices: [\n {\n name: \"web - メイン管理画面アプリ(Next.js + App Router)\",\n value: \"web\",\n checked: true,\n },\n ],\n validate: (input: string[]): boolean | string => {\n if (input.length === 0) {\n return \"少なくとも1つのアプリを選択してください\";\n }\n return true;\n },\n },\n ]);\n appComponents = appAnswers.apps as AppComponent[];\n }\n\n return {\n components: {\n packages: hasPackages,\n apps: hasApps,\n config: hasConfig,\n },\n packageComponents,\n appComponents,\n dryRun,\n };\n}\n","import { readdir } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport type {\n AddOptions,\n PackageComponent,\n SyncMetadata,\n} from \"../../types/index.js\";\nimport { mergeAndWriteFile } from \"../../utils/merger.js\";\nimport * as logger from \"../../utils/logger.js\";\n\n/**\n * packages/ ディレクトリにコンポーネントを追加\n */\nexport async function addPackages(\n options: AddOptions,\n components: PackageComponent[],\n syncMetadata: SyncMetadata\n): Promise<{ added: string[]; skipped: string[]; merged: string[] }> {\n const added: string[] = [];\n const skipped: string[] = [];\n const merged: string[] = [];\n\n const { targetDir, templateDir, config } = options;\n\n for (const component of components) {\n const componentName =\n component === \"front-core\"\n ? \"front-core\"\n : component === \"server-core\"\n ? \"server-core\"\n : component === \"config\"\n ? \"config\"\n : \"ui\";\n\n const srcDir = join(templateDir, \"packages\", componentName);\n const destDir = join(targetDir, \"packages\", componentName);\n\n logger.info(`Adding package component: ${componentName}`);\n\n await copyDirectory(\n srcDir,\n destDir,\n { added, skipped, merged },\n config.dryRun,\n syncMetadata\n );\n }\n\n return { added, skipped, merged };\n}\n\n/**\n * ディレクトリを再帰的にコピー\n */\nasync function copyDirectory(\n srcDir: string,\n destDir: string,\n result: { added: string[]; skipped: string[]; merged: string[] },\n dryRun: boolean,\n syncMetadata: SyncMetadata\n): Promise<void> {\n const entries = await readdir(srcDir, { withFileTypes: true });\n\n for (const entry of entries) {\n const srcPath = join(srcDir, entry.name);\n const destPath = join(destDir, entry.name);\n\n if (entry.isDirectory()) {\n await copyDirectory(srcPath, destPath, result, dryRun, syncMetadata);\n } else {\n if (!dryRun) {\n const mergeResult = await mergeAndWriteFile(\n srcPath,\n destPath,\n syncMetadata\n );\n\n if (mergeResult.action === \"created\") {\n result.added.push(destPath);\n } else if (mergeResult.action === \"skipped\") {\n result.skipped.push(destPath);\n } else if (mergeResult.action === \"merged\") {\n result.merged.push(destPath);\n }\n } else {\n // dry-runモードではスキップ\n result.skipped.push(destPath);\n }\n }\n }\n}\n","import { readFileSync, writeFileSync, existsSync } from \"node:fs\";\nimport { dirname } from \"node:path\";\nimport type { SyncMetadata, JsonPathsConfig } from \"../types/index.js\";\nimport { ensureDir } from \"./fs.js\";\n\n/**\n * マーカーベースのテキストマージを行う\n *\n * @param templateContent - テンプレートファイルの内容\n * @param existingContent - 既存ファイルの内容(存在しない場合はnull)\n * @returns マージ後の内容\n */\nexport function mergeTextWithMarkers(\n templateContent: string,\n existingContent: string | null\n): string {\n // Given: 既存ファイルが存在しない場合\n if (existingContent === null) {\n // When: テンプレートをそのまま使用\n return templateContent;\n }\n\n // Given: 既存ファイルとテンプレートの両方が存在する場合\n const templateSections = parseMarkers(templateContent);\n const localSections = parseMarkers(existingContent);\n\n // マーカーがなければ既存優先\n const hasMarkers = templateSections.some(\n (s) => s.type === \"managed\" || s.type === \"seed\"\n );\n if (!hasMarkers) {\n return existingContent;\n }\n\n // When: ID付きmanagedセクションとseedセクションをMapで管理\n const templateManagedById = new Map<string, MarkerSection>();\n const templateSeedById = new Map<string, MarkerSection>();\n const processedTemplateIds = new Set<string>();\n\n for (const section of templateSections) {\n if (section.type === \"managed\" && section.id) {\n templateManagedById.set(section.id, section);\n } else if (section.type === \"seed\" && section.id) {\n templateSeedById.set(section.id, section);\n }\n }\n\n // When: ローカルセクションを処理(ローカル側の順序を基準にする)\n const result: string[] = [];\n\n for (const localSection of localSections) {\n if (localSection.type === \"managed\") {\n const match = localSection.id ? templateManagedById.get(localSection.id) : undefined;\n if (localSection.id && match) {\n // IDマッチ → テンプレートで上書き\n processedTemplateIds.add(localSection.id);\n result.push(match.content);\n } else if (!localSection.id) {\n // IDなし → ローカル内容を保持(安全策)\n result.push(localSection.content);\n }\n // ID付きでテンプレートにマッチなし → 削除(resultに追加しない)\n } else if (localSection.type === \"seed\") {\n // seed: ローカル優先\n if (localSection.id) {\n processedTemplateIds.add(localSection.id);\n }\n result.push(localSection.content);\n } else {\n // unmanaged: ローカル優先\n result.push(localSection.content);\n }\n }\n\n // When: テンプレートにのみ存在するID付きmanagedセクションを末尾に追加\n for (const [id, section] of templateManagedById) {\n if (!processedTemplateIds.has(id)) {\n // テンプレートにのみ存在するID付きmanagedセクションを追加\n result.push(section.content);\n }\n }\n\n // When: テンプレートにのみ存在するID付きseedセクションを末尾に追加\n for (const [id, section] of templateSeedById) {\n if (!processedTemplateIds.has(id)) {\n // テンプレートにのみ存在するID付きseedセクションを追加\n result.push(section.content);\n }\n }\n\n // Then: ファイル先頭の空セクションのみ除去(セクション間の空行は保持)\n const firstElement = result[0];\n if (result.length > 0 && firstElement !== undefined && firstElement.length === 0) {\n result.shift();\n }\n return result.join(\"\\n\");\n}\n\n/**\n * JSONのディープマージを行う\n *\n * @param templateJson - テンプレートのJSON\n * @param existingJson - 既存のJSON(存在しない場合はnull)\n * @param jsonPaths - managed/seedパスの設定\n * @param filePath - ファイルパス(例: \"package.json\")\n * @returns マージ後のJSON\n */\nexport function mergeJson(\n templateJson: Record<string, unknown>,\n existingJson: Record<string, unknown> | null,\n jsonPaths: JsonPathsConfig,\n filePath = \"package.json\"\n): Record<string, unknown> {\n // Given: 既存JSONが存在しない場合\n if (existingJson === null) {\n // When: テンプレートをディープコピーして使用\n return JSON.parse(JSON.stringify(templateJson));\n }\n\n // When: ディープマージを実行\n return deepMergeWithPaths(\n templateJson,\n existingJson,\n jsonPaths,\n filePath,\n \"\"\n );\n}\n\n/**\n * パスを考慮したディープマージを行う\n *\n * @param template - テンプレートオブジェクト\n * @param existing - 既存オブジェクト\n * @param jsonPaths - managed/seedパスの設定\n * @param filePath - ファイルパス\n * @param currentPath - 現在のキーパス(例: \"scripts.dev\")\n * @returns マージ後のオブジェクト\n */\nfunction deepMergeWithPaths(\n template: Record<string, unknown>,\n existing: Record<string, unknown>,\n jsonPaths: JsonPathsConfig,\n filePath: string,\n currentPath: string\n): Record<string, unknown> {\n // 既存オブジェクトをディープコピー(参照を共有しないように)\n const result = JSON.parse(JSON.stringify(existing)) as Record<string, unknown>;\n\n for (const [key, templateValue] of Object.entries(template)) {\n const keyPath = currentPath ? `${currentPath}.${key}` : key;\n const existingValue = existing[key];\n\n // Given: このパスがmanagedに含まれるか確認\n if (isPathManaged(filePath, keyPath, jsonPaths)) {\n // Then: managedパスはテンプレート値でディープコピーして上書き\n result[key] = deepClone(templateValue);\n }\n // Given: このパスがseedに含まれるか確認\n else if (isPathSeed(filePath, keyPath, jsonPaths)) {\n // Given: seedパスでオブジェクトの場合、子キーもディープマージ\n if (\n typeof templateValue === \"object\" &&\n templateValue !== null &&\n !Array.isArray(templateValue) &&\n typeof existingValue === \"object\" &&\n existingValue !== null &&\n !Array.isArray(existingValue)\n ) {\n // Then: seedパス内でもディープマージ(既存にないキーのみ追加)\n result[key] = deepMergeWithPaths(\n templateValue as Record<string, unknown>,\n existingValue as Record<string, unknown>,\n jsonPaths,\n filePath,\n keyPath\n );\n } else if (!(key in existing)) {\n // Then: seedパスはローカル優先(キーが存在しない場合のみディープコピーして追加)\n result[key] = deepClone(templateValue);\n }\n // 既存値がある場合は何もしない(既存値を保持)\n }\n // Given: 両方がオブジェクトの場合\n else if (\n typeof templateValue === \"object\" &&\n templateValue !== null &&\n !Array.isArray(templateValue) &&\n typeof existingValue === \"object\" &&\n existingValue !== null &&\n !Array.isArray(existingValue)\n ) {\n // Then: 再帰的にディープマージ\n result[key] = deepMergeWithPaths(\n templateValue as Record<string, unknown>,\n existingValue as Record<string, unknown>,\n jsonPaths,\n filePath,\n keyPath\n );\n }\n // Given: それ以外のパス(テンプレートにのみ存在する場合)\n else if (!(key in existing)) {\n // Then: テンプレートの値をディープコピーして追加\n result[key] = deepClone(templateValue);\n }\n // 既存値がある場合は何もしない(既存値を保持)\n }\n\n return result;\n}\n\n/**\n * 値をディープコピーする(undefinedも正しく扱う)\n *\n * @param value - コピーする値\n * @returns ディープコピーされた値\n */\nfunction deepClone(value: unknown): unknown {\n if (value === undefined) {\n return undefined;\n }\n return JSON.parse(JSON.stringify(value));\n}\n\n/**\n * .einja-sync.json を読み込む\n *\n * @param targetDir - ターゲットディレクトリ\n * @returns メタデータ(存在しない場合はnull)\n */\nexport async function loadSyncMetadata(\n targetDir: string\n): Promise<SyncMetadata | null> {\n const metadataPath = `${targetDir}/.einja-sync.json`;\n\n if (!existsSync(metadataPath)) {\n return null;\n }\n\n try {\n const content = readFileSync(metadataPath, \"utf-8\");\n return JSON.parse(content) as SyncMetadata;\n } catch {\n return null;\n }\n}\n\n/**\n * .einja-sync.json を保存する\n *\n * @param targetDir - ターゲットディレクトリ\n * @param metadata - メタデータ\n */\nexport async function saveSyncMetadata(\n targetDir: string,\n metadata: SyncMetadata\n): Promise<void> {\n const metadataPath = `${targetDir}/.einja-sync.json`;\n ensureDir(dirname(metadataPath));\n writeFileSync(metadataPath, JSON.stringify(metadata, null, 2), \"utf-8\");\n}\n\n/**\n * ファイルマージの実行(テキスト/JSON自動判定)\n *\n * @param templatePath - テンプレートファイルのパス\n * @param targetPath - ターゲットファイルのパス\n * @param syncMetadata - 同期メタデータ\n * @returns マージ結果\n */\nexport async function mergeAndWriteFile(\n templatePath: string,\n targetPath: string,\n syncMetadata: SyncMetadata\n): Promise<{\n action: \"created\" | \"merged\" | \"skipped\" | \"overwritten\";\n path: string;\n}> {\n const templateContent = readFileSync(templatePath, \"utf-8\");\n const targetExists = existsSync(targetPath);\n const existingContent = targetExists ? readFileSync(targetPath, \"utf-8\") : null;\n\n // Given: ファイルがJSONかどうか判定\n const isJsonFile = targetPath.endsWith(\".json\");\n\n let mergedContent: string;\n let action: \"created\" | \"merged\" | \"skipped\" | \"overwritten\";\n\n if (!targetExists) {\n // When: ファイルが存在しない場合は新規作成\n mergedContent = templateContent;\n action = \"created\";\n } else if (isJsonFile) {\n // When: JSONファイルの場合はディープマージ\n try {\n const templateJson = JSON.parse(templateContent) as Record<string, unknown>;\n const existingJson = existingContent\n ? (JSON.parse(existingContent) as Record<string, unknown>)\n : null;\n const jsonPaths = syncMetadata.jsonPaths || { managed: {}, seed: {} };\n // ファイルパスからファイル名を抽出(例: \"/path/to/package.json\" → \"package.json\")\n const fileName = targetPath.split(\"/\").pop() || \"package.json\";\n const mergedJson = mergeJson(templateJson, existingJson, jsonPaths, fileName);\n mergedContent = JSON.stringify(mergedJson, null, 2);\n action = \"merged\";\n } catch {\n // Then: パースエラーの場合はテンプレートで上書き\n mergedContent = templateContent;\n action = \"overwritten\";\n }\n } else {\n // When: テキストファイルの場合はマーカーベースマージ\n mergedContent = mergeTextWithMarkers(templateContent, existingContent);\n\n // Then: 内容が変更されたかチェック\n if (mergedContent === existingContent) {\n action = \"skipped\";\n } else {\n action = \"merged\";\n }\n }\n\n // Then: ファイルに書き込み\n if (action !== \"skipped\") {\n ensureDir(dirname(targetPath));\n writeFileSync(targetPath, mergedContent, \"utf-8\");\n }\n\n return { action, path: targetPath };\n}\n\n/**\n * マーカーセクションの型定義\n */\ninterface MarkerSection {\n type: \"managed\" | \"seed\" | \"unmanaged\";\n startLine: number;\n endLine: number;\n content: string;\n id?: string;\n}\n\n/**\n * ファイル内容をパースしてマーカーセクションに分離する\n *\n * @param content - ファイル内容\n * @returns セクション配列\n */\nfunction parseMarkers(content: string): MarkerSection[] {\n const lines = content.split(\"\\n\");\n const sections: MarkerSection[] = [];\n let currentType: \"managed\" | \"seed\" | \"unmanaged\" = \"unmanaged\";\n let currentStartLine = 1;\n let currentContent: string[] = [];\n let currentId: string | undefined;\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i] as string;\n const lineNumber = i + 1;\n\n // Given: マーカー開始を検出\n const startMarker = parseStartMarker(line);\n if (startMarker) {\n if (currentType !== \"unmanaged\") {\n // Then: 入れ子のマーカーは無視\n currentContent.push(line);\n continue;\n }\n\n // When: 現在のunmanagedセクションを保存\n if (currentContent.length > 0 || sections.length === 0) {\n sections.push({\n type: \"unmanaged\",\n startLine: currentStartLine,\n endLine: lineNumber - 1,\n content: currentContent.join(\"\\n\"),\n });\n }\n\n // When: managed/seedセクション開始\n currentType = startMarker.type;\n currentId = startMarker.id;\n currentStartLine = lineNumber;\n currentContent = [line];\n }\n // Given: マーカー終了を検出\n else if (parseEndMarker(line)) {\n if (currentType === \"unmanaged\") {\n // Then: 対応するstartがない場合は無視\n currentContent.push(line);\n continue;\n }\n\n // When: マーカー終了行を追加\n currentContent.push(line);\n\n // When: managed/seedセクションを保存\n sections.push({\n type: currentType,\n startLine: currentStartLine,\n endLine: lineNumber,\n content: currentContent.join(\"\\n\"),\n id: currentId,\n });\n\n // When: unmanagedセクション開始\n currentType = \"unmanaged\";\n currentId = undefined;\n currentStartLine = lineNumber + 1;\n currentContent = [];\n }\n // Given: 通常行\n else {\n currentContent.push(line);\n }\n }\n\n // Then: 最後のセクションを保存\n if (currentContent.length > 0 || sections.length === 0) {\n sections.push({\n type: currentType,\n startLine: currentStartLine,\n endLine: lines.length,\n content: currentContent.join(\"\\n\"),\n id: currentId,\n });\n }\n\n return sections;\n}\n\n/**\n * 行がマーカー開始かどうかを判定し、種別とIDを返す\n *\n * @param line - 行内容\n * @returns マーカー情報またはnull\n */\nfunction parseStartMarker(\n line: string\n): { type: \"managed\" | \"seed\"; id?: string } | null {\n // Markdown managed\n const markdownManagedPattern =\n /^<!--\\s*@einja:managed:start(?:\\s+id=\"([^\"]+)\")?\\s*-->$/;\n let match = line.match(markdownManagedPattern);\n if (match) {\n return { type: \"managed\", id: match[1] || undefined };\n }\n\n // Markdown seed\n const markdownSeedPattern =\n /^<!--\\s*@einja:seed:start(?:\\s+id=\"([^\"]+)\")?\\s*-->$/;\n match = line.match(markdownSeedPattern);\n if (match) {\n return { type: \"seed\", id: match[1] || undefined };\n }\n\n // YAML/JSON managed\n const yamlManagedPattern = /^\\s*#\\s*@einja:managed:start(?:\\s+id=\"([^\"]+)\")?\\s*$/;\n match = line.match(yamlManagedPattern);\n if (match) {\n return { type: \"managed\", id: match[1] || undefined };\n }\n\n // YAML/JSON seed\n const yamlSeedPattern = /^\\s*#\\s*@einja:seed:start(?:\\s+id=\"([^\"]+)\")?\\s*$/;\n match = line.match(yamlSeedPattern);\n if (match) {\n return { type: \"seed\", id: match[1] || undefined };\n }\n\n return null;\n}\n\n/**\n * 行がマーカー終了かどうかを判定し、種別を返す\n *\n * @param line - 行内容\n * @returns マーカー種別またはnull\n */\nfunction parseEndMarker(line: string): \"managed\" | \"seed\" | null {\n // Markdown managed\n if (/^<!--\\s*@einja:managed:end\\s*-->$/.test(line)) {\n return \"managed\";\n }\n\n // Markdown seed\n if (/^<!--\\s*@einja:seed:end\\s*-->$/.test(line)) {\n return \"seed\";\n }\n\n // YAML/JSON managed\n if (/^\\s*#\\s*@einja:managed:end\\s*$/.test(line)) {\n return \"managed\";\n }\n\n // YAML/JSON seed\n if (/^\\s*#\\s*@einja:seed:end\\s*$/.test(line)) {\n return \"seed\";\n }\n\n return null;\n}\n\n/**\n * パスがmanagedに含まれるかチェック\n *\n * @param filePath - ファイルパス(例: \"package.json\")\n * @param keyPath - チェックするキーパス(例: \"scripts.dev\")\n * @param jsonPaths - JSONパス設定\n * @returns managedに含まれる場合true\n */\nfunction isPathManaged(\n filePath: string,\n keyPath: string,\n jsonPaths: JsonPathsConfig\n): boolean {\n const managedPaths = jsonPaths.managed[filePath] || [];\n // keyPath が managedPaths のいずれかで始まるかチェック\n // 例: keyPath=\"scripts.dev\" が managedPaths=[\"scripts.dev\"] にマッチ\n // または keyPath=\"scripts.dev\" が managedPaths=[\"scripts\"] にマッチ\n return managedPaths.some(\n (p) => keyPath === p || keyPath.startsWith(`${p}.`)\n );\n}\n\n/**\n * パスがseedに含まれるかチェック\n *\n * @param filePath - ファイルパス(例: \"package.json\")\n * @param keyPath - チェックするキーパス(例: \"scripts.custom\")\n * @param jsonPaths - JSONパス設定\n * @returns seedに含まれる場合true\n */\nfunction isPathSeed(\n filePath: string,\n keyPath: string,\n jsonPaths: JsonPathsConfig\n): boolean {\n const seedPaths = jsonPaths.seed[filePath] || [];\n // keyPath が seedPaths のいずれかで始まるかチェック\n return seedPaths.some((p) => keyPath === p || keyPath.startsWith(`${p}.`));\n}\n","import { readdir } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport type {\n AddOptions,\n AppComponent,\n SyncMetadata,\n} from \"../../types/index.js\";\nimport { mergeAndWriteFile } from \"../../utils/merger.js\";\nimport * as logger from \"../../utils/logger.js\";\n\n/**\n * apps/ ディレクトリにコンポーネントを追加\n */\nexport async function addApps(\n options: AddOptions,\n components: AppComponent[],\n syncMetadata: SyncMetadata\n): Promise<{ added: string[]; skipped: string[]; merged: string[] }> {\n const added: string[] = [];\n const skipped: string[] = [];\n const merged: string[] = [];\n\n const { targetDir, templateDir, config } = options;\n\n for (const component of components) {\n const componentName = component === \"web\" ? \"web\" : component;\n\n const srcDir = join(templateDir, \"apps\", componentName);\n const destDir = join(targetDir, \"apps\", componentName);\n\n logger.info(`Adding app component: ${componentName}`);\n\n await copyDirectory(\n srcDir,\n destDir,\n { added, skipped, merged },\n config.dryRun,\n syncMetadata\n );\n }\n\n return { added, skipped, merged };\n}\n\n/**\n * ディレクトリを再帰的にコピー\n */\nasync function copyDirectory(\n srcDir: string,\n destDir: string,\n result: { added: string[]; skipped: string[]; merged: string[] },\n dryRun: boolean,\n syncMetadata: SyncMetadata\n): Promise<void> {\n const entries = await readdir(srcDir, { withFileTypes: true });\n\n for (const entry of entries) {\n const srcPath = join(srcDir, entry.name);\n const destPath = join(destDir, entry.name);\n\n if (entry.isDirectory()) {\n await copyDirectory(srcPath, destPath, result, dryRun, syncMetadata);\n } else {\n if (!dryRun) {\n const mergeResult = await mergeAndWriteFile(\n srcPath,\n destPath,\n syncMetadata\n );\n\n if (mergeResult.action === \"created\") {\n result.added.push(destPath);\n } else if (mergeResult.action === \"skipped\") {\n result.skipped.push(destPath);\n } else if (mergeResult.action === \"merged\") {\n result.merged.push(destPath);\n }\n } else {\n // dry-runモードではスキップ\n result.skipped.push(destPath);\n }\n }\n }\n}\n","import { readdir, readFile } from \"node:fs/promises\";\nimport { join, relative, sep } from \"node:path\";\nimport type { AddOptions, SyncMetadata } from \"../../types/index.js\";\nimport { mergeAndWriteFile } from \"../../utils/merger.js\";\nimport * as logger from \"../../utils/logger.js\";\n\n/**\n * プロジェクト直下の設定ファイルを追加\n */\nexport async function addConfigFiles(\n options: AddOptions,\n syncMetadata: SyncMetadata\n): Promise<{ added: string[]; skipped: string[]; merged: string[] }> {\n const added: string[] = [];\n const skipped: string[] = [];\n const merged: string[] = [];\n\n const { targetDir, templateDir, config } = options;\n\n logger.info(\"Adding config files from template root\");\n\n // 除外パターン\n const excludedPaths = new Set([\n \".claude\",\n \"docs/einja\",\n \"CLAUDE.md\",\n \".mcp.json\",\n \"node_modules\",\n \".turbo\",\n \"next-env.d.ts\",\n \"styled-system\",\n \"pnpm-lock.yaml\",\n \"package-lock.json\",\n \"packages\",\n \"apps\",\n ]);\n\n // .gitignore のパターンを読み込み\n const gitignorePatterns = await loadGitignorePatterns(templateDir);\n\n await copyConfigDirectory(\n templateDir,\n targetDir,\n templateDir, // rootDir として templateDir を渡す\n { added, skipped, merged },\n config.dryRun,\n excludedPaths,\n gitignorePatterns,\n syncMetadata\n );\n\n return { added, skipped, merged };\n}\n\n/**\n * .gitignore のパターンを読み込み\n */\nasync function loadGitignorePatterns(templateDir: string): Promise<Set<string>> {\n const patterns = new Set<string>();\n const gitignorePath = join(templateDir, \".gitignore\");\n\n try {\n const content = await readFile(gitignorePath, \"utf-8\");\n const lines = content.split(\"\\n\");\n\n for (const line of lines) {\n const trimmed = line.trim();\n // コメントと空行を除外\n if (trimmed && !trimmed.startsWith(\"#\")) {\n // 先頭の / を削除\n const pattern = trimmed.startsWith(\"/\") ? trimmed.slice(1) : trimmed;\n patterns.add(pattern);\n }\n }\n } catch {\n // .gitignore が存在しない場合は無視\n }\n\n return patterns;\n}\n\n/**\n * 設定ファイルのディレクトリを再帰的にコピー\n */\nasync function copyConfigDirectory(\n srcDir: string,\n destDir: string,\n rootDir: string, // テンプレートルートディレクトリ\n result: { added: string[]; skipped: string[]; merged: string[] },\n dryRun: boolean,\n excludedPaths: Set<string>,\n gitignorePatterns: Set<string>,\n syncMetadata: SyncMetadata\n): Promise<void> {\n const entries = await readdir(srcDir, { withFileTypes: true });\n\n for (const entry of entries) {\n const srcPath = join(srcDir, entry.name);\n const destPath = join(destDir, entry.name);\n // rootDir からの相対パスを計算(一貫性を保つ)\n const rawRelativePath = relative(rootDir, srcPath);\n // Windows対応: パス区切り文字をPOSIX形式(/)に正規化\n const relativePath = rawRelativePath.split(sep).join(\"/\");\n\n // 除外パターンに一致するかチェック\n if (shouldExclude(relativePath, excludedPaths, gitignorePatterns)) {\n continue;\n }\n\n if (entry.isDirectory()) {\n await copyConfigDirectory(\n srcPath,\n destPath,\n rootDir, // rootDir を引き継ぐ\n result,\n dryRun,\n excludedPaths,\n gitignorePatterns,\n syncMetadata\n );\n } else {\n if (!dryRun) {\n const mergeResult = await mergeAndWriteFile(\n srcPath,\n destPath,\n syncMetadata\n );\n\n if (mergeResult.action === \"created\") {\n result.added.push(destPath);\n } else if (mergeResult.action === \"skipped\") {\n result.skipped.push(destPath);\n } else if (mergeResult.action === \"merged\") {\n result.merged.push(destPath);\n }\n } else {\n // dry-runモードではスキップ\n result.skipped.push(destPath);\n }\n }\n }\n}\n\n/**\n * パスを除外すべきか判定\n */\nfunction shouldExclude(\n relativePath: string,\n excludedPaths: Set<string>,\n gitignorePatterns: Set<string>\n): boolean {\n // 除外パスに完全一致または部分一致\n for (const excluded of excludedPaths) {\n if (relativePath === excluded || relativePath.startsWith(`${excluded}/`)) {\n return true;\n }\n }\n\n // .gitignore パターンに一致\n for (const pattern of gitignorePatterns) {\n // シンプルなパターンマッチング(ワイルドカード対応)\n if (matchPattern(relativePath, pattern)) {\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * シンプルなパターンマッチング\n */\nfunction matchPattern(path: string, pattern: string): boolean {\n // パターンの最後が / の場合、ディレクトリのみ一致\n if (pattern.endsWith(\"/\")) {\n const dirPattern = pattern.slice(0, -1);\n return path === dirPattern || path.startsWith(`${dirPattern}/`);\n }\n\n // * を含むパターン\n if (pattern.includes(\"*\")) {\n const regexPattern = pattern\n .replace(/\\./g, \"\\\\.\")\n .replace(/\\*/g, \".*\");\n return new RegExp(`^${regexPattern}$`).test(path);\n }\n\n // 完全一致または部分一致\n return path === pattern || path.startsWith(`${pattern}/`);\n}\n"],"mappings":"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","names":["readFileSync","fileURLToPath","dirname","join","existsSync","ora","dirname","join","readFileSync","writeFileSync","existsSync","__filename","__dirname","dirname","join","error","chalk","inquirer","inquirer","error","chalk","existsSync","error","ora","existsSync","join","ora","inquirer","join","inquirer","join","inquirer","error","join","readFileSync","writeFileSync","join","packageJsonPath","join","readFileSync","writeFileSync","join","join","join","join","join","join","writeFileSync","join","writeFileSync","packageJsonPath","join","existsSync","ora","error","existsSync","readFile","dirname","join","fileURLToPath","ora","inquirer","join","readFileSync","writeFileSync","existsSync","dirname","existsSync","readFileSync","dirname","writeFileSync","join","readdir","join","join","copyDirectory","readdir","readdir","join","relative","join","readdir","relative","getTemplatePath","__filename","fileURLToPath","__dirname","dirname","join","existsSync","readFile","ora","error","packageJsonPath","packageJson","__filename","fileURLToPath","__dirname","dirname","join","readFileSync"]}
|
|
1
|
+
{"version":3,"sources":["../src/cli.ts","../src/commands/create.ts","../src/prompts/project.ts","../src/generators/template.ts","../src/utils/fs.ts","../src/utils/logger.ts","../src/generators/post-setup.ts","../src/commands/setup.ts","../src/prompts/setup.ts","../src/generators/tools/direnv.ts","../src/generators/tools/dotenvx.ts","../src/utils/package-json.ts","../src/generators/tools/volta.ts","../src/generators/tools/biome.ts","../src/generators/tools/husky.ts","../src/commands/add.ts","../src/prompts/add.ts","../src/generators/partials/packages.ts","../src/utils/merger.ts","../src/generators/partials/apps.ts","../src/generators/partials/config.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport { readFileSync } from \"node:fs\";\nimport { fileURLToPath } from \"node:url\";\nimport { dirname, join } from \"node:path\";\nimport { createCommand } from \"./commands/create.js\";\nimport { setupCommand } from \"./commands/setup.js\";\nimport { addCommand } from \"./commands/add.js\";\n\n// package.jsonからバージョン情報を読み込み\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\nconst packageJsonPath = join(__dirname, \"../package.json\");\nconst packageJson = JSON.parse(readFileSync(packageJsonPath, \"utf-8\"));\n\nconst program = new Command();\n\nprogram\n .name(\"create-einja-app\")\n .description(\"CLI tool to create new projects with Einja Management Template\")\n .version(packageJson.version);\n\n// createコマンド\nprogram\n .argument(\"[project-name]\", \"Project name\")\n .option(\"--skip-git\", \"Skip git initialization\")\n .option(\"--skip-install\", \"Skip package installation\")\n .option(\"-y, --yes\", \"Skip interactive prompts\")\n .action(\n async (\n projectName: string | undefined,\n options: {\n skipGit?: boolean;\n skipInstall?: boolean;\n yes?: boolean;\n }\n ) => {\n await createCommand(projectName, options);\n }\n );\n\n// setupコマンド\nprogram\n .command(\"setup\")\n .description(\"Setup tools for existing project\")\n .action(async () => {\n await setupCommand();\n });\n\n// addコマンド\nprogram\n .command(\"add\")\n .description(\"Add einja components to existing monorepo\")\n .option(\"-y, --yes\", \"Skip prompts and use defaults (select all)\")\n .option(\"--all\", \"Select all components (same as -y)\")\n .option(\"--dry-run\", \"Preview changes without making them\")\n .action(\n async (options: { yes?: boolean; all?: boolean; dryRun?: boolean }) => {\n await addCommand({\n skipPrompts: options.yes || options.all || false,\n dryRun: options.dryRun || false,\n });\n }\n );\n\nprogram.parse();\n","import { existsSync, readdirSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport ora from \"ora\";\nimport { promptProjectConfig, type ProjectConfig } from \"../prompts/project.js\";\nimport { generateTemplate } from \"../generators/template.js\";\nimport { execPostSetup } from \"../generators/post-setup.js\";\nimport * as logger from \"../utils/logger.js\";\n\n/**\n * ディレクトリが空かどうかを確認\n * @param dirPath - ディレクトリパス\n * @returns 空の場合true、存在しないかファイルがある場合false\n */\nfunction isDirectoryEmpty(dirPath: string): boolean {\n if (!existsSync(dirPath)) {\n return true;\n }\n const files = readdirSync(dirPath);\n // .git, .DS_Store などの隠しファイルは無視(空のGitリポジトリは空とみなす)\n const significantFiles = files.filter(\n (f) => !f.startsWith(\".\")\n );\n return significantFiles.length === 0;\n}\n\n/**\n * CreateOptions型\n * createコマンドのオプション\n */\ninterface CreateOptions {\n skipGit?: boolean;\n skipInstall?: boolean;\n yes?: boolean;\n}\n\n/**\n * プロジェクト名のバリデーション\n * @param projectName - プロジェクト名\n * @returns エラーメッセージ(問題なければundefined)\n */\nfunction validateProjectName(projectName: string): string | undefined {\n const regex = /^[a-zA-Z][a-zA-Z0-9_-]{0,49}$/;\n if (!regex.test(projectName)) {\n return \"プロジェクト名は英字で始まり、英数字・ハイフン・アンダースコアのみ使用できます(1〜50文字)\";\n }\n return undefined;\n}\n\n/**\n * プロジェクトディレクトリの存在確認\n * @param targetPath - ターゲットパス\n * @returns 存在する場合true\n */\nfunction checkProjectExists(targetPath: string): boolean {\n return existsSync(targetPath);\n}\n\n\n/**\n * createコマンドの実装\n * @param projectName - プロジェクト名(オプション)\n * @param options - コマンドオプション\n */\nexport async function createCommand(\n projectName: string | undefined,\n options: CreateOptions\n): Promise<void> {\n try {\n // プロンプトで設定収集\n let config: ProjectConfig;\n\n if (options.yes && projectName) {\n // --yes オプション: デフォルト値を使用\n const error = validateProjectName(projectName);\n if (error) {\n logger.error(error);\n process.exit(1);\n }\n\n config = {\n projectName,\n packageScope: \"@repo\",\n template: \"default\",\n authMethod: \"default\",\n tools: {\n direnv: true,\n dotenvx: true,\n volta: true,\n biome: true,\n husky: true,\n },\n setupEinjaCli: true,\n worktreeConfig: undefined,\n useCurrentDir: false,\n };\n\n logger.info(`プロジェクト名: ${config.projectName}`);\n logger.info(`テンプレート: ${config.template}`);\n logger.info(`認証方式: ${config.authMethod}`);\n } else {\n // 対話式プロンプト\n config = await promptProjectConfig(projectName);\n }\n\n // ターゲットパスの解決\n const targetPath = config.useCurrentDir\n ? process.cwd()\n : resolve(process.cwd(), config.projectName);\n\n // ディレクトリの確認\n if (config.useCurrentDir) {\n // カレントディレクトリに展開する場合、空かどうか確認\n if (!isDirectoryEmpty(targetPath)) {\n logger.error(\"現在のディレクトリにファイルが存在します\");\n logger.info(\"空のディレクトリで実行するか、サブディレクトリを作成してください\");\n process.exit(1);\n }\n } else {\n // サブディレクトリを作成する場合、存在確認\n if (checkProjectExists(targetPath)) {\n logger.error(`ディレクトリ '${config.projectName}' は既に存在します`);\n logger.info(\"別の名前を指定するか、既存ディレクトリを削除してください\");\n process.exit(1);\n }\n }\n\n // テンプレート展開\n const spinner = ora(\"プロジェクトを作成中...\").start();\n\n try {\n await generateTemplate(config, targetPath);\n spinner.succeed(\"プロジェクトを作成しました\");\n } catch (error) {\n spinner.fail(\"プロジェクトの作成に失敗しました\");\n throw error;\n }\n\n // 生成後セットアップ実行\n await execPostSetup(config, targetPath, {\n skipGit: options.skipGit,\n skipInstall: options.skipInstall,\n });\n } catch (error) {\n logger.error(\"エラーが発生しました:\");\n if (error instanceof Error) {\n logger.error(error.message);\n } else {\n logger.error(String(error));\n }\n process.exit(1);\n }\n}\n","import inquirer from \"inquirer\";\nimport type { ProjectConfig, WorktreeConfig, App } from \"../types/index.js\";\n\nexport type { ProjectConfig, WorktreeConfig, App };\n\n/**\n * プロジェクト作成用プロンプトを実行\n * @param defaultProjectName - デフォルトのプロジェクト名\n * @returns ProjectConfig - プロジェクト設定\n */\nexport async function promptProjectConfig(\n defaultProjectName?: string\n): Promise<ProjectConfig> {\n const answers = await inquirer.prompt([\n {\n type: \"input\",\n name: \"projectName\",\n message: \"プロジェクト名:\",\n default: defaultProjectName || \"my-project\",\n validate: (input: string): boolean | string => {\n // 英数字・ハイフン・アンダースコアのみ許可、先頭は英字、1〜50文字\n const regex = /^[a-zA-Z][a-zA-Z0-9_-]{0,49}$/;\n if (!regex.test(input)) {\n return \"プロジェクト名は英字で始まり、英数字・ハイフン・アンダースコアのみ使用できます(1〜50文字)\";\n }\n return true;\n },\n },\n {\n type: \"confirm\",\n name: \"useCurrentDir\",\n message: \"今いるディレクトリに直接作成しますか?(Noならサブディレクトリを作成)\",\n default: false,\n },\n {\n type: \"input\",\n name: \"packageScope\",\n message: \"パッケージスコープ:\",\n default: \"@repo\",\n validate: (input: string): boolean | string => {\n // @で始まり、英数字・ハイフン・アンダースコアのみ許可\n const regex = /^@[a-zA-Z][a-zA-Z0-9_-]{0,49}$/;\n if (!regex.test(input)) {\n return \"パッケージスコープは@で始まり、英数字・ハイフン・アンダースコアのみ使用できます\";\n }\n return true;\n },\n },\n {\n type: \"list\",\n name: \"authMethod\",\n message: \"認証機能:\",\n choices: [\n { name: \"NextAuth.js を使用\", value: \"default\" },\n { name: \"なし(認証ファイルを除外)\", value: \"none\" },\n ],\n default: \"default\",\n },\n {\n type: \"confirm\",\n name: \"setupEinjaCli\",\n message: \"@einja/dev-cli を自動セットアップしますか?\",\n default: true,\n },\n {\n type: \"confirm\",\n name: \"customizeWorktree\",\n message: \"Worktree設定をカスタマイズしますか?\",\n default: false,\n },\n ]);\n\n // ツールは全て有効(固定)\n const tools = {\n direnv: true,\n dotenvx: true,\n volta: true,\n biome: true,\n husky: true,\n };\n\n let worktreeConfig: WorktreeConfig | undefined;\n\n // Worktree設定カスタマイズ\n if (answers.customizeWorktree) {\n const worktreeAnswers = await inquirer.prompt([\n {\n type: \"input\",\n name: \"postgresPort\",\n message: \"PostgreSQLポート番号:\",\n default: \"25432\",\n validate: (input: string): boolean | string => {\n const port = Number.parseInt(input, 10);\n if (Number.isNaN(port) || port < 1024 || port > 65535) {\n return \"ポート番号は1024〜65535の範囲で指定してください\";\n }\n return true;\n },\n },\n {\n type: \"input\",\n name: \"containerName\",\n message: \"Dockerコンテナ名:\",\n default: `${answers.projectName}-postgres`,\n },\n {\n type: \"input\",\n name: \"appId\",\n message: \"アプリケーションID:\",\n default: \"web\",\n },\n {\n type: \"input\",\n name: \"portRangeStart\",\n message: \"アプリポート範囲開始:\",\n default: \"3000\",\n validate: (input: string): boolean | string => {\n const port = Number.parseInt(input, 10);\n if (Number.isNaN(port) || port < 1024 || port > 65535) {\n return \"ポート番号は1024〜65535の範囲で指定してください\";\n }\n return true;\n },\n },\n {\n type: \"input\",\n name: \"rangeSize\",\n message: \"ポート範囲サイズ:\",\n default: \"1000\",\n validate: (input: string): boolean | string => {\n const size = Number.parseInt(input, 10);\n if (Number.isNaN(size) || size < 1 || size > 10000) {\n return \"範囲サイズは1〜10000の範囲で指定してください\";\n }\n return true;\n },\n },\n ]);\n\n worktreeConfig = {\n postgres: {\n port: Number.parseInt(worktreeAnswers.postgresPort, 10),\n containerName: worktreeAnswers.containerName,\n },\n apps: [\n {\n id: worktreeAnswers.appId,\n portRangeStart: Number.parseInt(worktreeAnswers.portRangeStart, 10),\n rangeSize: Number.parseInt(worktreeAnswers.rangeSize, 10),\n },\n ],\n };\n }\n\n return {\n projectName: answers.projectName,\n packageScope: answers.packageScope,\n template: \"default\" as const,\n authMethod: answers.authMethod,\n tools,\n setupEinjaCli: answers.setupEinjaCli,\n worktreeConfig,\n useCurrentDir: answers.useCurrentDir,\n };\n}\n","import fsExtra from \"fs-extra\";\nconst { copySync, readFileSync, writeFileSync, existsSync, removeSync } = fsExtra;\nimport { glob } from \"glob\";\nimport { dirname, join, relative } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport type { ProjectConfig } from \"../prompts/project.js\";\nimport { ensureDir } from \"../utils/fs.js\";\nimport * as logger from \"../utils/logger.js\";\n\n/**\n * TemplateVariables型\n * テンプレート変数(プレースホルダー置換用)\n */\nexport interface TemplateVariables {\n projectName: string;\n packageName: string;\n description: string;\n}\n\n/**\n * テンプレートディレクトリのパスを取得\n * @param templateName - テンプレート名\n * @returns テンプレートディレクトリパス\n */\nfunction getTemplatePath(templateName: string): string {\n const __filename = fileURLToPath(import.meta.url);\n const __dirname = dirname(__filename);\n\n // バンドル後(dist/cli.js)とソース実行(src/generators/template.ts)の両方に対応\n // dist/cli.js -> ../templates/ (1階層上)\n // src/generators/template.ts -> ../../templates/ (2階層上)\n const distPath = join(__dirname, \"../templates\", templateName);\n const srcPath = join(__dirname, \"../../templates\", templateName);\n\n if (existsSync(distPath)) {\n return distPath;\n }\n if (existsSync(srcPath)) {\n return srcPath;\n }\n\n // どちらも存在しない場合はdistPathを返す(エラーメッセージ用)\n return distPath;\n}\n\n/**\n * 認証方式に応じた除外パターンを取得\n * @param authMethod - 認証方式\n * @returns 除外パターン配列\n */\nfunction getAuthExcludePatterns(authMethod: string): string[] {\n if (authMethod === \"none\") {\n return [\n \"**/api/auth/**\",\n \"**/packages/auth/**\",\n \"**/signin/**\",\n \"**/signup/**\",\n ];\n }\n return [];\n}\n\n/**\n * ファイル内容のプレースホルダー変数を置換\n * @param content - ファイル内容\n * @param variables - 置換する変数\n * @returns 置換後の内容\n */\nfunction replacePlaceholders(\n content: string,\n variables: TemplateVariables\n): string {\n let result = content;\n\n // {{projectName}} の置換\n result = result.replaceAll(\"{{projectName}}\", variables.projectName);\n\n // {{packageName}}/ の置換(長いパターンを先に置換)\n result = result.replaceAll(\"{{packageName}}/\", `${variables.packageName}/`);\n\n // {{packageName}} の置換\n result = result.replaceAll(\"{{packageName}}\", variables.packageName);\n\n // {{description}} の置換\n result = result.replaceAll(\"{{description}}\", variables.description);\n\n // @repo/ の置換(パッケージスコープ)\n result = result.replaceAll(\"@repo/\", `${variables.packageName}/`);\n\n return result;\n}\n\n/**\n * ファイルの変数置換処理\n * @param filePath - ファイルパス\n * @param variables - 置換する変数\n */\nfunction processFileVariables(\n filePath: string,\n variables: TemplateVariables\n): void {\n // バイナリファイルは処理しない\n const binaryExtensions = [\".png\", \".jpg\", \".jpeg\", \".gif\", \".ico\", \".woff\", \".woff2\", \".ttf\", \".eot\"];\n if (binaryExtensions.some((ext) => filePath.endsWith(ext))) {\n return;\n }\n\n try {\n const content = readFileSync(filePath, \"utf-8\");\n const replaced = replacePlaceholders(content, variables);\n\n if (content !== replaced) {\n writeFileSync(filePath, replaced, \"utf-8\");\n }\n } catch (error) {\n // 読み込みに失敗した場合はスキップ(バイナリファイル等)\n logger.warn(`変数置換をスキップ: ${filePath}`);\n }\n}\n\n/**\n * .templateファイルのリネーム処理\n * @param targetPath - ターゲットディレクトリパス\n */\nfunction renameTemplateFiles(targetPath: string): void {\n const templateFiles = glob.sync(\"**/*.template\", {\n cwd: targetPath,\n absolute: true,\n dot: true,\n });\n\n for (const file of templateFiles) {\n const newPath = file.replace(/\\.template$/, \"\");\n copySync(file, newPath);\n removeSync(file);\n }\n}\n\n/**\n * gitignoreファイルをリネーム処理(gitignore → .gitignore)\n * @param targetPath - ターゲットディレクトリパス\n */\nfunction renameSpecialFiles(targetPath: string): void {\n const gitignoreFiles = glob.sync(\"**/gitignore\", {\n cwd: targetPath,\n absolute: true,\n dot: true,\n });\n\n for (const file of gitignoreFiles) {\n const dir = dirname(file);\n const newPath = join(dir, \".gitignore\");\n\n if (existsSync(file)) {\n copySync(file, newPath);\n removeSync(file);\n }\n }\n}\n\n/**\n * 認証方式に応じたファイル除外処理\n * @param targetPath - ターゲットディレクトリパス\n * @param authMethod - 認証方式\n */\nfunction excludeAuthFiles(targetPath: string, authMethod: string): void {\n const excludePatterns = getAuthExcludePatterns(authMethod);\n\n if (excludePatterns.length === 0) {\n return;\n }\n\n logger.info(\"認証方式に応じたファイルを除外中...\");\n\n for (const pattern of excludePatterns) {\n const files = glob.sync(pattern, {\n cwd: targetPath,\n absolute: true,\n dot: true,\n });\n\n for (const file of files) {\n removeSync(file);\n }\n }\n}\n\n/**\n * テンプレートを展開\n * @param config - プロジェクト設定\n * @param targetPath - ターゲットディレクトリパス\n */\nexport async function generateTemplate(\n config: ProjectConfig,\n targetPath: string\n): Promise<void> {\n const templatePath = getTemplatePath(config.template);\n\n // テンプレートディレクトリの存在確認\n if (!existsSync(templatePath)) {\n throw new Error(`テンプレートが見つかりません: ${config.template}`);\n }\n\n logger.info(\"テンプレートをコピー中...\");\n\n // ターゲットディレクトリの作成\n await ensureDir(targetPath);\n\n // テンプレートファイルをコピー\n copySync(templatePath, targetPath, {\n filter: (src: string): boolean => {\n const relativePath = relative(templatePath, src);\n\n // 除外パターン(ディレクトリ名やファイル名として完全一致するもの)\n // 注意: .env.*ファイルはテンプレートに含め、pnpm env:updateで再設定する\n const excludePatterns = [\n \"node_modules\",\n \".git\",\n \".next\",\n \".turbo\",\n \"out\",\n \"dist\",\n \"logs\",\n \".env\", // フェイルセーフ(暗号化キーファイル)\n \".DS_Store\",\n \"Thumbs.db\",\n \"coverage\",\n ];\n\n // ファイル拡張子パターン(*.log など)\n const excludeExtensions = [\".log\"];\n\n // パスセグメントに分割(/ または \\ で分割)\n const pathSegments = relativePath.split(/[/\\\\]/);\n\n // パスセグメント単位で完全一致チェック\n // これにより \"out\" は \"out/\" ディレクトリにマッチするが\n // \"logout-button.tsx\" にはマッチしない\n const matchesExcludePattern = excludePatterns.some((pattern) =>\n pathSegments.includes(pattern)\n );\n\n // 拡張子チェック\n const matchesExtension = excludeExtensions.some((ext) =>\n relativePath.endsWith(ext)\n );\n\n return !matchesExcludePattern && !matchesExtension;\n },\n });\n\n // 認証方式に応じたファイル除外\n excludeAuthFiles(targetPath, config.authMethod);\n\n // .templateファイルのリネーム\n renameTemplateFiles(targetPath);\n\n // gitignore → .gitignore リネーム\n renameSpecialFiles(targetPath);\n\n // 変数置換\n logger.info(\"プレースホルダー変数を置換中...\");\n\n const variables: TemplateVariables = {\n projectName: config.projectName,\n packageName: config.packageScope,\n description: `${config.projectName} - Einja Management Template`,\n };\n\n const allFiles = glob.sync(\"**/*\", {\n cwd: targetPath,\n absolute: true,\n nodir: true,\n dot: true,\n });\n\n for (const file of allFiles) {\n processFileVariables(file, variables);\n }\n\n logger.success(\"テンプレート展開完了\");\n}\n","import { existsSync, readFileSync, writeFileSync, appendFileSync, mkdirSync } from \"node:fs\";\nimport { join, dirname } from \"node:path\";\nimport type { ConflictStrategy } from \"../types/index.js\";\n\n/**\n * 競合戦略に基づいてファイルを書き込む\n */\nexport function writeWithStrategy(\n filePath: string,\n content: string,\n strategy: ConflictStrategy\n): boolean {\n const exists = existsSync(filePath);\n\n if (!exists) {\n ensureDir(dirname(filePath));\n writeFileSync(filePath, content, \"utf-8\");\n return true;\n }\n\n switch (strategy) {\n case \"overwrite\": {\n writeFileSync(filePath, content, \"utf-8\");\n return true;\n }\n\n case \"merge\": {\n const existingContent = readFileSync(filePath, \"utf-8\");\n const mergedContent = mergeContent(existingContent, content);\n writeFileSync(filePath, mergedContent, \"utf-8\");\n return true;\n }\n\n case \"skip\": {\n return false;\n }\n\n default: {\n const _exhaustiveCheck: never = strategy;\n throw new Error(`Unknown strategy: ${_exhaustiveCheck}`);\n }\n }\n}\n\n/**\n * 既存コンテンツと新規コンテンツをマージする\n */\nfunction mergeContent(existing: string, newContent: string): string {\n if (existing.includes(newContent)) {\n return existing;\n }\n return `${existing}\\n${newContent}`;\n}\n\n/**\n * ディレクトリが存在しない場合は作成する\n */\nexport function ensureDir(dirPath: string): void {\n if (!existsSync(dirPath)) {\n mkdirSync(dirPath, { recursive: true });\n }\n}\n\n/**\n * .gitignoreに行を追加する\n */\nexport function appendToGitignore(targetDir: string, line: string): void {\n const gitignorePath = join(targetDir, \".gitignore\");\n\n if (!existsSync(gitignorePath)) {\n writeFileSync(gitignorePath, `${line}\\n`, \"utf-8\");\n return;\n }\n\n const content = readFileSync(gitignorePath, \"utf-8\");\n if (content.includes(line)) {\n return;\n }\n\n appendFileSync(gitignorePath, `\\n${line}\\n`, \"utf-8\");\n}\n\n/**\n * ファイルが存在するか確認する\n */\nexport function fileExists(filePath: string): boolean {\n return existsSync(filePath);\n}\n","import chalk from \"chalk\";\n\n/**\n * 情報メッセージを出力\n * @param message - メッセージ\n */\nexport function info(message: string): void {\n console.log(chalk.blue(\"ℹ\"), message);\n}\n\n/**\n * 成功メッセージを出力(緑色)\n * @param message - メッセージ\n */\nexport function success(message: string): void {\n console.log(chalk.green(\"✔\"), message);\n}\n\n/**\n * 警告メッセージを出力(黄色)\n * @param message - メッセージ\n */\nexport function warn(message: string): void {\n console.log(chalk.yellow(\"⚠\"), message);\n}\n\n/**\n * エラーメッセージを出力(赤色)\n * @param message - メッセージ\n */\nexport function error(message: string): void {\n console.error(chalk.red(\"✖\"), message);\n}\n","import { execa, execaSync } from \"execa\";\nimport chalk from \"chalk\";\nimport inquirer from \"inquirer\";\nimport ora from \"ora\";\nimport type { ProjectConfig } from \"../types/index.js\";\nimport * as logger from \"../utils/logger.js\";\n\n/**\n * PostSetupOptions型\n * 生成後セットアップのオプション\n */\nexport interface PostSetupOptions {\n skipGit?: boolean;\n skipInstall?: boolean;\n}\n\n/**\n * direnvコマンドが利用可能かチェック\n * @returns direnvコマンドが利用可能な場合true\n */\nfunction isDirenvAvailable(): boolean {\n try {\n execaSync(\"which\", [\"direnv\"]);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * direnv allowの確認プロンプトを表示し、実行する\n * @param targetPath - プロジェクトディレクトリ\n */\nasync function promptAndExecuteDirenvAllow(targetPath: string): Promise<void> {\n try {\n const { shouldAllow } = await inquirer.prompt([\n {\n type: \"confirm\",\n name: \"shouldAllow\",\n message: \"direnv allow を実行しますか?(環境変数を有効化します)\",\n default: true,\n },\n ]);\n\n if (shouldAllow) {\n try {\n await execa(\"direnv\", [\"allow\"], { cwd: targetPath });\n logger.success(\"direnv allow を実行しました\");\n } catch (error) {\n logger.warn(\"direnv allow の実行に失敗しました\");\n logger.info(\"後で手動で 'direnv allow' を実行してください\");\n }\n } else {\n logger.info(\"direnv allow をスキップしました\");\n logger.info(\"後で手動で 'direnv allow' を実行してください\");\n }\n } catch (error) {\n logger.info(\"direnv allow をスキップしました\");\n }\n}\n\n/**\n * 完了メッセージを表示\n * @param config - プロジェクト設定\n */\nfunction printCompletionMessage(config: ProjectConfig): void {\n console.log();\n logger.success(\"プロジェクトの作成が完了しました!\");\n console.log();\n console.log(chalk.bold(\"次のステップ:\"));\n console.log();\n console.log(chalk.cyan(` cd ${config.projectName}`));\n console.log(chalk.cyan(\" pnpm env:update # 環境変数を設定\"));\n console.log(chalk.cyan(\" docker-compose up -d postgres\"));\n console.log(chalk.cyan(\" pnpm dev\"));\n console.log();\n console.log(chalk.gray(\"開発サーバー: ターミナルに表示されるURLを確認\"));\n console.log();\n console.log(\n chalk.yellow(\"⚠ 重要: \") +\n chalk.gray(\"pnpm env:update で環境変数を自分のプロジェクト用に再設定してください\")\n );\n console.log();\n console.log(chalk.gray(\"詳細は README.md をご確認ください。\"));\n console.log();\n}\n\n/**\n * 生成後セットアップを実行\n * @param config - プロジェクト設定\n * @param targetPath - プロジェクトディレクトリ\n * @param options - セットアップオプション\n */\nexport async function execPostSetup(\n config: ProjectConfig,\n targetPath: string,\n options: PostSetupOptions\n): Promise<void> {\n const { skipGit, skipInstall } = options;\n\n // Git初期化\n if (!skipGit) {\n const gitSpinner = ora(\"Gitリポジトリを初期化中...\").start();\n try {\n await execa(\"git\", [\"init\"], { cwd: targetPath });\n await execa(\"git\", [\"add\", \".\"], { cwd: targetPath });\n await execa(\"git\", [\"commit\", \"-m\", \"Initial commit\"], { cwd: targetPath });\n gitSpinner.succeed(\"Gitリポジトリを初期化しました\");\n } catch (error) {\n gitSpinner.fail(\"Gitリポジトリの初期化に失敗しました\");\n logger.warn(\"後で手動で 'git init' を実行してください\");\n }\n }\n\n // 依存関係インストール\n if (!skipInstall) {\n const installSpinner = ora(\"依存関係をインストール中...\").start();\n try {\n await execa(\"pnpm\", [\"install\"], { cwd: targetPath });\n installSpinner.succeed(\"依存関係をインストールしました\");\n\n // Prismaクライアント生成\n const prismaSpinner = ora(\"Prismaクライアントを生成中...\").start();\n try {\n await execa(\"pnpm\", [\"db:generate\"], { cwd: targetPath });\n prismaSpinner.succeed(\"Prismaクライアントを生成しました\");\n } catch (error) {\n prismaSpinner.fail(\"Prismaクライアントの生成に失敗しました\");\n logger.warn(\"後で手動で 'pnpm db:generate' を実行してください\");\n }\n } catch (error) {\n installSpinner.fail(\"依存関係のインストールに失敗しました\");\n logger.warn(\"後で手動で 'pnpm install' を実行してください\");\n }\n }\n\n // direnv allow(direnvが有効で、コマンドが利用可能な場合)\n if (config.tools.direnv && isDirenvAvailable()) {\n await promptAndExecuteDirenvAllow(targetPath);\n }\n\n // @einja/dev-cli init\n if (config.setupEinjaCli) {\n const einjaSpinner = ora(\"@einja/dev-cli を初期化中...\").start();\n try {\n await execa(\"npx\", [\"@einja/dev-cli\", \"init\", \"--force\", \"--no-backup\"], { cwd: targetPath });\n einjaSpinner.succeed(\"@einja/dev-cli を初期化しました\");\n } catch (error) {\n einjaSpinner.fail(\"@einja/dev-cli の初期化に失敗しました\");\n logger.warn(\"後で手動で 'npx @einja/dev-cli init' を実行してください\");\n }\n }\n\n // 完了メッセージ表示\n printCompletionMessage(config);\n}\n","import { existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport ora from \"ora\";\nimport { promptSetupConfig } from \"../prompts/setup.js\";\nimport {\n setupDirenv,\n setupDotenvx,\n setupVolta,\n setupBiome,\n setupHusky,\n promptDirenvAllow,\n} from \"../generators/tools/index.js\";\nimport type { ToolSetupOptions } from \"../types/index.js\";\nimport * as logger from \"../utils/logger.js\";\n\n/**\n * setupコマンド - 既存プロジェクトへのツール追加\n *\n * US-002: 既存プロジェクトへの環境ツール追加\n * AC-002-1: `npx create-einja-app --setup` で対話式プロンプトが表示される\n * AC-002-2: 既存の設定ファイルがある場合、マージ・上書き・スキップを選択できる\n * AC-002-3: 選択したツールのみがセットアップされる\n * AC-002-4: 既存ファイルを破壊せずにツールが追加される(マージモード時)\n */\nexport async function setupCommand(): Promise<void> {\n const targetDir = process.cwd();\n\n // 1. プロジェクトディレクトリ確認(package.json存在確認)\n const packageJsonPath = join(targetDir, \"package.json\");\n if (!existsSync(packageJsonPath)) {\n logger.error(\"エラー: package.jsonが見つかりません\");\n logger.info(\"このコマンドは既存のプロジェクトディレクトリで実行してください\");\n process.exit(1);\n }\n\n logger.info(\"既存プロジェクトへのツール追加を開始します\");\n logger.info(\"\");\n\n // 2. プロンプトで設定収集\n const config = await promptSetupConfig();\n\n logger.info(\"\");\n logger.info(\"セットアップを開始します...\");\n logger.info(\"\");\n\n const options: ToolSetupOptions = {\n targetDir,\n conflictStrategy: config.conflictStrategy,\n };\n\n // 3. 選択されたツールのセットアップ\n let setupCount = 0;\n\n if (config.tools.direnv) {\n const spin = ora(\"direnv をセットアップしています...\").start();\n try {\n setupDirenv(options);\n spin.succeed(\"direnv セットアップ完了\");\n setupCount++;\n } catch (error) {\n spin.fail(\"direnv セットアップ失敗\");\n logger.error(\n error instanceof Error ? error.message : \"予期しないエラーが発生しました\"\n );\n }\n }\n\n if (config.tools.dotenvx) {\n const spin = ora(\"dotenvx をセットアップしています...\").start();\n try {\n setupDotenvx(options);\n spin.succeed(\"dotenvx セットアップ完了\");\n setupCount++;\n } catch (error) {\n spin.fail(\"dotenvx セットアップ失敗\");\n logger.error(\n error instanceof Error ? error.message : \"予期しないエラーが発生しました\"\n );\n }\n }\n\n if (config.tools.volta) {\n const spin = ora(\"Volta をセットアップしています...\").start();\n try {\n setupVolta(options);\n spin.succeed(\"Volta セットアップ完了\");\n setupCount++;\n } catch (error) {\n spin.fail(\"Volta セットアップ失敗\");\n logger.error(\n error instanceof Error ? error.message : \"予期しないエラーが発生しました\"\n );\n }\n }\n\n if (config.tools.biome) {\n const spin = ora(\"Biome をセットアップしています...\").start();\n try {\n setupBiome(options);\n spin.succeed(\"Biome セットアップ完了\");\n setupCount++;\n } catch (error) {\n spin.fail(\"Biome セットアップ失敗\");\n logger.error(\n error instanceof Error ? error.message : \"予期しないエラーが発生しました\"\n );\n }\n }\n\n if (config.tools.husky) {\n const spin = ora(\"Husky をセットアップしています...\").start();\n try {\n setupHusky(options);\n spin.succeed(\"Husky セットアップ完了\");\n setupCount++;\n } catch (error) {\n spin.fail(\"Husky セットアップ失敗\");\n logger.error(\n error instanceof Error ? error.message : \"予期しないエラーが発生しました\"\n );\n }\n }\n\n logger.info(\"\");\n\n // 4. direnv allowの確認プロンプト(direnvがセットアップされた場合のみ)\n if (config.tools.direnv) {\n await promptDirenvAllow(targetDir);\n logger.info(\"\");\n }\n\n // 5. 完了メッセージ\n logger.success(`✅ セットアップが完了しました!(${setupCount}個のツール)`);\n logger.info(\"\");\n logger.info(\"次のステップ:\");\n\n if (config.tools.direnv) {\n logger.info(\" 1. .envrc を編集して環境変数を設定\");\n logger.info(\" 2. direnv allow を実行(まだの場合)\");\n }\n\n if (config.tools.dotenvx) {\n logger.info(\" - .env.example をコピーして .env を作成\");\n logger.info(\" - 必要に応じて pnpm env:encrypt で暗号化\");\n }\n\n if (config.tools.biome) {\n logger.info(\" - pnpm lint でコードをチェック\");\n logger.info(\" - pnpm format:fix でフォーマット\");\n }\n\n if (config.tools.husky) {\n logger.info(\" - pnpm install でHuskyフックをインストール\");\n }\n\n logger.info(\"\");\n logger.success(\"開発を開始できます!\");\n}\n","import inquirer from \"inquirer\";\n\n/**\n * SetupConfig型\n * 既存プロジェクトへのツール追加設定\n */\nexport interface SetupConfig {\n tools: {\n direnv: boolean;\n dotenvx: boolean;\n volta: boolean;\n biome: boolean;\n husky: boolean;\n };\n conflictStrategy: \"merge\" | \"overwrite\" | \"skip\";\n}\n\n/**\n * セットアップ用プロンプトを実行\n * @returns SetupConfig - セットアップ設定\n */\nexport async function promptSetupConfig(): Promise<SetupConfig> {\n const answers = await inquirer.prompt([\n {\n type: \"checkbox\",\n name: \"tools\",\n message: \"セットアップするツールを選択(複数選択可):\",\n choices: [\n {\n name: \"direnv(ディレクトリごとの環境変数管理)\",\n value: \"direnv\",\n checked: true,\n },\n {\n name: \"dotenvx(.env暗号化)\",\n value: \"dotenvx\",\n checked: true,\n },\n {\n name: \"Volta(Node.jsバージョン管理)\",\n value: \"volta\",\n checked: true,\n },\n {\n name: \"Biome(Linter / Formatter)\",\n value: \"biome\",\n checked: false,\n },\n {\n name: \"Husky + lint-staged(Git hooks)\",\n value: \"husky\",\n checked: false,\n },\n ],\n },\n {\n type: \"list\",\n name: \"conflictStrategy\",\n message: \"既存ファイルがある場合の動作:\",\n choices: [\n {\n name: \"マージ(既存設定を保持しつつ追加)\",\n value: \"merge\",\n },\n {\n name: \"上書き\",\n value: \"overwrite\",\n },\n {\n name: \"スキップ\",\n value: \"skip\",\n },\n ],\n default: \"merge\",\n },\n ]);\n\n // ツール選択を boolean フラグに変換\n const toolsArray = answers.tools as string[];\n const tools = {\n direnv: toolsArray.includes(\"direnv\"),\n dotenvx: toolsArray.includes(\"dotenvx\"),\n volta: toolsArray.includes(\"volta\"),\n biome: toolsArray.includes(\"biome\"),\n husky: toolsArray.includes(\"husky\"),\n };\n\n return {\n tools,\n conflictStrategy: answers.conflictStrategy,\n };\n}\n","import { join } from \"node:path\";\nimport { execSync } from \"node:child_process\";\nimport inquirer from \"inquirer\";\nimport type { ToolSetupOptions } from \"../../types/index.js\";\nimport { writeWithStrategy, appendToGitignore } from \"../../utils/fs.js\";\nimport * as logger from \"../../utils/logger.js\";\n\nconst ENVRC_CONTENT = `# direnv configuration\n# Load .env if it exists\ndotenv_if_exists\n\n# Allow local overrides\ndotenv_if_exists .env.local\n`;\n\nconst ENVRC_EXAMPLE_CONTENT = `# Example direnv configuration\n# Copy this file to .envrc and run 'direnv allow'\n\n# Load environment variables from .env\ndotenv_if_exists\n\n# Load local overrides\ndotenv_if_exists .env.local\n`;\n\n/**\n * direnvのセットアップを実行する\n *\n * AC-003-1: .envrc ファイルが生成される\n * AC-003-2: .envrc.example ファイルが生成される\n * AC-003-3: .gitignore に .envrc が追加される\n */\nexport function setupDirenv(options: ToolSetupOptions): void {\n const { targetDir, conflictStrategy } = options;\n\n const envrcPath = join(targetDir, \".envrc\");\n const envrcExamplePath = join(targetDir, \".envrc.example\");\n\n writeWithStrategy(envrcPath, ENVRC_CONTENT, conflictStrategy);\n\n writeWithStrategy(envrcExamplePath, ENVRC_EXAMPLE_CONTENT, conflictStrategy);\n\n appendToGitignore(targetDir, \".envrc\");\n}\n\n/**\n * direnv allowの確認プロンプトを表示し、実行する\n *\n * AC-003-4: 確認後 `direnv allow` が実行される\n *\n * @param targetDir - ターゲットディレクトリ\n */\nexport async function promptDirenvAllow(targetDir: string): Promise<void> {\n try {\n const { shouldAllow } = await inquirer.prompt([\n {\n type: \"confirm\",\n name: \"shouldAllow\",\n message: \"direnv allow を実行しますか?(環境変数を有効化します)\",\n default: true,\n },\n ]);\n\n if (shouldAllow) {\n try {\n execSync(\"direnv allow\", { cwd: targetDir, stdio: \"inherit\" });\n logger.success(\"direnv allow を実行しました\");\n } catch (error) {\n logger.warn(\"direnv allow の実行に失敗しました\");\n logger.info(\"後で手動で 'direnv allow' を実行してください\");\n }\n } else {\n logger.info(\"direnv allow をスキップしました\");\n logger.info(\"後で手動で 'direnv allow' を実行してください\");\n }\n } catch (error) {\n // プロンプトがキャンセルされた場合など\n logger.info(\"direnv allow をスキップしました\");\n }\n}\n","import { join } from \"node:path\";\nimport type { ToolSetupOptions } from \"../../types/index.js\";\nimport { writeWithStrategy } from \"../../utils/fs.js\";\nimport { addDependencies, addScripts } from \"../../utils/package-json.js\";\n\nconst ENV_EXAMPLE_CONTENT = `# Environment variables template\n# Copy this file to .env and fill in the values\n\n# Database\nDATABASE_URL=\"postgresql://user:password@localhost:25432/dbname\"\n\n# NextAuth\nNEXTAUTH_URL=\"http://localhost:3000\"\nNEXTAUTH_SECRET=\"your-secret-here\"\n\n# OAuth (if using)\n# GOOGLE_CLIENT_ID=\"\"\n# GOOGLE_CLIENT_SECRET=\"\"\n# GITHUB_CLIENT_ID=\"\"\n# GITHUB_CLIENT_SECRET=\"\"\n`;\n\n/**\n * dotenvxのセットアップを実行する\n *\n * AC-004-1: package.jsonに依存関係が追加される\n * AC-004-2: npm scriptsにdotenvxコマンドが追加される\n * AC-004-3: .env.example が生成される\n */\nexport function setupDotenvx(options: ToolSetupOptions): void {\n const { targetDir, conflictStrategy } = options;\n\n addDependencies(targetDir, {\n \"@dotenvx/dotenvx\": \"^1.29.0\",\n });\n\n addScripts(targetDir, {\n \"env:encrypt\": \"dotenvx encrypt\",\n \"env:decrypt\": \"dotenvx decrypt\",\n });\n\n const envExamplePath = join(targetDir, \".env.example\");\n writeWithStrategy(envExamplePath, ENV_EXAMPLE_CONTENT, conflictStrategy);\n}\n","import { readFileSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { fileExists } from \"./fs.js\";\n\ntype PackageJson = {\n name?: string;\n version?: string;\n scripts?: Record<string, string>;\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n volta?: {\n node?: string;\n pnpm?: string;\n };\n \"lint-staged\"?: Record<string, string | string[]>;\n [key: string]: unknown;\n};\n\n/**\n * package.jsonを読み込む\n */\nexport function readPackageJson(targetDir: string): PackageJson {\n const packageJsonPath = join(targetDir, \"package.json\");\n\n if (!fileExists(packageJsonPath)) {\n return {};\n }\n\n const content = readFileSync(packageJsonPath, \"utf-8\");\n return JSON.parse(content) as PackageJson;\n}\n\n/**\n * package.jsonに書き込む\n */\nexport function writePackageJson(targetDir: string, data: PackageJson): void {\n const packageJsonPath = join(targetDir, \"package.json\");\n const content = JSON.stringify(data, null, 2);\n writeFileSync(packageJsonPath, `${content}\\n`, \"utf-8\");\n}\n\n/**\n * package.jsonにスクリプトを追加する\n */\nexport function addScripts(\n targetDir: string,\n scripts: Record<string, string>\n): void {\n const pkg = readPackageJson(targetDir);\n pkg.scripts = { ...pkg.scripts, ...scripts };\n writePackageJson(targetDir, pkg);\n}\n\n/**\n * package.jsonに依存関係を追加する\n */\nexport function addDependencies(\n targetDir: string,\n dependencies: Record<string, string>,\n dev = false\n): void {\n const pkg = readPackageJson(targetDir);\n\n if (dev) {\n pkg.devDependencies = { ...pkg.devDependencies, ...dependencies };\n } else {\n pkg.dependencies = { ...pkg.dependencies, ...dependencies };\n }\n\n writePackageJson(targetDir, pkg);\n}\n\n/**\n * package.jsonにVoltaフィールドを追加する\n */\nexport function addVoltaField(\n targetDir: string,\n nodeVersion: string,\n pnpmVersion: string\n): void {\n const pkg = readPackageJson(targetDir);\n pkg.volta = {\n node: nodeVersion,\n pnpm: pnpmVersion,\n };\n writePackageJson(targetDir, pkg);\n}\n\n/**\n * package.jsonにlint-staged設定を追加する\n */\nexport function addLintStaged(\n targetDir: string,\n config: Record<string, string | string[]>\n): void {\n const pkg = readPackageJson(targetDir);\n pkg[\"lint-staged\"] = { ...pkg[\"lint-staged\"], ...config };\n writePackageJson(targetDir, pkg);\n}\n","import { join } from \"node:path\";\nimport type { ToolSetupOptions } from \"../../types/index.js\";\nimport { writeWithStrategy } from \"../../utils/fs.js\";\nimport { addVoltaField } from \"../../utils/package-json.js\";\n\nconst NODE_VERSION = \"22.16.0\";\nconst PNPM_VERSION = \"9.15.0\";\n\nconst NODE_VERSION_CONTENT = `${NODE_VERSION}\n`;\n\n/**\n * Voltaのセットアップを実行する\n *\n * AC-005-1: package.jsonにvoltaフィールドが追加される\n * AC-005-2: .node-version ファイルが生成される\n */\nexport function setupVolta(options: ToolSetupOptions): void {\n const { targetDir, conflictStrategy } = options;\n\n addVoltaField(targetDir, NODE_VERSION, PNPM_VERSION);\n\n const nodeVersionPath = join(targetDir, \".node-version\");\n writeWithStrategy(nodeVersionPath, NODE_VERSION_CONTENT, conflictStrategy);\n}\n","import { join } from \"node:path\";\nimport type { ToolSetupOptions } from \"../../types/index.js\";\nimport { writeWithStrategy, ensureDir } from \"../../utils/fs.js\";\nimport { addDependencies, addScripts } from \"../../utils/package-json.js\";\n\nconst BIOME_CONFIG = `{\n \"$schema\": \"https://biomejs.dev/schemas/1.9.4/schema.json\",\n \"vcs\": {\n \"enabled\": true,\n \"clientKind\": \"git\",\n \"useIgnoreFile\": true\n },\n \"files\": {\n \"ignoreUnknown\": false,\n \"ignore\": [\"node_modules\", \"dist\", \".next\", \"out\", \"build\", \"coverage\"]\n },\n \"formatter\": {\n \"enabled\": true,\n \"indentStyle\": \"space\",\n \"indentWidth\": 2,\n \"lineEnding\": \"lf\",\n \"lineWidth\": 100\n },\n \"organizeImports\": {\n \"enabled\": true\n },\n \"linter\": {\n \"enabled\": true,\n \"rules\": {\n \"recommended\": true\n }\n },\n \"javascript\": {\n \"formatter\": {\n \"quoteStyle\": \"double\",\n \"trailingCommas\": \"es5\",\n \"semicolons\": \"always\",\n \"arrowParentheses\": \"always\"\n }\n }\n}\n`;\n\nconst VSCODE_SETTINGS = `{\n \"editor.defaultFormatter\": \"biomejs.biome\",\n \"editor.formatOnSave\": true,\n \"editor.codeActionsOnSave\": {\n \"quickfix.biome\": \"explicit\",\n \"source.organizeImports.biome\": \"explicit\"\n },\n \"[javascript]\": {\n \"editor.defaultFormatter\": \"biomejs.biome\"\n },\n \"[typescript]\": {\n \"editor.defaultFormatter\": \"biomejs.biome\"\n },\n \"[json]\": {\n \"editor.defaultFormatter\": \"biomejs.biome\"\n }\n}\n`;\n\n/**\n * Biomeのセットアップを実行する(--setupモードのみ)\n *\n * AC-006-1: biome.json が生成される\n * AC-006-2: package.jsonにlint/formatスクリプトが追加される\n * AC-006-3: VSCode設定が追加される\n */\nexport function setupBiome(options: ToolSetupOptions): void {\n const { targetDir, conflictStrategy } = options;\n\n const biomeConfigPath = join(targetDir, \"biome.json\");\n writeWithStrategy(biomeConfigPath, BIOME_CONFIG, conflictStrategy);\n\n addDependencies(\n targetDir,\n {\n \"@biomejs/biome\": \"^1.9.4\",\n },\n true\n );\n\n addScripts(targetDir, {\n lint: \"biome lint .\",\n \"lint:fix\": \"biome lint --write .\",\n format: \"biome format .\",\n \"format:fix\": \"biome format --write .\",\n });\n\n const vscodeDir = join(targetDir, \".vscode\");\n ensureDir(vscodeDir);\n\n const vscodeSettingsPath = join(vscodeDir, \"settings.json\");\n writeWithStrategy(vscodeSettingsPath, VSCODE_SETTINGS, conflictStrategy);\n}\n","import { join } from \"node:path\";\nimport { writeFileSync } from \"node:fs\";\nimport type { ToolSetupOptions } from \"../../types/index.js\";\nimport { ensureDir } from \"../../utils/fs.js\";\nimport { addDependencies, addScripts, addLintStaged } from \"../../utils/package-json.js\";\n\nconst PRE_COMMIT_HOOK = `#!/usr/bin/env sh\n. \"$(dirname -- \"$0\")/_/husky.sh\"\n\npnpm lint-staged\n`;\n\n/**\n * Husky + lint-stagedのセットアップを実行する(--setupモードのみ)\n *\n * AC-007-1: .husky/ ディレクトリが生成される\n * AC-007-2: pre-commitフックが設定される\n * AC-007-3: lint-staged設定が追加される\n */\nexport function setupHusky(options: ToolSetupOptions): void {\n const { targetDir } = options;\n\n addDependencies(\n targetDir,\n {\n husky: \"^9.1.7\",\n \"lint-staged\": \"^15.2.11\",\n },\n true\n );\n\n addScripts(targetDir, {\n prepare: \"husky\",\n });\n\n addLintStaged(targetDir, {\n \"*.{js,jsx,ts,tsx}\": [\"biome format --write\", \"biome lint --write\"],\n \"*.{json,md,yml,yaml}\": [\"biome format --write\"],\n });\n\n const huskyDir = join(targetDir, \".husky\");\n ensureDir(huskyDir);\n\n const preCommitPath = join(huskyDir, \"pre-commit\");\n writeFileSync(preCommitPath, PRE_COMMIT_HOOK, { mode: 0o755 });\n}\n","import { existsSync } from \"node:fs\";\nimport { readFile } from \"node:fs/promises\";\nimport { dirname, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport ora from \"ora\";\nimport {\n promptAddConfig,\n getDefaultAddConfig,\n} from \"../prompts/add.js\";\nimport type { AddConfig, AddOptions, SyncMetadata } from \"../types/index.js\";\nimport { addPackages } from \"../generators/partials/packages.js\";\nimport { addApps } from \"../generators/partials/apps.js\";\nimport { addConfigFiles } from \"../generators/partials/config.js\";\nimport {\n loadSyncMetadata,\n saveSyncMetadata,\n} from \"../utils/merger.js\";\nimport * as logger from \"../utils/logger.js\";\n\n/**\n * AddCommandOptions型\n * addコマンドのオプション\n */\nexport interface AddCommandOptions {\n skipPrompts: boolean;\n dryRun: boolean;\n}\n\n/**\n * テンプレートディレクトリのパスを取得\n * @param templateName - テンプレート名\n * @returns テンプレートディレクトリパス\n */\nfunction getTemplatePath(templateName: string): string {\n const __filename = fileURLToPath(import.meta.url);\n const __dirname = dirname(__filename);\n\n // バンドル後(dist/cli.js)とソース実行(src/commands/add.ts)の両方に対応\n // dist/cli.js -> ../templates/ (1階層上)\n // src/commands/add.ts -> ../../templates/ (2階層上)\n const distPath = join(__dirname, \"../templates\", templateName);\n const srcPath = join(__dirname, \"../../templates\", templateName);\n\n if (existsSync(distPath)) {\n return distPath;\n }\n if (existsSync(srcPath)) {\n return srcPath;\n }\n\n // どちらも存在しない場合はdistPathを返す(エラーメッセージ用)\n return distPath;\n}\n\n/**\n * テンプレートから.einja-sync.jsonを読み込む\n * @param templateDir - テンプレートディレクトリパス\n * @returns SyncMetadata または null(ファイルが存在しない場合)\n */\nasync function loadTemplateSyncMetadata(\n templateDir: string\n): Promise<SyncMetadata | null> {\n const syncFilePath = join(templateDir, \".einja-sync.json\");\n try {\n const content = await readFile(syncFilePath, \"utf-8\");\n return JSON.parse(content) as SyncMetadata;\n } catch {\n return null;\n }\n}\n\n/**\n * テンプレートと既存のSyncMetadataをマージ\n * @param template - テンプレートのSyncMetadata\n * @param existing - 既存のSyncMetadata\n * @returns マージされたSyncMetadata\n */\nfunction mergeSyncMetadata(\n template: SyncMetadata | null,\n existing: SyncMetadata | null\n): SyncMetadata {\n const now = new Date().toISOString();\n\n // テンプレートのjsonPathsを優先的に使用\n const jsonPaths =\n template?.jsonPaths ?? existing?.jsonPaths ?? { managed: {}, seed: {} };\n\n return {\n version: template?.version ?? existing?.version ?? \"1.0.0\",\n lastSync: now,\n templateVersion: template?.templateVersion ?? \"1.0.0\",\n files: { ...(existing?.files ?? {}), ...(template?.files ?? {}) },\n jsonPaths,\n };\n}\n\n/**\n * addコマンドの実装\n * @param options - コマンドオプション\n */\nexport async function addCommand(options: AddCommandOptions): Promise<void> {\n try {\n // Given: カレントディレクトリをターゲットとする\n const targetDir = process.cwd();\n\n // Given: プロンプトまたはデフォルト設定を取得\n let config: AddConfig;\n\n if (options.skipPrompts) {\n // When: skipPromptsが有効な場合、デフォルト設定を使用\n config = getDefaultAddConfig();\n logger.info(\"デフォルト設定を使用します(すべてのコンポーネントを選択)\");\n } else {\n // When: 対話式プロンプトを実行\n config = await promptAddConfig(options.dryRun);\n }\n\n // Given: dry-runモードかどうかを設定に反映\n config.dryRun = options.dryRun;\n\n // When: dry-runモードの場合、プレビューを表示\n if (config.dryRun) {\n logger.warn(\"dry-runモード: 実際のファイル操作は行いません\");\n logger.info(\"\\n--- 追加予定のコンポーネント ---\");\n\n if (config.components.packages) {\n logger.info(\n `- packages/: ${config.packageComponents.join(\", \")}`\n );\n }\n\n if (config.components.apps) {\n logger.info(`- apps/: ${config.appComponents.join(\", \")}`);\n }\n\n if (config.components.config) {\n logger.info(\"- 直下設定ファイル: turbo.json, pnpm-workspace.yaml 等\");\n }\n\n logger.info(\"---\\n\");\n }\n\n // Given: テンプレートディレクトリのパスを取得\n const templateDir = getTemplatePath(\"default\");\n\n // Given: テンプレートディレクトリの存在確認\n if (!existsSync(templateDir)) {\n throw new Error(\"テンプレートが見つかりません: default\");\n }\n\n // Given: テンプレートのSyncMetadataを読み込む\n const templateMetadata = await loadTemplateSyncMetadata(templateDir);\n\n // Given: 既存のSyncMetadataを読み込む\n const existingMetadata = await loadSyncMetadata(targetDir);\n\n // When: テンプレートと既存のメタデータをマージ\n const syncMetadata = mergeSyncMetadata(templateMetadata, existingMetadata);\n\n // Given: AddOptionsを構築\n const addOptions: AddOptions = {\n targetDir,\n templateDir,\n config,\n };\n\n let totalAdded = 0;\n let totalMerged = 0;\n let totalSkipped = 0;\n\n // When: packages を追加\n if (config.components.packages && config.packageComponents.length > 0) {\n const spinner = ora(\"パッケージを追加中...\").start();\n\n try {\n const result = await addPackages(\n addOptions,\n config.packageComponents,\n syncMetadata\n );\n\n totalAdded += result.added.length;\n totalMerged += result.merged.length;\n totalSkipped += result.skipped.length;\n\n spinner.succeed(\n `パッケージを追加しました(追加: ${result.added.length}, マージ: ${result.merged.length}, スキップ: ${result.skipped.length})`\n );\n } catch (error) {\n spinner.fail(\"パッケージの追加に失敗しました\");\n throw error;\n }\n }\n\n // When: apps を追加\n if (config.components.apps && config.appComponents.length > 0) {\n const spinner = ora(\"アプリを追加中...\").start();\n\n try {\n const result = await addApps(\n addOptions,\n config.appComponents,\n syncMetadata\n );\n\n totalAdded += result.added.length;\n totalMerged += result.merged.length;\n totalSkipped += result.skipped.length;\n\n spinner.succeed(\n `アプリを追加しました(追加: ${result.added.length}, マージ: ${result.merged.length}, スキップ: ${result.skipped.length})`\n );\n } catch (error) {\n spinner.fail(\"アプリの追加に失敗しました\");\n throw error;\n }\n }\n\n // When: config を追加\n if (config.components.config) {\n const spinner = ora(\"設定ファイルを追加中...\").start();\n\n try {\n const result = await addConfigFiles(addOptions, syncMetadata);\n\n totalAdded += result.added.length;\n totalMerged += result.merged.length;\n totalSkipped += result.skipped.length;\n\n spinner.succeed(\n `設定ファイルを追加しました(追加: ${result.added.length}, マージ: ${result.merged.length}, スキップ: ${result.skipped.length})`\n );\n } catch (error) {\n spinner.fail(\"設定ファイルの追加に失敗しました\");\n throw error;\n }\n }\n\n // When: SyncMetadataを更新して保存\n if (!config.dryRun) {\n syncMetadata.lastSync = new Date().toISOString();\n await saveSyncMetadata(targetDir, syncMetadata);\n }\n\n // Then: 結果サマリーを表示\n logger.success(\"\\n✓ 追加完了!\\n\");\n\n if (config.dryRun) {\n logger.info(\"(dry-runモードのため、実際の変更は行われていません)\\n\");\n }\n\n logger.info(`追加されたファイル: ${totalAdded}個`);\n logger.info(`マージされたファイル: ${totalMerged}個`);\n logger.info(`スキップされたファイル: ${totalSkipped}個\\n`);\n\n // When: @einja/cliがインストールされていない場合、案内メッセージを表示\n const packageJsonPath = join(targetDir, \"package.json\");\n if (existsSync(packageJsonPath)) {\n const packageJson = await import(packageJsonPath, {\n assert: { type: \"json\" },\n });\n\n const hasEinjaCli =\n packageJson.default?.devDependencies?.[\"@einja/dev-cli\"] ||\n packageJson.default?.dependencies?.[\"@einja/dev-cli\"];\n\n if (!hasEinjaCli) {\n logger.info(\"次のステップ:\");\n logger.info(\"1. pnpm install\");\n logger.info(\"2. pnpm dev:setup\");\n logger.info(\"\\n推奨:\");\n logger.info(\" einja開発支援CLI (@einja/dev-cli) のインストール:\");\n logger.info(\" pnpm add -D @einja/dev-cli\\n\");\n } else {\n logger.info(\"次のステップ:\");\n logger.info(\"1. pnpm install\");\n logger.info(\"2. pnpm dev:setup\\n\");\n }\n } else {\n logger.info(\"次のステップ:\");\n logger.info(\"1. pnpm install\");\n logger.info(\"2. pnpm dev:setup\\n\");\n }\n } catch (error) {\n logger.error(\"エラーが発生しました:\");\n if (error instanceof Error) {\n logger.error(error.message);\n } else {\n logger.error(String(error));\n }\n process.exit(1);\n }\n}\n","import inquirer from \"inquirer\";\nimport type {\n AddConfig,\n PackageComponent,\n AppComponent,\n} from \"../types/index.js\";\n\n/**\n * デフォルトの追加設定を取得\n * skipPrompts=true 時に使用\n */\nexport function getDefaultAddConfig(): AddConfig {\n return {\n components: {\n packages: true,\n apps: true,\n config: true,\n },\n packageComponents: [\"front-core\", \"server-core\", \"config\", \"ui\"],\n appComponents: [\"web\"],\n dryRun: false,\n };\n}\n\n/**\n * 追加用プロンプトを実行\n * @param dryRun - dry-runモードかどうか\n * @returns AddConfig - 追加設定\n */\nexport async function promptAddConfig(dryRun: boolean): Promise<AddConfig> {\n // ステージ1: コンポーネント種別選択\n const componentAnswers = await inquirer.prompt([\n {\n type: \"checkbox\",\n name: \"components\",\n message: \"追加するコンポーネントを選択(Spaceで選択、Enterで確定):\",\n choices: [\n {\n name: \"packages/ - 共通パッケージ(front-core, server-core, config, ui)\",\n value: \"packages\",\n checked: true,\n },\n {\n name: \"apps/ - アプリテンプレート\",\n value: \"apps\",\n checked: true,\n },\n {\n name: \"直下設定ファイル - turbo.json, pnpm-workspace.yaml 等\",\n value: \"config\",\n checked: true,\n },\n ],\n },\n ]);\n\n const selectedComponents = componentAnswers.components as string[];\n const hasPackages = selectedComponents.includes(\"packages\");\n const hasApps = selectedComponents.includes(\"apps\");\n const hasConfig = selectedComponents.includes(\"config\");\n\n // ステージ2: packages詳細選択\n let packageComponents: PackageComponent[] = [];\n if (hasPackages) {\n const packageAnswers = await inquirer.prompt([\n {\n type: \"checkbox\",\n name: \"packages\",\n message: \"追加するパッケージを選択:\",\n choices: [\n {\n name: \"front-core - フロントエンド共通層(認証設定、hooks、utils)\",\n value: \"front-core\",\n checked: true,\n },\n {\n name: \"server-core - バックエンド共通層(Prisma、ドメインロジック)\",\n value: \"server-core\",\n checked: true,\n },\n {\n name: \"config - 共通設定(Biome, TypeScript, Panda CSS)\",\n value: \"config\",\n checked: true,\n },\n {\n name: \"ui - 共通UIコンポーネント(shadcn/ui)\",\n value: \"ui\",\n checked: true,\n },\n ],\n validate: (input: string[]): boolean | string => {\n if (input.length === 0) {\n return \"少なくとも1つのパッケージを選択してください\";\n }\n return true;\n },\n },\n ]);\n packageComponents = packageAnswers.packages as PackageComponent[];\n }\n\n // ステージ3: apps詳細選択\n let appComponents: AppComponent[] = [];\n if (hasApps) {\n const appAnswers = await inquirer.prompt([\n {\n type: \"checkbox\",\n name: \"apps\",\n message: \"追加するアプリを選択:\",\n choices: [\n {\n name: \"web - メイン管理画面アプリ(Next.js + App Router)\",\n value: \"web\",\n checked: true,\n },\n ],\n validate: (input: string[]): boolean | string => {\n if (input.length === 0) {\n return \"少なくとも1つのアプリを選択してください\";\n }\n return true;\n },\n },\n ]);\n appComponents = appAnswers.apps as AppComponent[];\n }\n\n return {\n components: {\n packages: hasPackages,\n apps: hasApps,\n config: hasConfig,\n },\n packageComponents,\n appComponents,\n dryRun,\n };\n}\n","import { readdir } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport type {\n AddOptions,\n PackageComponent,\n SyncMetadata,\n} from \"../../types/index.js\";\nimport { mergeAndWriteFile } from \"../../utils/merger.js\";\nimport * as logger from \"../../utils/logger.js\";\n\n/**\n * packages/ ディレクトリにコンポーネントを追加\n */\nexport async function addPackages(\n options: AddOptions,\n components: PackageComponent[],\n syncMetadata: SyncMetadata\n): Promise<{ added: string[]; skipped: string[]; merged: string[] }> {\n const added: string[] = [];\n const skipped: string[] = [];\n const merged: string[] = [];\n\n const { targetDir, templateDir, config } = options;\n\n for (const component of components) {\n const componentName =\n component === \"front-core\"\n ? \"front-core\"\n : component === \"server-core\"\n ? \"server-core\"\n : component === \"config\"\n ? \"config\"\n : \"ui\";\n\n const srcDir = join(templateDir, \"packages\", componentName);\n const destDir = join(targetDir, \"packages\", componentName);\n\n logger.info(`Adding package component: ${componentName}`);\n\n await copyDirectory(\n srcDir,\n destDir,\n { added, skipped, merged },\n config.dryRun,\n syncMetadata\n );\n }\n\n return { added, skipped, merged };\n}\n\n/**\n * ディレクトリを再帰的にコピー\n */\nasync function copyDirectory(\n srcDir: string,\n destDir: string,\n result: { added: string[]; skipped: string[]; merged: string[] },\n dryRun: boolean,\n syncMetadata: SyncMetadata\n): Promise<void> {\n const entries = await readdir(srcDir, { withFileTypes: true });\n\n for (const entry of entries) {\n const srcPath = join(srcDir, entry.name);\n const destPath = join(destDir, entry.name);\n\n if (entry.isDirectory()) {\n await copyDirectory(srcPath, destPath, result, dryRun, syncMetadata);\n } else {\n if (!dryRun) {\n const mergeResult = await mergeAndWriteFile(\n srcPath,\n destPath,\n syncMetadata\n );\n\n if (mergeResult.action === \"created\") {\n result.added.push(destPath);\n } else if (mergeResult.action === \"skipped\") {\n result.skipped.push(destPath);\n } else if (mergeResult.action === \"merged\") {\n result.merged.push(destPath);\n }\n } else {\n // dry-runモードではスキップ\n result.skipped.push(destPath);\n }\n }\n }\n}\n","import { readFileSync, writeFileSync, existsSync } from \"node:fs\";\nimport { dirname } from \"node:path\";\nimport type { SyncMetadata, JsonPathsConfig } from \"../types/index.js\";\nimport { ensureDir } from \"./fs.js\";\n\n/**\n * マーカーベースのテキストマージを行う\n *\n * @param templateContent - テンプレートファイルの内容\n * @param existingContent - 既存ファイルの内容(存在しない場合はnull)\n * @returns マージ後の内容\n */\nexport function mergeTextWithMarkers(\n templateContent: string,\n existingContent: string | null\n): string {\n // Given: 既存ファイルが存在しない場合\n if (existingContent === null) {\n // When: テンプレートをそのまま使用\n return templateContent;\n }\n\n // Given: 既存ファイルとテンプレートの両方が存在する場合\n const templateSections = parseMarkers(templateContent);\n const localSections = parseMarkers(existingContent);\n\n // マーカーがなければ既存優先\n const hasMarkers = templateSections.some(\n (s) => s.type === \"managed\" || s.type === \"seed\"\n );\n if (!hasMarkers) {\n return existingContent;\n }\n\n // When: ID付きmanagedセクションとseedセクションをMapで管理\n const templateManagedById = new Map<string, MarkerSection>();\n const templateSeedById = new Map<string, MarkerSection>();\n const processedTemplateIds = new Set<string>();\n\n for (const section of templateSections) {\n if (section.type === \"managed\" && section.id) {\n templateManagedById.set(section.id, section);\n } else if (section.type === \"seed\" && section.id) {\n templateSeedById.set(section.id, section);\n }\n }\n\n // When: ローカルセクションを処理(ローカル側の順序を基準にする)\n const result: string[] = [];\n\n for (const localSection of localSections) {\n if (localSection.type === \"managed\") {\n const match = localSection.id ? templateManagedById.get(localSection.id) : undefined;\n if (localSection.id && match) {\n // IDマッチ → テンプレートで上書き\n processedTemplateIds.add(localSection.id);\n result.push(match.content);\n } else if (!localSection.id) {\n // IDなし → ローカル内容を保持(安全策)\n result.push(localSection.content);\n }\n // ID付きでテンプレートにマッチなし → 削除(resultに追加しない)\n } else if (localSection.type === \"seed\") {\n // seed: ローカル優先\n if (localSection.id) {\n processedTemplateIds.add(localSection.id);\n }\n result.push(localSection.content);\n } else {\n // unmanaged: ローカル優先\n result.push(localSection.content);\n }\n }\n\n // When: テンプレートにのみ存在するID付きmanagedセクションを末尾に追加\n for (const [id, section] of templateManagedById) {\n if (!processedTemplateIds.has(id)) {\n // テンプレートにのみ存在するID付きmanagedセクションを追加\n result.push(section.content);\n }\n }\n\n // When: テンプレートにのみ存在するID付きseedセクションを末尾に追加\n for (const [id, section] of templateSeedById) {\n if (!processedTemplateIds.has(id)) {\n // テンプレートにのみ存在するID付きseedセクションを追加\n result.push(section.content);\n }\n }\n\n // Then: ファイル先頭の空セクションのみ除去(セクション間の空行は保持)\n const firstElement = result[0];\n if (result.length > 0 && firstElement !== undefined && firstElement.length === 0) {\n result.shift();\n }\n return result.join(\"\\n\");\n}\n\n/**\n * JSONのディープマージを行う\n *\n * @param templateJson - テンプレートのJSON\n * @param existingJson - 既存のJSON(存在しない場合はnull)\n * @param jsonPaths - managed/seedパスの設定\n * @param filePath - ファイルパス(例: \"package.json\")\n * @returns マージ後のJSON\n */\nexport function mergeJson(\n templateJson: Record<string, unknown>,\n existingJson: Record<string, unknown> | null,\n jsonPaths: JsonPathsConfig,\n filePath = \"package.json\"\n): Record<string, unknown> {\n // Given: 既存JSONが存在しない場合\n if (existingJson === null) {\n // When: テンプレートをディープコピーして使用\n return JSON.parse(JSON.stringify(templateJson));\n }\n\n // When: ディープマージを実行\n return deepMergeWithPaths(\n templateJson,\n existingJson,\n jsonPaths,\n filePath,\n \"\"\n );\n}\n\n/**\n * パスを考慮したディープマージを行う\n *\n * @param template - テンプレートオブジェクト\n * @param existing - 既存オブジェクト\n * @param jsonPaths - managed/seedパスの設定\n * @param filePath - ファイルパス\n * @param currentPath - 現在のキーパス(例: \"scripts.dev\")\n * @returns マージ後のオブジェクト\n */\nfunction deepMergeWithPaths(\n template: Record<string, unknown>,\n existing: Record<string, unknown>,\n jsonPaths: JsonPathsConfig,\n filePath: string,\n currentPath: string\n): Record<string, unknown> {\n // 既存オブジェクトをディープコピー(参照を共有しないように)\n const result = JSON.parse(JSON.stringify(existing)) as Record<string, unknown>;\n\n for (const [key, templateValue] of Object.entries(template)) {\n const keyPath = currentPath ? `${currentPath}.${key}` : key;\n const existingValue = existing[key];\n\n // Given: このパスがmanagedに含まれるか確認\n if (isPathManaged(filePath, keyPath, jsonPaths)) {\n // Then: managedパスはテンプレート値でディープコピーして上書き\n result[key] = deepClone(templateValue);\n }\n // Given: このパスがseedに含まれるか確認\n else if (isPathSeed(filePath, keyPath, jsonPaths)) {\n // Given: seedパスでオブジェクトの場合、子キーもディープマージ\n if (\n typeof templateValue === \"object\" &&\n templateValue !== null &&\n !Array.isArray(templateValue) &&\n typeof existingValue === \"object\" &&\n existingValue !== null &&\n !Array.isArray(existingValue)\n ) {\n // Then: seedパス内でもディープマージ(既存にないキーのみ追加)\n result[key] = deepMergeWithPaths(\n templateValue as Record<string, unknown>,\n existingValue as Record<string, unknown>,\n jsonPaths,\n filePath,\n keyPath\n );\n } else if (!(key in existing)) {\n // Then: seedパスはローカル優先(キーが存在しない場合のみディープコピーして追加)\n result[key] = deepClone(templateValue);\n }\n // 既存値がある場合は何もしない(既存値を保持)\n }\n // Given: 両方がオブジェクトの場合\n else if (\n typeof templateValue === \"object\" &&\n templateValue !== null &&\n !Array.isArray(templateValue) &&\n typeof existingValue === \"object\" &&\n existingValue !== null &&\n !Array.isArray(existingValue)\n ) {\n // Then: 再帰的にディープマージ\n result[key] = deepMergeWithPaths(\n templateValue as Record<string, unknown>,\n existingValue as Record<string, unknown>,\n jsonPaths,\n filePath,\n keyPath\n );\n }\n // Given: それ以外のパス(テンプレートにのみ存在する場合)\n else if (!(key in existing)) {\n // Then: テンプレートの値をディープコピーして追加\n result[key] = deepClone(templateValue);\n }\n // 既存値がある場合は何もしない(既存値を保持)\n }\n\n return result;\n}\n\n/**\n * 値をディープコピーする(undefinedも正しく扱う)\n *\n * @param value - コピーする値\n * @returns ディープコピーされた値\n */\nfunction deepClone(value: unknown): unknown {\n if (value === undefined) {\n return undefined;\n }\n return JSON.parse(JSON.stringify(value));\n}\n\n/**\n * .einja-sync.json を読み込む\n *\n * @param targetDir - ターゲットディレクトリ\n * @returns メタデータ(存在しない場合はnull)\n */\nexport async function loadSyncMetadata(\n targetDir: string\n): Promise<SyncMetadata | null> {\n const metadataPath = `${targetDir}/.einja-sync.json`;\n\n if (!existsSync(metadataPath)) {\n return null;\n }\n\n try {\n const content = readFileSync(metadataPath, \"utf-8\");\n return JSON.parse(content) as SyncMetadata;\n } catch {\n return null;\n }\n}\n\n/**\n * .einja-sync.json を保存する\n *\n * @param targetDir - ターゲットディレクトリ\n * @param metadata - メタデータ\n */\nexport async function saveSyncMetadata(\n targetDir: string,\n metadata: SyncMetadata\n): Promise<void> {\n const metadataPath = `${targetDir}/.einja-sync.json`;\n ensureDir(dirname(metadataPath));\n writeFileSync(metadataPath, JSON.stringify(metadata, null, 2), \"utf-8\");\n}\n\n/**\n * ファイルマージの実行(テキスト/JSON自動判定)\n *\n * @param templatePath - テンプレートファイルのパス\n * @param targetPath - ターゲットファイルのパス\n * @param syncMetadata - 同期メタデータ\n * @returns マージ結果\n */\nexport async function mergeAndWriteFile(\n templatePath: string,\n targetPath: string,\n syncMetadata: SyncMetadata\n): Promise<{\n action: \"created\" | \"merged\" | \"skipped\" | \"overwritten\";\n path: string;\n}> {\n const templateContent = readFileSync(templatePath, \"utf-8\");\n const targetExists = existsSync(targetPath);\n const existingContent = targetExists ? readFileSync(targetPath, \"utf-8\") : null;\n\n // Given: ファイルがJSONかどうか判定\n const isJsonFile = targetPath.endsWith(\".json\");\n\n let mergedContent: string;\n let action: \"created\" | \"merged\" | \"skipped\" | \"overwritten\";\n\n if (!targetExists) {\n // When: ファイルが存在しない場合は新規作成\n mergedContent = templateContent;\n action = \"created\";\n } else if (isJsonFile) {\n // When: JSONファイルの場合はディープマージ\n try {\n const templateJson = JSON.parse(templateContent) as Record<string, unknown>;\n const existingJson = existingContent\n ? (JSON.parse(existingContent) as Record<string, unknown>)\n : null;\n const jsonPaths = syncMetadata.jsonPaths || { managed: {}, seed: {} };\n // ファイルパスからファイル名を抽出(例: \"/path/to/package.json\" → \"package.json\")\n const fileName = targetPath.split(\"/\").pop() || \"package.json\";\n const mergedJson = mergeJson(templateJson, existingJson, jsonPaths, fileName);\n mergedContent = JSON.stringify(mergedJson, null, 2);\n action = \"merged\";\n } catch {\n // Then: パースエラーの場合はテンプレートで上書き\n mergedContent = templateContent;\n action = \"overwritten\";\n }\n } else {\n // When: テキストファイルの場合はマーカーベースマージ\n mergedContent = mergeTextWithMarkers(templateContent, existingContent);\n\n // Then: 内容が変更されたかチェック\n if (mergedContent === existingContent) {\n action = \"skipped\";\n } else {\n action = \"merged\";\n }\n }\n\n // Then: ファイルに書き込み\n if (action !== \"skipped\") {\n ensureDir(dirname(targetPath));\n writeFileSync(targetPath, mergedContent, \"utf-8\");\n }\n\n return { action, path: targetPath };\n}\n\n/**\n * マーカーセクションの型定義\n */\ninterface MarkerSection {\n type: \"managed\" | \"seed\" | \"unmanaged\";\n startLine: number;\n endLine: number;\n content: string;\n id?: string;\n}\n\n/**\n * ファイル内容をパースしてマーカーセクションに分離する\n *\n * @param content - ファイル内容\n * @returns セクション配列\n */\nfunction parseMarkers(content: string): MarkerSection[] {\n const lines = content.split(\"\\n\");\n const sections: MarkerSection[] = [];\n let currentType: \"managed\" | \"seed\" | \"unmanaged\" = \"unmanaged\";\n let currentStartLine = 1;\n let currentContent: string[] = [];\n let currentId: string | undefined;\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i] as string;\n const lineNumber = i + 1;\n\n // Given: マーカー開始を検出\n const startMarker = parseStartMarker(line);\n if (startMarker) {\n if (currentType !== \"unmanaged\") {\n // Then: 入れ子のマーカーは無視\n currentContent.push(line);\n continue;\n }\n\n // When: 現在のunmanagedセクションを保存\n if (currentContent.length > 0 || sections.length === 0) {\n sections.push({\n type: \"unmanaged\",\n startLine: currentStartLine,\n endLine: lineNumber - 1,\n content: currentContent.join(\"\\n\"),\n });\n }\n\n // When: managed/seedセクション開始\n currentType = startMarker.type;\n currentId = startMarker.id;\n currentStartLine = lineNumber;\n currentContent = [line];\n }\n // Given: マーカー終了を検出\n else if (parseEndMarker(line)) {\n if (currentType === \"unmanaged\") {\n // Then: 対応するstartがない場合は無視\n currentContent.push(line);\n continue;\n }\n\n // When: マーカー終了行を追加\n currentContent.push(line);\n\n // When: managed/seedセクションを保存\n sections.push({\n type: currentType,\n startLine: currentStartLine,\n endLine: lineNumber,\n content: currentContent.join(\"\\n\"),\n id: currentId,\n });\n\n // When: unmanagedセクション開始\n currentType = \"unmanaged\";\n currentId = undefined;\n currentStartLine = lineNumber + 1;\n currentContent = [];\n }\n // Given: 通常行\n else {\n currentContent.push(line);\n }\n }\n\n // Then: 最後のセクションを保存\n if (currentContent.length > 0 || sections.length === 0) {\n sections.push({\n type: currentType,\n startLine: currentStartLine,\n endLine: lines.length,\n content: currentContent.join(\"\\n\"),\n id: currentId,\n });\n }\n\n return sections;\n}\n\n/**\n * 行がマーカー開始かどうかを判定し、種別とIDを返す\n *\n * @param line - 行内容\n * @returns マーカー情報またはnull\n */\nfunction parseStartMarker(\n line: string\n): { type: \"managed\" | \"seed\"; id?: string } | null {\n // Markdown managed\n const markdownManagedPattern =\n /^<!--\\s*@einja:managed:start(?:\\s+id=\"([^\"]+)\")?\\s*-->$/;\n let match = line.match(markdownManagedPattern);\n if (match) {\n return { type: \"managed\", id: match[1] || undefined };\n }\n\n // Markdown seed\n const markdownSeedPattern =\n /^<!--\\s*@einja:seed:start(?:\\s+id=\"([^\"]+)\")?\\s*-->$/;\n match = line.match(markdownSeedPattern);\n if (match) {\n return { type: \"seed\", id: match[1] || undefined };\n }\n\n // YAML/JSON managed\n const yamlManagedPattern = /^\\s*#\\s*@einja:managed:start(?:\\s+id=\"([^\"]+)\")?\\s*$/;\n match = line.match(yamlManagedPattern);\n if (match) {\n return { type: \"managed\", id: match[1] || undefined };\n }\n\n // YAML/JSON seed\n const yamlSeedPattern = /^\\s*#\\s*@einja:seed:start(?:\\s+id=\"([^\"]+)\")?\\s*$/;\n match = line.match(yamlSeedPattern);\n if (match) {\n return { type: \"seed\", id: match[1] || undefined };\n }\n\n return null;\n}\n\n/**\n * 行がマーカー終了かどうかを判定し、種別を返す\n *\n * @param line - 行内容\n * @returns マーカー種別またはnull\n */\nfunction parseEndMarker(line: string): \"managed\" | \"seed\" | null {\n // Markdown managed\n if (/^<!--\\s*@einja:managed:end\\s*-->$/.test(line)) {\n return \"managed\";\n }\n\n // Markdown seed\n if (/^<!--\\s*@einja:seed:end\\s*-->$/.test(line)) {\n return \"seed\";\n }\n\n // YAML/JSON managed\n if (/^\\s*#\\s*@einja:managed:end\\s*$/.test(line)) {\n return \"managed\";\n }\n\n // YAML/JSON seed\n if (/^\\s*#\\s*@einja:seed:end\\s*$/.test(line)) {\n return \"seed\";\n }\n\n return null;\n}\n\n/**\n * パスがmanagedに含まれるかチェック\n *\n * @param filePath - ファイルパス(例: \"package.json\")\n * @param keyPath - チェックするキーパス(例: \"scripts.dev\")\n * @param jsonPaths - JSONパス設定\n * @returns managedに含まれる場合true\n */\nfunction isPathManaged(\n filePath: string,\n keyPath: string,\n jsonPaths: JsonPathsConfig\n): boolean {\n const managedPaths = jsonPaths.managed[filePath] || [];\n // keyPath が managedPaths のいずれかで始まるかチェック\n // 例: keyPath=\"scripts.dev\" が managedPaths=[\"scripts.dev\"] にマッチ\n // または keyPath=\"scripts.dev\" が managedPaths=[\"scripts\"] にマッチ\n return managedPaths.some(\n (p) => keyPath === p || keyPath.startsWith(`${p}.`)\n );\n}\n\n/**\n * パスがseedに含まれるかチェック\n *\n * @param filePath - ファイルパス(例: \"package.json\")\n * @param keyPath - チェックするキーパス(例: \"scripts.custom\")\n * @param jsonPaths - JSONパス設定\n * @returns seedに含まれる場合true\n */\nfunction isPathSeed(\n filePath: string,\n keyPath: string,\n jsonPaths: JsonPathsConfig\n): boolean {\n const seedPaths = jsonPaths.seed[filePath] || [];\n // keyPath が seedPaths のいずれかで始まるかチェック\n return seedPaths.some((p) => keyPath === p || keyPath.startsWith(`${p}.`));\n}\n","import { readdir } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport type {\n AddOptions,\n AppComponent,\n SyncMetadata,\n} from \"../../types/index.js\";\nimport { mergeAndWriteFile } from \"../../utils/merger.js\";\nimport * as logger from \"../../utils/logger.js\";\n\n/**\n * apps/ ディレクトリにコンポーネントを追加\n */\nexport async function addApps(\n options: AddOptions,\n components: AppComponent[],\n syncMetadata: SyncMetadata\n): Promise<{ added: string[]; skipped: string[]; merged: string[] }> {\n const added: string[] = [];\n const skipped: string[] = [];\n const merged: string[] = [];\n\n const { targetDir, templateDir, config } = options;\n\n for (const component of components) {\n const componentName = component === \"web\" ? \"web\" : component;\n\n const srcDir = join(templateDir, \"apps\", componentName);\n const destDir = join(targetDir, \"apps\", componentName);\n\n logger.info(`Adding app component: ${componentName}`);\n\n await copyDirectory(\n srcDir,\n destDir,\n { added, skipped, merged },\n config.dryRun,\n syncMetadata\n );\n }\n\n return { added, skipped, merged };\n}\n\n/**\n * ディレクトリを再帰的にコピー\n */\nasync function copyDirectory(\n srcDir: string,\n destDir: string,\n result: { added: string[]; skipped: string[]; merged: string[] },\n dryRun: boolean,\n syncMetadata: SyncMetadata\n): Promise<void> {\n const entries = await readdir(srcDir, { withFileTypes: true });\n\n for (const entry of entries) {\n const srcPath = join(srcDir, entry.name);\n const destPath = join(destDir, entry.name);\n\n if (entry.isDirectory()) {\n await copyDirectory(srcPath, destPath, result, dryRun, syncMetadata);\n } else {\n if (!dryRun) {\n const mergeResult = await mergeAndWriteFile(\n srcPath,\n destPath,\n syncMetadata\n );\n\n if (mergeResult.action === \"created\") {\n result.added.push(destPath);\n } else if (mergeResult.action === \"skipped\") {\n result.skipped.push(destPath);\n } else if (mergeResult.action === \"merged\") {\n result.merged.push(destPath);\n }\n } else {\n // dry-runモードではスキップ\n result.skipped.push(destPath);\n }\n }\n }\n}\n","import { readdir, readFile } from \"node:fs/promises\";\nimport { join, relative, sep } from \"node:path\";\nimport type { AddOptions, SyncMetadata } from \"../../types/index.js\";\nimport { mergeAndWriteFile } from \"../../utils/merger.js\";\nimport * as logger from \"../../utils/logger.js\";\n\n/**\n * プロジェクト直下の設定ファイルを追加\n */\nexport async function addConfigFiles(\n options: AddOptions,\n syncMetadata: SyncMetadata\n): Promise<{ added: string[]; skipped: string[]; merged: string[] }> {\n const added: string[] = [];\n const skipped: string[] = [];\n const merged: string[] = [];\n\n const { targetDir, templateDir, config } = options;\n\n logger.info(\"Adding config files from template root\");\n\n // 除外パターン\n const excludedPaths = new Set([\n \".claude\",\n \"docs/einja\",\n \"CLAUDE.md\",\n \".mcp.json\",\n \"node_modules\",\n \".turbo\",\n \"next-env.d.ts\",\n \"styled-system\",\n \"pnpm-lock.yaml\",\n \"package-lock.json\",\n \"packages\",\n \"apps\",\n ]);\n\n // .gitignore のパターンを読み込み\n const gitignorePatterns = await loadGitignorePatterns(templateDir);\n\n await copyConfigDirectory(\n templateDir,\n targetDir,\n templateDir, // rootDir として templateDir を渡す\n { added, skipped, merged },\n config.dryRun,\n excludedPaths,\n gitignorePatterns,\n syncMetadata\n );\n\n return { added, skipped, merged };\n}\n\n/**\n * .gitignore のパターンを読み込み\n */\nasync function loadGitignorePatterns(templateDir: string): Promise<Set<string>> {\n const patterns = new Set<string>();\n const gitignorePath = join(templateDir, \".gitignore\");\n\n try {\n const content = await readFile(gitignorePath, \"utf-8\");\n const lines = content.split(\"\\n\");\n\n for (const line of lines) {\n const trimmed = line.trim();\n // コメントと空行を除外\n if (trimmed && !trimmed.startsWith(\"#\")) {\n // 先頭の / を削除\n const pattern = trimmed.startsWith(\"/\") ? trimmed.slice(1) : trimmed;\n patterns.add(pattern);\n }\n }\n } catch {\n // .gitignore が存在しない場合は無視\n }\n\n return patterns;\n}\n\n/**\n * 設定ファイルのディレクトリを再帰的にコピー\n */\nasync function copyConfigDirectory(\n srcDir: string,\n destDir: string,\n rootDir: string, // テンプレートルートディレクトリ\n result: { added: string[]; skipped: string[]; merged: string[] },\n dryRun: boolean,\n excludedPaths: Set<string>,\n gitignorePatterns: Set<string>,\n syncMetadata: SyncMetadata\n): Promise<void> {\n const entries = await readdir(srcDir, { withFileTypes: true });\n\n for (const entry of entries) {\n const srcPath = join(srcDir, entry.name);\n const destPath = join(destDir, entry.name);\n // rootDir からの相対パスを計算(一貫性を保つ)\n const rawRelativePath = relative(rootDir, srcPath);\n // Windows対応: パス区切り文字をPOSIX形式(/)に正規化\n const relativePath = rawRelativePath.split(sep).join(\"/\");\n\n // 除外パターンに一致するかチェック\n if (shouldExclude(relativePath, excludedPaths, gitignorePatterns)) {\n continue;\n }\n\n if (entry.isDirectory()) {\n await copyConfigDirectory(\n srcPath,\n destPath,\n rootDir, // rootDir を引き継ぐ\n result,\n dryRun,\n excludedPaths,\n gitignorePatterns,\n syncMetadata\n );\n } else {\n if (!dryRun) {\n const mergeResult = await mergeAndWriteFile(\n srcPath,\n destPath,\n syncMetadata\n );\n\n if (mergeResult.action === \"created\") {\n result.added.push(destPath);\n } else if (mergeResult.action === \"skipped\") {\n result.skipped.push(destPath);\n } else if (mergeResult.action === \"merged\") {\n result.merged.push(destPath);\n }\n } else {\n // dry-runモードではスキップ\n result.skipped.push(destPath);\n }\n }\n }\n}\n\n/**\n * パスを除外すべきか判定\n */\nfunction shouldExclude(\n relativePath: string,\n excludedPaths: Set<string>,\n gitignorePatterns: Set<string>\n): boolean {\n // 除外パスに完全一致または部分一致\n for (const excluded of excludedPaths) {\n if (relativePath === excluded || relativePath.startsWith(`${excluded}/`)) {\n return true;\n }\n }\n\n // .gitignore パターンに一致\n for (const pattern of gitignorePatterns) {\n // シンプルなパターンマッチング(ワイルドカード対応)\n if (matchPattern(relativePath, pattern)) {\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * シンプルなパターンマッチング\n */\nfunction matchPattern(path: string, pattern: string): boolean {\n // パターンの最後が / の場合、ディレクトリのみ一致\n if (pattern.endsWith(\"/\")) {\n const dirPattern = pattern.slice(0, -1);\n return path === dirPattern || path.startsWith(`${dirPattern}/`);\n }\n\n // * を含むパターン\n if (pattern.includes(\"*\")) {\n const regexPattern = pattern\n .replace(/\\./g, \"\\\\.\")\n .replace(/\\*/g, \".*\");\n return new RegExp(`^${regexPattern}$`).test(path);\n }\n\n // 完全一致または部分一致\n return path === pattern || path.startsWith(`${pattern}/`);\n}\n"],"mappings":";;;AAAA,SAAS,eAAe;AACxB,SAAS,gBAAAA,qBAAoB;AAC7B,SAAS,iBAAAC,sBAAqB;AAC9B,SAAS,WAAAC,UAAS,QAAAC,cAAY;;;ACH9B,SAAS,cAAAC,aAAY,mBAAmB;AACxC,SAAS,eAAe;AACxB,OAAOC,UAAS;;;ACFhB,OAAO,cAAc;AAUrB,eAAsB,oBACpB,oBACwB;AACxB,QAAM,UAAU,MAAM,SAAS,OAAO;AAAA,IACpC;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS;AAAA,MACT,SAAS,sBAAsB;AAAA,MAC/B,UAAU,CAAC,UAAoC;AAE7C,cAAM,QAAQ;AACd,YAAI,CAAC,MAAM,KAAK,KAAK,GAAG;AACtB,iBAAO;AAAA,QACT;AACA,eAAO;AAAA,MACT;AAAA,IACF;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS;AAAA,MACT,SAAS;AAAA,IACX;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS;AAAA,MACT,SAAS;AAAA,MACT,UAAU,CAAC,UAAoC;AAE7C,cAAM,QAAQ;AACd,YAAI,CAAC,MAAM,KAAK,KAAK,GAAG;AACtB,iBAAO;AAAA,QACT;AACA,eAAO;AAAA,MACT;AAAA,IACF;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS;AAAA,MACT,SAAS;AAAA,QACP,EAAE,MAAM,kCAAmB,OAAO,UAAU;AAAA,QAC5C,EAAE,MAAM,kFAAiB,OAAO,OAAO;AAAA,MACzC;AAAA,MACA,SAAS;AAAA,IACX;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS;AAAA,MACT,SAAS;AAAA,IACX;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS;AAAA,MACT,SAAS;AAAA,IACX;AAAA,EACF,CAAC;AAGD,QAAM,QAAQ;AAAA,IACZ,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,OAAO;AAAA,IACP,OAAO;AAAA,IACP,OAAO;AAAA,EACT;AAEA,MAAI;AAGJ,MAAI,QAAQ,mBAAmB;AAC7B,UAAM,kBAAkB,MAAM,SAAS,OAAO;AAAA,MAC5C;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS;AAAA,QACT,SAAS;AAAA,QACT,UAAU,CAAC,UAAoC;AAC7C,gBAAM,OAAO,OAAO,SAAS,OAAO,EAAE;AACtC,cAAI,OAAO,MAAM,IAAI,KAAK,OAAO,QAAQ,OAAO,OAAO;AACrD,mBAAO;AAAA,UACT;AACA,iBAAO;AAAA,QACT;AAAA,MACF;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS;AAAA,QACT,SAAS,GAAG,QAAQ,WAAW;AAAA,MACjC;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS;AAAA,QACT,SAAS;AAAA,MACX;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS;AAAA,QACT,SAAS;AAAA,QACT,UAAU,CAAC,UAAoC;AAC7C,gBAAM,OAAO,OAAO,SAAS,OAAO,EAAE;AACtC,cAAI,OAAO,MAAM,IAAI,KAAK,OAAO,QAAQ,OAAO,OAAO;AACrD,mBAAO;AAAA,UACT;AACA,iBAAO;AAAA,QACT;AAAA,MACF;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS;AAAA,QACT,SAAS;AAAA,QACT,UAAU,CAAC,UAAoC;AAC7C,gBAAM,OAAO,OAAO,SAAS,OAAO,EAAE;AACtC,cAAI,OAAO,MAAM,IAAI,KAAK,OAAO,KAAK,OAAO,KAAO;AAClD,mBAAO;AAAA,UACT;AACA,iBAAO;AAAA,QACT;AAAA,MACF;AAAA,IACF,CAAC;AAED,qBAAiB;AAAA,MACf,UAAU;AAAA,QACR,MAAM,OAAO,SAAS,gBAAgB,cAAc,EAAE;AAAA,QACtD,eAAe,gBAAgB;AAAA,MACjC;AAAA,MACA,MAAM;AAAA,QACJ;AAAA,UACE,IAAI,gBAAgB;AAAA,UACpB,gBAAgB,OAAO,SAAS,gBAAgB,gBAAgB,EAAE;AAAA,UAClE,WAAW,OAAO,SAAS,gBAAgB,WAAW,EAAE;AAAA,QAC1D;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL,aAAa,QAAQ;AAAA,IACrB,cAAc,QAAQ;AAAA,IACtB,UAAU;AAAA,IACV,YAAY,QAAQ;AAAA,IACpB;AAAA,IACA,eAAe,QAAQ;AAAA,IACvB;AAAA,IACA,eAAe,QAAQ;AAAA,EACzB;AACF;;;ACpKA,OAAO,aAAa;AAEpB,SAAS,YAAY;AACrB,SAAS,WAAAC,UAAS,QAAAC,OAAM,gBAAgB;AACxC,SAAS,qBAAqB;;;ACJ9B,SAAS,YAAY,cAAc,eAAe,gBAAgB,iBAAiB;AACnF,SAAS,MAAM,eAAe;AAMvB,SAAS,kBACd,UACA,SACA,UACS;AACT,QAAM,SAAS,WAAW,QAAQ;AAElC,MAAI,CAAC,QAAQ;AACX,cAAU,QAAQ,QAAQ,CAAC;AAC3B,kBAAc,UAAU,SAAS,OAAO;AACxC,WAAO;AAAA,EACT;AAEA,UAAQ,UAAU;AAAA,IAChB,KAAK,aAAa;AAChB,oBAAc,UAAU,SAAS,OAAO;AACxC,aAAO;AAAA,IACT;AAAA,IAEA,KAAK,SAAS;AACZ,YAAM,kBAAkB,aAAa,UAAU,OAAO;AACtD,YAAM,gBAAgB,aAAa,iBAAiB,OAAO;AAC3D,oBAAc,UAAU,eAAe,OAAO;AAC9C,aAAO;AAAA,IACT;AAAA,IAEA,KAAK,QAAQ;AACX,aAAO;AAAA,IACT;AAAA,IAEA,SAAS;AACP,YAAM,mBAA0B;AAChC,YAAM,IAAI,MAAM,qBAAqB,gBAAgB,EAAE;AAAA,IACzD;AAAA,EACF;AACF;AAKA,SAAS,aAAa,UAAkB,YAA4B;AAClE,MAAI,SAAS,SAAS,UAAU,GAAG;AACjC,WAAO;AAAA,EACT;AACA,SAAO,GAAG,QAAQ;AAAA,EAAK,UAAU;AACnC;AAKO,SAAS,UAAU,SAAuB;AAC/C,MAAI,CAAC,WAAW,OAAO,GAAG;AACxB,cAAU,SAAS,EAAE,WAAW,KAAK,CAAC;AAAA,EACxC;AACF;AAKO,SAAS,kBAAkB,WAAmB,MAAoB;AACvE,QAAM,gBAAgB,KAAK,WAAW,YAAY;AAElD,MAAI,CAAC,WAAW,aAAa,GAAG;AAC9B,kBAAc,eAAe,GAAG,IAAI;AAAA,GAAM,OAAO;AACjD;AAAA,EACF;AAEA,QAAM,UAAU,aAAa,eAAe,OAAO;AACnD,MAAI,QAAQ,SAAS,IAAI,GAAG;AAC1B;AAAA,EACF;AAEA,iBAAe,eAAe;AAAA,EAAK,IAAI;AAAA,GAAM,OAAO;AACtD;AAKO,SAAS,WAAW,UAA2B;AACpD,SAAO,WAAW,QAAQ;AAC5B;;;ACvFA,OAAO,WAAW;AAMX,SAAS,KAAK,SAAuB;AAC1C,UAAQ,IAAI,MAAM,KAAK,QAAG,GAAG,OAAO;AACtC;AAMO,SAAS,QAAQ,SAAuB;AAC7C,UAAQ,IAAI,MAAM,MAAM,QAAG,GAAG,OAAO;AACvC;AAMO,SAAS,KAAK,SAAuB;AAC1C,UAAQ,IAAI,MAAM,OAAO,QAAG,GAAG,OAAO;AACxC;AAMO,SAAS,MAAM,SAAuB;AAC3C,UAAQ,MAAM,MAAM,IAAI,QAAG,GAAG,OAAO;AACvC;;;AF/BA,IAAM,EAAE,UAAU,cAAAC,eAAc,eAAAC,gBAAe,YAAAC,aAAY,WAAW,IAAI;AAuB1E,SAAS,gBAAgB,cAA8B;AACrD,QAAMC,cAAa,cAAc,YAAY,GAAG;AAChD,QAAMC,aAAYC,SAAQF,WAAU;AAKpC,QAAM,WAAWG,MAAKF,YAAW,gBAAgB,YAAY;AAC7D,QAAM,UAAUE,MAAKF,YAAW,mBAAmB,YAAY;AAE/D,MAAIF,YAAW,QAAQ,GAAG;AACxB,WAAO;AAAA,EACT;AACA,MAAIA,YAAW,OAAO,GAAG;AACvB,WAAO;AAAA,EACT;AAGA,SAAO;AACT;AAOA,SAAS,uBAAuB,YAA8B;AAC5D,MAAI,eAAe,QAAQ;AACzB,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACA,SAAO,CAAC;AACV;AAQA,SAAS,oBACP,SACA,WACQ;AACR,MAAI,SAAS;AAGb,WAAS,OAAO,WAAW,mBAAmB,UAAU,WAAW;AAGnE,WAAS,OAAO,WAAW,oBAAoB,GAAG,UAAU,WAAW,GAAG;AAG1E,WAAS,OAAO,WAAW,mBAAmB,UAAU,WAAW;AAGnE,WAAS,OAAO,WAAW,mBAAmB,UAAU,WAAW;AAGnE,WAAS,OAAO,WAAW,UAAU,GAAG,UAAU,WAAW,GAAG;AAEhE,SAAO;AACT;AAOA,SAAS,qBACP,UACA,WACM;AAEN,QAAM,mBAAmB,CAAC,QAAQ,QAAQ,SAAS,QAAQ,QAAQ,SAAS,UAAU,QAAQ,MAAM;AACpG,MAAI,iBAAiB,KAAK,CAAC,QAAQ,SAAS,SAAS,GAAG,CAAC,GAAG;AAC1D;AAAA,EACF;AAEA,MAAI;AACF,UAAM,UAAUF,cAAa,UAAU,OAAO;AAC9C,UAAM,WAAW,oBAAoB,SAAS,SAAS;AAEvD,QAAI,YAAY,UAAU;AACxB,MAAAC,eAAc,UAAU,UAAU,OAAO;AAAA,IAC3C;AAAA,EACF,SAASM,QAAO;AAEd,IAAO,KAAK,2DAAc,QAAQ,EAAE;AAAA,EACtC;AACF;AAMA,SAAS,oBAAoB,YAA0B;AACrD,QAAM,gBAAgB,KAAK,KAAK,iBAAiB;AAAA,IAC/C,KAAK;AAAA,IACL,UAAU;AAAA,IACV,KAAK;AAAA,EACP,CAAC;AAED,aAAW,QAAQ,eAAe;AAChC,UAAM,UAAU,KAAK,QAAQ,eAAe,EAAE;AAC9C,aAAS,MAAM,OAAO;AACtB,eAAW,IAAI;AAAA,EACjB;AACF;AAMA,SAAS,mBAAmB,YAA0B;AACpD,QAAM,iBAAiB,KAAK,KAAK,gBAAgB;AAAA,IAC/C,KAAK;AAAA,IACL,UAAU;AAAA,IACV,KAAK;AAAA,EACP,CAAC;AAED,aAAW,QAAQ,gBAAgB;AACjC,UAAM,MAAMF,SAAQ,IAAI;AACxB,UAAM,UAAUC,MAAK,KAAK,YAAY;AAEtC,QAAIJ,YAAW,IAAI,GAAG;AACpB,eAAS,MAAM,OAAO;AACtB,iBAAW,IAAI;AAAA,IACjB;AAAA,EACF;AACF;AAOA,SAAS,iBAAiB,YAAoB,YAA0B;AACtE,QAAM,kBAAkB,uBAAuB,UAAU;AAEzD,MAAI,gBAAgB,WAAW,GAAG;AAChC;AAAA,EACF;AAEA,EAAO,KAAK,qGAAqB;AAEjC,aAAW,WAAW,iBAAiB;AACrC,UAAM,QAAQ,KAAK,KAAK,SAAS;AAAA,MAC/B,KAAK;AAAA,MACL,UAAU;AAAA,MACV,KAAK;AAAA,IACP,CAAC;AAED,eAAW,QAAQ,OAAO;AACxB,iBAAW,IAAI;AAAA,IACjB;AAAA,EACF;AACF;AAOA,eAAsB,iBACpB,QACA,YACe;AACf,QAAM,eAAe,gBAAgB,OAAO,QAAQ;AAGpD,MAAI,CAACA,YAAW,YAAY,GAAG;AAC7B,UAAM,IAAI,MAAM,yFAAmB,OAAO,QAAQ,EAAE;AAAA,EACtD;AAEA,EAAO,KAAK,uEAAgB;AAG5B,QAAM,UAAU,UAAU;AAG1B,WAAS,cAAc,YAAY;AAAA,IACjC,QAAQ,CAAC,QAAyB;AAChC,YAAM,eAAe,SAAS,cAAc,GAAG;AAI/C,YAAM,kBAAkB;AAAA,QACtB;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAGA,YAAM,oBAAoB,CAAC,MAAM;AAGjC,YAAM,eAAe,aAAa,MAAM,OAAO;AAK/C,YAAM,wBAAwB,gBAAgB;AAAA,QAAK,CAAC,YAClD,aAAa,SAAS,OAAO;AAAA,MAC/B;AAGA,YAAM,mBAAmB,kBAAkB;AAAA,QAAK,CAAC,QAC/C,aAAa,SAAS,GAAG;AAAA,MAC3B;AAEA,aAAO,CAAC,yBAAyB,CAAC;AAAA,IACpC;AAAA,EACF,CAAC;AAGD,mBAAiB,YAAY,OAAO,UAAU;AAG9C,sBAAoB,UAAU;AAG9B,qBAAmB,UAAU;AAG7B,EAAO,KAAK,yFAAmB;AAE/B,QAAM,YAA+B;AAAA,IACnC,aAAa,OAAO;AAAA,IACpB,aAAa,OAAO;AAAA,IACpB,aAAa,GAAG,OAAO,WAAW;AAAA,EACpC;AAEA,QAAM,WAAW,KAAK,KAAK,QAAQ;AAAA,IACjC,KAAK;AAAA,IACL,UAAU;AAAA,IACV,OAAO;AAAA,IACP,KAAK;AAAA,EACP,CAAC;AAED,aAAW,QAAQ,UAAU;AAC3B,yBAAqB,MAAM,SAAS;AAAA,EACtC;AAEA,EAAO,QAAQ,8DAAY;AAC7B;;;AGzRA,SAAS,OAAO,iBAAiB;AACjC,OAAOM,YAAW;AAClB,OAAOC,eAAc;AACrB,OAAO,SAAS;AAiBhB,SAAS,oBAA6B;AACpC,MAAI;AACF,cAAU,SAAS,CAAC,QAAQ,CAAC;AAC7B,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAMA,eAAe,4BAA4B,YAAmC;AAC5E,MAAI;AACF,UAAM,EAAE,YAAY,IAAI,MAAMC,UAAS,OAAO;AAAA,MAC5C;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS;AAAA,QACT,SAAS;AAAA,MACX;AAAA,IACF,CAAC;AAED,QAAI,aAAa;AACf,UAAI;AACF,cAAM,MAAM,UAAU,CAAC,OAAO,GAAG,EAAE,KAAK,WAAW,CAAC;AACpD,QAAO,QAAQ,yDAAsB;AAAA,MACvC,SAASC,QAAO;AACd,QAAO,KAAK,2EAAyB;AACrC,QAAO,KAAK,sGAAgC;AAAA,MAC9C;AAAA,IACF,OAAO;AACL,MAAO,KAAK,qEAAwB;AACpC,MAAO,KAAK,sGAAgC;AAAA,IAC9C;AAAA,EACF,SAASA,QAAO;AACd,IAAO,KAAK,qEAAwB;AAAA,EACtC;AACF;AAMA,SAAS,uBAAuB,QAA6B;AAC3D,UAAQ,IAAI;AACZ,EAAO,QAAQ,wGAAmB;AAClC,UAAQ,IAAI;AACZ,UAAQ,IAAIC,OAAM,KAAK,uCAAS,CAAC;AACjC,UAAQ,IAAI;AACZ,UAAQ,IAAIA,OAAM,KAAK,QAAQ,OAAO,WAAW,EAAE,CAAC;AACpD,UAAQ,IAAIA,OAAM,KAAK,yEAAsC,CAAC;AAC9D,UAAQ,IAAIA,OAAM,KAAK,iCAAiC,CAAC;AACzD,UAAQ,IAAIA,OAAM,KAAK,YAAY,CAAC;AACpC,UAAQ,IAAI;AACZ,UAAQ,IAAIA,OAAM,KAAK,+HAA2B,CAAC;AACnD,UAAQ,IAAI;AACZ,UAAQ;AAAA,IACNA,OAAM,OAAO,uBAAQ,IACnBA,OAAM,KAAK,8KAA4C;AAAA,EAC3D;AACA,UAAQ,IAAI;AACZ,UAAQ,IAAIA,OAAM,KAAK,qFAAyB,CAAC;AACjD,UAAQ,IAAI;AACd;AAQA,eAAsB,cACpB,QACA,YACA,SACe;AACf,QAAM,EAAE,SAAS,YAAY,IAAI;AAGjC,MAAI,CAAC,SAAS;AACZ,UAAM,aAAa,IAAI,oEAAkB,EAAE,MAAM;AACjD,QAAI;AACF,YAAM,MAAM,OAAO,CAAC,MAAM,GAAG,EAAE,KAAK,WAAW,CAAC;AAChD,YAAM,MAAM,OAAO,CAAC,OAAO,GAAG,GAAG,EAAE,KAAK,WAAW,CAAC;AACpD,YAAM,MAAM,OAAO,CAAC,UAAU,MAAM,gBAAgB,GAAG,EAAE,KAAK,WAAW,CAAC;AAC1E,iBAAW,QAAQ,mFAAkB;AAAA,IACvC,SAASD,QAAO;AACd,iBAAW,KAAK,qGAAqB;AACrC,MAAO,KAAK,kGAA4B;AAAA,IAC1C;AAAA,EACF;AAGA,MAAI,CAAC,aAAa;AAChB,UAAM,iBAAiB,IAAI,6EAAiB,EAAE,MAAM;AACpD,QAAI;AACF,YAAM,MAAM,QAAQ,CAAC,SAAS,GAAG,EAAE,KAAK,WAAW,CAAC;AACpD,qBAAe,QAAQ,4FAAiB;AAGxC,YAAM,gBAAgB,IAAI,uEAAqB,EAAE,MAAM;AACvD,UAAI;AACF,cAAM,MAAM,QAAQ,CAAC,aAAa,GAAG,EAAE,KAAK,WAAW,CAAC;AACxD,sBAAc,QAAQ,sFAAqB;AAAA,MAC7C,SAASA,QAAO;AACd,sBAAc,KAAK,wGAAwB;AAC3C,QAAO,KAAK,0GAAoC;AAAA,MAClD;AAAA,IACF,SAASA,QAAO;AACd,qBAAe,KAAK,8GAAoB;AACxC,MAAO,KAAK,sGAAgC;AAAA,IAC9C;AAAA,EACF;AAGA,MAAI,OAAO,MAAM,UAAU,kBAAkB,GAAG;AAC9C,UAAM,4BAA4B,UAAU;AAAA,EAC9C;AAGA,MAAI,OAAO,eAAe;AACxB,UAAM,eAAe,IAAI,kDAAyB,EAAE,MAAM;AAC1D,QAAI;AACF,YAAM,MAAM,OAAO,CAAC,kBAAkB,QAAQ,WAAW,aAAa,GAAG,EAAE,KAAK,WAAW,CAAC;AAC5F,mBAAa,QAAQ,iEAAyB;AAAA,IAChD,SAASA,QAAO;AACd,mBAAa,KAAK,mFAA4B;AAC9C,MAAO,KAAK,iHAA2C;AAAA,IACzD;AAAA,EACF;AAGA,yBAAuB,MAAM;AAC/B;;;AL9IA,SAAS,iBAAiB,SAA0B;AAClD,MAAI,CAACE,YAAW,OAAO,GAAG;AACxB,WAAO;AAAA,EACT;AACA,QAAM,QAAQ,YAAY,OAAO;AAEjC,QAAM,mBAAmB,MAAM;AAAA,IAC7B,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG;AAAA,EAC1B;AACA,SAAO,iBAAiB,WAAW;AACrC;AAiBA,SAAS,oBAAoB,aAAyC;AACpE,QAAM,QAAQ;AACd,MAAI,CAAC,MAAM,KAAK,WAAW,GAAG;AAC5B,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAOA,SAAS,mBAAmB,YAA6B;AACvD,SAAOA,YAAW,UAAU;AAC9B;AAQA,eAAsB,cACpB,aACA,SACe;AACf,MAAI;AAEF,QAAI;AAEJ,QAAI,QAAQ,OAAO,aAAa;AAE9B,YAAMC,SAAQ,oBAAoB,WAAW;AAC7C,UAAIA,QAAO;AACT,QAAO,MAAMA,MAAK;AAClB,gBAAQ,KAAK,CAAC;AAAA,MAChB;AAEA,eAAS;AAAA,QACP;AAAA,QACA,cAAc;AAAA,QACd,UAAU;AAAA,QACV,YAAY;AAAA,QACZ,OAAO;AAAA,UACL,QAAQ;AAAA,UACR,SAAS;AAAA,UACT,OAAO;AAAA,UACP,OAAO;AAAA,UACP,OAAO;AAAA,QACT;AAAA,QACA,eAAe;AAAA,QACf,gBAAgB;AAAA,QAChB,eAAe;AAAA,MACjB;AAEA,MAAO,KAAK,+CAAY,OAAO,WAAW,EAAE;AAC5C,MAAO,KAAK,yCAAW,OAAO,QAAQ,EAAE;AACxC,MAAO,KAAK,6BAAS,OAAO,UAAU,EAAE;AAAA,IAC1C,OAAO;AAEL,eAAS,MAAM,oBAAoB,WAAW;AAAA,IAChD;AAGA,UAAM,aAAa,OAAO,gBACtB,QAAQ,IAAI,IACZ,QAAQ,QAAQ,IAAI,GAAG,OAAO,WAAW;AAG7C,QAAI,OAAO,eAAe;AAExB,UAAI,CAAC,iBAAiB,UAAU,GAAG;AACjC,QAAO,MAAM,0HAAsB;AACnC,QAAO,KAAK,kMAAkC;AAC9C,gBAAQ,KAAK,CAAC;AAAA,MAChB;AAAA,IACF,OAAO;AAEL,UAAI,mBAAmB,UAAU,GAAG;AAClC,QAAO,MAAM,yCAAW,OAAO,WAAW,oDAAY;AACtD,QAAO,KAAK,0KAA8B;AAC1C,gBAAQ,KAAK,CAAC;AAAA,MAChB;AAAA,IACF;AAGA,UAAM,UAAUC,KAAI,iEAAe,EAAE,MAAM;AAE3C,QAAI;AACF,YAAM,iBAAiB,QAAQ,UAAU;AACzC,cAAQ,QAAQ,gFAAe;AAAA,IACjC,SAASD,QAAO;AACd,cAAQ,KAAK,kGAAkB;AAC/B,YAAMA;AAAA,IACR;AAGA,UAAM,cAAc,QAAQ,YAAY;AAAA,MACtC,SAAS,QAAQ;AAAA,MACjB,aAAa,QAAQ;AAAA,IACvB,CAAC;AAAA,EACH,SAASA,QAAO;AACd,IAAO,MAAM,+DAAa;AAC1B,QAAIA,kBAAiB,OAAO;AAC1B,MAAO,MAAMA,OAAM,OAAO;AAAA,IAC5B,OAAO;AACL,MAAO,MAAM,OAAOA,MAAK,CAAC;AAAA,IAC5B;AACA,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF;;;AMvJA,SAAS,cAAAE,mBAAkB;AAC3B,SAAS,QAAAC,aAAY;AACrB,OAAOC,UAAS;;;ACFhB,OAAOC,eAAc;AAqBrB,eAAsB,oBAA0C;AAC9D,QAAM,UAAU,MAAMA,UAAS,OAAO;AAAA,IACpC;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS;AAAA,MACT,SAAS;AAAA,QACP;AAAA,UACE,MAAM;AAAA,UACN,OAAO;AAAA,UACP,SAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAM;AAAA,UACN,OAAO;AAAA,UACP,SAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAM;AAAA,UACN,OAAO;AAAA,UACP,SAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAM;AAAA,UACN,OAAO;AAAA,UACP,SAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAM;AAAA,UACN,OAAO;AAAA,UACP,SAAS;AAAA,QACX;AAAA,MACF;AAAA,IACF;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS;AAAA,MACT,SAAS;AAAA,QACP;AAAA,UACE,MAAM;AAAA,UACN,OAAO;AAAA,QACT;AAAA,QACA;AAAA,UACE,MAAM;AAAA,UACN,OAAO;AAAA,QACT;AAAA,QACA;AAAA,UACE,MAAM;AAAA,UACN,OAAO;AAAA,QACT;AAAA,MACF;AAAA,MACA,SAAS;AAAA,IACX;AAAA,EACF,CAAC;AAGD,QAAM,aAAa,QAAQ;AAC3B,QAAM,QAAQ;AAAA,IACZ,QAAQ,WAAW,SAAS,QAAQ;AAAA,IACpC,SAAS,WAAW,SAAS,SAAS;AAAA,IACtC,OAAO,WAAW,SAAS,OAAO;AAAA,IAClC,OAAO,WAAW,SAAS,OAAO;AAAA,IAClC,OAAO,WAAW,SAAS,OAAO;AAAA,EACpC;AAEA,SAAO;AAAA,IACL;AAAA,IACA,kBAAkB,QAAQ;AAAA,EAC5B;AACF;;;AC3FA,SAAS,QAAAC,aAAY;AACrB,SAAS,gBAAgB;AACzB,OAAOC,eAAc;AAKrB,IAAM,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAQtB,IAAM,wBAAwB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAiBvB,SAAS,YAAY,SAAiC;AAC3D,QAAM,EAAE,WAAW,iBAAiB,IAAI;AAExC,QAAM,YAAYC,MAAK,WAAW,QAAQ;AAC1C,QAAM,mBAAmBA,MAAK,WAAW,gBAAgB;AAEzD,oBAAkB,WAAW,eAAe,gBAAgB;AAE5D,oBAAkB,kBAAkB,uBAAuB,gBAAgB;AAE3E,oBAAkB,WAAW,QAAQ;AACvC;AASA,eAAsB,kBAAkB,WAAkC;AACxE,MAAI;AACF,UAAM,EAAE,YAAY,IAAI,MAAMC,UAAS,OAAO;AAAA,MAC5C;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS;AAAA,QACT,SAAS;AAAA,MACX;AAAA,IACF,CAAC;AAED,QAAI,aAAa;AACf,UAAI;AACF,iBAAS,gBAAgB,EAAE,KAAK,WAAW,OAAO,UAAU,CAAC;AAC7D,QAAO,QAAQ,yDAAsB;AAAA,MACvC,SAASC,QAAO;AACd,QAAO,KAAK,2EAAyB;AACrC,QAAO,KAAK,sGAAgC;AAAA,MAC9C;AAAA,IACF,OAAO;AACL,MAAO,KAAK,qEAAwB;AACpC,MAAO,KAAK,sGAAgC;AAAA,IAC9C;AAAA,EACF,SAASA,QAAO;AAEd,IAAO,KAAK,qEAAwB;AAAA,EACtC;AACF;;;AC/EA,SAAS,QAAAC,aAAY;;;ACArB,SAAS,gBAAAC,eAAc,iBAAAC,sBAAqB;AAC5C,SAAS,QAAAC,aAAY;AAoBd,SAAS,gBAAgB,WAAgC;AAC9D,QAAMC,mBAAkBC,MAAK,WAAW,cAAc;AAEtD,MAAI,CAAC,WAAWD,gBAAe,GAAG;AAChC,WAAO,CAAC;AAAA,EACV;AAEA,QAAM,UAAUE,cAAaF,kBAAiB,OAAO;AACrD,SAAO,KAAK,MAAM,OAAO;AAC3B;AAKO,SAAS,iBAAiB,WAAmB,MAAyB;AAC3E,QAAMA,mBAAkBC,MAAK,WAAW,cAAc;AACtD,QAAM,UAAU,KAAK,UAAU,MAAM,MAAM,CAAC;AAC5C,EAAAE,eAAcH,kBAAiB,GAAG,OAAO;AAAA,GAAM,OAAO;AACxD;AAKO,SAAS,WACd,WACA,SACM;AACN,QAAM,MAAM,gBAAgB,SAAS;AACrC,MAAI,UAAU,EAAE,GAAG,IAAI,SAAS,GAAG,QAAQ;AAC3C,mBAAiB,WAAW,GAAG;AACjC;AAKO,SAAS,gBACd,WACA,cACA,MAAM,OACA;AACN,QAAM,MAAM,gBAAgB,SAAS;AAErC,MAAI,KAAK;AACP,QAAI,kBAAkB,EAAE,GAAG,IAAI,iBAAiB,GAAG,aAAa;AAAA,EAClE,OAAO;AACL,QAAI,eAAe,EAAE,GAAG,IAAI,cAAc,GAAG,aAAa;AAAA,EAC5D;AAEA,mBAAiB,WAAW,GAAG;AACjC;AAKO,SAAS,cACd,WACA,aACA,aACM;AACN,QAAM,MAAM,gBAAgB,SAAS;AACrC,MAAI,QAAQ;AAAA,IACV,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AACA,mBAAiB,WAAW,GAAG;AACjC;AAKO,SAAS,cACd,WACA,QACM;AACN,QAAM,MAAM,gBAAgB,SAAS;AACrC,MAAI,aAAa,IAAI,EAAE,GAAG,IAAI,aAAa,GAAG,GAAG,OAAO;AACxD,mBAAiB,WAAW,GAAG;AACjC;;;AD7FA,IAAM,sBAAsB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAwBrB,SAAS,aAAa,SAAiC;AAC5D,QAAM,EAAE,WAAW,iBAAiB,IAAI;AAExC,kBAAgB,WAAW;AAAA,IACzB,oBAAoB;AAAA,EACtB,CAAC;AAED,aAAW,WAAW;AAAA,IACpB,eAAe;AAAA,IACf,eAAe;AAAA,EACjB,CAAC;AAED,QAAM,iBAAiBI,MAAK,WAAW,cAAc;AACrD,oBAAkB,gBAAgB,qBAAqB,gBAAgB;AACzE;;;AE3CA,SAAS,QAAAC,aAAY;AAKrB,IAAM,eAAe;AACrB,IAAM,eAAe;AAErB,IAAM,uBAAuB,GAAG,YAAY;AAAA;AASrC,SAAS,WAAW,SAAiC;AAC1D,QAAM,EAAE,WAAW,iBAAiB,IAAI;AAExC,gBAAc,WAAW,cAAc,YAAY;AAEnD,QAAM,kBAAkBC,MAAK,WAAW,eAAe;AACvD,oBAAkB,iBAAiB,sBAAsB,gBAAgB;AAC3E;;;ACxBA,SAAS,QAAAC,aAAY;AAKrB,IAAM,eAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAsCrB,IAAM,kBAAkB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA0BjB,SAAS,WAAW,SAAiC;AAC1D,QAAM,EAAE,WAAW,iBAAiB,IAAI;AAExC,QAAM,kBAAkBC,MAAK,WAAW,YAAY;AACpD,oBAAkB,iBAAiB,cAAc,gBAAgB;AAEjE;AAAA,IACE;AAAA,IACA;AAAA,MACE,kBAAkB;AAAA,IACpB;AAAA,IACA;AAAA,EACF;AAEA,aAAW,WAAW;AAAA,IACpB,MAAM;AAAA,IACN,YAAY;AAAA,IACZ,QAAQ;AAAA,IACR,cAAc;AAAA,EAChB,CAAC;AAED,QAAM,YAAYA,MAAK,WAAW,SAAS;AAC3C,YAAU,SAAS;AAEnB,QAAM,qBAAqBA,MAAK,WAAW,eAAe;AAC1D,oBAAkB,oBAAoB,iBAAiB,gBAAgB;AACzE;;;AC/FA,SAAS,QAAAC,aAAY;AACrB,SAAS,iBAAAC,sBAAqB;AAK9B,IAAM,kBAAkB;AAAA;AAAA;AAAA;AAAA;AAajB,SAAS,WAAW,SAAiC;AAC1D,QAAM,EAAE,UAAU,IAAI;AAEtB;AAAA,IACE;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,eAAe;AAAA,IACjB;AAAA,IACA;AAAA,EACF;AAEA,aAAW,WAAW;AAAA,IACpB,SAAS;AAAA,EACX,CAAC;AAED,gBAAc,WAAW;AAAA,IACvB,qBAAqB,CAAC,wBAAwB,oBAAoB;AAAA,IAClE,wBAAwB,CAAC,sBAAsB;AAAA,EACjD,CAAC;AAED,QAAM,WAAWC,MAAK,WAAW,QAAQ;AACzC,YAAU,QAAQ;AAElB,QAAM,gBAAgBA,MAAK,UAAU,YAAY;AACjD,EAAAC,eAAc,eAAe,iBAAiB,EAAE,MAAM,IAAM,CAAC;AAC/D;;;APrBA,eAAsB,eAA8B;AAClD,QAAM,YAAY,QAAQ,IAAI;AAG9B,QAAMC,mBAAkBC,MAAK,WAAW,cAAc;AACtD,MAAI,CAACC,YAAWF,gBAAe,GAAG;AAChC,IAAO,MAAM,kFAA2B;AACxC,IAAO,KAAK,4LAAiC;AAC7C,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,EAAO,KAAK,gIAAuB;AACnC,EAAO,KAAK,EAAE;AAGd,QAAM,SAAS,MAAM,kBAAkB;AAEvC,EAAO,KAAK,EAAE;AACd,EAAO,KAAK,6EAAiB;AAC7B,EAAO,KAAK,EAAE;AAEd,QAAM,UAA4B;AAAA,IAChC;AAAA,IACA,kBAAkB,OAAO;AAAA,EAC3B;AAGA,MAAI,aAAa;AAEjB,MAAI,OAAO,MAAM,QAAQ;AACvB,UAAM,OAAOG,KAAI,oFAAwB,EAAE,MAAM;AACjD,QAAI;AACF,kBAAY,OAAO;AACnB,WAAK,QAAQ,yDAAiB;AAC9B;AAAA,IACF,SAASC,QAAO;AACd,WAAK,KAAK,yDAAiB;AAC3B,MAAO;AAAA,QACLA,kBAAiB,QAAQA,OAAM,UAAU;AAAA,MAC3C;AAAA,IACF;AAAA,EACF;AAEA,MAAI,OAAO,MAAM,SAAS;AACxB,UAAM,OAAOD,KAAI,qFAAyB,EAAE,MAAM;AAClD,QAAI;AACF,mBAAa,OAAO;AACpB,WAAK,QAAQ,0DAAkB;AAC/B;AAAA,IACF,SAASC,QAAO;AACd,WAAK,KAAK,0DAAkB;AAC5B,MAAO;AAAA,QACLA,kBAAiB,QAAQA,OAAM,UAAU;AAAA,MAC3C;AAAA,IACF;AAAA,EACF;AAEA,MAAI,OAAO,MAAM,OAAO;AACtB,UAAM,OAAOD,KAAI,mFAAuB,EAAE,MAAM;AAChD,QAAI;AACF,iBAAW,OAAO;AAClB,WAAK,QAAQ,wDAAgB;AAC7B;AAAA,IACF,SAASC,QAAO;AACd,WAAK,KAAK,wDAAgB;AAC1B,MAAO;AAAA,QACLA,kBAAiB,QAAQA,OAAM,UAAU;AAAA,MAC3C;AAAA,IACF;AAAA,EACF;AAEA,MAAI,OAAO,MAAM,OAAO;AACtB,UAAM,OAAOD,KAAI,mFAAuB,EAAE,MAAM;AAChD,QAAI;AACF,iBAAW,OAAO;AAClB,WAAK,QAAQ,wDAAgB;AAC7B;AAAA,IACF,SAASC,QAAO;AACd,WAAK,KAAK,wDAAgB;AAC1B,MAAO;AAAA,QACLA,kBAAiB,QAAQA,OAAM,UAAU;AAAA,MAC3C;AAAA,IACF;AAAA,EACF;AAEA,MAAI,OAAO,MAAM,OAAO;AACtB,UAAM,OAAOD,KAAI,mFAAuB,EAAE,MAAM;AAChD,QAAI;AACF,iBAAW,OAAO;AAClB,WAAK,QAAQ,wDAAgB;AAC7B;AAAA,IACF,SAASC,QAAO;AACd,WAAK,KAAK,wDAAgB;AAC1B,MAAO;AAAA,QACLA,kBAAiB,QAAQA,OAAM,UAAU;AAAA,MAC3C;AAAA,IACF;AAAA,EACF;AAEA,EAAO,KAAK,EAAE;AAGd,MAAI,OAAO,MAAM,QAAQ;AACvB,UAAM,kBAAkB,SAAS;AACjC,IAAO,KAAK,EAAE;AAAA,EAChB;AAGA,EAAO,QAAQ,oGAAoB,UAAU,sCAAQ;AACrD,EAAO,KAAK,EAAE;AACd,EAAO,KAAK,uCAAS;AAErB,MAAI,OAAO,MAAM,QAAQ;AACvB,IAAO,KAAK,sFAA0B;AACtC,IAAO,KAAK,gFAA8B;AAAA,EAC5C;AAEA,MAAI,OAAO,MAAM,SAAS;AACxB,IAAO,KAAK,+EAAkC;AAC9C,IAAO,KAAK,oFAAkC;AAAA,EAChD;AAEA,MAAI,OAAO,MAAM,OAAO;AACtB,IAAO,KAAK,sEAAyB;AACrC,IAAO,KAAK,gEAA6B;AAAA,EAC3C;AAEA,MAAI,OAAO,MAAM,OAAO;AACtB,IAAO,KAAK,0FAAmC;AAAA,EACjD;AAEA,EAAO,KAAK,EAAE;AACd,EAAO,QAAQ,8DAAY;AAC7B;;;AQ7JA,SAAS,cAAAC,mBAAkB;AAC3B,SAAS,YAAAC,iBAAgB;AACzB,SAAS,WAAAC,UAAS,QAAAC,cAAY;AAC9B,SAAS,iBAAAC,sBAAqB;AAC9B,OAAOC,UAAS;;;ACJhB,OAAOC,eAAc;AAWd,SAAS,sBAAiC;AAC/C,SAAO;AAAA,IACL,YAAY;AAAA,MACV,UAAU;AAAA,MACV,MAAM;AAAA,MACN,QAAQ;AAAA,IACV;AAAA,IACA,mBAAmB,CAAC,cAAc,eAAe,UAAU,IAAI;AAAA,IAC/D,eAAe,CAAC,KAAK;AAAA,IACrB,QAAQ;AAAA,EACV;AACF;AAOA,eAAsB,gBAAgB,QAAqC;AAEzE,QAAM,mBAAmB,MAAMA,UAAS,OAAO;AAAA,IAC7C;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS;AAAA,MACT,SAAS;AAAA,QACP;AAAA,UACE,MAAM;AAAA,UACN,OAAO;AAAA,UACP,SAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAM;AAAA,UACN,OAAO;AAAA,UACP,SAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAM;AAAA,UACN,OAAO;AAAA,UACP,SAAS;AAAA,QACX;AAAA,MACF;AAAA,IACF;AAAA,EACF,CAAC;AAED,QAAM,qBAAqB,iBAAiB;AAC5C,QAAM,cAAc,mBAAmB,SAAS,UAAU;AAC1D,QAAM,UAAU,mBAAmB,SAAS,MAAM;AAClD,QAAM,YAAY,mBAAmB,SAAS,QAAQ;AAGtD,MAAI,oBAAwC,CAAC;AAC7C,MAAI,aAAa;AACf,UAAM,iBAAiB,MAAMA,UAAS,OAAO;AAAA,MAC3C;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS;AAAA,QACT,SAAS;AAAA,UACP;AAAA,YACE,MAAM;AAAA,YACN,OAAO;AAAA,YACP,SAAS;AAAA,UACX;AAAA,UACA;AAAA,YACE,MAAM;AAAA,YACN,OAAO;AAAA,YACP,SAAS;AAAA,UACX;AAAA,UACA;AAAA,YACE,MAAM;AAAA,YACN,OAAO;AAAA,YACP,SAAS;AAAA,UACX;AAAA,UACA;AAAA,YACE,MAAM;AAAA,YACN,OAAO;AAAA,YACP,SAAS;AAAA,UACX;AAAA,QACF;AAAA,QACA,UAAU,CAAC,UAAsC;AAC/C,cAAI,MAAM,WAAW,GAAG;AACtB,mBAAO;AAAA,UACT;AACA,iBAAO;AAAA,QACT;AAAA,MACF;AAAA,IACF,CAAC;AACD,wBAAoB,eAAe;AAAA,EACrC;AAGA,MAAI,gBAAgC,CAAC;AACrC,MAAI,SAAS;AACX,UAAM,aAAa,MAAMA,UAAS,OAAO;AAAA,MACvC;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS;AAAA,QACT,SAAS;AAAA,UACP;AAAA,YACE,MAAM;AAAA,YACN,OAAO;AAAA,YACP,SAAS;AAAA,UACX;AAAA,QACF;AAAA,QACA,UAAU,CAAC,UAAsC;AAC/C,cAAI,MAAM,WAAW,GAAG;AACtB,mBAAO;AAAA,UACT;AACA,iBAAO;AAAA,QACT;AAAA,MACF;AAAA,IACF,CAAC;AACD,oBAAgB,WAAW;AAAA,EAC7B;AAEA,SAAO;AAAA,IACL,YAAY;AAAA,MACV,UAAU;AAAA,MACV,MAAM;AAAA,MACN,QAAQ;AAAA,IACV;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;;;AC1IA,SAAS,eAAe;AACxB,SAAS,QAAAC,cAAY;;;ACDrB,SAAS,gBAAAC,eAAc,iBAAAC,gBAAe,cAAAC,mBAAkB;AACxD,SAAS,WAAAC,gBAAe;AAWjB,SAAS,qBACd,iBACA,iBACQ;AAER,MAAI,oBAAoB,MAAM;AAE5B,WAAO;AAAA,EACT;AAGA,QAAM,mBAAmB,aAAa,eAAe;AACrD,QAAM,gBAAgB,aAAa,eAAe;AAGlD,QAAM,aAAa,iBAAiB;AAAA,IAClC,CAAC,MAAM,EAAE,SAAS,aAAa,EAAE,SAAS;AAAA,EAC5C;AACA,MAAI,CAAC,YAAY;AACf,WAAO;AAAA,EACT;AAGA,QAAM,sBAAsB,oBAAI,IAA2B;AAC3D,QAAM,mBAAmB,oBAAI,IAA2B;AACxD,QAAM,uBAAuB,oBAAI,IAAY;AAE7C,aAAW,WAAW,kBAAkB;AACtC,QAAI,QAAQ,SAAS,aAAa,QAAQ,IAAI;AAC5C,0BAAoB,IAAI,QAAQ,IAAI,OAAO;AAAA,IAC7C,WAAW,QAAQ,SAAS,UAAU,QAAQ,IAAI;AAChD,uBAAiB,IAAI,QAAQ,IAAI,OAAO;AAAA,IAC1C;AAAA,EACF;AAGA,QAAM,SAAmB,CAAC;AAE1B,aAAW,gBAAgB,eAAe;AACxC,QAAI,aAAa,SAAS,WAAW;AACnC,YAAM,QAAQ,aAAa,KAAK,oBAAoB,IAAI,aAAa,EAAE,IAAI;AAC3E,UAAI,aAAa,MAAM,OAAO;AAE5B,6BAAqB,IAAI,aAAa,EAAE;AACxC,eAAO,KAAK,MAAM,OAAO;AAAA,MAC3B,WAAW,CAAC,aAAa,IAAI;AAE3B,eAAO,KAAK,aAAa,OAAO;AAAA,MAClC;AAAA,IAEF,WAAW,aAAa,SAAS,QAAQ;AAEvC,UAAI,aAAa,IAAI;AACnB,6BAAqB,IAAI,aAAa,EAAE;AAAA,MAC1C;AACA,aAAO,KAAK,aAAa,OAAO;AAAA,IAClC,OAAO;AAEL,aAAO,KAAK,aAAa,OAAO;AAAA,IAClC;AAAA,EACF;AAGA,aAAW,CAAC,IAAI,OAAO,KAAK,qBAAqB;AAC/C,QAAI,CAAC,qBAAqB,IAAI,EAAE,GAAG;AAEjC,aAAO,KAAK,QAAQ,OAAO;AAAA,IAC7B;AAAA,EACF;AAGA,aAAW,CAAC,IAAI,OAAO,KAAK,kBAAkB;AAC5C,QAAI,CAAC,qBAAqB,IAAI,EAAE,GAAG;AAEjC,aAAO,KAAK,QAAQ,OAAO;AAAA,IAC7B;AAAA,EACF;AAGA,QAAM,eAAe,OAAO,CAAC;AAC7B,MAAI,OAAO,SAAS,KAAK,iBAAiB,UAAa,aAAa,WAAW,GAAG;AAChF,WAAO,MAAM;AAAA,EACf;AACA,SAAO,OAAO,KAAK,IAAI;AACzB;AAWO,SAAS,UACd,cACA,cACA,WACA,WAAW,gBACc;AAEzB,MAAI,iBAAiB,MAAM;AAEzB,WAAO,KAAK,MAAM,KAAK,UAAU,YAAY,CAAC;AAAA,EAChD;AAGA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAYA,SAAS,mBACP,UACA,UACA,WACA,UACA,aACyB;AAEzB,QAAM,SAAS,KAAK,MAAM,KAAK,UAAU,QAAQ,CAAC;AAElD,aAAW,CAAC,KAAK,aAAa,KAAK,OAAO,QAAQ,QAAQ,GAAG;AAC3D,UAAM,UAAU,cAAc,GAAG,WAAW,IAAI,GAAG,KAAK;AACxD,UAAM,gBAAgB,SAAS,GAAG;AAGlC,QAAI,cAAc,UAAU,SAAS,SAAS,GAAG;AAE/C,aAAO,GAAG,IAAI,UAAU,aAAa;AAAA,IACvC,WAES,WAAW,UAAU,SAAS,SAAS,GAAG;AAEjD,UACE,OAAO,kBAAkB,YACzB,kBAAkB,QAClB,CAAC,MAAM,QAAQ,aAAa,KAC5B,OAAO,kBAAkB,YACzB,kBAAkB,QAClB,CAAC,MAAM,QAAQ,aAAa,GAC5B;AAEA,eAAO,GAAG,IAAI;AAAA,UACZ;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF,WAAW,EAAE,OAAO,WAAW;AAE7B,eAAO,GAAG,IAAI,UAAU,aAAa;AAAA,MACvC;AAAA,IAEF,WAGE,OAAO,kBAAkB,YACzB,kBAAkB,QAClB,CAAC,MAAM,QAAQ,aAAa,KAC5B,OAAO,kBAAkB,YACzB,kBAAkB,QAClB,CAAC,MAAM,QAAQ,aAAa,GAC5B;AAEA,aAAO,GAAG,IAAI;AAAA,QACZ;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF,WAES,EAAE,OAAO,WAAW;AAE3B,aAAO,GAAG,IAAI,UAAU,aAAa;AAAA,IACvC;AAAA,EAEF;AAEA,SAAO;AACT;AAQA,SAAS,UAAU,OAAyB;AAC1C,MAAI,UAAU,QAAW;AACvB,WAAO;AAAA,EACT;AACA,SAAO,KAAK,MAAM,KAAK,UAAU,KAAK,CAAC;AACzC;AAQA,eAAsB,iBACpB,WAC8B;AAC9B,QAAM,eAAe,GAAG,SAAS;AAEjC,MAAI,CAACC,YAAW,YAAY,GAAG;AAC7B,WAAO;AAAA,EACT;AAEA,MAAI;AACF,UAAM,UAAUC,cAAa,cAAc,OAAO;AAClD,WAAO,KAAK,MAAM,OAAO;AAAA,EAC3B,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAQA,eAAsB,iBACpB,WACA,UACe;AACf,QAAM,eAAe,GAAG,SAAS;AACjC,YAAUC,SAAQ,YAAY,CAAC;AAC/B,EAAAC,eAAc,cAAc,KAAK,UAAU,UAAU,MAAM,CAAC,GAAG,OAAO;AACxE;AAUA,eAAsB,kBACpB,cACA,YACA,cAIC;AACD,QAAM,kBAAkBF,cAAa,cAAc,OAAO;AAC1D,QAAM,eAAeD,YAAW,UAAU;AAC1C,QAAM,kBAAkB,eAAeC,cAAa,YAAY,OAAO,IAAI;AAG3E,QAAM,aAAa,WAAW,SAAS,OAAO;AAE9C,MAAI;AACJ,MAAI;AAEJ,MAAI,CAAC,cAAc;AAEjB,oBAAgB;AAChB,aAAS;AAAA,EACX,WAAW,YAAY;AAErB,QAAI;AACF,YAAM,eAAe,KAAK,MAAM,eAAe;AAC/C,YAAM,eAAe,kBAChB,KAAK,MAAM,eAAe,IAC3B;AACJ,YAAM,YAAY,aAAa,aAAa,EAAE,SAAS,CAAC,GAAG,MAAM,CAAC,EAAE;AAEpE,YAAM,WAAW,WAAW,MAAM,GAAG,EAAE,IAAI,KAAK;AAChD,YAAM,aAAa,UAAU,cAAc,cAAc,WAAW,QAAQ;AAC5E,sBAAgB,KAAK,UAAU,YAAY,MAAM,CAAC;AAClD,eAAS;AAAA,IACX,QAAQ;AAEN,sBAAgB;AAChB,eAAS;AAAA,IACX;AAAA,EACF,OAAO;AAEL,oBAAgB,qBAAqB,iBAAiB,eAAe;AAGrE,QAAI,kBAAkB,iBAAiB;AACrC,eAAS;AAAA,IACX,OAAO;AACL,eAAS;AAAA,IACX;AAAA,EACF;AAGA,MAAI,WAAW,WAAW;AACxB,cAAUC,SAAQ,UAAU,CAAC;AAC7B,IAAAC,eAAc,YAAY,eAAe,OAAO;AAAA,EAClD;AAEA,SAAO,EAAE,QAAQ,MAAM,WAAW;AACpC;AAmBA,SAAS,aAAa,SAAkC;AACtD,QAAM,QAAQ,QAAQ,MAAM,IAAI;AAChC,QAAM,WAA4B,CAAC;AACnC,MAAI,cAAgD;AACpD,MAAI,mBAAmB;AACvB,MAAI,iBAA2B,CAAC;AAChC,MAAI;AAEJ,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,UAAM,OAAO,MAAM,CAAC;AACpB,UAAM,aAAa,IAAI;AAGvB,UAAM,cAAc,iBAAiB,IAAI;AACzC,QAAI,aAAa;AACf,UAAI,gBAAgB,aAAa;AAE/B,uBAAe,KAAK,IAAI;AACxB;AAAA,MACF;AAGA,UAAI,eAAe,SAAS,KAAK,SAAS,WAAW,GAAG;AACtD,iBAAS,KAAK;AAAA,UACZ,MAAM;AAAA,UACN,WAAW;AAAA,UACX,SAAS,aAAa;AAAA,UACtB,SAAS,eAAe,KAAK,IAAI;AAAA,QACnC,CAAC;AAAA,MACH;AAGA,oBAAc,YAAY;AAC1B,kBAAY,YAAY;AACxB,yBAAmB;AACnB,uBAAiB,CAAC,IAAI;AAAA,IACxB,WAES,eAAe,IAAI,GAAG;AAC7B,UAAI,gBAAgB,aAAa;AAE/B,uBAAe,KAAK,IAAI;AACxB;AAAA,MACF;AAGA,qBAAe,KAAK,IAAI;AAGxB,eAAS,KAAK;AAAA,QACZ,MAAM;AAAA,QACN,WAAW;AAAA,QACX,SAAS;AAAA,QACT,SAAS,eAAe,KAAK,IAAI;AAAA,QACjC,IAAI;AAAA,MACN,CAAC;AAGD,oBAAc;AACd,kBAAY;AACZ,yBAAmB,aAAa;AAChC,uBAAiB,CAAC;AAAA,IACpB,OAEK;AACH,qBAAe,KAAK,IAAI;AAAA,IAC1B;AAAA,EACF;AAGA,MAAI,eAAe,SAAS,KAAK,SAAS,WAAW,GAAG;AACtD,aAAS,KAAK;AAAA,MACZ,MAAM;AAAA,MACN,WAAW;AAAA,MACX,SAAS,MAAM;AAAA,MACf,SAAS,eAAe,KAAK,IAAI;AAAA,MACjC,IAAI;AAAA,IACN,CAAC;AAAA,EACH;AAEA,SAAO;AACT;AAQA,SAAS,iBACP,MACkD;AAElD,QAAM,yBACJ;AACF,MAAI,QAAQ,KAAK,MAAM,sBAAsB;AAC7C,MAAI,OAAO;AACT,WAAO,EAAE,MAAM,WAAW,IAAI,MAAM,CAAC,KAAK,OAAU;AAAA,EACtD;AAGA,QAAM,sBACJ;AACF,UAAQ,KAAK,MAAM,mBAAmB;AACtC,MAAI,OAAO;AACT,WAAO,EAAE,MAAM,QAAQ,IAAI,MAAM,CAAC,KAAK,OAAU;AAAA,EACnD;AAGA,QAAM,qBAAqB;AAC3B,UAAQ,KAAK,MAAM,kBAAkB;AACrC,MAAI,OAAO;AACT,WAAO,EAAE,MAAM,WAAW,IAAI,MAAM,CAAC,KAAK,OAAU;AAAA,EACtD;AAGA,QAAM,kBAAkB;AACxB,UAAQ,KAAK,MAAM,eAAe;AAClC,MAAI,OAAO;AACT,WAAO,EAAE,MAAM,QAAQ,IAAI,MAAM,CAAC,KAAK,OAAU;AAAA,EACnD;AAEA,SAAO;AACT;AAQA,SAAS,eAAe,MAAyC;AAE/D,MAAI,oCAAoC,KAAK,IAAI,GAAG;AAClD,WAAO;AAAA,EACT;AAGA,MAAI,iCAAiC,KAAK,IAAI,GAAG;AAC/C,WAAO;AAAA,EACT;AAGA,MAAI,iCAAiC,KAAK,IAAI,GAAG;AAC/C,WAAO;AAAA,EACT;AAGA,MAAI,8BAA8B,KAAK,IAAI,GAAG;AAC5C,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAUA,SAAS,cACP,UACA,SACA,WACS;AACT,QAAM,eAAe,UAAU,QAAQ,QAAQ,KAAK,CAAC;AAIrD,SAAO,aAAa;AAAA,IAClB,CAAC,MAAM,YAAY,KAAK,QAAQ,WAAW,GAAG,CAAC,GAAG;AAAA,EACpD;AACF;AAUA,SAAS,WACP,UACA,SACA,WACS;AACT,QAAM,YAAY,UAAU,KAAK,QAAQ,KAAK,CAAC;AAE/C,SAAO,UAAU,KAAK,CAAC,MAAM,YAAY,KAAK,QAAQ,WAAW,GAAG,CAAC,GAAG,CAAC;AAC3E;;;ADjhBA,eAAsB,YACpB,SACA,YACA,cACmE;AACnE,QAAM,QAAkB,CAAC;AACzB,QAAM,UAAoB,CAAC;AAC3B,QAAM,SAAmB,CAAC;AAE1B,QAAM,EAAE,WAAW,aAAa,OAAO,IAAI;AAE3C,aAAW,aAAa,YAAY;AAClC,UAAM,gBACJ,cAAc,eACV,eACA,cAAc,gBACZ,gBACA,cAAc,WACZ,WACA;AAEV,UAAM,SAASC,OAAK,aAAa,YAAY,aAAa;AAC1D,UAAM,UAAUA,OAAK,WAAW,YAAY,aAAa;AAEzD,IAAO,KAAK,6BAA6B,aAAa,EAAE;AAExD,UAAM;AAAA,MACJ;AAAA,MACA;AAAA,MACA,EAAE,OAAO,SAAS,OAAO;AAAA,MACzB,OAAO;AAAA,MACP;AAAA,IACF;AAAA,EACF;AAEA,SAAO,EAAE,OAAO,SAAS,OAAO;AAClC;AAKA,eAAe,cACb,QACA,SACA,QACA,QACA,cACe;AACf,QAAM,UAAU,MAAM,QAAQ,QAAQ,EAAE,eAAe,KAAK,CAAC;AAE7D,aAAW,SAAS,SAAS;AAC3B,UAAM,UAAUA,OAAK,QAAQ,MAAM,IAAI;AACvC,UAAM,WAAWA,OAAK,SAAS,MAAM,IAAI;AAEzC,QAAI,MAAM,YAAY,GAAG;AACvB,YAAM,cAAc,SAAS,UAAU,QAAQ,QAAQ,YAAY;AAAA,IACrE,OAAO;AACL,UAAI,CAAC,QAAQ;AACX,cAAM,cAAc,MAAM;AAAA,UACxB;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAEA,YAAI,YAAY,WAAW,WAAW;AACpC,iBAAO,MAAM,KAAK,QAAQ;AAAA,QAC5B,WAAW,YAAY,WAAW,WAAW;AAC3C,iBAAO,QAAQ,KAAK,QAAQ;AAAA,QAC9B,WAAW,YAAY,WAAW,UAAU;AAC1C,iBAAO,OAAO,KAAK,QAAQ;AAAA,QAC7B;AAAA,MACF,OAAO;AAEL,eAAO,QAAQ,KAAK,QAAQ;AAAA,MAC9B;AAAA,IACF;AAAA,EACF;AACF;;;AE1FA,SAAS,WAAAC,gBAAe;AACxB,SAAS,QAAAC,cAAY;AAYrB,eAAsB,QACpB,SACA,YACA,cACmE;AACnE,QAAM,QAAkB,CAAC;AACzB,QAAM,UAAoB,CAAC;AAC3B,QAAM,SAAmB,CAAC;AAE1B,QAAM,EAAE,WAAW,aAAa,OAAO,IAAI;AAE3C,aAAW,aAAa,YAAY;AAClC,UAAM,gBAAgB,cAAc,QAAQ,QAAQ;AAEpD,UAAM,SAASC,OAAK,aAAa,QAAQ,aAAa;AACtD,UAAM,UAAUA,OAAK,WAAW,QAAQ,aAAa;AAErD,IAAO,KAAK,yBAAyB,aAAa,EAAE;AAEpD,UAAMC;AAAA,MACJ;AAAA,MACA;AAAA,MACA,EAAE,OAAO,SAAS,OAAO;AAAA,MACzB,OAAO;AAAA,MACP;AAAA,IACF;AAAA,EACF;AAEA,SAAO,EAAE,OAAO,SAAS,OAAO;AAClC;AAKA,eAAeA,eACb,QACA,SACA,QACA,QACA,cACe;AACf,QAAM,UAAU,MAAMC,SAAQ,QAAQ,EAAE,eAAe,KAAK,CAAC;AAE7D,aAAW,SAAS,SAAS;AAC3B,UAAM,UAAUF,OAAK,QAAQ,MAAM,IAAI;AACvC,UAAM,WAAWA,OAAK,SAAS,MAAM,IAAI;AAEzC,QAAI,MAAM,YAAY,GAAG;AACvB,YAAMC,eAAc,SAAS,UAAU,QAAQ,QAAQ,YAAY;AAAA,IACrE,OAAO;AACL,UAAI,CAAC,QAAQ;AACX,cAAM,cAAc,MAAM;AAAA,UACxB;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAEA,YAAI,YAAY,WAAW,WAAW;AACpC,iBAAO,MAAM,KAAK,QAAQ;AAAA,QAC5B,WAAW,YAAY,WAAW,WAAW;AAC3C,iBAAO,QAAQ,KAAK,QAAQ;AAAA,QAC9B,WAAW,YAAY,WAAW,UAAU;AAC1C,iBAAO,OAAO,KAAK,QAAQ;AAAA,QAC7B;AAAA,MACF,OAAO;AAEL,eAAO,QAAQ,KAAK,QAAQ;AAAA,MAC9B;AAAA,IACF;AAAA,EACF;AACF;;;ACnFA,SAAS,WAAAE,UAAS,gBAAgB;AAClC,SAAS,QAAAC,QAAM,YAAAC,WAAU,WAAW;AAQpC,eAAsB,eACpB,SACA,cACmE;AACnE,QAAM,QAAkB,CAAC;AACzB,QAAM,UAAoB,CAAC;AAC3B,QAAM,SAAmB,CAAC;AAE1B,QAAM,EAAE,WAAW,aAAa,OAAO,IAAI;AAE3C,EAAO,KAAK,wCAAwC;AAGpD,QAAM,gBAAgB,oBAAI,IAAI;AAAA,IAC5B;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAGD,QAAM,oBAAoB,MAAM,sBAAsB,WAAW;AAEjE,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IACA,EAAE,OAAO,SAAS,OAAO;AAAA,IACzB,OAAO;AAAA,IACP;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,SAAO,EAAE,OAAO,SAAS,OAAO;AAClC;AAKA,eAAe,sBAAsB,aAA2C;AAC9E,QAAM,WAAW,oBAAI,IAAY;AACjC,QAAM,gBAAgBC,OAAK,aAAa,YAAY;AAEpD,MAAI;AACF,UAAM,UAAU,MAAM,SAAS,eAAe,OAAO;AACrD,UAAM,QAAQ,QAAQ,MAAM,IAAI;AAEhC,eAAW,QAAQ,OAAO;AACxB,YAAM,UAAU,KAAK,KAAK;AAE1B,UAAI,WAAW,CAAC,QAAQ,WAAW,GAAG,GAAG;AAEvC,cAAM,UAAU,QAAQ,WAAW,GAAG,IAAI,QAAQ,MAAM,CAAC,IAAI;AAC7D,iBAAS,IAAI,OAAO;AAAA,MACtB;AAAA,IACF;AAAA,EACF,QAAQ;AAAA,EAER;AAEA,SAAO;AACT;AAKA,eAAe,oBACb,QACA,SACA,SACA,QACA,QACA,eACA,mBACA,cACe;AACf,QAAM,UAAU,MAAMC,SAAQ,QAAQ,EAAE,eAAe,KAAK,CAAC;AAE7D,aAAW,SAAS,SAAS;AAC3B,UAAM,UAAUD,OAAK,QAAQ,MAAM,IAAI;AACvC,UAAM,WAAWA,OAAK,SAAS,MAAM,IAAI;AAEzC,UAAM,kBAAkBE,UAAS,SAAS,OAAO;AAEjD,UAAM,eAAe,gBAAgB,MAAM,GAAG,EAAE,KAAK,GAAG;AAGxD,QAAI,cAAc,cAAc,eAAe,iBAAiB,GAAG;AACjE;AAAA,IACF;AAEA,QAAI,MAAM,YAAY,GAAG;AACvB,YAAM;AAAA,QACJ;AAAA,QACA;AAAA,QACA;AAAA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF,OAAO;AACL,UAAI,CAAC,QAAQ;AACX,cAAM,cAAc,MAAM;AAAA,UACxB;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAEA,YAAI,YAAY,WAAW,WAAW;AACpC,iBAAO,MAAM,KAAK,QAAQ;AAAA,QAC5B,WAAW,YAAY,WAAW,WAAW;AAC3C,iBAAO,QAAQ,KAAK,QAAQ;AAAA,QAC9B,WAAW,YAAY,WAAW,UAAU;AAC1C,iBAAO,OAAO,KAAK,QAAQ;AAAA,QAC7B;AAAA,MACF,OAAO;AAEL,eAAO,QAAQ,KAAK,QAAQ;AAAA,MAC9B;AAAA,IACF;AAAA,EACF;AACF;AAKA,SAAS,cACP,cACA,eACA,mBACS;AAET,aAAW,YAAY,eAAe;AACpC,QAAI,iBAAiB,YAAY,aAAa,WAAW,GAAG,QAAQ,GAAG,GAAG;AACxE,aAAO;AAAA,IACT;AAAA,EACF;AAGA,aAAW,WAAW,mBAAmB;AAEvC,QAAI,aAAa,cAAc,OAAO,GAAG;AACvC,aAAO;AAAA,IACT;AAAA,EACF;AAEA,SAAO;AACT;AAKA,SAAS,aAAa,MAAc,SAA0B;AAE5D,MAAI,QAAQ,SAAS,GAAG,GAAG;AACzB,UAAM,aAAa,QAAQ,MAAM,GAAG,EAAE;AACtC,WAAO,SAAS,cAAc,KAAK,WAAW,GAAG,UAAU,GAAG;AAAA,EAChE;AAGA,MAAI,QAAQ,SAAS,GAAG,GAAG;AACzB,UAAM,eAAe,QAClB,QAAQ,OAAO,KAAK,EACpB,QAAQ,OAAO,IAAI;AACtB,WAAO,IAAI,OAAO,IAAI,YAAY,GAAG,EAAE,KAAK,IAAI;AAAA,EAClD;AAGA,SAAO,SAAS,WAAW,KAAK,WAAW,GAAG,OAAO,GAAG;AAC1D;;;AL5JA,SAASC,iBAAgB,cAA8B;AACrD,QAAMC,cAAaC,eAAc,YAAY,GAAG;AAChD,QAAMC,aAAYC,SAAQH,WAAU;AAKpC,QAAM,WAAWI,OAAKF,YAAW,gBAAgB,YAAY;AAC7D,QAAM,UAAUE,OAAKF,YAAW,mBAAmB,YAAY;AAE/D,MAAIG,YAAW,QAAQ,GAAG;AACxB,WAAO;AAAA,EACT;AACA,MAAIA,YAAW,OAAO,GAAG;AACvB,WAAO;AAAA,EACT;AAGA,SAAO;AACT;AAOA,eAAe,yBACb,aAC8B;AAC9B,QAAM,eAAeD,OAAK,aAAa,kBAAkB;AACzD,MAAI;AACF,UAAM,UAAU,MAAME,UAAS,cAAc,OAAO;AACpD,WAAO,KAAK,MAAM,OAAO;AAAA,EAC3B,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAQA,SAAS,kBACP,UACA,UACc;AACd,QAAM,OAAM,oBAAI,KAAK,GAAE,YAAY;AAGnC,QAAM,YACJ,UAAU,aAAa,UAAU,aAAa,EAAE,SAAS,CAAC,GAAG,MAAM,CAAC,EAAE;AAExE,SAAO;AAAA,IACL,SAAS,UAAU,WAAW,UAAU,WAAW;AAAA,IACnD,UAAU;AAAA,IACV,iBAAiB,UAAU,mBAAmB;AAAA,IAC9C,OAAO,EAAE,GAAI,UAAU,SAAS,CAAC,GAAI,GAAI,UAAU,SAAS,CAAC,EAAG;AAAA,IAChE;AAAA,EACF;AACF;AAMA,eAAsB,WAAW,SAA2C;AAC1E,MAAI;AAEF,UAAM,YAAY,QAAQ,IAAI;AAG9B,QAAI;AAEJ,QAAI,QAAQ,aAAa;AAEvB,eAAS,oBAAoB;AAC7B,MAAO,KAAK,gLAA+B;AAAA,IAC7C,OAAO;AAEL,eAAS,MAAM,gBAAgB,QAAQ,MAAM;AAAA,IAC/C;AAGA,WAAO,SAAS,QAAQ;AAGxB,QAAI,OAAO,QAAQ;AACjB,MAAO,KAAK,uHAA6B;AACzC,MAAO,KAAK,oFAAwB;AAEpC,UAAI,OAAO,WAAW,UAAU;AAC9B,QAAO;AAAA,UACL,gBAAgB,OAAO,kBAAkB,KAAK,IAAI,CAAC;AAAA,QACrD;AAAA,MACF;AAEA,UAAI,OAAO,WAAW,MAAM;AAC1B,QAAO,KAAK,YAAY,OAAO,cAAc,KAAK,IAAI,CAAC,EAAE;AAAA,MAC3D;AAEA,UAAI,OAAO,WAAW,QAAQ;AAC5B,QAAO,KAAK,4FAA+C;AAAA,MAC7D;AAEA,MAAO,KAAK,OAAO;AAAA,IACrB;AAGA,UAAM,cAAcP,iBAAgB,SAAS;AAG7C,QAAI,CAACM,YAAW,WAAW,GAAG;AAC5B,YAAM,IAAI,MAAM,+FAAyB;AAAA,IAC3C;AAGA,UAAM,mBAAmB,MAAM,yBAAyB,WAAW;AAGnE,UAAM,mBAAmB,MAAM,iBAAiB,SAAS;AAGzD,UAAM,eAAe,kBAAkB,kBAAkB,gBAAgB;AAGzE,UAAM,aAAyB;AAAA,MAC7B;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAEA,QAAI,aAAa;AACjB,QAAI,cAAc;AAClB,QAAI,eAAe;AAGnB,QAAI,OAAO,WAAW,YAAY,OAAO,kBAAkB,SAAS,GAAG;AACrE,YAAM,UAAUE,KAAI,2DAAc,EAAE,MAAM;AAE1C,UAAI;AACF,cAAM,SAAS,MAAM;AAAA,UACnB;AAAA,UACA,OAAO;AAAA,UACP;AAAA,QACF;AAEA,sBAAc,OAAO,MAAM;AAC3B,uBAAe,OAAO,OAAO;AAC7B,wBAAgB,OAAO,QAAQ;AAE/B,gBAAQ;AAAA,UACN,+FAAoB,OAAO,MAAM,MAAM,yBAAU,OAAO,OAAO,MAAM,+BAAW,OAAO,QAAQ,MAAM;AAAA,QACvG;AAAA,MACF,SAASC,QAAO;AACd,gBAAQ,KAAK,4FAAiB;AAC9B,cAAMA;AAAA,MACR;AAAA,IACF;AAGA,QAAI,OAAO,WAAW,QAAQ,OAAO,cAAc,SAAS,GAAG;AAC7D,YAAM,UAAUD,KAAI,+CAAY,EAAE,MAAM;AAExC,UAAI;AACF,cAAM,SAAS,MAAM;AAAA,UACnB;AAAA,UACA,OAAO;AAAA,UACP;AAAA,QACF;AAEA,sBAAc,OAAO,MAAM;AAC3B,uBAAe,OAAO,OAAO;AAC7B,wBAAgB,OAAO,QAAQ;AAE/B,gBAAQ;AAAA,UACN,mFAAkB,OAAO,MAAM,MAAM,yBAAU,OAAO,OAAO,MAAM,+BAAW,OAAO,QAAQ,MAAM;AAAA,QACrG;AAAA,MACF,SAASC,QAAO;AACd,gBAAQ,KAAK,gFAAe;AAC5B,cAAMA;AAAA,MACR;AAAA,IACF;AAGA,QAAI,OAAO,WAAW,QAAQ;AAC5B,YAAM,UAAUD,KAAI,iEAAe,EAAE,MAAM;AAE3C,UAAI;AACF,cAAM,SAAS,MAAM,eAAe,YAAY,YAAY;AAE5D,sBAAc,OAAO,MAAM;AAC3B,uBAAe,OAAO,OAAO;AAC7B,wBAAgB,OAAO,QAAQ;AAE/B,gBAAQ;AAAA,UACN,qGAAqB,OAAO,MAAM,MAAM,yBAAU,OAAO,OAAO,MAAM,+BAAW,OAAO,QAAQ,MAAM;AAAA,QACxG;AAAA,MACF,SAASC,QAAO;AACd,gBAAQ,KAAK,kGAAkB;AAC/B,cAAMA;AAAA,MACR;AAAA,IACF;AAGA,QAAI,CAAC,OAAO,QAAQ;AAClB,mBAAa,YAAW,oBAAI,KAAK,GAAE,YAAY;AAC/C,YAAM,iBAAiB,WAAW,YAAY;AAAA,IAChD;AAGA,IAAO,QAAQ,2CAAa;AAE5B,QAAI,OAAO,QAAQ;AACjB,MAAO,KAAK,qJAAkC;AAAA,IAChD;AAEA,IAAO,KAAK,2DAAc,UAAU,QAAG;AACvC,IAAO,KAAK,iEAAe,WAAW,QAAG;AACzC,IAAO,KAAK,uEAAgB,YAAY;AAAA,CAAK;AAG7C,UAAMC,mBAAkBL,OAAK,WAAW,cAAc;AACtD,QAAIC,YAAWI,gBAAe,GAAG;AAC/B,YAAMC,eAAc,MAAM,OAAOD;AAIjC,YAAM,cACJC,aAAY,SAAS,kBAAkB,gBAAgB,KACvDA,aAAY,SAAS,eAAe,gBAAgB;AAEtD,UAAI,CAAC,aAAa;AAChB,QAAO,KAAK,uCAAS;AACrB,QAAO,KAAK,iBAAiB;AAC7B,QAAO,KAAK,mBAAmB;AAC/B,QAAO,KAAK,iBAAO;AACnB,QAAO,KAAK,iGAA0C;AACtD,QAAO,KAAK,gCAAgC;AAAA,MAC9C,OAAO;AACL,QAAO,KAAK,uCAAS;AACrB,QAAO,KAAK,iBAAiB;AAC7B,QAAO,KAAK,qBAAqB;AAAA,MACnC;AAAA,IACF,OAAO;AACL,MAAO,KAAK,uCAAS;AACrB,MAAO,KAAK,iBAAiB;AAC7B,MAAO,KAAK,qBAAqB;AAAA,IACnC;AAAA,EACF,SAASF,QAAO;AACd,IAAO,MAAM,+DAAa;AAC1B,QAAIA,kBAAiB,OAAO;AAC1B,MAAO,MAAMA,OAAM,OAAO;AAAA,IAC5B,OAAO;AACL,MAAO,MAAM,OAAOA,MAAK,CAAC;AAAA,IAC5B;AACA,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF;;;Af3RA,IAAMG,cAAaC,eAAc,YAAY,GAAG;AAChD,IAAMC,aAAYC,SAAQH,WAAU;AACpC,IAAM,kBAAkBI,OAAKF,YAAW,iBAAiB;AACzD,IAAM,cAAc,KAAK,MAAMG,cAAa,iBAAiB,OAAO,CAAC;AAErE,IAAM,UAAU,IAAI,QAAQ;AAE5B,QACG,KAAK,kBAAkB,EACvB,YAAY,gEAAgE,EAC5E,QAAQ,YAAY,OAAO;AAG9B,QACG,SAAS,kBAAkB,cAAc,EACzC,OAAO,cAAc,yBAAyB,EAC9C,OAAO,kBAAkB,2BAA2B,EACpD,OAAO,aAAa,0BAA0B,EAC9C;AAAA,EACC,OACE,aACA,YAKG;AACH,UAAM,cAAc,aAAa,OAAO;AAAA,EAC1C;AACF;AAGF,QACG,QAAQ,OAAO,EACf,YAAY,kCAAkC,EAC9C,OAAO,YAAY;AAClB,QAAM,aAAa;AACrB,CAAC;AAGH,QACG,QAAQ,KAAK,EACb,YAAY,2CAA2C,EACvD,OAAO,aAAa,4CAA4C,EAChE,OAAO,SAAS,oCAAoC,EACpD,OAAO,aAAa,qCAAqC,EACzD;AAAA,EACC,OAAO,YAAgE;AACrE,UAAM,WAAW;AAAA,MACf,aAAa,QAAQ,OAAO,QAAQ,OAAO;AAAA,MAC3C,QAAQ,QAAQ,UAAU;AAAA,IAC5B,CAAC;AAAA,EACH;AACF;AAEF,QAAQ,MAAM;","names":["readFileSync","fileURLToPath","dirname","join","existsSync","ora","dirname","join","readFileSync","writeFileSync","existsSync","__filename","__dirname","dirname","join","error","chalk","inquirer","inquirer","error","chalk","existsSync","error","ora","existsSync","join","ora","inquirer","join","inquirer","join","inquirer","error","join","readFileSync","writeFileSync","join","packageJsonPath","join","readFileSync","writeFileSync","join","join","join","join","join","join","writeFileSync","join","writeFileSync","packageJsonPath","join","existsSync","ora","error","existsSync","readFile","dirname","join","fileURLToPath","ora","inquirer","join","readFileSync","writeFileSync","existsSync","dirname","existsSync","readFileSync","dirname","writeFileSync","join","readdir","join","join","copyDirectory","readdir","readdir","join","relative","join","readdir","relative","getTemplatePath","__filename","fileURLToPath","__dirname","dirname","join","existsSync","readFile","ora","error","packageJsonPath","packageJson","__filename","fileURLToPath","__dirname","dirname","join","readFileSync"]}
|